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