Bluetooth: Controller: mayfly enable to supercede over disable
If mayfly enable is called before mayfly could be disabled,
then enable shall supercede disabling, the mayfly will
remain enabled. Any new mayfly enqueued by the caller that
tried to disable mayfly will be chain for deferred
executon under this condition.
The BLE Controller's connection update procedure broke when
mayfly implementation was updated to defer disabling until
all queued mayfly where completed. Mayfly is disabled
between ticker_stop and ticker_start calls to chain them
so that ticker does not power off counter h/w if the ticker
being stopped is last one.
This commit fixes the connection update procedure which
used the mayfly enable before mayfly disable could
complete.
Jira: ZEP-1839
Change-id: I07d34c90d193b5eca9762acd8b7272e8d7a78474
Signed-off-by: Vinayak Chettimada <vinayak.kariappa.chettimada@nordicsemi.no>
diff --git a/subsys/bluetooth/controller/util/mayfly.c b/subsys/bluetooth/controller/util/mayfly.c
index 531627c..d97d796 100644
--- a/subsys/bluetooth/controller/util/mayfly.c
+++ b/subsys/bluetooth/controller/util/mayfly.c
@@ -14,13 +14,10 @@
static struct {
void *head;
void *tail;
- union {
- uint32_t flags;
- struct {
- uint32_t disable_req : 1;
- uint32_t disable_ack : 1;
- };
- };
+ uint8_t enable_req;
+ uint8_t enable_ack;
+ uint8_t disable_req;
+ uint8_t disable_ack;
} mft[MAYFLY_CALLEE_COUNT][MAYFLY_CALLER_COUNT];
static void *mfl[MAYFLY_CALLEE_COUNT][MAYFLY_CALLER_COUNT][2];
@@ -45,6 +42,11 @@
void mayfly_enable(uint8_t caller_id, uint8_t callee_id, uint8_t enable)
{
if (enable) {
+ if (mft[callee_id][caller_id].enable_req ==
+ mft[callee_id][caller_id].enable_ack) {
+ mft[callee_id][caller_id].enable_req++;
+ }
+
mayfly_enable_cb(caller_id, callee_id, enable);
} else {
if (mft[callee_id][caller_id].disable_req ==
@@ -63,7 +65,9 @@
uint8_t ack;
chain = chain || !mayfly_prio_is_equal(caller_id, callee_id) ||
- !mayfly_is_enabled(caller_id, callee_id);
+ !mayfly_is_enabled(caller_id, callee_id) ||
+ (mft[callee_id][caller_id].disable_req !=
+ mft[callee_id][caller_id].disable_ack);
/* shadow the ack */
ack = m->_ack;
@@ -110,8 +114,9 @@
void mayfly_run(uint8_t callee_id)
{
- uint8_t caller_id;
uint8_t disable = 0;
+ uint8_t enable = 0;
+ uint8_t caller_id;
/* iterate through each caller queue to this callee_id */
caller_id = MAYFLY_CALLER_COUNT;
@@ -180,9 +185,17 @@
mft[callee_id][caller_id].disable_ack =
mft[callee_id][caller_id].disable_req;
}
+
+ if (mft[callee_id][caller_id].enable_req !=
+ mft[callee_id][caller_id].enable_ack) {
+ enable = 1;
+
+ mft[callee_id][caller_id].enable_ack =
+ mft[callee_id][caller_id].enable_req;
+ }
}
- if (disable) {
+ if (disable && !enable) {
mayfly_enable_cb(callee_id, callee_id, 0);
}
}