[Resend v1] Bluetooth: hci_qca: Wait for timeout during suspend

2020-11-10 Thread Balakrishna Godavarthi
From: Venkata Lakshmi Narayana Gubba 

Currently qca_suspend() is relied on IBS mechanism. During
FW download and memory dump collections, IBS will be disabled.
In those cases, driver will allow suspend and still uses the
serdev port, which results to errors. Now added a wait timeout
if suspend is triggered during FW download and memory collections.

Signed-off-by: Venkata Lakshmi Narayana Gubba 
Signed-off-by: Balakrishna Godavarthi 
Reviewed-by: Abhishek Pandit-Subedi 
---
 drivers/bluetooth/hci_qca.c | 48 -
 1 file changed, 39 insertions(+), 9 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 1c9a2d46..180b324 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -50,6 +50,8 @@
 #define IBS_HOST_TX_IDLE_TIMEOUT_MS2000
 #define CMD_TRANS_TIMEOUT_MS   100
 #define MEMDUMP_TIMEOUT_MS 8000
+#define IBS_DISABLE_SSR_TIMEOUT_MS (MEMDUMP_TIMEOUT_MS + 1000)
+#define FW_DOWNLOAD_TIMEOUT_MS 3000
 
 /* susclk rate */
 #define SUSCLK_RATE_32KHZ  32768
@@ -68,12 +70,13 @@
 #define QCA_MEMDUMP_BYTE   0xFB
 
 enum qca_flags {
-   QCA_IBS_ENABLED,
+   QCA_IBS_DISABLED,
QCA_DROP_VENDOR_EVENT,
QCA_SUSPENDING,
QCA_MEMDUMP_COLLECTION,
QCA_HW_ERROR_EVENT,
-   QCA_SSR_TRIGGERED
+   QCA_SSR_TRIGGERED,
+   QCA_BT_OFF
 };
 
 enum qca_capabilities {
@@ -870,7 +873,7 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff 
*skb)
 * Out-Of-Band(GPIOs control) sleep is selected.
 * Don't wake the device up when suspending.
 */
-   if (!test_bit(QCA_IBS_ENABLED, >flags) ||
+   if (test_bit(QCA_IBS_DISABLED, >flags) ||
test_bit(QCA_SUSPENDING, >flags)) {
skb_queue_tail(>txq, skb);
spin_unlock_irqrestore(>hci_ibs_lock, flags);
@@ -1015,7 +1018,7 @@ static void qca_controller_memdump(struct work_struct 
*work)
 * the controller to send the dump is 8 seconds. let us
 * start timer to handle this asynchronous activity.
 */
-   clear_bit(QCA_IBS_ENABLED, >flags);
+   set_bit(QCA_IBS_DISABLED, >flags);
set_bit(QCA_MEMDUMP_COLLECTION, >flags);
dump = (void *) skb->data;
dump_size = __le32_to_cpu(dump->dump_size);
@@ -1619,6 +1622,7 @@ static int qca_power_on(struct hci_dev *hdev)
struct hci_uart *hu = hci_get_drvdata(hdev);
enum qca_btsoc_type soc_type = qca_soc_type(hu);
struct qca_serdev *qcadev;
+   struct qca_data *qca = hu->priv;
int ret = 0;
 
/* Non-serdev device usually is powered by external power
@@ -1638,6 +1642,7 @@ static int qca_power_on(struct hci_dev *hdev)
}
}
 
+   clear_bit(QCA_BT_OFF, >flags);
return ret;
 }
 
@@ -1657,7 +1662,7 @@ static int qca_setup(struct hci_uart *hu)
return ret;
 
/* Patch downloading has to be done without IBS mode */
-   clear_bit(QCA_IBS_ENABLED, >flags);
+   set_bit(QCA_IBS_DISABLED, >flags);
 
/* Enable controller to do both LE scan and BR/EDR inquiry
 * simultaneously.
@@ -1708,7 +1713,7 @@ static int qca_setup(struct hci_uart *hu)
ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver,
firmware_name);
if (!ret) {
-   set_bit(QCA_IBS_ENABLED, >flags);
+   clear_bit(QCA_IBS_DISABLED, >flags);
qca_debugfs_init(hdev);
hu->hdev->hw_error = qca_hw_error;
hu->hdev->cmd_timeout = qca_cmd_timeout;
@@ -1816,7 +1821,7 @@ static void qca_power_shutdown(struct hci_uart *hu)
 * data in skb's.
 */
spin_lock_irqsave(>hci_ibs_lock, flags);
-   clear_bit(QCA_IBS_ENABLED, >flags);
+   set_bit(QCA_IBS_DISABLED, >flags);
qca_flush(hu);
spin_unlock_irqrestore(>hci_ibs_lock, flags);
 
@@ -1833,6 +1838,8 @@ static void qca_power_shutdown(struct hci_uart *hu)
} else if (qcadev->bt_en) {
gpiod_set_value_cansleep(qcadev->bt_en, 0);
}
+
+   set_bit(QCA_BT_OFF, >flags);
 }
 
 static int qca_power_off(struct hci_dev *hdev)
@@ -2090,11 +2097,34 @@ static int __maybe_unused qca_suspend(struct device 
*dev)
bool tx_pending = false;
int ret = 0;
u8 cmd;
+   u32 wait_timeout = 0;
 
set_bit(QCA_SUSPENDING, >flags);
 
-   /* Device is downloading patch or doesn't support in-band sleep. */
-   if (!test_bit(QCA_IBS_ENABLED, >flags))
+   if (test_bit(QCA_BT_OFF, >flags))
+   return 0;
+
+   if (test_bit(QCA_IBS_DISABLED, >flags)) {
+   wait_timeout = test_bit(QC

[Resend v1] Bluetooth: hci_qca: Enhance retry logic in qca_setup

2020-11-10 Thread Balakrishna Godavarthi
Currently driver only retries to download FW if FW downloading
is failed. Sometimes observed command timeout for version request
command, if this happen on some platforms during boot time, then
a reboot is needed to turn ON BT. Instead to avoid a reboot, now
extended retry logic for version request command too.

Signed-off-by: Balakrishna Godavarthi 
Reviewed-by: Abhishek Pandit-Subedi 
---
 drivers/bluetooth/hci_qca.c | 34 ++
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 2d3f1f1..1c9a2d46 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1672,7 +1672,7 @@ static int qca_setup(struct hci_uart *hu)
 retry:
ret = qca_power_on(hdev);
if (ret)
-   return ret;
+   goto out;
 
clear_bit(QCA_SSR_TRIGGERED, >flags);
 
@@ -1681,7 +1681,7 @@ static int qca_setup(struct hci_uart *hu)
 
ret = qca_read_soc_version(hdev, _ver, soc_type);
if (ret)
-   return ret;
+   goto out;
} else {
qca_set_speed(hu, QCA_INIT_SPEED);
}
@@ -1691,7 +1691,7 @@ static int qca_setup(struct hci_uart *hu)
if (speed) {
ret = qca_set_speed(hu, QCA_OPER_SPEED);
if (ret)
-   return ret;
+   goto out;
 
qca_baudrate = qca_get_baudrate_value(speed);
}
@@ -1700,7 +1700,7 @@ static int qca_setup(struct hci_uart *hu)
/* Get QCA version information */
ret = qca_read_soc_version(hdev, _ver, soc_type);
if (ret)
-   return ret;
+   goto out;
}
 
bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver);
@@ -1721,20 +1721,22 @@ static int qca_setup(struct hci_uart *hu)
 * patch/nvm-config is found, so run with original fw/config.
 */
ret = 0;
-   } else {
-   if (retries < MAX_INIT_RETRIES) {
-   qca_power_shutdown(hu);
-   if (hu->serdev) {
-   serdev_device_close(hu->serdev);
-   ret = serdev_device_open(hu->serdev);
-   if (ret) {
-   bt_dev_err(hdev, "failed to open port");
-   return ret;
-   }
+   }
+
+out:
+   if (ret && retries < MAX_INIT_RETRIES) {
+   bt_dev_warn(hdev, "Retry BT power ON:%d", retries);
+   qca_power_shutdown(hu);
+   if (hu->serdev) {
+   serdev_device_close(hu->serdev);
+   ret = serdev_device_open(hu->serdev);
+   if (ret) {
+   bt_dev_err(hdev, "failed to open port");
+   return ret;
}
-   retries++;
-   goto retry;
}
+   retries++;
+   goto retry;
}
 
/* Setup bdaddr */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v1] Bluetooth: hci_qca: Wait for timeout during suspend

2020-10-06 Thread Balakrishna Godavarthi
From: Venkata Lakshmi Narayana Gubba 

Currently qca_suspend() is relied on IBS mechanism. During
FW download and memory dump collections, IBS will be disabled.
In those cases, driver will allow suspend and still uses the
serdev port, which results to errors. Now added a wait timeout
if suspend is triggered during FW download and memory collections.

Signed-off-by: Venkata Lakshmi Narayana Gubba 
Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 48 -
 1 file changed, 39 insertions(+), 9 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 3d13002..652a84c 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -50,6 +50,8 @@
 #define IBS_HOST_TX_IDLE_TIMEOUT_MS2000
 #define CMD_TRANS_TIMEOUT_MS   100
 #define MEMDUMP_TIMEOUT_MS 8000
+#define IBS_DISABLE_SSR_TIMEOUT_MS (MEMDUMP_TIMEOUT_MS + 1000)
+#define FW_DOWNLOAD_TIMEOUT_MS 3000
 
 /* susclk rate */
 #define SUSCLK_RATE_32KHZ  32768
@@ -68,12 +70,13 @@
 #define QCA_MEMDUMP_BYTE   0xFB
 
 enum qca_flags {
-   QCA_IBS_ENABLED,
+   QCA_IBS_DISABLED,
QCA_DROP_VENDOR_EVENT,
QCA_SUSPENDING,
QCA_MEMDUMP_COLLECTION,
QCA_HW_ERROR_EVENT,
-   QCA_SSR_TRIGGERED
+   QCA_SSR_TRIGGERED,
+   QCA_BT_OFF
 };
 
 enum qca_capabilities {
@@ -871,7 +874,7 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff 
*skb)
 * Out-Of-Band(GPIOs control) sleep is selected.
 * Don't wake the device up when suspending.
 */
-   if (!test_bit(QCA_IBS_ENABLED, >flags) ||
+   if (test_bit(QCA_IBS_DISABLED, >flags) ||
test_bit(QCA_SUSPENDING, >flags)) {
skb_queue_tail(>txq, skb);
spin_unlock_irqrestore(>hci_ibs_lock, flags);
@@ -1016,7 +1019,7 @@ static void qca_controller_memdump(struct work_struct 
*work)
 * the controller to send the dump is 8 seconds. let us
 * start timer to handle this asynchronous activity.
 */
-   clear_bit(QCA_IBS_ENABLED, >flags);
+   set_bit(QCA_IBS_DISABLED, >flags);
set_bit(QCA_MEMDUMP_COLLECTION, >flags);
dump = (void *) skb->data;
dump_size = __le32_to_cpu(dump->dump_size);
@@ -1620,6 +1623,7 @@ static int qca_power_on(struct hci_dev *hdev)
struct hci_uart *hu = hci_get_drvdata(hdev);
enum qca_btsoc_type soc_type = qca_soc_type(hu);
struct qca_serdev *qcadev;
+   struct qca_data *qca = hu->priv;
int ret = 0;
 
/* Non-serdev device usually is powered by external power
@@ -1639,6 +1643,7 @@ static int qca_power_on(struct hci_dev *hdev)
}
}
 
+   clear_bit(QCA_BT_OFF, >flags);
return ret;
 }
 
@@ -1658,7 +1663,7 @@ static int qca_setup(struct hci_uart *hu)
return ret;
 
/* Patch downloading has to be done without IBS mode */
-   clear_bit(QCA_IBS_ENABLED, >flags);
+   set_bit(QCA_IBS_DISABLED, >flags);
 
/* Enable controller to do both LE scan and BR/EDR inquiry
 * simultaneously.
@@ -1707,7 +1712,7 @@ static int qca_setup(struct hci_uart *hu)
ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver,
firmware_name);
if (!ret) {
-   set_bit(QCA_IBS_ENABLED, >flags);
+   clear_bit(QCA_IBS_DISABLED, >flags);
qca_debugfs_init(hdev);
hu->hdev->hw_error = qca_hw_error;
hu->hdev->cmd_timeout = qca_cmd_timeout;
@@ -1813,7 +1818,7 @@ static void qca_power_shutdown(struct hci_uart *hu)
 * data in skb's.
 */
spin_lock_irqsave(>hci_ibs_lock, flags);
-   clear_bit(QCA_IBS_ENABLED, >flags);
+   set_bit(QCA_IBS_DISABLED, >flags);
qca_flush(hu);
spin_unlock_irqrestore(>hci_ibs_lock, flags);
 
@@ -1833,6 +1838,8 @@ static void qca_power_shutdown(struct hci_uart *hu)
} else if (qcadev->bt_en) {
gpiod_set_value_cansleep(qcadev->bt_en, 0);
}
+
+   set_bit(QCA_BT_OFF, >flags);
 }
 
 static int qca_power_off(struct hci_dev *hdev)
@@ -2082,11 +2089,34 @@ static int __maybe_unused qca_suspend(struct device 
*dev)
bool tx_pending = false;
int ret = 0;
u8 cmd;
+   u32 wait_timeout = 0;
 
set_bit(QCA_SUSPENDING, >flags);
 
-   /* Device is downloading patch or doesn't support in-band sleep. */
-   if (!test_bit(QCA_IBS_ENABLED, >flags))
+   if (test_bit(QCA_BT_OFF, >flags))
+   return 0;
+
+   if (test_bit(QCA_IBS_DISABLED, >flags)) {
+   wait_timeout = test_bit(QC

[PATCH v1] Bluetooth: hci_qca: Enhance retry logic in qca_setup

2020-10-06 Thread Balakrishna Godavarthi
Currently driver only retries to download FW if FW downloading
is failed. Sometimes observed command timeout for version request
command, if this happen on some platforms during boot time, then
a reboot is needed to turn ON BT. Instead to avoid a reboot, now
extended retry logic for version request command too.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 34 ++
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 2d3f1f1..1c9a2d46 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1672,7 +1672,7 @@ static int qca_setup(struct hci_uart *hu)
 retry:
ret = qca_power_on(hdev);
if (ret)
-   return ret;
+   goto out;
 
clear_bit(QCA_SSR_TRIGGERED, >flags);
 
@@ -1681,7 +1681,7 @@ static int qca_setup(struct hci_uart *hu)
 
ret = qca_read_soc_version(hdev, _ver, soc_type);
if (ret)
-   return ret;
+   goto out;
} else {
qca_set_speed(hu, QCA_INIT_SPEED);
}
@@ -1691,7 +1691,7 @@ static int qca_setup(struct hci_uart *hu)
if (speed) {
ret = qca_set_speed(hu, QCA_OPER_SPEED);
if (ret)
-   return ret;
+   goto out;
 
qca_baudrate = qca_get_baudrate_value(speed);
}
@@ -1700,7 +1700,7 @@ static int qca_setup(struct hci_uart *hu)
/* Get QCA version information */
ret = qca_read_soc_version(hdev, _ver, soc_type);
if (ret)
-   return ret;
+   goto out;
}
 
bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver);
@@ -1721,20 +1721,22 @@ static int qca_setup(struct hci_uart *hu)
 * patch/nvm-config is found, so run with original fw/config.
 */
ret = 0;
-   } else {
-   if (retries < MAX_INIT_RETRIES) {
-   qca_power_shutdown(hu);
-   if (hu->serdev) {
-   serdev_device_close(hu->serdev);
-   ret = serdev_device_open(hu->serdev);
-   if (ret) {
-   bt_dev_err(hdev, "failed to open port");
-   return ret;
-   }
+   }
+
+out:
+   if (ret && retries < MAX_INIT_RETRIES) {
+   bt_dev_warn(hdev, "Retry BT power ON:%d", retries);
+   qca_power_shutdown(hu);
+   if (hu->serdev) {
+   serdev_device_close(hu->serdev);
+   ret = serdev_device_open(hu->serdev);
+   if (ret) {
+   bt_dev_err(hdev, "failed to open port");
+   return ret;
}
-   retries++;
-   goto retry;
}
+   retries++;
+   goto retry;
}
 
/* Setup bdaddr */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v1] Bluetooth: hci_qca: Increase SoC idle timeout to 200ms

2020-06-12 Thread Balakrishna Godavarthi
In some version of WCN399x, SoC idle timeout is configured
as 80ms instead of 20ms or 40ms. To honor all the SoC's
supported in the driver increasing SoC idle timeout to 200ms.

Fixes: 41d5b25fed0a0 ("Bluetooth: hci_qca: add PM support")
Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f3fde99..91c9aa6 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -46,7 +46,7 @@
 #define HCI_MAX_IBS_SIZE   10
 
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
-#define IBS_BTSOC_TX_IDLE_TIMEOUT_MS   40
+#define IBS_BTSOC_TX_IDLE_TIMEOUT_MS   200
 #define IBS_HOST_TX_IDLE_TIMEOUT_MS2000
 #define CMD_TRANS_TIMEOUT_MS   100
 #define MEMDUMP_TIMEOUT_MS 8000
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v1] Bluetooth: hci_qca: Disable SoC debug logging for WCN3991

2020-06-12 Thread Balakrishna Godavarthi
By default, WCN3991 sent debug packets to HOST via ACL packet
with header 0xDC2E. This logging is not required on commercial
devices. With this patch SoC logging is disabled post fw
download.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/btqca.c | 27 +++
 drivers/bluetooth/btqca.h |  2 ++
 2 files changed, 29 insertions(+)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index c598496..ce9dcff 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -400,6 +400,27 @@ static int qca_download_firmware(struct hci_dev *hdev,
return ret;
 }
 
+static int qca_disable_soc_logging(struct hci_dev *hdev)
+{
+   struct sk_buff *skb;
+   u8 cmd[2];
+   int err;
+
+   cmd[0] = QCA_DISABLE_LOGGING_SUB_OP;
+   cmd[1] = 0x00;
+   skb = __hci_cmd_sync_ev(hdev, QCA_DISABLE_LOGGING, sizeof(cmd), cmd,
+   HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT);
+   if (IS_ERR(skb)) {
+   err = PTR_ERR(skb);
+   bt_dev_err(hdev, "QCA Failed to disable soc logging(%d)", err);
+   return err;
+   }
+
+   kfree_skb(skb);
+
+   return 0;
+}
+
 int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 {
struct sk_buff *skb;
@@ -486,6 +507,12 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
return err;
}
 
