nimble/ll: Optimize sync sm scheduler handling

Scheduler item in sync sm can be initialize only once, no need to do
this on each event. Callbacks for ADV_SYNC_IND and ADV_CHAIN_IND are
pretty much the same except for wfr calculations so we'll just have
flag to indicate what is being scanned.
This commit is contained in:
Andrzej Kaczmarek
2021-10-20 11:35:12 +02:00
parent aab952c4a3
commit 99de1340e7
+37 -92
View File
@@ -61,6 +61,7 @@
#define BLE_LL_SYNC_SM_FLAG_ADDR_RESOLVED 0x0080
#define BLE_LL_SYNC_SM_FLAG_HCI_TRUNCATED 0x0100
#define BLE_LL_SYNC_SM_FLAG_NEW_CHANMAP 0x0200
#define BLE_LL_SYNC_SM_FLAG_CHAIN 0x0400
#define BLE_LL_SYNC_CHMAP_LEN 5
#define BLE_LL_SYNC_ITVL_USECS 1250
@@ -137,6 +138,8 @@ static uint8_t *g_ble_ll_sync_create_comp_ev;
static struct ble_ll_sync_sm *g_ble_ll_sync_sm_current;
static int ble_ll_sync_event_start_cb(struct ble_ll_sched_item *sch);
static int
ble_ll_sync_on_list(const uint8_t *addr, uint8_t addr_type, uint8_t sid)
{
@@ -211,7 +214,12 @@ ble_ll_sync_sm_clear(struct ble_ll_sync_sm *sm)
BLE_LL_ASSERT(sm->sync_ev_end.ev.ev_queued == 0);
BLE_LL_ASSERT(sm->sch.enqueued == 0);
memset(sm, 0, sizeof(*sm));
sm->sch.sched_cb = ble_ll_sync_event_start_cb;
sm->sch.cb_arg = sm;
sm->sch.sched_type = BLE_LL_SCHED_TYPE_SYNC;
}
static uint8_t
@@ -436,6 +444,7 @@ ble_ll_sync_event_start_cb(struct ble_ll_sched_item *sch)
struct ble_ll_sync_sm *sm;
uint32_t wfr_usecs;
uint32_t start;
uint8_t chan;
int rc;
/* Set current connection state machine */
@@ -451,7 +460,9 @@ ble_ll_sync_event_start_cb(struct ble_ll_sched_item *sch)
ble_ll_state_set(BLE_LL_STATE_SYNC);
/* Set channel */
ble_phy_setchan(sm->chan_index, sm->access_addr, sm->crcinit);
chan = sm->flags & BLE_LL_SYNC_SM_FLAG_CHAIN ? sm->chan_chain :
sm->chan_index;
ble_phy_setchan(chan, sm->access_addr, sm->crcinit);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
ble_phy_resolv_list_disable();
@@ -469,31 +480,35 @@ ble_ll_sync_event_start_cb(struct ble_ll_sched_item *sch)
rc = ble_phy_rx_set_start_time(start, sch->remainder);
if (rc && rc != BLE_PHY_ERR_RX_LATE) {
STATS_INC(ble_ll_stats, sync_event_failed);
rc = BLE_LL_SCHED_STATE_DONE;
ble_ll_event_send(&sm->sync_ev_end);
ble_ll_sync_current_sm_over();
rc = BLE_LL_SCHED_STATE_DONE;
} else {
/*
* Set flag that tells to set last anchor point if a packet
* has been received.
*/
sm->flags |= BLE_LL_SYNC_SM_FLAG_SET_ANCHOR;
/* Set WFR timer.
* If establishing we always adjust with offset unit.
* If this is first packet of sync (one that was pointed by from
* SyncInfo we don't adjust WFT with window widening.
*/
if (sm->flags & BLE_LL_SYNC_SM_FLAG_ESTABLISHING) {
if (sm->flags & BLE_LL_SYNC_SM_FLAG_CHAIN) {
wfr_usecs = (sm->flags & BLE_LL_SYNC_SM_FLAG_OFFSET_300) ? 300 : 30;
if (!(sm->flags & BLE_LL_SYNC_SM_FLAG_SYNC_INFO)) {
wfr_usecs += 2 * sm->window_widening;
}
} else {
wfr_usecs = 2 * sm->window_widening;
}
ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, wfr_usecs);
/* Set flag that tells to set last anchor point if a packet
* has been received.
*/
sm->flags |= BLE_LL_SYNC_SM_FLAG_SET_ANCHOR;
/* Set WFR timer.
* If establishing we always adjust with offset unit.
* If this is first packet of sync (one that was pointed by from
* SyncInfo we don't adjust WFR with window widening.
*/
if (sm->flags & BLE_LL_SYNC_SM_FLAG_ESTABLISHING) {
wfr_usecs = (sm->flags & BLE_LL_SYNC_SM_FLAG_OFFSET_300) ? 300
: 30;
if (!(sm->flags & BLE_LL_SYNC_SM_FLAG_SYNC_INFO)) {
wfr_usecs += 2 * sm->window_widening;
}
} else {
wfr_usecs = 2 * sm->window_widening;
}
}
ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, wfr_usecs);
rc = BLE_LL_SCHED_STATE_RUNNING;
}
@@ -865,63 +880,6 @@ ble_ll_sync_parse_aux_ptr(const uint8_t *buf, uint8_t *chan, uint32_t *offset,
*phy = (aux_ptr_field >> 21) & 0x07;
}
static int
ble_ll_sync_chain_start_cb(struct ble_ll_sched_item *sch)
{
struct ble_ll_sync_sm *sm;
uint32_t wfr_usecs;
uint32_t start;
int rc;
/* Set current connection state machine */
sm = sch->cb_arg;
g_ble_ll_sync_sm_current = sm;
BLE_LL_ASSERT(sm);
/* Disable whitelisting */
ble_ll_whitelist_disable();
/* Set LL state */
ble_ll_state_set(BLE_LL_STATE_SYNC);
/* Set channel */
ble_phy_setchan(sm->chan_chain, sm->access_addr, sm->crcinit);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
ble_phy_resolv_list_disable();
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
ble_phy_encrypt_disable();
#endif
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
ble_phy_mode_set(sm->phy_mode, sm->phy_mode);
#endif
start = sch->start_time + g_ble_ll_sched_offset_ticks;
rc = ble_phy_rx_set_start_time(start, sch->remainder);
if (rc && rc != BLE_PHY_ERR_RX_LATE) {
STATS_INC(ble_ll_stats, sync_chain_failed);
rc = BLE_LL_SCHED_STATE_DONE;
ble_ll_event_send(&sm->sync_ev_end);
ble_ll_sync_current_sm_over();
} else {
/*
* Clear flag that tells to set last anchor point if a packet
* has been received, this is chain and we don't need it.
*/
sm->flags &= ~BLE_LL_SYNC_SM_FLAG_SET_ANCHOR;
wfr_usecs = (sm->flags & BLE_LL_SYNC_SM_FLAG_OFFSET_300) ? 300 : 30;
ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, wfr_usecs);
rc = BLE_LL_SCHED_STATE_RUNNING;
}
return rc;
}
static int
ble_ll_sync_schedule_chain(struct ble_ll_sync_sm *sm, struct ble_mbuf_hdr *hdr,
const uint8_t *aux)
@@ -954,9 +912,7 @@ ble_ll_sync_schedule_chain(struct ble_ll_sync_sm *sm, struct ble_mbuf_hdr *hdr,
sm->chan_chain = chan;
sm->sch.sched_cb = ble_ll_sync_chain_start_cb;
sm->sch.cb_arg = sm;
sm->sch.sched_type = BLE_LL_SCHED_TYPE_SYNC;
sm->flags |= BLE_LL_SYNC_SM_FLAG_CHAIN;
return ble_ll_sched_sync(&sm->sch, hdr->beg_cputime, hdr->rem_usecs,
offset, sm->phy_mode);
@@ -1308,10 +1264,7 @@ ble_ll_sync_event_end(struct ble_npl_event *ev)
/* Event ended so we are no longer chaining */
sm->flags &= ~BLE_LL_SYNC_SM_FLAG_HCI_TRUNCATED;
sm->sch.sched_cb = ble_ll_sync_event_start_cb;
sm->sch.cb_arg = sm;
sm->sch.sched_type = BLE_LL_SCHED_TYPE_SYNC;
sm->flags &= ~BLE_LL_SYNC_SM_FLAG_CHAIN;
do {
if (ble_ll_sync_next_event(sm, 0) < 0) {
@@ -1473,10 +1426,6 @@ ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd,
sm->chan_index = ble_ll_utils_calc_dci_csa2(sm->event_cntr, sm->channel_id,
sm->num_used_chans, sm->chanmap);
sm->sch.sched_cb = ble_ll_sync_event_start_cb;
sm->sch.cb_arg = sm;
sm->sch.sched_type = BLE_LL_SCHED_TYPE_SYNC;
if (ble_ll_sched_sync(&sm->sch, rxhdr->beg_cputime, rxhdr->rem_usecs,
offset, sm->phy_mode)) {
return;
@@ -2031,10 +1980,6 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm,
sm->chan_index = ble_ll_utils_calc_dci_csa2(sm->event_cntr, sm->channel_id,
sm->num_used_chans, sm->chanmap);
sm->sch.sched_cb = ble_ll_sync_event_start_cb;
sm->sch.cb_arg = sm;
sm->sch.sched_type = BLE_LL_SCHED_TYPE_SYNC;
/* get anchor for specified conn event */
conn_event_count = get_le16(sync_ind + 20);
ble_ll_conn_get_anchor(connsm, conn_event_count, &sm->anchor_point,