Skip to content

Commit 3344537

Browse files
Venkata Lakshmi Narayana Gubbaholtmann
authored andcommitted
Bluetooth: hci_qca: Bug fixes for SSR
1.During SSR for command time out if BT SoC goes to inresponsive state, power cycling of BT SoC was not happening. Given the fix by sending hw error event to reset the BT SoC. 2.If SSR is triggered then ignore the transmit data requests to BT SoC until SSR is completed. Signed-off-by: Venkata Lakshmi Narayana Gubba <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 33bfd94 commit 3344537

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

drivers/bluetooth/hci_qca.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

7879
enum 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

15381568
static 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

Comments
 (0)