Skip to content

Commit 4c674aa

Browse files
cvinayakmbolivar-nordic
authored andcommitted
Bluetooth: Controller: Fix instant based procedure complete event
Fix instant based procedure complete event generation to be held until after the on-air instant has elapsed. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent f96b504 commit 4c674aa

File tree

7 files changed

+150
-9
lines changed

7 files changed

+150
-9
lines changed

subsys/bluetooth/controller/Kconfig.ll_sw_split

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,7 @@ config BT_CTLR_LLID_DATA_START_EMPTY
563563

564564
config BT_CTLR_RX_ENQUEUE_HOLD
565565
bool "Procedure Complete after on-air instant"
566+
depends on BT_LL_SW_LLCP_LEGACY
566567
default y if BT_HCI_RAW
567568
help
568569
Hold enqueue of Procedure Complete events with instant until after the

subsys/bluetooth/controller/ll_sw/lll_conn.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ struct lll_conn {
140140
#endif /* CONFIG_BT_CTLR_CONN_RSSI_EVENT */
141141
#endif /* CONFIG_BT_CTLR_CONN_RSSI */
142142

143+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
144+
#define RX_HOLD_MASK 3U
145+
#define RX_HOLD_REQ 1U
146+
#define RX_HOLD_ACK 2U
147+
uint8_t rx_hold_req;
148+
uint8_t rx_hold_ack;
149+
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
150+
143151
#if defined(CONFIG_BT_CTLR_CONN_META)
144152
struct lll_conn_meta conn_meta;
145153
#endif /* CONFIG_BT_CTLR_CONN_META */

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,13 @@ void lll_conn_isr_rx(void *param)
395395

396396
is_ull_rx = 0U;
397397

398+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
399+
if (((lll->rx_hold_req - lll->rx_hold_ack) & RX_HOLD_MASK) ==
400+
RX_HOLD_REQ) {
401+
lll->rx_hold_ack--;
402+
}
403+
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
404+
398405
if (tx_release) {
399406
LL_ASSERT(lll->handle != 0xFFFF);
400407

subsys/bluetooth/controller/ll_sw/ull_adv.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,12 @@ uint8_t ll_adv_enable(uint8_t enable)
10921092
*/
10931093
conn->llcp_terminate.node_rx.hdr.link = link;
10941094

1095+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
1096+
conn->llcp_rx_hold = NULL;
1097+
conn_lll->rx_hold_req = 0U;
1098+
conn_lll->rx_hold_ack = 0U;
1099+
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
1100+
10951101
#if defined(CONFIG_BT_CTLR_LE_ENC)
10961102
conn_lll->enc_rx = conn_lll->enc_tx = 0U;
10971103
conn->llcp_enc.req = conn->llcp_enc.ack = 0U;

subsys/bluetooth/controller/ll_sw/ull_central.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,12 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window,
325325
*/
326326
conn->llcp_terminate.node_rx.hdr.link = link;
327327

328+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
329+
conn->llcp_rx_hold = NULL;
330+
conn_lll->rx_hold_req = 0U;
331+
conn_lll->rx_hold_ack = 0U;
332+
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
333+
328334
#if defined(CONFIG_BT_CTLR_LE_ENC)
329335
conn_lll->enc_rx = conn_lll->enc_tx = 0U;
330336
conn->llcp_enc.req = conn->llcp_enc.ack = 0U;

subsys/bluetooth/controller/ll_sw/ull_conn.c

Lines changed: 118 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@
7373
#include "hal/debug.h"
7474

7575
static int init_reset(void);
76+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
77+
static bool rx_hold_is_done(struct ll_conn *conn);
78+
static void rx_hold_flush(struct ll_conn *conn);
79+
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
7680
#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL)
7781
static void tx_demux_sched(struct ll_conn *conn);
7882
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */
@@ -1010,6 +1014,12 @@ int ull_conn_rx(memq_link_t *link, struct node_rx_pdu **rx)
10101014
return 0;
10111015
}
10121016

1017+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
1018+
if (conn->llcp_rx_hold && rx_hold_is_done(conn)) {
1019+
rx_hold_flush(conn);
1020+
}
1021+
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
1022+
10131023
pdu_rx = (void *)(*rx)->pdu;
10141024

10151025
switch (pdu_rx->ll_id) {
@@ -1379,6 +1389,16 @@ void ull_conn_done(struct node_rx_event_done *done)
13791389
return;
13801390
}
13811391

1392+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
1393+
if (conn->llcp_rx_hold && rx_hold_is_done(conn)) {
1394+
rx_hold_flush(conn);
1395+
1396+
#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL)
1397+
ll_rx_sched();
1398+
#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL */
1399+
}
1400+
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
1401+
13821402
#if defined(CONFIG_BT_CTLR_LE_ENC)
13831403
/* Check authenticated payload expiry or MIC failure */
13841404
switch (done->extra.mic_state) {
@@ -1936,6 +1956,12 @@ void ull_conn_tx_ack(uint16_t handle, memq_link_t *link, struct node_tx *tx)
19361956
if (handle != LLL_HANDLE_INVALID) {
19371957
struct ll_conn *conn = ll_conn_get(handle);
19381958

1959+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
1960+
if (conn->llcp_rx_hold && rx_hold_is_done(conn)) {
1961+
rx_hold_flush(conn);
1962+
}
1963+
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
1964+
19391965
#if defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
19401966
ctrl_tx_ack(conn, &tx, pdu_tx);
19411967
#else /* CONFIG_BT_LL_SW_LLCP_LEGACY */
@@ -1964,6 +1990,14 @@ void ull_conn_tx_ack(uint16_t handle, memq_link_t *link, struct node_tx *tx)
19641990
pdu_tx->ll_id = PDU_DATA_LLID_RESV;
19651991
} else {
19661992
LL_ASSERT(handle != LLL_HANDLE_INVALID);
1993+
1994+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
1995+
struct ll_conn *conn = ll_conn_get(handle);
1996+
1997+
if (conn->llcp_rx_hold && rx_hold_is_done(conn)) {
1998+
rx_hold_flush(conn);
1999+
}
2000+
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
19672001
}
19682002

19692003
ll_tx_ack_put(handle, tx);
@@ -2154,6 +2188,72 @@ static int init_reset(void)
21542188
return 0;
21552189
}
21562190

2191+
#if defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
2192+
static void rx_hold_put(struct ll_conn *conn, memq_link_t *link,
2193+
struct node_rx_pdu *rx)
2194+
{
2195+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
2196+
struct node_rx_pdu *rx_last;
2197+
struct lll_conn *lll;
2198+
2199+
link->mem = NULL;
2200+
rx->hdr.link = link;
2201+
2202+
rx_last = conn->llcp_rx_hold;
2203+
while (rx_last && rx_last->hdr.link && rx_last->hdr.link->mem) {
2204+
rx_last = rx_last->hdr.link->mem;
2205+
}
2206+
2207+
if (rx_last) {
2208+
rx_last->hdr.link->mem = rx;
2209+
} else {
2210+
conn->llcp_rx_hold = rx;
2211+
}
2212+
2213+
lll = &conn->lll;
2214+
if (lll->rx_hold_req == lll->rx_hold_ack) {
2215+
lll->rx_hold_req++;
2216+
}
2217+
2218+
#else /* !CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
2219+
ARG_UNUSED(conn);
2220+
2221+
ll_rx_put(link, rx);
2222+
#endif /* !CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
2223+
}
2224+
2225+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
2226+
static bool rx_hold_is_done(struct ll_conn *conn)
2227+
{
2228+
return ((conn->lll.rx_hold_req -
2229+
conn->lll.rx_hold_ack) & RX_HOLD_MASK) == RX_HOLD_ACK;
2230+
}
2231+
2232+
static void rx_hold_flush(struct ll_conn *conn)
2233+
{
2234+
struct node_rx_pdu *rx;
2235+
struct lll_conn *lll;
2236+
2237+
rx = conn->llcp_rx_hold;
2238+
do {
2239+
struct node_rx_hdr *hdr;
2240+
2241+
/* traverse to next rx node */
2242+
hdr = &rx->hdr;
2243+
rx = hdr->link->mem;
2244+
2245+
/* enqueue rx node towards Thread */
2246+
ll_rx_put(hdr->link, hdr);
2247+
} while (rx);
2248+
2249+
conn->llcp_rx_hold = NULL;
2250+
lll = &conn->lll;
2251+
lll->rx_hold_req = 0U;
2252+
lll->rx_hold_ack = 0U;
2253+
}
2254+
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
2255+
#endif /* CONFIG_BT_LL_SW_LLCP_LEGACY */
2256+
21572257
#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL)
21582258
static void tx_demux_sched(struct ll_conn *conn)
21592259
{
@@ -3121,14 +3221,21 @@ static inline int event_conn_upd_prep(struct ll_conn *conn, uint16_t lazy,
31213221
cu->interval = conn->llcp_cu.interval;
31223222
cu->latency = conn->llcp_cu.latency;
31233223
cu->timeout = conn->llcp_cu.timeout;
3224+
3225+
/* hold node rx until the instant's anchor point sync */
3226+
rx_hold_put(conn, rx->hdr.link, rx);
3227+
3228+
if (!IS_ENABLED(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)) {
3229+
ll_rx_sched();
3230+
}
31243231
} else {
31253232
/* Mark for buffer for release */
31263233
rx->hdr.type = NODE_RX_TYPE_RELEASE;
3127-
}
31283234

3129-
/* enqueue rx node towards Thread */
3130-
ll_rx_put(rx->hdr.link, rx);
3131-
ll_rx_sched();
3235+
/* enqueue rx node towards Thread */
3236+
ll_rx_put(rx->hdr.link, rx);
3237+
ll_rx_sched();
3238+
}
31323239

31333240
#if defined(CONFIG_BT_CTLR_XTAL_ADVANCED)
31343241
/* restore to normal prepare */
@@ -4672,8 +4779,8 @@ static inline void event_phy_upd_ind_prep(struct ll_conn *conn,
46724779
upd->tx = lll->phy_tx;
46734780
upd->rx = lll->phy_rx;
46744781

4675-
/* enqueue rx node towards Thread */
4676-
ll_rx_put(rx->hdr.link, rx);
4782+
/* hold node rx until the instant's anchor point sync */
4783+
rx_hold_put(conn, rx->hdr.link, rx);
46774784

46784785
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
46794786
/* get a rx node for ULL->LL */
@@ -4716,11 +4823,13 @@ static inline void event_phy_upd_ind_prep(struct ll_conn *conn,
47164823
lr->max_rx_time = sys_cpu_to_le16(lll->max_rx_time);
47174824
lr->max_tx_time = sys_cpu_to_le16(lll->max_tx_time);
47184825

4719-
/* enqueue rx node towards Thread */
4720-
ll_rx_put(rx->hdr.link, rx);
4826+
/* hold node rx until the instant's anchor point sync */
4827+
rx_hold_put(conn, rx->hdr.link, rx);
47214828
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
47224829

4723-
ll_rx_sched();
4830+
if (!IS_ENABLED(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)) {
4831+
ll_rx_sched();
4832+
}
47244833
}
47254834
}
47264835
#endif /* CONFIG_BT_CTLR_PHY */

subsys/bluetooth/controller/ll_sw/ull_conn_types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ struct ll_conn {
153153

154154
struct node_rx_pdu *llcp_rx;
155155

156+
#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
157+
struct node_rx_pdu *llcp_rx_hold;
158+
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */
159+
156160
struct {
157161
uint8_t req;
158162
uint8_t ack;

0 commit comments

Comments
 (0)