+   if (soc_type >= QCA_WCN3991) {
+   err = qca_disable_soc_logging(hdev);
+   if (err < 0)
+   return err;
+   }
+
/* Perform HCI reset */
err = qca_send_reset(hdev);
if (err < 0) {
diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
index 6e1e62d..d81b74c 100644
--- a/drivers/bluetooth/btqca.h
+++ b/drivers/bluetooth/btqca.h
@@ -14,6 +14,7 @@
 #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01)
 #define MAX_SIZE_PER_TLV_SEGMENT   (243)
 #define QCA_PRE_SHUTDOWN_CMD   (0xFC08)
+#define QCA_DISABLE_LOGGING(0xFC17)
 
 #define EDL_CMD_REQ_RES_EVT(0x00)
 #define EDL_PATCH_VER_RES_EVT  (0x19)
@@ -22,6 +23,7 @@
 #define EDL_CMD_EXE_STATUS_EVT (0x00)
 #define EDL_SET_BAUDRATE_RSP_EVT   (0x92)
 #define EDL_NVM_ACCESS_CODE_EVT(0x0B)
+#define QCA_DISABLE_LOGGING_SUB_OP (0x14)
 
 #define EDL_TAG_ID_HCI (17)
 #define EDL_TAG_ID_DEEP_SLEEP  (27)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v1] Bluetooth: hci_qca: Request Tx clock vote off only when Tx is pending

2020-06-12 Thread Balakrishna Godavarthi
Tx pending flag is set to true when HOST IBS state is AWAKE or
AWAKEING. If IBS state is ASLEEP, then Tx clock is already voted
off. To optimize further directly calling serial_clock_vote()
instead of qca_wq_serial_tx_clock_vote_off(), at this point of
qca_suspend() already data is sent out. No need to wake up hci to
send data.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f3fde99..50f896f 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -2107,6 +2107,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
if (tx_pending) {
serdev_device_wait_until_sent(hu->serdev,
  
msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
+   serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
}
 
/* Wait for HCI_IBS_SLEEP_IND sent by device to indicate its Tx is going
@@ -2120,7 +2121,6 @@ static int __maybe_unused qca_suspend(struct device *dev)
goto error;
}
 
-   qca_wq_serial_tx_clock_vote_off(>ws_tx_vote_off);
return 0;
 
 error:
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH 2/4] Bluetooth: hci_qca: Don't vote for specific voltage

2019-10-22 Thread Balakrishna Godavarthi

Hi Matthias, Bjorn andresson,

On 2019-10-21 12:07, Harish Bandi wrote:

+ Bala

On 2019-10-18 23:52, Matthias Kaehlcke wrote:

On Thu, Oct 17, 2019 at 10:24:02PM -0700, Bjorn Andersson wrote:

Devices with specific voltage requirements should not request voltage
from the driver, but instead rely on the system configuration to 
define

appropriate voltages for each rail.

This ensures that PMIC and board variations are accounted for, 
something

that the 0.1V range in the hci_qca driver currently tries to address.
But on the Lenovo Yoga C630 (with wcn3990) vddch0 is 3.1V, which 
means

the driver will fail to set the voltage.

Signed-off-by: Bjorn Andersson 
---
 drivers/bluetooth/hci_qca.c | 26 --
 1 file changed, 8 insertions(+), 18 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c 
b/drivers/bluetooth/hci_qca.c

index c07c529b0d81..54aafcc69d06 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -130,8 +130,6 @@ enum qca_speed_type {
  */
 struct qca_vreg {
const char *name;
-   unsigned int min_uV;
-   unsigned int max_uV;
unsigned int load_uA;
 };

@@ -1332,10 +1330,10 @@ static const struct hci_uart_proto qca_proto 
= {

 static const struct qca_vreg_data qca_soc_data_wcn3990 = {
.soc_type = QCA_WCN3990,
.vregs = (struct qca_vreg []) {
-   { "vddio",   180, 190,  15000  },
-   { "vddxo",   180, 190,  8  },
-   { "vddrf",   130, 135,  30 },
-   { "vddch0",  330, 340,  45 },
+   { "vddio", 15000  },
+   { "vddxo", 8  },
+   { "vddrf", 30 },
+   { "vddch0", 45 },
},
.num_vregs = 4,
 };
@@ -1343,10 +1341,10 @@ static const struct qca_vreg_data 
qca_soc_data_wcn3990 = {

 static const struct qca_vreg_data qca_soc_data_wcn3998 = {
.soc_type = QCA_WCN3998,
.vregs = (struct qca_vreg []) {
-   { "vddio",   180, 190,  1  },
-   { "vddxo",   180, 190,  8  },
-   { "vddrf",   130, 1352000,  30 },
-   { "vddch0",  330, 330,  45 },
+   { "vddio", 1  },
+   { "vddxo", 8  },
+   { "vddrf", 30 },
+   { "vddch0", 45 },
},
.num_vregs = 4,
 };
@@ -1386,13 +1384,6 @@ static int qca_power_off(struct hci_dev *hdev)
 static int qca_enable_regulator(struct qca_vreg vregs,
struct regulator *regulator)
 {
-   int ret;
-
-   ret = regulator_set_voltage(regulator, vregs.min_uV,
-   vregs.max_uV);
-   if (ret)
-   return ret;
-
return regulator_enable(regulator);

 }
@@ -1401,7 +1392,6 @@ static void qca_disable_regulator(struct 
qca_vreg vregs,

  struct regulator *regulator)
 {
regulator_disable(regulator);
-   regulator_set_voltage(regulator, 0, vregs.max_uV);

 }


This was brought up multiple times during the initial review, but
wasn't addressed.

Reviewed-by: Matthias Kaehlcke 



yes true PMIC dts regulator should do this.
But we have some real time issues observed.

Issue 1:

In PMIC dts node, ASAIK we have three levels of voltages.

1. Default voltage.
2. Minimum voltage. (mandatory entry)
3. Maximum voltage. (mandatory entry)

Let us assume that the if PMIC regulator dts node supports  defaults 
voltage to 3.2 Volts and Min  as 3.1 V and max as 3.3V
So default operating voltage is 3.1V  when we turn on BT (but according 
to spec SoC requires min of 3.3V to operate,

Might have some functionality failures on end to end testing

Issue 2:

WCN3990 RF is shared with WiFi, so it also try to turn on the 
regulators. Wifi driver uses the same approach of restricting to min and 
max voltages in driver.
Let us assume we turned ON BT and CH0 is set to 3.1v (as in your case), 
Wifi is tuned on now, as its request the CH0 to operate at 3.3 Volts, 
regulator will fail to set this voltage as BT is operating

at CH0 3.1v (assuming max voltage is 3.2v)
https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git/tree/drivers/net/wireless/ath/ath10k/snoc.c#n39

Issue 3:

By mistake PMIC has low min or default voltage and high max voltages, 
that is harm for WNC3990.


I would suggest to restrict the min and max voltages in driver, instead 
of relaying on PMIC to do this.

BTW pmic will do this and doing it in our driver is safer.

Let me know your views on this.
--
Regards
Balakrishna.


Re: [PATCH] Bluetooth: hci_qca: fix in-band sleep enablement

2019-10-11 Thread Balakrishna Godavarthi

Hi Claire,

This change will not work  as we need fw files to be loaded tofor IBS to 
active.
may i know on which chipset you have this issue of IBS active even with 
out fw download.


On 2019-10-11 12:31, Harish Bandi wrote:

++ Balakrishna

On 2019-10-09 14:21, Claire Chang wrote:

Enabling in-band sleep when there is no patch/nvm-config found and
bluetooth is running with the original fw/config.

Fixes: ba8f35979002 ("Bluetooth: hci_qca: Avoid setup failure on
missing rampatch")
Fixes: 7dc5fe0814c3 ("Bluetooth: hci_qca: Avoid missing rampatch
failure with userspace fw loader")
Signed-off-by: Claire Chang 
---
 drivers/bluetooth/hci_qca.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index e3164c200eac..367eef893a11 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1291,10 +1291,8 @@ static int qca_setup(struct hci_uart *hu)
/* Setup patch / NVM configurations */
ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver,
firmware_name);
-   if (!ret) {
-   set_bit(QCA_IBS_ENABLED, >flags);
-   qca_debugfs_init(hdev);
-   } else if (ret == -ENOENT) {
+
+   if (ret == -ENOENT) {
/* No patch/nvm-config found, run with original fw/config */
ret = 0;
} else if (ret == -EAGAIN) {
@@ -1305,6 +1303,11 @@ static int qca_setup(struct hci_uart *hu)
ret = 0;
}

+   if (!ret) {
+   set_bit(QCA_IBS_ENABLED, >flags);
+   qca_debugfs_init(hdev);
+   }
+
/* Setup bdaddr */
if (qca_is_wcn399x(soc_type))
hu->hdev->set_bdaddr = qca_set_bdaddr;


--
Regards
Balakrishna.


Re: [PATCH v1] Bluetooth: hci_qca: wait for Pre shutdown to command complete event before sending the Power off pulse

2019-08-08 Thread Balakrishna Godavarthi

Hi Harish,

On 2019-08-08 14:55, Harish Bandi wrote:

When SoC receives pre shut down command, it share the same
with other COEX shared clients. So SoC needs a short
time after sending VS pre shutdown command before
turning off the regulators and sending the power off pulse.

Signed-off-by: Harish Bandi 
---
 drivers/bluetooth/btqca.c   | 5 +++--
 drivers/bluetooth/hci_qca.c | 2 ++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index 2221935..f20991e 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -106,8 +106,9 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)

bt_dev_dbg(hdev, "QCA pre shutdown cmd");

-   skb = __hci_cmd_sync(hdev, QCA_PRE_SHUTDOWN_CMD, 0,
-   NULL, HCI_INIT_TIMEOUT);
+   skb = __hci_cmd_sync_ev(hdev, QCA_PRE_SHUTDOWN_CMD, 0,
+   NULL, HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT);


[Bala]: nit: can you also add reason in commit text for adding 
HCI_EV_CMD_COMPLETE



+
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
bt_dev_err(hdev, "QCA preshutdown_cmd failed (%d)", err);
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 16db6c0..566aa28 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1386,6 +1386,8 @@ static int qca_power_off(struct hci_dev *hdev)
/* Perform pre shutdown command */
qca_send_pre_shutdown_cmd(hdev);

+   usleep_range(8000, 1);
+
qca_power_shutdown(hu);
return 0;
 }


Reviewed-by: Balakrishna Godavarthi 

--
Regards
Balakrishna.


Re: [PATCH] Bluetooth: btqca: release_firmware after qca_inject_cmd_complete_event

2019-08-06 Thread Balakrishna Godavarthi

Hi,

On 2019-08-06 15:26, Claire Chang wrote:

commit 32646db8cc28 ("Bluetooth: btqca: inject command complete event
during fw download") added qca_inject_cmd_complete_event() for certain
qualcomm chips. However, qca_download_firmware() will return without
calling release_firmware() in this case.

This leads to a memory leak like the following found by kmemleak:

unreferenced object 0xfff3868a5880 (size 128):
  comm "kworker/u17:5", pid 347, jiffies 4294676481 (age 312.157s)
  hex dump (first 32 bytes):
ac fd 00 00 00 00 00 00 00 d0 7e 17 80 ff ff ff  ..~.
00 00 00 00 00 00 00 00 00 59 8a 86 f3 ff ff ff  .Y..
  backtrace:
[<978ce31d>] kmem_cache_alloc_trace+0x194/0x298
[<6ea0398c>] _request_firmware+0x74/0x4e4
[<4da31ca0>] request_firmware+0x44/0x64
[<94572996>] qca_download_firmware+0x74/0x6e4 [btqca]
[<b24d615a>] qca_uart_setup+0xc0/0x2b0 [btqca]
[<364a6d5a>] qca_setup+0x204/0x570 [hci_uart]
[<6be1a544>] hci_uart_setup+0xa8/0x148 [hci_uart]
[<d64c0f4f>] hci_dev_do_open+0x144/0x530 [bluetooth]
[<f69f5110>] hci_power_on+0x84/0x288 [bluetooth]
[<d4151583>] process_one_work+0x210/0x420
[<3cf3dcfb>] worker_thread+0x2c4/0x3e4
[<7ccaf055>] kthread+0x124/0x134
[<bef1f723>] ret_from_fork+0x10/0x18
[<c36ee3dd>] 0x
unreferenced object 0xfff37b16de00 (size 128):
  comm "kworker/u17:5", pid 347, jiffies 4294676873 (age 311.766s)
  hex dump (first 32 bytes):
da 07 00 00 00 00 00 00 00 50 ff 0b 80 ff ff ff  .P..
00 00 00 00 00 00 00 00 00 dd 16 7b f3 ff ff ff  ...{
  backtrace:
[<978ce31d>] kmem_cache_alloc_trace+0x194/0x298
[<6ea0398c>] _request_firmware+0x74/0x4e4
[<4da31ca0>] request_firmware+0x44/0x64
[<94572996>] qca_download_firmware+0x74/0x6e4 [btqca]
[<0cde20a9>] qca_uart_setup+0x144/0x2b0 [btqca]
[<364a6d5a>] qca_setup+0x204/0x570 [hci_uart]
[<6be1a544>] hci_uart_setup+0xa8/0x148 [hci_uart]
[<d64c0f4f>] hci_dev_do_open+0x144/0x530 [bluetooth]
[<f69f5110>] hci_power_on+0x84/0x288 [bluetooth]
[<d4151583>] process_one_work+0x210/0x420
[<3cf3dcfb>] worker_thread+0x2c4/0x3e4
[<7ccaf055>] kthread+0x124/0x134
[<bef1f723>] ret_from_fork+0x10/0x18
[<c36ee3dd>] 0x

Make sure release_firmware() is called aftre
qca_inject_cmd_complete_event() to avoid the memory leak.

Fixes: 32646db8cc28 ("Bluetooth: btqca: inject command complete event
during fw download")
Signed-off-by: Claire Chang 
---
 drivers/bluetooth/btqca.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index 2221935fac7e..8f0fec5acade 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -344,7 +344,7 @@ static int qca_download_firmware(struct hci_dev 
*hdev,

 */
if (config->dnld_type == ROME_SKIP_EVT_VSE_CC ||
config->dnld_type == ROME_SKIP_EVT_VSE)
-   return qca_inject_cmd_complete_event(hdev);
+   ret = qca_inject_cmd_complete_event(hdev);

 out:
release_firmware(fw);


Change look fine to me.

Reviewed-by: Balakrishna Godavarthi 

--
Regards
Balakrishna.


Re: [PATCH v8] Bluetooth: btqca: inject command complete event during fw download

2019-04-30 Thread Balakrishna Godavarthi

Hi Harish,

On 2019-04-30 21:08, Matthias Kaehlcke wrote:

On Tue, Apr 30, 2019 at 02:27:33PM +0800, kbuild test robot wrote:

Hi Matthias,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on bluetooth-next/master]
[also build test ERROR on next-20190429]
[cannot apply to v5.1-rc7]
[if your patch is applied to the wrong git tree, please drop us a note 
to help improve the system]


url:
https://github.com/0day-ci/linux/commits/Matthias-Kaehlcke/Bluetooth-btqca-inject-command-complete-event-during-fw-download/20190430-125407
base:   
https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git 
master

config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross 
-O ~/bin/make.cross

chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.1.0 make.cross ARCH=xtensa

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot 

All errors (new ones prefixed by >>):

   drivers/bluetooth/btqca.c: In function 
'qca_inject_cmd_complete_event':

>> drivers/bluetooth/btqca.c:286:18: error: 'QCA_HCI_CC_SUCCESS' undeclared 
(first use in this function); did you mean 'QCA_HCI_CC_OPCODE'?
 skb_put_u8(skb, QCA_HCI_CC_SUCCESS);
 ^~
 QCA_HCI_CC_OPCODE
   drivers/bluetooth/btqca.c:286:18: note: each undeclared identifier 
is reported only once for each function it appears in


vim +286 drivers/bluetooth/btqca.c

   267
   268  static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
   269  {
   270  struct hci_event_hdr *hdr;
   271  struct hci_ev_cmd_complete *evt;
   272  struct sk_buff *skb;
   273
   274		skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, 
GFP_KERNEL);

   275  if (!skb)
   276  return -ENOMEM;
   277
   278  hdr = skb_put(skb, sizeof(*hdr));
   279  hdr->evt = HCI_EV_CMD_COMPLETE;
   280  hdr->plen = sizeof(*evt) + 1;
   281
   282  evt = skb_put(skb, sizeof(*evt));
   283  evt->ncmd = 1;
   284  evt->opcode = HCI_OP_NOP;
   285
 > 286   skb_put_u8(skb, QCA_HCI_CC_SUCCESS);


Oh, I changed it in my tree, but somehow missed to include this file
in the commit ...

I'll fix it in the next version. Since I expect the change to remain
controversial I'll wait a bit for other comments before sending out
v9.

Thanks

Matthias


[Bala]: can you check whether this change  is applicable for wcn3998 as 
well.


@Matthias, Thanks Matthias for taking Up :)

--
Regards
Balakrishna.


Re: [PATCH v3 1/2] Bluetooth: hci_qca: Rename STATE_ to QCA_

2019-04-30 Thread Balakrishna Godavarthi

Hi Mathhias,

On 2019-04-30 04:51, Matthias Kaehlcke wrote:

Rename STATE_IN_BAND_SLEEP_ENABLED to QCA_IBS_ENABLED. The constant
represents a flag (multiple flags can be set at once), not a unique
state of the controller or driver.

Also make the flag an enum value instead of a pre-processor constant
(more flags will be added to the enum group by another patch).

Signed-off-by: Matthias Kaehlcke 
---
Changes in v3:
- rename STATE_IN_BAND_SLEEP_ENABLED to QCA_IBS_ENABLED

Changes in v2:
- don't use BIT()
- change to enum type
- updated commit message
---
 drivers/bluetooth/hci_qca.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index c53ee8d8ca15..57322c42bb2d 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -54,9 +54,6 @@
 #define HCI_IBS_WAKE_ACK   0xFC
 #define HCI_MAX_IBS_SIZE   10

-/* Controller states */
-#define STATE_IN_BAND_SLEEP_ENABLED1
-
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
 #define CMD_TRANS_TIMEOUT_MS   100
@@ -67,6 +64,10 @@
 /* Controller debug log header */
 #define QCA_DEBUG_HANDLE   0x2EDC

+enum qca_flags {
+   QCA_IBS_ENABLED,
+};
+
 /* HCI_IBS transmit side sleep protocol states */
 enum tx_ibs_states {
HCI_IBS_TX_ASLEEP,
@@ -792,7 +793,7 @@ static int qca_enqueue(struct hci_uart *hu, struct
sk_buff *skb)
/* Don't go to sleep in middle of patch download or
 * Out-Of-Band(GPIOs control) sleep is selected.
 */
-   if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags)) {
+   if (!test_bit(QCA_IBS_ENABLED, >flags)) {
skb_queue_tail(>txq, skb);
spin_unlock_irqrestore(>hci_ibs_lock, flags);
return 0;
@@ -1202,7 +1203,7 @@ static int qca_setup(struct hci_uart *hu)
return ret;

/* Patch downloading has to be done without IBS mode */
-   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   clear_bit(QCA_IBS_ENABLED, >flags);

if (qca_is_wcn399x(soc_type)) {
bt_dev_info(hdev, "setting up wcn3990");
@@ -1246,7 +1247,7 @@ static int qca_setup(struct hci_uart *hu)
/* Setup patch / NVM configurations */
ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver);
if (!ret) {
-   set_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   set_bit(QCA_IBS_ENABLED, >flags);
qca_debugfs_init(hdev);
} else if (ret == -ENOENT) {
/* No patch/nvm-config found, run with original fw/config */
@@ -1315,7 +1316,7 @@ static void qca_power_shutdown(struct hci_uart 
*hu)

 * data in skb's.
 */
spin_lock_irqsave(>hci_ibs_lock, flags);
-   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   clear_bit(QCA_IBS_ENABLED, >flags);
qca_flush(hu);
spin_unlock_irqrestore(>hci_ibs_lock, flags);


Change looks fine to me.

Reviewed-by: Balakrishna Godavarthi 
--
Regards
Balakrishna.


Re: [RFC v1] Bluetooth: hci_core: Don't stop BT if the BD address missing in dts

2019-04-24 Thread Balakrishna Godavarthi

Hi Harish,

On 2019-04-24 12:34, Harish Bandi wrote:

Hi Balakrishna,

On 2019-04-23 22:05, Marcel Holtmann wrote:

Hi Balakrishna,


When flag HCI_QUIRK_USE_BDADDR_PROPERTY is set, we will read the
bluetooth address from dts. If the bluetooth address node is missing
from the dts we will enable it controller UNCONFIGURED state.
This patch enables the normal flow even if the BD address is missing
from the dts tree.

Signed-off-by: Balakrishna Godavarthi 
---
net/bluetooth/hci_core.c | 2 --
1 file changed, 2 deletions(-)


can I get an ACK for this one?

Regards

Marcel


nit: it would be better if we print error message, if bd address 
missing in dts.


tested 20 times with bd address missing in dts.
tested 20 times with bd address available in dts.

Tested-by: Harish Bandi 


Thanks,
Harish


Thanks for testing will note this improvement and send an incremental 
patch.


--
Regards
Balakrishna.


[RFC v1] Bluetooth: hci_core: Don't stop BT if the BD address missing in dts

2019-04-18 Thread Balakrishna Godavarthi
When flag HCI_QUIRK_USE_BDADDR_PROPERTY is set, we will read the
bluetooth address from dts. If the bluetooth address node is missing
from the dts we will enable it controller UNCONFIGURED state.
This patch enables the normal flow even if the BD address is missing
from the dts tree.

Signed-off-by: Balakrishna Godavarthi 
---
 net/bluetooth/hci_core.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index d6b2540ba7f8..3d9175f130b3 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1460,8 +1460,6 @@ static int hci_dev_do_open(struct hci_dev *hdev)
hdev->set_bdaddr)
ret = hdev->set_bdaddr(hdev,
   >public_addr);
-   else
-   ret = -EADDRNOTAVAIL;
}
 
 setup_failed:
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[RFC PATCH v3] Bluetooth: hci_qca: Collect controller memory dump during SSR

2019-04-16 Thread Balakrishna Godavarthi
We will collect the ramdump of BT controller when hardware error event
received before rebooting the HCI layer. Before restarting a subsystem
or a process running on a subsystem, it is often required to request
either a subsystem or a process to perform proper cache dump and
software failure reason into a memory buffer which application
processor can retrieve afterwards. SW developers can often provide
initial investigation by looking into that debugging information.

Signed-off-by: Balakrishna Godavarthi 
---
changes v3:
  * used wakeup helper instead of polling while collecting dump.
  * directly coping the crash command to the skb instead of local buffer.
  * update review comments.
---
 drivers/bluetooth/hci_qca.c | 291 +++-
 1 file changed, 287 insertions(+), 4 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 237aea34b69f..2b9bcf811776 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -56,10 +57,12 @@
 
 /* Controller states */
 #define STATE_IN_BAND_SLEEP_ENABLED1
+#define STATE_MEMDUMP_COLLECTION   2
 
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
 #define CMD_TRANS_TIMEOUT_MS   100
+#define MEMDUMP_COLLECTION_TIMEOUT_MS  8000
 
 /* susclk rate */
 #define SUSCLK_RATE_32KHZ  32768
@@ -67,6 +70,13 @@
 /* Controller debug log header */
 #define QCA_DEBUG_HANDLE   0x2EDC
 
+/* Controller dump header */
+#define QCA_SSR_DUMP_HANDLE0x0108
+#define QCA_DUMP_PACKET_SIZE   255
+#define QCA_LAST_SEQUENCE_NUM  0x
+#define QCA_CRASHBYTE_PACKET_LEN   1100
+#define QCA_MEMDUMP_BYTE   0xFB
+
 /* HCI_IBS transmit side sleep protocol states */
 enum tx_ibs_states {
HCI_IBS_TX_ASLEEP,
@@ -89,12 +99,41 @@ enum hci_ibs_clock_state_vote {
HCI_IBS_RX_VOTE_CLOCK_OFF,
 };
 
+/* Controller memory dump states */
+enum qca_memdump_states {
+   QCA_MEMDUMP_IDLE,
+   QCA_MEMDUMP_COLLECTING,
+   QCA_MEMDUMP_COLLECTED,
+   QCA_MEMDUMP_TIMEOUT,
+};
+
+struct qca_memdump_data {
+   char *memdump_buf_head;
+   char *memdump_buf_tail;
+   u32 current_seq_no;
+   u32 received_dump;
+};
+
+struct qca_memdump_event_hdr {
+   __u8evt;
+   __u8plen;
+   __u16   opcode;
+   __u16   seq_no;
+   __u8reserved;
+} __packed;
+
+
+struct qca_dump_size {
+   u32 dump_size;
+} __packed;
+
 struct qca_data {
struct hci_uart *hu;
struct sk_buff *rx_skb;
struct sk_buff_head txq;
-   struct sk_buff_head tx_wait_q;  /* HCI_IBS wait queue   */
-   spinlock_t hci_ibs_lock;/* HCI_IBS state lock   */
+   struct sk_buff_head tx_wait_q;  /* HCI_IBS wait queue   */
+   struct sk_buff_head rx_memdump_q;   /* Memdump wait queue   */
+   spinlock_t hci_ibs_lock;/* HCI_IBS state lock   */
u8 tx_ibs_state;/* HCI_IBS transmit side power state*/
u8 rx_ibs_state;/* HCI_IBS receive side power state */
bool tx_vote;   /* Clock must be on for TX */
@@ -103,12 +142,17 @@ struct qca_data {
u32 tx_idle_delay;
struct timer_list wake_retrans_timer;
u32 wake_retrans;
+   struct timer_list memdump_timer;
+   u32 memdump_delay;
struct workqueue_struct *workqueue;
struct work_struct ws_awake_rx;
struct work_struct ws_awake_device;
struct work_struct ws_rx_vote_off;
struct work_struct ws_tx_vote_off;
+   struct work_struct ctrl_memdump_evt;
+   struct qca_memdump_data *qca_memdump;
unsigned long flags;
+   enum qca_memdump_states memdump_state;
 
/* For debugging purpose */
u64 ibs_sent_wacks;
@@ -173,6 +217,7 @@ struct qca_serdev {
 static int qca_power_setup(struct hci_uart *hu, bool on);
 static void qca_power_shutdown(struct hci_uart *hu);
 static int qca_power_off(struct hci_dev *hdev);
+static void qca_controller_memdump(struct work_struct *work);
 
 static void __serial_clock_on(struct tty_struct *tty)
 {
@@ -446,6 +491,21 @@ static void hci_ibs_wake_retrans_timeout(struct timer_list 
*t)
hci_uart_tx_wakeup(hu);
 }
 
+static void hci_memdump_timeout(struct timer_list *t)
+{
+   struct qca_data *qca = from_timer(qca, t, tx_idle_timer);
+   struct hci_uart *hu = qca->hu;
+   struct qca_memdump_data *qca_memdump = qca->qca_memdump;
+   char *memdump_buf = qca_memdump->memdump_buf_tail;
+
+   bt_dev_err(hu->hdev, "clearing allocated memory due to memdump 
timeout");
+   kfree(memdump_buf);
+   kfree(qca_memdump);
+   qca->memdump_state = QCA_MEMDUMP_TIMEOUT;
+   del_timer(>memdump_timer);
+   cancel_work_sync(>ctrl_memdump_evt);
+}
+
 /* Initialize protocol */
 static i

Re: [PATCH 2/2] Bluetooth: hci_qca: wcn3990: Drop baudrate change vendor event

2019-04-04 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-04-03 21:44, Matthias Kaehlcke wrote:

On Wed, Apr 03, 2019 at 11:53:26AM +0530, Balakrishna Godavarthi wrote:

+ Harish to update his findings on wcn3998.
Mean time i will perform a regression to detect the failure.


On my system it typically reproduces within a few dozen
iterations. Make sure your tree doesn't contain any custom BT patches,
even if they just add logging or fix the timeout during
initialization. Since this problem is timing sensitive it might get
masked. My tree is based on 4.19 LTS with all QCA BT related changes
on top:
https://chromium.googlesource.com/chromiumos/third_party/kernel/+/refs/heads/chromeos-4.19

I found some problems during initialization easier to reproduce
when binding and unbinding the device through sysfs, instead of
doing hciconfig up/down, this resembles more the initialization at
boot time.


[Bala]: I am able to replicate this issue.
are you seeing the below error message getting logged on the 
console in the issue case or an different error message.

Bluetooth: hci0: QCA TLV response size mismatch


On 2019-04-02 23:35, Matthias Kaehlcke wrote:
> On Tue, Apr 02, 2019 at 05:32:54PM +0530, Balakrishna Godavarthi wrote:
> > Hi Matthias,
> >
> > On 2019-04-01 22:42, Matthias Kaehlcke wrote:
> > > On Mon, Apr 01, 2019 at 01:48:23PM +0530, Balakrishna Godavarthi wrote:
> > > > Hi Matthias,
> > > >
> > > > On 2019-04-01 13:29, Balakrishna Godavarthi wrote:
> > > > > Hi Matthias,
> > > > >
> > > > > Sorry for the late reply i was on vacation.
> > > > >
> > > > > On 2019-03-08 05:00, Matthias Kaehlcke wrote:
> > > > > > On Thu, Mar 07, 2019 at 10:20:09AM -0800, Matthias Kaehlcke wrote:
> > > > > > > Hi Balakrishna,
> > > > > > >
> > > > > > > On Thu, Mar 07, 2019 at 10:35:08AM +0530, Balakrishna Godavarthi
> > > > > > > wrote:
> > > > > > > > hi Matthias,
> > > > > > > >
> > > > > > > > On 2019-03-07 06:10, Matthias Kaehlcke wrote:
> > > > > > > > > Firmware download to the WCN3990 often fails with a 'TLV 
response size
> > > > > > > > > mismatch' error:
> > > > > > > > >
> > > > > > > > > [  133.064659] Bluetooth: hci0: setting up wcn3990
> > > > > > > > > [  133.489150] Bluetooth: hci0: QCA controller version 
0x02140201
> > > > > > > > > [  133.495245] Bluetooth: hci0: QCA Downloading 
qca/crbtfw21.tlv
> > > > > > > > > [  133.507214] Bluetooth: hci0: QCA TLV response size mismatch
> > > > > > > > > [  133.513265] Bluetooth: hci0: QCA Failed to download patch 
(-84)
> > > > > > > > >
> > > > > > > > > This is caused by a vendor event that corresponds to an 
earlier command
> > > > > > > > > to change the baudrate. The event is not processed in the 
context of the
> > > > > > > > > baudrate change and later interpreted as response to the 
firmware
> > > > > > > > > download command (which is also a vendor command), but the 
driver
> > > > > > > > > detects
> > > > > > > > > that the event doesn't have the expected amount of associated 
data.
> > > > > > > > >
> > > > > > > > > More details:
> > > > > > > > >
> > > > > > > > > For the WCN3990 the vendor command for a baudrate change 
isn't sent as
> > > > > > > > > synchronous HCI command, because the controller sends the 
corresponding
> > > > > > > > > vendor event with the new baudrate. The event is received and 
decoded
> > > > > > > > > after the baudrate change of the host port.
> > > > > > > > >
> > > > > > > > > Identify the 'unused' event when it is received and don't add 
it to
> > > > > > > > > the queue of RX frames.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Matthias Kaehlcke 
> > > > > > > > > ---
> > > > > > > >
> > > > > > > > ...
> > > > > > > >
> > > > > > > > Can you test by reverting this change "94d6671473924".
> > > > > > >
> > > > > > > The issue is st

Re: [PATCH v2 1/2] Bluetooth: hci_qca: Load customized NVM based on the device property

2019-04-04 Thread Balakrishna Godavarthi

Hi Rocky,

On 2019-04-04 14:38, Rocky Liao wrote:
QCA BTSOC nvm is a customized file and different vendor/platoform may 
want

to have different BTSOC configuration via this file (e.g. Configure SCO
over PCM or I2S, Setting Tx power, etc.) This patch will allow vendors 
to
download different nvm file by reading a device property "nvm-postfix" 
as

the nvm file name postfix.

Signed-off-by: Rocky Liao 
---
Changes in v2:
  * added the property to the document file
Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt
  * fixed coding style warnings
  * moved the nvm-postfix to the last entry of the qca_serdev
---
 drivers/bluetooth/btqca.c   | 14 ++
 drivers/bluetooth/btqca.h   |  6 --
 drivers/bluetooth/hci_qca.c | 19 ++-
 3 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index 6122685..4e89286 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -332,7 +332,8 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev,
const bdaddr_t *bdaddr)
 EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);

 int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
-  enum qca_btsoc_type soc_type, u32 soc_ver)
+  enum qca_btsoc_type soc_type, u32 soc_ver,
+  const char *nvm_postfix)
 {
struct rome_config config;
int err;
@@ -368,9 +369,14 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t 
baudrate,

if (soc_type == QCA_WCN3990)
snprintf(config.fwname, sizeof(config.fwname),
 "qca/crnv%02x.bin", rom_ver);
-   else
-   snprintf(config.fwname, sizeof(config.fwname),
-"qca/nvm_%08x.bin", soc_ver);
+   else {
+   if (nvm_postfix)
+   snprintf(config.fwname, sizeof(config.fwname),
+"qca/nvm_%08x_%s.bin", soc_ver, nvm_postfix);
+   else
+   snprintf(config.fwname, sizeof(config.fwname),
+"qca/nvm_%08x.bin", soc_ver);
+   }

err = qca_download_firmware(hdev, );
if (err < 0) {
diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
index 6fdc25d..0dd6cd0 100644
--- a/drivers/bluetooth/btqca.h
+++ b/drivers/bluetooth/btqca.h
@@ -139,7 +139,8 @@ enum qca_btsoc_type {

 int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
-  enum qca_btsoc_type soc_type, u32 soc_ver);
+  enum qca_btsoc_type soc_type, u32 soc_ver,
+  const char *nvm_postfix);
 int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version);
 int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 #else
@@ -150,7 +151,8 @@ static inline int qca_set_bdaddr_rome(struct
hci_dev *hdev, const bdaddr_t *bdad
 }

 static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t 
baudrate,

-enum qca_btsoc_type soc_type, u32 soc_ver)
+enum qca_btsoc_type soc_type, u32 soc_ver,
+const char *nvm_postfix)
 {
return -EOPNOTSUPP;
 }
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 4ea995d..560e880 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -168,6 +168,7 @@ struct qca_serdev {
struct qca_power *bt_power;
u32 init_speed;
u32 oper_speed;
+   const char *nvm_postfix;


[Bala]: I guess your trying to the read the type of communication for 
SCO.
so i would recommend to change this to variable name to 
sco_com_type or might be to the use understandable name.
just an suggestion. Don't respin right away wait for other 
comments too :)



 };

 static int qca_power_setup(struct hci_uart *hu, bool on);
@@ -189,6 +190,17 @@ static enum qca_btsoc_type qca_soc_type(struct
hci_uart *hu)
return soc_type;
 }

+static const char *qca_get_nvm_postfix(struct hci_uart *hu)
+{
+   if (hu->serdev) {
+   struct qca_serdev *qsd = serdev_device_get_drvdata(hu->serdev);
+
+   return qsd->nvm_postfix;
+   } else {
+   return NULL;
+   }
+}
+
 static void __serial_clock_on(struct tty_struct *tty)
 {
/* TODO: Some chipset requires to enable UART clock on client
@@ -1191,6 +1203,7 @@ static int qca_setup(struct hci_uart *hu)
struct qca_data *qca = hu->priv;
unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200;
enum qca_btsoc_type soc_type = qca_soc_type(hu);
+   const char *nvm_postfix = qca_get_nvm_postfix(hu);
int ret;
int soc_ver = 0;

@@ -1241,7 +1254,8 @@ static int qca_setup(struct hci_uart *hu)

bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver);
/* Setup patch / NVM configurations */
-   ret = 

Re: [PATCH] Bluetooth: hci_qca: Load customized NVM based on the device property

2019-04-04 Thread Balakrishna Godavarthi

Hi Rocky,

On 2019-04-04 12:07, Rocky Liao wrote:
QCA BTSOC nvm is a customized file and different vendor/platoform may 
want
to have different BTSOC configuration via this file (e.g. Configure SCO 
over
PCM or I2S, Setting Tx power, etc.) This patch will allow vendors to 
download
different nvm file by reading a device property as the nvm file name 
postfix.




[Bala]: add the property which your reading to the documentation file.
"Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt"


Signed-off-by: Rocky Liao 
---
 drivers/bluetooth/btqca.c   | 13 +
 drivers/bluetooth/btqca.h   |  4 ++--
 drivers/bluetooth/hci_qca.c | 18 +-
 3 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index 6122685..81e42f3 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -332,7 +332,7 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev,
const bdaddr_t *bdaddr)
 EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);

 int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
-  enum qca_btsoc_type soc_type, u32 soc_ver)
+		   enum qca_btsoc_type soc_type, u32 soc_ver, const char 
*nvm_postfix)

 {
struct rome_config config;
int err;
@@ -368,9 +368,14 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t 
baudrate,

if (soc_type == QCA_WCN3990)
snprintf(config.fwname, sizeof(config.fwname),
 "qca/crnv%02x.bin", rom_ver);
-   else
-   snprintf(config.fwname, sizeof(config.fwname),
-"qca/nvm_%08x.bin", soc_ver);
+   else {
+   if (NULL == nvm_postfix)

[Bala]:
   something like this is more readable.
if (nvm_postfix)
append the nvm postfix string.
else
go with an default name.


+   snprintf(config.fwname, sizeof(config.fwname),
+"qca/nvm_%08x.bin", soc_ver);
+   else
+   snprintf(config.fwname, sizeof(config.fwname),
+"qca/nvm_%08x_%s.bin", soc_ver, nvm_postfix);
+   }

err = qca_download_firmware(hdev, );
if (err < 0) {
diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
index 6fdc25d..60a868f 100644
--- a/drivers/bluetooth/btqca.h
+++ b/drivers/bluetooth/btqca.h
@@ -139,7 +139,7 @@ enum qca_btsoc_type {

 int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
-  enum qca_btsoc_type soc_type, u32 soc_ver);
+		   enum qca_btsoc_type soc_type, u32 soc_ver, const char 
*nvm_postfix);

 int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version);
 int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 #else
@@ -150,7 +150,7 @@ static inline int qca_set_bdaddr_rome(struct
hci_dev *hdev, const bdaddr_t *bdad
 }

 static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t 
baudrate,

-enum qca_btsoc_type soc_type, u32 soc_ver)
+ enum qca_btsoc_type soc_type, u32 soc_ver, const char 
*nvm_postfix)

 {
return -EOPNOTSUPP;
 }
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 4ea995d..f495f3b 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -164,6 +164,7 @@ struct qca_serdev {
struct hci_uart  serdev_hu;
struct gpio_desc *bt_en;
struct clk   *susclk;
+   const char   *nvm_postfix;


[Bala]: nit: add the entry at last is preferred.


enum qca_btsoc_type btsoc_type;
struct qca_power *bt_power;
u32 init_speed;
@@ -189,6 +190,17 @@ static enum qca_btsoc_type qca_soc_type(struct
hci_uart *hu)
return soc_type;
 }

+static const char *qca_get_nvm_postfix(struct hci_uart *hu)
+{
+   if (hu->serdev) {
+   struct qca_serdev *qsd = serdev_device_get_drvdata(hu->serdev);
+
+   return qsd->nvm_postfix;
+   } else {
+   return NULL;
+   }
+}
+
 static void __serial_clock_on(struct tty_struct *tty)
 {
/* TODO: Some chipset requires to enable UART clock on client
@@ -1191,6 +1203,7 @@ static int qca_setup(struct hci_uart *hu)
struct qca_data *qca = hu->priv;
unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200;
enum qca_btsoc_type soc_type = qca_soc_type(hu);
+   const char *nvm_postfix = qca_get_nvm_postfix(hu);
int ret;
int soc_ver = 0;

@@ -1241,7 +1254,7 @@ static int qca_setup(struct hci_uart *hu)

bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver);
/* Setup patch / NVM configurations */
-   ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver);
+	ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver, 
nvm_postfix);

