Skip to content

Commit f8a4f1d

Browse files
committed
Merge remote-tracking branch tech/net/bluetooth into qcom-next
2 parents 5225c6d + 27ab39b commit f8a4f1d

5 files changed

Lines changed: 75 additions & 0 deletions

File tree

drivers/bluetooth/hci_qca.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,6 +1653,24 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
16531653
}
16541654

16551655
clear_bit(QCA_HW_ERROR_EVENT, &qca->flags);
1656+
1657+
/*
1658+
* If the SoC always enables the bt_en pin via hardware and the driver
1659+
* cannot control the bt_en pin of the SoC chip, then during SSR,
1660+
* the QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits cannot be cleared.
1661+
* This leads to a reset command timeout failure.
1662+
*
1663+
* To address this, clear QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits
1664+
* after the coredump collection is complete.
1665+
* Also, add msleep delay to wait for controller to complete SSR.
1666+
*/
1667+
if (!test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
1668+
clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
1669+
clear_bit(QCA_IBS_DISABLED, &qca->flags);
1670+
qca->tx_ibs_state = HCI_IBS_TX_AWAKE;
1671+
qca->memdump_state = QCA_MEMDUMP_IDLE;
1672+
msleep(50);
1673+
}
16561674
}
16571675

16581676
static void qca_reset(struct hci_dev *hdev)

include/net/bluetooth/hci_core.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,8 @@ struct hci_conn {
767767

768768
struct bt_codec codec;
769769

770+
struct l2cap_pending_connect *pending_connect;
771+
770772
void (*connect_cfm_cb) (struct hci_conn *conn, u8 status);
771773
void (*security_cfm_cb) (struct hci_conn *conn, u8 status);
772774
void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason);
@@ -970,6 +972,7 @@ enum {
970972
HCI_CONN_CREATE_PA_SYNC,
971973
HCI_CONN_PA_SYNC,
972974
HCI_CONN_PA_SYNC_FAILED,
975+
HCI_CONN_ENC_KEY_READY,
973976
};
974977

975978
static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)

include/net/bluetooth/l2cap.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,13 @@ struct l2cap_user {
679679
void (*remove) (struct l2cap_conn *conn, struct l2cap_user *user);
680680
};
681681

682+
struct l2cap_pending_connect {
683+
struct l2cap_conn *conn;
684+
struct l2cap_cmd_hdr cmd;
685+
u8 data[sizeof(struct l2cap_conn_req)];
686+
u8 rsp_code;
687+
};
688+
682689
#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01
683690
#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
684691
#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
@@ -977,4 +984,6 @@ void l2cap_conn_put(struct l2cap_conn *conn);
977984
int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user);
978985
void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user);
979986

987+
void l2cap_process_pending_connect(struct l2cap_conn *conn,
988+
struct l2cap_cmd_hdr *cmd, u8 *data, u8 rsp_code);
980989
#endif /* __L2CAP_H */

net/bluetooth/hci_event.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <net/bluetooth/bluetooth.h>
3333
#include <net/bluetooth/hci_core.h>
3434
#include <net/bluetooth/mgmt.h>
35+
#include <net/bluetooth/l2cap.h>
3536

3637
#include "hci_debugfs.h"
3738
#include "hci_codec.h"
@@ -766,10 +767,22 @@ static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
766767
/* Update the key encryption size with the connection one */
767768
if (key_enc_size && *key_enc_size != conn->enc_key_size)
768769
*key_enc_size = conn->enc_key_size;
770+
set_bit(HCI_CONN_ENC_KEY_READY, &conn->flags);
769771
}
770772

771773
hci_encrypt_cfm(conn, status);
772774

775+
/*Defer l2cap_connect here if it's triggered before key size is read.*/
776+
if (conn->pending_connect) {
777+
struct l2cap_pending_connect *pc = conn->pending_connect;
778+
779+
conn->pending_connect = NULL;
780+
781+
bt_dev_dbg(hdev, "Defer l2cap_connect");
782+
l2cap_process_pending_connect(pc->conn, &pc->cmd, pc->data, pc->rsp_code);
783+
784+
kfree(pc);
785+
}
773786
done:
774787
hci_dev_unlock(hdev);
775788

@@ -3556,6 +3569,8 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
35563569
if (!conn)
35573570
goto unlock;
35583571

3572+
clear_bit(HCI_CONN_ENC_KEY_READY, &conn->flags);
3573+
35593574
if (!ev->status) {
35603575
if (ev->encrypt) {
35613576
/* Encryption implies authentication */

net/bluetooth/l2cap_core.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3982,6 +3982,30 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
39823982
struct l2cap_chan *chan = NULL, *pchan = NULL;
39833983
int result, status = L2CAP_CS_NO_INFO;
39843984

3985+
/* If encryption is requested, but the key size is not ready yet,
3986+
* we need to wait for the key size to be ready before we can
3987+
* proceed with the connection. We do this by deferring the
3988+
* connection request until the key size is ready. This is done
3989+
* by storing the connection request in the hcon->pending_connect
3990+
* field. The connection request will be retried when the key size
3991+
* is ready.
3992+
*/
3993+
if (test_bit(HCI_CONN_ENCRYPT, &conn->hcon->flags) &&
3994+
!test_bit(HCI_CONN_ENC_KEY_READY, &conn->hcon->flags)) {
3995+
struct l2cap_pending_connect *pc;
3996+
3997+
pc = kzalloc(sizeof(*pc), GFP_KERNEL);
3998+
if (!pc)
3999+
return;
4000+
pc->conn = conn;
4001+
memcpy(&pc->cmd, cmd, sizeof(*cmd));
4002+
memcpy(pc->data, data, sizeof(struct l2cap_conn_req));
4003+
pc->rsp_code = rsp_code;
4004+
BT_DBG("store request and retried when keysize is ready");
4005+
conn->hcon->pending_connect = pc;
4006+
return;
4007+
}
4008+
39854009
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
39864010
__le16 psm = req->psm;
39874011

@@ -4105,6 +4129,12 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
41054129
l2cap_chan_put(pchan);
41064130
}
41074131

4132+
void l2cap_process_pending_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
4133+
u8 *data, u8 rsp_code)
4134+
{
4135+
l2cap_connect(conn, cmd, data, rsp_code);
4136+
}
4137+
41084138
static int l2cap_connect_req(struct l2cap_conn *conn,
41094139
struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
41104140
{

0 commit comments

Comments
 (0)