From a8e25d94024933867bab59076a00990edad00715 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 21 Jan 2021 18:44:44 +0530 Subject: [PATCH] Bluetooth: controller: Fix deferred Conn Param Req offset population Fix deferred Connection Parameter Request offset population by introduction of explicit states waiting for the offset calculations to complete in the ULL_LOW context. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_conn.c | 42 ++++++++++++++++--- .../controller/ll_sw/ull_conn_types.h | 4 +- subsys/bluetooth/controller/ll_sw/ull_sched.c | 3 ++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 74bbdcccf54..f681d229610 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -3064,9 +3064,6 @@ static inline void event_conn_param_req(struct ll_conn *conn, return; } - /* move to wait for conn_update/rsp/rej */ - conn->llcp_conn_param.state = LLCP_CPR_STATE_RSP_WAIT; - /* place the conn param req packet as next in tx queue */ pdu_ctrl_tx = (void *)tx->pdu; pdu_ctrl_tx->ll_id = PDU_DATA_LLID_CTRL; @@ -3079,7 +3076,6 @@ static inline void event_conn_param_req(struct ll_conn *conn, p->latency = sys_cpu_to_le16(conn->llcp_conn_param.latency); p->timeout = sys_cpu_to_le16(conn->llcp_conn_param.timeout); p->preferred_periodicity = 0U; - p->reference_conn_event_count = sys_cpu_to_le16(event_counter); p->offset0 = sys_cpu_to_le16(0x0000); p->offset1 = sys_cpu_to_le16(0xffff); p->offset2 = sys_cpu_to_le16(0xffff); @@ -3087,8 +3083,6 @@ static inline void event_conn_param_req(struct ll_conn *conn, p->offset4 = sys_cpu_to_le16(0xffff); p->offset5 = sys_cpu_to_le16(0xffff); - ctrl_tx_enqueue(conn, tx); - /* set CUI/CPR mutex */ conn_upd_curr = conn; @@ -3098,6 +3092,9 @@ static inline void event_conn_param_req(struct ll_conn *conn, conn->procedure_expire = conn->procedure_reload; #if defined(CONFIG_BT_CTLR_SCHED_ADVANCED) + /* move to wait for offset calculations */ + conn->llcp_conn_param.state = LLCP_CPR_STATE_OFFS_REQ; + { static memq_link_t s_link; static struct mayfly s_mfy_sched_offset = {0, 0, &s_link, NULL, @@ -3129,6 +3126,13 @@ static inline void event_conn_param_req(struct ll_conn *conn, } #else /* !CONFIG_BT_CTLR_SCHED_ADVANCED */ ARG_UNUSED(ticks_at_expire); + + /* set reference counter value */ + p->reference_conn_event_count = sys_cpu_to_le16(event_counter); + /* move to wait for conn_update_rsp/rej */ + conn->llcp_conn_param.state = LLCP_CPR_STATE_RSP_WAIT; + /* enqueue control PDU */ + ctrl_tx_enqueue(conn, tx); #endif /* !CONFIG_BT_CTLR_SCHED_ADVANCED */ } @@ -3314,6 +3318,32 @@ static inline void event_conn_param_prep(struct ll_conn *conn, /* Do nothing */ break; +#if defined(CONFIG_BT_CTLR_SCHED_ADVANCED) + case LLCP_CPR_STATE_OFFS_REQ: + /* Do nothing */ + break; + + case LLCP_CPR_STATE_OFFS_RDY: + { + struct pdu_data *pdu_ctrl_tx; + struct node_tx *tx; + + /* set reference counter value */ + pdu_ctrl_tx = + CONTAINER_OF(conn->llcp_conn_param.pdu_win_offset0, + struct pdu_data, + llctrl.conn_param_req.offset0); + pdu_ctrl_tx->llctrl.conn_param_req.reference_conn_event_count = + sys_cpu_to_le16(event_counter); + /* move to wait for conn_update_rsp/rej */ + conn->llcp_conn_param.state = LLCP_CPR_STATE_RSP_WAIT; + /* enqueue control PDU */ + tx = CONTAINER_OF(pdu_ctrl_tx, struct node_tx, pdu); + ctrl_tx_enqueue(conn, tx); + } + break; +#endif /* CONFIG_BT_CTLR_SCHED_ADVANCED */ + default: LL_ASSERT(0); break; diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h index c97b3b1c414..a1800220e2a 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h @@ -218,7 +218,9 @@ struct ll_conn { LLCP_CPR_STATE_APP_REQ, LLCP_CPR_STATE_APP_WAIT, LLCP_CPR_STATE_RSP_WAIT, - LLCP_CPR_STATE_UPD + LLCP_CPR_STATE_UPD, + LLCP_CPR_STATE_OFFS_REQ, + LLCP_CPR_STATE_OFFS_RDY, } state:3 __packed; uint8_t cmd:1; uint8_t disabled:1; diff --git a/subsys/bluetooth/controller/ll_sw/ull_sched.c b/subsys/bluetooth/controller/ll_sw/ull_sched.c index 38189805134..13ec10a5100 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sched.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sched.c @@ -210,6 +210,9 @@ void ull_sched_mfy_free_win_offset_calc(void *param) win_offset_calc(conn, 0, ticks_to_offset_next, conn->llcp_conn_param.interval_max, &offset_max, (void *)conn->llcp_conn_param.pdu_win_offset0); + + /* move to offset calculated state */ + conn->llcp_conn_param.state = LLCP_CPR_STATE_OFFS_RDY; } void ull_sched_mfy_win_offset_select(void *param)