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:
parent
97355e4799
commit
fbf91da922
6 changed files with 88 additions and 28 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue