@@ -72,7 +72,8 @@ enum qca_flags {
7272 QCA_DROP_VENDOR_EVENT ,
7373 QCA_SUSPENDING ,
7474 QCA_MEMDUMP_COLLECTION ,
75- QCA_HW_ERROR_EVENT
75+ QCA_HW_ERROR_EVENT ,
76+ QCA_SSR_TRIGGERED
7677};
7778
7879enum qca_capabilities {
@@ -854,6 +855,13 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
854855 BT_DBG ("hu %p qca enq skb %p tx_ibs_state %d" , hu , skb ,
855856 qca -> tx_ibs_state );
856857
858+ if (test_bit (QCA_SSR_TRIGGERED , & qca -> flags )) {
859+ /* As SSR is in progress, ignore the packets */
860+ bt_dev_dbg (hu -> hdev , "SSR is in progress" );
861+ kfree_skb (skb );
862+ return 0 ;
863+ }
864+
857865 /* Prepend skb with frame type */
858866 memcpy (skb_push (skb , 1 ), & hci_skb_pkt_type (skb ), 1 );
859867
@@ -1123,6 +1131,7 @@ static int qca_controller_memdump_event(struct hci_dev *hdev,
11231131 struct hci_uart * hu = hci_get_drvdata (hdev );
11241132 struct qca_data * qca = hu -> priv ;
11251133
1134+ set_bit (QCA_SSR_TRIGGERED , & qca -> flags );
11261135 skb_queue_tail (& qca -> rx_memdump_q , skb );
11271136 queue_work (qca -> workqueue , & qca -> ctrl_memdump_evt );
11281137
@@ -1481,6 +1490,7 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
14811490 struct hci_uart * hu = hci_get_drvdata (hdev );
14821491 struct qca_data * qca = hu -> priv ;
14831492
1493+ set_bit (QCA_SSR_TRIGGERED , & qca -> flags );
14841494 set_bit (QCA_HW_ERROR_EVENT , & qca -> flags );
14851495 bt_dev_info (hdev , "mem_dump_status: %d" , qca -> memdump_state );
14861496
@@ -1529,10 +1539,30 @@ static void qca_cmd_timeout(struct hci_dev *hdev)
15291539 struct hci_uart * hu = hci_get_drvdata (hdev );
15301540 struct qca_data * qca = hu -> priv ;
15311541
1532- if (qca -> memdump_state == QCA_MEMDUMP_IDLE )
1542+ set_bit (QCA_SSR_TRIGGERED , & qca -> flags );
1543+ if (qca -> memdump_state == QCA_MEMDUMP_IDLE ) {
1544+ set_bit (QCA_MEMDUMP_COLLECTION , & qca -> flags );
15331545 qca_send_crashbuffer (hu );
1534- else
1535- bt_dev_info (hdev , "Dump collection is in process" );
1546+ qca_wait_for_dump_collection (hdev );
1547+ } else if (qca -> memdump_state == QCA_MEMDUMP_COLLECTING ) {
1548+ /* Let us wait here until memory dump collected or
1549+ * memory dump timer expired.
1550+ */
1551+ bt_dev_info (hdev , "waiting for dump to complete" );
1552+ qca_wait_for_dump_collection (hdev );
1553+ }
1554+
1555+ mutex_lock (& qca -> hci_memdump_lock );
1556+ if (qca -> memdump_state != QCA_MEMDUMP_COLLECTED ) {
1557+ qca -> memdump_state = QCA_MEMDUMP_TIMEOUT ;
1558+ if (!test_bit (QCA_HW_ERROR_EVENT , & qca -> flags )) {
1559+ /* Inject hw error event to reset the device
1560+ * and driver.
1561+ */
1562+ hci_reset_dev (hu -> hdev );
1563+ }
1564+ }
1565+ mutex_unlock (& qca -> hci_memdump_lock );
15361566}
15371567
15381568static int qca_wcn3990_init (struct hci_uart * hu )
@@ -1643,6 +1673,8 @@ static int qca_setup(struct hci_uart *hu)
16431673 if (ret )
16441674 return ret ;
16451675
1676+ clear_bit (QCA_SSR_TRIGGERED , & qca -> flags );
1677+
16461678 if (qca_is_wcn399x (soc_type )) {
16471679 set_bit (HCI_QUIRK_USE_BDADDR_PROPERTY , & hdev -> quirks );
16481680
0 commit comments