From 6b1cfdda33c2a50a1e04fd0feea27c51eb3e62b1 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sun, 6 Sep 2020 07:16:29 +0530 Subject: [PATCH] Bluetooth: controller: Fix premature connection event close Fix premature connection event close due to the new Tx buffers not being de-multiplexed and routed to connection's Lower Link Layer context when they arrive while being inside the connection's radio event. Also, fix master prepare to demux and enqueue two Tx buffers so that MD bit can be set correctly. Relates to #27981. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_conn.c | 18 ++++++++++++++++++ subsys/bluetooth/controller/ll_sw/ull_master.c | 6 +++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 92d209d902a..28f39c8fe55 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -63,6 +63,7 @@ static void ticker_start_conn_op_cb(uint32_t status, void *param); static inline void disable(uint16_t handle); static void conn_cleanup(struct ll_conn *conn, uint8_t reason); +static void tx_demux(void *param); static struct node_tx *tx_ull_dequeue(struct ll_conn *conn, struct node_tx *tx); static void tx_ull_flush(struct ll_conn *conn); static void tx_lll_flush(void *param); @@ -236,6 +237,16 @@ int ll_tx_mem_enqueue(uint16_t handle, void *tx) MFIFO_ENQUEUE(conn_tx, idx); + if (ull_ref_get(&conn->ull)) { + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, NULL, tx_demux}; + + mfy.param = conn; + + mayfly_enqueue(TICKER_USER_ID_THREAD, TICKER_USER_ID_ULL_HIGH, + 0, &mfy); + } + #if defined(CONFIG_BT_PERIPHERAL) /* break slave latency */ if (conn->lll.role && conn->lll.latency_event && @@ -1694,6 +1705,13 @@ static void conn_cleanup(struct ll_conn *conn, uint8_t reason) ull_conn_tx_demux(UINT8_MAX); } +static void tx_demux(void *param) +{ + ull_conn_tx_demux(1); + + ull_conn_tx_lll_enqueue(param, 1); +} + static struct node_tx *tx_ull_dequeue(struct ll_conn *conn, struct node_tx *tx) { if (!conn->tx_ctrl && (conn->tx_head != conn->tx_data)) { diff --git a/subsys/bluetooth/controller/ll_sw/ull_master.c b/subsys/bluetooth/controller/ll_sw/ull_master.c index 38a487da5e2..937c04f16e2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_master.c +++ b/subsys/bluetooth/controller/ll_sw/ull_master.c @@ -752,11 +752,11 @@ void ull_master_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t ref = ull_ref_inc(&conn->ull); LL_ASSERT(ref); - /* De-mux 1 tx node from FIFO */ - ull_conn_tx_demux(1); + /* De-mux 2 tx node from FIFO, sufficient to be able to set MD bit */ + ull_conn_tx_demux(2); /* Enqueue towards LLL */ - ull_conn_tx_lll_enqueue(conn, 1); + ull_conn_tx_lll_enqueue(conn, 2); /* Append timing parameters */ p.ticks_at_expire = ticks_at_expire;