Skip to content

Commit c334ed5

Browse files
cvinayakcarlescufi
authored andcommitted
Bluetooth: Controller: Fix multiple Extended Adv chain reception
Fix assertion when enabling simultaneous multiple Extended Advertising chain reception that is enabled by increasing supported auxiliary scan contexts. ULL sets the association of aux context to scan and sync context, and LLL resets the association; this is safer compared to earlier implementation where ULL did both the association and reset which caused aux context memory leak. Supported auxiliary scan contexts can be increased using CONFIG_BT_CTLR_SCAN_AUX_SET value. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 29b78ab commit c334ed5

File tree

4 files changed

+37
-18
lines changed

4 files changed

+37
-18
lines changed

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,6 +1549,11 @@ static int isr_rx_scan_report(struct lll_scan *lll, uint8_t devmatch_ok,
15491549
{
15501550
struct node_rx_ftr *ftr;
15511551

1552+
/* Reset Scan context association with any Aux context as a new
1553+
* extended advertising chain is being setup for reception here.
1554+
*/
1555+
lll->lll_aux = NULL;
1556+
15521557
ftr = &(node_rx->rx_ftr);
15531558
ftr->param = lll;
15541559
ftr->ticks_anchor = radio_tmr_start_get();

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,17 +1241,32 @@ static int isr_rx_pdu(struct lll_scan *lll, struct lll_scan_aux *lll_aux,
12411241

12421242
ftr = &(node_rx->rx_ftr);
12431243
if (lll_aux) {
1244+
/* Auxiliary context was used in ULL scheduling in the
1245+
* reception of this current PDU.
1246+
*/
12441247
ftr->param = lll_aux;
12451248
ftr->scan_rsp = lll_aux->state;
12461249

12471250
/* Further auxiliary PDU reception will be chain PDUs */
12481251
lll_aux->is_chain_sched = 1U;
1252+
1253+
/* Reset auxiliary context association with scan context
1254+
* as ULL scheduling has been used and may switch to
1255+
* using LLL scheduling if the next auxiliary PDU in
1256+
* chain is below the threshold to use ULL scheduling.
1257+
*/
1258+
lll->lll_aux = NULL;
1259+
12491260
} else if (lll->lll_aux) {
1261+
/* Auxiliary context was allocated to Scan context in
1262+
* LLL scheduling in the reception of this current PDU.
1263+
*/
12501264
ftr->param = lll;
12511265
ftr->scan_rsp = lll->lll_aux->state;
12521266

12531267
/* Further auxiliary PDU reception will be chain PDUs */
12541268
lll->lll_aux->is_chain_sched = 1U;
1269+
12551270
} else {
12561271
/* Return -ECHILD, as ULL execution has not yet assigned
12571272
* an aux context. This can happen only under LLL

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,11 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok,
805805
* again a node_rx for periodic report incomplete.
806806
*/
807807
if (node_type != NODE_RX_TYPE_EXT_AUX_REPORT) {
808+
/* Reset Sync context association with any Aux context
809+
* as a new chain is being setup for reception here.
810+
*/
811+
lll->lll_aux = NULL;
812+
808813
node_rx = ull_pdu_rx_alloc_peek(4);
809814
} else {
810815
node_rx = ull_pdu_rx_alloc_peek(3);

subsys/bluetooth/controller/ll_sw/ull_scan_aux.c

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,9 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
645645
*/
646646
if (ftr->aux_lll_sched) {
647647
if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && sync_lll) {
648+
/* Associate Sync context with the Aux context so that
649+
* it can continue reception in LLL scheduling.
650+
*/
648651
sync_lll->lll_aux = lll_aux;
649652

650653
/* AUX_ADV_IND/AUX_CHAIN_IND PDU reception is being
@@ -661,8 +664,8 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
661664
*/
662665
LL_ASSERT(!lll->lll_aux || (lll->lll_aux == lll_aux));
663666

664-
/* scan context get the aux context so that it can
665-
* continue reception in LLL scheduling.
667+
/* Associate Scan context with the Aux context so that
668+
* it can continue reception in LLL scheduling.
666669
*/
667670
lll->lll_aux = lll_aux;
668671

@@ -688,11 +691,6 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
688691
if (unlikely(scan->is_stop)) {
689692
goto ull_scan_aux_rx_flush;
690693
}
691-
692-
/* Remove auxiliary context association with scan context so
693-
* that LLL can differentiate it to being ULL scheduling.
694-
*/
695-
lll->lll_aux = NULL;
696694
} else {
697695
struct ll_sync_set *sync_set;
698696

@@ -705,7 +703,13 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
705703
goto ull_scan_aux_rx_flush;
706704
}
707705

708-
/* Associate the auxiliary context with sync context */
706+
/* Associate the auxiliary context with sync context, we do this
707+
* for ULL scheduling also in constrast to how extended
708+
* advertising only associates when LLL scheduling is used.
709+
* Each Periodic Advertising chain is received by unique sync
710+
* context, hence LLL and ULL scheduling is always associated
711+
* with same unique sync context.
712+
*/
709713
sync_lll->lll_aux = lll_aux;
710714

711715
/* Backup the node rx to be dispatch on successfully ULL
@@ -1280,19 +1284,9 @@ static void flush(void *param)
12801284
scan = HDR_LLL2ULL(lll);
12811285
scan = ull_scan_is_valid_get(scan);
12821286
if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) || scan) {
1283-
lll->lll_aux = NULL;
12841287
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
12851288
lll->scan_aux_score = aux->lll.hdr.score;
12861289
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
1287-
} else {
1288-
struct lll_sync *sync_lll;
1289-
struct ll_sync_set *sync;
1290-
1291-
sync_lll = aux->parent;
1292-
sync = HDR_LLL2ULL(sync_lll);
1293-
1294-
LL_ASSERT(sync->is_stop || sync_lll->lll_aux);
1295-
sync_lll->lll_aux = NULL;
12961290
}
12971291

12981292
aux_release(aux);

0 commit comments

Comments
 (0)