if (!ret) {

Re: [PATCH 2/2] Bluetooth: hci_qca: wcn3990: Drop baudrate change vendor event

2019-04-03 Thread Balakrishna Godavarthi

+ Harish to update his findings on wcn3998.
Mean time i will perform a regression to detect the failure.

On 2019-04-02 23:35, Matthias Kaehlcke wrote:

On Tue, Apr 02, 2019 at 05:32:54PM +0530, Balakrishna Godavarthi wrote:

Hi Matthias,

On 2019-04-01 22:42, Matthias Kaehlcke wrote:
> On Mon, Apr 01, 2019 at 01:48:23PM +0530, Balakrishna Godavarthi wrote:
> > Hi Matthias,
> >
> > On 2019-04-01 13:29, Balakrishna Godavarthi wrote:
> > > Hi Matthias,
> > >
> > > Sorry for the late reply i was on vacation.
> > >
> > > On 2019-03-08 05:00, Matthias Kaehlcke wrote:
> > > > On Thu, Mar 07, 2019 at 10:20:09AM -0800, Matthias Kaehlcke wrote:
> > > > > Hi Balakrishna,
> > > > >
> > > > > On Thu, Mar 07, 2019 at 10:35:08AM +0530, Balakrishna Godavarthi
> > > > > wrote:
> > > > > > hi Matthias,
> > > > > >
> > > > > > On 2019-03-07 06:10, Matthias Kaehlcke wrote:
> > > > > > > Firmware download to the WCN3990 often fails with a 'TLV response 
size
> > > > > > > mismatch' error:
> > > > > > >
> > > > > > > [  133.064659] Bluetooth: hci0: setting up wcn3990
> > > > > > > [  133.489150] Bluetooth: hci0: QCA controller version 0x02140201
> > > > > > > [  133.495245] Bluetooth: hci0: QCA Downloading qca/crbtfw21.tlv
> > > > > > > [  133.507214] Bluetooth: hci0: QCA TLV response size mismatch
> > > > > > > [  133.513265] Bluetooth: hci0: QCA Failed to download patch (-84)
> > > > > > >
> > > > > > > This is caused by a vendor event that corresponds to an earlier 
command
> > > > > > > to change the baudrate. The event is not processed in the context 
of the
> > > > > > > baudrate change and later interpreted as response to the firmware
> > > > > > > download command (which is also a vendor command), but the driver
> > > > > > > detects
> > > > > > > that the event doesn't have the expected amount of associated 
data.
> > > > > > >
> > > > > > > More details:
> > > > > > >
> > > > > > > For the WCN3990 the vendor command for a baudrate change isn't 
sent as
> > > > > > > synchronous HCI command, because the controller sends the 
corresponding
> > > > > > > vendor event with the new baudrate. The event is received and 
decoded
> > > > > > > after the baudrate change of the host port.
> > > > > > >
> > > > > > > Identify the 'unused' event when it is received and don't add it 
to
> > > > > > > the queue of RX frames.
> > > > > > >
> > > > > > > Signed-off-by: Matthias Kaehlcke 
> > > > > > > ---
> > > > > >
> > > > > > ...
> > > > > >
> > > > > > Can you test by reverting this change "94d6671473924".
> > > > >
> > > > > The issue is still reproducible.
> > > > >
> > > > > > We need at least 15ms minimum delay for the soc to change its baud 
rate and
> > > > > > respond to the with command complete event.
> > > > >
> > > > > The baudrate change has clearly been successful when the problem is
> > > > > observed, since the host receives the vendor event with the new
> > > > > baudrate.
> > > >
> > > > I forgot to mention this earlier: the controller doesn't send a
> > > > command complete event for the command, or at least not a correct
> > > > one.
> > > >
> > > > That's the data that is received:
> > > >
> > > > 04 0e 04 01 00 00 00
> > > > ~~ ~~
> > > >
> > > [Bala]: can you share me the command sent and event recevied.
> > >  I see that we receive a command complete event for the baud rate
> > > change command.
> > >
> > > command sent: 01 48 fc 01 11
> > > vendor specific event: 04 ff 02 92 01
> > > command complete event: 04 0e 04 01 00 00 00.
> > >
> > >
> > >
> > > > This is *a* command complete event, but the opcode is 0x instead
> > > > of the earlier command. The same happens for the firmware
> > > > download/read version command, which is the reason why the command
>

Re: [PATCH 2/2] Bluetooth: hci_qca: wcn3990: Drop baudrate change vendor event

2019-04-02 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-04-01 22:42, Matthias Kaehlcke wrote:

On Mon, Apr 01, 2019 at 01:48:23PM +0530, Balakrishna Godavarthi wrote:

Hi Matthias,

On 2019-04-01 13:29, Balakrishna Godavarthi wrote:
> Hi Matthias,
>
> Sorry for the late reply i was on vacation.
>
> On 2019-03-08 05:00, Matthias Kaehlcke wrote:
> > On Thu, Mar 07, 2019 at 10:20:09AM -0800, Matthias Kaehlcke wrote:
> > > Hi Balakrishna,
> > >
> > > On Thu, Mar 07, 2019 at 10:35:08AM +0530, Balakrishna Godavarthi
> > > wrote:
> > > > hi Matthias,
> > > >
> > > > On 2019-03-07 06:10, Matthias Kaehlcke wrote:
> > > > > Firmware download to the WCN3990 often fails with a 'TLV response size
> > > > > mismatch' error:
> > > > >
> > > > > [  133.064659] Bluetooth: hci0: setting up wcn3990
> > > > > [  133.489150] Bluetooth: hci0: QCA controller version 0x02140201
> > > > > [  133.495245] Bluetooth: hci0: QCA Downloading qca/crbtfw21.tlv
> > > > > [  133.507214] Bluetooth: hci0: QCA TLV response size mismatch
> > > > > [  133.513265] Bluetooth: hci0: QCA Failed to download patch (-84)
> > > > >
> > > > > This is caused by a vendor event that corresponds to an earlier 
command
> > > > > to change the baudrate. The event is not processed in the context of 
the
> > > > > baudrate change and later interpreted as response to the firmware
> > > > > download command (which is also a vendor command), but the driver
> > > > > detects
> > > > > that the event doesn't have the expected amount of associated data.
> > > > >
> > > > > More details:
> > > > >
> > > > > For the WCN3990 the vendor command for a baudrate change isn't sent as
> > > > > synchronous HCI command, because the controller sends the 
corresponding
> > > > > vendor event with the new baudrate. The event is received and decoded
> > > > > after the baudrate change of the host port.
> > > > >
> > > > > Identify the 'unused' event when it is received and don't add it to
> > > > > the queue of RX frames.
> > > > >
> > > > > Signed-off-by: Matthias Kaehlcke 
> > > > > ---
> > > >
> > > > ...
> > > >
> > > > Can you test by reverting this change "94d6671473924".
> > >
> > > The issue is still reproducible.
> > >
> > > > We need at least 15ms minimum delay for the soc to change its baud rate 
and
> > > > respond to the with command complete event.
> > >
> > > The baudrate change has clearly been successful when the problem is
> > > observed, since the host receives the vendor event with the new
> > > baudrate.
> >
> > I forgot to mention this earlier: the controller doesn't send a
> > command complete event for the command, or at least not a correct
> > one.
> >
> > That's the data that is received:
> >
> > 04 0e 04 01 00 00 00
> > ~~ ~~
> >
> [Bala]: can you share me the command sent and event recevied.
>  I see that we receive a command complete event for the baud rate
> change command.
>
> command sent: 01 48 fc 01 11
> vendor specific event: 04 ff 02 92 01
> command complete event: 04 0e 04 01 00 00 00.
>
>
>
> > This is *a* command complete event, but the opcode is 0x instead
> > of the earlier command. The same happens for the firmware
> > download/read version command, which is the reason why the command
> > complete injection mess
> > (https://lore.kernel.org/patchwork/patch/1027955/) is needed in one
> > way or another.
> >
> [Bala]: fw download approach is different where we use
> __hci_cmd_sync() where as here we use hci_uart_tx_wakeup()
> which directly calls the hci_uart_write_work(). so even we
> send an valid opcode or not for baudrate change will bot matter.
>
[Bala]: i miss understood the comment. Yes your true. in the all 
vendor

commands SoC responds with an 0x opcode.


And IIUC this is not compliant with the spec, or at least the BT core
expects the actual opcode to consider the command to be completed.


[Bala]: Did you try increasing the the baud rate change timeout to 50ms 
instead of 10ms.

i suspect it is an timing issue.
I have see on the hardware sniffer that the chip is responding 
with command complete event with

the newer baud rate after 15ms.
--
Regards
Balakrishna.


[PATCH v2] Bluetooth: hci_qca: Give enough time to ROME controller to bootup.

2019-04-01 Thread Balakrishna Godavarthi
This patch enables enough time to ROME controller to bootup
after we bring the enable pin out of reset.

Fixes: 05ba533c5c11 ("Bluetooth: hci_qca: Add serdev support").
Signed-off-by: Balakrishna Godavarthi 
Reviewed-by: Rocky Liao 
Tested-by: Rocky Liao 
Tested-by: Claire Chang 
---
Changes in v2:
  * added fixes tag in the commit text.
---
 drivers/bluetooth/hci_qca.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 4ea995d610d2..a80c3bc90904 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -523,6 +523,8 @@ static int qca_open(struct hci_uart *hu)
qcadev = serdev_device_get_drvdata(hu->serdev);
if (qcadev->btsoc_type != QCA_WCN3990) {
gpiod_set_value_cansleep(qcadev->bt_en, 1);
+   /* Controller needs time to bootup. */
+   msleep(150);
} else {
hu->init_speed = qcadev->init_speed;
hu->oper_speed = qcadev->oper_speed;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH 2/2] Bluetooth: hci_qca: wcn3990: Drop baudrate change vendor event

2019-04-01 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-04-01 13:29, Balakrishna Godavarthi wrote:

Hi Matthias,

Sorry for the late reply i was on vacation.

On 2019-03-08 05:00, Matthias Kaehlcke wrote:

On Thu, Mar 07, 2019 at 10:20:09AM -0800, Matthias Kaehlcke wrote:

Hi Balakrishna,

On Thu, Mar 07, 2019 at 10:35:08AM +0530, Balakrishna Godavarthi 
wrote:

> hi Matthias,
>
> On 2019-03-07 06:10, Matthias Kaehlcke wrote:
> > Firmware download to the WCN3990 often fails with a 'TLV response size
> > mismatch' error:
> >
> > [  133.064659] Bluetooth: hci0: setting up wcn3990
> > [  133.489150] Bluetooth: hci0: QCA controller version 0x02140201
> > [  133.495245] Bluetooth: hci0: QCA Downloading qca/crbtfw21.tlv
> > [  133.507214] Bluetooth: hci0: QCA TLV response size mismatch
> > [  133.513265] Bluetooth: hci0: QCA Failed to download patch (-84)
> >
> > This is caused by a vendor event that corresponds to an earlier command
> > to change the baudrate. The event is not processed in the context of the
> > baudrate change and later interpreted as response to the firmware
> > download command (which is also a vendor command), but the driver
> > detects
> > that the event doesn't have the expected amount of associated data.
> >
> > More details:
> >
> > For the WCN3990 the vendor command for a baudrate change isn't sent as
> > synchronous HCI command, because the controller sends the corresponding
> > vendor event with the new baudrate. The event is received and decoded
> > after the baudrate change of the host port.
> >
> > Identify the 'unused' event when it is received and don't add it to
> > the queue of RX frames.
> >
> > Signed-off-by: Matthias Kaehlcke 
> > ---
>
> ...
>
> Can you test by reverting this change "94d6671473924".

The issue is still reproducible.

> We need at least 15ms minimum delay for the soc to change its baud rate and
> respond to the with command complete event.

The baudrate change has clearly been successful when the problem is
observed, since the host receives the vendor event with the new
baudrate.


I forgot to mention this earlier: the controller doesn't send a
command complete event for the command, or at least not a correct
one.

That's the data that is received:

04 0e 04 01 00 00 00
~~ ~~


[Bala]: can you share me the command sent and event recevied.
 I see that we receive a command complete event for the baud rate
change command.

command sent: 01 48 fc 01 11
vendor specific event: 04 ff 02 92 01
command complete event: 04 0e 04 01 00 00 00.




This is *a* command complete event, but the opcode is 0x instead
of the earlier command. The same happens for the firmware
download/read version command, which is the reason why the command
complete injection mess
(https://lore.kernel.org/patchwork/patch/1027955/) is needed in one
way or another.


[Bala]: fw download approach is different where we use
__hci_cmd_sync() where as here we use hci_uart_tx_wakeup()
which directly calls the hci_uart_write_work(). so even we
send an valid opcode or not for baudrate change will bot matter.

[Bala]: i miss understood the comment. Yes your true. in the all vendor 
commands SoC responds with an 0x opcode.



I wished Qualcomm FW developers would get their act together and:

- send actual command complete events :
- acknowledge a baudrate change request using the current baudrate
  like Broadcom and Intel chips apparently do

this would have saved countless hours of debugging and implementing
quirky workarounds ...

Maybe there is hope for future chips (hint, hint)?


[Bala]: will take this forward to the SoC teams.


--
Regards
Balakrishna.


Re: [PATCH 2/2] Bluetooth: hci_qca: wcn3990: Drop baudrate change vendor event

2019-04-01 Thread Balakrishna Godavarthi

Hi Matthias,

Sorry for the late reply i was on vacation.

On 2019-03-08 05:00, Matthias Kaehlcke wrote:

On Thu, Mar 07, 2019 at 10:20:09AM -0800, Matthias Kaehlcke wrote:

Hi Balakrishna,

On Thu, Mar 07, 2019 at 10:35:08AM +0530, Balakrishna Godavarthi 
wrote:

> hi Matthias,
>
> On 2019-03-07 06:10, Matthias Kaehlcke wrote:
> > Firmware download to the WCN3990 often fails with a 'TLV response size
> > mismatch' error:
> >
> > [  133.064659] Bluetooth: hci0: setting up wcn3990
> > [  133.489150] Bluetooth: hci0: QCA controller version 0x02140201
> > [  133.495245] Bluetooth: hci0: QCA Downloading qca/crbtfw21.tlv
> > [  133.507214] Bluetooth: hci0: QCA TLV response size mismatch
> > [  133.513265] Bluetooth: hci0: QCA Failed to download patch (-84)
> >
> > This is caused by a vendor event that corresponds to an earlier command
> > to change the baudrate. The event is not processed in the context of the
> > baudrate change and later interpreted as response to the firmware
> > download command (which is also a vendor command), but the driver
> > detects
> > that the event doesn't have the expected amount of associated data.
> >
> > More details:
> >
> > For the WCN3990 the vendor command for a baudrate change isn't sent as
> > synchronous HCI command, because the controller sends the corresponding
> > vendor event with the new baudrate. The event is received and decoded
> > after the baudrate change of the host port.
> >
> > Identify the 'unused' event when it is received and don't add it to
> > the queue of RX frames.
> >
> > Signed-off-by: Matthias Kaehlcke 
> > ---
>
> ...
>
> Can you test by reverting this change "94d6671473924".

The issue is still reproducible.

> We need at least 15ms minimum delay for the soc to change its baud rate and
> respond to the with command complete event.

The baudrate change has clearly been successful when the problem is
observed, since the host receives the vendor event with the new
baudrate.


I forgot to mention this earlier: the controller doesn't send a
command complete event for the command, or at least not a correct
one.

That's the data that is received:

04 0e 04 01 00 00 00
~~ ~~


[Bala]: can you share me the command sent and event recevied.
 I see that we receive a command complete event for the baud rate change 
command.


command sent: 01 48 fc 01 11
vendor specific event: 04 ff 02 92 01
command complete event: 04 0e 04 01 00 00 00.




This is *a* command complete event, but the opcode is 0x instead
of the earlier command. The same happens for the firmware
download/read version command, which is the reason why the command
complete injection mess
(https://lore.kernel.org/patchwork/patch/1027955/) is needed in one
way or another.

[Bala]: fw download approach is different where we use __hci_cmd_sync() 
where as here we use hci_uart_tx_wakeup()
which directly calls the hci_uart_write_work(). so even we send 
an valid opcode or not for baudrate change will bot matter.



I wished Qualcomm FW developers would get their act together and:

- send actual command complete events :
- acknowledge a baudrate change request using the current baudrate
  like Broadcom and Intel chips apparently do

this would have saved countless hours of debugging and implementing
quirky workarounds ...

Maybe there is hope for future chips (hint, hint)?


[Bala]: will take this forward to the SoC teams.

--
Regards
Balakrishna.


Re: [PATCH v2 1/2] Bluetooth: hci_qca: Rename STATE_ to QCA_

2019-04-01 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-03-13 02:12, Matthias Kaehlcke wrote:

Rename STATE_IN_BAND_SLEEP_ENABLED to QCA_IN_BAND_SLEEP_ENABLED.
The constant represents a flag (multiple flags can be set at once),
not a unique state of the controller or driver.

Also make the flag an enum value instead of a pre-processor constant
(more flags will be added to the enum group by another patch).

Signed-off-by: Matthias Kaehlcke 
---
Changes in v2:
- don't use BIT()
- change to enum type
- updated commit message
---
 drivers/bluetooth/hci_qca.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 237aea34b69f..1b7ba9e9e08a 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -54,9 +54,6 @@
 #define HCI_IBS_WAKE_ACK   0xFC
 #define HCI_MAX_IBS_SIZE   10

-/* Controller states */
-#define STATE_IN_BAND_SLEEP_ENABLED1
-
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
 #define CMD_TRANS_TIMEOUT_MS   100
@@ -67,6 +64,10 @@
 /* Controller debug log header */
 #define QCA_DEBUG_HANDLE   0x2EDC

+enum qca_flags {
+   QCA_IN_BAND_SLEEP_ENABLED,
+};
+


[Bala]: I would recommend to go with QCA_IBS_ENABLED as IBS is 
abbreviated as In band sleep.



 /* HCI_IBS transmit side sleep protocol states */
 enum tx_ibs_states {
HCI_IBS_TX_ASLEEP,
@@ -775,7 +776,7 @@ static int qca_enqueue(struct hci_uart *hu, struct
sk_buff *skb)
/* Don't go to sleep in middle of patch download or
 * Out-Of-Band(GPIOs control) sleep is selected.
 */
-   if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags)) {
+   if (!test_bit(QCA_IN_BAND_SLEEP_ENABLED, >flags)) {
skb_queue_tail(>txq, skb);
spin_unlock_irqrestore(>hci_ibs_lock, flags);
return 0;
@@ -1192,7 +1193,7 @@ static int qca_setup(struct hci_uart *hu)
return ret;

/* Patch downloading has to be done without IBS mode */
-   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   clear_bit(QCA_IN_BAND_SLEEP_ENABLED, >flags);

if (qcadev->btsoc_type == QCA_WCN3990) {
bt_dev_info(hdev, "setting up wcn3990");
@@ -1236,7 +1237,7 @@ static int qca_setup(struct hci_uart *hu)
/* Setup patch / NVM configurations */
 	ret = qca_uart_setup(hdev, qca_baudrate, qcadev->btsoc_type, 
soc_ver);

if (!ret) {
-   set_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   set_bit(QCA_IN_BAND_SLEEP_ENABLED, >flags);
qca_debugfs_init(hdev);
} else if (ret == -ENOENT) {
/* No patch/nvm-config found, run with original fw/config */
@@ -1294,7 +1295,7 @@ static void qca_power_shutdown(struct hci_uart 
*hu)

 * data in skb's.
 */
spin_lock_irqsave(>hci_ibs_lock, flags);
-   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   clear_bit(QCA_IN_BAND_SLEEP_ENABLED, >flags);
qca_flush(hu);
spin_unlock_irqrestore(>hci_ibs_lock, flags);


--
Regards
Balakrishna.


Re: [PATCH] Bluetooth: hci_qca: Fix crash with non-serdev devices

2019-04-01 Thread Balakrishna Godavarthi

On 2019-03-14 05:22, Matthias Kaehlcke wrote:

qca_set_baudrate() calls serdev_device_wait_until_sent() assuming that
the HCI is always associated with a serdev device. This isn't true for
ROME controllers instantiated through ldisc, where the call causes a
crash due to a NULL pointer dereferentiation. Only call the function
when we have a serdev device. The timeout for ROME devices at the end
of qca_set_baudrate() is long enough to be reasonably sure that the
command was sent.

Fixes: fa9ad876b8e0 ("Bluetooth: hci_qca: Add support for Qualcomm
Bluetooth chip wcn3990")
Reported-by: Balakrishna Godavarthi 
Reported-by: Rocky Liao 
Signed-off-by: Matthias Kaehlcke 
---
 drivers/bluetooth/hci_qca.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 4ea995d610d2..714a6a16f9d5 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1004,7 +1004,8 @@ static int qca_set_baudrate(struct hci_dev
*hdev, uint8_t baudrate)
while (!skb_queue_empty(>txq))
usleep_range(100, 200);

-   serdev_device_wait_until_sent(hu->serdev,
+   if (hu->serdev)
+   serdev_device_wait_until_sent(hu->serdev,
  msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));

/* Give the controller time to process the request */


Reviewed-by: Balakrishna Godavarthi 

--
Regards
Balakrishna.


Re: [PATCH v6 1/2] Bluetooth: hci_qca: Added support for WCN3998

2019-03-27 Thread Balakrishna Godavarthi
assert RTS while
 * changing the baudrate of chip and host.
 */
-   if (soc_type == QCA_WCN3990)
+   if (qca_is_wcn399x(soc_type))
hci_uart_set_flow_control(hu, true);

qca_baudrate = qca_get_baudrate_value(speed);
@@ -1128,7 +1128,7 @@ static int qca_set_speed(struct hci_uart *hu,
enum qca_speed_type speed_type)
host_set_baudrate(hu, speed);

 error:
-   if (soc_type == QCA_WCN3990)
+   if (qca_is_wcn399x(soc_type))
hci_uart_set_flow_control(hu, false);
}

@@ -1201,7 +1201,7 @@ static int qca_setup(struct hci_uart *hu)
/* Patch downloading has to be done without IBS mode */
clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);

-   if (soc_type == QCA_WCN3990) {
+   if (qca_is_wcn399x(soc_type)) {
bt_dev_info(hdev, "setting up wcn3990");


[Bala]: nit: if you respin the serie.
 let us make this "wcn3990" string in the info message as 
wcn399x or with actual chip name.




/* Enable NON_PERSISTENT_SETUP QUIRK to ensure to execute
@@ -1232,7 +1232,7 @@ static int qca_setup(struct hci_uart *hu)
qca_baudrate = qca_get_baudrate_value(speed);
}

-   if (soc_type != QCA_WCN3990) {
+   if (!qca_is_wcn399x(soc_type)) {
/* Get QCA version information */
ret = qca_read_soc_version(hdev, _ver);
if (ret)
@@ -1257,7 +1257,7 @@ static int qca_setup(struct hci_uart *hu)
}

/* Setup bdaddr */
-   if (soc_type == QCA_WCN3990)
+   if (qca_is_wcn399x(soc_type))
hu->hdev->set_bdaddr = qca_set_bdaddr;
else
hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
@@ -1280,7 +1280,7 @@ static int qca_setup(struct hci_uart *hu)
.dequeue= qca_dequeue,
 };

-static const struct qca_vreg_data qca_soc_data = {
+static const struct qca_vreg_data qca_soc_data_wcn3990 = {
.soc_type = QCA_WCN3990,
.vregs = (struct qca_vreg []) {
{ "vddio",   180, 190,  15000  },
@@ -1291,6 +1291,17 @@ static int qca_setup(struct hci_uart *hu)
.num_vregs = 4,
 };

+static const struct qca_vreg_data qca_soc_data_wcn3998 = {
+   .soc_type = QCA_WCN3998,
+   .vregs = (struct qca_vreg []) {
+   { "vddio",   180, 190,  1  },
+   { "vddxo",   180, 190,  8  },
+   { "vddrf",   130, 1352000,  30 },
+   { "vddch0",  330, 330,  45 },
+   },
+   .num_vregs = 4,
+};
+
 static void qca_power_shutdown(struct hci_uart *hu)
 {
struct qca_data *qca = hu->priv;
@@ -1424,8 +1435,8 @@ static int qca_serdev_probe(struct serdev_device 
*serdev)

qcadev->serdev_hu.serdev = serdev;
data = of_device_get_match_data(>dev);
serdev_device_set_drvdata(serdev, qcadev);
-   if (data && data->soc_type == QCA_WCN3990) {
-   qcadev->btsoc_type = QCA_WCN3990;
+   if (data && qca_is_wcn399x(data->soc_type)) {
+   qcadev->btsoc_type = data->soc_type;
qcadev->bt_power = devm_kzalloc(>dev,
sizeof(struct qca_power),
GFP_KERNEL);
@@ -1489,7 +1500,7 @@ static void qca_serdev_remove(struct
serdev_device *serdev)
 {
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);

-   if (qcadev->btsoc_type == QCA_WCN3990)
+   if (qca_is_wcn399x(qcadev->btsoc_type))
qca_power_shutdown(>serdev_hu);
else
clk_disable_unprepare(qcadev->susclk);
@@ -1499,7 +1510,8 @@ static void qca_serdev_remove(struct
serdev_device *serdev)

 static const struct of_device_id qca_bluetooth_of_match[] = {
{ .compatible = "qcom,qca6174-bt" },
-   { .compatible = "qcom,wcn3990-bt", .data = _soc_data},
+   { .compatible = "qcom,wcn3990-bt", .data = _soc_data_wcn3990},
+   { .compatible = "qcom,wcn3998-bt", .data = _soc_data_wcn3998},
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);


Reviewed-by: Balakrishna Godavarthi 

--
Regards
Balakrishna.


Re: [PATCH v1] Bluetooth: hci_qca: Enable the ldisc for ROME for x86 platforms.

2019-03-07 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-03-08 02:12, Matthias Kaehlcke wrote:

Hi Balakrishna,

On Thu, Mar 07, 2019 at 03:47:22PM +0530, Balakrishna Godavarthi wrote:

When using btattach to setup Rome over ldisc we observed a crash
in qca_setup as it will try to access the serdev which is not
available in the ldisc proto. This patch will fix the crash by
support both the ldisc and serdev way in the qca hci_uart driver.

Signed-off-by: Balakrishna Godavarthi 


Oh, I wasn't aware of the instantiation through ldisc and was actually
considering to *remove* some of the seemingly unnecessary serdev
checks.


---
 drivers/bluetooth/hci_qca.c | 47 
++---

 1 file changed, 28 insertions(+), 19 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 237aea34b69f..0a5c98d46864 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -963,7 +963,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, 
uint8_t baudrate)

 {
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
-   struct qca_serdev *qcadev;
+   struct qca_serdev *qcadev = NULL;


In many cases the only field that is accessed is qcadev->btsoc_type. I
think something like 'qca_get_soc_type(struct hci_dev *hdev / struct
hci_uart *hu)' would make things more readable.

[Bala]: sure will update this in other patch once this change is landed 
as this has to

go in priority as we have crash coming.


IMO the whole 'qcadev' vs 'qca(_data)' is confusing anyway, in this
sense even better if we can make most of the 'qcadev' references
disappear.

[Bala]: will note this improvement point and do it with the above 
change.



Thanks

Matthias


--
Regards
Balakrishna.


[PATCH v1] Bluetooth: hci_qca: Enable the ldisc for ROME for x86 platforms.

2019-03-07 Thread Balakrishna Godavarthi
When using btattach to setup Rome over ldisc we observed a crash
in qca_setup as it will try to access the serdev which is not
available in the ldisc proto. This patch will fix the crash by
support both the ldisc and serdev way in the qca hci_uart driver.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 47 ++---
 1 file changed, 28 insertions(+), 19 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 237aea34b69f..0a5c98d46864 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -963,7 +963,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
 {
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
-   struct qca_serdev *qcadev;
+   struct qca_serdev *qcadev = NULL;
struct sk_buff *skb;
u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };
 
@@ -985,18 +985,19 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
skb_queue_tail(>txq, skb);
hci_uart_tx_wakeup(hu);
 
-   qcadev = serdev_device_get_drvdata(hu->serdev);
+   if (hu->serdev)
+   qcadev = serdev_device_get_drvdata(hu->serdev);
 
/* Wait for the baudrate change request to be sent */
-
while (!skb_queue_empty(>txq))
usleep_range(100, 200);
 
-   serdev_device_wait_until_sent(hu->serdev,
- msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
+   if (hu->serdev)
+   serdev_device_wait_until_sent(hu->serdev,
+   msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
 
/* Give the controller time to process the request */
-   if (qcadev->btsoc_type == QCA_WCN3990)
+   if (qcadev && qcadev->btsoc_type == QCA_WCN3990)
msleep(10);
else
msleep(300);
@@ -1072,10 +1073,12 @@ static unsigned int qca_get_speed(struct hci_uart *hu,
 
 static int qca_check_speeds(struct hci_uart *hu)
 {
-   struct qca_serdev *qcadev;
+   struct qca_serdev *qcadev = NULL;
 
-   qcadev = serdev_device_get_drvdata(hu->serdev);
-   if (qcadev->btsoc_type == QCA_WCN3990) {
+   if (hu->serdev)
+   qcadev = serdev_device_get_drvdata(hu->serdev);
+
+   if (qcadev && qcadev->btsoc_type == QCA_WCN3990) {
if (!qca_get_speed(hu, QCA_INIT_SPEED) &&
!qca_get_speed(hu, QCA_OPER_SPEED))
return -EINVAL;
@@ -1091,7 +1094,7 @@ static int qca_check_speeds(struct hci_uart *hu)
 static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
 {
unsigned int speed, qca_baudrate;
-   struct qca_serdev *qcadev;
+   struct qca_serdev *qcadev = NULL;
int ret = 0;
 
if (speed_type == QCA_INIT_SPEED) {
@@ -1106,8 +1109,10 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
/* Disable flow control for wcn3990 to deassert RTS while
 * changing the baudrate of chip and host.
 */
-   qcadev = serdev_device_get_drvdata(hu->serdev);
-   if (qcadev->btsoc_type == QCA_WCN3990)
+   if (hu->serdev)
+   qcadev = serdev_device_get_drvdata(hu->serdev);
+
+   if (qcadev && qcadev->btsoc_type == QCA_WCN3990)
hci_uart_set_flow_control(hu, true);
 
qca_baudrate = qca_get_baudrate_value(speed);
@@ -1119,7 +1124,7 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
host_set_baudrate(hu, speed);
 
 error:
-   if (qcadev->btsoc_type == QCA_WCN3990)
+   if (qcadev && qcadev->btsoc_type == QCA_WCN3990)
hci_uart_set_flow_control(hu, false);
}
 
@@ -1181,11 +1186,15 @@ static int qca_setup(struct hci_uart *hu)
struct hci_dev *hdev = hu->hdev;
struct qca_data *qca = hu->priv;
unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200;
-   struct qca_serdev *qcadev;
+   struct qca_serdev *qcadev = NULL;
int ret;
int soc_ver = 0;
+   enum qca_btsoc_type btsoc_type = QCA_ROME;
 
-   qcadev = serdev_device_get_drvdata(hu->serdev);
+   if (hu->serdev) {
+   qcadev = serdev_device_get_drvdata(hu->serdev);
+   btsoc_type = qcadev->btsoc_type;
+   }
 
ret = qca_check_speeds(hu);
if (ret)
@@ -1194,7 +1203,7 @@ static int qca_setup(struct hci_uart *hu)
/* Patch downloading has to be done without IBS mode */
clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
 
-   if (qcadev->btsoc_type == QCA_WCN3990) {
+   if (qcadev && btsoc_type == QCA_WCN3990) {
bt_dev_info(hdev, 

Re: [PATCH v1] Bluetooth: hci_qca: Give enough time to ROME controller to bootup.

2019-03-06 Thread Balakrishna Godavarthi

Hi Stepen,

On 2019-03-07 04:03, Stephen Boyd wrote:

Quoting Balakrishna Godavarthi (2019-03-06 08:21:13)

This patch enables enough time to ROME controller to bootup
after we bring the enable ping out of reset.

Signed-off-by: Balakrishna Godavarthi 
---


Any Fixes tag? And maybe some more explanation or background on where
150 ms sleep comes from would be useful. Was it determined
experimentally or did it come from a datasheet somewhere? Does the time
differ between boards?

[Bala]: this was observed in our stress testing and even the CHIP 
firmware team

confirmed that BT chip required at least 150 ms to boot up.

@Rocky to confirm my statement.


 drivers/bluetooth/hci_qca.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 237aea34b69f..1953b13511e7 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -508,6 +508,8 @@ static int qca_open(struct hci_uart *hu)
qcadev = serdev_device_get_drvdata(hu->serdev);
if (qcadev->btsoc_type != QCA_WCN3990) {
gpiod_set_value_cansleep(qcadev->bt_en, 1);
+   /* Controller needs time to bootup. */
+   msleep(150);
} else {
hu->init_speed = qcadev->init_speed;
hu->oper_speed = qcadev->oper_speed;


--
Regards
Balakrishna.


Re: [PATCH 2/2] Bluetooth: hci_qca: wcn3990: Drop baudrate change vendor event

2019-03-06 Thread Balakrishna Godavarthi

hi Matthias,

On 2019-03-07 06:10, Matthias Kaehlcke wrote:

Firmware download to the WCN3990 often fails with a 'TLV response size
mismatch' error:

[  133.064659] Bluetooth: hci0: setting up wcn3990
[  133.489150] Bluetooth: hci0: QCA controller version 0x02140201
[  133.495245] Bluetooth: hci0: QCA Downloading qca/crbtfw21.tlv
[  133.507214] Bluetooth: hci0: QCA TLV response size mismatch
[  133.513265] Bluetooth: hci0: QCA Failed to download patch (-84)

This is caused by a vendor event that corresponds to an earlier command
to change the baudrate. The event is not processed in the context of 
the

baudrate change and later interpreted as response to the firmware
download command (which is also a vendor command), but the driver 
detects

that the event doesn't have the expected amount of associated data.

More details:

For the WCN3990 the vendor command for a baudrate change isn't sent as
synchronous HCI command, because the controller sends the corresponding
vendor event with the new baudrate. The event is received and decoded
after the baudrate change of the host port.

Identify the 'unused' event when it is received and don't add it to
the queue of RX frames.

Signed-off-by: Matthias Kaehlcke 
---
 drivers/bluetooth/hci_qca.c | 54 ++---
 1 file changed, 51 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index ab8e59419dbc4..565681a6a1167 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -30,6 +30,7 @@

 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -55,6 +56,7 @@
 #define HCI_MAX_IBS_SIZE   10

 #define QCA_IN_BAND_SLEEP_ENABLED  BIT(0)
+#define QCA_DROP_VENDOR_EVENT  BIT(1)

 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
@@ -108,6 +110,7 @@ struct qca_data {
struct work_struct ws_rx_vote_off;
struct work_struct ws_tx_vote_off;
unsigned long flags;
+   struct completion drop_ev_comp;

/* For debugging purpose */
u64 ibs_sent_wacks;
@@ -474,6 +477,7 @@ static int qca_open(struct hci_uart *hu)
INIT_WORK(>ws_tx_vote_off, qca_wq_serial_tx_clock_vote_off);

qca->hu = hu;
+   init_completion(>drop_ev_comp);

/* Assume we start with both sides asleep -- extra wakes OK */
qca->tx_ibs_state = HCI_IBS_TX_ASLEEP;
@@ -866,6 +870,33 @@ static int qca_recv_acl_data(struct hci_dev
*hdev, struct sk_buff *skb)
return hci_recv_frame(hdev, skb);
 }

+static int qca_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
+{
+   struct hci_uart *hu = hci_get_drvdata(hdev);
+   struct qca_data *qca = hu->priv;
+
+   if (test_bit(QCA_DROP_VENDOR_EVENT, >flags)) {
+   struct hci_event_hdr *hdr = (void *)skb->data;
+
+   /* For the WCN3990 the vendor command for a baudrate change
+* isn't sent as synchronous HCI command, because the
+* controller sends the corresponding vendor event with the
+* new baudrate. The event is received and properly decoded
+* after changing the baudrate of the host port. It needs to
+* be dropped, otherwise it can be mis-interpreted as
+* response to a later firmware download command (also a
+* vendor command).
+*/
+
+   if (hdr->evt == HCI_EV_VENDOR)
+   complete(>drop_ev_comp);
+
+   return 0;
+   }
+
+   return hci_recv_frame(hdev, skb);
+}
+
 #define QCA_IBS_SLEEP_IND_EVENT \
.type = HCI_IBS_SLEEP_IND, \
.hlen = 0, \
@@ -890,7 +921,7 @@ static int qca_recv_acl_data(struct hci_dev *hdev,
struct sk_buff *skb)
 static const struct h4_recv_pkt qca_recv_pkts[] = {
{ H4_RECV_ACL, .recv = qca_recv_acl_data },
{ H4_RECV_SCO, .recv = hci_recv_frame},
-   { H4_RECV_EVENT,   .recv = hci_recv_frame},
+   { H4_RECV_EVENT,   .recv = qca_recv_event},
{ QCA_IBS_WAKE_IND_EVENT,  .recv = qca_ibs_wake_ind  },
{ QCA_IBS_WAKE_ACK_EVENT,  .recv = qca_ibs_wake_ack  },
{ QCA_IBS_SLEEP_IND_EVENT, .recv = qca_ibs_sleep_ind },
@@ -1091,6 +1122,7 @@ static int qca_set_speed(struct hci_uart *hu,
enum qca_speed_type speed_type)
 {
unsigned int speed, qca_baudrate;
struct qca_serdev *qcadev;
+   struct qca_data *qca = hu->priv;
int ret = 0;

if (speed_type == QCA_INIT_SPEED) {
@@ -1106,8 +1138,11 @@ static int qca_set_speed(struct hci_uart *hu,
enum qca_speed_type speed_type)
 * changing the baudrate of chip and host.
 */
qcadev = serdev_device_get_drvdata(hu->serdev);
-   if (qcadev->btsoc_type == QCA_WCN3990)
+   if (qcadev->btsoc_type == QCA_WCN3990) {
hci_uart_set_flow_control(hu, 

Re: [PATCH 1/2] Bluetooth: hci_qca: Rename STATE_ to QCA_

2019-03-06 Thread Balakrishna Godavarthi

On 2019-03-07 06:10, Matthias Kaehlcke wrote:

Rename STATE_IN_BAND_SLEEP_ENABLED to QCA_IN_BAND_SLEEP_ENABLED.
The constant represents a flag (multiple flags can be set at once),
not a unique state of the controller or driver. Also use the BIT()
macro to specify the position of the flag instead of an integer
literal.

Signed-off-by: Matthias Kaehlcke 
---
 drivers/bluetooth/hci_qca.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 237aea34b69f1..ab8e59419dbc4 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -54,8 +54,7 @@
 #define HCI_IBS_WAKE_ACK   0xFC
 #define HCI_MAX_IBS_SIZE   10

-/* Controller states */
-#define STATE_IN_BAND_SLEEP_ENABLED1
+#define QCA_IN_BAND_SLEEP_ENABLED  BIT(0)

 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
@@ -775,7 +774,7 @@ static int qca_enqueue(struct hci_uart *hu, struct
sk_buff *skb)
/* Don't go to sleep in middle of patch download or
 * Out-Of-Band(GPIOs control) sleep is selected.
 */
-   if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags)) {
+   if (!test_bit(QCA_IN_BAND_SLEEP_ENABLED, >flags)) {
skb_queue_tail(>txq, skb);
spin_unlock_irqrestore(>hci_ibs_lock, flags);
return 0;
@@ -1192,7 +1191,7 @@ static int qca_setup(struct hci_uart *hu)
return ret;

/* Patch downloading has to be done without IBS mode */
-   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   clear_bit(QCA_IN_BAND_SLEEP_ENABLED, >flags);

if (qcadev->btsoc_type == QCA_WCN3990) {
bt_dev_info(hdev, "setting up wcn3990");
@@ -1236,7 +1235,7 @@ static int qca_setup(struct hci_uart *hu)
/* Setup patch / NVM configurations */
 	ret = qca_uart_setup(hdev, qca_baudrate, qcadev->btsoc_type, 
soc_ver);

if (!ret) {
-   set_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   set_bit(QCA_IN_BAND_SLEEP_ENABLED, >flags);
qca_debugfs_init(hdev);
} else if (ret == -ENOENT) {
/* No patch/nvm-config found, run with original fw/config */
@@ -1294,7 +1293,7 @@ static void qca_power_shutdown(struct hci_uart 
*hu)

 * data in skb's.
 */
spin_lock_irqsave(>hci_ibs_lock, flags);
-   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   clear_bit(QCA_IN_BAND_SLEEP_ENABLED, >flags);
qca_flush(hu);
spin_unlock_irqrestore(>hci_ibs_lock, flags);



Reviewed-by: Balakrishna Godavarthi 
--
Regards
Balakrishna.


Fw files for QCA BT Chip QCA6174

2019-03-06 Thread Balakrishna Godavarthi



Hi,

The following changes since commit 
54b0a748c8966c93aaa8726402e0b69cb51cd5d2:


  WHENCE: Correct errant entries (2019-02-21 07:21:45 -0500)

are available in the Git repository at:

  https://github.com/bgodavar/qca6174_bt_fw.git

for you to fetch changes up to c99beda7e0368961d024ddc8e45a46f118100cc7:

  QCA: Add the fw files for BT Chip QCA6174. (2019-02-25 15:36:36 +0530)


Balakrishna Godavarthi (1):
  QCA: Add the fw files for BT Chip QCA6174.

 WHENCE|   2 ++
 qca/nvm_00440302.bin  | Bin 0 -> 2010 bytes
 qca/rampatch_00440302.bin | Bin 0 -> 64940 bytes
 3 files changed, 2 insertions(+)
 create mode 100644 qca/nvm_00440302.bin
 create mode 100644 qca/rampatch_00440302.bin


--
Regards
Balakrishna.


[PATCH v1] Bluetooth: hci_qca: Give enough time to ROME controller to bootup.

2019-03-06 Thread Balakrishna Godavarthi
This patch enables enough time to ROME controller to bootup
after we bring the enable ping out of reset.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 237aea34b69f..1953b13511e7 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -508,6 +508,8 @@ static int qca_open(struct hci_uart *hu)
qcadev = serdev_device_get_drvdata(hu->serdev);
if (qcadev->btsoc_type != QCA_WCN3990) {
gpiod_set_value_cansleep(qcadev->bt_en, 1);
+   /* Controller needs time to bootup. */
+   msleep(150);
} else {
hu->init_speed = qcadev->init_speed;
hu->oper_speed = qcadev->oper_speed;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH] Bluetooth: hci_qca: Remove redundant initializations to zero

2019-03-05 Thread Balakrishna Godavarthi

On 2019-03-06 02:34, Matthias Kaehlcke wrote:

The qca_data structure is allocated with kzalloc() and hence
zero-initialized. Remove a bunch of unnecessary explicit
initializations of struct members to zero.

Signed-off-by: Matthias Kaehlcke 
---
 drivers/bluetooth/hci_qca.c | 19 ---
 1 file changed, 19 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 237aea34b69f1..8dccbb934e384 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -480,26 +480,7 @@ static int qca_open(struct hci_uart *hu)
qca->tx_ibs_state = HCI_IBS_TX_ASLEEP;
qca->rx_ibs_state = HCI_IBS_RX_ASLEEP;

-   /* clocks actually on, but we start votes off */
-   qca->tx_vote = false;
-   qca->rx_vote = false;
-   qca->flags = 0;
-
-   qca->ibs_sent_wacks = 0;
-   qca->ibs_sent_slps = 0;
-   qca->ibs_sent_wakes = 0;
-   qca->ibs_recv_wacks = 0;
-   qca->ibs_recv_slps = 0;
-   qca->ibs_recv_wakes = 0;
qca->vote_last_jif = jiffies;
-   qca->vote_on_ms = 0;
-   qca->vote_off_ms = 0;
-   qca->votes_on = 0;
-   qca->votes_off = 0;
-   qca->tx_votes_on = 0;
-   qca->tx_votes_off = 0;
-   qca->rx_votes_on = 0;
-   qca->rx_votes_off = 0;

    hu->priv = qca;


Reviewed-by: Balakrishna Godavarthi 

--
Regards
Balakrishna.


Re: [PATCH 2/3] Bluetooth: hci_qca: Move boot delay to qca_send_power_pulse()

2019-02-26 Thread Balakrishna Godavarthi

hi Matthias,

On 2019-02-26 17:48, Balakrishna Godavarthi wrote:

On 2019-02-26 05:19, Matthias Kaehlcke wrote:

After sending a power on pulse the driver has a delay of 100ms
to allow the host controller to boot. Move the delay into
qca_send_power_pulse(), since it is directly related with the
power-on pulse.

Signed-off-by: Matthias Kaehlcke 
---
 drivers/bluetooth/hci_qca.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index e4128774e9686..eacc108c422d0 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1036,6 +1036,9 @@ static int qca_send_power_pulse(struct hci_uart
*hu, bool on)
usleep_range(100, 200);


[Bala] : i still doubt do we require this delay.


hci_uart_set_flow_control(hu, false);

+   if (on)
+   msleep(100);
+
return 0;
 }

@@ -1148,9 +1151,6 @@ static int qca_wcn3990_init(struct hci_uart *hu)
if (ret)
return ret;

-   /* Wait for 100 ms for SoC to boot */
-   msleep(100);
-
/* Now the device is in ready state to communicate with host.
 * To sync host with device we need to reopen port.
 * Without this, we will have RTS and CTS synchronization


Reviewed-by: Balakrishna Godavarthi 


--
Regards
Balakrishna.


Re: [PATCH 3/3] Bluetooth: hci_qca: Add delay after power-off pulse

2019-02-26 Thread Balakrishna Godavarthi

On 2019-02-26 05:19, Matthias Kaehlcke wrote:

During initialization the power-on pulse is currently sent inmediately
after the prior power-off pulse. With this initialization often fails
at boot time:

[   15.205224] Bluetooth: hci0: setting up wcn3990
[   17.341062] Bluetooth: hci0: command 0xfc00 tx timeout
[   22.101453] ERROR: Bluetooth initialization failed
[   25.337740] Bluetooth: hci0: Reading QCA version information failed 
(-110)


After a power-off pulse wait 10ms to give the controller time to power
off.

Signed-off-by: Matthias Kaehlcke 
---
 drivers/bluetooth/hci_qca.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index eacc108c422d0..c89c1ed87ffe9 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1036,8 +1036,11 @@ static int qca_send_power_pulse(struct hci_uart
*hu, bool on)
usleep_range(100, 200);
hci_uart_set_flow_control(hu, false);

+   /* Give to controller time to boot/shutdown */
if (on)
msleep(100);
+   else
+   msleep(10);

return 0;
 }


Reviewed-by: Balakrishna Godavarthi 

--
Regards
Balakrishna.


Re: [PATCH 2/3] Bluetooth: hci_qca: Move boot delay to qca_send_power_pulse()

2019-02-26 Thread Balakrishna Godavarthi

On 2019-02-26 05:19, Matthias Kaehlcke wrote:

After sending a power on pulse the driver has a delay of 100ms
to allow the host controller to boot. Move the delay into
qca_send_power_pulse(), since it is directly related with the
power-on pulse.

Signed-off-by: Matthias Kaehlcke 
---
 drivers/bluetooth/hci_qca.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index e4128774e9686..eacc108c422d0 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1036,6 +1036,9 @@ static int qca_send_power_pulse(struct hci_uart
*hu, bool on)
usleep_range(100, 200);
hci_uart_set_flow_control(hu, false);

+   if (on)
+   msleep(100);
+
return 0;
 }

@@ -1148,9 +1151,6 @@ static int qca_wcn3990_init(struct hci_uart *hu)
if (ret)
return ret;

-   /* Wait for 100 ms for SoC to boot */
-   msleep(100);
-
/* Now the device is in ready state to communicate with host.
 * To sync host with device we need to reopen port.
 * Without this, we will have RTS and CTS synchronization


Reviewed-by: Balakrishna Godavarthi 

--
Regards
Balakrishna.


Re: [PATCH 1/3] Bluetooth: hci_qca: Pass boolean 'on/off' to qca_send_power_pulse()

2019-02-26 Thread Balakrishna Godavarthi

On 2019-02-26 05:19, Matthias Kaehlcke wrote:

There are only two types of power pulses 'on' or 'off', pass a boolean
instead of the power pulse 'command'.

Signed-off-by: Matthias Kaehlcke 
---
 drivers/bluetooth/hci_qca.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 5e03504c4e0ca..e4128774e9686 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1004,10 +1004,11 @@ static inline void host_set_baudrate(struct
hci_uart *hu, unsigned int speed)
hci_uart_set_baudrate(hu, speed);
 }

-static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
+static int qca_send_power_pulse(struct hci_uart *hu, bool on)
 {
int ret;
int timeout = msecs_to_jiffies(POWER_PULSE_TRANS_TIMEOUT_MS);
+   u8 cmd = on ? QCA_WCN3990_POWERON_PULSE : QCA_WCN3990_POWEROFF_PULSE;

/* These power pulses are single byte command which are sent
 * at required baudrate to wcn3990. On wcn3990, we have an external
@@ -1138,12 +1139,12 @@ static int qca_wcn3990_init(struct hci_uart 
*hu)


/* Forcefully enable wcn3990 to enter in to boot mode. */
host_set_baudrate(hu, 2400);
-   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
+   ret = qca_send_power_pulse(hu, false);
if (ret)
return ret;

qca_set_speed(hu, QCA_INIT_SPEED);
-   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWERON_PULSE);
+   ret = qca_send_power_pulse(hu, true);
if (ret)
return ret;

@@ -1289,7 +1290,7 @@ static void qca_power_shutdown(struct hci_uart 
*hu)

spin_unlock_irqrestore(>hci_ibs_lock, flags);

host_set_baudrate(hu, 2400);
-   qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
+   qca_send_power_pulse(hu, false);
qca_power_setup(hu, false);
 }


Reviewed-by: Balakrishna Godavarthi 

--
Regards
Balakrishna.


Fw files for QCA BT Chip QCA6174

2019-02-25 Thread Balakrishna Godavarthi



Hi,

The following changes since commit 
54b0a748c8966c93aaa8726402e0b69cb51cd5d2:


  WHENCE: Correct errant entries (2019-02-21 07:21:45 -0500)

are available in the Git repository at:

  https://github.com/bgodavar/qca6174_bt_fw.git

for you to fetch changes up to c99beda7e0368961d024ddc8e45a46f118100cc7:

  QCA: Add the fw files for BT Chip QCA6174. (2019-02-25 15:36:36 +0530)


Balakrishna Godavarthi (1):
  QCA: Add the fw files for BT Chip QCA6174.

 WHENCE|   2 ++
 qca/nvm_00440302.bin  | Bin 0 -> 2010 bytes
 qca/rampatch_00440302.bin | Bin 0 -> 64940 bytes
 3 files changed, 2 insertions(+)
 create mode 100644 qca/nvm_00440302.bin
 create mode 100644 qca/rampatch_00440302.bin

--
Regards
Balakrishna.


Firmware files for QCA BT chip wcn3990

2019-02-20 Thread Balakrishna Godavarthi



Hi,

The following changes since commit 
710963fe53ee3f227556d36839df3858daf6e232:


  Merge https://github.com/ajaykuee/linux-firmware (2019-02-13 07:42:20 
-0500)


are available in the Git repository at:

  https://github.com/bgodavar/qca_bt_wcn3990_fw.git

for you to fetch changes up to f859d9fda9379205c9bcf2eab11fae68891085ee:

  qca: Add firmware files for BT chip wcn3990. (2019-02-20 18:23:46 
+0530)



Balakrishna Godavarthi (1):
  qca: Add firmware files for BT chip wcn3990.

 WHENCE   |   2 +
 qca/NOTICE.txt   | 334 


 qca/crbtfw21.tlv | Bin 0 -> 177060 bytes
 qca/crnv21.bin   | Bin 0 -> 4587 bytes
 4 files changed, 129 insertions(+), 207 deletions(-)
 create mode 100644 qca/crbtfw21.tlv
 create mode 100644 qca/crnv21.bin


--
Regards
Balakrishna.


[PATCH v1] Bluetooth: hci_qca: Update baudrate change wait time for wcn3990

2019-02-20 Thread Balakrishna Godavarthi
This patch will update the baudrate change request wait time from
300 ms to 100 ms. When host sends the change baudrate request to
the controller, controller sets its clock and wait until the
clocks settle down. Here the Wait time is required for both
host and controller to be on sync.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 5e03504c4e0c..22f3c983f868 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -59,7 +59,8 @@
 
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
-#define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#define ROME_BD_SETTLE_TIMEOUT_MS  300
+#define WCN3990_BD_SETTLE_TIMEOUT_MS   100
 #define POWER_PULSE_TRANS_TIMEOUT_MS   100
 
 /* susclk rate */
@@ -965,8 +966,11 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
struct sk_buff *skb;
+   struct qca_serdev *qcadev;
+   unsigned int bd_settling_timeout;
u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };
 
+   qcadev = serdev_device_get_drvdata(hu->serdev);
if (baudrate > QCA_BAUDRATE_320)
return -EINVAL;
 
@@ -989,8 +993,12 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
 * controller will come back after they receive this HCI command
 * then host can communicate with new baudrate to controller
 */
+   bd_settling_timeout = qcadev->btsoc_type == QCA_WCN3990 ?
+  WCN3990_BD_SETTLE_TIMEOUT_MS :
+  ROME_BD_SETTLE_TIMEOUT_MS;
+
set_current_state(TASK_UNINTERRUPTIBLE);
-   schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
+   schedule_timeout(msecs_to_jiffies(bd_settling_timeout));
set_current_state(TASK_RUNNING);
 
return 0;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: Firmware files for QCA BT chip WCN3990.

2019-02-18 Thread Balakrishna Godavarthi

 Hi Nicolas,


On 2019-02-18 14:08, Nicolas Dechesne wrote:

hi Balakrishna,

On Mon, Feb 18, 2019 at 7:13 AM Balakrishna Godavarthi
 wrote:



Hi,

The following changes since commit
a9c22d3d8af87bd39a078ec6c846b0674dd2ca38:

   qca: Add firmware files for BT chip wcn3990. (2019-02-15 16:07:56
+0530)

are available in the Git repository at:

   https://github.com/bgodavar/qca_bt_wcn3990_fw.git

for you to fetch changes up to 
a9c22d3d8af87bd39a078ec6c846b0674dd2ca38:


   qca: Add firmware files for BT chip wcn3990. (2019-02-15 16:07:56
+0530)


 qca/NOTICE.txt   | 334
++

^ This looks a rather unexpected change.


[Bala]: yes we want to update the notice file according to the latest 
legal rules here in QCA.




You are missing updates in WHENCE file, as such:

$ make check
E: qca/crbtfw21.tlv not listed in WHENCE
E: qca/crnv21.bin not listed in WHENCE


[Bala]: will update them in WHENCE.




--
Regards
Balakrishna.


--
Regards
Balakrishna.


Firmware files for QCA BT chip WCN3990.

2019-02-17 Thread Balakrishna Godavarthi



Hi,

The following changes since commit 
a9c22d3d8af87bd39a078ec6c846b0674dd2ca38:


  qca: Add firmware files for BT chip wcn3990. (2019-02-15 16:07:56 
+0530)


are available in the Git repository at:

  https://github.com/bgodavar/qca_bt_wcn3990_fw.git

for you to fetch changes up to a9c22d3d8af87bd39a078ec6c846b0674dd2ca38:

  qca: Add firmware files for BT chip wcn3990. (2019-02-15 16:07:56 
+0530)



--
Regards
Balakrishna.


[PATCH v11 0/3] Bug fixes for Qualcomm BT chip wcn3990

2019-02-04 Thread Balakrishna Godavarthi
The below issues are found in our recent testing.

1. Observed device is not going into off state or not responding.
As wcn3990 require a power pulses to turn on the irrespctive of
igniting regulators, it was observed that power on or power off
pulses are not in sync with respective to chip.
The below patch will help us to wait until byte is pushed on to wires.  


* Bluetooth: hci_qca: use wait_until_sent() for power pulses

2. Observed Chip responding when we are in sleep.
   This is due to turn on flow control during change baudrate request.
   The below patch will only pull the RTS line high instead of turning off
   the flow.

   * Bluetooth: hci_qca: Pull RTS line high for baudrate change command.

3. Disable IBS state machine and flush Tx buffer
   We are disabling IBS and flushing the Tx buffer before turning off the chip.
  
   This is due to IBS state machine is active when we turn off the chip.
   This will stop queuing IBS protocol bytes.

   * Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

Changes in v11:
* added correct signatures for the patch.

Changes in v10:
 * Decreased wait time for power pulse to 100 ms instead of 1second.
 * enabling the flow control back when baudarte change request fails.
 * updated review comments.
 
Changes in v9:
 * Reverted the 100us delay and used msecs to jiffies inline call.
 * Disabling the flow control and enabling it back while setting the firmware.
 * Added spinlock while clearing the IBS state machine.
  
Changes in v8:
 * dropped inject the command complete event.
 * added one second time for the power pules instead of the indefinite time.

Changes in v7:
 * dropped frame reassmebly error patch.
 * dropped baudrate change wait time patch.
 * increased a wait to 5 ms for power pulses.

Changes in v6:
 * added serdev_device_write_flush in qca_send_power_pulse().
 * added new patch to update the baudrate change wait time.

Changes in V5:
 * added serdev_device_write_flush before sending the power off pulse
   during shutdown.

Changes in v4:
 * used serdev_device_write_buf() instead of serdev_device_write().
 * added new patch to stop logging of 0xfc00 timeout on console.

Changes in v3:
 * moved IBS & qca_flush to different patch
 * updated comments in code fo Deassert RTS patch
Balakrishna Godavarthi (3):
  Bluetooth: hci_qca: use wait_until_sent() for power pulses
  Bluetooth: hci_qca: Deassert RTS while baudrate change command
  Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

 drivers/bluetooth/hci_qca.c | 82 -
 1 file changed, 44 insertions(+), 38 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v11 1/3] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-02-04 Thread Balakrishna Godavarthi
wcn3990 requires a power pulse to turn ON/OFF along with
regulators. Sometimes we are observing the power pulses are sent
out with some time delay, due to queuing these commands. This is
causing synchronization issues with chip, which intern delay the
chip setup or may end up with communication issues.

Signed-off-by: Balakrishna Godavarthi 
Reviewed-by: Matthias Kaehlcke 
---
Changes in v10:
Updated the wait time to 100 us for power pules.
---
 drivers/bluetooth/hci_qca.c | 38 +++--
 1 file changed, 15 insertions(+), 23 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 53ac5ade532b..9a1c0a71b460 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -60,6 +60,7 @@
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
 #define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#define POWER_PULSE_TRANS_TIMEOUT_MS   100
 
 /* susclk rate */
 #define SUSCLK_RATE_32KHZ  32768
@@ -1013,11 +1014,10 @@ static inline void host_set_baudrate(struct hci_uart 
*hu, unsigned int speed)
hci_uart_set_baudrate(hu, speed);
 }
 
-static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
+static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
 {
-   struct hci_uart *hu = hci_get_drvdata(hdev);
-   struct qca_data *qca = hu->priv;
-   struct sk_buff *skb;
+   int ret;
+   int timeout = msecs_to_jiffies(POWER_PULSE_TRANS_TIMEOUT_MS);
 
/* These power pulses are single byte command which are sent
 * at required baudrate to wcn3990. On wcn3990, we have an external
@@ -1029,19 +1029,17 @@ static int qca_send_power_pulse(struct hci_dev *hdev, 
u8 cmd)
 * save power. Disabling hardware flow control is mandatory while
 * sending power pulses to SoC.
 */
-   bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
-
-   skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
-   if (!skb)
-   return -ENOMEM;
+   bt_dev_dbg(hu->hdev, "sending power pulse %02x to controller", cmd);
 
+   serdev_device_write_flush(hu->serdev);
hci_uart_set_flow_control(hu, true);
+   ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
+   if (ret < 0) {
+   bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd);
+   return ret;
+   }
 
-   skb_put_u8(skb, cmd);
-   hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
-
-   skb_queue_tail(>txq, skb);
-   hci_uart_tx_wakeup(hu);
+   serdev_device_wait_until_sent(hu->serdev, timeout);
 
/* Wait for 100 uS for SoC to settle down */
usleep_range(100, 200);
@@ -1116,7 +1114,6 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
 
 static int qca_wcn3990_init(struct hci_uart *hu)
 {
-   struct hci_dev *hdev = hu->hdev;
struct qca_serdev *qcadev;
int ret;
 
@@ -1139,12 +1136,12 @@ static int qca_wcn3990_init(struct hci_uart *hu)
 
/* Forcefully enable wcn3990 to enter in to boot mode. */
host_set_baudrate(hu, 2400);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
if (ret)
return ret;
 
qca_set_speed(hu, QCA_INIT_SPEED);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWERON_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWERON_PULSE);
if (ret)
return ret;
 
@@ -1277,13 +1274,8 @@ static const struct qca_vreg_data qca_soc_data = {
 
 static void qca_power_shutdown(struct hci_uart *hu)
 {
-   struct serdev_device *serdev = hu->serdev;
-   unsigned char cmd = QCA_WCN3990_POWEROFF_PULSE;
-
host_set_baudrate(hu, 2400);
-   hci_uart_set_flow_control(hu, true);
-   serdev_device_write_buf(serdev, , sizeof(cmd));
-   hci_uart_set_flow_control(hu, false);
+   qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v11 3/3] Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

2019-02-04 Thread Balakrishna Godavarthi
During hci down we observed IBS sleep commands are queued in the Tx
buffer and hci_uart_write_work is sending data to the chip which is
not required as the chip is powered off. This patch will disable IBS
and flush the Tx buffer before we turn off the chip.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index e3cf0dbfc89d..5e03504c4e0c 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -771,16 +771,17 @@ static int qca_enqueue(struct hci_uart *hu, struct 
sk_buff *skb)
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), _skb_pkt_type(skb), 1);
 
+   spin_lock_irqsave(>hci_ibs_lock, flags);
+
/* Don't go to sleep in middle of patch download or
 * Out-Of-Band(GPIOs control) sleep is selected.
 */
if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags)) {
skb_queue_tail(>txq, skb);
+   spin_unlock_irqrestore(>hci_ibs_lock, flags);
return 0;
}
 
-   spin_lock_irqsave(>hci_ibs_lock, flags);
-
/* Act according to current state */
switch (qca->tx_ibs_state) {
case HCI_IBS_TX_AWAKE:
@@ -1275,6 +1276,18 @@ static const struct qca_vreg_data qca_soc_data = {
 
 static void qca_power_shutdown(struct hci_uart *hu)
 {
+   struct qca_data *qca = hu->priv;
+   unsigned long flags;
+
+   /* From this point we go into power off state. But serial port is
+* still open, stop queueing the IBS data and flush all the buffered
+* data in skb's.
+*/
+   spin_lock_irqsave(>hci_ibs_lock, flags);
+   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   qca_flush(hu);
+   spin_unlock_irqrestore(>hci_ibs_lock, flags);
+
host_set_baudrate(hu, 2400);
qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v11 2/3] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2019-02-04 Thread Balakrishna Godavarthi
This patch will help to stop frame reassembly errors while changing
the baudrate. This is because host send a change baudrate request
command to the chip with 115200 bps, Whereas chip will change their
UART clocks to the enable for new baudrate and sends the response
for the change request command with newer baudrate, On host side
we are still operating in 115200 bps which results of reading garbage
data. Here we are pulling RTS line, so that chip we will wait to send data
to host until host change its baudrate.

Signed-off-by: Balakrishna Godavarthi 
Tested-by: Matthias Kaehlcke 
Reviewed-by: Matthias Kaehlcke 
---
Changes in v10:
Enabled flow control back when the baudarte change request fails.
---
 drivers/bluetooth/hci_qca.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 9a1c0a71b460..e3cf0dbfc89d 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -964,7 +964,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
struct sk_buff *skb;
-   struct qca_serdev *qcadev;
u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };
 
if (baudrate > QCA_BAUDRATE_320)
@@ -978,13 +977,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
return -ENOMEM;
}
 
-   /* Disabling hardware flow control is mandatory while
-* sending change baudrate request to wcn3990 SoC.
-*/
-   qcadev = serdev_device_get_drvdata(hu->serdev);
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, true);
-
/* Assign commands to change baudrate and packet type. */
skb_put_data(skb, cmd, sizeof(cmd));
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
@@ -1000,9 +992,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
set_current_state(TASK_RUNNING);
 
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, false);
-
return 0;
 }
 
@@ -1089,7 +1078,8 @@ static int qca_check_speeds(struct hci_uart *hu)
 static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
 {
unsigned int speed, qca_baudrate;
-   int ret;
+   struct qca_serdev *qcadev;
+   int ret = 0;
 
if (speed_type == QCA_INIT_SPEED) {
speed = qca_get_speed(hu, QCA_INIT_SPEED);
@@ -1100,16 +1090,27 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
if (!speed)
return 0;
 
+   /* Disable flow control for wcn3990 to deassert RTS while
+* changing the baudrate of chip and host.
+*/
+   qcadev = serdev_device_get_drvdata(hu->serdev);
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   hci_uart_set_flow_control(hu, true);
+
qca_baudrate = qca_get_baudrate_value(speed);
bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed);
ret = qca_set_baudrate(hu->hdev, qca_baudrate);
if (ret)
-   return ret;
+   goto error;
 
host_set_baudrate(hu, speed);
+
+error:
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   hci_uart_set_flow_control(hu, false);
}
 
-   return 0;
+   return ret;
 }
 
 static int qca_wcn3990_init(struct hci_uart *hu)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v10 2/3] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2019-02-04 Thread Balakrishna Godavarthi
From: Balakrishna Godavarthi 

This patch will help to stop frame reassembly errors while changing
the baudrate. This is because host send a change baudrate request
command to the chip with 115200 bps, Whereas chip will change their
UART clocks to the enable for new baudrate and sends the response
for the change request command with newer baudrate, On host side
we are still operating in 115200 bps which results of reading garbage
data. Here we are pulling RTS line, so that chip we will wait to send data
to host until host change its baudrate.

Signed-off-by: Balakrishna Godavarthi 
Tested-by: Matthias Kaehlcke 
Reviewed-by: Matthias Kaehlcke 
---
Changes in v10:
Enabled flow control back when the baudarte change request fails.
---
 drivers/bluetooth/hci_qca.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 9a1c0a71b460..e3cf0dbfc89d 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -964,7 +964,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
struct sk_buff *skb;
-   struct qca_serdev *qcadev;
u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };
 
if (baudrate > QCA_BAUDRATE_320)
@@ -978,13 +977,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
return -ENOMEM;
}
 
-   /* Disabling hardware flow control is mandatory while
-* sending change baudrate request to wcn3990 SoC.
-*/
-   qcadev = serdev_device_get_drvdata(hu->serdev);
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, true);
-
/* Assign commands to change baudrate and packet type. */
skb_put_data(skb, cmd, sizeof(cmd));
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
@@ -1000,9 +992,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
set_current_state(TASK_RUNNING);
 
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, false);
-
return 0;
 }
 
@@ -1089,7 +1078,8 @@ static int qca_check_speeds(struct hci_uart *hu)
 static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
 {
unsigned int speed, qca_baudrate;
-   int ret;
+   struct qca_serdev *qcadev;
+   int ret = 0;
 
if (speed_type == QCA_INIT_SPEED) {
speed = qca_get_speed(hu, QCA_INIT_SPEED);
@@ -1100,16 +1090,27 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
if (!speed)
return 0;
 
+   /* Disable flow control for wcn3990 to deassert RTS while
+* changing the baudrate of chip and host.
+*/
+   qcadev = serdev_device_get_drvdata(hu->serdev);
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   hci_uart_set_flow_control(hu, true);
+
qca_baudrate = qca_get_baudrate_value(speed);
bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed);
ret = qca_set_baudrate(hu->hdev, qca_baudrate);
if (ret)
-   return ret;
+   goto error;
 
host_set_baudrate(hu, speed);
+
+error:
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   hci_uart_set_flow_control(hu, false);
}
 
-   return 0;
+   return ret;
 }
 
 static int qca_wcn3990_init(struct hci_uart *hu)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v10 1/3] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-02-04 Thread Balakrishna Godavarthi
From: Balakrishna Godavarthi 

wcn3990 requires a power pulse to turn ON/OFF along with
regulators. Sometimes we are observing the power pulses are sent
out with some time delay, due to queuing these commands. This is
causing synchronization issues with chip, which intern delay the
chip setup or may end up with communication issues.

Signed-off-by: Balakrishna Godavarthi 
Reviewed-by: Matthias Kaehlcke 
---
Changes in v10:
Updated the wait time to 100 us for power pules.
---
 drivers/bluetooth/hci_qca.c | 38 +++--
 1 file changed, 15 insertions(+), 23 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 53ac5ade532b..9a1c0a71b460 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -60,6 +60,7 @@
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
 #define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#define POWER_PULSE_TRANS_TIMEOUT_MS   100
 
 /* susclk rate */
 #define SUSCLK_RATE_32KHZ  32768
@@ -1013,11 +1014,10 @@ static inline void host_set_baudrate(struct hci_uart 
*hu, unsigned int speed)
hci_uart_set_baudrate(hu, speed);
 }
 
-static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
+static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
 {
-   struct hci_uart *hu = hci_get_drvdata(hdev);
-   struct qca_data *qca = hu->priv;
-   struct sk_buff *skb;
+   int ret;
+   int timeout = msecs_to_jiffies(POWER_PULSE_TRANS_TIMEOUT_MS);
 
/* These power pulses are single byte command which are sent
 * at required baudrate to wcn3990. On wcn3990, we have an external
@@ -1029,19 +1029,17 @@ static int qca_send_power_pulse(struct hci_dev *hdev, 
u8 cmd)
 * save power. Disabling hardware flow control is mandatory while
 * sending power pulses to SoC.
 */
-   bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
-
-   skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
-   if (!skb)
-   return -ENOMEM;
+   bt_dev_dbg(hu->hdev, "sending power pulse %02x to controller", cmd);
 
+   serdev_device_write_flush(hu->serdev);
hci_uart_set_flow_control(hu, true);
+   ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
+   if (ret < 0) {
+   bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd);
+   return ret;
+   }
 
-   skb_put_u8(skb, cmd);
-   hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
-
-   skb_queue_tail(>txq, skb);
-   hci_uart_tx_wakeup(hu);
+   serdev_device_wait_until_sent(hu->serdev, timeout);
 
/* Wait for 100 uS for SoC to settle down */
usleep_range(100, 200);
@@ -1116,7 +1114,6 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
 
 static int qca_wcn3990_init(struct hci_uart *hu)
 {
-   struct hci_dev *hdev = hu->hdev;
struct qca_serdev *qcadev;
int ret;
 
@@ -1139,12 +1136,12 @@ static int qca_wcn3990_init(struct hci_uart *hu)
 
/* Forcefully enable wcn3990 to enter in to boot mode. */
host_set_baudrate(hu, 2400);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
if (ret)
return ret;
 
qca_set_speed(hu, QCA_INIT_SPEED);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWERON_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWERON_PULSE);
if (ret)
return ret;
 
@@ -1277,13 +1274,8 @@ static const struct qca_vreg_data qca_soc_data = {
 
 static void qca_power_shutdown(struct hci_uart *hu)
 {
-   struct serdev_device *serdev = hu->serdev;
-   unsigned char cmd = QCA_WCN3990_POWEROFF_PULSE;
-
host_set_baudrate(hu, 2400);
-   hci_uart_set_flow_control(hu, true);
-   serdev_device_write_buf(serdev, , sizeof(cmd));
-   hci_uart_set_flow_control(hu, false);
+   qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v10 0/3] Bug fixes for Qualcomm BT chip wcn3990.

2019-02-04 Thread Balakrishna Godavarthi
The below issues are found in our recent testing.

1. Observed device is not going into off state or not responding.
As wcn3990 require a power pulses to turn on the irrespctive of
igniting regulators, it was observed that power on or power off
pulses are not in sync with respective to chip.
The below patch will help us to wait until byte is pushed on to wires.  


* Bluetooth: hci_qca: use wait_until_sent() for power pulses

2. Observed Chip responding when we are in sleep.
   This is due to turn on flow control during change baudrate request.
   The below patch will only pull the RTS line high instead of turning off
   the flow.

   * Bluetooth: hci_qca: Pull RTS line high for baudrate change command.

3. Disable IBS state machine and flush Tx buffer
   We are disabling IBS and flushing the Tx buffer before turning off the chip.
  
   This is due to IBS state machine is active when we turn off the chip.
   This will stop queuing IBS protocol bytes.

   * Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

Changes in v10:
 * Decreased wait time for power pulse to 100 ms instead of 1second.
 * enabling the flow control back when baudarte change request fails.
 * updated review comments.
 
Changes in v9:
 * Reverted the 100us delay and used msecs to jiffies inline call.
 * Disabling the flow control and enabling it back while setting the firmware.
 * Added spinlock while clearing the IBS state machine.
  
Changes in v8:
 * dropped inject the command complete event.
 * added one second time for the power pules instead of the indefinite time.

Changes in v7:
 * dropped frame reassmebly error patch.
 * dropped baudrate change wait time patch.
 * increased a wait to 5 ms for power pulses.

Changes in v6:
 * added serdev_device_write_flush in qca_send_power_pulse().
 * added new patch to update the baudrate change wait time.

Changes in V5:
 * added serdev_device_write_flush before sending the power off pulse
   during shutdown.

Changes in v4:
 * used serdev_device_write_buf() instead of serdev_device_write().
 * added new patch to stop logging of 0xfc00 timeout on console.

Changes in v3:
 * moved IBS & qca_flush to different patch
 * updated comments in code fo Deassert RTS patch
Balakrishna Godavarthi (3):
  Bluetooth: hci_qca: use wait_until_sent() for power pulses
  Bluetooth: hci_qca: Deassert RTS while baudrate change command
  Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

 drivers/bluetooth/hci_qca.c | 82 -
 1 file changed, 44 insertions(+), 38 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v10 3/3] Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

2019-02-04 Thread Balakrishna Godavarthi
From: Balakrishna Godavarthi 

During hci down we observed IBS sleep commands are queued in the Tx
buffer and hci_uart_write_work is sending data to the chip which is
not required as the chip is powered off. This patch will disable IBS
and flush the Tx buffer before we turn off the chip.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index e3cf0dbfc89d..5e03504c4e0c 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -771,16 +771,17 @@ static int qca_enqueue(struct hci_uart *hu, struct 
sk_buff *skb)
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), _skb_pkt_type(skb), 1);
 
+   spin_lock_irqsave(>hci_ibs_lock, flags);
+
/* Don't go to sleep in middle of patch download or
 * Out-Of-Band(GPIOs control) sleep is selected.
 */
if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags)) {
skb_queue_tail(>txq, skb);
+   spin_unlock_irqrestore(>hci_ibs_lock, flags);
return 0;
}
 
