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 <erbr@oticon.com>
This commit is contained in:
Erik Brockhoff 2022-09-08 13:19:49 +02:00 committed by Carles Cufí
commit 0604a4d2f1
8 changed files with 40 additions and 54 deletions

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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));

View file

@ -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);