From 416d7ee32aa779038205d782f45f1ecdef115b27 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Mon, 28 Sep 2020 15:16:08 +0530 Subject: [PATCH] Bluetooth: controller: Fix latency cancel on LLCP initiation Fix controller implementation to cancel peripheral latency when initiating new control procedures. Fixes #28699. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_conn.c | 68 ++++++++++++++------ 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index d4d60180ac7..2bc35fea70f 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -55,6 +55,7 @@ static int init_reset(void); #if defined(CONFIG_BT_PERIPHERAL) static void ticker_update_latency_cancel_op_cb(uint32_t ticker_status, void *params); +static void peripheral_latency_cancel(struct ll_conn *conn, uint16_t handle); #endif /* CONFIG_BT_PERIPHERAL */ static void ticker_update_conn_op_cb(uint32_t status, void *param); @@ -274,25 +275,9 @@ int ll_tx_mem_enqueue(uint16_t handle, void *tx) #endif /* CONFIG_BT_CTLR_FORCE_MD_AUTO */ } -#if defined(CONFIG_BT_PERIPHERAL) - /* break slave latency */ - if (conn->lll.role && conn->lll.latency_event && - !conn->slave.latency_cancel) { - uint32_t ticker_status; - - conn->slave.latency_cancel = 1U; - - ticker_status = - ticker_update(TICKER_INSTANCE_ID_CTLR, - TICKER_USER_ID_THREAD, - (TICKER_ID_CONN_BASE + handle), - 0, 0, 0, 0, 1, 0, - ticker_update_latency_cancel_op_cb, - (void *)conn); - LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) || - (ticker_status == TICKER_STATUS_BUSY)); + if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn->lll.role) { + peripheral_latency_cancel(conn, handle); } -#endif /* CONFIG_BT_PERIPHERAL */ #if defined(CONFIG_BT_CTLR_THROUGHPUT) static uint32_t last_cycle_stamp; @@ -391,6 +376,11 @@ uint8_t ll_conn_update(uint16_t handle, uint8_t cmd, uint8_t status, uint16_t in conn->llcp_conn_param.state = cmd; conn->llcp_conn_param.cmd = 1U; conn->llcp_conn_param.req++; + + if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && + conn->lll.role) { + peripheral_latency_cancel(conn, handle); + } } #else /* !CONFIG_BT_CTLR_CONN_PARAM_REQ */ @@ -436,6 +426,10 @@ uint8_t ll_terminate_ind_send(uint16_t handle, uint8_t reason) conn->llcp_terminate.req++; + if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn->lll.role) { + peripheral_latency_cancel(conn, handle); + } + return 0; } @@ -454,6 +448,12 @@ uint8_t ll_feature_req_send(uint16_t handle) conn->llcp_feature.req++; + if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && + IS_ENABLED(CONFIG_BT_CTLR_SLAVE_FEAT_REQ) && + conn->lll.role) { + peripheral_latency_cancel(conn, handle); + } + return 0; } @@ -472,6 +472,10 @@ uint8_t ll_version_ind_send(uint16_t handle) conn->llcp_version.req++; + if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn->lll.role) { + peripheral_latency_cancel(conn, handle); + } + return 0; } @@ -521,6 +525,10 @@ uint32_t ll_length_req_send(uint16_t handle, uint16_t tx_octets, uint16_t tx_tim conn->llcp_length.req++; + if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn->lll.role) { + peripheral_latency_cancel(conn, handle); + } + return 0; } @@ -612,6 +620,10 @@ uint8_t ll_phy_req_send(uint16_t handle, uint8_t tx, uint8_t flags, uint8_t rx) conn->llcp_phy.rx = rx; conn->llcp_phy.req++; + if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn->lll.role) { + peripheral_latency_cancel(conn, handle); + } + return 0; } #endif /* CONFIG_BT_CTLR_PHY */ @@ -1628,6 +1640,26 @@ static void ticker_update_latency_cancel_op_cb(uint32_t ticker_status, conn->slave.latency_cancel = 0U; } + +static void peripheral_latency_cancel(struct ll_conn *conn, uint16_t handle) +{ + /* break peripheral latency */ + if (conn->lll.latency_event && !conn->slave.latency_cancel) { + uint32_t ticker_status; + + conn->slave.latency_cancel = 1U; + + ticker_status = + ticker_update(TICKER_INSTANCE_ID_CTLR, + TICKER_USER_ID_THREAD, + (TICKER_ID_CONN_BASE + handle), + 0, 0, 0, 0, 1, 0, + ticker_update_latency_cancel_op_cb, + (void *)conn); + LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) || + (ticker_status == TICKER_STATUS_BUSY)); + } +} #endif /* CONFIG_BT_PERIPHERAL */ static void ticker_update_conn_op_cb(uint32_t status, void *param)