-   spin_lock_irqsave(>hci_ibs_lock, flags);
-
/* Act according to current state */
switch (qca->tx_ibs_state) {
case HCI_IBS_TX_AWAKE:
@@ -1275,6 +1276,18 @@ static const struct qca_vreg_data qca_soc_data = {
 
 static void qca_power_shutdown(struct hci_uart *hu)
 {
+   struct qca_data *qca = hu->priv;
+   unsigned long flags;
+
+   /* From this point we go into power off state. But serial port is
+* still open, stop queueing the IBS data and flush all the buffered
+* data in skb's.
+*/
+   spin_lock_irqsave(>hci_ibs_lock, flags);
+   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   qca_flush(hu);
+   spin_unlock_irqrestore(>hci_ibs_lock, flags);
+
host_set_baudrate(hu, 2400);
qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v9 3/3] Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

2019-02-01 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-25 06:25, Matthias Kaehlcke wrote:

On Thu, Jan 24, 2019 at 05:38:08PM +0530, Balakrishna Godavarthi wrote:

During hci down we observed IBS sleep commands are queued in the Tx
buffer and hci_uart_write_work is sending data to the chip which is
not required as the chip is powered off. This patch will disable IBS
and flush the Tx buffer before we turn off the chip.

Signed-off-by: Balakrishna Godavarthi 
---
Changes v9:
  * added lock while disabling the IBS state machine.

---
 drivers/bluetooth/hci_qca.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 6b5bcd44e24c..99ddc35f08c6 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -771,16 +771,17 @@ static int qca_enqueue(struct hci_uart *hu, 
struct sk_buff *skb)

/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), _skb_pkt_type(skb), 1);

+   spin_lock_irqsave(>hci_ibs_lock, flags);
+
/* Don't go to sleep in middle of patch download or
 * Out-Of-Band(GPIOs control) sleep is selected.
 */
if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags)) {
skb_queue_tail(>txq, skb);
+   spin_unlock_irqrestore(>hci_ibs_lock, flags);
return 0;
}

-   spin_lock_irqsave(>hci_ibs_lock, flags);
-
/* Act according to current state */
switch (qca->tx_ibs_state) {
case HCI_IBS_TX_AWAKE:
@@ -1273,6 +1274,18 @@ static const struct qca_vreg_data qca_soc_data 
= {


 static void qca_power_shutdown(struct hci_uart *hu)
 {
+   struct qca_data *qca = hu->priv;
+   unsigned long flags;
+
+   /* From this point we go into power off state. But serial port is
+* still open, stop queueing the IBS data and flush all the buffered
+* data in skb's.
+*/
+   spin_lock_irqsave(>hci_ibs_lock, flags);
+   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   qca_flush(hu);
+   spin_unlock_irqrestore(>hci_ibs_lock, flags);
+
host_set_baudrate(hu, 2400);
qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);


I was about to add my 'Reviewed-by' tag, but I'm still left with a
doubt. This patch certainly improves the situation by clearing the IBS
bit and flushing the buffered data, however IIUC new data could still
be added to the TX queue after releasing the spinlock:

static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
{
...

if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags)) {
skb_queue_tail(>txq, skb);

...
}

To prevent this a boolean/bit like 'shutting_down' or similar would be
needed (I don't think there is something common in the HCI core),
which is set in qca_power_shutdown(). If the bit is set qca_enqueue()
discards the data.

Not sure how important this is, and I don't want to add necessarily
more revisions to this series. If it is preferable to have an empty
queue after shutdown maybe it can be done in a follow up patch.

Thanks

Matthias


[Bala]: during shutdown Bt stack will not send any data to the Bt  
kernel Tx path.

so this call may not be called. once we shutdown chip.

--
Regards
Balakrishna.


Re: [PATCH v9 1/3] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-01-29 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-28 23:17, Matthias Kaehlcke wrote:

On Mon, Jan 28, 2019 at 07:19:56PM +0530, Balakrishna Godavarthi wrote:

Hi Matthias,

On 2019-01-25 06:44, Matthias Kaehlcke wrote:
> On Thu, Jan 24, 2019 at 05:38:06PM +0530, Balakrishna Godavarthi wrote:
> > wcn3990 requires a power pulse to turn ON/OFF along with
> > regulators. Sometimes we are observing the power pulses are sent
> > out with some time delay, due to queuing these commands. This is
> > causing synchronization issues with chip, which intern delay the
> > chip setup or may end up with communication issues.
> >
> > Signed-off-by: Balakrishna Godavarthi 
> > ---
> > Changes in v9:
> >  * Reverted to 100us sleep.
> >  * used inline call msecs_to_jiffies()
> >
> > Changes in v8:
> >  * Updated 1 second timeout instead of indefinite wait.
> >
> > Changes in v7:
> >  *  updated the wait time to 5 ms after sending power pulses.
> >
> > Changes in v6:
> >  * added serdev_device_write_flush() in qca_send_power_pulse
> >instead during the power off pulse.
> >
> > Changes in v5:
> >  * added serdev_device_write_flush() in qca_power_off().
> > ---
> >  drivers/bluetooth/hci_qca.c | 40
> > +++--
> >  1 file changed, 16 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> > index f036c8f98ea3..c08f4d105e73 100644
> > --- a/drivers/bluetooth/hci_qca.c
> > +++ b/drivers/bluetooth/hci_qca.c
> > @@ -60,6 +60,7 @@
> >  #define IBS_WAKE_RETRANS_TIMEOUT_MS  100
> >  #define IBS_TX_IDLE_TIMEOUT_MS   2000
> >  #define BAUDRATE_SETTLE_TIMEOUT_MS   300
> > +#define POWER_PULSE_TRANS_TIMEOUT_MS 1000
>
> I still doubt that this mega-timeout of 1s is needed, but it shouldn't
> do any harm either, so whatever ...
>

[Bala]: for now let us have it. we can improve it in the improvement 
patch

based on the results.


Fine.

With the UART buffer flushed and flow control disabled I wonder though
what makes you think that it could take longer than a few milliseconds
for the byte being put on the wire, short of a bug in the UART driver
or hardware, which (if it existed) shouldn't be worked around here.



[Bala]: i don't see any issue decreasing to milliseconds. will update it 
to 100ms.



> >  /* susclk rate */
> >  #define SUSCLK_RATE_32KHZ32768
> > @@ -1013,11 +1014,10 @@ static inline void host_set_baudrate(struct
> > hci_uart *hu, unsigned int speed)
> >   hci_uart_set_baudrate(hu, speed);
> >  }
> >
> > -static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
> > +static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
> >  {
> > - struct hci_uart *hu = hci_get_drvdata(hdev);
> > - struct qca_data *qca = hu->priv;
> > - struct sk_buff *skb;
> > + int ret;
> > + int timeout = msecs_to_jiffies(POWER_PULSE_TRANS_TIMEOUT_MS);
> >
> >   /* These power pulses are single byte command which are sent
> >* at required baudrate to wcn3990. On wcn3990, we have an external
> > @@ -1029,21 +1029,19 @@ static int qca_send_power_pulse(struct
> > hci_dev *hdev, u8 cmd)
> >* save power. Disabling hardware flow control is mandatory while
> >* sending power pulses to SoC.
> >*/
> > - bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
> > -
> > - skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
> > - if (!skb)
> > - return -ENOMEM;
> > + bt_dev_dbg(hu->hdev, "sending power pulse %02x to controller", cmd);
> >
> > + serdev_device_write_flush(hu->serdev);
> >   hci_uart_set_flow_control(hu, true);
> > + ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
> > + if (ret < 0) {
> > + bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd);
> > + return ret;
> > + }
> >
> > - skb_put_u8(skb, cmd);
> > - hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
> > -
> > - skb_queue_tail(>txq, skb);
> > - hci_uart_tx_wakeup(hu);
> > + serdev_device_wait_until_sent(hu->serdev, timeout);
> >
> > - /* Wait for 100 uS for SoC to settle down */
> > + /* Wait for 100 uS for SoC to settle down for the received byte. */
>
> I don't think 'for the received byte' adds much value here. If you
> respin anyway I'd suggest to leave the comment as is.
>

[Bala]: will update.

> >   usleep_range(100, 200);
> >

Re: [PATCH v9 1/3] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-01-28 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-25 06:44, Matthias Kaehlcke wrote:

On Thu, Jan 24, 2019 at 05:38:06PM +0530, Balakrishna Godavarthi wrote:

wcn3990 requires a power pulse to turn ON/OFF along with
regulators. Sometimes we are observing the power pulses are sent
out with some time delay, due to queuing these commands. This is
causing synchronization issues with chip, which intern delay the
chip setup or may end up with communication issues.

Signed-off-by: Balakrishna Godavarthi 
---
Changes in v9:
 * Reverted to 100us sleep.
 * used inline call msecs_to_jiffies()

Changes in v8:
 * Updated 1 second timeout instead of indefinite wait.

Changes in v7:
 *  updated the wait time to 5 ms after sending power pulses.

Changes in v6:
 * added serdev_device_write_flush() in qca_send_power_pulse
   instead during the power off pulse.

Changes in v5:
 * added serdev_device_write_flush() in qca_power_off().
---
 drivers/bluetooth/hci_qca.c | 40 
+++--

 1 file changed, 16 insertions(+), 24 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f036c8f98ea3..c08f4d105e73 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -60,6 +60,7 @@
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
 #define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#define POWER_PULSE_TRANS_TIMEOUT_MS   1000


I still doubt that this mega-timeout of 1s is needed, but it shouldn't
do any harm either, so whatever ...



[Bala]: for now let us have it. we can improve it in the improvement 
patch

based on the results.


 /* susclk rate */
 #define SUSCLK_RATE_32KHZ  32768
@@ -1013,11 +1014,10 @@ static inline void host_set_baudrate(struct 
hci_uart *hu, unsigned int speed)

hci_uart_set_baudrate(hu, speed);
 }

-static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
+static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
 {
-   struct hci_uart *hu = hci_get_drvdata(hdev);
-   struct qca_data *qca = hu->priv;
-   struct sk_buff *skb;
+   int ret;
+   int timeout = msecs_to_jiffies(POWER_PULSE_TRANS_TIMEOUT_MS);

/* These power pulses are single byte command which are sent
 * at required baudrate to wcn3990. On wcn3990, we have an external
@@ -1029,21 +1029,19 @@ static int qca_send_power_pulse(struct hci_dev 
*hdev, u8 cmd)

 * save power. Disabling hardware flow control is mandatory while
 * sending power pulses to SoC.
 */
-   bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
-
-   skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
-   if (!skb)
-   return -ENOMEM;
+   bt_dev_dbg(hu->hdev, "sending power pulse %02x to controller", cmd);

+   serdev_device_write_flush(hu->serdev);
hci_uart_set_flow_control(hu, true);
+   ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
+   if (ret < 0) {
+   bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd);
+   return ret;
+   }

-   skb_put_u8(skb, cmd);
-   hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
-
-   skb_queue_tail(>txq, skb);
-   hci_uart_tx_wakeup(hu);
+   serdev_device_wait_until_sent(hu->serdev, timeout);

-   /* Wait for 100 uS for SoC to settle down */
+   /* Wait for 100 uS for SoC to settle down for the received byte. */


I don't think 'for the received byte' adds much value here. If you
respin anyway I'd suggest to leave the comment as is.



[Bala]: will update.


usleep_range(100, 200);
hci_uart_set_flow_control(hu, false);

@@ -1116,7 +1114,6 @@ static int qca_set_speed(struct hci_uart *hu, 
enum qca_speed_type speed_type)


 static int qca_wcn3990_init(struct hci_uart *hu)
 {
-   struct hci_dev *hdev = hu->hdev;
struct qca_serdev *qcadev;
int ret;

@@ -1139,12 +1136,12 @@ static int qca_wcn3990_init(struct hci_uart 
*hu)


/* Forcefully enable wcn3990 to enter in to boot mode. */
host_set_baudrate(hu, 2400);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
if (ret)
return ret;

qca_set_speed(hu, QCA_INIT_SPEED);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWERON_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWERON_PULSE);
if (ret)
return ret;

