.. | .. |
---|
50 | 50 | #define IBS_HOST_TX_IDLE_TIMEOUT_MS 2000 |
---|
51 | 51 | #define CMD_TRANS_TIMEOUT_MS 100 |
---|
52 | 52 | #define MEMDUMP_TIMEOUT_MS 8000 |
---|
| 53 | +#define IBS_DISABLE_SSR_TIMEOUT_MS \ |
---|
| 54 | + (MEMDUMP_TIMEOUT_MS + FW_DOWNLOAD_TIMEOUT_MS) |
---|
| 55 | +#define FW_DOWNLOAD_TIMEOUT_MS 3000 |
---|
53 | 56 | |
---|
54 | 57 | /* susclk rate */ |
---|
55 | 58 | #define SUSCLK_RATE_32KHZ 32768 |
---|
.. | .. |
---|
68 | 71 | #define QCA_MEMDUMP_BYTE 0xFB |
---|
69 | 72 | |
---|
70 | 73 | enum qca_flags { |
---|
71 | | - QCA_IBS_ENABLED, |
---|
| 74 | + QCA_IBS_DISABLED, |
---|
72 | 75 | QCA_DROP_VENDOR_EVENT, |
---|
73 | 76 | QCA_SUSPENDING, |
---|
74 | 77 | QCA_MEMDUMP_COLLECTION, |
---|
75 | 78 | QCA_HW_ERROR_EVENT, |
---|
76 | | - QCA_SSR_TRIGGERED |
---|
| 79 | + QCA_SSR_TRIGGERED, |
---|
| 80 | + QCA_BT_OFF, |
---|
| 81 | + QCA_ROM_FW, |
---|
| 82 | + QCA_DEBUGFS_CREATED, |
---|
77 | 83 | }; |
---|
78 | 84 | |
---|
79 | 85 | enum qca_capabilities { |
---|
.. | .. |
---|
628 | 634 | if (!hdev->debugfs) |
---|
629 | 635 | return; |
---|
630 | 636 | |
---|
| 637 | + if (test_and_set_bit(QCA_DEBUGFS_CREATED, &qca->flags)) |
---|
| 638 | + return; |
---|
| 639 | + |
---|
631 | 640 | ibs_dir = debugfs_create_dir("ibs", hdev->debugfs); |
---|
632 | 641 | |
---|
633 | 642 | /* read only */ |
---|
.. | .. |
---|
870 | 879 | * Out-Of-Band(GPIOs control) sleep is selected. |
---|
871 | 880 | * Don't wake the device up when suspending. |
---|
872 | 881 | */ |
---|
873 | | - if (!test_bit(QCA_IBS_ENABLED, &qca->flags) || |
---|
| 882 | + if (test_bit(QCA_IBS_DISABLED, &qca->flags) || |
---|
874 | 883 | test_bit(QCA_SUSPENDING, &qca->flags)) { |
---|
875 | 884 | skb_queue_tail(&qca->txq, skb); |
---|
876 | 885 | spin_unlock_irqrestore(&qca->hci_ibs_lock, flags); |
---|
.. | .. |
---|
905 | 914 | default: |
---|
906 | 915 | BT_ERR("Illegal tx state: %d (losing packet)", |
---|
907 | 916 | qca->tx_ibs_state); |
---|
908 | | - kfree_skb(skb); |
---|
| 917 | + dev_kfree_skb_irq(skb); |
---|
909 | 918 | break; |
---|
910 | 919 | } |
---|
911 | 920 | |
---|
.. | .. |
---|
1015 | 1024 | * the controller to send the dump is 8 seconds. let us |
---|
1016 | 1025 | * start timer to handle this asynchronous activity. |
---|
1017 | 1026 | */ |
---|
1018 | | - clear_bit(QCA_IBS_ENABLED, &qca->flags); |
---|
| 1027 | + set_bit(QCA_IBS_DISABLED, &qca->flags); |
---|
1019 | 1028 | set_bit(QCA_MEMDUMP_COLLECTION, &qca->flags); |
---|
1020 | 1029 | dump = (void *) skb->data; |
---|
1021 | 1030 | dump_size = __le32_to_cpu(dump->dump_size); |
---|
.. | .. |
---|
1621 | 1630 | struct hci_uart *hu = hci_get_drvdata(hdev); |
---|
1622 | 1631 | enum qca_btsoc_type soc_type = qca_soc_type(hu); |
---|
1623 | 1632 | struct qca_serdev *qcadev; |
---|
| 1633 | + struct qca_data *qca = hu->priv; |
---|
1624 | 1634 | int ret = 0; |
---|
1625 | 1635 | |
---|
1626 | 1636 | /* Non-serdev device usually is powered by external power |
---|
.. | .. |
---|
1640 | 1650 | } |
---|
1641 | 1651 | } |
---|
1642 | 1652 | |
---|
| 1653 | + clear_bit(QCA_BT_OFF, &qca->flags); |
---|
1643 | 1654 | return ret; |
---|
1644 | 1655 | } |
---|
1645 | 1656 | |
---|
.. | .. |
---|
1658 | 1669 | if (ret) |
---|
1659 | 1670 | return ret; |
---|
1660 | 1671 | |
---|
| 1672 | + clear_bit(QCA_ROM_FW, &qca->flags); |
---|
1661 | 1673 | /* Patch downloading has to be done without IBS mode */ |
---|
1662 | | - clear_bit(QCA_IBS_ENABLED, &qca->flags); |
---|
| 1674 | + set_bit(QCA_IBS_DISABLED, &qca->flags); |
---|
1663 | 1675 | |
---|
1664 | 1676 | /* Enable controller to do both LE scan and BR/EDR inquiry |
---|
1665 | 1677 | * simultaneously. |
---|
.. | .. |
---|
1710 | 1722 | ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver, |
---|
1711 | 1723 | firmware_name); |
---|
1712 | 1724 | if (!ret) { |
---|
1713 | | - set_bit(QCA_IBS_ENABLED, &qca->flags); |
---|
| 1725 | + clear_bit(QCA_IBS_DISABLED, &qca->flags); |
---|
1714 | 1726 | qca_debugfs_init(hdev); |
---|
1715 | 1727 | hu->hdev->hw_error = qca_hw_error; |
---|
1716 | 1728 | hu->hdev->cmd_timeout = qca_cmd_timeout; |
---|
1717 | 1729 | } else if (ret == -ENOENT) { |
---|
1718 | 1730 | /* No patch/nvm-config found, run with original fw/config */ |
---|
| 1731 | + set_bit(QCA_ROM_FW, &qca->flags); |
---|
1719 | 1732 | ret = 0; |
---|
1720 | 1733 | } else if (ret == -EAGAIN) { |
---|
1721 | 1734 | /* |
---|
1722 | 1735 | * Userspace firmware loader will return -EAGAIN in case no |
---|
1723 | 1736 | * patch/nvm-config is found, so run with original fw/config. |
---|
1724 | 1737 | */ |
---|
| 1738 | + set_bit(QCA_ROM_FW, &qca->flags); |
---|
1725 | 1739 | ret = 0; |
---|
1726 | 1740 | } else { |
---|
1727 | 1741 | if (retries < MAX_INIT_RETRIES) { |
---|
.. | .. |
---|
1814 | 1828 | * data in skb's. |
---|
1815 | 1829 | */ |
---|
1816 | 1830 | spin_lock_irqsave(&qca->hci_ibs_lock, flags); |
---|
1817 | | - clear_bit(QCA_IBS_ENABLED, &qca->flags); |
---|
| 1831 | + set_bit(QCA_IBS_DISABLED, &qca->flags); |
---|
1818 | 1832 | qca_flush(hu); |
---|
1819 | 1833 | spin_unlock_irqrestore(&qca->hci_ibs_lock, flags); |
---|
1820 | 1834 | |
---|
.. | .. |
---|
1833 | 1847 | } else if (qcadev->bt_en) { |
---|
1834 | 1848 | gpiod_set_value_cansleep(qcadev->bt_en, 0); |
---|
1835 | 1849 | } |
---|
| 1850 | + |
---|
| 1851 | + set_bit(QCA_BT_OFF, &qca->flags); |
---|
1836 | 1852 | } |
---|
1837 | 1853 | |
---|
1838 | 1854 | static int qca_power_off(struct hci_dev *hdev) |
---|
.. | .. |
---|
2057 | 2073 | int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS); |
---|
2058 | 2074 | struct serdev_device *serdev = to_serdev_device(dev); |
---|
2059 | 2075 | struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); |
---|
| 2076 | + struct hci_uart *hu = &qcadev->serdev_hu; |
---|
| 2077 | + struct hci_dev *hdev = hu->hdev; |
---|
| 2078 | + struct qca_data *qca = hu->priv; |
---|
2060 | 2079 | const u8 ibs_wake_cmd[] = { 0xFD }; |
---|
2061 | 2080 | const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 }; |
---|
2062 | 2081 | |
---|
2063 | 2082 | if (qcadev->btsoc_type == QCA_QCA6390) { |
---|
| 2083 | + if (test_bit(QCA_BT_OFF, &qca->flags) || |
---|
| 2084 | + !test_bit(HCI_RUNNING, &hdev->flags)) |
---|
| 2085 | + return; |
---|
| 2086 | + |
---|
2064 | 2087 | serdev_device_write_flush(serdev); |
---|
2065 | 2088 | ret = serdev_device_write_buf(serdev, ibs_wake_cmd, |
---|
2066 | 2089 | sizeof(ibs_wake_cmd)); |
---|
.. | .. |
---|
2093 | 2116 | bool tx_pending = false; |
---|
2094 | 2117 | int ret = 0; |
---|
2095 | 2118 | u8 cmd; |
---|
| 2119 | + u32 wait_timeout = 0; |
---|
2096 | 2120 | |
---|
2097 | 2121 | set_bit(QCA_SUSPENDING, &qca->flags); |
---|
2098 | 2122 | |
---|
2099 | | - /* Device is downloading patch or doesn't support in-band sleep. */ |
---|
2100 | | - if (!test_bit(QCA_IBS_ENABLED, &qca->flags)) |
---|
| 2123 | + /* if BT SoC is running with default firmware then it does not |
---|
| 2124 | + * support in-band sleep |
---|
| 2125 | + */ |
---|
| 2126 | + if (test_bit(QCA_ROM_FW, &qca->flags)) |
---|
2101 | 2127 | return 0; |
---|
2102 | 2128 | |
---|
| 2129 | + /* During SSR after memory dump collection, controller will be |
---|
| 2130 | + * powered off and then powered on.If controller is powered off |
---|
| 2131 | + * during SSR then we should wait until SSR is completed. |
---|
| 2132 | + */ |
---|
| 2133 | + if (test_bit(QCA_BT_OFF, &qca->flags) && |
---|
| 2134 | + !test_bit(QCA_SSR_TRIGGERED, &qca->flags)) |
---|
| 2135 | + return 0; |
---|
| 2136 | + |
---|
| 2137 | + if (test_bit(QCA_IBS_DISABLED, &qca->flags) || |
---|
| 2138 | + test_bit(QCA_SSR_TRIGGERED, &qca->flags)) { |
---|
| 2139 | + wait_timeout = test_bit(QCA_SSR_TRIGGERED, &qca->flags) ? |
---|
| 2140 | + IBS_DISABLE_SSR_TIMEOUT_MS : |
---|
| 2141 | + FW_DOWNLOAD_TIMEOUT_MS; |
---|
| 2142 | + |
---|
| 2143 | + /* QCA_IBS_DISABLED flag is set to true, During FW download |
---|
| 2144 | + * and during memory dump collection. It is reset to false, |
---|
| 2145 | + * After FW download complete. |
---|
| 2146 | + */ |
---|
| 2147 | + wait_on_bit_timeout(&qca->flags, QCA_IBS_DISABLED, |
---|
| 2148 | + TASK_UNINTERRUPTIBLE, msecs_to_jiffies(wait_timeout)); |
---|
| 2149 | + |
---|
| 2150 | + if (test_bit(QCA_IBS_DISABLED, &qca->flags)) { |
---|
| 2151 | + bt_dev_err(hu->hdev, "SSR or FW download time out"); |
---|
| 2152 | + ret = -ETIMEDOUT; |
---|
| 2153 | + goto error; |
---|
| 2154 | + } |
---|
| 2155 | + } |
---|
| 2156 | + |
---|
2103 | 2157 | cancel_work_sync(&qca->ws_awake_device); |
---|
2104 | 2158 | cancel_work_sync(&qca->ws_awake_rx); |
---|
2105 | 2159 | |
---|