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_hdr hdr;
struct lll_scan *scan;
uint8_t chan:6;
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 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);
}

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 */
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 */

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
};