32
32
#define RTL_ROM_LMP_8851B 0x8851
33
33
#define RTL_CONFIG_MAGIC 0x8723ab55
34
34
35
+ #define RTL_VSC_OP_COREDUMP 0xfcff
36
+
35
37
#define IC_MATCH_FL_LMPSUBV (1 << 0)
36
38
#define IC_MATCH_FL_HCIREV (1 << 1)
37
39
#define IC_MATCH_FL_HCIVER (1 << 2)
@@ -81,6 +83,7 @@ struct id_table {
81
83
bool has_msft_ext ;
82
84
char * fw_name ;
83
85
char * cfg_name ;
86
+ char * hw_info ;
84
87
};
85
88
86
89
struct btrtl_device_info {
@@ -102,21 +105,24 @@ static const struct id_table ic_id_table[] = {
102
105
.config_needed = false,
103
106
.has_rom_version = false,
104
107
.fw_name = "rtl_bt/rtl8723a_fw.bin" ,
105
- .cfg_name = NULL },
108
+ .cfg_name = NULL ,
109
+ .hw_info = "rtl8723au" },
106
110
107
111
/* 8723BS */
108
112
{ IC_INFO (RTL_ROM_LMP_8723B , 0xb , 0x6 , HCI_UART ),
109
113
.config_needed = true,
110
114
.has_rom_version = true,
111
115
.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" },
113
118
114
119
/* 8723B */
115
120
{ IC_INFO (RTL_ROM_LMP_8723B , 0xb , 0x6 , HCI_USB ),
116
121
.config_needed = false,
117
122
.has_rom_version = true,
118
123
.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" },
120
126
121
127
/* 8723CS-CG */
122
128
{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
@@ -127,7 +133,8 @@ static const struct id_table ic_id_table[] = {
127
133
.config_needed = true,
128
134
.has_rom_version = true,
129
135
.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" },
131
138
132
139
/* 8723CS-VF */
133
140
{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
@@ -138,7 +145,8 @@ static const struct id_table ic_id_table[] = {
138
145
.config_needed = true,
139
146
.has_rom_version = true,
140
147
.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" },
142
150
143
151
/* 8723CS-XX */
144
152
{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
@@ -149,138 +157,156 @@ static const struct id_table ic_id_table[] = {
149
157
.config_needed = true,
150
158
.has_rom_version = true,
151
159
.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" },
153
162
154
163
/* 8723D */
155
164
{ IC_INFO (RTL_ROM_LMP_8723B , 0xd , 0x8 , HCI_USB ),
156
165
.config_needed = true,
157
166
.has_rom_version = true,
158
167
.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" },
160
170
161
171
/* 8723DS */
162
172
{ IC_INFO (RTL_ROM_LMP_8723B , 0xd , 0x8 , HCI_UART ),
163
173
.config_needed = true,
164
174
.has_rom_version = true,
165
175
.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" },
167
178
168
179
/* 8821A */
169
180
{ IC_INFO (RTL_ROM_LMP_8821A , 0xa , 0x6 , HCI_USB ),
170
181
.config_needed = false,
171
182
.has_rom_version = true,
172
183
.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" },
174
186
175
187
/* 8821C */
176
188
{ IC_INFO (RTL_ROM_LMP_8821A , 0xc , 0x8 , HCI_USB ),
177
189
.config_needed = false,
178
190
.has_rom_version = true,
179
191
.has_msft_ext = true,
180
192
.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" },
182
195
183
196
/* 8821CS */
184
197
{ IC_INFO (RTL_ROM_LMP_8821A , 0xc , 0x8 , HCI_UART ),
185
198
.config_needed = true,
186
199
.has_rom_version = true,
187
200
.has_msft_ext = true,
188
201
.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" },
190
204
191
205
/* 8761A */
192
206
{ IC_INFO (RTL_ROM_LMP_8761A , 0xa , 0x6 , HCI_USB ),
193
207
.config_needed = false,
194
208
.has_rom_version = true,
195
209
.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" },
197
212
198
213
/* 8761B */
199
214
{ IC_INFO (RTL_ROM_LMP_8761A , 0xb , 0xa , HCI_UART ),
200
215
.config_needed = false,
201
216
.has_rom_version = true,
202
217
.has_msft_ext = true,
203
218
.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" },
205
221
206
222
/* 8761BU */
207
223
{ IC_INFO (RTL_ROM_LMP_8761A , 0xb , 0xa , HCI_USB ),
208
224
.config_needed = false,
209
225
.has_rom_version = true,
210
226
.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" },
212
229
213
230
/* 8822C with UART interface */
214
231
{ IC_INFO (RTL_ROM_LMP_8822B , 0xc , 0x8 , HCI_UART ),
215
232
.config_needed = true,
216
233
.has_rom_version = true,
217
234
.has_msft_ext = true,
218
235
.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" },
220
238
221
239
/* 8822C with UART interface */
222
240
{ IC_INFO (RTL_ROM_LMP_8822B , 0xc , 0xa , HCI_UART ),
223
241
.config_needed = true,
224
242
.has_rom_version = true,
225
243
.has_msft_ext = true,
226
244
.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" },
228
247
229
248
/* 8822C with USB interface */
230
249
{ IC_INFO (RTL_ROM_LMP_8822B , 0xc , 0xa , HCI_USB ),
231
250
.config_needed = false,
232
251
.has_rom_version = true,
233
252
.has_msft_ext = true,
234
253
.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" },
236
256
237
257
/* 8822B */
238
258
{ IC_INFO (RTL_ROM_LMP_8822B , 0xb , 0x7 , HCI_USB ),
239
259
.config_needed = true,
240
260
.has_rom_version = true,
241
261
.has_msft_ext = true,
242
262
.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" },
244
265
245
266
/* 8852A */
246
267
{ IC_INFO (RTL_ROM_LMP_8852A , 0xa , 0xb , HCI_USB ),
247
268
.config_needed = false,
248
269
.has_rom_version = true,
249
270
.has_msft_ext = true,
250
271
.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" },
252
274
253
275
/* 8852B with UART interface */
254
276
{ IC_INFO (RTL_ROM_LMP_8852A , 0xb , 0xb , HCI_UART ),
255
277
.config_needed = true,
256
278
.has_rom_version = true,
257
279
.has_msft_ext = true,
258
280
.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" },
260
283
261
284
/* 8852B */
262
285
{ IC_INFO (RTL_ROM_LMP_8852A , 0xb , 0xb , HCI_USB ),
263
286
.config_needed = false,
264
287
.has_rom_version = true,
265
288
.has_msft_ext = true,
266
289
.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" },
268
292
269
293
/* 8852C */
270
294
{ IC_INFO (RTL_ROM_LMP_8852A , 0xc , 0xc , HCI_USB ),
271
295
.config_needed = false,
272
296
.has_rom_version = true,
273
297
.has_msft_ext = true,
274
298
.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" },
276
301
277
302
/* 8851B */
278
303
{ IC_INFO (RTL_ROM_LMP_8851B , 0xb , 0xc , HCI_USB ),
279
304
.config_needed = false,
280
305
.has_rom_version = true,
281
306
.has_msft_ext = false,
282
307
.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" },
284
310
};
285
311
286
312
static 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,
590
616
unsigned char * * _buf )
591
617
{
592
618
static const u8 extension_sig [] = { 0x51 , 0x04 , 0xfd , 0x77 };
619
+ struct btrealtek_data * coredump_info = hci_get_priv (hdev );
593
620
struct rtl_epatch_header * epatch_info ;
594
621
unsigned char * buf ;
595
622
int i , len ;
@@ -705,8 +732,10 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
705
732
706
733
epatch_info = (struct rtl_epatch_header * )btrtl_dev -> fw_data ;
707
734
num_patches = le16_to_cpu (epatch_info -> num_patches );
735
+
708
736
BT_DBG ("fw_version=%x, num_patches=%d" ,
709
737
le32_to_cpu (epatch_info -> fw_version ), num_patches );
738
+ coredump_info -> rtl_dump .fw_version = le32_to_cpu (epatch_info -> fw_version );
710
739
711
740
/* After the rtl_epatch_header there is a funky patch metadata section.
712
741
* Assuming 2 patches, the layout is:
@@ -903,6 +932,53 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev,
903
932
return ret ;
904
933
}
905
934
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
+
906
982
static bool rtl_has_chip_type (u16 lmp_subver )
907
983
{
908
984
switch (lmp_subver ) {
@@ -964,6 +1040,7 @@ EXPORT_SYMBOL_GPL(btrtl_free);
964
1040
struct btrtl_device_info * btrtl_initialize (struct hci_dev * hdev ,
965
1041
const char * postfix )
966
1042
{
1043
+ struct btrealtek_data * coredump_info = hci_get_priv (hdev );
967
1044
struct btrtl_device_info * btrtl_dev ;
968
1045
struct sk_buff * skb ;
969
1046
struct hci_rp_read_local_version * resp ;
@@ -1113,6 +1190,9 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
1113
1190
if (btrtl_dev -> ic_info -> has_msft_ext )
1114
1191
hci_set_msft_opcode (hdev , 0xFCF0 );
1115
1192
1193
+ if (btrtl_dev -> ic_info )
1194
+ coredump_info -> rtl_dump .controller = btrtl_dev -> ic_info -> hw_info ;
1195
+
1116
1196
return btrtl_dev ;
1117
1197
1118
1198
err_free :
@@ -1125,6 +1205,8 @@ EXPORT_SYMBOL_GPL(btrtl_initialize);
1125
1205
int btrtl_download_firmware (struct hci_dev * hdev ,
1126
1206
struct btrtl_device_info * btrtl_dev )
1127
1207
{
1208
+ int err = 0 ;
1209
+
1128
1210
/* Match a set of subver values that correspond to stock firmware,
1129
1211
* which is not compatible with standard btusb.
1130
1212
* If matched, upload an alternative firmware that does conform to
@@ -1133,24 +1215,33 @@ int btrtl_download_firmware(struct hci_dev *hdev,
1133
1215
*/
1134
1216
if (!btrtl_dev -> ic_info ) {
1135
1217
rtl_dev_info (hdev , "assuming no firmware upload needed" );
1136
- return 0 ;
1218
+ err = 0 ;
1219
+ goto done ;
1137
1220
}
1138
1221
1139
1222
switch (btrtl_dev -> ic_info -> lmp_subver ) {
1140
1223
case RTL_ROM_LMP_8723A :
1141
- return btrtl_setup_rtl8723a (hdev , btrtl_dev );
1224
+ err = btrtl_setup_rtl8723a (hdev , btrtl_dev );
1225
+ break ;
1142
1226
case RTL_ROM_LMP_8723B :
1143
1227
case RTL_ROM_LMP_8821A :
1144
1228
case RTL_ROM_LMP_8761A :
1145
1229
case RTL_ROM_LMP_8822B :
1146
1230
case RTL_ROM_LMP_8852A :
1147
1231
case RTL_ROM_LMP_8703B :
1148
1232
case RTL_ROM_LMP_8851B :
1149
- return btrtl_setup_rtl8723b (hdev , btrtl_dev );
1233
+ err = btrtl_setup_rtl8723b (hdev , btrtl_dev );
1234
+ break ;
1150
1235
default :
1151
1236
rtl_dev_info (hdev , "assuming no firmware upload needed" );
1152
- return 0 ;
1237
+ break ;
1153
1238
}
1239
+
1240
+ done :
1241
+ if (!err )
1242
+ err = btrtl_register_devcoredump_support (hdev );
1243
+
1244
+ return err ;
1154
1245
}
1155
1246
EXPORT_SYMBOL_GPL (btrtl_download_firmware );
1156
1247
0 commit comments