mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-19 11:43:40 +00:00
Bluetooth: hci_sync: Use advertised PHYs on hci_le_ext_create_conn_sync
The extended advertising reports do report the PHYs so this store then in hci_conn so it can be later used in hci_le_ext_create_conn_sync to narrow the PHYs to be scanned since the controller will also perform a scan having a smaller set of PHYs shall reduce the time it takes to find and connect peers. Fixes: 288c90224eec ("Bluetooth: Enable all supported LE PHY by default") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
9bf4e919cc
commit
2e7ed5f5e6
@ -738,6 +738,8 @@ struct hci_conn {
|
|||||||
__u8 le_per_adv_data[HCI_MAX_PER_AD_TOT_LEN];
|
__u8 le_per_adv_data[HCI_MAX_PER_AD_TOT_LEN];
|
||||||
__u16 le_per_adv_data_len;
|
__u16 le_per_adv_data_len;
|
||||||
__u16 le_per_adv_data_offset;
|
__u16 le_per_adv_data_offset;
|
||||||
|
__u8 le_adv_phy;
|
||||||
|
__u8 le_adv_sec_phy;
|
||||||
__u8 le_tx_phy;
|
__u8 le_tx_phy;
|
||||||
__u8 le_rx_phy;
|
__u8 le_rx_phy;
|
||||||
__s8 rssi;
|
__s8 rssi;
|
||||||
@ -1512,7 +1514,7 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
|
|||||||
enum conn_reasons conn_reason);
|
enum conn_reasons conn_reason);
|
||||||
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
||||||
u8 dst_type, bool dst_resolved, u8 sec_level,
|
u8 dst_type, bool dst_resolved, u8 sec_level,
|
||||||
u16 conn_timeout, u8 role);
|
u16 conn_timeout, u8 role, u8 phy, u8 sec_phy);
|
||||||
void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status);
|
void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status);
|
||||||
struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
|
struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
|
||||||
u8 sec_level, u8 auth_type,
|
u8 sec_level, u8 auth_type,
|
||||||
|
@ -1263,7 +1263,7 @@ u8 hci_conn_set_handle(struct hci_conn *conn, u16 handle)
|
|||||||
|
|
||||||
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
||||||
u8 dst_type, bool dst_resolved, u8 sec_level,
|
u8 dst_type, bool dst_resolved, u8 sec_level,
|
||||||
u16 conn_timeout, u8 role)
|
u16 conn_timeout, u8 role, u8 phy, u8 sec_phy)
|
||||||
{
|
{
|
||||||
struct hci_conn *conn;
|
struct hci_conn *conn;
|
||||||
struct smp_irk *irk;
|
struct smp_irk *irk;
|
||||||
@ -1326,6 +1326,8 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
|||||||
conn->dst_type = dst_type;
|
conn->dst_type = dst_type;
|
||||||
conn->sec_level = BT_SECURITY_LOW;
|
conn->sec_level = BT_SECURITY_LOW;
|
||||||
conn->conn_timeout = conn_timeout;
|
conn->conn_timeout = conn_timeout;
|
||||||
|
conn->le_adv_phy = phy;
|
||||||
|
conn->le_adv_sec_phy = sec_phy;
|
||||||
|
|
||||||
err = hci_connect_le_sync(hdev, conn);
|
err = hci_connect_le_sync(hdev, conn);
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -2273,7 +2275,7 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
|
|||||||
le = hci_connect_le(hdev, dst, dst_type, false,
|
le = hci_connect_le(hdev, dst, dst_type, false,
|
||||||
BT_SECURITY_LOW,
|
BT_SECURITY_LOW,
|
||||||
HCI_LE_CONN_TIMEOUT,
|
HCI_LE_CONN_TIMEOUT,
|
||||||
HCI_ROLE_SLAVE);
|
HCI_ROLE_SLAVE, 0, 0);
|
||||||
else
|
else
|
||||||
le = hci_connect_le_scan(hdev, dst, dst_type,
|
le = hci_connect_le_scan(hdev, dst, dst_type,
|
||||||
BT_SECURITY_LOW,
|
BT_SECURITY_LOW,
|
||||||
|
@ -6038,7 +6038,7 @@ static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data,
|
|||||||
static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
|
static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
|
||||||
bdaddr_t *addr,
|
bdaddr_t *addr,
|
||||||
u8 addr_type, bool addr_resolved,
|
u8 addr_type, bool addr_resolved,
|
||||||
u8 adv_type)
|
u8 adv_type, u8 phy, u8 sec_phy)
|
||||||
{
|
{
|
||||||
struct hci_conn *conn;
|
struct hci_conn *conn;
|
||||||
struct hci_conn_params *params;
|
struct hci_conn_params *params;
|
||||||
@ -6093,7 +6093,7 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
|
|||||||
|
|
||||||
conn = hci_connect_le(hdev, addr, addr_type, addr_resolved,
|
conn = hci_connect_le(hdev, addr, addr_type, addr_resolved,
|
||||||
BT_SECURITY_LOW, hdev->def_le_autoconnect_timeout,
|
BT_SECURITY_LOW, hdev->def_le_autoconnect_timeout,
|
||||||
HCI_ROLE_MASTER);
|
HCI_ROLE_MASTER, phy, sec_phy);
|
||||||
if (!IS_ERR(conn)) {
|
if (!IS_ERR(conn)) {
|
||||||
/* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned
|
/* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned
|
||||||
* by higher layer that tried to connect, if no then
|
* by higher layer that tried to connect, if no then
|
||||||
@ -6128,8 +6128,9 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
|
|||||||
|
|
||||||
static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
|
static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
|
||||||
u8 bdaddr_type, bdaddr_t *direct_addr,
|
u8 bdaddr_type, bdaddr_t *direct_addr,
|
||||||
u8 direct_addr_type, s8 rssi, u8 *data, u8 len,
|
u8 direct_addr_type, u8 phy, u8 sec_phy, s8 rssi,
|
||||||
bool ext_adv, bool ctl_time, u64 instant)
|
u8 *data, u8 len, bool ext_adv, bool ctl_time,
|
||||||
|
u64 instant)
|
||||||
{
|
{
|
||||||
struct discovery_state *d = &hdev->discovery;
|
struct discovery_state *d = &hdev->discovery;
|
||||||
struct smp_irk *irk;
|
struct smp_irk *irk;
|
||||||
@ -6217,7 +6218,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
|
|||||||
* for advertising reports) and is already verified to be RPA above.
|
* for advertising reports) and is already verified to be RPA above.
|
||||||
*/
|
*/
|
||||||
conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved,
|
conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved,
|
||||||
type);
|
type, phy, sec_phy);
|
||||||
if (!ext_adv && conn && type == LE_ADV_IND &&
|
if (!ext_adv && conn && type == LE_ADV_IND &&
|
||||||
len <= max_adv_len(hdev)) {
|
len <= max_adv_len(hdev)) {
|
||||||
/* Store report for later inclusion by
|
/* Store report for later inclusion by
|
||||||
@ -6363,7 +6364,8 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
|
|||||||
if (info->length <= max_adv_len(hdev)) {
|
if (info->length <= max_adv_len(hdev)) {
|
||||||
rssi = info->data[info->length];
|
rssi = info->data[info->length];
|
||||||
process_adv_report(hdev, info->type, &info->bdaddr,
|
process_adv_report(hdev, info->type, &info->bdaddr,
|
||||||
info->bdaddr_type, NULL, 0, rssi,
|
info->bdaddr_type, NULL, 0,
|
||||||
|
HCI_ADV_PHY_1M, 0, rssi,
|
||||||
info->data, info->length, false,
|
info->data, info->length, false,
|
||||||
false, instant);
|
false, instant);
|
||||||
} else {
|
} else {
|
||||||
@ -6448,6 +6450,8 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
|
|||||||
if (legacy_evt_type != LE_ADV_INVALID) {
|
if (legacy_evt_type != LE_ADV_INVALID) {
|
||||||
process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
|
process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
|
||||||
info->bdaddr_type, NULL, 0,
|
info->bdaddr_type, NULL, 0,
|
||||||
|
info->primary_phy,
|
||||||
|
info->secondary_phy,
|
||||||
info->rssi, info->data, info->length,
|
info->rssi, info->data, info->length,
|
||||||
!(evt_type & LE_EXT_ADV_LEGACY_PDU),
|
!(evt_type & LE_EXT_ADV_LEGACY_PDU),
|
||||||
false, instant);
|
false, instant);
|
||||||
@ -6730,8 +6734,8 @@ static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,
|
|||||||
|
|
||||||
process_adv_report(hdev, info->type, &info->bdaddr,
|
process_adv_report(hdev, info->type, &info->bdaddr,
|
||||||
info->bdaddr_type, &info->direct_addr,
|
info->bdaddr_type, &info->direct_addr,
|
||||||
info->direct_addr_type, info->rssi, NULL, 0,
|
info->direct_addr_type, HCI_ADV_PHY_1M, 0,
|
||||||
false, false, instant);
|
info->rssi, NULL, 0, false, false, instant);
|
||||||
}
|
}
|
||||||
|
|
||||||
hci_dev_unlock(hdev);
|
hci_dev_unlock(hdev);
|
||||||
|
@ -6346,7 +6346,8 @@ static int hci_le_ext_create_conn_sync(struct hci_dev *hdev,
|
|||||||
|
|
||||||
plen = sizeof(*cp);
|
plen = sizeof(*cp);
|
||||||
|
|
||||||
if (scan_1m(hdev)) {
|
if (scan_1m(hdev) && (conn->le_adv_phy == HCI_ADV_PHY_1M ||
|
||||||
|
conn->le_adv_sec_phy == HCI_ADV_PHY_1M)) {
|
||||||
cp->phys |= LE_SCAN_PHY_1M;
|
cp->phys |= LE_SCAN_PHY_1M;
|
||||||
set_ext_conn_params(conn, p);
|
set_ext_conn_params(conn, p);
|
||||||
|
|
||||||
@ -6354,7 +6355,8 @@ static int hci_le_ext_create_conn_sync(struct hci_dev *hdev,
|
|||||||
plen += sizeof(*p);
|
plen += sizeof(*p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scan_2m(hdev)) {
|
if (scan_2m(hdev) && (conn->le_adv_phy == HCI_ADV_PHY_2M ||
|
||||||
|
conn->le_adv_sec_phy == HCI_ADV_PHY_2M)) {
|
||||||
cp->phys |= LE_SCAN_PHY_2M;
|
cp->phys |= LE_SCAN_PHY_2M;
|
||||||
set_ext_conn_params(conn, p);
|
set_ext_conn_params(conn, p);
|
||||||
|
|
||||||
@ -6362,7 +6364,8 @@ static int hci_le_ext_create_conn_sync(struct hci_dev *hdev,
|
|||||||
plen += sizeof(*p);
|
plen += sizeof(*p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scan_coded(hdev)) {
|
if (scan_coded(hdev) && (conn->le_adv_phy == HCI_ADV_PHY_CODED ||
|
||||||
|
conn->le_adv_sec_phy == HCI_ADV_PHY_CODED)) {
|
||||||
cp->phys |= LE_SCAN_PHY_CODED;
|
cp->phys |= LE_SCAN_PHY_CODED;
|
||||||
set_ext_conn_params(conn, p);
|
set_ext_conn_params(conn, p);
|
||||||
|
|
||||||
|
@ -7018,7 +7018,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
|
|||||||
if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
|
if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
|
||||||
hcon = hci_connect_le(hdev, dst, dst_type, false,
|
hcon = hci_connect_le(hdev, dst, dst_type, false,
|
||||||
chan->sec_level, timeout,
|
chan->sec_level, timeout,
|
||||||
HCI_ROLE_SLAVE);
|
HCI_ROLE_SLAVE, 0, 0);
|
||||||
else
|
else
|
||||||
hcon = hci_connect_le_scan(hdev, dst, dst_type,
|
hcon = hci_connect_le_scan(hdev, dst, dst_type,
|
||||||
chan->sec_level, timeout,
|
chan->sec_level, timeout,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user