Bluetooth: controller: split: Fix pipeline for continuous events

Fix the pipeline prepare-resume implementation to correctly
handle multiple continuous events that request resume on
being pre-empted.

Symptoms of the bug being, when having continuous scanning,
and an active peripheral if a directed advertising is
started the peripheral event are not scheduled causing link
supervision timeout.

This is fixed by not having an enqueued resume event
prepared if there is an enqueued new non-resume event in the
pipeline.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2019-08-08 16:29:09 +05:30 committed by Carles Cufí
commit 3e0e378dca

View file

@ -191,21 +191,9 @@ void lll_resume(void *param)
struct lll_event *next = param;
int ret;
if (event.curr.abort_cb) {
ret = prepare(next->is_abort_cb, next->abort_cb,
next->prepare_cb, next->prio,
&next->prepare_param, next->is_resume);
LL_ASSERT(!ret || ret == -EINPROGRESS);
return;
}
event.curr.is_abort_cb = next->is_abort_cb;
event.curr.abort_cb = next->abort_cb;
event.curr.param = next->prepare_param.param;
ret = next->prepare_cb(&next->prepare_param);
LL_ASSERT(!ret);
ret = prepare(next->is_abort_cb, next->abort_cb, next->prepare_cb,
next->prio, &next->prepare_param, next->is_resume);
LL_ASSERT(!ret || ret == -EINPROGRESS);
}
void lll_disable(void *param)
@ -426,12 +414,14 @@ static int prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
struct lll_event *p;
u8_t idx = UINT8_MAX;
/* Find the ready prepare in the pipeline */
p = ull_prepare_dequeue_iter(&idx);
while (p && p->is_aborted) {
while (p && (p->is_aborted || p->is_resume)) {
p = ull_prepare_dequeue_iter(&idx);
}
if (event.curr.abort_cb || p) {
/* Current event active or another prepare is ready in the pipeline */
if (event.curr.abort_cb || (p && is_resume)) {
#if !defined(CONFIG_BT_CTLR_LOW_LAT)
u32_t preempt_anchor;
struct evt_hdr *evt;
@ -453,11 +443,11 @@ static int prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
prepare_cb, prio, is_resume);
LL_ASSERT(!ret);
#if !defined(CONFIG_BT_CTLR_LOW_LAT)
if (is_resume) {
return -EINPROGRESS;
}
#if !defined(CONFIG_BT_CTLR_LOW_LAT)
/* Calc the preempt timeout */
evt = HDR_LLL2EVT(prepare_param->param);
preempt_anchor = prepare_param->ticks_at_expire;
@ -571,7 +561,7 @@ static void preempt(void *param)
return;
}
while (next && next->is_resume) {
while (next && (next->is_aborted || next->is_resume)) {
next = ull_prepare_dequeue_iter(&idx);
}