Bluetooth: controller: split: Extended scanning Rx list

Added implementation to enqueue received auxiliary PDUs in
the ULL.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2020-04-28 14:12:04 +05:30 committed by Carles Cufí
commit fbf91da922
6 changed files with 88 additions and 28 deletions

View file

@ -47,8 +47,6 @@ struct lll_scan {
struct lll_scan_aux { struct lll_scan_aux {
struct lll_hdr hdr; struct lll_hdr hdr;
struct lll_scan *scan;
uint8_t chan:6; uint8_t chan:6;
uint8_t phy:3; uint8_t phy:3;

View file

@ -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 int isr_rx_pdu(struct lll_scan_aux *lll, uint8_t rssi_ready);
static void isr_done(void *param); 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 lll_scan_aux_init(void)
{ {
int err; int err;
@ -94,6 +97,8 @@ static int prepare_cb(struct lll_prepare_param *p)
DEBUG_RADIO_START_O(1); DEBUG_RADIO_START_O(1);
trx_cnt = 0U;
radio_reset(); radio_reset();
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) #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; 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; return -EINVAL;
} }
ull_pdu_rx_alloc(); ull_pdu_rx_alloc();
trx_cnt++;
switch (lll->phy) { switch (lll->phy) {
case BIT(0): case BIT(0):
node_rx->hdr.type = NODE_RX_TYPE_EXT_1M_REPORT; 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 = &(node_rx->hdr.rx_ftr);
ftr->param = lll->scan; ftr->param = lll;
ftr->ticks_anchor = radio_tmr_start_get(); ftr->ticks_anchor = radio_tmr_start_get();
ftr->radio_end_us = radio_tmr_end_get() - ftr->radio_end_us = radio_tmr_end_get() -
radio_rx_chain_delay_get(lll->phy, 1); radio_rx_chain_delay_get(lll->phy, 1);
@ -325,10 +332,12 @@ static void isr_done(void *param)
lll_isr_status_reset(); lll_isr_status_reset();
e = ull_event_done_extra_get(); if (!trx_cnt) {
LL_ASSERT(e); 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); lll_isr_cleanup(param);
} }

View file

@ -1600,10 +1600,7 @@ static inline int rx_demux_rx(memq_link_t *link, struct node_rx_hdr *rx)
} }
/* TODO: below interface is WIP */ /* TODO: below interface is WIP */
ull_scan_aux_setup(rx, phy, NULL); ull_scan_aux_setup(link, rx, phy);
ll_rx_put(link, rx);
ll_rx_sched();
} }
break; break;
#endif /* CONFIG_BT_CTLR_ADV_EXT */ #endif /* CONFIG_BT_CTLR_ADV_EXT */

View file

@ -36,7 +36,8 @@
static int init_reset(void); static int init_reset(void);
static inline struct ll_scan_aux_set *aux_acquire(void); static inline struct ll_scan_aux_set *aux_acquire(void);
static inline void aux_release(struct ll_scan_aux_set *aux); 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, static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, void *param); uint16_t lazy, void *param);
static void ticker_op_cb(uint32_t status, void *param); static void ticker_op_cb(uint32_t status, void *param);
@ -69,11 +70,11 @@ int ull_scan_aux_reset(void)
return 0; return 0;
} }
void ull_scan_aux_setup(struct node_rx_hdr *rx, uint8_t phy, void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx, uint8_t phy)
struct ll_scan_aux_set *aux)
{ {
struct ext_adv_aux_ptr *aux_ptr; struct ext_adv_aux_ptr *aux_ptr;
struct pdu_adv_com_ext_adv *p; struct pdu_adv_com_ext_adv *p;
struct ll_scan_aux_set *aux;
uint32_t ticks_slot_overhead; uint32_t ticks_slot_overhead;
uint32_t window_widening_us; uint32_t window_widening_us;
struct lll_scan_aux *lll; 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 aux_handle;
uint8_t *ptr; 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; pdu = (void *)((struct node_rx_pdu *)rx)->pdu;
if ((pdu->type != PDU_ADV_TYPE_EXT_IND) || !pdu->len) { if (pdu->type != PDU_ADV_TYPE_EXT_IND) {
return; aux = NULL;
goto ull_scan_aux_rx_flush;
} }
p = (void *)&pdu->adv_ext_ind; p = (void *)&pdu->adv_ext_ind;
if (!p->ext_hdr_len) { if (!p->ext_hdr_len) {
return; goto ull_scan_aux_rx_flush;
} }
h = (void *)p->ext_hdr_adi_adv_data; h = (void *)p->ext_hdr_adi_adv_data;
if (!h->aux_ptr) { if (!h->aux_ptr) {
return; goto ull_scan_aux_rx_flush;
} }
if (!aux) { if (!aux) {
aux = aux_acquire(); aux = aux_acquire();
if (!aux) { if (!aux) {
return; goto ull_scan_aux_rx_flush;
} }
aux->rx_last = NULL;
lll = &aux->lll; lll = &aux->lll;
ull_hdr_init((void *)lll); ull_hdr_init((void *)lll);
lll_hdr_init(lll, aux); lll_hdr_init(lll, aux);
} else { } else {
lll = &aux->lll; LL_ASSERT(0);
} }
ptr = (uint8_t *)h + sizeof(*h); 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; 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->chan = aux_ptr->chan_idx;
lll->phy = BIT(aux_ptr->phy); 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); ticker_cb, aux, ticker_op_cb, aux);
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) || LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
(ticker_status == TICKER_STATUS_BUSY)); (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) 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 lll_scan_aux *lll = (void *)HDR_ULL2LLL(done->param);
struct ll_scan_aux_set *aux = (void *)HDR_LLL2EVT(lll); 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) 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); 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, return mem_index_get(aux, ll_scan_aux_pool,
sizeof(struct ll_scan_aux_set)); 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, static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, void *param) uint16_t lazy, void *param)
{ {
@ -288,12 +342,12 @@ static void ticker_op_cb(uint32_t status, void *param)
mfy.param = 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); 0, &mfy);
LL_ASSERT(!ret); LL_ASSERT(!ret);
} }
static void ticker_op_aux_failure(void *param) static void ticker_op_aux_failure(void *param)
{ {
aux_release(param); rx_flush_release(param);
} }

View file

@ -44,8 +44,7 @@ int ull_scan_aux_init(void);
int ull_scan_aux_reset(void); int ull_scan_aux_reset(void);
/* Helper to setup scanning on auxiliary channel */ /* Helper to setup scanning on auxiliary channel */
void ull_scan_aux_setup(struct node_rx_hdr *rx, uint8_t phy, void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx, uint8_t phy);
struct ll_scan_aux_set *aux);
/* Helper to clean up auxiliary channel scanning */ /* Helper to clean up auxiliary channel scanning */
void ull_scan_aux_done(struct node_rx_event_done *done); void ull_scan_aux_done(struct node_rx_event_done *done);

View file

@ -17,4 +17,7 @@ struct ll_scan_aux_set {
struct evt_hdr evt; struct evt_hdr evt;
struct ull_hdr ull; struct ull_hdr ull;
struct lll_scan_aux lll; struct lll_scan_aux lll;
memq_link_t *rx_head;
memq_link_t *rx_last;
}; };