14
14
15
15
#define VERSION "0.1"
16
16
17
- int qca_read_soc_version (struct hci_dev * hdev , u32 * soc_version )
17
+ int qca_read_soc_version (struct hci_dev * hdev , u32 * soc_version ,
18
+ enum qca_btsoc_type soc_type )
18
19
{
19
20
struct sk_buff * skb ;
20
21
struct edl_event_hdr * edl ;
21
- struct rome_version * ver ;
22
+ struct qca_btsoc_version * ver ;
22
23
char cmd ;
23
24
int err = 0 ;
25
+ u8 event_type = HCI_EV_VENDOR ;
26
+ u8 rlen = sizeof (* edl ) + sizeof (* ver );
27
+ u8 rtype = EDL_APP_VER_RES_EVT ;
24
28
25
29
bt_dev_dbg (hdev , "QCA Version Request" );
26
30
31
+ /* Unlike other SoC's sending version command response as payload to
32
+ * VSE event. WCN3991 sends version command response as a payload to
33
+ * command complete event.
34
+ */
35
+ if (soc_type == QCA_WCN3991 ) {
36
+ event_type = 0 ;
37
+ rlen += 1 ;
38
+ rtype = EDL_PATCH_VER_REQ_CMD ;
39
+ }
40
+
27
41
cmd = EDL_PATCH_VER_REQ_CMD ;
28
42
skb = __hci_cmd_sync_ev (hdev , EDL_PATCH_CMD_OPCODE , EDL_PATCH_CMD_LEN ,
29
- & cmd , HCI_EV_VENDOR , HCI_INIT_TIMEOUT );
43
+ & cmd , event_type , HCI_INIT_TIMEOUT );
30
44
if (IS_ERR (skb )) {
31
45
err = PTR_ERR (skb );
32
46
bt_dev_err (hdev , "Reading QCA version information failed (%d)" ,
33
47
err );
34
48
return err ;
35
49
}
36
50
37
- if (skb -> len != sizeof ( * edl ) + sizeof ( * ver ) ) {
51
+ if (skb -> len != rlen ) {
38
52
bt_dev_err (hdev , "QCA Version size mismatch len %d" , skb -> len );
39
53
err = - EILSEQ ;
40
54
goto out ;
@@ -48,26 +62,29 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version)
48
62
}
49
63
50
64
if (edl -> cresp != EDL_CMD_REQ_RES_EVT ||
51
- edl -> rtype != EDL_APP_VER_RES_EVT ) {
65
+ edl -> rtype != rtype ) {
52
66
bt_dev_err (hdev , "QCA Wrong packet received %d %d" , edl -> cresp ,
53
67
edl -> rtype );
54
68
err = - EIO ;
55
69
goto out ;
56
70
}
57
71
58
- ver = (struct rome_version * )(edl -> data );
72
+ if (soc_type == QCA_WCN3991 )
73
+ memmove (& edl -> data , & edl -> data [1 ], sizeof (* ver ));
74
+
75
+ ver = (struct qca_btsoc_version * )(edl -> data );
59
76
60
77
BT_DBG ("%s: Product:0x%08x" , hdev -> name , le32_to_cpu (ver -> product_id ));
61
78
BT_DBG ("%s: Patch :0x%08x" , hdev -> name , le16_to_cpu (ver -> patch_ver ));
62
- BT_DBG ("%s: ROM :0x%08x" , hdev -> name , le16_to_cpu (ver -> rome_ver ));
79
+ BT_DBG ("%s: ROM :0x%08x" , hdev -> name , le16_to_cpu (ver -> rom_ver ));
63
80
BT_DBG ("%s: SOC :0x%08x" , hdev -> name , le32_to_cpu (ver -> soc_id ));
64
81
65
82
/* QCA chipset version can be decided by patch and SoC
66
83
* version, combination with upper 2 bytes from SoC
67
84
* and lower 2 bytes from patch will be used.
68
85
*/
69
86
* soc_version = (le32_to_cpu (ver -> soc_id ) << 16 ) |
70
- (le16_to_cpu (ver -> rome_ver ) & 0x0000ffff );
87
+ (le16_to_cpu (ver -> rom_ver ) & 0x0000ffff );
71
88
if (* soc_version == 0 )
72
89
err = - EILSEQ ;
73
90
@@ -121,7 +138,7 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
121
138
}
122
139
EXPORT_SYMBOL_GPL (qca_send_pre_shutdown_cmd );
123
140
124
- static void qca_tlv_check_data (struct rome_config * config ,
141
+ static void qca_tlv_check_data (struct qca_fw_config * config ,
125
142
const struct firmware * fw )
126
143
{
127
144
const u8 * data ;
@@ -140,8 +157,8 @@ static void qca_tlv_check_data(struct rome_config *config,
140
157
BT_DBG ("TLV Type\t\t : 0x%x" , type_len & 0x000000ff );
141
158
BT_DBG ("Length\t\t : %d bytes" , length );
142
159
143
- config -> dnld_mode = ROME_SKIP_EVT_NONE ;
144
- config -> dnld_type = ROME_SKIP_EVT_NONE ;
160
+ config -> dnld_mode = QCA_SKIP_EVT_NONE ;
161
+ config -> dnld_type = QCA_SKIP_EVT_NONE ;
145
162
146
163
switch (config -> type ) {
147
164
case TLV_TYPE_PATCH :
@@ -223,31 +240,45 @@ static void qca_tlv_check_data(struct rome_config *config,
223
240
}
224
241
225
242
static int qca_tlv_send_segment (struct hci_dev * hdev , int seg_size ,
226
- const u8 * data , enum rome_tlv_dnld_mode mode )
243
+ const u8 * data , enum qca_tlv_dnld_mode mode ,
244
+ enum qca_btsoc_type soc_type )
227
245
{
228
246
struct sk_buff * skb ;
229
247
struct edl_event_hdr * edl ;
230
248
struct tlv_seg_resp * tlv_resp ;
231
249
u8 cmd [MAX_SIZE_PER_TLV_SEGMENT + 2 ];
232
250
int err = 0 ;
251
+ u8 event_type = HCI_EV_VENDOR ;
252
+ u8 rlen = (sizeof (* edl ) + sizeof (* tlv_resp ));
253
+ u8 rtype = EDL_TVL_DNLD_RES_EVT ;
233
254
234
255
cmd [0 ] = EDL_PATCH_TLV_REQ_CMD ;
235
256
cmd [1 ] = seg_size ;
236
257
memcpy (cmd + 2 , data , seg_size );
237
258
238
- if (mode == ROME_SKIP_EVT_VSE_CC || mode == ROME_SKIP_EVT_VSE )
259
+ if (mode == QCA_SKIP_EVT_VSE_CC || mode == QCA_SKIP_EVT_VSE )
239
260
return __hci_cmd_send (hdev , EDL_PATCH_CMD_OPCODE , seg_size + 2 ,
240
261
cmd );
241
262
263
+ /* Unlike other SoC's sending version command response as payload to
264
+ * VSE event. WCN3991 sends version command response as a payload to
265
+ * command complete event.
266
+ */
267
+ if (soc_type == QCA_WCN3991 ) {
268
+ event_type = 0 ;
269
+ rlen = sizeof (* edl );
270
+ rtype = EDL_PATCH_TLV_REQ_CMD ;
271
+ }
272
+
242
273
skb = __hci_cmd_sync_ev (hdev , EDL_PATCH_CMD_OPCODE , seg_size + 2 , cmd ,
243
- HCI_EV_VENDOR , HCI_INIT_TIMEOUT );
274
+ event_type , HCI_INIT_TIMEOUT );
244
275
if (IS_ERR (skb )) {
245
276
err = PTR_ERR (skb );
246
277
bt_dev_err (hdev , "QCA Failed to send TLV segment (%d)" , err );
247
278
return err ;
248
279
}
249
280
250
- if (skb -> len != sizeof ( * edl ) + sizeof ( * tlv_resp ) ) {
281
+ if (skb -> len != rlen ) {
251
282
bt_dev_err (hdev , "QCA TLV response size mismatch" );
252
283
err = - EILSEQ ;
253
284
goto out ;
@@ -260,13 +291,19 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size,
260
291
goto out ;
261
292
}
262
293
263
- tlv_resp = (struct tlv_seg_resp * )(edl -> data );
294
+ if (edl -> cresp != EDL_CMD_REQ_RES_EVT || edl -> rtype != rtype ) {
295
+ bt_dev_err (hdev , "QCA TLV with error stat 0x%x rtype 0x%x" ,
296
+ edl -> cresp , edl -> rtype );
297
+ err = - EIO ;
298
+ }
264
299
265
- if (edl -> cresp != EDL_CMD_REQ_RES_EVT ||
266
- edl -> rtype != EDL_TVL_DNLD_RES_EVT || tlv_resp -> result != 0x00 ) {
300
+ if (soc_type == QCA_WCN3991 )
301
+ goto out ;
302
+
303
+ tlv_resp = (struct tlv_seg_resp * )(edl -> data );
304
+ if (tlv_resp -> result ) {
267
305
bt_dev_err (hdev , "QCA TLV with error stat 0x%x rtype 0x%x (0x%x)" ,
268
306
edl -> cresp , edl -> rtype , tlv_resp -> result );
269
- err = - EIO ;
270
307
}
271
308
272
309
out :
@@ -301,7 +338,8 @@ static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
301
338
}
302
339
303
340
static int qca_download_firmware (struct hci_dev * hdev ,
304
- struct rome_config * config )
341
+ struct qca_fw_config * config ,
342
+ enum qca_btsoc_type soc_type )
305
343
{
306
344
const struct firmware * fw ;
307
345
const u8 * segment ;
@@ -328,10 +366,10 @@ static int qca_download_firmware(struct hci_dev *hdev,
328
366
remain -= segsize ;
329
367
/* The last segment is always acked regardless download mode */
330
368
if (!remain || segsize < MAX_SIZE_PER_TLV_SEGMENT )
331
- config -> dnld_mode = ROME_SKIP_EVT_NONE ;
369
+ config -> dnld_mode = QCA_SKIP_EVT_NONE ;
332
370
333
371
ret = qca_tlv_send_segment (hdev , segsize , segment ,
334
- config -> dnld_mode );
372
+ config -> dnld_mode , soc_type );
335
373
if (ret )
336
374
goto out ;
337
375
@@ -344,8 +382,8 @@ static int qca_download_firmware(struct hci_dev *hdev,
344
382
* decrease the BT in initialization time. Here we will inject a command
345
383
* complete event to avoid a command timeout error message.
346
384
*/
347
- if (config -> dnld_type == ROME_SKIP_EVT_VSE_CC ||
348
- config -> dnld_type == ROME_SKIP_EVT_VSE )
385
+ if (config -> dnld_type == QCA_SKIP_EVT_VSE_CC ||
386
+ config -> dnld_type == QCA_SKIP_EVT_VSE )
349
387
ret = qca_inject_cmd_complete_event (hdev );
350
388
351
389
out :
@@ -382,7 +420,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
382
420
enum qca_btsoc_type soc_type , u32 soc_ver ,
383
421
const char * firmware_name )
384
422
{
385
- struct rome_config config ;
423
+ struct qca_fw_config config ;
386
424
int err ;
387
425
u8 rom_ver = 0 ;
388
426
@@ -405,7 +443,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
405
443
"qca/rampatch_%08x.bin" , soc_ver );
406
444
}
407
445
408
- err = qca_download_firmware (hdev , & config );
446
+ err = qca_download_firmware (hdev , & config , soc_type );
409
447
if (err < 0 ) {
410
448
bt_dev_err (hdev , "QCA Failed to download patch (%d)" , err );
411
449
return err ;
@@ -426,7 +464,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
426
464
snprintf (config .fwname , sizeof (config .fwname ),
427
465
"qca/nvm_%08x.bin" , soc_ver );
428
466
429
- err = qca_download_firmware (hdev , & config );
467
+ err = qca_download_firmware (hdev , & config , soc_type );
430
468
if (err < 0 ) {
431
469
bt_dev_err (hdev , "QCA Failed to download NVM (%d)" , err );
432
470
return err ;
0 commit comments