Skip to content

Commit 78e8fa2

Browse files
bgodavarholtmann
authored andcommitted
Bluetooth: hci_qca: Deassert RTS while baudrate change command
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 <[email protected]> Tested-by: Matthias Kaehlcke <[email protected]> Reviewed-by: Matthias Kaehlcke <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent f955827 commit 78e8fa2

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

drivers/bluetooth/hci_qca.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
964964
struct hci_uart *hu = hci_get_drvdata(hdev);
965965
struct qca_data *qca = hu->priv;
966966
struct sk_buff *skb;
967-
struct qca_serdev *qcadev;
968967
u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };
969968

970969
if (baudrate > QCA_BAUDRATE_3200000)
@@ -978,13 +977,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
978977
return -ENOMEM;
979978
}
980979

981-
/* Disabling hardware flow control is mandatory while
982-
* sending change baudrate request to wcn3990 SoC.
983-
*/
984-
qcadev = serdev_device_get_drvdata(hu->serdev);
985-
if (qcadev->btsoc_type == QCA_WCN3990)
986-
hci_uart_set_flow_control(hu, true);
987-
988980
/* Assign commands to change baudrate and packet type. */
989981
skb_put_data(skb, cmd, sizeof(cmd));
990982
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
@@ -1000,9 +992,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
1000992
schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
1001993
set_current_state(TASK_RUNNING);
1002994

1003-
if (qcadev->btsoc_type == QCA_WCN3990)
1004-
hci_uart_set_flow_control(hu, false);
1005-
1006995
return 0;
1007996
}
1008997

@@ -1089,7 +1078,8 @@ static int qca_check_speeds(struct hci_uart *hu)
10891078
static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
10901079
{
10911080
unsigned int speed, qca_baudrate;
1092-
int ret;
1081+
struct qca_serdev *qcadev;
1082+
int ret = 0;
10931083

10941084
if (speed_type == QCA_INIT_SPEED) {
10951085
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)
11001090
if (!speed)
11011091
return 0;
11021092

1093+
/* Disable flow control for wcn3990 to deassert RTS while
1094+
* changing the baudrate of chip and host.
1095+
*/
1096+
qcadev = serdev_device_get_drvdata(hu->serdev);
1097+
if (qcadev->btsoc_type == QCA_WCN3990)
1098+
hci_uart_set_flow_control(hu, true);
1099+
11031100
qca_baudrate = qca_get_baudrate_value(speed);
11041101
bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed);
11051102
ret = qca_set_baudrate(hu->hdev, qca_baudrate);
11061103
if (ret)
1107-
return ret;
1104+
goto error;
11081105

11091106
host_set_baudrate(hu, speed);
1107+
1108+
error:
1109+
if (qcadev->btsoc_type == QCA_WCN3990)
1110+
hci_uart_set_flow_control(hu, false);
11101111
}
11111112

1112-
return 0;
1113+
return ret;
11131114
}
11141115

11151116
static int qca_wcn3990_init(struct hci_uart *hu)

0 commit comments

Comments
 (0)