From fbf91da9228068e1d900db67d17d425f1dd15482 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 28 Apr 2020 14:12:04 +0530 Subject: [PATCH] Bluetooth: controller: split: Extended scanning Rx list Added implementation to enqueue received auxiliary PDUs in the ULL. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll_scan.h | 2 - .../ll_sw/nordic/lll/lll_scan_aux.c | 19 +++-- subsys/bluetooth/controller/ll_sw/ull.c | 5 +- .../bluetooth/controller/ll_sw/ull_scan_aux.c | 84 +++++++++++++++---- .../controller/ll_sw/ull_scan_internal.h | 3 +- .../controller/ll_sw/ull_scan_types.h | 3 + 6 files changed, 88 insertions(+), 28 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.h b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.h index 0da8c7320d6..0a546afe855 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.h @@ -47,8 +47,6 @@ struct lll_scan { struct lll_scan_aux { struct lll_hdr hdr; - struct lll_scan *scan; - uint8_t chan:6; uint8_t phy:3; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c index a653d5a2165..1889ad8f9a6 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c @@ -39,6 +39,9 @@ static void isr_rx(void *param); static int isr_rx_pdu(struct lll_scan_aux *lll, uint8_t rssi_ready); static void isr_done(void *param); +static uint16_t trx_cnt; /* TODO: move to a union in lll.c, common to all roles + */ + int lll_scan_aux_init(void) { int err; @@ -94,6 +97,8 @@ static int prepare_cb(struct lll_prepare_param *p) DEBUG_RADIO_START_O(1); + trx_cnt = 0U; + radio_reset(); #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) @@ -283,12 +288,14 @@ static int isr_rx_pdu(struct lll_scan_aux *lll, uint8_t rssi_ready) } pdu = (void *)node_rx->pdu; - if (pdu->type != PDU_ADV_TYPE_EXT_IND) { + if ((pdu->type != PDU_ADV_TYPE_EXT_IND) || !pdu->len) { return -EINVAL; } ull_pdu_rx_alloc(); + trx_cnt++; + switch (lll->phy) { case BIT(0): node_rx->hdr.type = NODE_RX_TYPE_EXT_1M_REPORT; @@ -308,7 +315,7 @@ static int isr_rx_pdu(struct lll_scan_aux *lll, uint8_t rssi_ready) } ftr = &(node_rx->hdr.rx_ftr); - ftr->param = lll->scan; + ftr->param = lll; ftr->ticks_anchor = radio_tmr_start_get(); ftr->radio_end_us = radio_tmr_end_get() - radio_rx_chain_delay_get(lll->phy, 1); @@ -325,10 +332,12 @@ static void isr_done(void *param) lll_isr_status_reset(); - e = ull_event_done_extra_get(); - LL_ASSERT(e); + if (!trx_cnt) { + e = ull_event_done_extra_get(); + LL_ASSERT(e); - e->type = EVENT_DONE_EXTRA_TYPE_SCAN_AUX; + e->type = EVENT_DONE_EXTRA_TYPE_SCAN_AUX; + } lll_isr_cleanup(param); } diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index b09534ba6fe..9470925f6bc 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -1600,10 +1600,7 @@ static inline int rx_demux_rx(memq_link_t *link, struct node_rx_hdr *rx) } /* TODO: below interface is WIP */ - ull_scan_aux_setup(rx, phy, NULL); - - ll_rx_put(link, rx); - ll_rx_sched(); + ull_scan_aux_setup(link, rx, phy); } break; #endif /* CONFIG_BT_CTLR_ADV_EXT */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c index 4854259fcaf..768b6d7d06c 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c @@ -36,7 +36,8 @@ static int init_reset(void); static inline struct ll_scan_aux_set *aux_acquire(void); static inline void aux_release(struct ll_scan_aux_set *aux); -static inline uint16_t aux_handle_get(struct ll_scan_aux_set *aux); +static inline uint8_t aux_handle_get(struct ll_scan_aux_set *aux); +static void rx_flush_release(struct ll_scan_aux_set *aux); static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy, void *param); static void ticker_op_cb(uint32_t status, void *param); @@ -69,11 +70,11 @@ int ull_scan_aux_reset(void) return 0; } -void ull_scan_aux_setup(struct node_rx_hdr *rx, uint8_t phy, - struct ll_scan_aux_set *aux) +void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx, uint8_t phy) { struct ext_adv_aux_ptr *aux_ptr; struct pdu_adv_com_ext_adv *p; + struct ll_scan_aux_set *aux; uint32_t ticks_slot_overhead; uint32_t window_widening_us; struct lll_scan_aux *lll; @@ -87,33 +88,45 @@ void ull_scan_aux_setup(struct node_rx_hdr *rx, uint8_t phy, uint8_t aux_handle; uint8_t *ptr; + ftr = &rx->rx_ftr; + lll = ftr->param; + aux = lll->hdr.parent; + if (((uint8_t *)aux < (uint8_t *)ll_scan_aux_pool) || + ((uint8_t *)aux > ((uint8_t *)ll_scan_aux_pool + + (sizeof(struct ll_scan_aux_set) * + (CONFIG_BT_CTLR_SCAN_AUX_SET - 1))))) { + aux = NULL; + } + pdu = (void *)((struct node_rx_pdu *)rx)->pdu; - if ((pdu->type != PDU_ADV_TYPE_EXT_IND) || !pdu->len) { - return; + if (pdu->type != PDU_ADV_TYPE_EXT_IND) { + aux = NULL; + goto ull_scan_aux_rx_flush; } p = (void *)&pdu->adv_ext_ind; if (!p->ext_hdr_len) { - return; + goto ull_scan_aux_rx_flush; } h = (void *)p->ext_hdr_adi_adv_data; if (!h->aux_ptr) { - return; + goto ull_scan_aux_rx_flush; } if (!aux) { aux = aux_acquire(); if (!aux) { - return; + goto ull_scan_aux_rx_flush; } + aux->rx_last = NULL; lll = &aux->lll; ull_hdr_init((void *)lll); lll_hdr_init(lll, aux); } else { - lll = &aux->lll; + LL_ASSERT(0); } ptr = (uint8_t *)h + sizeof(*h); @@ -134,9 +147,20 @@ void ull_scan_aux_setup(struct node_rx_hdr *rx, uint8_t phy, } aux_ptr = (void *)ptr; + if (!aux_ptr->offs) { + goto ull_scan_aux_rx_flush; + } + + /* Enqueue the rx in aux context */ + link->next = NULL; + link->mem = rx; + if (aux->rx_last) { + aux->rx_last->next = link; + } else { + aux->rx_head = link; + } + aux->rx_last = link; - ftr = &rx->rx_ftr; - lll->scan = ftr->param; lll->chan = aux_ptr->chan_idx; lll->phy = BIT(aux_ptr->phy); @@ -204,6 +228,16 @@ void ull_scan_aux_setup(struct node_rx_hdr *rx, uint8_t phy, ticker_cb, aux, ticker_op_cb, aux); LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) || (ticker_status == TICKER_STATUS_BUSY)); + + return; + +ull_scan_aux_rx_flush: + if (aux) { + rx_flush_release(aux); + } + + ll_rx_put(link, rx); + ll_rx_sched(); } void ull_scan_aux_done(struct node_rx_event_done *done) @@ -211,7 +245,7 @@ void ull_scan_aux_done(struct node_rx_event_done *done) struct lll_scan_aux *lll = (void *)HDR_ULL2LLL(done->param); struct ll_scan_aux_set *aux = (void *)HDR_LLL2EVT(lll); - aux_release(aux); + rx_flush_release(aux); } uint8_t ull_scan_aux_lll_handle_get(struct lll_scan_aux *lll) @@ -239,12 +273,32 @@ static inline void aux_release(struct ll_scan_aux_set *aux) mem_release(aux, &scan_aux_free); } -static inline uint16_t aux_handle_get(struct ll_scan_aux_set *aux) +static inline uint8_t aux_handle_get(struct ll_scan_aux_set *aux) { return mem_index_get(aux, ll_scan_aux_pool, sizeof(struct ll_scan_aux_set)); } +static void rx_flush_release(struct ll_scan_aux_set *aux) +{ + if (aux->rx_last) { + memq_link_t *head = aux->rx_head; + + do { + struct node_rx_hdr *rx = head->mem; + memq_link_t *link = head; + + head = link->next; + + ll_rx_put(link, rx); + } while (head); + + ll_rx_sched(); + } + + aux_release(aux); +} + static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy, void *param) { @@ -288,12 +342,12 @@ static void ticker_op_cb(uint32_t status, void *param) mfy.param = param; - ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_LLL, + ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, TICKER_USER_ID_ULL_HIGH, 0, &mfy); LL_ASSERT(!ret); } static void ticker_op_aux_failure(void *param) { - aux_release(param); + rx_flush_release(param); } diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_internal.h b/subsys/bluetooth/controller/ll_sw/ull_scan_internal.h index f440c4610af..15889070ff4 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_internal.h @@ -44,8 +44,7 @@ int ull_scan_aux_init(void); int ull_scan_aux_reset(void); /* Helper to setup scanning on auxiliary channel */ -void ull_scan_aux_setup(struct node_rx_hdr *rx, uint8_t phy, - struct ll_scan_aux_set *aux); +void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx, uint8_t phy); /* Helper to clean up auxiliary channel scanning */ void ull_scan_aux_done(struct node_rx_event_done *done); diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_types.h b/subsys/bluetooth/controller/ll_sw/ull_scan_types.h index 44650585353..45e410bb4ac 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_types.h @@ -17,4 +17,7 @@ struct ll_scan_aux_set { struct evt_hdr evt; struct ull_hdr ull; struct lll_scan_aux lll; + + memq_link_t *rx_head; + memq_link_t *rx_last; };