From 0604a4d2f1500b869ce452fda8f4b0f4982fb811 Mon Sep 17 00:00:00 2001 From: Erik Brockhoff Date: Thu, 8 Sep 2022 13:19:49 +0200 Subject: [PATCH] Bluetooth: controller: store STO value instead of pre-calculated reload Instead of storing the calculated reload value (in conn intervals) in the conn object, now store the timeout value, and perform calculation when used. This allows using the timeout value across all CIS's without having to re-calc and store on change of TO Signed-off-by: Erik Brockhoff --- .../bluetooth/controller/ll_sw/ull_central.c | 3 +- subsys/bluetooth/controller/ll_sw/ull_conn.c | 40 ++++++++----------- .../controller/ll_sw/ull_conn_types.h | 4 +- .../controller/ll_sw/ull_llcp_common.c | 6 ++- .../controller/ll_sw/ull_llcp_conn_upd.c | 9 ++--- .../controller/ll_sw/ull_peripheral.c | 7 +--- .../controller/common/src/helper_util.c | 2 + .../controller/ctrl_conn_update/src/main.c | 23 ++++------- 8 files changed, 40 insertions(+), 54 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central.c b/subsys/bluetooth/controller/ll_sw/ull_central.c index adfd7126178..b76fc2b52f7 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central.c @@ -284,8 +284,7 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window, conn->connect_expire = CONN_ESTAB_COUNTDOWN; conn->supervision_expire = 0U; conn_interval_us = (uint32_t)interval * CONN_INT_UNIT_US; - conn->supervision_reload = RADIO_CONN_EVENTS(timeout * 10000U, - conn_interval_us); + conn->supervision_timeout = timeout; #if defined(CONFIG_BT_LL_SW_LLCP_LEGACY) conn->procedure_expire = 0U; diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index aa02f71147f..e3b747405e0 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -1423,7 +1423,11 @@ int ull_conn_llcp(struct ll_conn *conn, uint32_t ticks_at_expire, uint16_t lazy) /* Terminate Procedure timeout is started, will * replace any other timeout running */ - conn->procedure_expire = conn->supervision_reload; + const uint32_t conn_interval_us = conn->lll.interval * CONN_INT_UNIT_US; + + conn->procedure_expire = RADIO_CONN_EVENTS( + (conn->supervision_timeout * 10U * 1000U), + conn_interval_us); /* NOTE: if supervision timeout equals connection * interval, dont timeout in current event. @@ -1678,7 +1682,11 @@ void ull_conn_done(struct node_rx_event_done *done) else { /* Start supervision timeout, if not started already */ if (!conn->supervision_expire) { - conn->supervision_expire = conn->supervision_reload; + const uint32_t conn_interval_us = conn->lll.interval * CONN_INT_UNIT_US; + + conn->supervision_expire = RADIO_CONN_EVENTS( + (conn->supervision_timeout * 10U * 1000U), + conn_interval_us); } } @@ -3330,9 +3338,7 @@ static inline int event_conn_upd_prep(struct ll_conn *conn, uint16_t lazy, /* Prepare the rx packet structure */ if ((conn->llcp_cu.interval != lll->interval) || (conn->llcp_cu.latency != lll->latency) || - (RADIO_CONN_EVENTS(conn->llcp_cu.timeout * 10000U, - lll->interval * CONN_INT_UNIT_US) != - conn->supervision_reload)) { + (conn->llcp_cu.timeout != conn->supervision_timeout)) { struct node_rx_cu *cu; rx->hdr.handle = lll->handle; @@ -3464,9 +3470,7 @@ static inline int event_conn_upd_prep(struct ll_conn *conn, uint16_t lazy, lll->interval = conn->llcp_cu.interval; lll->latency = conn->llcp_cu.latency; - conn->supervision_reload = - RADIO_CONN_EVENTS((conn->llcp_cu.timeout * 10U * 1000U), - conn_interval_us); + conn->supervision_timeout = conn->llcp_cu.timeout; conn->procedure_reload = RADIO_CONN_EVENTS((40 * 1000 * 1000), conn_interval_us); @@ -5614,8 +5618,7 @@ static inline int reject_ind_conn_upd_recv(struct ll_conn *conn, cu->status = rej_ext_ind->error_code; cu->interval = lll->interval; cu->latency = lll->latency; - cu->timeout = conn->supervision_reload * - lll->interval * 125U / 1000; + cu->timeout = conn->supervision_timeout; return 0; } @@ -7201,11 +7204,7 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx, lll->interval) || (conn->llcp_conn_param.latency != lll->latency) || - (RADIO_CONN_EVENTS(conn->llcp_conn_param.timeout * - 10000U, - lll->interval * - CONN_INT_UNIT_US) != - conn->supervision_reload)) { + (conn->llcp_conn_param.timeout != conn->supervision_timeout)) { #if defined(CONFIG_BT_CTLR_LE_ENC) /* postpone CP request event if under * encryption setup @@ -7302,11 +7301,7 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx, if ((conn->llcp_conn_param.interval_max != lll->interval) || (conn->llcp_conn_param.latency != lll->latency) || - (RADIO_CONN_EVENTS(conn->llcp_conn_param.timeout * - 10000U, - lll->interval * - CONN_INT_UNIT_US) != - conn->supervision_reload)) { + (conn->llcp_conn_param.timeout != conn->supervision_timeout)) { conn->llcp_conn_param.state = LLCP_CPR_STATE_APP_WAIT; } else { @@ -7513,8 +7508,7 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx, cu->status = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; cu->interval = lll->interval; cu->latency = lll->latency; - cu->timeout = conn->supervision_reload * - lll->interval * 125U / 1000; + cu->timeout = conn->supervision_timeout; #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */ #if defined(CONFIG_BT_CTLR_DATA_LENGTH) @@ -8087,7 +8081,7 @@ void ull_conn_update_parameters(struct ll_conn *conn, uint8_t is_cu_proc, uint8_ lll->interval = interval; lll->latency = latency; - conn->supervision_reload = RADIO_CONN_EVENTS((timeout * 10U * 1000U), conn_interval_us); + conn->supervision_timeout = timeout; ull_cp_prt_reload_set(conn, conn_interval_us); #if defined(CONFIG_BT_CTLR_LE_PING) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h index e97c0917683..ee791521c9b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h @@ -38,7 +38,7 @@ struct ll_conn { struct lll_conn lll; uint16_t connect_expire; - uint16_t supervision_reload; + uint16_t supervision_timeout; uint16_t supervision_expire; uint16_t procedure_reload; uint16_t procedure_expire; @@ -537,7 +537,7 @@ struct ll_conn { #endif /* CONFIG_BT_CTLR_LE_PING */ uint16_t connect_expire; - uint16_t supervision_reload; + uint16_t supervision_timeout; uint16_t supervision_expire; uint32_t connect_accept_to; diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c index 6f020c8fffe..9cc7d082309 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c @@ -220,7 +220,11 @@ static void lp_comm_tx(struct ll_conn *conn, struct proc_ctx *ctx) * NOTE: As the supervision timeout is at most 32s the normal procedure response * timeout of 40s will never come into play for the ACL Termination procedure. */ - llcp_lr_prt_restart_with_value(conn, conn->supervision_reload); + const uint32_t conn_interval_us = conn->lll.interval * CONN_INT_UNIT_US; + const uint16_t sto_reload = RADIO_CONN_EVENTS( + (conn->supervision_timeout * 10U * 1000U), + conn_interval_us); + llcp_lr_prt_restart_with_value(conn, sto_reload); } } diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c index b1cdb7566b6..ccd5eee0a1f 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c @@ -152,8 +152,7 @@ static bool cu_have_params_changed(struct ll_conn *conn, uint16_t interval, uint struct lll_conn *lll = &conn->lll; if ((interval != lll->interval) || (latency != lll->latency) || - (RADIO_CONN_EVENTS(timeout * 10000U, lll->interval * CONN_INT_UNIT_US) != - conn->supervision_reload)) { + (timeout != conn->supervision_timeout)) { return true; } return false; @@ -301,8 +300,7 @@ static void lp_cu_ntf(struct ll_conn *conn, struct proc_ctx *ctx) } else { pdu->interval = conn->lll.interval; pdu->latency = conn->lll.latency; - pdu->timeout = conn->supervision_reload * - conn->lll.interval * 125U / 1000; + pdu->timeout = conn->supervision_timeout; } /* Enqueue notification towards LL */ @@ -759,8 +757,7 @@ static void rp_cu_ntf(struct ll_conn *conn, struct proc_ctx *ctx) } else { pdu->interval = conn->lll.interval; pdu->latency = conn->lll.latency; - pdu->timeout = conn->supervision_reload * - conn->lll.interval * 125U / 1000; + pdu->timeout = conn->supervision_timeout; } /* Enqueue notification towards LL */ ll_rx_put(ntf->hdr.link, ntf); diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c index fa564521e6c..4d7e794c333 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c @@ -91,7 +91,6 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, uint16_t max_rx_time; uint16_t win_offset; memq_link_t *link; - uint16_t timeout; uint8_t chan_sel; void *node; @@ -204,9 +203,7 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, CONN_INT_UNIT_US; /* procedure timeouts */ - timeout = sys_le16_to_cpu(pdu_adv->connect_ind.timeout); - conn->supervision_reload = - RADIO_CONN_EVENTS((timeout * 10U * 1000U), conn_interval_us); + conn->supervision_timeout = sys_le16_to_cpu(pdu_adv->connect_ind.timeout); #if defined(CONFIG_BT_LL_SW_LLCP_LEGACY) conn->procedure_reload = @@ -286,7 +283,7 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, cc->interval = lll->interval; cc->latency = lll->latency; - cc->timeout = timeout; + cc->timeout = conn->supervision_timeout; cc->sca = conn->periph.sca; lll->handle = ll_conn_handle_get(conn); diff --git a/tests/bluetooth/controller/common/src/helper_util.c b/tests/bluetooth/controller/common/src/helper_util.c index 49841674578..551d33f9a20 100644 --- a/tests/bluetooth/controller/common/src/helper_util.c +++ b/tests/bluetooth/controller/common/src/helper_util.c @@ -269,6 +269,8 @@ void test_setup(struct ll_conn *conn) ll_reset(); conn->lll.event_counter = 0; + conn->lll.interval = 6; + conn->supervision_timeout = 600; event_active[0] = 0; memset(emul_conn_pool, 0x00, sizeof(emul_conn_pool)); diff --git a/tests/bluetooth/controller/ctrl_conn_update/src/main.c b/tests/bluetooth/controller/ctrl_conn_update/src/main.c index 78ff956e0b7..62e58ad8baa 100644 --- a/tests/bluetooth/controller/ctrl_conn_update/src/main.c +++ b/tests/bluetooth/controller/ctrl_conn_update/src/main.c @@ -195,7 +195,7 @@ static void setup(void) lll->interval = 0; lll->latency = 0; - conn.supervision_reload = 1U; + conn.supervision_timeout = 1U; lll->event_counter = 0; } @@ -2467,6 +2467,7 @@ void test_conn_update_periph_rem_apm_accept_right_away(void) #if defined(CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE) struct node_tx *tx; uint16_t instant; + uint8_t error = 0U; /* Default conn_param_req PDU */ struct pdu_data_llctrl_conn_param_req conn_param_req_apm = { .interval_min = INTVL_MIN, .interval_max = INTVL_MAX, @@ -2494,7 +2495,6 @@ void test_conn_update_periph_rem_apm_accept_right_away(void) .offset3 = 0xffffU, .offset4 = 0xffffU, .offset5 = 0xffffU }; - uint8_t error = 0; /* Prepare mocked call to ull_handle_cpr_anchor_point_move */ /* No APM deferance, accept with error == 0 */ @@ -2509,8 +2509,7 @@ void test_conn_update_periph_rem_apm_accept_right_away(void) conn.lll.interval = conn_param_req_apm.interval_max; conn.lll.latency = conn_param_req_apm.latency; - conn.supervision_reload = RADIO_CONN_EVENTS(TIMEOUT * 10000U, conn.lll.interval * - CONN_INT_UNIT_US); + conn.supervision_timeout = TIMEOUT; /* Prepare */ event_prepare(&conn); @@ -2638,7 +2637,6 @@ void test_conn_update_periph_rem_apm_reject_right_away(void) ztest_returns_value(ull_handle_cpr_anchor_point_move, false); ztest_return_data(ull_handle_cpr_anchor_point_move, status, &error); - /* Role */ test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL); @@ -2647,8 +2645,7 @@ void test_conn_update_periph_rem_apm_reject_right_away(void) conn.lll.interval = conn_param_req_apm.interval_max; conn.lll.latency = conn_param_req_apm.latency; - conn.supervision_reload = RADIO_CONN_EVENTS(TIMEOUT * 10000U, conn.lll.interval * - CONN_INT_UNIT_US); + conn.supervision_timeout = TIMEOUT; /* Prepare */ event_prepare(&conn); @@ -2740,6 +2737,7 @@ void test_conn_update_periph_rem_apm_accept_defered(void) }; struct node_tx *tx; uint16_t instant; + uint8_t error = 0U; /* Default conn_param_req PDU */ struct pdu_data_llctrl_conn_param_req conn_param_req_apm = { .interval_min = INTVL_MIN, .interval_max = INTVL_MAX, @@ -2767,7 +2765,6 @@ void test_conn_update_periph_rem_apm_accept_defered(void) .offset3 = 0xffffU, .offset4 = 0xffffU, .offset5 = 0xffffU }; - uint8_t error = 0; /* Prepare mocked call to ull_handle_cpr_anchor_point_move */ /* Defer APM */ @@ -2782,8 +2779,7 @@ void test_conn_update_periph_rem_apm_accept_defered(void) conn.lll.interval = conn_param_req_apm.interval_max; conn.lll.latency = conn_param_req_apm.latency; - conn.supervision_reload = RADIO_CONN_EVENTS(TIMEOUT * 10000U, conn.lll.interval * - CONN_INT_UNIT_US); + conn.supervision_timeout = TIMEOUT; /* Prepare */ event_prepare(&conn); @@ -2797,7 +2793,6 @@ void test_conn_update_periph_rem_apm_accept_defered(void) /* Done */ event_done(&conn); - /* Run a few events */ for (int i = 0; i < 10; i++) { @@ -2906,6 +2901,7 @@ void test_conn_update_periph_rem_apm_reject_defered(void) { #if defined(CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE) struct node_tx *tx; + uint8_t error = 0U; /* Default conn_param_req PDU */ struct pdu_data_llctrl_conn_param_req conn_param_req_apm = { .interval_min = INTVL_MIN, .interval_max = INTVL_MAX, @@ -2923,14 +2919,12 @@ void test_conn_update_periph_rem_apm_reject_defered(void) .reject_opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ, .error_code = BT_HCI_ERR_UNSUPP_LL_PARAM_VAL }; - uint8_t error = 0U; /* Prepare mocked call to ull_handle_cpr_anchor_point_move */ /* Defer APM */ ztest_returns_value(ull_handle_cpr_anchor_point_move, true); ztest_return_data(ull_handle_cpr_anchor_point_move, status, &error); - /* Role */ test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL); @@ -2939,8 +2933,7 @@ void test_conn_update_periph_rem_apm_reject_defered(void) conn.lll.interval = conn_param_req_apm.interval_max; conn.lll.latency = conn_param_req_apm.latency; - conn.supervision_reload = RADIO_CONN_EVENTS(TIMEOUT * 10000U, conn.lll.interval * - CONN_INT_UNIT_US); + conn.supervision_timeout = TIMEOUT; /* Prepare */ event_prepare(&conn);