@@ -1274,13 +1271,8 @@ static const struct qca_vreg_data qca_soc_data 
= {


 static void qca_power_shutdown(struct hci_uart *hu)
 {
-   struct serdev_device *serdev = hu->serdev;
-   unsigned char cmd = QCA_WCN3990_POWEROFF_PULSE;
-
host_set_baudrate(hu, 2400);
-   hci_uart_set_flow_control(hu, true);
-   serdev_device_write_buf(serdev, , sizeof(cmd));
-   hci_uart_set_flow_control(hu, false);

Re: [PATCH v9 2/3] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2019-01-28 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-25 05:42, Matthias Kaehlcke wrote:

Hi Balakrishna,

On Thu, Jan 24, 2019 at 05:38:07PM +0530, Balakrishna Godavarthi wrote:

This patch will help to stop frame reassembly errors while changing
the baudrate. This is because host send a change baudrate request
command to the chip with 115200 bps, Whereas chip will change their
UART clocks to the enable for new baudrate and sends the response
for the change request command with newer baudrate, On host side
we are still operating in 115200 bps which results of reading garbage
data. Here we are pulling RTS line, so that chip we will wait to send 
data

to host until host change its baudrate.

Signed-off-by: Balakrishna Godavarthi 
Tested-by: Matthias Kaehlcke 
Reviewed-by: Matthias Kaehlcke 
---
Changes in v9:
 * disabled flow control while setting the baudrate of HOST and chip.
---
 drivers/bluetooth/hci_qca.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index c08f4d105e73..6b5bcd44e24c 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -964,7 +964,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, 
uint8_t baudrate)

struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
struct sk_buff *skb;
-   struct qca_serdev *qcadev;
u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };

if (baudrate > QCA_BAUDRATE_320)
@@ -978,13 +977,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, 
uint8_t baudrate)

return -ENOMEM;
}

-   /* Disabling hardware flow control is mandatory while
-* sending change baudrate request to wcn3990 SoC.
-*/
-   qcadev = serdev_device_get_drvdata(hu->serdev);
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, true);
-
/* Assign commands to change baudrate and packet type. */
skb_put_data(skb, cmd, sizeof(cmd));
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
@@ -1000,9 +992,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, 
uint8_t baudrate)

schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
set_current_state(TASK_RUNNING);

-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, false);
-
return 0;
 }

@@ -1089,6 +1078,7 @@ static int qca_check_speeds(struct hci_uart *hu)
 static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type 
speed_type)

 {
unsigned int speed, qca_baudrate;
+   struct qca_serdev *qcadev;
int ret;

if (speed_type == QCA_INIT_SPEED) {
@@ -1100,6 +1090,15 @@ static int qca_set_speed(struct hci_uart *hu, 
enum qca_speed_type speed_type)

if (!speed)
return 0;

+   /* Deassert RTS while changing the baudrate of chip and host.
+* This will prevent chip from transmitting its response with
+* the new baudrate while the host port is still operating at
+* the old speed.
+*/


It is not necessarily evident which action deasserts RTS, I suggest to
rephrase it to something like:

"Disable flow control for wcn3990 to deassert RTS while ... "



[Bala]: will update.


+   qcadev = serdev_device_get_drvdata(hu->serdev);
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   hci_uart_set_flow_control(hu, true);
+
qca_baudrate = qca_get_baudrate_value(speed);
bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed);
ret = qca_set_baudrate(hu->hdev, qca_baudrate);


flow control should be re-enabled in the error path.

Cheers

Matthias


[Bala; will update.

--
Regards
Balakrishna.


[PATCH v9 2/3] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2019-01-24 Thread Balakrishna Godavarthi
This patch will help to stop frame reassembly errors while changing
the baudrate. This is because host send a change baudrate request
command to the chip with 115200 bps, Whereas chip will change their
UART clocks to the enable for new baudrate and sends the response
for the change request command with newer baudrate, On host side
we are still operating in 115200 bps which results of reading garbage
data. Here we are pulling RTS line, so that chip we will wait to send data
to host until host change its baudrate.

Signed-off-by: Balakrishna Godavarthi 
Tested-by: Matthias Kaehlcke 
Reviewed-by: Matthias Kaehlcke 
---
Changes in v9:
 * disabled flow control while setting the baudrate of HOST and chip.
---
 drivers/bluetooth/hci_qca.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index c08f4d105e73..6b5bcd44e24c 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -964,7 +964,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
struct sk_buff *skb;
-   struct qca_serdev *qcadev;
u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };
 
if (baudrate > QCA_BAUDRATE_320)
@@ -978,13 +977,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
return -ENOMEM;
}
 
-   /* Disabling hardware flow control is mandatory while
-* sending change baudrate request to wcn3990 SoC.
-*/
-   qcadev = serdev_device_get_drvdata(hu->serdev);
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, true);
-
/* Assign commands to change baudrate and packet type. */
skb_put_data(skb, cmd, sizeof(cmd));
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
@@ -1000,9 +992,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
set_current_state(TASK_RUNNING);
 
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, false);
-
return 0;
 }
 
@@ -1089,6 +1078,7 @@ static int qca_check_speeds(struct hci_uart *hu)
 static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
 {
unsigned int speed, qca_baudrate;
+   struct qca_serdev *qcadev;
int ret;
 
if (speed_type == QCA_INIT_SPEED) {
@@ -1100,6 +1090,15 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
if (!speed)
return 0;
 
+   /* Deassert RTS while changing the baudrate of chip and host.
+* This will prevent chip from transmitting its response with
+* the new baudrate while the host port is still operating at
+* the old speed.
+*/
+   qcadev = serdev_device_get_drvdata(hu->serdev);
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   hci_uart_set_flow_control(hu, true);
+
qca_baudrate = qca_get_baudrate_value(speed);
bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed);
ret = qca_set_baudrate(hu->hdev, qca_baudrate);
@@ -1107,6 +1106,9 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
return ret;
 
host_set_baudrate(hu, speed);
+
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   hci_uart_set_flow_control(hu, false);
}
 
return 0;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v9 1/3] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-01-24 Thread Balakrishna Godavarthi
wcn3990 requires a power pulse to turn ON/OFF along with
regulators. Sometimes we are observing the power pulses are sent
out with some time delay, due to queuing these commands. This is
causing synchronization issues with chip, which intern delay the
chip setup or may end up with communication issues.

Signed-off-by: Balakrishna Godavarthi 
---
Changes in v9:
 * Reverted to 100us sleep.
 * used inline call msecs_to_jiffies()

Changes in v8:
 * Updated 1 second timeout instead of indefinite wait.

Changes in v7:
 *  updated the wait time to 5 ms after sending power pulses.

Changes in v6:
 * added serdev_device_write_flush() in qca_send_power_pulse
   instead during the power off pulse.

Changes in v5:
 * added serdev_device_write_flush() in qca_power_off().
---
 drivers/bluetooth/hci_qca.c | 40 +++--
 1 file changed, 16 insertions(+), 24 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f036c8f98ea3..c08f4d105e73 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -60,6 +60,7 @@
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
 #define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#define POWER_PULSE_TRANS_TIMEOUT_MS   1000
 
 /* susclk rate */
 #define SUSCLK_RATE_32KHZ  32768
@@ -1013,11 +1014,10 @@ static inline void host_set_baudrate(struct hci_uart 
*hu, unsigned int speed)
hci_uart_set_baudrate(hu, speed);
 }
 
-static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
+static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
 {
-   struct hci_uart *hu = hci_get_drvdata(hdev);
-   struct qca_data *qca = hu->priv;
-   struct sk_buff *skb;
+   int ret;
+   int timeout = msecs_to_jiffies(POWER_PULSE_TRANS_TIMEOUT_MS);
 
/* These power pulses are single byte command which are sent
 * at required baudrate to wcn3990. On wcn3990, we have an external
@@ -1029,21 +1029,19 @@ static int qca_send_power_pulse(struct hci_dev *hdev, 
u8 cmd)
 * save power. Disabling hardware flow control is mandatory while
 * sending power pulses to SoC.
 */
-   bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
-
-   skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
-   if (!skb)
-   return -ENOMEM;
+   bt_dev_dbg(hu->hdev, "sending power pulse %02x to controller", cmd);
 
+   serdev_device_write_flush(hu->serdev);
hci_uart_set_flow_control(hu, true);
+   ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
+   if (ret < 0) {
+   bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd);
+   return ret;
+   }
 
-   skb_put_u8(skb, cmd);
-   hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
-
-   skb_queue_tail(>txq, skb);
-   hci_uart_tx_wakeup(hu);
+   serdev_device_wait_until_sent(hu->serdev, timeout);
 
-   /* Wait for 100 uS for SoC to settle down */
+   /* Wait for 100 uS for SoC to settle down for the received byte. */
usleep_range(100, 200);
hci_uart_set_flow_control(hu, false);
 
@@ -1116,7 +1114,6 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
 
 static int qca_wcn3990_init(struct hci_uart *hu)
 {
-   struct hci_dev *hdev = hu->hdev;
struct qca_serdev *qcadev;
int ret;
 
@@ -1139,12 +1136,12 @@ static int qca_wcn3990_init(struct hci_uart *hu)
 
/* Forcefully enable wcn3990 to enter in to boot mode. */
host_set_baudrate(hu, 2400);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
if (ret)
return ret;
 
qca_set_speed(hu, QCA_INIT_SPEED);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWERON_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWERON_PULSE);
if (ret)
return ret;
 
@@ -1274,13 +1271,8 @@ static const struct qca_vreg_data qca_soc_data = {
 
 static void qca_power_shutdown(struct hci_uart *hu)
 {
-   struct serdev_device *serdev = hu->serdev;
-   unsigned char cmd = QCA_WCN3990_POWEROFF_PULSE;
-
host_set_baudrate(hu, 2400);
-   hci_uart_set_flow_control(hu, true);
-   serdev_device_write_buf(serdev, , sizeof(cmd));
-   hci_uart_set_flow_control(hu, false);
+   qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v9 3/3] Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

2019-01-24 Thread Balakrishna Godavarthi
During hci down we observed IBS sleep commands are queued in the Tx
buffer and hci_uart_write_work is sending data to the chip which is
not required as the chip is powered off. This patch will disable IBS
and flush the Tx buffer before we turn off the chip.

Signed-off-by: Balakrishna Godavarthi 
---
Changes v9:
  * added lock while disabling the IBS state machine.

---
 drivers/bluetooth/hci_qca.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 6b5bcd44e24c..99ddc35f08c6 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -771,16 +771,17 @@ static int qca_enqueue(struct hci_uart *hu, struct 
sk_buff *skb)
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), _skb_pkt_type(skb), 1);
 
+   spin_lock_irqsave(>hci_ibs_lock, flags);
+
/* Don't go to sleep in middle of patch download or
 * Out-Of-Band(GPIOs control) sleep is selected.
 */
if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags)) {
skb_queue_tail(>txq, skb);
+   spin_unlock_irqrestore(>hci_ibs_lock, flags);
return 0;
}
 
-   spin_lock_irqsave(>hci_ibs_lock, flags);
-
/* Act according to current state */
switch (qca->tx_ibs_state) {
case HCI_IBS_TX_AWAKE:
@@ -1273,6 +1274,18 @@ static const struct qca_vreg_data qca_soc_data = {
 
 static void qca_power_shutdown(struct hci_uart *hu)
 {
+   struct qca_data *qca = hu->priv;
+   unsigned long flags;
+
+   /* From this point we go into power off state. But serial port is
+* still open, stop queueing the IBS data and flush all the buffered
+* data in skb's.
+*/
+   spin_lock_irqsave(>hci_ibs_lock, flags);
+   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   qca_flush(hu);
+   spin_unlock_irqrestore(>hci_ibs_lock, flags);
+
host_set_baudrate(hu, 2400);
qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v9 0/3] Bug fixes for Qualcomm BT chip wcn3990.

2019-01-24 Thread Balakrishna Godavarthi
The below issues are found in our recent testing.

1. Observed device is not going into off state or not responding.
As wcn3990 require a power pulses to turn on the irrespctive of
igniting regulators, it was observed that power on or power off
pulses are not in sync with respective to chip.
The below patch will help us to wait until byte is pushed on to wires.  


* Bluetooth: hci_qca: use wait_until_sent() for power pulses

2. Observed Chip responding when we are in sleep.
   This is due to turn on flow control during change baudrate request.
   The below patch will only pull the RTS line high instead of turning off
   the flow.

   * Bluetooth: hci_qca: Pull RTS line high for baudrate change command.

3. Disable IBS state machine and flush Tx buffer
   We are disabling IBS and flushing the Tx buffer before turning off the chip.
  
   This is due to IBS state machine is active when we turn off the chip.
   This will stop queuing IBS protocol bytes.

   * Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

Changes in v9:
 * Reverted the 100us delay and used msecs to jiffies inline call.
 * Disabling the flow control and enabling it back while setting the firmware.
 * Added spinlock while clearing the IBS state machine.
  
Changes in v8:
 * dropped inject the command complete event.
 * added one second time for the power pules instead of the indefinite time.

Changes in v7:
 * dropped frame reassmebly error patch.
 * dropped baudrate change wait time patch.
 * increased a wait to 5 ms for power pulses.

Changes in v6:
 * added serdev_device_write_flush in qca_send_power_pulse().
 * added new patch to update the baudrate change wait time.

Changes in V5:
 * added serdev_device_write_flush before sending the power off pulse
   during shutdown.

Changes in v4:
 * used serdev_device_write_buf() instead of serdev_device_write().
 * added new patch to stop logging of 0xfc00 timeout on console.

Changes in v3:
 * moved IBS & qca_flush to different patch
 * updated comments in code fo Deassert RTS patch
Balakrishna Godavarthi (3):
  Bluetooth: hci_qca: use wait_until_sent() for power pulses
  Bluetooth: hci_qca: Deassert RTS while baudrate change command
  Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

 drivers/bluetooth/hci_qca.c | 79 -
 1 file changed, 43 insertions(+), 36 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v8 1/3] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-01-24 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-17 01:52, Matthias Kaehlcke wrote:

On Wed, Jan 16, 2019 at 05:16:01PM +0530, Balakrishna Godavarthi wrote:

wcn3990 requires a power pulse to turn ON/OFF along with
regulators. Sometimes we are observing the power pulses are sent
out with some time delay, due to queuing these commands. This is
causing synchronization issues with chip, which intern delay the
chip setup or may end up with communication issues.

Signed-off-by: Balakrishna Godavarthi 
---
Changes in v8:
 * Updated 1 second timeout instead of indefinite wait.

Changes in v7:
 *  updated the wait time to 5 ms after sending power pulses.

Changes in v6:
 * added serdev_device_write_flush() in qca_send_power_pulse
   instead during the power off pulse.

Changes in v5:
 * added serdev_device_write_flush() in qca_power_off().
---
 drivers/bluetooth/hci_qca.c | 46 
-

 1 file changed, 20 insertions(+), 26 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f036c8f98ea3..681bfa30467e 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -60,6 +60,7 @@
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
 #define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#define POWER_PULSE_TRANS_TIMEOUT_MS   1000


nit: Not that it should make a different in normal operation, but 1s
seems extreme. Is there really any chance that the byte hasn't been
sent after say 100ms (which is still an eternity for a single byte)?


[Bala]: i missed to address this. for now let us have 1 second delay.
based on stress test or further enchantments we can reduce this 
delay.



 /* susclk rate */
 #define SUSCLK_RATE_32KHZ  32768
@@ -1013,11 +1014,10 @@ static inline void host_set_baudrate(struct 
hci_uart *hu, unsigned int speed)

hci_uart_set_baudrate(hu, speed);
 }

-static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
+static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
 {
-   struct hci_uart *hu = hci_get_drvdata(hdev);
-   struct qca_data *qca = hu->priv;
-   struct sk_buff *skb;
+   int ret;
+   int timeout = __msecs_to_jiffies(POWER_PULSE_TRANS_TIMEOUT_MS);


use msecs_to_jiffies()


/* These power pulses are single byte command which are sent
 * at required baudrate to wcn3990. On wcn3990, we have an external
@@ -1029,22 +1029,22 @@ static int qca_send_power_pulse(struct hci_dev 
*hdev, u8 cmd)

 * save power. Disabling hardware flow control is mandatory while
 * sending power pulses to SoC.
 */
-   bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
-
-   skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
-   if (!skb)
-   return -ENOMEM;
+   bt_dev_dbg(hu->hdev, "sending power pulse %02x to controller", cmd);

+   serdev_device_write_flush(hu->serdev);
hci_uart_set_flow_control(hu, true);
+   ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
+   if (ret < 0) {
+   bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd);
+   return ret;
+   }

-   skb_put_u8(skb, cmd);
-   hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
-
-   skb_queue_tail(>txq, skb);
-   hci_uart_tx_wakeup(hu);
-
-   /* Wait for 100 uS for SoC to settle down */
-   usleep_range(100, 200);
+   serdev_device_wait_until_sent(hu->serdev, timeout);
+   /* Wait of 5ms is required for assuring to send the byte on the Tx
+* line and also for the controller to settle down for the received
+* byte.
+*/
+   usleep_range(5000, 6000);


I incorrectly claimed that there might be still bytes sitting in the
UART FIFO when serdev_device_wait_until_sent() returns, Johan
corrected me on that (thanks!). So if it takes the SoC 100us to settle
down we should be good with the original code.

Cheers

Matthias


--
Regards
Balakrishna.


Re: [PATCH v5 2/5] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2019-01-23 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-23 03:23, Matthias Kaehlcke wrote:

On Mon, Jan 21, 2019 at 08:11:39PM +0530, Balakrishna Godavarthi wrote:

Hi Matthias,

On 2019-01-19 06:01, Matthias Kaehlcke wrote:
> On Fri, Jan 18, 2019 at 10:44:16AM +0100, Johan Hovold wrote:
> > On Thu, Jan 17, 2019 at 09:21:09AM -0800, Matthias Kaehlcke wrote:
> >
> > > I observed that the qcom_geni_serial driver doesn't raise RTS with
> > > flow control disabled. It seems we have to investigate why that's the
> > > case. I agree that the driver should be platform agnostic.
> >
> > Sounds like a driver bug, unless the hardware is just "odd". The
> > driver implementation of this looks very non-standard judging from a
> > quick peek.
> >
> > In fact, qcom_geni_serial_get_mctrl() is currently a no-op if hardware
> > flow control is not enabled:
> >
> >   if (uart_console(uport) || !uart_cts_enabled(uport))
> >   return;
> >
> > Perhaps dropping the !uart_cts_enabled() test is sufficient.
>
> Thanks for taking a look Johan, that was indeed the problem (also
> in set_mctrl()). I posted a fix:
> https://lore.kernel.org/patchwork/patch/1033611/
>
> Balakrishna, the following (applied on top of your patch) works for me
> with the UART patch above:
>

[Bala]: will test and update BT patch accordingly.


Note that Johan pointed out that hci_uart_set_flow_control() deasserts
RTS when flow control is disabled, so the _set_rts() calls can be
removed. With that only a single action needs to be undone in case of
an error, you can consider to keep the return instead of using the
goto introduced by my patch.



[Bala]: ok sure. will note this.


Please keep/adapt the "Deassert RTS while changing the baudrate ..."
comment to leave it clear to posterity why flow control is disabled
during baudrate changes. It's fairly obvious once you understand the
problem and that disabling flow control deasserts RTS, but it took us
a while to get there, initially we only had a comment saying
"disabling flow control is mandatory" (I recall I inquired about this
multiple times during the initial review of the wcn3990 patches ;-)

Thanks

Matthias


--
Regards
Balakrishna.


Re: [PATCH v5 2/5] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2019-01-21 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-19 06:01, Matthias Kaehlcke wrote:

On Fri, Jan 18, 2019 at 10:44:16AM +0100, Johan Hovold wrote:

On Thu, Jan 17, 2019 at 09:21:09AM -0800, Matthias Kaehlcke wrote:

> I observed that the qcom_geni_serial driver doesn't raise RTS with
> flow control disabled. It seems we have to investigate why that's the
> case. I agree that the driver should be platform agnostic.

Sounds like a driver bug, unless the hardware is just "odd". The
driver implementation of this looks very non-standard judging from a
quick peek.

In fact, qcom_geni_serial_get_mctrl() is currently a no-op if hardware
flow control is not enabled:

if (uart_console(uport) || !uart_cts_enabled(uport))
return;

Perhaps dropping the !uart_cts_enabled() test is sufficient.


Thanks for taking a look Johan, that was indeed the problem (also
in set_mctrl()). I posted a fix:
https://lore.kernel.org/patchwork/patch/1033611/

Balakrishna, the following (applied on top of your patch) works for me
with the UART patch above:



[Bala]: will test and update BT patch accordingly.



diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 9d5e41f159c78f..60bfdf01f72841 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1080,7 +1080,7 @@ static int qca_set_speed(struct hci_uart *hu,
enum qca_speed_type speed_type)
 {
unsigned int speed, qca_baudrate;
struct qca_serdev *qcadev;
-   int ret;
+   int ret = 0;

if (speed_type == QCA_INIT_SPEED) {
speed = qca_get_speed(hu, QCA_INIT_SPEED);
@@ -1097,22 +1097,27 @@ static int qca_set_speed(struct hci_uart *hu,
enum qca_speed_type speed_type)
 * the old speed.
 */
qcadev = serdev_device_get_drvdata(hu->serdev);
-   if (qcadev->btsoc_type == QCA_WCN3990)
+   if (qcadev->btsoc_type == QCA_WCN3990) {
+   hci_uart_set_flow_control(hu, true);
serdev_device_set_rts(hu->serdev, false);
+   }

qca_baudrate = qca_get_baudrate_value(speed);
bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed);
ret = qca_set_baudrate(hu->hdev, qca_baudrate);
if (ret)
-   return ret;
+   goto out;

host_set_baudrate(hu, speed);

-   if (qcadev->btsoc_type == QCA_WCN3990)
+out:
+   if (qcadev->btsoc_type == QCA_WCN3990) {
+   hci_uart_set_flow_control(hu, false);
serdev_device_set_rts(hu->serdev, true);
+   }
}

-   return 0;
+   return ret;
 }

 static int qca_wcn3990_init(struct hci_uart *hu)


--
Regards
Balakrishna.


Re: [RFC,v2] Bluetooth: hci_qca: Collect controller memory dump during SSR

2019-01-21 Thread Balakrishna Godavarthi

Hi Marcel,

On 2019-01-18 14:24, Marcel Holtmann wrote:

Hi Balakrishna,

We will collect the ramdump of BT controller when hardware error 
event
received before rebooting the HCI layer. Before restarting a 
subsystem
or a process running on a subsystem, it is often required to 
request

either a subsystem or a process to perform proper cache dump and
software failure reason into a memory buffer which application
processor can retrieve afterwards. SW developers can often provide
initial investigation by looking into that debugging information.
Signed-off-by: Balakrishna Godavarthi 
---
changes v2:
* entirely an newer approach handling with an work queue.
---
drivers/bluetooth/hci_qca.c | 289 
++--

1 file changed, 278 insertions(+), 11 deletions(-)
diff --git a/drivers/bluetooth/hci_qca.c 
b/drivers/bluetooth/hci_qca.c

index f036c8f98ea3..62b768bc32ec 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -32,6 +32,7 @@
#include 
#include 
#include 
+#include 
#include 
#include 
#include 
don't we have some crashdump core facility that could be utilized 
here?

[Bala]: no i don't think so. that is reason calling devcoredump.h

what is wrong with using devcoredump.h?


[Bala]: using the  devcoredump.h


