29
29
#define BTNXPUART_CHECK_BOOT_SIGNATURE 3
30
30
#define BTNXPUART_SERDEV_OPEN 4
31
31
#define BTNXPUART_IR_IN_PROGRESS 5
32
+ #define BTNXPUART_FW_DOWNLOAD_ABORT 6
32
33
33
34
/* NXP HW err codes */
34
35
#define BTNXPUART_IR_HW_ERR 0xb0
@@ -159,6 +160,7 @@ struct btnxpuart_dev {
159
160
u8 fw_name [MAX_FW_FILE_NAME_LEN ];
160
161
u32 fw_dnld_v1_offset ;
161
162
u32 fw_v1_sent_bytes ;
163
+ u32 fw_dnld_v3_offset ;
162
164
u32 fw_v3_offset_correction ;
163
165
u32 fw_v1_expected_len ;
164
166
u32 boot_reg_offset ;
@@ -550,6 +552,7 @@ static int nxp_download_firmware(struct hci_dev *hdev)
550
552
nxpdev -> fw_v1_sent_bytes = 0 ;
551
553
nxpdev -> fw_v1_expected_len = HDR_LEN ;
552
554
nxpdev -> boot_reg_offset = 0 ;
555
+ nxpdev -> fw_dnld_v3_offset = 0 ;
553
556
nxpdev -> fw_v3_offset_correction = 0 ;
554
557
nxpdev -> baudrate_changed = false;
555
558
nxpdev -> timeout_changed = false;
@@ -564,14 +567,23 @@ static int nxp_download_firmware(struct hci_dev *hdev)
564
567
!test_bit (BTNXPUART_FW_DOWNLOADING ,
565
568
& nxpdev -> tx_state ),
566
569
msecs_to_jiffies (60000 ));
570
+
571
+ release_firmware (nxpdev -> fw );
572
+ memset (nxpdev -> fw_name , 0 , sizeof (nxpdev -> fw_name ));
573
+
567
574
if (err == 0 ) {
568
- bt_dev_err (hdev , "FW Download Timeout." );
575
+ bt_dev_err (hdev , "FW Download Timeout. offset: %d" ,
576
+ nxpdev -> fw_dnld_v1_offset ?
577
+ nxpdev -> fw_dnld_v1_offset :
578
+ nxpdev -> fw_dnld_v3_offset );
569
579
return - ETIMEDOUT ;
570
580
}
581
+ if (test_bit (BTNXPUART_FW_DOWNLOAD_ABORT , & nxpdev -> tx_state )) {
582
+ bt_dev_err (hdev , "FW Download Aborted" );
583
+ return - EINTR ;
584
+ }
571
585
572
586
serdev_device_set_flow_control (nxpdev -> serdev , true);
573
- release_firmware (nxpdev -> fw );
574
- memset (nxpdev -> fw_name , 0 , sizeof (nxpdev -> fw_name ));
575
587
576
588
/* Allow the downloaded FW to initialize */
577
589
msleep (1200 );
@@ -955,8 +967,9 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
955
967
goto free_skb ;
956
968
}
957
969
958
- serdev_device_write_buf (nxpdev -> serdev , nxpdev -> fw -> data + offset -
959
- nxpdev -> fw_v3_offset_correction , len );
970
+ nxpdev -> fw_dnld_v3_offset = offset - nxpdev -> fw_v3_offset_correction ;
971
+ serdev_device_write_buf (nxpdev -> serdev , nxpdev -> fw -> data +
972
+ nxpdev -> fw_dnld_v3_offset , len );
960
973
961
974
free_skb :
962
975
kfree_skb (skb );
@@ -1390,16 +1403,22 @@ static void nxp_serdev_remove(struct serdev_device *serdev)
1390
1403
struct btnxpuart_dev * nxpdev = serdev_device_get_drvdata (serdev );
1391
1404
struct hci_dev * hdev = nxpdev -> hdev ;
1392
1405
1393
- /* Restore FW baudrate to fw_init_baudrate if changed.
1394
- * This will ensure FW baudrate is in sync with
1395
- * driver baudrate in case this driver is re-inserted.
1396
- */
1397
- if (nxpdev -> current_baudrate != nxpdev -> fw_init_baudrate ) {
1398
- nxpdev -> new_baudrate = nxpdev -> fw_init_baudrate ;
1399
- nxp_set_baudrate_cmd (hdev , NULL );
1406
+ if (is_fw_downloading (nxpdev )) {
1407
+ set_bit (BTNXPUART_FW_DOWNLOAD_ABORT , & nxpdev -> tx_state );
1408
+ clear_bit (BTNXPUART_FW_DOWNLOADING , & nxpdev -> tx_state );
1409
+ wake_up_interruptible (& nxpdev -> check_boot_sign_wait_q );
1410
+ wake_up_interruptible (& nxpdev -> fw_dnld_done_wait_q );
1411
+ } else {
1412
+ /* Restore FW baudrate to fw_init_baudrate if changed.
1413
+ * This will ensure FW baudrate is in sync with
1414
+ * driver baudrate in case this driver is re-inserted.
1415
+ */
1416
+ if (nxpdev -> current_baudrate != nxpdev -> fw_init_baudrate ) {
1417
+ nxpdev -> new_baudrate = nxpdev -> fw_init_baudrate ;
1418
+ nxp_set_baudrate_cmd (hdev , NULL );
1419
+ }
1420
+ ps_cancel_timer (nxpdev );
1400
1421
}
1401
-
1402
- ps_cancel_timer (nxpdev );
1403
1422
hci_unregister_dev (hdev );
1404
1423
hci_free_dev (hdev );
1405
1424
}
0 commit comments