2929#define BTNXPUART_CHECK_BOOT_SIGNATURE 3
3030#define BTNXPUART_SERDEV_OPEN 4
3131#define BTNXPUART_IR_IN_PROGRESS 5
32+ #define BTNXPUART_FW_DOWNLOAD_ABORT 6
3233
3334/* NXP HW err codes */
3435#define BTNXPUART_IR_HW_ERR 0xb0
@@ -159,6 +160,7 @@ struct btnxpuart_dev {
159160 u8 fw_name [MAX_FW_FILE_NAME_LEN ];
160161 u32 fw_dnld_v1_offset ;
161162 u32 fw_v1_sent_bytes ;
163+ u32 fw_dnld_v3_offset ;
162164 u32 fw_v3_offset_correction ;
163165 u32 fw_v1_expected_len ;
164166 u32 boot_reg_offset ;
@@ -550,6 +552,7 @@ static int nxp_download_firmware(struct hci_dev *hdev)
550552 nxpdev -> fw_v1_sent_bytes = 0 ;
551553 nxpdev -> fw_v1_expected_len = HDR_LEN ;
552554 nxpdev -> boot_reg_offset = 0 ;
555+ nxpdev -> fw_dnld_v3_offset = 0 ;
553556 nxpdev -> fw_v3_offset_correction = 0 ;
554557 nxpdev -> baudrate_changed = false;
555558 nxpdev -> timeout_changed = false;
@@ -564,14 +567,23 @@ static int nxp_download_firmware(struct hci_dev *hdev)
564567 !test_bit (BTNXPUART_FW_DOWNLOADING ,
565568 & nxpdev -> tx_state ),
566569 msecs_to_jiffies (60000 ));
570+
571+ release_firmware (nxpdev -> fw );
572+ memset (nxpdev -> fw_name , 0 , sizeof (nxpdev -> fw_name ));
573+
567574 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 );
569579 return - ETIMEDOUT ;
570580 }
581+ if (test_bit (BTNXPUART_FW_DOWNLOAD_ABORT , & nxpdev -> tx_state )) {
582+ bt_dev_err (hdev , "FW Download Aborted" );
583+ return - EINTR ;
584+ }
571585
572586 serdev_device_set_flow_control (nxpdev -> serdev , true);
573- release_firmware (nxpdev -> fw );
574- memset (nxpdev -> fw_name , 0 , sizeof (nxpdev -> fw_name ));
575587
576588 /* Allow the downloaded FW to initialize */
577589 msleep (1200 );
@@ -955,8 +967,9 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
955967 goto free_skb ;
956968 }
957969
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 );
960973
961974free_skb :
962975 kfree_skb (skb );
@@ -1390,16 +1403,22 @@ static void nxp_serdev_remove(struct serdev_device *serdev)
13901403 struct btnxpuart_dev * nxpdev = serdev_device_get_drvdata (serdev );
13911404 struct hci_dev * hdev = nxpdev -> hdev ;
13921405
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 );
14001421 }
1401-
1402- ps_cancel_timer (nxpdev );
14031422 hci_unregister_dev (hdev );
14041423 hci_free_dev (hdev );
14051424}
0 commit comments