@@ -57,9 +58,10 @@
/* Controller states */
#define STATE_IN_BAND_SLEEP_ENABLED 1
-#define IBS_WAKE_RETRANS_TIMEOUT_MS100
+#defineIBS_WAKE_RETRANS_TIMEOUT_MS 100
#define IBS_TX_IDLE_TIMEOUT_MS  2000
-#define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#defineBAUDRATE_SETTLE_TIMEOUT_MS  300
+#define MEMDUMP_COLLECTION_TIMEOUT_MS  8000
/* susclk rate */
#define SUSCLK_RATE_32KHZ   32768
@@ -67,6 +69,13 @@
/* Controller debug log header */
#define QCA_DEBUG_HANDLE0x2EDC
+/* Controller dump header */
+#define QCA_SSR_DUMP_HANDLE0x0108
+#define QCA_DUMP_PACKET_SIZE   255
+#define QCA_LAST_SEQUENCE_NUM  0x
+#define QCA_CRASHBYTE_PACKET_LEN   1100
+#define QCA_MEMDUMP_BYTE   0xFB
+
/* HCI_IBS transmit side sleep protocol states */
enum tx_ibs_states {
HCI_IBS_TX_ASLEEP,
@@ -89,12 +98,41 @@ enum hci_ibs_clock_state_vote {
HCI_IBS_RX_VOTE_CLOCK_OFF,
};
+/* Controller memory dump states */
+enum qca_memdump_states {
+   QCA_MEMDUMP_IDLE,
+   QCA_MEMDUMP_COLLECTING,
+   QCA_MEMDUMP_COLLECTED,
+   QCA_MEMDUMP_TIMEOUT,
+};
+
+struct qca_memdump_data {
+   char *memdump_buf_head;
+   char *memdump_buf_tail;
+   u32 current_seq_no;
+   u32 received_dump;
+};
+
+struct qca_memdump_event_hdr {
+   __u8evt;
+   __u8plen;
+   __u16   opcode;
+   __u16   seq_no;
+   __u8reserved;
+} __packed;
+
+
+struct qca_dump_size {
+   u32 dump_size;
+} __packed;
+
struct qca_data {
struct hci_uart *hu;
struct sk_buff *rx_skb;
struct sk_buff_head txq;
-   struct sk_buff_head tx_wait_q;  /* HCI_IBS wait queue   */
-   spinlock_t hci_ibs_lock;/* HCI_IBS state lock   */
+   struct sk_buff_head tx_wait_q;  /* HCI_IBS wait queue   */
+   struct sk_buff_head rx_memdump_q;   /* Memdump wait queue   */
+   spinlock_t hci_ibs_lock;/* HCI_IBS state lock   */
u8 tx_ibs_state;/* HCI_IBS transmit side power state*/
u8 rx_ibs_state;/* HCI_IBS receive side power state */
bool tx_vote;   /* Clock must be on for TX */
@@ -103,12 +141,17 @@ struct qca_data {
u32 tx_idle_delay;
struct timer_list wake_retrans_timer;
u32 wake_retrans;
+   struct timer_list memdump_timer;
+   u32 memdump_delay;
struct workqueue_struct *workqueue;
struct work_struct ws_awake_rx;
struct work_struct ws_awake_device;
struct work_struct ws_rx_vote_off;
struct work_struct ws_tx_vote_off;
+   struct work_struct ctrl_memdump_evt;
+   struct qca_memdump_data *qca_memdump;
unsigned long flags;
+   enum qca_memdump_states memdump_state;
/* For debugging purpose */
u64 ibs_sent_wacks;
@@ -173,6 +216,7 @@ struct qca_serdev {
static int qca_power_setup(struct hci_uart *hu, bool on);
static void qca_power_shutdown(struct hci_uart *hu);
static int qca_power_off(struct hci_dev *hdev);
+static void qca_controller_memdump(struct work_struct *work);
static void __serial_clock_on(struct tty_struct *tty)
{
@@ -446,6 +490,21 @@ static void 
hci_ibs_wake_retrans_timeout(struct timer_list *t)

hci_uart_tx_wakeup(hu);
}
+static void hci_memdump_timeout(struct timer_list *t)
+{
+   struct qca_data *qca = from_timer(qca, t, tx_idle_timer);
+   struct hci_uart *hu = qca->hu;
+   struct qca_memdump_data *qca_memdump = qca->qca_memdump;
+   char *memdump_buf = qca_memdump->memdump_buf_tail;
+
+	bt_dev_err(hu->hdev, "clearing allocated memory due to memdump 
timeout");

+   kfree(memdu

Re: [PATCH v8 1/3] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-01-17 Thread Balakrishna Godavarthi

On 2019-01-17 21:43, Johan Hovold wrote:

On Thu, Jan 17, 2019 at 03:55:17PM +0530, Balakrishna Godavarthi wrote:

Hi Matthias,

On 2019-01-17 01:52, Matthias Kaehlcke wrote:



>> -  /* Wait for 100 uS for SoC to settle down */
>> -  usleep_range(100, 200);
>> +  serdev_device_wait_until_sent(hu->serdev, timeout);
>> +  /* Wait of 5ms is required for assuring to send the byte on the Tx
>> +   * line and also for the controller to settle down for the received
>> +   * byte.
>> +   */
>> +  usleep_range(5000, 6000);
>
> I incorrectly claimed that there might be still bytes sitting in the
> UART FIFO when serdev_device_wait_until_sent() returns, Johan
> corrected me on that (thanks!). So if it takes the SoC 100us to settle
> down we should be good with the original code.

[Bala]: sure will revert, i think he commented that wait_until_sent()
will only guarantee circular buffer is empty. if wait_until_sent()
guarantee us that the data was transmitted from the FIFO, then 100us
will work.


No, Matthias is correct; I claimed that the UART FIFO will be empty (at
least as long as flow control is disabled, otherwise it may never empty
and we therefore also have a time out).

Johan


[Bala]: Thanks Johan for clarification.
--
Regards
Balakrishna.


Re: [PATCH v8 3/3] Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

2019-01-17 Thread Balakrishna Godavarthi

On 2019-01-17 04:38, Matthias Kaehlcke wrote:

On Wed, Jan 16, 2019 at 05:16:03PM +0530, Balakrishna Godavarthi wrote:

During hci down we observed IBS sleep commands are queued in the Tx
buffer and hci_uart_write_work is sending data to the chip which is
not required as the chip is powered off. This patch will disable IBS
and flush the Tx buffer before we turn off the chip.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 7e4afcf40da2..7330ba71ada4 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1275,6 +1275,14 @@ static const struct qca_vreg_data qca_soc_data 
= {


 static void qca_power_shutdown(struct hci_uart *hu)
 {
+   struct qca_data *qca = hu->priv;
+
+   /* From this point we go into power off state. But serial port is
+* still open, stop queueing the IBS data and flush all the buffered
+* data in skb's.
+*/
+   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   qca_flush(hu);
host_set_baudrate(hu, 2400);
qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);


Due to a race-condition there could be an IBS sleep command queued
even after clearing the bit and flushing the queue.

In qca_enqueue() we have this:

static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
{
...

/* Don't go to sleep in middle of patch download or
 * Out-Of-Band(GPIOs control) sleep is selected.
 */
if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags)) {
skb_queue_tail(>txq, skb);
return 0;
}

spin_lock_irqsave(>hci_ibs_lock, flags);
}

With process X executing qca_power_shutdown() and process Y running
qca_enqueue() this could happen:

[X] test_bit(STATE_IN_BAND_SLEEP_ENABLED)  => set
[Y] clear_bit(STATE_IN_BAND_SLEEP_ENABLED)
[Y] qca_flush(hu);
[X] skb_queue_tail(>txq, skb);

The following should fix this race:

--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -770,16 +770,17 @@ static int qca_enqueue(struct hci_uart *hu,
struct sk_buff *skb)
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), _skb_pkt_type(skb), 1);

+   spin_lock_irqsave(>hci_ibs_lock, flags);
+
/* Don't go to sleep in middle of patch download or
 * Out-Of-Band(GPIOs control) sleep is selected.
 */
if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags)) {
skb_queue_tail(>txq, skb);
+   spin_unlock_irqrestore(>hci_ibs_lock, flags);
return 0;
}

-   spin_lock_irqsave(>hci_ibs_lock, flags);
-
/* Act according to current state */
switch (qca->tx_ibs_state) {
case HCI_IBS_TX_AWAKE:
@@ -1275,13 +1276,17 @@ static const struct qca_vreg_data qca_soc_data 
= {

 static void qca_power_shutdown(struct hci_uart *hu)
 {
struct qca_data *qca = hu->priv;
+   unsigned long flags;

/* From this point we go into power off state. But serial port is
 * still open, stop queueing the IBS data and flush all the buffered
 * data in skb's.
 */
+   spin_lock_irqsave(>hci_ibs_lock, flags);
clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
qca_flush(hu);
+   spin_unlock_irqrestore(>hci_ibs_lock, flags);
+
[Bala]: Thanks for catch this. yes you are rite, we will have an byte 
queued in the skb.

will update with the lock.


host_set_baudrate(hu, 2400);
qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);

Cheers

Matthias


--
Regards
Balakrishna.


Re: [PATCH v8 1/3] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-01-17 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-17 01:52, Matthias Kaehlcke wrote:

On Wed, Jan 16, 2019 at 05:16:01PM +0530, Balakrishna Godavarthi wrote:

wcn3990 requires a power pulse to turn ON/OFF along with
regulators. Sometimes we are observing the power pulses are sent
out with some time delay, due to queuing these commands. This is
causing synchronization issues with chip, which intern delay the
chip setup or may end up with communication issues.

Signed-off-by: Balakrishna Godavarthi 
---
Changes in v8:
 * Updated 1 second timeout instead of indefinite wait.

Changes in v7:
 *  updated the wait time to 5 ms after sending power pulses.

Changes in v6:
 * added serdev_device_write_flush() in qca_send_power_pulse
   instead during the power off pulse.

Changes in v5:
 * added serdev_device_write_flush() in qca_power_off().
---
 drivers/bluetooth/hci_qca.c | 46 
-

 1 file changed, 20 insertions(+), 26 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f036c8f98ea3..681bfa30467e 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -60,6 +60,7 @@
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
 #define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#define POWER_PULSE_TRANS_TIMEOUT_MS   1000


nit: Not that it should make a different in normal operation, but 1s
seems extreme. Is there really any chance that the byte hasn't been
sent after say 100ms (which is still an eternity for a single byte)?


 /* susclk rate */
 #define SUSCLK_RATE_32KHZ  32768
@@ -1013,11 +1014,10 @@ static inline void host_set_baudrate(struct 
hci_uart *hu, unsigned int speed)

hci_uart_set_baudrate(hu, speed);
 }

-static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
+static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
 {
-   struct hci_uart *hu = hci_get_drvdata(hdev);
-   struct qca_data *qca = hu->priv;
-   struct sk_buff *skb;
+   int ret;
+   int timeout = __msecs_to_jiffies(POWER_PULSE_TRANS_TIMEOUT_MS);


use msecs_to_jiffies()


[Bala]: will upadte.


/* These power pulses are single byte command which are sent
 * at required baudrate to wcn3990. On wcn3990, we have an external
@@ -1029,22 +1029,22 @@ static int qca_send_power_pulse(struct hci_dev 
*hdev, u8 cmd)

 * save power. Disabling hardware flow control is mandatory while
 * sending power pulses to SoC.
 */
-   bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
-
-   skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
-   if (!skb)
-   return -ENOMEM;
+   bt_dev_dbg(hu->hdev, "sending power pulse %02x to controller", cmd);

+   serdev_device_write_flush(hu->serdev);
hci_uart_set_flow_control(hu, true);
+   ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
+   if (ret < 0) {
+   bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd);
+   return ret;
+   }

-   skb_put_u8(skb, cmd);
-   hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
-
-   skb_queue_tail(>txq, skb);
-   hci_uart_tx_wakeup(hu);
-
-   /* Wait for 100 uS for SoC to settle down */
-   usleep_range(100, 200);
+   serdev_device_wait_until_sent(hu->serdev, timeout);
+   /* Wait of 5ms is required for assuring to send the byte on the Tx
+* line and also for the controller to settle down for the received
+* byte.
+*/
+   usleep_range(5000, 6000);


I incorrectly claimed that there might be still bytes sitting in the
UART FIFO when serdev_device_wait_until_sent() returns, Johan
corrected me on that (thanks!). So if it takes the SoC 100us to settle
down we should be good with the original code.


[Bala]: sure will revert, i think he commented that wait_until_sent()
will only guarantee circular buffer is empty. if 
wait_until_sent()
guarantee us that the data was transmitted from the FIFO, then 
100us will work.


Cheers

Matthias


--
Regards
Balakrishna.


Re: [PATCH v7 4/4] Bluetooth: btqca: inject command complete event during fw download

2019-01-17 Thread Balakrishna Godavarthi

 Hi Matthias,

On 2019-01-17 01:27, Matthias Kaehlcke wrote:

On Wed, Jan 16, 2019 at 03:06:29PM +0530, Balakrishna Godavarthi wrote:

On 2019-01-15 06:50, Matthias Kaehlcke wrote:
> On Mon, Jan 14, 2019 at 09:21:25PM +0530, Balakrishna Godavarthi wrote:
> > On 2019-01-12 04:42, Matthias Kaehlcke wrote:
> > > On Fri, Jan 11, 2019 at 07:53:43PM +0530, Balakrishna Godavarthi wrote:
> > > > Hi Matthias,
> > > >
> > > > On 2019-01-11 02:13, Matthias Kaehlcke wrote:
> > > > > Hi Balakrishna,
> > > > >
> > > > > On Thu, Jan 10, 2019 at 08:30:43PM +0530, Balakrishna Godavarthi 
wrote:
> > > > > > Hi Matthias,
> > > > > >
> > > > > > On 2019-01-03 03:45, Matthias Kaehlcke wrote:
> > > > > > > On Mon, Dec 31, 2018 at 11:34:46AM +0530, Balakrishna Godavarthi 
wrote:
> > > > > > > > Hi Marcel,
> > > > > > > >
> > > > > > > > On 2018-12-30 13:40, Marcel Holtmann wrote:
> > > > > > > > > Hi Balakrishna,
> > > > > > > > >
> > > > > > > > > > > > Latest qualcomm chips are not sending an command 
complete event for
> > > > > > > > > > > > every firmware packet sent to chip. They only respond 
with a vendor
> > > > > > > > > > > > specific event for the last firmware packet. This 
optimization will
> > > > > > > > > > > > decrease the BT ON time. Due to this we are seeing a 
timeout error
> > > > > > > > > > > > message logs on the console during firmware download. 
Now we are
> > > > > > > > > > > > injecting a command complete event once we receive an 
vendor
> > > > > > > > > > > > specific
> > > > > > > > > > > > event for the last RAM firmware packet.
> > > > > > > > > > > > Signed-off-by: Balakrishna Godavarthi 

> > > > > > > > > > > > ---
> > > > > > > > > > > > drivers/bluetooth/btqca.c | 39
> > > > > > > > > > > > ++-
> > > > > > > > > > > > drivers/bluetooth/btqca.h |  3 +++
> > > > > > > > > > > > 2 files changed, 41 insertions(+), 1 deletion(-)
> > > > > > > > > > > > diff --git a/drivers/bluetooth/btqca.c 
b/drivers/bluetooth/btqca.c
> > > > > > > > > > > > index ec9e03a6b778..0b533f65f652 100644
> > > > > > > > > > > > --- a/drivers/bluetooth/btqca.c
> > > > > > > > > > > > +++ b/drivers/bluetooth/btqca.c
> > > > > > > > > > > > @@ -144,6 +144,7 @@ static void 
qca_tlv_check_data(struct
> > > > > > > > > > > > rome_config *config,
> > > > > > > > > > > >  * In case VSE is skipped, only the last 
segment is acked.
> > > > > > > > > > > >  */
> > > > > > > > > > > > config->dnld_mode = 
tlv_patch->download_mode;
> > > > > > > > > > > > +   config->dnld_type = config->dnld_mode;
> > > > > > > > > > > > BT_DBG("Total Length   : %d bytes",
> > > > > > > > > > > >le32_to_cpu(tlv_patch->total_size));
> > > > > > > > > > > > @@ -264,6 +265,31 @@ static int 
qca_tlv_send_segment(struct
> > > > > > > > > > > > hci_dev *hdev, int seg_size,
> > > > > > > > > > > > return err;
> > > > > > > > > > > > }
> > > > > > > > > > > > +static int qca_inject_cmd_complete_event(struct 
hci_dev *hdev)
> > > > > > > > > > > > +{
> > > > > > > > > > > > +   struct hci_event_hdr *hdr;
> > > > > > > > > > > > +   struct hci_ev_cmd_complete *evt;
> > > > > > > > > > > > +   struct sk_buff *skb;
> > > > > > > > > > > > +
> > > > > > > > > > > > +   skb = bt_skb_alloc(sizeof(*hdr) + size

Re: [PATCH] arm64: dts: qcom: sdm845-mtp: Add WCN3990 BT node

2019-01-16 Thread Balakrishna Godavarthi

Hi Anderson,

On 2019-01-17 10:10, Bjorn Andersson wrote:

The SDM845 MTP has a WCN3990 Bluetooth chip on UART6, enable this.

Signed-off-by: Bjorn Andersson 
---
 arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 44 +
 1 file changed, 44 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
index af8c6a2445a2..f65d5a674103 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
@@ -17,6 +17,7 @@

aliases {
serial0 = 
+   hsuart0 = 
};

chosen {
@@ -357,6 +358,10 @@
clock-frequency = <40>;
 };

+_id_0 {
+   status = "okay";
+};
+
 _id_1 {
status = "okay";
 };
@@ -373,6 +378,20 @@
cd-gpios = < 126 GPIO_ACTIVE_LOW>;
 };

+ {
+   status = "okay";
+
+   bluetooth {
+   compatible = "qcom,wcn3990-bt";
+
+   vddio-supply = <_s4a_1p8>;
+   vddxo-supply = <_l7a_1p8>;
+   vddrf-supply = <_l17a_1p3>;
+   vddch0-supply = <_l25a_3p3>;
+   max-speed = <320>;
+   };
+};
+
  {
status = "okay";
 };
@@ -470,6 +489,31 @@
};
 };

+_uart6_default {
+   pinmux {
+   pins = "gpio45", "gpio46", "gpio47", "gpio48";
+   function = "qup6";
+   };
+
+   ctsrx {
+   pins = "gpio45", "gpio48";
+   drive-strength = <2>;
+   bias-no-pull;
+   };
+
+   rts {
+   pins = "gpio46";
+   drive-strength = <2>;
+   bias-pull-down;
+   };
+
+   tx {
+   pins = "gpio47";
+   drive-strength = <2>;
+   bias-pull-up;
+   };
+};
+
 _uart9_default {
pinconf-tx {
pins = "gpio4";



[Bala]:
   GPIO 45 is CTS
   GPIO 46 is RTS
   GPIO 47 is Tx
   GPIO 48 is Rx.

   Tx & RTS are inputs to APPS processor, bias should be disable as 
the source i.e. BT chip will pull them up.
   CTS & RX are outputs from APPS processor, where as CTS is GPIO 
which need to toggled, so the default state should be pull down.

 RX is should be pulled up.
   when TX & RX are pulled high it indicates that the lines are 
ideal i.e. no data.


Above is just my assumption, not sure whether they work on MTP.

--
Regards
Balakrishna.


Re: [RFC,v2] Bluetooth: hci_qca: Collect controller memory dump during SSR

2019-01-16 Thread Balakrishna Godavarthi

Hi Marcel,

On 2019-01-04 14:41, Marcel Holtmann wrote:

Hi Balakrishna,

We will collect the ramdump of BT controller when hardware error 
event
received before rebooting the HCI layer. Before restarting a 
subsystem

or a process running on a subsystem, it is often required to request
either a subsystem or a process to perform proper cache dump and
software failure reason into a memory buffer which application
processor can retrieve afterwards. SW developers can often provide
initial investigation by looking into that debugging information.
Signed-off-by: Balakrishna Godavarthi 
---
changes v2:
* entirely an newer approach handling with an work queue.
---
drivers/bluetooth/hci_qca.c | 289 
++--

1 file changed, 278 insertions(+), 11 deletions(-)
diff --git a/drivers/bluetooth/hci_qca.c 
b/drivers/bluetooth/hci_qca.c

index f036c8f98ea3..62b768bc32ec 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -32,6 +32,7 @@
#include 
#include 
#include 
+#include 
#include 
#include 
#include 
don't we have some crashdump core facility that could be utilized 
here?


[Bala]: no i don't think so. that is reason calling devcoredump.h


what is wrong with using devcoredump.h?



[Bala]: using the  devcoredump.h


@@ -57,9 +58,10 @@
/* Controller states */
#define STATE_IN_BAND_SLEEP_ENABLED 1
-#define IBS_WAKE_RETRANS_TIMEOUT_MS100
+#defineIBS_WAKE_RETRANS_TIMEOUT_MS 100
#define IBS_TX_IDLE_TIMEOUT_MS  2000
-#define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#defineBAUDRATE_SETTLE_TIMEOUT_MS  300
+#define MEMDUMP_COLLECTION_TIMEOUT_MS  8000
/* susclk rate */
#define SUSCLK_RATE_32KHZ   32768
@@ -67,6 +69,13 @@
/* Controller debug log header */
#define QCA_DEBUG_HANDLE0x2EDC
+/* Controller dump header */
+#define QCA_SSR_DUMP_HANDLE0x0108
+#define QCA_DUMP_PACKET_SIZE   255
+#define QCA_LAST_SEQUENCE_NUM  0x
+#define QCA_CRASHBYTE_PACKET_LEN   1100
+#define QCA_MEMDUMP_BYTE   0xFB
+
/* HCI_IBS transmit side sleep protocol states */
enum tx_ibs_states {
HCI_IBS_TX_ASLEEP,
@@ -89,12 +98,41 @@ enum hci_ibs_clock_state_vote {
HCI_IBS_RX_VOTE_CLOCK_OFF,
};
+/* Controller memory dump states */
+enum qca_memdump_states {
+   QCA_MEMDUMP_IDLE,
+   QCA_MEMDUMP_COLLECTING,
+   QCA_MEMDUMP_COLLECTED,
+   QCA_MEMDUMP_TIMEOUT,
+};
+
+struct qca_memdump_data {
+   char *memdump_buf_head;
+   char *memdump_buf_tail;
+   u32 current_seq_no;
+   u32 received_dump;
+};
+
+struct qca_memdump_event_hdr {
+   __u8evt;
+   __u8plen;
+   __u16   opcode;
+   __u16   seq_no;
+   __u8reserved;
+} __packed;
+
+
+struct qca_dump_size {
+   u32 dump_size;
+} __packed;
+
struct qca_data {
struct hci_uart *hu;
struct sk_buff *rx_skb;
struct sk_buff_head txq;
-   struct sk_buff_head tx_wait_q;  /* HCI_IBS wait queue   */
-   spinlock_t hci_ibs_lock;/* HCI_IBS state lock   */
+   struct sk_buff_head tx_wait_q;  /* HCI_IBS wait queue   */
+   struct sk_buff_head rx_memdump_q;   /* Memdump wait queue   */
+   spinlock_t hci_ibs_lock;/* HCI_IBS state lock   */
u8 tx_ibs_state;/* HCI_IBS transmit side power state*/
u8 rx_ibs_state;/* HCI_IBS receive side power state */
bool tx_vote;   /* Clock must be on for TX */
@@ -103,12 +141,17 @@ struct qca_data {
u32 tx_idle_delay;
struct timer_list wake_retrans_timer;
u32 wake_retrans;
+   struct timer_list memdump_timer;
+   u32 memdump_delay;
struct workqueue_struct *workqueue;
struct work_struct ws_awake_rx;
struct work_struct ws_awake_device;
struct work_struct ws_rx_vote_off;
struct work_struct ws_tx_vote_off;
+   struct work_struct ctrl_memdump_evt;
+   struct qca_memdump_data *qca_memdump;
unsigned long flags;
+   enum qca_memdump_states memdump_state;
/* For debugging purpose */
u64 ibs_sent_wacks;
@@ -173,6 +216,7 @@ struct qca_serdev {
static int qca_power_setup(struct hci_uart *hu, bool on);
static void qca_power_shutdown(struct hci_uart *hu);
static int qca_power_off(struct hci_dev *hdev);
+static void qca_controller_memdump(struct work_struct *work);
static void __serial_clock_on(struct tty_struct *tty)
{
@@ -446,6 +490,21 @@ static void hci_ibs_wake_retrans_timeout(struct 
timer_list *t)

hci_uart_tx_wakeup(hu);
}
+static void hci_memdump_timeout(struct timer_list *t)
+{
+   struct qca_data *qca = from_timer(qca, t, tx_idle_timer);
+   struct hci_uart *hu = qca->hu;
+   struct qca_memdump_data *qca_memdump = qca->qca_memdump;
+   char *memdump_buf = qca_memdump->memdump_buf_tail;
+
+	bt_dev_err(hu->hdev, "clearing allocated memory due to memdump 
timeout");

+   kfree(memdu

[RESEND v2] Bluetooth: hci_qca: Add helper to set device address

2019-01-16 Thread Balakrishna Godavarthi
This patch add qca_set_bdaddr() to set the device
address for latest Qualcomm Bluetooth chipset wcn3990 and above.

Signed-off-by: Balakrishna Godavarthi 
Reviewed-by: Matthias Kaehlcke 
Tested-by: Matthias Kaehlcke 
---
 drivers/bluetooth/btqca.c   | 19 +++
 drivers/bluetooth/btqca.h   |  8 +++-
 drivers/bluetooth/hci_qca.c |  5 -
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index ec9e03a6b778..612268574fc7 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -391,6 +391,25 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
 }
 EXPORT_SYMBOL_GPL(qca_uart_setup);
 
+int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+   struct sk_buff *skb;
+   int err;
+
+   skb = __hci_cmd_sync_ev(hdev, EDL_WRITE_BD_ADDR_OPCODE, 6, bdaddr,
+   HCI_EV_VENDOR, HCI_INIT_TIMEOUT);
+   if (IS_ERR(skb)) {
+   err = PTR_ERR(skb);
+   bt_dev_err(hdev, "QCA Change address cmd failed (%d)", err);
+   return err;
+   }
+
+   kfree_skb(skb);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(qca_set_bdaddr);
+
 MODULE_AUTHOR("Ben Young Tae Kim ");
 MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver " 
VERSION);
 MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
index 0c01f375fe83..c72c56ea7480 100644
--- a/drivers/bluetooth/btqca.h
+++ b/drivers/bluetooth/btqca.h
@@ -20,6 +20,7 @@
 
 #define EDL_PATCH_CMD_OPCODE   (0xFC00)
 #define EDL_NVM_ACCESS_OPCODE  (0xFC0B)
+#define EDL_WRITE_BD_ADDR_OPCODE   (0xFC14)
 #define EDL_PATCH_CMD_LEN  (1)
 #define EDL_PATCH_VER_REQ_CMD  (0x19)
 #define EDL_PATCH_TLV_REQ_CMD  (0x1E)
@@ -140,7 +141,7 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const 
bdaddr_t *bdaddr);
 int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
   enum qca_btsoc_type soc_type, u32 soc_ver);
 int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version);
-
+int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 #else
 
 static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t 
*bdaddr)
@@ -159,4 +160,9 @@ static inline int qca_read_soc_version(struct hci_dev 
*hdev, u32 *soc_version)
return -EOPNOTSUPP;
 }
 
+static inline int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+   return -EOPNOTSUPP;
+}
+
 #endif
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f036c8f98ea3..53ac5ade532b 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1241,7 +1241,10 @@ static int qca_setup(struct hci_uart *hu)
}
 
/* Setup bdaddr */
-   hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   hu->hdev->set_bdaddr = qca_set_bdaddr;
+   else
+   hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
 
return ret;
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v8 1/3] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-01-16 Thread Balakrishna Godavarthi
wcn3990 requires a power pulse to turn ON/OFF along with
regulators. Sometimes we are observing the power pulses are sent
out with some time delay, due to queuing these commands. This is
causing synchronization issues with chip, which intern delay the
chip setup or may end up with communication issues.

Signed-off-by: Balakrishna Godavarthi 
---
Changes in v8:
 * Updated 1 second timeout instead of indefinite wait.

Changes in v7:
 *  updated the wait time to 5 ms after sending power pulses.

Changes in v6:
 * added serdev_device_write_flush() in qca_send_power_pulse
   instead during the power off pulse.

Changes in v5:
 * added serdev_device_write_flush() in qca_power_off().
---
 drivers/bluetooth/hci_qca.c | 46 -
 1 file changed, 20 insertions(+), 26 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f036c8f98ea3..681bfa30467e 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -60,6 +60,7 @@
 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
 #define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#define POWER_PULSE_TRANS_TIMEOUT_MS   1000
 
 /* susclk rate */
 #define SUSCLK_RATE_32KHZ  32768
@@ -1013,11 +1014,10 @@ static inline void host_set_baudrate(struct hci_uart 
*hu, unsigned int speed)
hci_uart_set_baudrate(hu, speed);
 }
 
-static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
+static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
 {
-   struct hci_uart *hu = hci_get_drvdata(hdev);
-   struct qca_data *qca = hu->priv;
-   struct sk_buff *skb;
+   int ret;
+   int timeout = __msecs_to_jiffies(POWER_PULSE_TRANS_TIMEOUT_MS);
 
/* These power pulses are single byte command which are sent
 * at required baudrate to wcn3990. On wcn3990, we have an external
@@ -1029,22 +1029,22 @@ static int qca_send_power_pulse(struct hci_dev *hdev, 
u8 cmd)
 * save power. Disabling hardware flow control is mandatory while
 * sending power pulses to SoC.
 */
-   bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
-
-   skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
-   if (!skb)
-   return -ENOMEM;
+   bt_dev_dbg(hu->hdev, "sending power pulse %02x to controller", cmd);
 
+   serdev_device_write_flush(hu->serdev);
hci_uart_set_flow_control(hu, true);
+   ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
+   if (ret < 0) {
+   bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd);
+   return ret;
+   }
 
-   skb_put_u8(skb, cmd);
-   hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
-
-   skb_queue_tail(>txq, skb);
-   hci_uart_tx_wakeup(hu);
-
-   /* Wait for 100 uS for SoC to settle down */
-   usleep_range(100, 200);
+   serdev_device_wait_until_sent(hu->serdev, timeout);
+   /* Wait of 5ms is required for assuring to send the byte on the Tx
+* line and also for the controller to settle down for the received
+* byte.
+*/
+   usleep_range(5000, 6000);
hci_uart_set_flow_control(hu, false);
 
return 0;
@@ -1116,7 +1116,6 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
 
 static int qca_wcn3990_init(struct hci_uart *hu)
 {
-   struct hci_dev *hdev = hu->hdev;
struct qca_serdev *qcadev;
int ret;
 
@@ -1139,12 +1138,12 @@ static int qca_wcn3990_init(struct hci_uart *hu)
 
/* Forcefully enable wcn3990 to enter in to boot mode. */
host_set_baudrate(hu, 2400);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
if (ret)
return ret;
 
qca_set_speed(hu, QCA_INIT_SPEED);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWERON_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWERON_PULSE);
if (ret)
return ret;
 
@@ -1274,13 +1273,8 @@ static const struct qca_vreg_data qca_soc_data = {
 
 static void qca_power_shutdown(struct hci_uart *hu)
 {
-   struct serdev_device *serdev = hu->serdev;
-   unsigned char cmd = QCA_WCN3990_POWEROFF_PULSE;
-
host_set_baudrate(hu, 2400);
-   hci_uart_set_flow_control(hu, true);
-   serdev_device_write_buf(serdev, , sizeof(cmd));
-   hci_uart_set_flow_control(hu, false);
+   qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v8 3/3] Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

2019-01-16 Thread Balakrishna Godavarthi
During hci down we observed IBS sleep commands are queued in the Tx
buffer and hci_uart_write_work is sending data to the chip which is
not required as the chip is powered off. This patch will disable IBS
and flush the Tx buffer before we turn off the chip.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 7e4afcf40da2..7330ba71ada4 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1275,6 +1275,14 @@ static const struct qca_vreg_data qca_soc_data = {
 
 static void qca_power_shutdown(struct hci_uart *hu)
 {
+   struct qca_data *qca = hu->priv;
+
+   /* From this point we go into power off state. But serial port is
+* still open, stop queueing the IBS data and flush all the buffered
+* data in skb's.
+*/
+   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   qca_flush(hu);
host_set_baudrate(hu, 2400);
qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v8 0/3] Bug fixes for Qualcomm BT chip wcn3990.

2019-01-16 Thread Balakrishna Godavarthi
The below issues are found in our recent testing.

1. Observed device is not going into off state or not responding.
As wcn3990 require a power pulses to turn on the irrespctive of
igniting regulators, it was observed that power on or power off
pulses are not in sync with respective to chip.
The below patch will help us to wait until byte is pushed on to wires.  


* Bluetooth: hci_qca: use wait_until_sent() for power pulses

2. Observed Chip responding when we are in sleep.
   This is due to turn on flow control during change baudrate request.
   The below patch will only pull the RTS line high instead of turning off
   the flow.

   * Bluetooth: hci_qca: Pull RTS line high for baudrate change command.

3. Disable IBS state machine and flush Tx buffer
   We are disabling IBS and flushing the Tx buffer before turning off the chip.
  
   This is due to IBS state machine is active when we turn off the chip.
   This will stop queuing IBS protocol bytes.

   * Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

Changes in v8:
 * dropped inject the command complete event.
 * added one second time for the power pules instead of the indefinite time.

Changes in v7:
 * dropped frame reassmebly error patch.
 * dropped baudrate change wait time patch.
 * increased a wait to 5 ms for power pulses.

Changes in v6:
 * added serdev_device_write_flush in qca_send_power_pulse().
 * added new patch to update the baudrate change wait time.

Changes in V5:
 * added serdev_device_write_flush before sending the power off pulse
   during shutdown.

Changes in v4:
 * used serdev_device_write_buf() instead of serdev_device_write().
 * added new patch to stop logging of 0xfc00 timeout on console.

Changes in v3:
 * moved IBS & qca_flush to different patch
 * updated comments in code fo Deassert RTS patch

Balakrishna Godavarthi (3):
  Bluetooth: hci_qca: use wait_until_sent() for power pulses
  Bluetooth: hci_qca: Deassert RTS while baudrate change command
  Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

 drivers/bluetooth/hci_qca.c | 76 +++--
 1 file changed, 40 insertions(+), 36 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v8 2/3] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2019-01-16 Thread Balakrishna Godavarthi
This patch will help to stop frame reassembly errors while changing
the baudrate. This is because host send a change baudrate request
command to the chip with 115200 bps, Whereas chip will change their
UART clocks to the enable for new baudrate and sends the response
for the change request command with newer baudrate, On host side
we are still operating in 115200 bps which results of reading garbage
data. Here we are pulling RTS line, so that chip we will wait to send data
to host until host change its baudrate.

Signed-off-by: Balakrishna Godavarthi 
Tested-by: Matthias Kaehlcke 
Reviewed-by: Matthias Kaehlcke 
---
Note: will keep this change for now. If any change required after further
  discussions i will update accordingly.
---
 drivers/bluetooth/hci_qca.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 681bfa30467e..7e4afcf40da2 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -964,7 +964,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
struct sk_buff *skb;
-   struct qca_serdev *qcadev;
u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };
 
if (baudrate > QCA_BAUDRATE_320)
@@ -978,13 +977,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
return -ENOMEM;
}
 
-   /* Disabling hardware flow control is mandatory while
-* sending change baudrate request to wcn3990 SoC.
-*/
-   qcadev = serdev_device_get_drvdata(hu->serdev);
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, true);
-
/* Assign commands to change baudrate and packet type. */
skb_put_data(skb, cmd, sizeof(cmd));
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
@@ -1000,9 +992,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
set_current_state(TASK_RUNNING);
 
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, false);
-
return 0;
 }
 
@@ -1091,6 +1080,7 @@ static int qca_check_speeds(struct hci_uart *hu)
 static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
 {
unsigned int speed, qca_baudrate;
+   struct qca_serdev *qcadev;
int ret;
 
if (speed_type == QCA_INIT_SPEED) {
@@ -1102,6 +1092,15 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
if (!speed)
return 0;
 
+   /* Deassert RTS while changing the baudrate of chip and host.
+* This will prevent chip from transmitting its response with
+* the new baudrate while the host port is still operating at
+* the old speed.
+*/
+   qcadev = serdev_device_get_drvdata(hu->serdev);
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   serdev_device_set_rts(hu->serdev, false);
+
qca_baudrate = qca_get_baudrate_value(speed);
bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed);
ret = qca_set_baudrate(hu->hdev, qca_baudrate);
@@ -1109,6 +1108,9 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
return ret;
 
host_set_baudrate(hu, speed);
+
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   serdev_device_set_rts(hu->serdev, true);
}
 
return 0;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v7 4/4] Bluetooth: btqca: inject command complete event during fw download

2019-01-16 Thread Balakrishna Godavarthi

On 2019-01-15 06:50, Matthias Kaehlcke wrote:

On Mon, Jan 14, 2019 at 09:21:25PM +0530, Balakrishna Godavarthi wrote:

On 2019-01-12 04:42, Matthias Kaehlcke wrote:
> On Fri, Jan 11, 2019 at 07:53:43PM +0530, Balakrishna Godavarthi wrote:
> > Hi Matthias,
> >
> > On 2019-01-11 02:13, Matthias Kaehlcke wrote:
> > > Hi Balakrishna,
> > >
> > > On Thu, Jan 10, 2019 at 08:30:43PM +0530, Balakrishna Godavarthi wrote:
> > > > Hi Matthias,
> > > >
> > > > On 2019-01-03 03:45, Matthias Kaehlcke wrote:
> > > > > On Mon, Dec 31, 2018 at 11:34:46AM +0530, Balakrishna Godavarthi 
wrote:
> > > > > > Hi Marcel,
> > > > > >
> > > > > > On 2018-12-30 13:40, Marcel Holtmann wrote:
> > > > > > > Hi Balakrishna,
> > > > > > >
> > > > > > > > > > Latest qualcomm chips are not sending an command complete 
event for
> > > > > > > > > > every firmware packet sent to chip. They only respond with 
a vendor
> > > > > > > > > > specific event for the last firmware packet. This 
optimization will
> > > > > > > > > > decrease the BT ON time. Due to this we are seeing a 
timeout error
> > > > > > > > > > message logs on the console during firmware download. Now 
we are
> > > > > > > > > > injecting a command complete event once we receive an vendor
> > > > > > > > > > specific
> > > > > > > > > > event for the last RAM firmware packet.
> > > > > > > > > > Signed-off-by: Balakrishna Godavarthi 

