Skip to content

Commit 2da4429

Browse files
committed
Bluetooth: controller: Fix mayfly caller id for thread call path
role_disable initiated through HCI commands are initiated in thread context and controller code was using the job mayfly caller id instead of using the correct app caller id. Also the XTAL retain calls being called from two different call context used the same worker caller id and same mayfly instead of using the correct caller ids and independent mayfly for each caller. This potentially could cause mayfly enqueued list to be corrupted and enqueued mayfly could be lost. Change-id: Ia356419462d1fb4e38f4a20c720974143f12fdb6 Signed-off-by: Vinayak Chettimada <[email protected]>
1 parent 00fa999 commit 2da4429

File tree

1 file changed

+39
-19
lines changed
  • subsys/bluetooth/controller/ll

1 file changed

+39
-19
lines changed

subsys/bluetooth/controller/ll/ctrl.c

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2978,7 +2978,7 @@ static void mayfly_xtal_stop(void *params)
29782978
}
29792979

29802980
#if XTAL_ADVANCED
2981-
static void mayfly_xtal_retain(uint8_t retain)
2981+
static void mayfly_xtal_retain(uint8_t caller_id, uint8_t retain)
29822982
{
29832983
static uint8_t s_xtal_retained;
29842984

@@ -2989,25 +2989,45 @@ static void mayfly_xtal_retain(uint8_t retain)
29892989
0, mayfly_xtal_start};
29902990
uint32_t retval;
29912991

2992+
/* Only user id job will try to retain the XTAL. */
2993+
LL_ASSERT(caller_id == RADIO_TICKER_USER_ID_JOB);
2994+
29922995
s_xtal_retained = 1;
29932996

