Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 84 additions & 67 deletions subsys/bluetooth/controller/ll_sw/ull_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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 */

Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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) ||
Expand Down Expand Up @@ -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());
Expand All @@ -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) {
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
}

Expand All @@ -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) {
Expand All @@ -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);
}
}

Expand Down
51 changes: 30 additions & 21 deletions subsys/bluetooth/controller/ll_sw/ull_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -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);
}
}

Expand Down
Loading