> > > > > > > > > > ---
> > > > > > > > > > drivers/bluetooth/btqca.c | 39
> > > > > > > > > > ++-
> > > > > > > > > > drivers/bluetooth/btqca.h |  3 +++
> > > > > > > > > > 2 files changed, 41 insertions(+), 1 deletion(-)
> > > > > > > > > > diff --git a/drivers/bluetooth/btqca.c 
b/drivers/bluetooth/btqca.c
> > > > > > > > > > index ec9e03a6b778..0b533f65f652 100644
> > > > > > > > > > --- a/drivers/bluetooth/btqca.c
> > > > > > > > > > +++ b/drivers/bluetooth/btqca.c
> > > > > > > > > > @@ -144,6 +144,7 @@ static void qca_tlv_check_data(struct
> > > > > > > > > > rome_config *config,
> > > > > > > > > >* In case VSE is skipped, only the last 
segment is acked.
> > > > > > > > > >*/
> > > > > > > > > >   config->dnld_mode = tlv_patch->download_mode;
> > > > > > > > > > + config->dnld_type = config->dnld_mode;
> > > > > > > > > >   BT_DBG("Total Length   : %d bytes",
> > > > > > > > > >  le32_to_cpu(tlv_patch->total_size));
> > > > > > > > > > @@ -264,6 +265,31 @@ static int qca_tlv_send_segment(struct
> > > > > > > > > > hci_dev *hdev, int seg_size,
> > > > > > > > > >   return err;
> > > > > > > > > > }
> > > > > > > > > > +static int qca_inject_cmd_complete_event(struct hci_dev 
*hdev)
> > > > > > > > > > +{
> > > > > > > > > > + struct hci_event_hdr *hdr;
> > > > > > > > > > + struct hci_ev_cmd_complete *evt;
> > > > > > > > > > + struct sk_buff *skb;
> > > > > > > > > > +
> > > > > > > > > > + skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, 
GFP_KERNEL);
> > > > > > > > > > + if (!skb)
> > > > > > > > > > + return -ENOMEM;
> > > > > > > > > > +
> > > > > > > > > > + hdr = skb_put(skb, sizeof(*hdr));
> > > > > > > > > > + hdr->evt = HCI_EV_CMD_COMPLETE;
> > > > > > > > > > + hdr->plen = sizeof(*evt) + 1;
> > > > > > > > > > +
> > > > > > > > > > + evt = skb_put(

Re: [PATCH v7 4/4] Bluetooth: btqca: inject command complete event during fw download

2019-01-14 Thread Balakrishna Godavarthi

On 2019-01-12 04:42, Matthias Kaehlcke wrote:

On Fri, Jan 11, 2019 at 07:53:43PM +0530, Balakrishna Godavarthi wrote:

Hi Matthias,

On 2019-01-11 02:13, Matthias Kaehlcke wrote:
> Hi Balakrishna,
>
> On Thu, Jan 10, 2019 at 08:30:43PM +0530, Balakrishna Godavarthi wrote:
> > Hi Matthias,
> >
> > On 2019-01-03 03:45, Matthias Kaehlcke wrote:
> > > On Mon, Dec 31, 2018 at 11:34:46AM +0530, Balakrishna Godavarthi wrote:
> > > > Hi Marcel,
> > > >
> > > > On 2018-12-30 13:40, Marcel Holtmann wrote:
> > > > > Hi Balakrishna,
> > > > >
> > > > > > > > Latest qualcomm chips are not sending an command complete event 
for
> > > > > > > > every firmware packet sent to chip. They only respond with a 
vendor
> > > > > > > > specific event for the last firmware packet. This optimization 
will
> > > > > > > > decrease the BT ON time. Due to this we are seeing a timeout 
error
> > > > > > > > message logs on the console during firmware download. Now we are
> > > > > > > > injecting a command complete event once we receive an vendor
> > > > > > > > specific
> > > > > > > > event for the last RAM firmware packet.
> > > > > > > > Signed-off-by: Balakrishna Godavarthi 
> > > > > > > > ---
> > > > > > > > drivers/bluetooth/btqca.c | 39
> > > > > > > > ++-
> > > > > > > > drivers/bluetooth/btqca.h |  3 +++
> > > > > > > > 2 files changed, 41 insertions(+), 1 deletion(-)
> > > > > > > > diff --git a/drivers/bluetooth/btqca.c 
b/drivers/bluetooth/btqca.c
> > > > > > > > index ec9e03a6b778..0b533f65f652 100644
> > > > > > > > --- a/drivers/bluetooth/btqca.c
> > > > > > > > +++ b/drivers/bluetooth/btqca.c
> > > > > > > > @@ -144,6 +144,7 @@ static void qca_tlv_check_data(struct
> > > > > > > > rome_config *config,
> > > > > > > >  * In case VSE is skipped, only the last 
segment is acked.
> > > > > > > >  */
> > > > > > > > config->dnld_mode = tlv_patch->download_mode;
> > > > > > > > +   config->dnld_type = config->dnld_mode;
> > > > > > > > BT_DBG("Total Length   : %d bytes",
> > > > > > > >le32_to_cpu(tlv_patch->total_size));
> > > > > > > > @@ -264,6 +265,31 @@ static int qca_tlv_send_segment(struct
> > > > > > > > hci_dev *hdev, int seg_size,
> > > > > > > > return err;
> > > > > > > > }
> > > > > > > > +static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
> > > > > > > > +{
> > > > > > > > +   struct hci_event_hdr *hdr;
> > > > > > > > +   struct hci_ev_cmd_complete *evt;
> > > > > > > > +   struct sk_buff *skb;
> > > > > > > > +
> > > > > > > > +   skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, 
GFP_KERNEL);
> > > > > > > > +   if (!skb)
> > > > > > > > +   return -ENOMEM;
> > > > > > > > +
> > > > > > > > +   hdr = skb_put(skb, sizeof(*hdr));
> > > > > > > > +   hdr->evt = HCI_EV_CMD_COMPLETE;
> > > > > > > > +   hdr->plen = sizeof(*evt) + 1;
> > > > > > > > +
> > > > > > > > +   evt = skb_put(skb, sizeof(*evt));
> > > > > > > > +   evt->ncmd = 1;
> > > > > > > > +   evt->opcode = HCI_OP_NOP;
> > >
> > > After looking a bit more at it I realize HCI_OP_NOP is not a good
> > > value in this case:
> > >
> > > static void hci_cmd_complete_evt(...)
> > > {
> > >   ...
> > >
> > >   if (*opcode != HCI_OP_NOP)
> > > cancel_delayed_work(>cmd_timer);
> > >
> > >   ...
> > > }
> > >
> > > 
https://elixir.bootlin.com/linux/v4.19/source/net/bluetooth/hci_event.c#L3351
> > >
> > > Cancelling the command timeout 

Re: [PATCH v5 2/5] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2019-01-14 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-12 05:26, Matthias Kaehlcke wrote:

On Fri, Jan 11, 2019 at 08:37:12PM +0530, Balakrishna Godavarthi wrote:

Hi Matthias,

On 2019-01-11 07:07, Matthias Kaehlcke wrote:
> On Thu, Jan 10, 2019 at 08:22:12PM +0530, Balakrishna Godavarthi wrote:
> > Hi Johan,
> >
> > On 2019-01-10 20:09, Johan Hovold wrote:
> > > On Thu, Jan 10, 2019 at 08:04:12PM +0530, Balakrishna Godavarthi wrote:
> > > > Hi Johan,
> > > >
> > > > On 2019-01-09 20:22, Johan Hovold wrote:
> > > > > On Thu, Dec 20, 2018 at 08:16:36PM +0530, Balakrishna Godavarthi 
wrote:
> > > > >> This patch will help to stop frame reassembly errors while changing
> > > > >> the baudrate. This is because host send a change baudrate request
> > > > >> command to the chip with 115200 bps, Whereas chip will change their
> > > > >> UART clocks to the enable for new baudrate and sends the response
> > > > >> for the change request command with newer baudrate, On host side
> > > > >> we are still operating in 115200 bps which results of reading garbage
> > > > >> data. Here we are pulling RTS line, so that chip we will wait to send
> > > > >> data
> > > > >> to host until host change its baudrate.
> > >
> > > > >> +  /* Deassert RTS while changing the baudrate of chip and 
host.
> > > > >> +   * This will prevent chip from transmitting its response 
with
> > > > >> +   * the new baudrate while the host port is still 
operating at
> > > > >> +   * the old speed.
> > > > >> +   */
> > > > >> +  qcadev = serdev_device_get_drvdata(hu->serdev);
> > > > >> +  if (qcadev->btsoc_type == QCA_WCN3990)
> > > > >> +  serdev_device_set_rts(hu->serdev, false);
> > > > >> +
> > > > >
> > > > > This may not do what you want unless you also disable hardware flow
> > > > > control.
> > >
> > > > Here my requirement here is to block the chip to send its data before
> > > > HOST changes it is baudrate. So if i disable flow control lines of
> > > > HOST which will be in low state.  so that the chip will send it data
> > > > before HOST change the baudrate of HOST. which results in frame
> > > > reassembly error.
> > >
> > > Not sure I understand what you're trying to say above. My point is that
> > > you cannot reliable control RTS when you have automatic flow control
> > > enabled (i.e. it is managed by hardware and it's state reflects whether
> > > there's room in the UART receive FIFO).
> > >
> > > Johan
> >
> > [Bala]: Yes i got your point, but our driver
>
> I suppose with "our driver" you refer to a Qualcomm UART driver like
> qcom_geni_serial.c. Unless the Bluetooth controller is really tied to
> some specific SoC (e.g. because it is on-chip) you shouldn't make
> assumptions about the UART driver or hardware beyond standard
> behavior.
>
> But even if we assume that the driver you mention is used, I think you
> are rather confirming Johan's concern than dispersing it:
>

[Bala]: now understood the point.

> > will not support automatic flow control (based on the FIFO status)
> > unless we explicitly enabled via software. i.e. if we enable the
> > flow, hardware will look for it else it will not looks for CTS or
> > RTS Line.
>
> So we agree that the UART hardware may change RTS if hardware flow
> control is enabled?
>
> static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
> {
>   ...
>   hci_uart_set_flow_control(hu, false);
>   ...
> }
>
> I still find it utterly confusing that set_flow_control(false) enables
> flow control, but that's what it does, hence after
> qca_send_power_pulse() flow control is (re-)enabled.
>
> So far I haven't seen problems with qcom_geni_serial.c overriding the
> level set with serdev_device_set_rts(), but I tend to agree with Johan
> that this could be a problem (if not with this UART (driver) then with
> another). I'm not keen about adding more flow control on/off clutter,
> but if that is needed for the driver to operate reliably across
> platforms so be it.
>
> Cheers
>
> Matthias

[Bala]: previously we have disabling the flow control, that is not 
pulling

the RTS line if it disabled.
so that the reason we are explicilty pulling it by calling 
set_rts()

with false.

Johan concern 

Re: [PATCH v5 1/5] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-01-14 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-12 05:08, Matthias Kaehlcke wrote:

On Fri, Jan 11, 2019 at 08:02:00PM +0530, Balakrishna Godavarthi wrote:

On 2019-01-11 06:25, Matthias Kaehlcke wrote:
> On Thu, Jan 10, 2019 at 08:18:37PM +0530, Balakrishna Godavarthi wrote:
> > Hi Johan,
> >
> > On 2019-01-09 20:08, Johan Hovold wrote:
> > > On Fri, Dec 21, 2018 at 05:59:47PM -0800, Matthias Kaehlcke wrote:
> > > > On Thu, Dec 20, 2018 at 08:16:35PM +0530, Balakrishna Godavarthi
> > > > wrote:
> > > > > wcn3990 requires a power pulse to turn ON/OFF along with
> > > > > regulators. Sometimes we are observing the power pulses are sent
> > > > > out with some time delay, due to queuing these commands. This is
> > > > > causing synchronization issues with chip, which intern delay the
> > > > > chip setup or may end up with communication issues.
> > > > >
> > > > > Signed-off-by: Balakrishna Godavarthi 
> > > > > ---
> > > > >  drivers/bluetooth/hci_qca.c | 38 
++---
> > > > >  1 file changed, 14 insertions(+), 24 deletions(-)
> > > > >
> > > > > diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> > > > > index f036c8f98ea3..5a07c2370289 100644
> > > > > --- a/drivers/bluetooth/hci_qca.c
> > > > > +++ b/drivers/bluetooth/hci_qca.c
> > > > > @@ -1013,11 +1013,9 @@ static inline void host_set_baudrate(struct 
hci_uart *hu, unsigned int speed)
> > > > >hci_uart_set_baudrate(hu, speed);
> > > > >  }
> > > > >
> > > > > -static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
> > > > > +static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
> > > > >  {
> > > > > -  struct hci_uart *hu = hci_get_drvdata(hdev);
> > > > > -  struct qca_data *qca = hu->priv;
> > > > > -  struct sk_buff *skb;
> > > > > +  int ret;
> > > > >
> > > > >/* These power pulses are single byte command which are sent
> > > > > * at required baudrate to wcn3990. On wcn3990, we have an 
external
> > > > > @@ -1029,19 +1027,16 @@ static int qca_send_power_pulse(struct 
hci_dev *hdev, u8 cmd)
> > > > > * save power. Disabling hardware flow control is mandatory 
while
> > > > > * sending power pulses to SoC.
> > > > > */
> > > > > -  bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
> > > > > -
> > > > > -  skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
> > > > > -  if (!skb)
> > > > > -  return -ENOMEM;
> > > > > -
> > > > > +  bt_dev_dbg(hu->hdev, "sending power pulse %02x to SoC", cmd);
> > > > >hci_uart_set_flow_control(hu, true);
> > > > > +  ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
> > > > > +  if (ret < 0) {
> > > > > +  bt_dev_err(hu->hdev, "failed to send power pulse %02x to 
SoC",
> > > > > + cmd);
> > > > > +  return ret;
> > > > > +  }
> > > > >
> > > > > -  skb_put_u8(skb, cmd);
> > > > > -  hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
> > > > > -
> > > > > -  skb_queue_tail(>txq, skb);
> > > > > -  hci_uart_tx_wakeup(hu);
> > > > > +  serdev_device_wait_until_sent(hu->serdev, 0);
> > >
> > > Again, do you really want to wait indefinitely here?
> > >
> > [Bala]: these commands are mandatory to turn ON or OFF the chip.
> > so blocking to the max time is required.
> > these commands are sent during the BT chip ON & OFF.
> > in the latest series, i have flushed the uart before sending
> > this
> > commands
> > so the uart FIFO(as just opened the port before calling this
> > function) or the circular
> > buffer will be empty and also i am disabling the flow
> > control too.
> >https://patchwork.kernel.org/patch/10744435/
>
> The commands may be mandatory for switching the chip on or off, but
> what is better if there is a problem with sending them (e.g. a buggy
> UART driver):
>
> 1. wait a reasonable time, report an error
>

Re: [PATCH v5 2/5] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2019-01-11 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-11 07:07, Matthias Kaehlcke wrote:

On Thu, Jan 10, 2019 at 08:22:12PM +0530, Balakrishna Godavarthi wrote:

Hi Johan,

On 2019-01-10 20:09, Johan Hovold wrote:
> On Thu, Jan 10, 2019 at 08:04:12PM +0530, Balakrishna Godavarthi wrote:
> > Hi Johan,
> >
> > On 2019-01-09 20:22, Johan Hovold wrote:
> > > On Thu, Dec 20, 2018 at 08:16:36PM +0530, Balakrishna Godavarthi wrote:
> > >> This patch will help to stop frame reassembly errors while changing
> > >> the baudrate. This is because host send a change baudrate request
> > >> command to the chip with 115200 bps, Whereas chip will change their
> > >> UART clocks to the enable for new baudrate and sends the response
> > >> for the change request command with newer baudrate, On host side
> > >> we are still operating in 115200 bps which results of reading garbage
> > >> data. Here we are pulling RTS line, so that chip we will wait to send
> > >> data
> > >> to host until host change its baudrate.
>
> > >> +/* Deassert RTS while changing the baudrate of chip and 
host.
> > >> + * This will prevent chip from transmitting its response 
with
> > >> + * the new baudrate while the host port is still operating 
at
> > >> + * the old speed.
> > >> + */
> > >> +qcadev = serdev_device_get_drvdata(hu->serdev);
> > >> +if (qcadev->btsoc_type == QCA_WCN3990)
> > >> +serdev_device_set_rts(hu->serdev, false);
> > >> +
> > >
> > > This may not do what you want unless you also disable hardware flow
> > > control.
>
> > Here my requirement here is to block the chip to send its data before
> > HOST changes it is baudrate. So if i disable flow control lines of
> > HOST which will be in low state.  so that the chip will send it data
> > before HOST change the baudrate of HOST. which results in frame
> > reassembly error.
>
> Not sure I understand what you're trying to say above. My point is that
> you cannot reliable control RTS when you have automatic flow control
> enabled (i.e. it is managed by hardware and it's state reflects whether
> there's room in the UART receive FIFO).
>
> Johan

[Bala]: Yes i got your point, but our driver


I suppose with "our driver" you refer to a Qualcomm UART driver like
qcom_geni_serial.c. Unless the Bluetooth controller is really tied to
some specific SoC (e.g. because it is on-chip) you shouldn't make
assumptions about the UART driver or hardware beyond standard
behavior.

But even if we assume that the driver you mention is used, I think you
are rather confirming Johan's concern than dispersing it:



[Bala]: now understood the point.


will not support automatic flow control (based on the FIFO status)
unless we explicitly enabled via software. i.e. if we enable the
flow, hardware will look for it else it will not looks for CTS or
RTS Line.


So we agree that the UART hardware may change RTS if hardware flow
control is enabled?

static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
{
  ...
  hci_uart_set_flow_control(hu, false);
  ...
}

I still find it utterly confusing that set_flow_control(false) enables
flow control, but that's what it does, hence after
qca_send_power_pulse() flow control is (re-)enabled.

So far I haven't seen problems with qcom_geni_serial.c overriding the
level set with serdev_device_set_rts(), but I tend to agree with Johan
that this could be a problem (if not with this UART (driver) then with
another). I'm not keen about adding more flow control on/off clutter,
but if that is needed for the driver to operate reliably across
platforms so be it.

Cheers

Matthias


[Bala]: previously we have disabling the flow control, that is not 
pulling the RTS line if it disabled.
so that the reason we are explicilty pulling it by calling 
set_rts() with false.


Johan concern can be fixed either of two ways.

1. disable the flow control, but the uart driver should pull the 
RTS line high. as the line is unused
2. disable the flow control and call set_rts with false that 
will helps us to pull the RTS line.


will experiment more on this and post the change.


--
Regards
Balakrishna.


Re: [PATCH v5 1/5] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-01-11 Thread Balakrishna Godavarthi

On 2019-01-11 06:25, Matthias Kaehlcke wrote:

On Thu, Jan 10, 2019 at 08:18:37PM +0530, Balakrishna Godavarthi wrote:

Hi Johan,

On 2019-01-09 20:08, Johan Hovold wrote:
> On Fri, Dec 21, 2018 at 05:59:47PM -0800, Matthias Kaehlcke wrote:
> > On Thu, Dec 20, 2018 at 08:16:35PM +0530, Balakrishna Godavarthi
> > wrote:
> > > wcn3990 requires a power pulse to turn ON/OFF along with
> > > regulators. Sometimes we are observing the power pulses are sent
> > > out with some time delay, due to queuing these commands. This is
> > > causing synchronization issues with chip, which intern delay the
> > > chip setup or may end up with communication issues.
> > >
> > > Signed-off-by: Balakrishna Godavarthi 
> > > ---
> > >  drivers/bluetooth/hci_qca.c | 38 ++---
> > >  1 file changed, 14 insertions(+), 24 deletions(-)
> > >
> > > diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> > > index f036c8f98ea3..5a07c2370289 100644
> > > --- a/drivers/bluetooth/hci_qca.c
> > > +++ b/drivers/bluetooth/hci_qca.c
> > > @@ -1013,11 +1013,9 @@ static inline void host_set_baudrate(struct 
hci_uart *hu, unsigned int speed)
> > >  hci_uart_set_baudrate(hu, speed);
> > >  }
> > >
> > > -static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
> > > +static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
> > >  {
> > > -struct hci_uart *hu = hci_get_drvdata(hdev);
> > > -struct qca_data *qca = hu->priv;
> > > -struct sk_buff *skb;
> > > +int ret;
> > >
> > >  /* These power pulses are single byte command which are sent
> > >   * at required baudrate to wcn3990. On wcn3990, we have an 
external
> > > @@ -1029,19 +1027,16 @@ static int qca_send_power_pulse(struct hci_dev 
*hdev, u8 cmd)
> > >   * save power. Disabling hardware flow control is mandatory while
> > >   * sending power pulses to SoC.
> > >   */
> > > -bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
> > > -
> > > -skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
> > > -if (!skb)
> > > -return -ENOMEM;
> > > -
> > > +bt_dev_dbg(hu->hdev, "sending power pulse %02x to SoC", cmd);
> > >  hci_uart_set_flow_control(hu, true);
> > > +ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
> > > +if (ret < 0) {
> > > +bt_dev_err(hu->hdev, "failed to send power pulse %02x to 
SoC",
> > > +   cmd);
> > > +return ret;
> > > +}
> > >
> > > -skb_put_u8(skb, cmd);
> > > -hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
> > > -
> > > -skb_queue_tail(>txq, skb);
> > > -hci_uart_tx_wakeup(hu);
> > > +serdev_device_wait_until_sent(hu->serdev, 0);
>
> Again, do you really want to wait indefinitely here?
>
[Bala]: these commands are mandatory to turn ON or OFF the chip.
so blocking to the max time is required.
these commands are sent during the BT chip ON & OFF.
in the latest series, i have flushed the uart before sending 
this

commands
so the uart FIFO(as just opened the port before calling this
function) or the circular
buffer will be empty and also i am disabling the flow control 
too.

   https://patchwork.kernel.org/patch/10744435/


The commands may be mandatory for switching the chip on or off, but
what is better if there is a problem with sending them (e.g. a buggy
UART driver):

1. wait a reasonable time, report an error
2. wait forever

?

If the single byte command couldn't be sent after a few milliseconds,
it likely never will, waiting forever doesn't fix that. An error
report at least provides some information about the problem and the
driver is in a not-hanging state.

Cheers

Matthias


[Bala]: will update this with a bound TIMEOUT value. But 
wait_until_sent() is void return

type how could we know that the data is sent out on the lines.


--
Regards
Balakrishna.


Re: [PATCH v7 4/4] Bluetooth: btqca: inject command complete event during fw download

2019-01-11 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-11 02:13, Matthias Kaehlcke wrote:

Hi Balakrishna,

On Thu, Jan 10, 2019 at 08:30:43PM +0530, Balakrishna Godavarthi wrote:

Hi Matthias,

On 2019-01-03 03:45, Matthias Kaehlcke wrote:
> On Mon, Dec 31, 2018 at 11:34:46AM +0530, Balakrishna Godavarthi wrote:
> > Hi Marcel,
> >
> > On 2018-12-30 13:40, Marcel Holtmann wrote:
> > > Hi Balakrishna,
> > >
> > > > > > Latest qualcomm chips are not sending an command complete event for
> > > > > > every firmware packet sent to chip. They only respond with a vendor
> > > > > > specific event for the last firmware packet. This optimization will
> > > > > > decrease the BT ON time. Due to this we are seeing a timeout error
> > > > > > message logs on the console during firmware download. Now we are
> > > > > > injecting a command complete event once we receive an vendor
> > > > > > specific
> > > > > > event for the last RAM firmware packet.
> > > > > > Signed-off-by: Balakrishna Godavarthi 
> > > > > > ---
> > > > > > drivers/bluetooth/btqca.c | 39
> > > > > > ++-
> > > > > > drivers/bluetooth/btqca.h |  3 +++
> > > > > > 2 files changed, 41 insertions(+), 1 deletion(-)
> > > > > > diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
> > > > > > index ec9e03a6b778..0b533f65f652 100644
> > > > > > --- a/drivers/bluetooth/btqca.c
> > > > > > +++ b/drivers/bluetooth/btqca.c
> > > > > > @@ -144,6 +144,7 @@ static void qca_tlv_check_data(struct
> > > > > > rome_config *config,
> > > > > >* In case VSE is skipped, only the last segment is acked.
> > > > > >*/
> > > > > >   config->dnld_mode = tlv_patch->download_mode;
> > > > > > + config->dnld_type = config->dnld_mode;
> > > > > >   BT_DBG("Total Length   : %d bytes",
> > > > > >  le32_to_cpu(tlv_patch->total_size));
> > > > > > @@ -264,6 +265,31 @@ static int qca_tlv_send_segment(struct
> > > > > > hci_dev *hdev, int seg_size,
> > > > > >   return err;
> > > > > > }
> > > > > > +static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
> > > > > > +{
> > > > > > + struct hci_event_hdr *hdr;
> > > > > > + struct hci_ev_cmd_complete *evt;
> > > > > > + struct sk_buff *skb;
> > > > > > +
> > > > > > + skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, GFP_KERNEL);
> > > > > > + if (!skb)
> > > > > > + return -ENOMEM;
> > > > > > +
> > > > > > + hdr = skb_put(skb, sizeof(*hdr));
> > > > > > + hdr->evt = HCI_EV_CMD_COMPLETE;
> > > > > > + hdr->plen = sizeof(*evt) + 1;
> > > > > > +
> > > > > > + evt = skb_put(skb, sizeof(*evt));
> > > > > > + evt->ncmd = 1;
> > > > > > + evt->opcode = HCI_OP_NOP;
>
> After looking a bit more at it I realize HCI_OP_NOP is not a good
> value in this case:
>
> static void hci_cmd_complete_evt(...)
> {
>   ...
>
>   if (*opcode != HCI_OP_NOP)
> cancel_delayed_work(>cmd_timer);
>
>   ...
> }
>
> https://elixir.bootlin.com/linux/v4.19/source/net/bluetooth/hci_event.c#L3351
>
> Cancelling the command timeout is precisely what we want. Not sure why
> the patch with HCI_OP_NOP makes the timeouts go away in most cases
> (but not e.g. when inserting an msleep(1000) after downloading the
> NVM.
>
> I suggest to pass the opcode of the command to be completed.
>
> > > > > > +
> > > > > > + skb_put_u8(skb, QCA_HCI_CC_SUCCESS);
> > > > > > +
> > > > > > + hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
> > > > > > +
> > > > > > + return hci_recv_frame(hdev, skb);
> > > > > > +}
> > > > > > +
> > > > > > static int qca_download_firmware(struct hci_dev *hdev,
> > > > > > struct rome_config *config)
> > > > > > {
> > > > > > @@ -297,11 +323,22 @@ static int
> > > > > > qca_download_firmware(struct hci_dev *hdev,
> &g

Re: [PATCH v7 4/4] Bluetooth: btqca: inject command complete event during fw download

2019-01-10 Thread Balakrishna Godavarthi

Hi Matthias,

On 2019-01-03 03:45, Matthias Kaehlcke wrote:

On Mon, Dec 31, 2018 at 11:34:46AM +0530, Balakrishna Godavarthi wrote:

Hi Marcel,

On 2018-12-30 13:40, Marcel Holtmann wrote:
> Hi Balakrishna,
>
> > > > Latest qualcomm chips are not sending an command complete event for
> > > > every firmware packet sent to chip. They only respond with a vendor
> > > > specific event for the last firmware packet. This optimization will
> > > > decrease the BT ON time. Due to this we are seeing a timeout error
> > > > message logs on the console during firmware download. Now we are
> > > > injecting a command complete event once we receive an vendor
> > > > specific
> > > > event for the last RAM firmware packet.
> > > > Signed-off-by: Balakrishna Godavarthi 
> > > > ---
> > > > drivers/bluetooth/btqca.c | 39
> > > > ++-
> > > > drivers/bluetooth/btqca.h |  3 +++
> > > > 2 files changed, 41 insertions(+), 1 deletion(-)
> > > > diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
> > > > index ec9e03a6b778..0b533f65f652 100644
> > > > --- a/drivers/bluetooth/btqca.c
> > > > +++ b/drivers/bluetooth/btqca.c
> > > > @@ -144,6 +144,7 @@ static void qca_tlv_check_data(struct
> > > > rome_config *config,
> > > >  * In case VSE is skipped, only the last segment is acked.
> > > >  */
> > > > config->dnld_mode = tlv_patch->download_mode;
> > > > +   config->dnld_type = config->dnld_mode;
> > > > BT_DBG("Total Length   : %d bytes",
> > > >le32_to_cpu(tlv_patch->total_size));
> > > > @@ -264,6 +265,31 @@ static int qca_tlv_send_segment(struct
> > > > hci_dev *hdev, int seg_size,
> > > > return err;
> > > > }
> > > > +static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
> > > > +{
> > > > +   struct hci_event_hdr *hdr;
> > > > +   struct hci_ev_cmd_complete *evt;
> > > > +   struct sk_buff *skb;
> > > > +
> > > > +   skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, GFP_KERNEL);
> > > > +   if (!skb)
> > > > +   return -ENOMEM;
> > > > +
> > > > +   hdr = skb_put(skb, sizeof(*hdr));
> > > > +   hdr->evt = HCI_EV_CMD_COMPLETE;
> > > > +   hdr->plen = sizeof(*evt) + 1;
> > > > +
> > > > +   evt = skb_put(skb, sizeof(*evt));
> > > > +   evt->ncmd = 1;
> > > > +   evt->opcode = HCI_OP_NOP;


After looking a bit more at it I realize HCI_OP_NOP is not a good
value in this case:

static void hci_cmd_complete_evt(...)
{
  ...

  if (*opcode != HCI_OP_NOP)
cancel_delayed_work(>cmd_timer);

  ...
}

https://elixir.bootlin.com/linux/v4.19/source/net/bluetooth/hci_event.c#L3351

Cancelling the command timeout is precisely what we want. Not sure why
the patch with HCI_OP_NOP makes the timeouts go away in most cases
(but not e.g. when inserting an msleep(1000) after downloading the
NVM.

I suggest to pass the opcode of the command to be completed.


> > > > +
> > > > +   skb_put_u8(skb, QCA_HCI_CC_SUCCESS);
> > > > +
> > > > +   hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
> > > > +
> > > > +   return hci_recv_frame(hdev, skb);
> > > > +}
> > > > +
> > > > static int qca_download_firmware(struct hci_dev *hdev,
> > > >   struct rome_config *config)
> > > > {
> > > > @@ -297,11 +323,22 @@ static int
> > > > qca_download_firmware(struct hci_dev *hdev,
> > > > ret = qca_tlv_send_segment(hdev, segsize, segment,
> > > > config->dnld_mode);
> > > > if (ret)
> > > > -   break;
> > > > +   goto out;
> > > > segment += segsize;
> > > > }
> > > > +   /* Latest qualcomm chipsets are not sending a command
> > > > complete event
> > > > +* for every fw packet sent. They only respond with a
> > > > vendor specific
> > > > +* event for the last packet. This optimization in the chip will
> > > > +* decrease the BT in initialization time. Here we will
> > > > inject a command
> > > > +* complete event to avoid a co

Re: [PATCH v5 2/5] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2019-01-10 Thread Balakrishna Godavarthi

Hi Johan,

On 2019-01-10 20:09, Johan Hovold wrote:

On Thu, Jan 10, 2019 at 08:04:12PM +0530, Balakrishna Godavarthi wrote:

Hi Johan,

On 2019-01-09 20:22, Johan Hovold wrote:
> On Thu, Dec 20, 2018 at 08:16:36PM +0530, Balakrishna Godavarthi wrote:
>> This patch will help to stop frame reassembly errors while changing
>> the baudrate. This is because host send a change baudrate request
>> command to the chip with 115200 bps, Whereas chip will change their
>> UART clocks to the enable for new baudrate and sends the response
>> for the change request command with newer baudrate, On host side
>> we are still operating in 115200 bps which results of reading garbage
>> data. Here we are pulling RTS line, so that chip we will wait to send
>> data
>> to host until host change its baudrate.



>> +  /* Deassert RTS while changing the baudrate of chip and host.
>> +   * This will prevent chip from transmitting its response with
>> +   * the new baudrate while the host port is still operating at
>> +   * the old speed.
>> +   */
>> +  qcadev = serdev_device_get_drvdata(hu->serdev);
>> +  if (qcadev->btsoc_type == QCA_WCN3990)
>> +  serdev_device_set_rts(hu->serdev, false);
>> +
>
> This may not do what you want unless you also disable hardware flow
> control.



Here my requirement here is to block the chip to send its data before
HOST changes it is baudrate. So if i disable flow control lines of
HOST which will be in low state.  so that the chip will send it data
before HOST change the baudrate of HOST. which results in frame
reassembly error.


Not sure I understand what you're trying to say above. My point is that
you cannot reliable control RTS when you have automatic flow control
enabled (i.e. it is managed by hardware and it's state reflects whether
there's room in the UART receive FIFO).

Johan


[Bala]: Yes i got your point, but our driver will not support automatic 
flow control (based on the FIFO status)
unless we explicitly enabled via software. i.e. if we enable the 
flow, hardware will look for it.

else it will not looks for CTS or RTS Line.

--
Regards
Balakrishna.


Re: [PATCH v5 1/5] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2019-01-10 Thread Balakrishna Godavarthi

Hi Johan,

On 2019-01-09 20:08, Johan Hovold wrote:

On Fri, Dec 21, 2018 at 05:59:47PM -0800, Matthias Kaehlcke wrote:
On Thu, Dec 20, 2018 at 08:16:35PM +0530, Balakrishna Godavarthi 
wrote:

> wcn3990 requires a power pulse to turn ON/OFF along with
> regulators. Sometimes we are observing the power pulses are sent
> out with some time delay, due to queuing these commands. This is
> causing synchronization issues with chip, which intern delay the
> chip setup or may end up with communication issues.
>
> Signed-off-by: Balakrishna Godavarthi 
> ---
>  drivers/bluetooth/hci_qca.c | 38 ++---
>  1 file changed, 14 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index f036c8f98ea3..5a07c2370289 100644
> --- a/drivers/bluetooth/hci_qca.c
> +++ b/drivers/bluetooth/hci_qca.c
> @@ -1013,11 +1013,9 @@ static inline void host_set_baudrate(struct hci_uart 
*hu, unsigned int speed)
>hci_uart_set_baudrate(hu, speed);
>  }
>
> -static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
> +static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
>  {
> -  struct hci_uart *hu = hci_get_drvdata(hdev);
> -  struct qca_data *qca = hu->priv;
> -  struct sk_buff *skb;
> +  int ret;
>
>/* These power pulses are single byte command which are sent
> * at required baudrate to wcn3990. On wcn3990, we have an external
> @@ -1029,19 +1027,16 @@ static int qca_send_power_pulse(struct hci_dev *hdev, 
u8 cmd)
> * save power. Disabling hardware flow control is mandatory while
> * sending power pulses to SoC.
> */
> -  bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
> -
> -  skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
> -  if (!skb)
> -  return -ENOMEM;
> -
> +  bt_dev_dbg(hu->hdev, "sending power pulse %02x to SoC", cmd);
>hci_uart_set_flow_control(hu, true);
> +  ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
> +  if (ret < 0) {
> +  bt_dev_err(hu->hdev, "failed to send power pulse %02x to SoC",
> + cmd);
> +  return ret;
> +  }
>
> -  skb_put_u8(skb, cmd);
> -  hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
> -
> -  skb_queue_tail(>txq, skb);
> -  hci_uart_tx_wakeup(hu);
> +  serdev_device_wait_until_sent(hu->serdev, 0);


Again, do you really want to wait indefinitely here?


[Bala]: these commands are mandatory to turn ON or OFF the chip.
so blocking to the max time is required.
these commands are sent during the BT chip ON & OFF.
in the latest series, i have flushed the uart before sending 
this commands
so the uart FIFO(as just opened the port before calling this 
function) or the circular
buffer will be empty and also i am disabling the flow control 
too.

   https://patchwork.kernel.org/patch/10744435/


serdev_device_wait_until_sent() might only guarantee that the UART
circular buffer is empty (see
https://elixir.bootlin.com/linux/v4.19/source/drivers/tty/tty_ioctl.c#L225),
not that the data has actually sent (e.g. it might be sitting in
the UART FIFO).


For serial core, uart_wait_until_sent() makes sure also the UART FIFO 
is

empty, although it may time out when using flow control (as then the
FIFO may never empty, and flow control appears to be enabled here).

Johan



[Bala]: Pls refer the latest patch series 
https://patchwork.kernel.org/patch/10744435/
   where i am flushing the circular buffer before calling the 
qca_send_power_pulse().

   this how the flow

   1. open serial port (gurantess that UART FIFO is empty)
   2. flush the circular buffer
   3. disable the flow control.
   4. send the command byte.
   5. wait for the circular buffer is empty.

   the above is one time process,

--
Regards
Balakrishna.


Re: [PATCH v5 2/5] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2019-01-10 Thread Balakrishna Godavarthi

Hi Johan,

On 2019-01-09 20:22, Johan Hovold wrote:

On Thu, Dec 20, 2018 at 08:16:36PM +0530, Balakrishna Godavarthi wrote:

This patch will help to stop frame reassembly errors while changing
the baudrate. This is because host send a change baudrate request
command to the chip with 115200 bps, Whereas chip will change their
UART clocks to the enable for new baudrate and sends the response
for the change request command with newer baudrate, On host side
we are still operating in 115200 bps which results of reading garbage
data. Here we are pulling RTS line, so that chip we will wait to send 
data

to host until host change its baudrate.

Signed-off-by: Balakrishna Godavarthi 
Tested-by: Matthias Kaehlcke 
Reviewed-by: Matthias Kaehlcke 
---
 drivers/bluetooth/hci_qca.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 5a07c2370289..1680ead6cc3d 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -963,7 +963,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, 
uint8_t baudrate)

struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
struct sk_buff *skb;
-   struct qca_serdev *qcadev;
u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };

if (baudrate > QCA_BAUDRATE_320)
@@ -977,13 +976,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, 
uint8_t baudrate)

return -ENOMEM;
}

-   /* Disabling hardware flow control is mandatory while
-* sending change baudrate request to wcn3990 SoC.
-*/
-   qcadev = serdev_device_get_drvdata(hu->serdev);
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, true);
-
/* Assign commands to change baudrate and packet type. */
skb_put_data(skb, cmd, sizeof(cmd));
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
@@ -999,9 +991,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, 
uint8_t baudrate)

schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
set_current_state(TASK_RUNNING);

-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, false);
-
return 0;
 }

@@ -1086,6 +1075,7 @@ static int qca_check_speeds(struct hci_uart *hu)
 static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type 
speed_type)

 {
unsigned int speed, qca_baudrate;
+   struct qca_serdev *qcadev;
int ret;

if (speed_type == QCA_INIT_SPEED) {
@@ -1097,6 +1087,15 @@ static int qca_set_speed(struct hci_uart *hu, 
enum qca_speed_type speed_type)

if (!speed)
return 0;

+   /* Deassert RTS while changing the baudrate of chip and host.
+* This will prevent chip from transmitting its response with
+* the new baudrate while the host port is still operating at
+* the old speed.
+*/
+   qcadev = serdev_device_get_drvdata(hu->serdev);
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   serdev_device_set_rts(hu->serdev, false);
+


This may not do what you want unless you also disable hardware flow
control.

Johan



Here my requirement here is to block the chip to send its data before 
HOST changes
it is baudrate. So if i disable flow control lines of HOST which will be 
in low state.
so that the chip will send it data before HOST change the baudrate of 
HOST. which results in

frame reassembly error.

--
Regards
Balakrishna.


Re: [RESEND, v2] Bluetooth: hci_qca: Add helper to set device address

2019-01-07 Thread Balakrishna Godavarthi

Hi Marcel,

On 2018-12-28 17:37, Balakrishna Godavarthi wrote:

This patch add qca_set_bdaddr() to set the device
address for latest Qualcomm Bluetooth chipset wcn3990 and above.

Signed-off-by: Balakrishna Godavarthi 
Reviewed-by: Matthias Kaehlcke 
Tested-by: Matthias Kaehlcke 
---
 drivers/bluetooth/btqca.c   | 19 +++
 drivers/bluetooth/btqca.h   |  8 +++-
 drivers/bluetooth/hci_qca.c |  5 -
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index ec9e03a6b778..612268574fc7 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -391,6 +391,25 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t 
baudrate,

 }
 EXPORT_SYMBOL_GPL(qca_uart_setup);

+int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+   struct sk_buff *skb;
+   int err;
+
+   skb = __hci_cmd_sync_ev(hdev, EDL_WRITE_BD_ADDR_OPCODE, 6, bdaddr,
+   HCI_EV_VENDOR, HCI_INIT_TIMEOUT);
+   if (IS_ERR(skb)) {
+   err = PTR_ERR(skb);
+   bt_dev_err(hdev, "QCA Change address cmd failed (%d)", err);
+   return err;
+   }
+
+   kfree_skb(skb);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(qca_set_bdaddr);
+
 MODULE_AUTHOR("Ben Young Tae Kim ");
 MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver
" VERSION);
 MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
index 0c01f375fe83..c72c56ea7480 100644
--- a/drivers/bluetooth/btqca.h
+++ b/drivers/bluetooth/btqca.h
@@ -20,6 +20,7 @@

 #define EDL_PATCH_CMD_OPCODE   (0xFC00)
 #define EDL_NVM_ACCESS_OPCODE  (0xFC0B)
+#define EDL_WRITE_BD_ADDR_OPCODE   (0xFC14)
 #define EDL_PATCH_CMD_LEN  (1)
 #define EDL_PATCH_VER_REQ_CMD  (0x19)
 #define EDL_PATCH_TLV_REQ_CMD  (0x1E)
@@ -140,7 +141,7 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev,
const bdaddr_t *bdaddr);
 int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
   enum qca_btsoc_type soc_type, u32 soc_ver);
 int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version);
-
+int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 #else

 static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const
bdaddr_t *bdaddr)
@@ -159,4 +160,9 @@ static inline int qca_read_soc_version(struct
hci_dev *hdev, u32 *soc_version)
return -EOPNOTSUPP;
 }

+static inline int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t 
*bdaddr)

+{
+   return -EOPNOTSUPP;
+}
+
 #endif
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f036c8f98ea3..53ac5ade532b 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1241,7 +1241,10 @@ static int qca_setup(struct hci_uart *hu)
}

/* Setup bdaddr */
-   hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   hu->hdev->set_bdaddr = qca_set_bdaddr;
+   else
+   hu->hdev->set_bdaddr = qca_set_bdaddr_rome;

return ret;
 }



Can you pls review this change.

--
Regards
Balakrishna.


Re: [RFC,v2] Bluetooth: hci_qca: Collect controller memory dump during SSR

2019-01-03 Thread Balakrishna Godavarthi

Hi Marcel,

On 2018-12-29 12:57, Marcel Holtmann wrote:

Hi Balakrishna,


We will collect the ramdump of BT controller when hardware error event
received before rebooting the HCI layer. Before restarting a subsystem
or a process running on a subsystem, it is often required to request
either a subsystem or a process to perform proper cache dump and
software failure reason into a memory buffer which application
processor can retrieve afterwards. SW developers can often provide
initial investigation by looking into that debugging information.

Signed-off-by: Balakrishna Godavarthi 
---
changes v2:
* entirely an newer approach handling with an work queue.

---
drivers/bluetooth/hci_qca.c | 289 ++--
1 file changed, 278 insertions(+), 11 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f036c8f98ea3..62b768bc32ec 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -32,6 +32,7 @@
#include 
#include 
#include 
+#include 
#include 
#include 
#include 


don't we have some crashdump core facility that could be utilized here?



[Bala]: no i don't think so. that is reason calling devcoredump.h


@@ -57,9 +58,10 @@
/* Controller states */
#define STATE_IN_BAND_SLEEP_ENABLED 1

-#define IBS_WAKE_RETRANS_TIMEOUT_MS100
+#defineIBS_WAKE_RETRANS_TIMEOUT_MS 100
#define IBS_TX_IDLE_TIMEOUT_MS  2000
-#define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#defineBAUDRATE_SETTLE_TIMEOUT_MS  300
+#define MEMDUMP_COLLECTION_TIMEOUT_MS  8000

/* susclk rate */
#define SUSCLK_RATE_32KHZ   32768
@@ -67,6 +69,13 @@
/* Controller debug log header */
#define QCA_DEBUG_HANDLE0x2EDC