2994-
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_WORKER,
2997+
retval = mayfly_enqueue(caller_id,
29952998
RADIO_TICKER_USER_ID_WORKER, 0,
29962999
&s_mfy_xtal_start);
29973000
LL_ASSERT(!retval);
29983001
}
29993002
} else {
30003003
if (s_xtal_retained) {
3001-
static void *s_link[2];
3002-
static struct mayfly s_mfy_xtal_stop = {0, 0, s_link,
3003-
0, mayfly_xtal_stop};
3004+
static void *s_link[2][2];
3005+
static struct mayfly s_mfy_xtal_stop[2] = {
3006+
{0, 0, s_link[0], NULL, mayfly_xtal_stop},
3007+
{0, 0, s_link[1], NULL, mayfly_xtal_stop}
3008+
};
3009+
struct mayfly *p_mfy_xtal_stop = NULL;
30043010
uint32_t retval;
30053011

30063012
s_xtal_retained = 0;
30073013

3008-
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_WORKER,
3014+
switch (caller_id) {
3015+
case RADIO_TICKER_USER_ID_WORKER:
3016+
p_mfy_xtal_stop = &s_mfy_xtal_stop[0];
3017+
break;
3018+
3019+
case RADIO_TICKER_USER_ID_JOB:
3020+
p_mfy_xtal_stop = &s_mfy_xtal_stop[1];
3021+
break;
3022+
3023+
default:
3024+
LL_ASSERT(0);
3025+
break;
3026+
}
3027+
3028+
retval = mayfly_enqueue(caller_id,
30093029
RADIO_TICKER_USER_ID_WORKER, 0,
3010-
&s_mfy_xtal_stop);
3030+
p_mfy_xtal_stop);
30113031
LL_ASSERT(!retval);
30123032
}
30133033
}
@@ -3073,7 +3093,7 @@ static uint32_t preempt_calc(struct shdr *hdr, uint8_t ticker_id,
30733093

30743094
diff += 3;
30753095
if (diff > TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US)) {
3076-
mayfly_xtal_retain(0);
3096+
mayfly_xtal_retain(RADIO_TICKER_USER_ID_WORKER, 0);
30773097

30783098
prepare_normal_set(hdr, RADIO_TICKER_USER_ID_WORKER, ticker_id);
30793099

@@ -3122,7 +3142,7 @@ static void mayfly_xtal_stop_calc(void *params)
31223142

31233143
if ((ticker_id != 0xff) &&
31243144
(ticks_to_expire < TICKER_US_TO_TICKS(10000))) {
3125-
mayfly_xtal_retain(1);
3145+
mayfly_xtal_retain(RADIO_TICKER_USER_ID_JOB, 1);
31263146

31273147
if (ticker_id >= RADIO_TICKER_ID_ADV) {
31283148
#if SCHED_ADVANCED
@@ -3260,7 +3280,7 @@ static void mayfly_xtal_stop_calc(void *params)
32603280
#endif /* SCHED_ADVANCED */
32613281
}
32623282
} else {
3263-
mayfly_xtal_retain(0);
3283+
mayfly_xtal_retain(RADIO_TICKER_USER_ID_JOB, 0);
32643284

32653285
if ((ticker_id != 0xff) && (ticker_id >= RADIO_TICKER_ID_ADV)) {
32663286
struct shdr *hdr = NULL;
@@ -6836,7 +6856,7 @@ static inline void role_active_disable(uint8_t ticker_id_stop,
68366856
ticker_if_done, (void *)&ticker_status_event);
68376857

68386858
if (ticker_status_event == TICKER_STATUS_BUSY) {
6839-
mayfly_enable(RADIO_TICKER_USER_ID_JOB,
6859+
mayfly_enable(RADIO_TICKER_USER_ID_APP,
68406860
RADIO_TICKER_USER_ID_JOB, 1);
68416861

68426862
LL_ASSERT(ticker_status_event != TICKER_STATUS_BUSY);
@@ -6859,7 +6879,7 @@ static inline void role_active_disable(uint8_t ticker_id_stop,
68596879
(void *)&ticker_status_pre_event);
68606880

68616881
if (ticker_status_pre_event == TICKER_STATUS_BUSY) {
6862-
mayfly_enable(RADIO_TICKER_USER_ID_JOB,
6882+
mayfly_enable(RADIO_TICKER_USER_ID_APP,
68636883
RADIO_TICKER_USER_ID_JOB, 1);
68646884

68656885
LL_ASSERT(ticker_status_event != TICKER_STATUS_BUSY);
@@ -6876,7 +6896,7 @@ static inline void role_active_disable(uint8_t ticker_id_stop,
68766896
* here
68776897
*/
68786898
retval = mayfly_enqueue(
6879-
RADIO_TICKER_USER_ID_JOB,
6899+
RADIO_TICKER_USER_ID_APP,
68806900
RADIO_TICKER_USER_ID_WORKER, 0,
68816901
&s_mfy_radio_inactive);
68826902
LL_ASSERT(!retval);
@@ -6885,7 +6905,7 @@ static inline void role_active_disable(uint8_t ticker_id_stop,
68856905

68866906
/* XTAL started, handle XTAL stop here */
68876907
retval = mayfly_enqueue(
6888-
RADIO_TICKER_USER_ID_JOB,
6908+
RADIO_TICKER_USER_ID_APP,
68896909
RADIO_TICKER_USER_ID_WORKER, 0,
68906910
&s_mfy_xtal_stop);
68916911
LL_ASSERT(!retval);
@@ -6896,13 +6916,13 @@ static inline void role_active_disable(uint8_t ticker_id_stop,
68966916
/* Step 2.1.2: Deassert Radio Active and XTAL start */
68976917

68986918
/* radio active asserted, handle deasserting here */
6899-
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_JOB,
6919+
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_APP,
69006920
RADIO_TICKER_USER_ID_WORKER, 0,
69016921
&s_mfy_radio_inactive);
69026922
LL_ASSERT(!retval);
69036923

69046924
/* XTAL started, handle XTAL stop here */
6905-
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_JOB,
6925+
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_APP,
69066926
RADIO_TICKER_USER_ID_WORKER, 0,
69076927
&s_mfy_xtal_stop);
69086928
LL_ASSERT(!retval);
@@ -6925,7 +6945,7 @@ static inline void role_active_disable(uint8_t ticker_id_stop,
69256945
(void *)&ticker_status_stop);
69266946

69276947
if (ticker_status_stop == TICKER_STATUS_BUSY) {
6928-
mayfly_enable(RADIO_TICKER_USER_ID_JOB,
6948+
mayfly_enable(RADIO_TICKER_USER_ID_APP,
69296949
RADIO_TICKER_USER_ID_JOB, 1);
69306950

69316951
LL_ASSERT(ticker_status_event != TICKER_STATUS_BUSY);
@@ -6944,7 +6964,7 @@ static inline void role_active_disable(uint8_t ticker_id_stop,
69446964
s_mfy_radio_stop.param = (void *)STATE_STOP;
69456965

69466966
/* Stop Radio Tx/Rx */
6947-
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_JOB,
6967+
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_APP,
69486968
RADIO_TICKER_USER_ID_WORKER, 0,
69496969
&s_mfy_radio_stop);
69506970
LL_ASSERT(!retval);
@@ -7017,7 +7037,7 @@ static uint32_t role_disable(uint8_t ticker_id_primary,
70177037
if (ticker_status == TICKER_STATUS_BUSY) {
70187038
/* if inside our event, enable Job. */
70197039
if (_radio.ticker_id_event == ticker_id_primary) {
7020-
mayfly_enable(RADIO_TICKER_USER_ID_JOB,
7040+
mayfly_enable(RADIO_TICKER_USER_ID_APP,
70217041
RADIO_TICKER_USER_ID_JOB, 1);
70227042
}
70237043

0 commit comments

Comments
 (0)