diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv.c b/subsys/bluetooth/controller/ll_sw/ull_adv.c index d3e9b83ee6123..60bb9b88e1639 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv.c @@ -68,12 +68,13 @@ static uint16_t adv_time_get(struct pdu_adv *pdu, struct pdu_adv *pdu_scan, static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy, uint8_t force, void *param); -static void ticker_op_update_cb(uint32_t status, void *param); +static void ticker_update_op_cb(uint32_t status, void *param); #if defined(CONFIG_BT_PERIPHERAL) static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy, uint8_t force, void *param); -static void ticker_op_stop_cb(uint32_t status, void *param); +static void ticker_stop_op_cb(uint32_t status, void *param); +static void adv_disable(void *param); static void disabled_cb(void *param); static void conn_release(struct ll_adv_set *adv); #endif /* CONFIG_BT_PERIPHERAL */ @@ -82,9 +83,11 @@ static void conn_release(struct ll_adv_set *adv); static void adv_max_events_duration_set(struct ll_adv_set *adv, uint16_t duration, uint8_t max_ext_adv_evts); -static void ticker_op_aux_stop_cb(uint32_t status, void *param); +static void ticker_stop_aux_op_cb(uint32_t status, void *param); +static void aux_disable(void *param); static void aux_disabled_cb(void *param); -static void ticker_op_ext_stop_cb(uint32_t status, void *param); +static void ticker_stop_ext_op_cb(uint32_t status, void *param); +static void ext_disable(void *param); static void ext_disabled_cb(void *param); #endif /* CONFIG_BT_CTLR_ADV_EXT */ @@ -1774,7 +1777,7 @@ static uint32_t ticker_update_rand(struct ll_adv_set *adv, uint32_t ticks_delay_ TICKER_ID_ADV_BASE + ull_adv_handle_get(adv), random_delay, ticks_adjust_minus, 0, 0, 0, 0, - ticker_op_update_cb, adv); + ticker_update_op_cb, adv); LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || (ret == TICKER_STATUS_BUSY)); @@ -1892,12 +1895,12 @@ void ull_adv_done(struct node_rx_event_done *done) ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH, (TICKER_ID_ADV_AUX_BASE + aux_handle), - ticker_op_aux_stop_cb, adv); + ticker_stop_aux_op_cb, adv); } else { ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH, (TICKER_ID_ADV_BASE + handle), - ticker_op_ext_stop_cb, adv); + ticker_stop_ext_op_cb, adv); } LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || @@ -2168,7 +2171,7 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t laz DEBUG_RADIO_PREPARE_A(1); } -static void ticker_op_update_cb(uint32_t status, void *param) +static void ticker_update_op_cb(uint32_t status, void *param) { LL_ASSERT(status == TICKER_STATUS_SUCCESS || param == ull_disable_mark_get()); @@ -2187,17 +2190,16 @@ static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t remainder, ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH, TICKER_ID_ADV_BASE + handle, - ticker_op_stop_cb, adv); + ticker_stop_op_cb, adv); LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || (ret == TICKER_STATUS_BUSY)); } -static void ticker_op_stop_cb(uint32_t status, void *param) +static void ticker_stop_op_cb(uint32_t status, void *param) { static memq_link_t link; - static struct mayfly mfy = {0, 0, &link, NULL, NULL}; - struct ll_adv_set *adv; - struct ull_hdr *hdr; + static struct mayfly mfy = {0, 0, &link, NULL, adv_disable}; + uint32_t ret; /* Ignore if race between thread and ULL */ if (status != TICKER_STATUS_SUCCESS) { @@ -2213,33 +2215,42 @@ static void ticker_op_stop_cb(uint32_t status, void *param) } #endif /* CONFIG_BT_HCI_MESH_EXT */ - /* NOTE: We are in ULL_LOW which can be pre-empted by ULL_HIGH. - * As we are in the callback after successful stop of the - * ticker, the ULL reference count will not be modified - * further hence it is safe to check and act on either the need - * to call lll_disable or not. - */ + /* Check if any pending LLL events that need to be aborted */ + mfy.param = param; + ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, + TICKER_USER_ID_ULL_HIGH, 0, &mfy); + LL_ASSERT(!ret); +} + +static void adv_disable(void *param) +{ + struct ll_adv_set *adv; + struct ull_hdr *hdr; + + /* Check ref count to determine if any pending LLL events in pipeline */ adv = param; hdr = &adv->ull; - mfy.param = &adv->lll; if (ull_ref_get(hdr)) { + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, NULL, lll_disable}; uint32_t ret; + mfy.param = &adv->lll; + + /* Setup disabled callback to be called when ref count + * returns to zero. + */ LL_ASSERT(!hdr->disabled_cb); hdr->disabled_param = mfy.param; hdr->disabled_cb = disabled_cb; - mfy.fp = lll_disable; - ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, + /* Trigger LLL disable */ + ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_LLL, 0, &mfy); LL_ASSERT(!ret); } else { - uint32_t ret; - - mfy.fp = disabled_cb; - ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, - TICKER_USER_ID_ULL_HIGH, 0, &mfy); - LL_ASSERT(!ret); + /* No pending LLL events */ + disabled_cb(&adv->lll); } } @@ -2324,22 +2335,28 @@ static void adv_max_events_duration_set(struct ll_adv_set *adv, HAL_TICKER_US_TO_TICKS((uint64_t)duration * 10 * USEC_PER_MSEC); } -static void ticker_op_aux_stop_cb(uint32_t status, void *param) +static void ticker_stop_aux_op_cb(uint32_t status, void *param) +{ + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, NULL, aux_disable}; + uint32_t ret; + + LL_ASSERT(status == TICKER_STATUS_SUCCESS); + + /* Check if any pending LLL events that need to be aborted */ + mfy.param = param; + ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, + TICKER_USER_ID_ULL_HIGH, 0, &mfy); + LL_ASSERT(!ret); +} + +static void aux_disable(void *param) { struct lll_adv_aux *lll_aux; struct ll_adv_aux_set *aux; struct ll_adv_set *adv; struct ull_hdr *hdr; - uint32_t ret; - - LL_ASSERT(status == TICKER_STATUS_SUCCESS); - /* NOTE: We are in ULL_LOW which can be pre-empted by ULL_HIGH. - * As we are in the callback after successful stop of the - * ticker, the ULL reference count will not be modified - * further hence it is safe to check and act on either the need - * to call lll_disable or not. - */ adv = param; lll_aux = adv->lll.aux; aux = HDR_LLL2ULL(lll_aux); @@ -2349,15 +2366,7 @@ static void ticker_op_aux_stop_cb(uint32_t status, void *param) hdr->disabled_param = adv; hdr->disabled_cb = aux_disabled_cb; } else { - uint8_t handle; - - handle = ull_adv_handle_get(adv); - ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, - TICKER_USER_ID_ULL_LOW, - (TICKER_ID_ADV_BASE + handle), - ticker_op_ext_stop_cb, adv); - LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || - (ret == TICKER_STATUS_BUSY)); + aux_disabled_cb(param); } } @@ -2370,17 +2379,16 @@ static void aux_disabled_cb(void *param) ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH, (TICKER_ID_ADV_BASE + handle), - ticker_op_ext_stop_cb, param); + ticker_stop_ext_op_cb, param); LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || (ret == TICKER_STATUS_BUSY)); } -static void ticker_op_ext_stop_cb(uint32_t status, void *param) +static void ticker_stop_ext_op_cb(uint32_t status, void *param) { static memq_link_t link; - static struct mayfly mfy = {0, 0, &link, NULL, NULL}; - struct ll_adv_set *adv; - struct ull_hdr *hdr; + static struct mayfly mfy = {0, 0, &link, NULL, ext_disable}; + uint32_t ret; /* Ignore if race between thread and ULL */ if (status != TICKER_STATUS_SUCCESS) { @@ -2389,33 +2397,42 @@ static void ticker_op_ext_stop_cb(uint32_t status, void *param) return; } - /* NOTE: We are in ULL_LOW which can be pre-empted by ULL_HIGH. - * As we are in the callback after successful stop of the - * ticker, the ULL reference count will not be modified - * further hence it is safe to check and act on either the need - * to call lll_disable or not. - */ + /* Check if any pending LLL events that need to be aborted */ + mfy.param = param; + ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, + TICKER_USER_ID_ULL_HIGH, 0, &mfy); + LL_ASSERT(!ret); +} + +static void ext_disable(void *param) +{ + struct ll_adv_set *adv; + struct ull_hdr *hdr; + + /* Check ref count to determine if any pending LLL events in pipeline */ adv = param; hdr = &adv->ull; - mfy.param = &adv->lll; if (ull_ref_get(hdr)) { + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, NULL, lll_disable}; uint32_t ret; + mfy.param = &adv->lll; + + /* Setup disabled callback to be called when ref count + * returns to zero. + */ LL_ASSERT(!hdr->disabled_cb); hdr->disabled_param = mfy.param; hdr->disabled_cb = ext_disabled_cb; - mfy.fp = lll_disable; - ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, + /* Trigger LLL disable */ + ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_LLL, 0, &mfy); LL_ASSERT(!ret); } else { - uint32_t ret; - - mfy.fp = ext_disabled_cb; - ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, - TICKER_USER_ID_ULL_HIGH, 0, &mfy); - LL_ASSERT(!ret); + /* No pending LLL events */ + ext_disabled_cb(&adv->lll); } } diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 36a76ee58945f..6d18f01d3fb46 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -83,7 +83,8 @@ static inline void disable(uint16_t handle); static void conn_cleanup(struct ll_conn *conn, uint8_t reason); static void conn_cleanup_finalize(struct ll_conn *conn); static void tx_ull_flush(struct ll_conn *conn); -static void ticker_op_stop_cb(uint32_t status, void *param); +static void ticker_stop_op_cb(uint32_t status, void *param); +static void conn_disable(void *param); static void disabled_cb(void *param); static void tx_lll_flush(void *param); @@ -1974,7 +1975,7 @@ static void conn_cleanup_finalize(struct ll_conn *conn) ticker_status = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH, TICKER_ID_CONN_BASE + lll->handle, - ticker_op_stop_cb, conn); + ticker_stop_op_cb, conn); LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) || (ticker_status == TICKER_STATUS_BUSY)); @@ -2036,42 +2037,50 @@ static void tx_ull_flush(struct ll_conn *conn) } } -static void ticker_op_stop_cb(uint32_t status, void *param) +static void ticker_stop_op_cb(uint32_t status, void *param) { static memq_link_t link; - static struct mayfly mfy = {0, 0, &link, NULL, NULL}; - struct ll_conn *conn; - struct ull_hdr *hdr; + static struct mayfly mfy = {0, 0, &link, NULL, conn_disable}; + uint32_t ret; LL_ASSERT(status == TICKER_STATUS_SUCCESS); - /* NOTE: We are in ULL_LOW which can be pre-empted by ULL_HIGH. - * As we are in the callback after successful stop of the - * ticker, the ULL reference count will not be modified - * further hence it is safe to check and act on either the need - * to call lll_disable or not. - */ + /* Check if any pending LLL events that need to be aborted */ + mfy.param = param; + ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, + TICKER_USER_ID_ULL_HIGH, 0, &mfy); + LL_ASSERT(!ret); +} + +static void conn_disable(void *param) +{ + struct ll_conn *conn; + struct ull_hdr *hdr; + + /* Check ref count to determine if any pending LLL events in pipeline */ conn = param; hdr = &conn->ull; - mfy.param = &conn->lll; if (ull_ref_get(hdr)) { + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, NULL, lll_disable}; uint32_t ret; + mfy.param = &conn->lll; + + /* Setup disabled callback to be called when ref count + * returns to zero. + */ LL_ASSERT(!hdr->disabled_cb); hdr->disabled_param = mfy.param; hdr->disabled_cb = disabled_cb; - mfy.fp = lll_disable; - ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, + /* Trigger LLL disable */ + ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_LLL, 0, &mfy); LL_ASSERT(!ret); } else { - uint32_t ret; - - mfy.fp = disabled_cb; - ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, - TICKER_USER_ID_ULL_HIGH, 0, &mfy); - LL_ASSERT(!ret); + /* No pending LLL events */ + disabled_cb(&conn->lll); } } diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c index a196d894dc353..3647d1b137c6c 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c @@ -395,7 +395,7 @@ void ull_conn_iso_resume_ticker_start(struct lll_event *resume_event, (ret == TICKER_STATUS_BUSY)); } -static void disabled_cig_cb(void *param) +static void cig_disabled_cb(void *param) { struct ll_conn_iso_group *cig; @@ -427,7 +427,7 @@ static void ticker_stop_op_cb(uint32_t status, void *param) */ LL_ASSERT(!hdr->disabled_cb); hdr->disabled_param = mfy.param; - hdr->disabled_cb = disabled_cig_cb; + hdr->disabled_cb = cig_disabled_cb; mfy.fp = lll_disable; ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, @@ -435,14 +435,14 @@ static void ticker_stop_op_cb(uint32_t status, void *param) LL_ASSERT(!ret); } else { /* Disable now */ - mfy.fp = disabled_cig_cb; + mfy.fp = cig_disabled_cb; ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, TICKER_USER_ID_ULL_HIGH, 0, &mfy); LL_ASSERT(!ret); } } -static void disabled_cis_cb(void *param) +static void cis_disabled_cb(void *param) { struct ll_conn_iso_group *cig; struct ll_conn_iso_stream *cis; @@ -527,20 +527,20 @@ void ull_conn_iso_cis_stop(struct ll_conn_iso_stream *cis, * continue CIS teardown from there. The disabled_cb cannot be * reserved for other use. */ - LL_ASSERT(!hdr->disabled_cb || hdr->disabled_cb == disabled_cis_cb); + LL_ASSERT(!hdr->disabled_cb || hdr->disabled_cb == cis_disabled_cb); hdr->disabled_param = cig; - hdr->disabled_cb = disabled_cis_cb; + hdr->disabled_cb = cis_disabled_cb; } else { static memq_link_t link; static struct mayfly mfy = {0, 0, &link, NULL, NULL}; /* Tear down CIS now in ULL_HIGH context. Ignore enqueue * error (already enqueued) as all CISes marked for teardown - * will be handled in disabled_cis_cb. Use mayfly chaining to + * will be handled in cis_disabled_cb. Use mayfly chaining to * prevent recursive stop calls. */ - mfy.fp = disabled_cis_cb; + mfy.fp = cis_disabled_cb; mfy.param = cig; mayfly_enqueue(TICKER_USER_ID_ULL_LOW, TICKER_USER_ID_ULL_HIGH, 1, &mfy); diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan.c b/subsys/bluetooth/controller/ll_sw/ull_scan.c index 1166b3330ca04..4436277fe99ad 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan.c @@ -63,7 +63,8 @@ static uint8_t duration_period_setup(struct ll_scan_set *scan, struct node_rx_pdu **node_rx_scan_term); static uint8_t duration_period_update(struct ll_scan_set *scan, uint8_t is_update); -static void ticker_op_ext_stop_cb(uint32_t status, void *param); +static void ticker_stop_ext_op_cb(uint32_t status, void *param); +static void ext_disable(void *param); static void ext_disabled_cb(void *param); #endif /* CONFIG_BT_CTLR_ADV_EXT */ @@ -515,7 +516,7 @@ void ull_scan_done(struct node_rx_event_done *done) rx_hdr->handle = handle; ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH, - (TICKER_ID_SCAN_BASE + handle), ticker_op_ext_stop_cb, + (TICKER_ID_SCAN_BASE + handle), ticker_stop_ext_op_cb, scan); LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || @@ -837,12 +838,11 @@ static uint8_t duration_period_update(struct ll_scan_set *scan, return 0; } -static void ticker_op_ext_stop_cb(uint32_t status, void *param) +static void ticker_stop_ext_op_cb(uint32_t status, void *param) { static memq_link_t link; - static struct mayfly mfy = {0, 0, &link, NULL, NULL}; - struct ll_scan_set *scan; - struct ull_hdr *hdr; + static struct mayfly mfy = {0, 0, &link, NULL, ext_disable}; + uint32_t ret; /* Ignore if race between thread and ULL */ if (status != TICKER_STATUS_SUCCESS) { @@ -851,34 +851,42 @@ static void ticker_op_ext_stop_cb(uint32_t status, void *param) return; } - /* NOTE: We are in ULL_LOW which can be pre-empted by ULL_HIGH. - * As we are in the callback after successful stop of the - * ticker, the ULL reference count will not be modified - * further hence it is safe to check and act on either the need - * to call lll_disable or not. - */ + /* Check if any pending LLL events that need to be aborted */ + mfy.param = param; + ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, + TICKER_USER_ID_ULL_HIGH, 0, &mfy); + LL_ASSERT(!ret); +} + +static void ext_disable(void *param) +{ + struct ll_scan_set *scan; + struct ull_hdr *hdr; + + /* Check ref count to determine if any pending LLL events in pipeline */ scan = param; hdr = &scan->ull; - mfy.param = &scan->lll; if (ull_ref_get(hdr)) { + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, NULL, lll_disable}; uint32_t ret; - LL_ASSERT(!hdr->disabled_cb); + mfy.param = &scan->lll; + /* Setup disabled callback to be called when ref count + * returns to zero. + */ + LL_ASSERT(!hdr->disabled_cb); hdr->disabled_param = mfy.param; hdr->disabled_cb = ext_disabled_cb; - mfy.fp = lll_disable; - ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, + /* Trigger LLL disable */ + ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_LLL, 0, &mfy); LL_ASSERT(!ret); } else { - uint32_t ret; - - mfy.fp = ext_disabled_cb; - ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, - TICKER_USER_ID_ULL_HIGH, 0, &mfy); - LL_ASSERT(!ret); + /* No pending LLL events */ + ext_disabled_cb(&scan->lll); } }