+/* Controller dump header */
+#define QCA_SSR_DUMP_HANDLE0x0108
+#define QCA_DUMP_PACKET_SIZE   255
+#define QCA_LAST_SEQUENCE_NUM  0x
+#define QCA_CRASHBYTE_PACKET_LEN   1100
+#define QCA_MEMDUMP_BYTE   0xFB
+
/* HCI_IBS transmit side sleep protocol states */
enum tx_ibs_states {
HCI_IBS_TX_ASLEEP,
@@ -89,12 +98,41 @@ enum hci_ibs_clock_state_vote {
HCI_IBS_RX_VOTE_CLOCK_OFF,
};

+/* Controller memory dump states */
+enum qca_memdump_states {
+   QCA_MEMDUMP_IDLE,
+   QCA_MEMDUMP_COLLECTING,
+   QCA_MEMDUMP_COLLECTED,
+   QCA_MEMDUMP_TIMEOUT,
+};
+
+struct qca_memdump_data {
+   char *memdump_buf_head;
+   char *memdump_buf_tail;
+   u32 current_seq_no;
+   u32 received_dump;
+};
+
+struct qca_memdump_event_hdr {
+   __u8evt;
+   __u8plen;
+   __u16   opcode;
+   __u16   seq_no;
+   __u8reserved;
+} __packed;
+
+
+struct qca_dump_size {
+   u32 dump_size;
+} __packed;
+
struct qca_data {
struct hci_uart *hu;
struct sk_buff *rx_skb;
struct sk_buff_head txq;
-   struct sk_buff_head tx_wait_q;  /* HCI_IBS wait queue   */
-   spinlock_t hci_ibs_lock;/* HCI_IBS state lock   */
+   struct sk_buff_head tx_wait_q;  /* HCI_IBS wait queue   */
+   struct sk_buff_head rx_memdump_q;   /* Memdump wait queue   */
+   spinlock_t hci_ibs_lock;/* HCI_IBS state lock   */
u8 tx_ibs_state;/* HCI_IBS transmit side power state*/
u8 rx_ibs_state;/* HCI_IBS receive side power state */
bool tx_vote;   /* Clock must be on for TX */
@@ -103,12 +141,17 @@ struct qca_data {
u32 tx_idle_delay;
struct timer_list wake_retrans_timer;
u32 wake_retrans;
+   struct timer_list memdump_timer;
+   u32 memdump_delay;
struct workqueue_struct *workqueue;
struct work_struct ws_awake_rx;
struct work_struct ws_awake_device;
struct work_struct ws_rx_vote_off;
struct work_struct ws_tx_vote_off;
+   struct work_struct ctrl_memdump_evt;
+   struct qca_memdump_data *qca_memdump;
unsigned long flags;
+   enum qca_memdump_states memdump_state;

/* For debugging purpose */
u64 ibs_sent_wacks;
@@ -173,6 +216,7 @@ struct qca_serdev {
static int qca_power_setup(struct hci_uart *hu, bool on);
static void qca_power_shutdown(struct hci_uart *hu);
static int qca_power_off(struct hci_dev *hdev);
+static void qca_controller_memdump(struct work_struct *work);

static void __serial_clock_on(struct tty_struct *tty)
{
@@ -446,6 +490,21 @@ static void hci_ibs_wake_retrans_timeout(struct 
timer_list *t)

hci_uart_tx_wakeup(hu);
}

+static void hci_memdump_timeout(struct timer_list *t)
+{
+   struct qca_data *qca = from_timer(qca, t, tx_idle_timer);
+   struct hci_uart *hu = qca->hu;
+   struct qca_memdump_data *qca_memdump = qca->qca_memdump;
+   char *memdump_buf = qca_memdump->memdump_buf_tail;
+
+	bt_dev_err(hu->hdev, "clearing allocated memory due to memdump 
timeout");

+   kfree(memdump_buf);
+   kfree(qca_memdump);
+   qca->memdump_st

Re: [PATCH v7 4/4] Bluetooth: btqca: inject command complete event during fw download

2018-12-31 Thread Balakrishna Godavarthi

Hi Marcel,

On 2018-12-31 11:34, Balakrishna Godavarthi wrote:

Hi Marcel,

On 2018-12-30 13:40, Marcel Holtmann wrote:

Hi Balakrishna,


Latest qualcomm chips are not sending an command complete event for
every firmware packet sent to chip. They only respond with a vendor
specific event for the last firmware packet. This optimization will
decrease the BT ON time. Due to this we are seeing a timeout error
message logs on the console during firmware download. Now we are
injecting a command complete event once we receive an vendor 
specific

event for the last RAM firmware packet.
Signed-off-by: Balakrishna Godavarthi 
---
drivers/bluetooth/btqca.c | 39 
++-

drivers/bluetooth/btqca.h |  3 +++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index ec9e03a6b778..0b533f65f652 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -144,6 +144,7 @@ static void qca_tlv_check_data(struct 
rome_config *config,

 * In case VSE is skipped, only the last segment is acked.
 */
config->dnld_mode = tlv_patch->download_mode;
+   config->dnld_type = config->dnld_mode;
BT_DBG("Total Length   : %d bytes",
   le32_to_cpu(tlv_patch->total_size));
@@ -264,6 +265,31 @@ static int qca_tlv_send_segment(struct hci_dev 
*hdev, int seg_size,

return err;
}
+static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
+{
+   struct hci_event_hdr *hdr;
+   struct hci_ev_cmd_complete *evt;
+   struct sk_buff *skb;
+
+   skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, GFP_KERNEL);
+   if (!skb)
+   return -ENOMEM;
+
+   hdr = skb_put(skb, sizeof(*hdr));
+   hdr->evt = HCI_EV_CMD_COMPLETE;
+   hdr->plen = sizeof(*evt) + 1;
+
+   evt = skb_put(skb, sizeof(*evt));
+   evt->ncmd = 1;
+   evt->opcode = HCI_OP_NOP;
+
+   skb_put_u8(skb, QCA_HCI_CC_SUCCESS);
+
+   hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
+
+   return hci_recv_frame(hdev, skb);
+}
+
static int qca_download_firmware(struct hci_dev *hdev,
  struct rome_config *config)
{
@@ -297,11 +323,22 @@ static int qca_download_firmware(struct 
hci_dev *hdev,

ret = qca_tlv_send_segment(hdev, segsize, segment,
config->dnld_mode);
if (ret)
-   break;
+   goto out;
segment += segsize;
}
+	/* Latest qualcomm chipsets are not sending a command complete 
event
+	 * for every fw packet sent. They only respond with a vendor 
specific

+* event for the last packet. This optimization in the chip will
+	 * decrease the BT in initialization time. Here we will inject a 
command

+* complete event to avoid a command timeout error message.
+*/
+   if ((config->dnld_type == ROME_SKIP_EVT_VSE_CC ||
+   config->dnld_type == ROME_SKIP_EVT_VSE))
+   return qca_inject_cmd_complete_event(hdev);
+
have you actually considered using __hci_cmd_send in that case. It 
is
allowed for vendor OGF to use that command. I see you actually do 
use

it and now I am failing to understand what this is for.

[Bala]: thanks for reviewing the change.

__hci_cmd_send() can be used only to send the command to the chip. it 
will not wait for the response for the command sent.


as you know that every vendor command sent to chip will respond with 
vendor specific event and command complete event.
but in our case chip will only respond with vendor specific event 
only. so we are injecting command complete event.


and __hci_cmd_sync_ev is also not working for you? However since you
are not waiting for the vendor event anyway and just injecting
cmd_complete, I wonder what’s the difference in just using
__hci_cmd_send and not bothering to wait or inject at all. I am
failing to see where this injection makes a difference.

For me it is a big difference if we are injecting one event like in
the case of Intel compared to injecting one for every command. It will
show a wrong picture in btmon and that is a bad idea.

Regards

Marcel


[Bala]: here is the use case, when ever we download the fw packets
i.e. RAM image, for every command sent(i.e. fw packet) from
the host chip will respond with an vendor specific event and command
complete event.

the above is taking more time to setup the BT device. then we came up
with solution where we enable flags in fw file (i.e. RAM image header)
whether to wait for event to be received or sent the total packets and
wait for the events for the last packet.

So currently we are handling both the cases in the code. i.e wait for
event for all packet or wait for an event for the last packet.

but in the second case i.e. wait for event for the las

Re: [PATCH v7 4/4] Bluetooth: btqca: inject command complete event during fw download

2018-12-30 Thread Balakrishna Godavarthi

Hi Marcel,

On 2018-12-30 13:40, Marcel Holtmann wrote:

Hi Balakrishna,


Latest qualcomm chips are not sending an command complete event for
every firmware packet sent to chip. They only respond with a vendor
specific event for the last firmware packet. This optimization will
decrease the BT ON time. Due to this we are seeing a timeout error
message logs on the console during firmware download. Now we are
injecting a command complete event once we receive an vendor 
specific

event for the last RAM firmware packet.
Signed-off-by: Balakrishna Godavarthi 
---
drivers/bluetooth/btqca.c | 39 
++-

drivers/bluetooth/btqca.h |  3 +++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index ec9e03a6b778..0b533f65f652 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -144,6 +144,7 @@ static void qca_tlv_check_data(struct 
rome_config *config,

 * In case VSE is skipped, only the last segment is acked.
 */
config->dnld_mode = tlv_patch->download_mode;
+   config->dnld_type = config->dnld_mode;
BT_DBG("Total Length   : %d bytes",
   le32_to_cpu(tlv_patch->total_size));
@@ -264,6 +265,31 @@ static int qca_tlv_send_segment(struct hci_dev 
*hdev, int seg_size,

return err;
}
+static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
+{
+   struct hci_event_hdr *hdr;
+   struct hci_ev_cmd_complete *evt;
+   struct sk_buff *skb;
+
+   skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, GFP_KERNEL);
+   if (!skb)
+   return -ENOMEM;
+
+   hdr = skb_put(skb, sizeof(*hdr));
+   hdr->evt = HCI_EV_CMD_COMPLETE;
+   hdr->plen = sizeof(*evt) + 1;
+
+   evt = skb_put(skb, sizeof(*evt));
+   evt->ncmd = 1;
+   evt->opcode = HCI_OP_NOP;
+
+   skb_put_u8(skb, QCA_HCI_CC_SUCCESS);
+
+   hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
+
+   return hci_recv_frame(hdev, skb);
+}
+
static int qca_download_firmware(struct hci_dev *hdev,
  struct rome_config *config)
{
@@ -297,11 +323,22 @@ static int qca_download_firmware(struct 
hci_dev *hdev,

ret = qca_tlv_send_segment(hdev, segsize, segment,
config->dnld_mode);
if (ret)
-   break;
+   goto out;
segment += segsize;
}
+	/* Latest qualcomm chipsets are not sending a command complete 
event
+	 * for every fw packet sent. They only respond with a vendor 
specific

+* event for the last packet. This optimization in the chip will
+	 * decrease the BT in initialization time. Here we will inject a 
command

+* complete event to avoid a command timeout error message.
+*/
+   if ((config->dnld_type == ROME_SKIP_EVT_VSE_CC ||
+   config->dnld_type == ROME_SKIP_EVT_VSE))
+   return qca_inject_cmd_complete_event(hdev);
+

have you actually considered using __hci_cmd_send in that case. It is
allowed for vendor OGF to use that command. I see you actually do use
it and now I am failing to understand what this is for.

[Bala]: thanks for reviewing the change.

__hci_cmd_send() can be used only to send the command to the chip. it 
will not wait for the response for the command sent.


as you know that every vendor command sent to chip will respond with 
vendor specific event and command complete event.
but in our case chip will only respond with vendor specific event 
only. so we are injecting command complete event.


and __hci_cmd_sync_ev is also not working for you? However since you
are not waiting for the vendor event anyway and just injecting
cmd_complete, I wonder what’s the difference in just using
__hci_cmd_send and not bothering to wait or inject at all. I am
failing to see where this injection makes a difference.

For me it is a big difference if we are injecting one event like in
the case of Intel compared to injecting one for every command. It will
show a wrong picture in btmon and that is a bad idea.

Regards

Marcel


[Bala]: here is the use case, when ever we download the fw packets i.e. 
RAM image, for every command sent(i.e. fw packet) from
the host chip will respond with an vendor specific event and command 
complete event.


the above is taking more time to setup the BT device. then we came up 
with solution where we enable flags in fw file (i.e. RAM image header)
whether to wait for event to be received or sent the total packets and 
wait for the events for the last packet.


So currently we are handling both the cases in the code. i.e wait for 
event for all packet or wait for an event for the last packet.


but in the second case i.e. wait for event for the last packet sent, we 
are only receiving an vendor specific

Re: [PATCH v7 4/4] Bluetooth: btqca: inject command complete event during fw download

2018-12-28 Thread Balakrishna Godavarthi

Hi Marcel,

On 2018-12-29 12:48, Marcel Holtmann wrote:

Hi Balakrishna,


Latest qualcomm chips are not sending an command complete event for
every firmware packet sent to chip. They only respond with a vendor
specific event for the last firmware packet. This optimization will
decrease the BT ON time. Due to this we are seeing a timeout error
message logs on the console during firmware download. Now we are
injecting a command complete event once we receive an vendor specific
event for the last RAM firmware packet.

Signed-off-by: Balakrishna Godavarthi 
---
drivers/bluetooth/btqca.c | 39 ++-
drivers/bluetooth/btqca.h |  3 +++
2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index ec9e03a6b778..0b533f65f652 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -144,6 +144,7 @@ static void qca_tlv_check_data(struct rome_config 
*config,

 * In case VSE is skipped, only the last segment is acked.
 */
config->dnld_mode = tlv_patch->download_mode;
+   config->dnld_type = config->dnld_mode;

BT_DBG("Total Length   : %d bytes",
   le32_to_cpu(tlv_patch->total_size));
@@ -264,6 +265,31 @@ static int qca_tlv_send_segment(struct hci_dev 
*hdev, int seg_size,

return err;
}

+static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
+{
+   struct hci_event_hdr *hdr;
+   struct hci_ev_cmd_complete *evt;
+   struct sk_buff *skb;
+
+   skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, GFP_KERNEL);
+   if (!skb)
+   return -ENOMEM;
+
+   hdr = skb_put(skb, sizeof(*hdr));
+   hdr->evt = HCI_EV_CMD_COMPLETE;
+   hdr->plen = sizeof(*evt) + 1;
+
+   evt = skb_put(skb, sizeof(*evt));
+   evt->ncmd = 1;
+   evt->opcode = HCI_OP_NOP;
+
+   skb_put_u8(skb, QCA_HCI_CC_SUCCESS);
+
+   hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
+
+   return hci_recv_frame(hdev, skb);
+}
+
static int qca_download_firmware(struct hci_dev *hdev,
  struct rome_config *config)
{
@@ -297,11 +323,22 @@ static int qca_download_firmware(struct hci_dev 
*hdev,

ret = qca_tlv_send_segment(hdev, segsize, segment,
config->dnld_mode);
if (ret)
-   break;
+   goto out;

segment += segsize;
}

+   /* Latest qualcomm chipsets are not sending a command complete event
+	 * for every fw packet sent. They only respond with a vendor 
specific

+* event for the last packet. This optimization in the chip will
+	 * decrease the BT in initialization time. Here we will inject a 
command

+* complete event to avoid a command timeout error message.
+*/
+   if ((config->dnld_type == ROME_SKIP_EVT_VSE_CC ||
+   config->dnld_type == ROME_SKIP_EVT_VSE))
+   return qca_inject_cmd_complete_event(hdev);
+


have you actually considered using __hci_cmd_send in that case. It is
allowed for vendor OGF to use that command. I see you actually do use
it and now I am failing to understand what this is for.


[Bala]: thanks for reviewing the change.

 __hci_cmd_send() can be used only to send the command to the chip. it 
will not wait for the response for the command sent.


as you know that every vendor command sent to chip will respond with 
vendor specific event and command complete event.
but in our case chip will only respond with vendor specific event only. 
so we are injecting command complete event.



Regards

Marcel


--
Regards
Balakrishna.


[RFC,v2] Bluetooth: hci_qca: Collect controller memory dump during SSR

2018-12-28 Thread Balakrishna Godavarthi
We will collect the ramdump of BT controller when hardware error event
received before rebooting the HCI layer. Before restarting a subsystem
or a process running on a subsystem, it is often required to request
either a subsystem or a process to perform proper cache dump and
software failure reason into a memory buffer which application
processor can retrieve afterwards. SW developers can often provide
initial investigation by looking into that debugging information.

Signed-off-by: Balakrishna Godavarthi 
---
changes v2:
 * entirely an newer approach handling with an work queue.
  
---
 drivers/bluetooth/hci_qca.c | 289 ++--
 1 file changed, 278 insertions(+), 11 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f036c8f98ea3..62b768bc32ec 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -57,9 +58,10 @@
 /* Controller states */
 #define STATE_IN_BAND_SLEEP_ENABLED1
 
-#define IBS_WAKE_RETRANS_TIMEOUT_MS100
+#defineIBS_WAKE_RETRANS_TIMEOUT_MS 100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
-#define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#defineBAUDRATE_SETTLE_TIMEOUT_MS  300
+#define MEMDUMP_COLLECTION_TIMEOUT_MS  8000
 
 /* susclk rate */
 #define SUSCLK_RATE_32KHZ  32768
@@ -67,6 +69,13 @@
 /* Controller debug log header */
 #define QCA_DEBUG_HANDLE   0x2EDC
 
+/* Controller dump header */
+#define QCA_SSR_DUMP_HANDLE0x0108
+#define QCA_DUMP_PACKET_SIZE   255
+#define QCA_LAST_SEQUENCE_NUM  0x
+#define QCA_CRASHBYTE_PACKET_LEN   1100
+#define QCA_MEMDUMP_BYTE   0xFB
+
 /* HCI_IBS transmit side sleep protocol states */
 enum tx_ibs_states {
HCI_IBS_TX_ASLEEP,
@@ -89,12 +98,41 @@ enum hci_ibs_clock_state_vote {
HCI_IBS_RX_VOTE_CLOCK_OFF,
 };
 
+/* Controller memory dump states */
+enum qca_memdump_states {
+   QCA_MEMDUMP_IDLE,
+   QCA_MEMDUMP_COLLECTING,
+   QCA_MEMDUMP_COLLECTED,
+   QCA_MEMDUMP_TIMEOUT,
+};
+
+struct qca_memdump_data {
+   char *memdump_buf_head;
+   char *memdump_buf_tail;
+   u32 current_seq_no;
+   u32 received_dump;
+};
+
+struct qca_memdump_event_hdr {
+   __u8evt;
+   __u8plen;
+   __u16   opcode;
+   __u16   seq_no;
+   __u8reserved;
+} __packed;
+
+
+struct qca_dump_size {
+   u32 dump_size;
+} __packed;
+
 struct qca_data {
struct hci_uart *hu;
struct sk_buff *rx_skb;
struct sk_buff_head txq;
-   struct sk_buff_head tx_wait_q;  /* HCI_IBS wait queue   */
-   spinlock_t hci_ibs_lock;/* HCI_IBS state lock   */
+   struct sk_buff_head tx_wait_q;  /* HCI_IBS wait queue   */
+   struct sk_buff_head rx_memdump_q;   /* Memdump wait queue   */
+   spinlock_t hci_ibs_lock;/* HCI_IBS state lock   */
u8 tx_ibs_state;/* HCI_IBS transmit side power state*/
u8 rx_ibs_state;/* HCI_IBS receive side power state */
bool tx_vote;   /* Clock must be on for TX */
@@ -103,12 +141,17 @@ struct qca_data {
u32 tx_idle_delay;
struct timer_list wake_retrans_timer;
u32 wake_retrans;
+   struct timer_list memdump_timer;
+   u32 memdump_delay;
struct workqueue_struct *workqueue;
struct work_struct ws_awake_rx;
struct work_struct ws_awake_device;
struct work_struct ws_rx_vote_off;
struct work_struct ws_tx_vote_off;
+   struct work_struct ctrl_memdump_evt;
+   struct qca_memdump_data *qca_memdump;
unsigned long flags;
+   enum qca_memdump_states memdump_state;
 
/* For debugging purpose */
u64 ibs_sent_wacks;
@@ -173,6 +216,7 @@ struct qca_serdev {
 static int qca_power_setup(struct hci_uart *hu, bool on);
 static void qca_power_shutdown(struct hci_uart *hu);
 static int qca_power_off(struct hci_dev *hdev);
+static void qca_controller_memdump(struct work_struct *work);
 
 static void __serial_clock_on(struct tty_struct *tty)
 {
@@ -446,6 +490,21 @@ static void hci_ibs_wake_retrans_timeout(struct timer_list 
*t)
hci_uart_tx_wakeup(hu);
 }
 
+static void hci_memdump_timeout(struct timer_list *t)
+{
+   struct qca_data *qca = from_timer(qca, t, tx_idle_timer);
+   struct hci_uart *hu = qca->hu;
+   struct qca_memdump_data *qca_memdump = qca->qca_memdump;
+   char *memdump_buf = qca_memdump->memdump_buf_tail;
+
+   bt_dev_err(hu->hdev, "clearing allocated memory due to memdump 
timeout");
+   kfree(memdump_buf);
+   kfree(qca_memdump);
+   qca->memdump_state = QCA_MEMDUMP_TIMEOUT;
+   del_timer(>memdump_timer);
+   cancel_work_sync(>ctrl_memdump_evt);
+}
+
 /* Initialize protocol */
 static int qca_open(struct hci_uart *hu)
 {
@@ -461,

[RESEND, v2] Bluetooth: hci_qca: Add helper to set device address

2018-12-28 Thread Balakrishna Godavarthi
This patch add qca_set_bdaddr() to set the device
address for latest Qualcomm Bluetooth chipset wcn3990 and above.

Signed-off-by: Balakrishna Godavarthi 
Reviewed-by: Matthias Kaehlcke 
Tested-by: Matthias Kaehlcke 
---
 drivers/bluetooth/btqca.c   | 19 +++
 drivers/bluetooth/btqca.h   |  8 +++-
 drivers/bluetooth/hci_qca.c |  5 -
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index ec9e03a6b778..612268574fc7 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -391,6 +391,25 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
 }
 EXPORT_SYMBOL_GPL(qca_uart_setup);
 
+int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+   struct sk_buff *skb;
+   int err;
+
+   skb = __hci_cmd_sync_ev(hdev, EDL_WRITE_BD_ADDR_OPCODE, 6, bdaddr,
+   HCI_EV_VENDOR, HCI_INIT_TIMEOUT);
+   if (IS_ERR(skb)) {
+   err = PTR_ERR(skb);
+   bt_dev_err(hdev, "QCA Change address cmd failed (%d)", err);
+   return err;
+   }
+
+   kfree_skb(skb);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(qca_set_bdaddr);
+
 MODULE_AUTHOR("Ben Young Tae Kim ");
 MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver " 
VERSION);
 MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
index 0c01f375fe83..c72c56ea7480 100644
--- a/drivers/bluetooth/btqca.h
+++ b/drivers/bluetooth/btqca.h
@@ -20,6 +20,7 @@
 
 #define EDL_PATCH_CMD_OPCODE   (0xFC00)
 #define EDL_NVM_ACCESS_OPCODE  (0xFC0B)
+#define EDL_WRITE_BD_ADDR_OPCODE   (0xFC14)
 #define EDL_PATCH_CMD_LEN  (1)
 #define EDL_PATCH_VER_REQ_CMD  (0x19)
 #define EDL_PATCH_TLV_REQ_CMD  (0x1E)
@@ -140,7 +141,7 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const 
bdaddr_t *bdaddr);
 int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
   enum qca_btsoc_type soc_type, u32 soc_ver);
 int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version);
-
+int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 #else
 
 static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t 
*bdaddr)
@@ -159,4 +160,9 @@ static inline int qca_read_soc_version(struct hci_dev 
*hdev, u32 *soc_version)
return -EOPNOTSUPP;
 }
 
+static inline int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+   return -EOPNOTSUPP;
+}
+
 #endif
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f036c8f98ea3..53ac5ade532b 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1241,7 +1241,10 @@ static int qca_setup(struct hci_uart *hu)
}
 
/* Setup bdaddr */
-   hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   hu->hdev->set_bdaddr = qca_set_bdaddr;
+   else
+   hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
 
return ret;
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v7 3/4] Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

2018-12-28 Thread Balakrishna Godavarthi
During hci down we observed IBS sleep commands are queued in the Tx
buffer and hci_uart_write_work is sending data to the chip which is
not required as the chip is powered off. This patch will disable IBS
and flush the Tx buffer before we turn off the chip.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/hci_qca.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index b79ef901ab8b..9d5e41f159c7 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1274,6 +1274,14 @@ static const struct qca_vreg_data qca_soc_data = {
 
 static void qca_power_shutdown(struct hci_uart *hu)
 {
+   struct qca_data *qca = hu->priv;
+
+   /* From this point we go into power off state. But serial port is
+* still open, stop queueing the IBS data and flush all the buffered
+* data in skb's.
+*/
+   clear_bit(STATE_IN_BAND_SLEEP_ENABLED, >flags);
+   qca_flush(hu);
host_set_baudrate(hu, 2400);
qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v7 2/4] Bluetooth: hci_qca: Deassert RTS while baudrate change command

2018-12-28 Thread Balakrishna Godavarthi
This patch will help to stop frame reassembly errors while changing
the baudrate. This is because host send a change baudrate request
command to the chip with 115200 bps, Whereas chip will change their
UART clocks to the enable for new baudrate and sends the response
for the change request command with newer baudrate, On host side
we are still operating in 115200 bps which results of reading garbage
data. Here we are pulling RTS line, so that chip we will wait to send data
to host until host change its baudrate.

Signed-off-by: Balakrishna Godavarthi 
Tested-by: Matthias Kaehlcke 
Reviewed-by: Matthias Kaehlcke 
---
 drivers/bluetooth/hci_qca.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 2aab34b3e696..b79ef901ab8b 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -963,7 +963,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
struct sk_buff *skb;
-   struct qca_serdev *qcadev;
u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };
 
if (baudrate > QCA_BAUDRATE_320)
@@ -977,13 +976,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
return -ENOMEM;
}
 
-   /* Disabling hardware flow control is mandatory while
-* sending change baudrate request to wcn3990 SoC.
-*/
-   qcadev = serdev_device_get_drvdata(hu->serdev);
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, true);
-
/* Assign commands to change baudrate and packet type. */
skb_put_data(skb, cmd, sizeof(cmd));
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
@@ -999,9 +991,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t 
baudrate)
schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
set_current_state(TASK_RUNNING);
 
-   if (qcadev->btsoc_type == QCA_WCN3990)
-   hci_uart_set_flow_control(hu, false);
-
return 0;
 }
 
@@ -1090,6 +1079,7 @@ static int qca_check_speeds(struct hci_uart *hu)
 static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
 {
unsigned int speed, qca_baudrate;
+   struct qca_serdev *qcadev;
int ret;
 
if (speed_type == QCA_INIT_SPEED) {
@@ -1101,6 +1091,15 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
if (!speed)
return 0;
 
+   /* Deassert RTS while changing the baudrate of chip and host.
+* This will prevent chip from transmitting its response with
+* the new baudrate while the host port is still operating at
+* the old speed.
+*/
+   qcadev = serdev_device_get_drvdata(hu->serdev);
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   serdev_device_set_rts(hu->serdev, false);
+
qca_baudrate = qca_get_baudrate_value(speed);
bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed);
ret = qca_set_baudrate(hu->hdev, qca_baudrate);
@@ -1108,6 +1107,9 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
return ret;
 
host_set_baudrate(hu, speed);
+
+   if (qcadev->btsoc_type == QCA_WCN3990)
+   serdev_device_set_rts(hu->serdev, true);
}
 
return 0;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v7 4/4] Bluetooth: btqca: inject command complete event during fw download

2018-12-28 Thread Balakrishna Godavarthi
Latest qualcomm chips are not sending an command complete event for
every firmware packet sent to chip. They only respond with a vendor
specific event for the last firmware packet. This optimization will
decrease the BT ON time. Due to this we are seeing a timeout error
message logs on the console during firmware download. Now we are
injecting a command complete event once we receive an vendor specific
event for the last RAM firmware packet.

Signed-off-by: Balakrishna Godavarthi 
---
 drivers/bluetooth/btqca.c | 39 ++-
 drivers/bluetooth/btqca.h |  3 +++
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index ec9e03a6b778..0b533f65f652 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -144,6 +144,7 @@ static void qca_tlv_check_data(struct rome_config *config,
 * In case VSE is skipped, only the last segment is acked.
 */
config->dnld_mode = tlv_patch->download_mode;
+   config->dnld_type = config->dnld_mode;
 
BT_DBG("Total Length   : %d bytes",
   le32_to_cpu(tlv_patch->total_size));
@@ -264,6 +265,31 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int 
seg_size,
return err;
 }
 
+static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
+{
+   struct hci_event_hdr *hdr;
+   struct hci_ev_cmd_complete *evt;
+   struct sk_buff *skb;
+
+   skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, GFP_KERNEL);
+   if (!skb)
+   return -ENOMEM;
+
+   hdr = skb_put(skb, sizeof(*hdr));
+   hdr->evt = HCI_EV_CMD_COMPLETE;
+   hdr->plen = sizeof(*evt) + 1;
+
+   evt = skb_put(skb, sizeof(*evt));
+   evt->ncmd = 1;
+   evt->opcode = HCI_OP_NOP;
+
+   skb_put_u8(skb, QCA_HCI_CC_SUCCESS);
+
+   hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
+
+   return hci_recv_frame(hdev, skb);
+}
+
 static int qca_download_firmware(struct hci_dev *hdev,
  struct rome_config *config)
 {
@@ -297,11 +323,22 @@ static int qca_download_firmware(struct hci_dev *hdev,
ret = qca_tlv_send_segment(hdev, segsize, segment,
config->dnld_mode);
if (ret)
-   break;
+   goto out;
 
segment += segsize;
}
 
+   /* Latest qualcomm chipsets are not sending a command complete event
+* for every fw packet sent. They only respond with a vendor specific
+* event for the last packet. This optimization in the chip will
+* decrease the BT in initialization time. Here we will inject a command
+* complete event to avoid a command timeout error message.
+*/
+   if ((config->dnld_type == ROME_SKIP_EVT_VSE_CC ||
+   config->dnld_type == ROME_SKIP_EVT_VSE))
+   return qca_inject_cmd_complete_event(hdev);
+
+out:
release_firmware(fw);
 
return ret;
diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
index 0c01f375fe83..5c8fc54133e3 100644
--- a/drivers/bluetooth/btqca.h
+++ b/drivers/bluetooth/btqca.h
@@ -40,6 +40,8 @@
 #define QCA_WCN3990_POWERON_PULSE  0xFC
 #define QCA_WCN3990_POWEROFF_PULSE 0xC0
 
+#define QCA_HCI_CC_SUCCESS 0x00
+
 enum qca_bardrate {
QCA_BAUDRATE_115200 = 0,
QCA_BAUDRATE_57600,
@@ -81,6 +83,7 @@ struct rome_config {
char fwname[64];
uint8_t user_baud_rate;
enum rome_tlv_dnld_mode dnld_mode;
+   enum rome_tlv_dnld_mode dnld_type;
 };
 
 struct edl_event_hdr {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v7 0/4] Bug fixes for Qualcomm BT chip wcn3990.

2018-12-28 Thread Balakrishna Godavarthi
The below issues are found in our recent testing.

1. Observed device is not going into off state or not responding.
As wcn3990 require a power pulses to turn on the irrespctive of
igniting regulators, it was observed that power on or power off
pulses are not in sync with respective to chip.
The below patch will help us to wait until byte is pushed on to wires.  


* Bluetooth: hci_qca: use wait_until_sent() for power pulses

2. Observed Chip responding when we are in sleep.
   This is due to turn on flow control during change baudrate request.
   The below patch will only pull the RTS line high instead of turning off
   the flow.

   * Bluetooth: hci_qca: Pull RTS line high for baudrate change command.

3. Disable IBS state machine and flush Tx buffer
   We are disabling IBS and flushing the Tx buffer before turning off the chip.
  
   This is due to IBS state machine is active when we turn off the chip.
   This will stop queuing IBS protocol bytes.

   * Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer

   
4. btqca: inject command complete event during fw download
   
   Qualcomm latest chip will not send an command complete event
   for last packet of the fw dump sent, so here we are inject an command 
   complete event.

   * Bluetooth: btqca: inject command complete event during fw download

Changes in v7:
 * dropped frame reassmebly error patch.
 * dropped baudrate change wait time patch.
 * increased a wait to 5 ms for power pulses.

Changes in v6:
 * added serdev_device_write_flush in qca_send_power_pulse().
 * added new patch to update the baudrate change wait time.

Changes in V5:
 * added serdev_device_write_flush before sending the power off pulse
   during shutdown.

Changes in v4:
 * used serdev_device_write_buf() instead of serdev_device_write().
 * added new patch to stop logging of 0xfc00 timeout on console.

Changes in v3:
 * moved IBS & qca_flush to different patch
 * updated comments in code fo Deassert RTS patch
Balakrishna Godavarthi (4):
  Bluetooth: hci_qca: use wait_until_sent() for power pulses
  Bluetooth: hci_qca: Deassert RTS while baudrate change command
  Bluetooth: hci_qca: Disable IBS state machine and flush Tx buffer
  Bluetooth: btqca: inject command complete event during fw download

 drivers/bluetooth/btqca.c   | 39 +++-
 drivers/bluetooth/btqca.h   |  3 ++
 drivers/bluetooth/hci_qca.c | 73 +++--
 3 files changed, 79 insertions(+), 36 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v7 1/4] Bluetooth: hci_qca: use wait_until_sent() for power pulses

2018-12-28 Thread Balakrishna Godavarthi
wcn3990 requires a power pulse to turn ON/OFF along with
regulators. Sometimes we are observing the power pulses are sent
out with some time delay, due to queuing these commands. This is
causing synchronization issues with chip, which intern delay the
chip setup or may end up with communication issues.

Signed-off-by: Balakrishna Godavarthi 
---
Changes in v7:
 *  updated the wait time to 5 ms after sending power pulses.

Changes in v6:
 * added serdev_device_write_flush() in qca_send_power_pulse
   instead during the power off pulse.

Changes in v5:
 * added serdev_device_write_flush() in qca_power_off().
---
 drivers/bluetooth/hci_qca.c | 43 -
 1 file changed, 18 insertions(+), 25 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f036c8f98ea3..2aab34b3e696 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1013,11 +1013,9 @@ static inline void host_set_baudrate(struct hci_uart 
*hu, unsigned int speed)
hci_uart_set_baudrate(hu, speed);
 }
 
-static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
+static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
 {
-   struct hci_uart *hu = hci_get_drvdata(hdev);
-   struct qca_data *qca = hu->priv;
-   struct sk_buff *skb;
+   int ret;
 
/* These power pulses are single byte command which are sent
 * at required baudrate to wcn3990. On wcn3990, we have an external
@@ -1029,22 +1027,23 @@ static int qca_send_power_pulse(struct hci_dev *hdev, 
u8 cmd)
 * save power. Disabling hardware flow control is mandatory while
 * sending power pulses to SoC.
 */
-   bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
-
-   skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
-   if (!skb)
-   return -ENOMEM;
+   bt_dev_dbg(hu->hdev, "sending power pulse %02x to controller", cmd);
 
+   serdev_device_write_flush(hu->serdev);
hci_uart_set_flow_control(hu, true);
+   ret = serdev_device_write_buf(hu->serdev, , sizeof(cmd));
+   if (ret < 0) {
+   bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd);
+   return ret;
+   }
 
-   skb_put_u8(skb, cmd);
-   hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
-
-   skb_queue_tail(>txq, skb);
-   hci_uart_tx_wakeup(hu);
+   serdev_device_wait_until_sent(hu->serdev, 0);
 
-   /* Wait for 100 uS for SoC to settle down */
-   usleep_range(100, 200);
+   /* Wait of 5ms is required for assuring to send the byte on the Tx
+* line and also for the controller to settle down for the received
+* byte.
+*/
+   usleep_range(5000, 6000);
hci_uart_set_flow_control(hu, false);
 
return 0;
@@ -1116,7 +1115,6 @@ static int qca_set_speed(struct hci_uart *hu, enum 
qca_speed_type speed_type)
 
 static int qca_wcn3990_init(struct hci_uart *hu)
 {
-   struct hci_dev *hdev = hu->hdev;
struct qca_serdev *qcadev;
int ret;
 
@@ -1139,12 +1137,12 @@ static int qca_wcn3990_init(struct hci_uart *hu)
 
/* Forcefully enable wcn3990 to enter in to boot mode. */
host_set_baudrate(hu, 2400);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
if (ret)
return ret;
 
qca_set_speed(hu, QCA_INIT_SPEED);
-   ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWERON_PULSE);
+   ret = qca_send_power_pulse(hu, QCA_WCN3990_POWERON_PULSE);
if (ret)
return ret;
 
@@ -1274,13 +1272,8 @@ static const struct qca_vreg_data qca_soc_data = {
 
 static void qca_power_shutdown(struct hci_uart *hu)
 {
-   struct serdev_device *serdev = hu->serdev;
-   unsigned char cmd = QCA_WCN3990_POWEROFF_PULSE;
-
host_set_baudrate(hu, 2400);
-   hci_uart_set_flow_control(hu, true);
-   serdev_device_write_buf(serdev, , sizeof(cmd));
-   hci_uart_set_flow_control(hu, false);
+   qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
qca_power_setup(hu, false);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v6 5/6] Bluetooth: hci_qca: Update baudrate change wait time for wcn3990

2018-12-28 Thread Balakrishna Godavarthi

Hi Matthias,

On 2018-12-28 02:30, Matthias Kaehlcke wrote:

On Thu, Dec 27, 2018 at 01:01:35PM +0530, Balakrishna Godavarthi wrote:

This patch will update the baudrate change request wait time from
300 ms to 100 ms. When host sends the change baudrate request to
the controller, controller sets its clock and wait until the
clocks settle down. Here the Wait time is required for both
host and controller to be on sync.


Ultimately up to you, but I would advise against adding 'improvement'
changes to this series. The scope of the series is already fairly
vague ("Bug fixes for Qualcomm BT chip wcn3990"), with at least some
patches that could be sent individually, which would reduce churn when
respinning.


[Bala]: yes your correct will send this as improvement patch once the 
series is merged.





Signed-off-by: Balakrishna Godavarthi 
---

Changes in v6:
 * intial patch.

---
 drivers/bluetooth/hci_qca.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 4677a6a2716a..61b0fb1ff32f 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -60,7 +60,8 @@

 #define IBS_WAKE_RETRANS_TIMEOUT_MS100
 #define IBS_TX_IDLE_TIMEOUT_MS 2000
-#define BAUDRATE_SETTLE_TIMEOUT_MS 300
+#define ROME_BD_SETTLE_TIMEOUT_MS  300
+#define WCN3990_BD_SETTLE_TIMEOUT_MS   100


My testing suggests that even the lower 100 ms delay isn't needed, if
different parts that require a delay are addressed more specifically,
instead of using a single long 'settle' delay
(https://lore.kernel.org/patchwork/patch/1026795/#1212816 has some
details).

[Bala]: i to agree with you. but from the point 1, we have many chances 
of getting
baudrate change delay. after lot of stress test and experiments 
we found 100 ms is reasonable to handle all

of them together.


My idea was to sent a patch after this series has landed to avoid
interfering with it.



[Bala]: sure will drop this change from the series.


Cheers

Matthias


--
Regards
Balakrishna.


Re: [PATCH v6 3/6] Bluetooth: hci_qca: Fix frame reassembly errors for wcn3990

2018-12-27 Thread Balakrishna Godavarthi

Hi Matthias,

On 2018-12-28 01:55, Matthias Kaehlcke wrote:

On Thu, Dec 27, 2018 at 01:01:33PM +0530, Balakrishna Godavarthi wrote:

During initalization of wcn3990, we observed UART is reading some
stray bytes on the Rx line. This is logging Frame reassembly errors
on the serial console. This could be because of tristate of Tx line
of wcn3990 during boot up.


My testing suggests that this change is not needed if the Rx line of
the SoC/AP is configured with a pull-up. We'd probably all prefer not
to have this change if there's a neater way to address the garbage
data. Could you test with adding the pull-up and dropping this patch
on your side?

Thanks

Matthias


Thanks a lot it worked to me. will drop this patch.

--
Regards
Balakrishna.


  1   2   3   4   5   >