Skip to content

Commit 1d0fac2

Browse files
Vudentzholtmann
authored andcommitted
Bluetooth: Use controller sets when available
This makes use of controller sets when using Extended Advertising feature thus offloading the scheduling to the controller. Signed-off-by: Luiz Augusto von Dentz <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent c49a868 commit 1d0fac2

File tree

4 files changed

+37
-10
lines changed

4 files changed

+37
-10
lines changed

net/bluetooth/hci_conn.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ static void hci_req_directed_advertising(struct hci_request *req,
915915
sizeof(cp), &cp);
916916
}
917917

918-
__hci_req_enable_ext_advertising(req);
918+
__hci_req_enable_ext_advertising(req, 0x00);
919919
} else {
920920
struct hci_cp_le_set_adv_param cp;
921921

net/bluetooth/hci_core.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2827,7 +2827,7 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
28272827
memset(adv_instance->scan_rsp_data, 0,
28282828
sizeof(adv_instance->scan_rsp_data));
28292829
} else {
2830-
if (hdev->adv_instance_cnt >= HCI_MAX_ADV_INSTANCES ||
2830+
if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
28312831
instance < 1 || instance > HCI_MAX_ADV_INSTANCES)
28322832
return -EOVERFLOW;
28332833

@@ -3195,6 +3195,7 @@ struct hci_dev *hci_alloc_dev(void)
31953195
hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
31963196
hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
31973197
hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
3198+
hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
31983199

31993200
hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
32003201
hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;

net/bluetooth/hci_request.c

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,7 +1601,7 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance)
16011601
cp.own_addr_type = own_addr_type;
16021602
cp.channel_map = hdev->le_adv_channel_map;
16031603
cp.tx_power = 127;
1604-
cp.handle = 0;
1604+
cp.handle = instance;
16051605

16061606
if (flags & MGMT_ADV_FLAG_SEC_2M) {
16071607
cp.primary_phy = HCI_ADV_PHY_1M;
@@ -1643,11 +1643,21 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance)
16431643
return 0;
16441644
}
16451645

1646-
void __hci_req_enable_ext_advertising(struct hci_request *req)
1646+
int __hci_req_enable_ext_advertising(struct hci_request *req, u8 instance)
16471647
{
1648+
struct hci_dev *hdev = req->hdev;
16481649
struct hci_cp_le_set_ext_adv_enable *cp;
16491650
struct hci_cp_ext_adv_set *adv_set;
16501651
u8 data[sizeof(*cp) + sizeof(*adv_set) * 1];
1652+
struct adv_info *adv_instance;
1653+
1654+
if (instance > 0) {
1655+
adv_instance = hci_find_adv_instance(hdev, instance);
1656+
if (!adv_instance)
1657+
return -EINVAL;
1658+
} else {
1659+
adv_instance = NULL;
1660+
}
16511661

16521662
cp = (void *) data;
16531663
adv_set = (void *) cp->data;
@@ -1659,11 +1669,23 @@ void __hci_req_enable_ext_advertising(struct hci_request *req)
16591669

16601670
memset(adv_set, 0, sizeof(*adv_set));
16611671

1662-
adv_set->handle = 0;
1672+
adv_set->handle = instance;
1673+
1674+
/* Set duration per instance since controller is responsible for
1675+
* scheduling it.
1676+
*/
1677+
if (adv_instance && adv_instance->duration) {
1678+
u16 duration = adv_instance->duration * MSEC_PER_SEC;
1679+
1680+
/* Time = N * 10 ms */
1681+
adv_set->duration = cpu_to_le16(duration / 10);
1682+
}
16631683

16641684
hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_ENABLE,
16651685
sizeof(*cp) + sizeof(*adv_set) * cp->num_of_sets,
16661686
data);
1687+
1688+
return 0;
16671689
}
16681690

16691691
int __hci_req_start_ext_adv(struct hci_request *req, u8 instance)
@@ -1679,7 +1701,7 @@ int __hci_req_start_ext_adv(struct hci_request *req, u8 instance)
16791701
return err;
16801702

16811703
__hci_req_update_scan_rsp_data(req, instance);
1682-
__hci_req_enable_ext_advertising(req);
1704+
__hci_req_enable_ext_advertising(req, instance);
16831705

16841706
return 0;
16851707
}
@@ -1723,10 +1745,13 @@ int __hci_req_schedule_adv_instance(struct hci_request *req, u8 instance,
17231745
adv_instance->remaining_time =
17241746
adv_instance->remaining_time - timeout;
17251747

1726-
hdev->adv_instance_timeout = timeout;
1727-
queue_delayed_work(hdev->req_workqueue,
1748+
/* Only use work for scheduling instances with legacy advertising */
1749+
if (!ext_adv_capable(hdev)) {
1750+
hdev->adv_instance_timeout = timeout;
1751+
queue_delayed_work(hdev->req_workqueue,
17281752
&hdev->adv_instance_expire,
17291753
msecs_to_jiffies(timeout * 1000));
1754+
}
17301755

17311756
/* If we're just re-scheduling the same instance again then do not
17321757
* execute any HCI commands. This happens when a single instance is
@@ -2744,7 +2769,8 @@ static int powered_update_hci(struct hci_request *req, unsigned long opt)
27442769
if (!ext_adv_capable(hdev))
27452770
__hci_req_enable_advertising(req);
27462771
else if (!err)
2747-
__hci_req_enable_ext_advertising(req);
2772+
__hci_req_enable_ext_advertising(req,
2773+
0x00);
27482774
}
27492775
} else if (!list_empty(&hdev->adv_instances)) {
27502776
struct adv_info *adv_instance;

net/bluetooth/hci_request.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ void hci_req_clear_adv_instance(struct hci_dev *hdev, struct sock *sk,
8383

8484
int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance);
8585
int __hci_req_start_ext_adv(struct hci_request *req, u8 instance);
86-
void __hci_req_enable_ext_advertising(struct hci_request *req);
86+
int __hci_req_enable_ext_advertising(struct hci_request *req, u8 instance);
8787
void __hci_req_clear_ext_adv_sets(struct hci_request *req);
8888
int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
8989
bool use_rpa, struct adv_info *adv_instance,

0 commit comments

Comments
 (0)