Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  Bluetooth support for Realtek devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2015 Endless Mobile, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <net/bluetooth/bluetooth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <net/bluetooth/hci_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "btrtl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define VERSION "0.1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define RTL_EPATCH_SIGNATURE	"Realtech"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define RTL_ROM_LMP_3499	0x3499
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define RTL_ROM_LMP_8723A	0x1200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define RTL_ROM_LMP_8723B	0x8723
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define RTL_ROM_LMP_8723D	0x8873
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define RTL_ROM_LMP_8821A	0x8821
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define RTL_ROM_LMP_8761A	0x8761
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define RTL_ROM_LMP_8822B	0x8822
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define RTL_ROM_LMP_8852A	0x8852
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define RTL_CONFIG_MAGIC	0x8723ab55
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define IC_MATCH_FL_LMPSUBV	(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define IC_MATCH_FL_HCIREV	(1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define IC_MATCH_FL_HCIVER	(1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define IC_MATCH_FL_HCIBUS	(1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define IC_INFO(lmps, hcir) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	.match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	.lmp_subver = (lmps), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	.hci_rev = (hcir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) struct id_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	__u16 match_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	__u16 lmp_subver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	__u16 hci_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	__u8 hci_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	__u8 hci_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	bool config_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	bool has_rom_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	char *fw_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	char *cfg_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) struct btrtl_device_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	const struct id_table *ic_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	u8 rom_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	u8 *fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	int fw_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	u8 *cfg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	int cfg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static const struct id_table ic_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	{ IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_8723A, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	  .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	  .has_rom_version = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	  .fw_name = "rtl_bt/rtl8723a_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	  .cfg_name = NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	{ IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_3499, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	  .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	  .has_rom_version = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	  .fw_name = "rtl_bt/rtl8723a_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	  .cfg_name = NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	/* 8723BS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			 IC_MATCH_FL_HCIVER | IC_MATCH_FL_HCIBUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	  .lmp_subver = RTL_ROM_LMP_8723B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	  .hci_rev = 0xb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	  .hci_ver = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	  .hci_bus = HCI_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	  .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	  .fw_name  = "rtl_bt/rtl8723bs_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	  .cfg_name = "rtl_bt/rtl8723bs_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	/* 8723B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	{ IC_INFO(RTL_ROM_LMP_8723B, 0xb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	  .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	  .fw_name  = "rtl_bt/rtl8723b_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	  .cfg_name = "rtl_bt/rtl8723b_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	/* 8723D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	{ IC_INFO(RTL_ROM_LMP_8723B, 0xd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	  .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	  .fw_name  = "rtl_bt/rtl8723d_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	  .cfg_name = "rtl_bt/rtl8723d_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	/* 8723DS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			 IC_MATCH_FL_HCIVER | IC_MATCH_FL_HCIBUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	  .lmp_subver = RTL_ROM_LMP_8723B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	  .hci_rev = 0xd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	  .hci_ver = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	  .hci_bus = HCI_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	  .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	  .fw_name  = "rtl_bt/rtl8723ds_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	  .cfg_name = "rtl_bt/rtl8723ds_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	/* 8723DU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	{ IC_INFO(RTL_ROM_LMP_8723D, 0x826C),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	  .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	  .fw_name  = "rtl_bt/rtl8723d_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	  .cfg_name = "rtl_bt/rtl8723d_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	/* 8821A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	{ IC_INFO(RTL_ROM_LMP_8821A, 0xa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	  .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	  .fw_name  = "rtl_bt/rtl8821a_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	  .cfg_name = "rtl_bt/rtl8821a_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	/* 8821C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	{ IC_INFO(RTL_ROM_LMP_8821A, 0xc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	  .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	  .fw_name  = "rtl_bt/rtl8821c_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	  .cfg_name = "rtl_bt/rtl8821c_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	/* 8761A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	{ IC_INFO(RTL_ROM_LMP_8761A, 0xa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	  .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	  .fw_name  = "rtl_bt/rtl8761a_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	  .cfg_name = "rtl_bt/rtl8761a_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	/* 8761B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	{ IC_INFO(RTL_ROM_LMP_8761A, 0xb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	  .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	  .fw_name  = "rtl_bt/rtl8761b_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	  .cfg_name = "rtl_bt/rtl8761b_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	/* 8822C with UART interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			 IC_MATCH_FL_HCIBUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	  .lmp_subver = RTL_ROM_LMP_8822B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	  .hci_rev = 0x000c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	  .hci_ver = 0x0a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	  .hci_bus = HCI_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	  .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	  .fw_name  = "rtl_bt/rtl8822cs_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	  .cfg_name = "rtl_bt/rtl8822cs_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	/* 8822C with USB interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	{ IC_INFO(RTL_ROM_LMP_8822B, 0xc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	  .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	  .fw_name  = "rtl_bt/rtl8822cu_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	  .cfg_name = "rtl_bt/rtl8822cu_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	/* 8822B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	{ IC_INFO(RTL_ROM_LMP_8822B, 0xb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	  .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	  .fw_name  = "rtl_bt/rtl8822b_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	  .cfg_name = "rtl_bt/rtl8822b_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	/* 8852B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	{ IC_INFO(RTL_ROM_LMP_8852A, 0xb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	  .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	  .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	  .fw_name  = "rtl_bt/rtl8852bu_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	  .cfg_name = "rtl_bt/rtl8852bu_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 					     u8 hci_ver, u8 hci_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	for (i = 0; i < ARRAY_SIZE(ic_id_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		if ((ic_id_table[i].match_flags & IC_MATCH_FL_LMPSUBV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		    (ic_id_table[i].lmp_subver != lmp_subver))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIREV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		    (ic_id_table[i].hci_rev != hci_rev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIVER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		    (ic_id_table[i].hci_ver != hci_ver))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIBUS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		    (ic_id_table[i].hci_bus != hci_bus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	if (i >= ARRAY_SIZE(ic_id_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	return &ic_id_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			     HCI_INIT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		rtl_dev_err(hdev, "HCI_OP_READ_LOCAL_VERSION failed (%ld)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			    PTR_ERR(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	if (skb->len != sizeof(struct hci_rp_read_local_version)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		rtl_dev_err(hdev, "HCI_OP_READ_LOCAL_VERSION event length mismatch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		return ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	struct rtl_rom_version_evt *rom_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	/* Read RTL ROM version command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		rtl_dev_err(hdev, "Read ROM version failed (%ld)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			    PTR_ERR(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		return PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	if (skb->len != sizeof(*rom_version)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		rtl_dev_err(hdev, "version event length mismatch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	rom_version = (struct rtl_rom_version_evt *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	rtl_dev_info(hdev, "rom_version status=%x version=%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		     rom_version->status, rom_version->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	*version = rom_version->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int rtlbt_parse_firmware(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 				struct btrtl_device_info *btrtl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 				unsigned char **_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	static const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	struct rtl_epatch_header *epatch_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	size_t min_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	u8 opcode, length, data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	int project_id = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	const unsigned char *fwptr, *chip_id_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	const unsigned char *patch_length_base, *patch_offset_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	u32 patch_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	u16 patch_length, num_patches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		__u16 lmp_subver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		__u8 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	} project_id_to_lmp_subver[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		{ RTL_ROM_LMP_8723A, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		{ RTL_ROM_LMP_8723B, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		{ RTL_ROM_LMP_8821A, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		{ RTL_ROM_LMP_8761A, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		{ RTL_ROM_LMP_8822B, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		{ RTL_ROM_LMP_8723B, 9 },	/* 8723D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		{ RTL_ROM_LMP_8821A, 10 },	/* 8821C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		{ RTL_ROM_LMP_8822B, 13 },	/* 8822C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		{ RTL_ROM_LMP_8761A, 14 },	/* 8761B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		{ RTL_ROM_LMP_8852A, 20 },	/* 8852B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	if (btrtl_dev->fw_len < min_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	fwptr = btrtl_dev->fw_data + btrtl_dev->fw_len - sizeof(extension_sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		rtl_dev_err(hdev, "extension section signature mismatch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	/* Loop from the end of the firmware parsing instructions, until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	 * we find an instruction that identifies the "project ID" for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	 * hardware supported by this firwmare file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	 * Once we have that, we double-check that that project_id is suitable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	 * for the hardware we are working with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	while (fwptr >= btrtl_dev->fw_data + (sizeof(*epatch_info) + 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		opcode = *--fwptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		length = *--fwptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		data = *--fwptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		BT_DBG("check op=%x len=%x data=%x", opcode, length, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		if (opcode == 0xff) /* EOF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		if (length == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			rtl_dev_err(hdev, "found instruction with length 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		if (opcode == 0 && length == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			project_id = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		fwptr -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	if (project_id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		rtl_dev_err(hdev, "failed to find version instruction");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	/* Find project_id in table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	for (i = 0; i < ARRAY_SIZE(project_id_to_lmp_subver); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		if (project_id == project_id_to_lmp_subver[i].id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	if (i >= ARRAY_SIZE(project_id_to_lmp_subver)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		rtl_dev_err(hdev, "unknown project id %d", project_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	if (btrtl_dev->ic_info->lmp_subver !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 				project_id_to_lmp_subver[i].lmp_subver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		rtl_dev_err(hdev, "firmware is for %x but this is a %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			    project_id_to_lmp_subver[i].lmp_subver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			    btrtl_dev->ic_info->lmp_subver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	epatch_info = (struct rtl_epatch_header *)btrtl_dev->fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		rtl_dev_err(hdev, "bad EPATCH signature");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	num_patches = le16_to_cpu(epatch_info->num_patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	BT_DBG("fw_version=%x, num_patches=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	       le32_to_cpu(epatch_info->fw_version), num_patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	/* After the rtl_epatch_header there is a funky patch metadata section.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	 * Assuming 2 patches, the layout is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	 * ChipID1 ChipID2 PatchLength1 PatchLength2 PatchOffset1 PatchOffset2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	 * Find the right patch for this chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	min_size += 8 * num_patches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	if (btrtl_dev->fw_len < min_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	chip_id_base = btrtl_dev->fw_data + sizeof(struct rtl_epatch_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	patch_length_base = chip_id_base + (sizeof(u16) * num_patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	patch_offset_base = patch_length_base + (sizeof(u16) * num_patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	for (i = 0; i < num_patches; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		u16 chip_id = get_unaligned_le16(chip_id_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 						 (i * sizeof(u16)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		if (chip_id == btrtl_dev->rom_version + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			patch_length = get_unaligned_le16(patch_length_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 							  (i * sizeof(u16)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			patch_offset = get_unaligned_le32(patch_offset_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 							  (i * sizeof(u32)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	if (!patch_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		rtl_dev_err(hdev, "didn't find patch for chip id %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 			    btrtl_dev->rom_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	min_size = patch_offset + patch_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	if (btrtl_dev->fw_len < min_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	/* Copy the firmware into a new buffer and write the version at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	 * the end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	len = patch_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	buf = kvmalloc(patch_length, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	memcpy(buf, btrtl_dev->fw_data + patch_offset, patch_length - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	*_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static int rtl_download_firmware(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 				 const unsigned char *data, int fw_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	struct rtl_download_cmd *dl_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	int frag_num = fw_len / RTL_FRAG_LEN + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	int frag_len = RTL_FRAG_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	struct hci_rp_read_local_version *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	if (!dl_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	for (i = 0; i < frag_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		BT_DBG("download fw (%d/%d)", i, frag_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		if (i > 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			dl_cmd->index = (i & 0x7f) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			dl_cmd->index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		if (i == (frag_num - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			dl_cmd->index |= 0x80; /* data end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			frag_len = fw_len % RTL_FRAG_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		memcpy(dl_cmd->data, data, frag_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		/* Send download command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 				     HCI_INIT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			rtl_dev_err(hdev, "download fw command failed (%ld)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 				    PTR_ERR(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			ret = PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		if (skb->len != sizeof(struct rtl_download_response)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 			rtl_dev_err(hdev, "download fw event length mismatch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		data += RTL_FRAG_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	skb = btrtl_read_local_version(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		ret = PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		rtl_dev_err(hdev, "read local version failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	rp = (struct hci_rp_read_local_version *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	rtl_dev_info(hdev, "fw version 0x%04x%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		     __le16_to_cpu(rp->hci_rev), __le16_to_cpu(rp->lmp_subver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	kfree(dl_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static int rtl_load_file(struct hci_dev *hdev, const char *name, u8 **buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	const struct firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	rtl_dev_info(hdev, "loading %s", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	ret = request_firmware(&fw, name, &hdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	ret = fw->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	*buff = kvmalloc(fw->size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	if (*buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		memcpy(*buff, fw->data, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static int btrtl_setup_rtl8723a(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 				struct btrtl_device_info *btrtl_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	if (btrtl_dev->fw_len < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	/* Check that the firmware doesn't have the epatch signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	 * (which is only for RTL8723B and newer).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE, 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		rtl_dev_err(hdev, "unexpected EPATCH signature!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	return rtl_download_firmware(hdev, btrtl_dev->fw_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 				     btrtl_dev->fw_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static int btrtl_setup_rtl8723b(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 				struct btrtl_device_info *btrtl_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	unsigned char *fw_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	u8 *tbuff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	ret = rtlbt_parse_firmware(hdev, btrtl_dev, &fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	if (btrtl_dev->cfg_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		tbuff = kvzalloc(ret + btrtl_dev->cfg_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		if (!tbuff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		memcpy(tbuff, fw_data, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		kvfree(fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		memcpy(tbuff + ret, btrtl_dev->cfg_data, btrtl_dev->cfg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		ret += btrtl_dev->cfg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		fw_data = tbuff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	rtl_dev_info(hdev, "cfg_sz %d, total sz %d", btrtl_dev->cfg_len, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	ret = rtl_download_firmware(hdev, fw_data, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	kvfree(fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) void btrtl_free(struct btrtl_device_info *btrtl_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	kvfree(btrtl_dev->fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	kvfree(btrtl_dev->cfg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	kfree(btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) EXPORT_SYMBOL_GPL(btrtl_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 					   const char *postfix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	struct btrtl_device_info *btrtl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	struct hci_rp_read_local_version *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	char cfg_name[40];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	u16 hci_rev, lmp_subver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	u8 hci_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	if (!btrtl_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		goto err_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	skb = btrtl_read_local_version(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		ret = PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	resp = (struct hci_rp_read_local_version *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	rtl_dev_info(hdev, "examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x lmp_subver=%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		     resp->hci_ver, resp->hci_rev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		     resp->lmp_ver, resp->lmp_subver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	hci_ver = resp->hci_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	hci_rev = le16_to_cpu(resp->hci_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	lmp_subver = le16_to_cpu(resp->lmp_subver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 					    hdev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	if (!btrtl_dev->ic_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		rtl_dev_info(hdev, "unknown IC info, lmp subver %04x, hci rev %04x, hci ver %04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 			    lmp_subver, hci_rev, hci_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		return btrtl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	if (btrtl_dev->ic_info->has_rom_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		ret = rtl_read_rom_version(hdev, &btrtl_dev->rom_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 			goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	btrtl_dev->fw_len = rtl_load_file(hdev, btrtl_dev->ic_info->fw_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 					  &btrtl_dev->fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	if (btrtl_dev->fw_len < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		rtl_dev_err(hdev, "firmware file %s not found",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 			    btrtl_dev->ic_info->fw_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		ret = btrtl_dev->fw_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	if (btrtl_dev->ic_info->cfg_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		if (postfix) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 			snprintf(cfg_name, sizeof(cfg_name), "%s-%s.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 				 btrtl_dev->ic_info->cfg_name, postfix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 			snprintf(cfg_name, sizeof(cfg_name), "%s.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 				 btrtl_dev->ic_info->cfg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		btrtl_dev->cfg_len = rtl_load_file(hdev, cfg_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 						   &btrtl_dev->cfg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		if (btrtl_dev->ic_info->config_needed &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 		    btrtl_dev->cfg_len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 			rtl_dev_err(hdev, "mandatory config file %s not found",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 				    btrtl_dev->ic_info->cfg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 			ret = btrtl_dev->cfg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 			goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	return btrtl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	btrtl_free(btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) err_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) EXPORT_SYMBOL_GPL(btrtl_initialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) int btrtl_download_firmware(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 			    struct btrtl_device_info *btrtl_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	/* Match a set of subver values that correspond to stock firmware,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	 * which is not compatible with standard btusb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	 * If matched, upload an alternative firmware that does conform to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	 * standard btusb. Once that firmware is uploaded, the subver changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	 * to a different value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	if (!btrtl_dev->ic_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 		rtl_dev_info(hdev, "assuming no firmware upload needed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	switch (btrtl_dev->ic_info->lmp_subver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	case RTL_ROM_LMP_8723A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	case RTL_ROM_LMP_3499:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		return btrtl_setup_rtl8723a(hdev, btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	case RTL_ROM_LMP_8723B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	case RTL_ROM_LMP_8821A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	case RTL_ROM_LMP_8761A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	case RTL_ROM_LMP_8822B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	case RTL_ROM_LMP_8852A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		return btrtl_setup_rtl8723b(hdev, btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		rtl_dev_info(hdev, "assuming no firmware upload needed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) EXPORT_SYMBOL_GPL(btrtl_download_firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) int btrtl_setup_realtek(struct hci_dev *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	struct btrtl_device_info *btrtl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	btrtl_dev = btrtl_initialize(hdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	if (IS_ERR(btrtl_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		return PTR_ERR(btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	ret = btrtl_download_firmware(hdev, btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	btrtl_free(btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	/* Enable controller to do both LE scan and BR/EDR inquiry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	 * simultaneously.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) EXPORT_SYMBOL_GPL(btrtl_setup_realtek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int btrtl_shutdown_realtek(struct hci_dev *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	/* According to the vendor driver, BT must be reset on close to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	 * firmware crash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		ret = PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 		bt_dev_err(hdev, "HCI reset during shutdown failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) EXPORT_SYMBOL_GPL(btrtl_shutdown_realtek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static unsigned int btrtl_convert_baudrate(u32 device_baudrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	switch (device_baudrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	case 0x0252a00a:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 		return 230400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	case 0x05f75004:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		return 921600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	case 0x00005004:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 		return 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	case 0x04928002:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	case 0x01128002:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 		return 1500000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	case 0x00005002:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		return 2000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	case 0x0000b001:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		return 2500000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	case 0x04928001:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 		return 3000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	case 0x052a6001:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		return 3500000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	case 0x00005001:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		return 4000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	case 0x0252c014:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 		return 115200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) int btrtl_get_uart_settings(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 			    struct btrtl_device_info *btrtl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 			    unsigned int *controller_baudrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 			    u32 *device_baudrate, bool *flow_control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	struct rtl_vendor_config *config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	struct rtl_vendor_config_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	int i, total_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	total_data_len = btrtl_dev->cfg_len - sizeof(*config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	if (total_data_len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 		rtl_dev_warn(hdev, "no config loaded");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	config = (struct rtl_vendor_config *)btrtl_dev->cfg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	if (le32_to_cpu(config->signature) != RTL_CONFIG_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		rtl_dev_err(hdev, "invalid config magic");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	if (total_data_len < le16_to_cpu(config->total_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 		rtl_dev_err(hdev, "config is too short");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	for (i = 0; i < total_data_len; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 		entry = ((void *)config->entry) + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 		switch (le16_to_cpu(entry->offset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 		case 0xc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 			if (entry->len < sizeof(*device_baudrate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 				rtl_dev_err(hdev, "invalid UART config entry");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 			*device_baudrate = get_unaligned_le32(entry->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 			*controller_baudrate = btrtl_convert_baudrate(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 							*device_baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 			if (entry->len >= 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 				*flow_control = !!(entry->data[12] & BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 				*flow_control = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 			found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 			rtl_dev_dbg(hdev, "skipping config entry 0x%x (len %u)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 				   le16_to_cpu(entry->offset), entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		i += sizeof(*entry) + entry->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 		rtl_dev_err(hdev, "no UART config entry found");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	rtl_dev_dbg(hdev, "device baudrate = 0x%08x", *device_baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	rtl_dev_dbg(hdev, "controller baudrate = %u", *controller_baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	rtl_dev_dbg(hdev, "flow control %d", *flow_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) EXPORT_SYMBOL_GPL(btrtl_get_uart_settings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) MODULE_VERSION(VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) MODULE_FIRMWARE("rtl_bt/rtl8723a_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) MODULE_FIRMWARE("rtl_bt/rtl8723b_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) MODULE_FIRMWARE("rtl_bt/rtl8723b_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) MODULE_FIRMWARE("rtl_bt/rtl8723bs_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) MODULE_FIRMWARE("rtl_bt/rtl8723bs_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) MODULE_FIRMWARE("rtl_bt/rtl8723ds_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) MODULE_FIRMWARE("rtl_bt/rtl8723ds_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) MODULE_FIRMWARE("rtl_bt/rtl8761a_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) MODULE_FIRMWARE("rtl_bt/rtl8761a_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) MODULE_FIRMWARE("rtl_bt/rtl8821a_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) MODULE_FIRMWARE("rtl_bt/rtl8821a_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) MODULE_FIRMWARE("rtl_bt/rtl8822b_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) MODULE_FIRMWARE("rtl_bt/rtl8822b_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) MODULE_FIRMWARE("rtl_bt/rtl8852bu_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) MODULE_FIRMWARE("rtl_bt/rtl8852bu_config.bin");