Skip to content

Commit a6b8eba

Browse files
cvinayakcarlescufi
authored andcommitted
Bluetooth: controller: Implement disabling the other PHY initiator
When connection is initiated in one of either 1M or Coded PHY initiating scan instance then the other scanning instance's scheduling and memory allocation needs to be cleaned up. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 9eb5f85 commit a6b8eba

File tree

6 files changed

+152
-30
lines changed

6 files changed

+152
-30
lines changed

subsys/bluetooth/controller/ll_sw/lll_scan.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ struct lll_scan {
2424
uint8_t filter_policy:2;
2525
uint8_t type:1;
2626
uint8_t init_addr_type:1;
27-
#if defined(CONFIG_BT_CENTRAL)
28-
uint8_t adv_addr_type:1;
29-
#endif /* CONFIG_BT_CENTRAL */
27+
uint8_t is_stop:1;
3028

3129
#if defined(CONFIG_BT_CTLR_ADV_EXT)
3230
uint16_t duration_reload;
@@ -35,6 +33,10 @@ struct lll_scan {
3533
uint8_t is_adv_ind:1;
3634
#endif /* CONFIG_BT_CTLR_ADV_EXT */
3735

36+
#if defined(CONFIG_BT_CENTRAL)
37+
uint8_t adv_addr_type:1;
38+
#endif /* CONFIG_BT_CENTRAL */
39+
3840
#if defined(CONFIG_BT_CTLR_PRIVACY)
3941
uint8_t rpa_gen:1;
4042
/* initiator only */

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,10 @@ static int prepare_cb(struct lll_prepare_param *p)
217217
/* Check if stopped (on connection establishment race between LLL and
218218
* ULL.
219219
*/
220-
if (unlikely(lll->conn &&
221-
(lll->conn->master.initiated ||
222-
lll->conn->master.cancelled))) {
220+
if (unlikely(lll->is_stop ||
221+
(lll->conn &&
222+
(lll->conn->master.initiated ||
223+
lll->conn->master.cancelled)))) {
223224
radio_isr_set(lll_isr_early_abort, lll);
224225
radio_disable();
225226

@@ -960,8 +961,14 @@ static inline int isr_rx_pdu(struct lll_scan *lll, struct pdu_adv *pdu_adv_rx,
960961
* radio_status_reset();
961962
*/
962963

963-
/* Stop further LLL radio events */
964-
lll->conn->master.initiated = 1;
964+
/* Stop further connection initiation */
965+
/* FIXME: for extended connection initiation, handle reset on
966+
* event aborted before connect_rsp is received.
967+
*/
968+
lll->conn->master.initiated = 1U;
969+
970+
/* Stop further initiating events */
971+
lll->is_stop = 1U;
965972

966973
rx = ull_pdu_rx_alloc();
967974

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

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,32 @@ static int prepare_cb(struct lll_prepare_param *p)
124124

125125
DEBUG_RADIO_START_O(1);
126126

127+
lll = p->param;
128+
aux_set = HDR_LLL2ULL(lll);
129+
scan_set = HDR_LLL2ULL(aux_set->rx_head->rx_ftr.param);
130+
lll_scan = &scan_set->lll;
131+
132+
#if defined(CONFIG_BT_CENTRAL)
133+
/* Check if stopped (on connection establishment race between LLL and
134+
* ULL.
135+
*/
136+
if (unlikely(lll_scan->is_stop ||
137+
(lll_scan->conn &&
138+
(lll_scan->conn->master.initiated ||
139+
lll_scan->conn->master.cancelled)))) {
140+
radio_isr_set(lll_isr_early_abort, lll);
141+
radio_disable();
142+
143+
return 0;
144+
}
145+
#endif /* CONFIG_BT_CENTRAL */
146+
127147
/* Start setting up Radio h/w */
128148
radio_reset();
129149

130150
/* Reset Tx/rx count */
131151
trx_cnt = 0U;
132152

133-
lll = p->param;
134-
aux_set = HDR_LLL2ULL(lll);
135-
scan_set = HDR_LLL2ULL(aux_set->rx_head->rx_ftr.param);
136-
lll_scan = &scan_set->lll;
137-
138153
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
139154
radio_tx_power_set(lll->tx_pwr_lvl);
140155
#else
@@ -371,7 +386,7 @@ static int isr_rx_pdu(struct lll_scan_aux *lll, uint8_t devmatch_ok,
371386
if (0) {
372387
#if defined(CONFIG_BT_CENTRAL)
373388
/* Initiator */
374-
} else if (lll_scan->conn &&
389+
} else if (lll_scan->conn && !lll_scan->conn->master.cancelled &&
375390
(pdu->adv_ext_ind.adv_mode & BT_HCI_LE_ADV_PROP_CONN) &&
376391
isr_scan_init_check(lll_scan, pdu, rl_idx)) {
377392
struct node_rx_ftr *ftr;
@@ -493,6 +508,12 @@ static int isr_rx_pdu(struct lll_scan_aux *lll, uint8_t devmatch_ok,
493508
* radio_status_reset();
494509
*/
495510

511+
/* Stop further connection initiation */
512+
lll_scan->conn->master.initiated = 1U;
513+
514+
/* Stop further initiating events */
515+
lll_scan->is_stop = 1U;
516+
496517
rx = ull_pdu_rx_alloc();
497518

498519
rx->hdr.type = NODE_RX_TYPE_CONNECTION;
@@ -657,6 +678,12 @@ static void isr_rx_connect_rsp(void *param)
657678
if (!trx_done) {
658679
struct node_rx_ftr *ftr;
659680

681+
/* Try again with connection initiation */
682+
lll->conn->master.initiated = 0U;
683+
684+
/* Dont stop initiating events on primary channels */
685+
lll->is_stop = 0U;
686+
660687
ftr = &(rx->hdr.rx_ftr);
661688

662689
rx->hdr.type = NODE_RX_TYPE_RELEASE;
@@ -667,9 +694,6 @@ static void isr_rx_connect_rsp(void *param)
667694
goto isr_rx_do_close;
668695
}
669696

670-
/* Stop further LLL radio events */
671-
lll->conn->master.initiated = 1;
672-
673697
#if defined(CONFIG_BT_CTLR_PHY)
674698
lll->conn->phy_tx = lll_aux->phy;
675699
lll->conn->phy_tx_time = lll_aux->phy;

subsys/bluetooth/controller/ll_sw/ull.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,12 +961,32 @@ void ll_rx_dequeue(void)
961961
ARG_UNUSED(cc);
962962
#endif /* !CONFIG_BT_PERIPHERAL */
963963

964-
} else if (IS_ENABLED(CONFIG_BT_CENTRAL)) {
964+
#if defined(CONFIG_BT_CENTRAL)
965+
} else {
965966
struct ll_scan_set *scan = HDR_LLL2ULL(ftr->param);
966967

968+
#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_CTLR_PHY_CODED)
969+
struct ll_scan_set *scan_other =
970+
ull_scan_is_enabled_get(SCAN_HANDLE_PHY_CODED);
971+
972+
if (scan_other) {
973+
if (scan_other == scan) {
974+
scan_other = ull_scan_is_enabled_get(SCAN_HANDLE_1M);
975+
}
976+
977+
if (scan_other) {
978+
scan_other->lll.conn = NULL;
979+
scan_other->is_enabled = 0U;
980+
}
981+
}
982+
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_CTLR_PHY_CODED */
983+
984+
scan->lll.conn = NULL;
967985
scan->is_enabled = 0U;
986+
#else /* !CONFIG_BT_CENTRAL */
968987
} else {
969988
LL_ASSERT(0);
989+
#endif /* !CONFIG_BT_CENTRAL */
970990
}
971991

972992
if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {

subsys/bluetooth/controller/ll_sw/ull_master.c

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
#include "hal/debug.h"
5656

5757
static void ticker_op_stop_scan_cb(uint32_t status, void *param);
58+
#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_CTLR_PHY_CODED)
59+
static void ticker_op_stop_scan_other_cb(uint32_t status, void *param);
60+
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_CTLR_PHY_CODED */
5861
static void ticker_op_cb(uint32_t status, void *param);
5962
static inline void conn_release(struct ll_scan_set *scan);
6063

@@ -669,28 +672,28 @@ void ull_master_setup(memq_link_t *link, struct node_rx_hdr *rx,
669672
uint8_t ticker_id_scan, ticker_id_conn;
670673
uint8_t peer_addr[BDADDR_SIZE];
671674
uint32_t ticks_slot_overhead;
672-
struct ll_scan_set *scan;
673675
uint32_t ticks_slot_offset;
676+
struct ll_scan_set *scan;
674677
struct pdu_adv *pdu_tx;
675-
struct node_rx_cc *cc;
676-
struct ll_conn *conn;
677678
uint8_t peer_addr_type;
678679
uint32_t ticker_status;
680+
struct node_rx_cc *cc;
681+
struct ll_conn *conn;
679682
uint8_t chan_sel;
680683

681-
((struct lll_scan *)ftr->param)->conn = NULL;
682-
683-
scan = ((struct lll_scan *)ftr->param)->hdr.parent;
684-
conn = lll->hdr.parent;
685-
684+
/* Get reference to Tx-ed CONNECT_IND PDU */
686685
pdu_tx = (void *)((struct node_rx_pdu *)rx)->pdu;
687686

687+
/* Backup peer addr and type, as we reuse the Tx-ed PDU to generate
688+
* event towards LL
689+
*/
688690
peer_addr_type = pdu_tx->rx_addr;
689691
memcpy(peer_addr, &pdu_tx->connect_ind.adv_addr[0], BDADDR_SIZE);
690692

691693
/* This is the chan sel bit from the received adv pdu */
692694
chan_sel = pdu_tx->chan_sel;
693695

696+
/* Populate the fields required for connection complete event */
694697
cc = (void *)pdu_tx;
695698
cc->status = 0U;
696699
cc->role = 0U;
@@ -723,11 +726,14 @@ void ull_master_setup(memq_link_t *link, struct node_rx_hdr *rx,
723726
memcpy(cc->peer_addr, &peer_addr[0], BDADDR_SIZE);
724727
}
725728

729+
scan = HDR_LLL2ULL(ftr->param);
730+
726731
cc->interval = lll->interval;
727732
cc->latency = lll->latency;
728733
cc->timeout = scan->lll.conn_timeout;
729734
cc->sca = lll_clock_sca_local_get();
730735

736+
conn = lll->hdr.parent;
731737
lll->handle = ll_conn_handle_get(conn);
732738
rx->handle = lll->handle;
733739

@@ -804,8 +810,34 @@ void ull_master_setup(memq_link_t *link, struct node_rx_hdr *rx,
804810
ticker_status = ticker_stop(TICKER_INSTANCE_ID_CTLR,
805811
TICKER_USER_ID_ULL_HIGH,
806812
ticker_id_scan, ticker_op_stop_scan_cb,
807-
(void *)(uint32_t)ticker_id_scan);
808-
ticker_op_stop_scan_cb(ticker_status, (void *)(uint32_t)ticker_id_scan);
813+
scan);
814+
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
815+
(ticker_status == TICKER_STATUS_BUSY));
816+
817+
#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_CTLR_PHY_CODED)
818+
/* Determine if coded PHY was also enabled, if so, reset the assigned
819+
* connection context.
820+
*/
821+
struct ll_scan_set *scan_other =
822+
ull_scan_is_enabled_get(SCAN_HANDLE_PHY_CODED);
823+
if (scan_other) {
824+
if (scan_other == scan) {
825+
scan_other = ull_scan_is_enabled_get(SCAN_HANDLE_1M);
826+
}
827+
828+
if (scan_other) {
829+
ticker_id_scan = TICKER_ID_SCAN_BASE +
830+
ull_scan_handle_get(scan_other);
831+
ticker_status = ticker_stop(TICKER_INSTANCE_ID_CTLR,
832+
TICKER_USER_ID_ULL_HIGH,
833+
ticker_id_scan,
834+
ticker_op_stop_scan_other_cb,
835+
scan_other);
836+
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
837+
(ticker_status == TICKER_STATUS_BUSY));
838+
}
839+
}
840+
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_CTLR_PHY_CODED */
809841

810842
/* Scanner stop can expire while here in this ISR.
811843
* Deferred attempt to stop can fail as it would have
@@ -912,9 +944,45 @@ void ull_master_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t
912944

913945
static void ticker_op_stop_scan_cb(uint32_t status, void *param)
914946
{
915-
/* TODO: */
947+
/* NOTE: Nothing to do here, present here to add debug code if required
948+
*/
916949
}
917950

951+
#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_CTLR_PHY_CODED)
952+
static void ticker_op_stop_scan_other_cb(uint32_t status, void *param)
953+
{
954+
static memq_link_t link;
955+
static struct mayfly mfy = {0, 0, &link, NULL, NULL};
956+
struct ll_scan_set *scan;
957+
struct ull_hdr *hdr;
958+
959+
/* Ignore if race between thread and ULL */
960+
if (status != TICKER_STATUS_SUCCESS) {
961+
/* TODO: detect race */
962+
963+
return;
964+
}
965+
966+
/* NOTE: We are in ULL_LOW which can be pre-empted by ULL_HIGH.
967+
* As we are in the callback after successful stop of the
968+
* ticker, the ULL reference count will not be modified
969+
* further hence it is safe to check and act on either the need
970+
* to call lll_disable or not.
971+
*/
972+
scan = param;
973+
hdr = &scan->ull;
974+
mfy.param = &scan->lll;
975+
if (ull_ref_get(hdr)) {
976+
uint32_t ret;
977+
978+
mfy.fp = lll_disable;
979+
ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW,
980+
TICKER_USER_ID_LLL, 0, &mfy);
981+
LL_ASSERT(!ret);
982+
}
983+
}
984+
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_CTLR_PHY_CODED */
985+
918986
static void ticker_op_cb(uint32_t status, void *param)
919987
{
920988
ARG_UNUSED(param);

subsys/bluetooth/controller/ll_sw/ull_scan.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,10 @@ uint8_t ull_scan_enable(struct ll_scan_set *scan)
358358
uint32_t ticks_anchor;
359359
uint32_t ret;
360360

361-
lll->chan = 0;
362361
lll->init_addr_type = scan->own_addr_type;
363362
ll_addr_get(lll->init_addr_type, lll->init_addr);
363+
lll->chan = 0U;
364+
lll->is_stop = 0U;
364365

365366
ull_hdr_init(&scan->ull);
366367
lll_hdr_init(lll, scan);

0 commit comments

Comments
 (0)