3232#define RTL_ROM_LMP_8851B 0x8851
3333#define RTL_CONFIG_MAGIC 0x8723ab55
3434
35+ #define RTL_VSC_OP_COREDUMP 0xfcff
36+
3537#define IC_MATCH_FL_LMPSUBV (1 << 0)
3638#define IC_MATCH_FL_HCIREV (1 << 1)
3739#define IC_MATCH_FL_HCIVER (1 << 2)
@@ -81,6 +83,7 @@ struct id_table {
8183 bool has_msft_ext ;
8284 char * fw_name ;
8385 char * cfg_name ;
86+ char * hw_info ;
8487};
8588
8689struct btrtl_device_info {
@@ -102,21 +105,24 @@ static const struct id_table ic_id_table[] = {
102105 .config_needed = false,
103106 .has_rom_version = false,
104107 .fw_name = "rtl_bt/rtl8723a_fw.bin" ,
105- .cfg_name = NULL },
108+ .cfg_name = NULL ,
109+ .hw_info = "rtl8723au" },
106110
107111 /* 8723BS */
108112 { IC_INFO (RTL_ROM_LMP_8723B , 0xb , 0x6 , HCI_UART ),
109113 .config_needed = true,
110114 .has_rom_version = true,
111115 .fw_name = "rtl_bt/rtl8723bs_fw.bin" ,
112- .cfg_name = "rtl_bt/rtl8723bs_config" },
116+ .cfg_name = "rtl_bt/rtl8723bs_config" ,
117+ .hw_info = "rtl8723bs" },
113118
114119 /* 8723B */
115120 { IC_INFO (RTL_ROM_LMP_8723B , 0xb , 0x6 , HCI_USB ),
116121 .config_needed = false,
117122 .has_rom_version = true,
118123 .fw_name = "rtl_bt/rtl8723b_fw.bin" ,
119- .cfg_name = "rtl_bt/rtl8723b_config" },
124+ .cfg_name = "rtl_bt/rtl8723b_config" ,
125+ .hw_info = "rtl8723bu" },
120126
121127 /* 8723CS-CG */
122128 { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
@@ -127,7 +133,8 @@ static const struct id_table ic_id_table[] = {
127133 .config_needed = true,
128134 .has_rom_version = true,
129135 .fw_name = "rtl_bt/rtl8723cs_cg_fw.bin" ,
130- .cfg_name = "rtl_bt/rtl8723cs_cg_config" },
136+ .cfg_name = "rtl_bt/rtl8723cs_cg_config" ,
137+ .hw_info = "rtl8723cs-cg" },
131138
132139 /* 8723CS-VF */
133140 { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
@@ -138,7 +145,8 @@ static const struct id_table ic_id_table[] = {
138145 .config_needed = true,
139146 .has_rom_version = true,
140147 .fw_name = "rtl_bt/rtl8723cs_vf_fw.bin" ,
141- .cfg_name = "rtl_bt/rtl8723cs_vf_config" },
148+ .cfg_name = "rtl_bt/rtl8723cs_vf_config" ,
149+ .hw_info = "rtl8723cs-vf" },
142150
143151 /* 8723CS-XX */
144152 { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
@@ -149,138 +157,156 @@ static const struct id_table ic_id_table[] = {
149157 .config_needed = true,
150158 .has_rom_version = true,
151159 .fw_name = "rtl_bt/rtl8723cs_xx_fw.bin" ,
152- .cfg_name = "rtl_bt/rtl8723cs_xx_config" },
160+ .cfg_name = "rtl_bt/rtl8723cs_xx_config" ,
161+ .hw_info = "rtl8723cs" },
153162
154163 /* 8723D */
155164 { IC_INFO (RTL_ROM_LMP_8723B , 0xd , 0x8 , HCI_USB ),
156165 .config_needed = true,
157166 .has_rom_version = true,
158167 .fw_name = "rtl_bt/rtl8723d_fw.bin" ,
159- .cfg_name = "rtl_bt/rtl8723d_config" },
168+ .cfg_name = "rtl_bt/rtl8723d_config" ,
169+ .hw_info = "rtl8723du" },
160170
161171 /* 8723DS */
162172 { IC_INFO (RTL_ROM_LMP_8723B , 0xd , 0x8 , HCI_UART ),
163173 .config_needed = true,
164174 .has_rom_version = true,
165175 .fw_name = "rtl_bt/rtl8723ds_fw.bin" ,
166- .cfg_name = "rtl_bt/rtl8723ds_config" },
176+ .cfg_name = "rtl_bt/rtl8723ds_config" ,
177+ .hw_info = "rtl8723ds" },
167178
168179 /* 8821A */
169180 { IC_INFO (RTL_ROM_LMP_8821A , 0xa , 0x6 , HCI_USB ),
170181 .config_needed = false,
171182 .has_rom_version = true,
172183 .fw_name = "rtl_bt/rtl8821a_fw.bin" ,
173- .cfg_name = "rtl_bt/rtl8821a_config" },
184+ .cfg_name = "rtl_bt/rtl8821a_config" ,
185+ .hw_info = "rtl8821au" },
174186
175187 /* 8821C */
176188 { IC_INFO (RTL_ROM_LMP_8821A , 0xc , 0x8 , HCI_USB ),
177189 .config_needed = false,
178190 .has_rom_version = true,
179191 .has_msft_ext = true,
180192 .fw_name = "rtl_bt/rtl8821c_fw.bin" ,
181- .cfg_name = "rtl_bt/rtl8821c_config" },
193+ .cfg_name = "rtl_bt/rtl8821c_config" ,
194+ .hw_info = "rtl8821cu" },
182195
183196 /* 8821CS */
184197 { IC_INFO (RTL_ROM_LMP_8821A , 0xc , 0x8 , HCI_UART ),
185198 .config_needed = true,
186199 .has_rom_version = true,
187200 .has_msft_ext = true,
188201 .fw_name = "rtl_bt/rtl8821cs_fw.bin" ,
189- .cfg_name = "rtl_bt/rtl8821cs_config" },
202+ .cfg_name = "rtl_bt/rtl8821cs_config" ,
203+ .hw_info = "rtl8821cs" },
190204
191205 /* 8761A */
192206 { IC_INFO (RTL_ROM_LMP_8761A , 0xa , 0x6 , HCI_USB ),
193207 .config_needed = false,
194208 .has_rom_version = true,
195209 .fw_name = "rtl_bt/rtl8761a_fw.bin" ,
196- .cfg_name = "rtl_bt/rtl8761a_config" },
210+ .cfg_name = "rtl_bt/rtl8761a_config" ,
211+ .hw_info = "rtl8761au" },
197212
198213 /* 8761B */
199214 { IC_INFO (RTL_ROM_LMP_8761A , 0xb , 0xa , HCI_UART ),
200215 .config_needed = false,
201216 .has_rom_version = true,
202217 .has_msft_ext = true,
203218 .fw_name = "rtl_bt/rtl8761b_fw.bin" ,
204- .cfg_name = "rtl_bt/rtl8761b_config" },
219+ .cfg_name = "rtl_bt/rtl8761b_config" ,
220+ .hw_info = "rtl8761btv" },
205221
206222 /* 8761BU */
207223 { IC_INFO (RTL_ROM_LMP_8761A , 0xb , 0xa , HCI_USB ),
208224 .config_needed = false,
209225 .has_rom_version = true,
210226 .fw_name = "rtl_bt/rtl8761bu_fw.bin" ,
211- .cfg_name = "rtl_bt/rtl8761bu_config" },
227+ .cfg_name = "rtl_bt/rtl8761bu_config" ,
228+ .hw_info = "rtl8761bu" },
212229
213230 /* 8822C with UART interface */
214231 { IC_INFO (RTL_ROM_LMP_8822B , 0xc , 0x8 , HCI_UART ),
215232 .config_needed = true,
216233 .has_rom_version = true,
217234 .has_msft_ext = true,
218235 .fw_name = "rtl_bt/rtl8822cs_fw.bin" ,
219- .cfg_name = "rtl_bt/rtl8822cs_config" },
236+ .cfg_name = "rtl_bt/rtl8822cs_config" ,
237+ .hw_info = "rtl8822cs" },
220238
221239 /* 8822C with UART interface */
222240 { IC_INFO (RTL_ROM_LMP_8822B , 0xc , 0xa , HCI_UART ),
223241 .config_needed = true,
224242 .has_rom_version = true,
225243 .has_msft_ext = true,
226244 .fw_name = "rtl_bt/rtl8822cs_fw.bin" ,
227- .cfg_name = "rtl_bt/rtl8822cs_config" },
245+ .cfg_name = "rtl_bt/rtl8822cs_config" ,
246+ .hw_info = "rtl8822cs" },
228247
229248 /* 8822C with USB interface */
230249 { IC_INFO (RTL_ROM_LMP_8822B , 0xc , 0xa , HCI_USB ),
231250 .config_needed = false,
232251 .has_rom_version = true,
233252 .has_msft_ext = true,
234253 .fw_name = "rtl_bt/rtl8822cu_fw.bin" ,
235- .cfg_name = "rtl_bt/rtl8822cu_config" },
254+ .cfg_name = "rtl_bt/rtl8822cu_config" ,
255+ .hw_info = "rtl8822cu" },
236256
237257 /* 8822B */
238258 { IC_INFO (RTL_ROM_LMP_8822B , 0xb , 0x7 , HCI_USB ),
239259 .config_needed = true,
240260 .has_rom_version = true,
241261 .has_msft_ext = true,
242262 .fw_name = "rtl_bt/rtl8822b_fw.bin" ,
243- .cfg_name = "rtl_bt/rtl8822b_config" },
263+ .cfg_name = "rtl_bt/rtl8822b_config" ,
264+ .hw_info = "rtl8822bu" },
244265
245266 /* 8852A */
246267 { IC_INFO (RTL_ROM_LMP_8852A , 0xa , 0xb , HCI_USB ),
247268 .config_needed = false,
248269 .has_rom_version = true,
249270 .has_msft_ext = true,
250271 .fw_name = "rtl_bt/rtl8852au_fw.bin" ,
251- .cfg_name = "rtl_bt/rtl8852au_config" },
272+ .cfg_name = "rtl_bt/rtl8852au_config" ,
273+ .hw_info = "rtl8852au" },
252274
253275 /* 8852B with UART interface */
254276 { IC_INFO (RTL_ROM_LMP_8852A , 0xb , 0xb , HCI_UART ),
255277 .config_needed = true,
256278 .has_rom_version = true,
257279 .has_msft_ext = true,
258280 .fw_name = "rtl_bt/rtl8852bs_fw.bin" ,
259- .cfg_name = "rtl_bt/rtl8852bs_config" },
281+ .cfg_name = "rtl_bt/rtl8852bs_config" ,
282+ .hw_info = "rtl8852bs" },
260283
261284 /* 8852B */
262285 { IC_INFO (RTL_ROM_LMP_8852A , 0xb , 0xb , HCI_USB ),
263286 .config_needed = false,
264287 .has_rom_version = true,
265288 .has_msft_ext = true,
266289 .fw_name = "rtl_bt/rtl8852bu_fw.bin" ,
267- .cfg_name = "rtl_bt/rtl8852bu_config" },
290+ .cfg_name = "rtl_bt/rtl8852bu_config" ,
291+ .hw_info = "rtl8852bu" },
268292
269293 /* 8852C */
270294 { IC_INFO (RTL_ROM_LMP_8852A , 0xc , 0xc , HCI_USB ),
271295 .config_needed = false,
272296 .has_rom_version = true,
273297 .has_msft_ext = true,
274298 .fw_name = "rtl_bt/rtl8852cu_fw.bin" ,
275- .cfg_name = "rtl_bt/rtl8852cu_config" },
299+ .cfg_name = "rtl_bt/rtl8852cu_config" ,
300+ .hw_info = "rtl8852cu" },
276301
277302 /* 8851B */
278303 { IC_INFO (RTL_ROM_LMP_8851B , 0xb , 0xc , HCI_USB ),
279304 .config_needed = false,
280305 .has_rom_version = true,
281306 .has_msft_ext = false,
282307 .fw_name = "rtl_bt/rtl8851bu_fw.bin" ,
283- .cfg_name = "rtl_bt/rtl8851bu_config" },
308+ .cfg_name = "rtl_bt/rtl8851bu_config" ,
309+ .hw_info = "rtl8851bu" },
284310 };
285311
286312static const struct id_table * btrtl_match_ic (u16 lmp_subver , u16 hci_rev ,
@@ -590,6 +616,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
590616 unsigned char * * _buf )
591617{
592618 static const u8 extension_sig [] = { 0x51 , 0x04 , 0xfd , 0x77 };
619+ struct btrealtek_data * coredump_info = hci_get_priv (hdev );
593620 struct rtl_epatch_header * epatch_info ;
594621 unsigned char * buf ;
595622 int i , len ;
@@ -705,8 +732,10 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
705732
706733 epatch_info = (struct rtl_epatch_header * )btrtl_dev -> fw_data ;
707734 num_patches = le16_to_cpu (epatch_info -> num_patches );
735+
708736 BT_DBG ("fw_version=%x, num_patches=%d" ,
709737 le32_to_cpu (epatch_info -> fw_version ), num_patches );
738+ coredump_info -> rtl_dump .fw_version = le32_to_cpu (epatch_info -> fw_version );
710739
711740 /* After the rtl_epatch_header there is a funky patch metadata section.
712741 * Assuming 2 patches, the layout is:
@@ -903,6 +932,53 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev,
903932 return ret ;
904933}
905934
935+ static void btrtl_coredump (struct hci_dev * hdev )
936+ {
937+ static const u8 param [] = { 0x00 , 0x00 };
938+
939+ __hci_cmd_send (hdev , RTL_VSC_OP_COREDUMP , sizeof (param ), param );
940+ }
941+
942+ static void btrtl_dmp_hdr (struct hci_dev * hdev , struct sk_buff * skb )
943+ {
944+ struct btrealtek_data * coredump_info = hci_get_priv (hdev );
945+ char buf [80 ];
946+
947+ if (coredump_info -> rtl_dump .controller )
948+ snprintf (buf , sizeof (buf ), "Controller Name: %s\n" ,
949+ coredump_info -> rtl_dump .controller );
950+ else
951+ snprintf (buf , sizeof (buf ), "Controller Name: Unknown\n" );
952+ skb_put_data (skb , buf , strlen (buf ));
953+
954+ snprintf (buf , sizeof (buf ), "Firmware Version: 0x%X\n" ,
955+ coredump_info -> rtl_dump .fw_version );
956+ skb_put_data (skb , buf , strlen (buf ));
957+
958+ snprintf (buf , sizeof (buf ), "Driver: %s\n" , coredump_info -> rtl_dump .driver_name );
959+ skb_put_data (skb , buf , strlen (buf ));
960+
961+ snprintf (buf , sizeof (buf ), "Vendor: Realtek\n" );
962+ skb_put_data (skb , buf , strlen (buf ));
963+ }
964+
965+ static int btrtl_register_devcoredump_support (struct hci_dev * hdev )
966+ {
967+ int err ;
968+
969+ err = hci_devcd_register (hdev , btrtl_coredump , btrtl_dmp_hdr , NULL );
970+
971+ return err ;
972+ }
973+
974+ void btrtl_set_driver_name (struct hci_dev * hdev , const char * driver_name )
975+ {
976+ struct btrealtek_data * coredump_info = hci_get_priv (hdev );
977+
978+ coredump_info -> rtl_dump .driver_name = driver_name ;
979+ }
980+ EXPORT_SYMBOL_GPL (btrtl_set_driver_name );
981+
906982static bool rtl_has_chip_type (u16 lmp_subver )
907983{
908984 switch (lmp_subver ) {
@@ -964,6 +1040,7 @@ EXPORT_SYMBOL_GPL(btrtl_free);
9641040struct btrtl_device_info * btrtl_initialize (struct hci_dev * hdev ,
9651041 const char * postfix )
9661042{
1043+ struct btrealtek_data * coredump_info = hci_get_priv (hdev );
9671044 struct btrtl_device_info * btrtl_dev ;
9681045 struct sk_buff * skb ;
9691046 struct hci_rp_read_local_version * resp ;
@@ -1113,6 +1190,9 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
11131190 if (btrtl_dev -> ic_info -> has_msft_ext )
11141191 hci_set_msft_opcode (hdev , 0xFCF0 );
11151192
1193+ if (btrtl_dev -> ic_info )
1194+ coredump_info -> rtl_dump .controller = btrtl_dev -> ic_info -> hw_info ;
1195+
11161196 return btrtl_dev ;
11171197
11181198err_free :
@@ -1125,6 +1205,8 @@ EXPORT_SYMBOL_GPL(btrtl_initialize);
11251205int btrtl_download_firmware (struct hci_dev * hdev ,
11261206 struct btrtl_device_info * btrtl_dev )
11271207{
1208+ int err = 0 ;
1209+
11281210 /* Match a set of subver values that correspond to stock firmware,
11291211 * which is not compatible with standard btusb.
11301212 * If matched, upload an alternative firmware that does conform to
@@ -1133,24 +1215,33 @@ int btrtl_download_firmware(struct hci_dev *hdev,
11331215 */
11341216 if (!btrtl_dev -> ic_info ) {
11351217 rtl_dev_info (hdev , "assuming no firmware upload needed" );
1136- return 0 ;
1218+ err = 0 ;
1219+ goto done ;
11371220 }
11381221
11391222 switch (btrtl_dev -> ic_info -> lmp_subver ) {
11401223 case RTL_ROM_LMP_8723A :
1141- return btrtl_setup_rtl8723a (hdev , btrtl_dev );
1224+ err = btrtl_setup_rtl8723a (hdev , btrtl_dev );
1225+ break ;
11421226 case RTL_ROM_LMP_8723B :
11431227 case RTL_ROM_LMP_8821A :
11441228 case RTL_ROM_LMP_8761A :
11451229 case RTL_ROM_LMP_8822B :
11461230 case RTL_ROM_LMP_8852A :
11471231 case RTL_ROM_LMP_8703B :
11481232 case RTL_ROM_LMP_8851B :
1149- return btrtl_setup_rtl8723b (hdev , btrtl_dev );
1233+ err = btrtl_setup_rtl8723b (hdev , btrtl_dev );
1234+ break ;
11501235 default :
11511236 rtl_dev_info (hdev , "assuming no firmware upload needed" );
1152- return 0 ;
1237+ break ;
11531238 }
1239+
1240+ done :
1241+ if (!err )
1242+ err = btrtl_register_devcoredump_support (hdev );
1243+
1244+ return err ;
11541245}
11551246EXPORT_SYMBOL_GPL (btrtl_download_firmware );
11561247
0 commit comments