Bluetooth: Controller: Introduce BT_CTLR_PERIPHERAL_RESERVE_MAX
Introduce BT_CTLR_PERIPHERAL_RESERVE_MAX Kconfig option so that disabling this option will use minimum time reservation and exercise the peripheral connection event continuation using is_abort_cb mechanism. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
c344cca8e9
commit
cadef5a64f
10 changed files with 98 additions and 5 deletions
|
@ -72,6 +72,8 @@ CONFIG_BT_CTLR_SCAN_AUX_SET=1
|
|||
|
||||
CONFIG_BT_CTLR_ADV_RESERVE_MAX=n
|
||||
CONFIG_BT_CTLR_CENTRAL_RESERVE_MAX=n
|
||||
CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX=n
|
||||
CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX=y
|
||||
CONFIG_BT_CTLR_SLOT_RESERVATION_UPDATE=n
|
||||
CONFIG_BT_CTLR_SCAN_UNRESERVED=y
|
||||
CONFIG_BT_TICKER_NEXT_SLOT_GET_MATCH=y
|
||||
|
|
|
@ -754,6 +754,19 @@ config BT_CTLR_CENTRAL_RESERVE_MAX
|
|||
Note, currently this value is only used to space multiple central
|
||||
connections and not for actual ticker time reservations.
|
||||
|
||||
config BT_CTLR_PERIPHERAL_RESERVE_MAX
|
||||
bool "Use maximum data PDU size time reservation for Peripheral"
|
||||
depends on BT_PERIPHERAL
|
||||
default y
|
||||
help
|
||||
Use the maximum data PDU size time reservation considering the Data
|
||||
length could be updated from default 27 bytes to maximum support size.
|
||||
|
||||
If maximum time reservation is disabled then time reservation required
|
||||
for empty PDU transmission is used. Overlapping radio events will use
|
||||
the is_abort_cb mechanism to decide on continuation of the connection
|
||||
event.
|
||||
|
||||
config BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX
|
||||
bool "Reserve maximum event overhead in time reservations"
|
||||
default y
|
||||
|
|
|
@ -509,6 +509,7 @@ struct event_done_extra {
|
|||
struct {
|
||||
uint16_t trx_cnt;
|
||||
uint8_t crc_valid:1;
|
||||
uint8_t is_aborted:1;
|
||||
#if defined(CONFIG_BT_CTLR_SYNC_ISO)
|
||||
uint8_t estab_failed:1;
|
||||
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
|
||||
|
|
|
@ -69,11 +69,20 @@ struct lll_conn {
|
|||
struct {
|
||||
uint8_t initiated:1;
|
||||
uint8_t cancelled:1;
|
||||
uint8_t forced:1;
|
||||
};
|
||||
|
||||
struct {
|
||||
uint8_t initiated:1;
|
||||
uint8_t cancelled:1;
|
||||
uint8_t forced:1;
|
||||
} central;
|
||||
|
||||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
struct {
|
||||
uint8_t initiated:1;
|
||||
uint8_t cancelled:1;
|
||||
uint8_t forced:1;
|
||||
uint8_t latency_enabled:1;
|
||||
|
||||
uint32_t window_widening_periodic_us;
|
||||
|
@ -160,6 +169,7 @@ int lll_conn_reset(void);
|
|||
void lll_conn_flush(uint16_t handle, struct lll_conn *lll);
|
||||
|
||||
void lll_conn_prepare_reset(void);
|
||||
int lll_conn_is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb);
|
||||
void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param);
|
||||
void lll_conn_isr_rx(void *param);
|
||||
void lll_conn_isr_tx(void *param);
|
||||
|
|
|
@ -59,6 +59,7 @@ static struct pdu_data *get_last_tx_pdu(struct lll_conn *lll);
|
|||
|
||||
static uint8_t crc_expire;
|
||||
static uint8_t crc_valid;
|
||||
static uint8_t is_aborted;
|
||||
static uint16_t trx_cnt;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_LE_ENC)
|
||||
|
@ -142,12 +143,25 @@ void lll_conn_prepare_reset(void)
|
|||
trx_cnt = 0U;
|
||||
crc_valid = 0U;
|
||||
crc_expire = 0U;
|
||||
is_aborted = 0U;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_LE_ENC)
|
||||
mic_state = LLL_CONN_MIC_NONE;
|
||||
#endif /* CONFIG_BT_CTLR_LE_ENC */
|
||||
}
|
||||
|
||||
int lll_conn_is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb)
|
||||
{
|
||||
struct lll_conn *lll = curr;
|
||||
|
||||
/* Do not abort if near supervision timeout */
|
||||
if (lll->forced) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param)
|
||||
{
|
||||
struct event_done_extra *e;
|
||||
|
@ -156,6 +170,17 @@ void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param)
|
|||
|
||||
/* NOTE: This is not a prepare being cancelled */
|
||||
if (!prepare_param) {
|
||||
/* Get reference to LLL connection context */
|
||||
lll = param;
|
||||
|
||||
/* For a peripheral role, ensure at least one PDU is tx-ed
|
||||
* back to central, otherwise let the supervision timeout
|
||||
* countdown be started.
|
||||
*/
|
||||
if ((lll->role == BT_HCI_ROLE_PERIPHERAL) && (trx_cnt <= 1U)) {
|
||||
is_aborted = 1U;
|
||||
}
|
||||
|
||||
/* Perform event abort here.
|
||||
* After event has been cleanly aborted, clean up resources
|
||||
* and dispatch event done.
|
||||
|
@ -171,8 +196,10 @@ void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param)
|
|||
err = lll_hfclock_off();
|
||||
LL_ASSERT(err >= 0);
|
||||
|
||||
/* Accumulate the latency as event is aborted while being in pipeline */
|
||||
/* Get reference to LLL connection context */
|
||||
lll = prepare_param->param;
|
||||
|
||||
/* Accumulate the latency as event is aborted while being in pipeline */
|
||||
lll->latency_prepare += (prepare_param->lazy + 1);
|
||||
|
||||
/* Extra done event, to check supervision timeout */
|
||||
|
@ -867,6 +894,7 @@ static void isr_done(void *param)
|
|||
e->type = EVENT_DONE_EXTRA_TYPE_CONN;
|
||||
e->trx_cnt = trx_cnt;
|
||||
e->crc_valid = crc_valid;
|
||||
e->is_aborted = is_aborted;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_LE_ENC)
|
||||
e->mic_state = mic_state;
|
||||
|
|
|
@ -89,7 +89,8 @@ void lll_periph_prepare(void *param)
|
|||
}
|
||||
|
||||
/* Invoke common pipeline handling of prepare */
|
||||
err = lll_prepare(lll_is_abort_cb, lll_conn_abort_cb, prepare_cb, 0, p);
|
||||
err = lll_prepare(lll_conn_is_abort_cb, lll_conn_abort_cb, prepare_cb,
|
||||
0U, p);
|
||||
LL_ASSERT(!err || err == -EINPROGRESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -1072,6 +1072,7 @@ uint8_t ll_adv_enable(uint8_t enable)
|
|||
conn_lll->role = 1;
|
||||
conn_lll->periph.initiated = 0;
|
||||
conn_lll->periph.cancelled = 0;
|
||||
conn_lll->periph.forced = 0;
|
||||
conn_lll->data_chan_sel = 0;
|
||||
conn_lll->data_chan_use = 0;
|
||||
conn_lll->event_counter = 0;
|
||||
|
|
|
@ -253,6 +253,7 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window,
|
|||
conn_lll->role = 0;
|
||||
conn_lll->central.initiated = 0;
|
||||
conn_lll->central.cancelled = 0;
|
||||
conn_lll->central.forced = 0;
|
||||
/* FIXME: END: Move to ULL? */
|
||||
#if defined(CONFIG_BT_CTLR_CONN_META)
|
||||
memset(&conn_lll->conn_meta, 0, sizeof(conn_lll->conn_meta));
|
||||
|
|
|
@ -943,6 +943,7 @@ void ull_conn_done(struct node_rx_event_done *done)
|
|||
struct lll_conn *lll;
|
||||
struct ll_conn *conn;
|
||||
uint8_t reason_final;
|
||||
uint8_t force_lll;
|
||||
uint16_t lazy;
|
||||
uint8_t force;
|
||||
|
||||
|
@ -1054,7 +1055,7 @@ void ull_conn_done(struct node_rx_event_done *done)
|
|||
}
|
||||
|
||||
/* Reset supervision countdown */
|
||||
if (done->extra.crc_valid) {
|
||||
if (done->extra.crc_valid && !done->extra.is_aborted) {
|
||||
conn->supervision_expire = 0U;
|
||||
}
|
||||
|
||||
|
@ -1085,6 +1086,7 @@ void ull_conn_done(struct node_rx_event_done *done)
|
|||
|
||||
/* check supervision timeout */
|
||||
force = 0U;
|
||||
force_lll = 0U;
|
||||
if (conn->supervision_expire) {
|
||||
if (conn->supervision_expire > elapsed_event) {
|
||||
conn->supervision_expire -= elapsed_event;
|
||||
|
@ -1096,6 +1098,8 @@ void ull_conn_done(struct node_rx_event_done *done)
|
|||
* supervision timeout.
|
||||
*/
|
||||
if (conn->supervision_expire <= 6U) {
|
||||
force_lll = 1U;
|
||||
|
||||
force = 1U;
|
||||
}
|
||||
#if defined(CONFIG_BT_CTLR_CONN_RANDOM_FORCE)
|
||||
|
@ -1123,6 +1127,8 @@ void ull_conn_done(struct node_rx_event_done *done)
|
|||
}
|
||||
}
|
||||
|
||||
lll->forced = force_lll;
|
||||
|
||||
/* check procedure timeout */
|
||||
uint8_t error_code;
|
||||
|
||||
|
@ -1233,26 +1239,41 @@ void ull_conn_done(struct node_rx_event_done *done)
|
|||
uint32_t ready_delay, rx_time, tx_time, ticks_slot, slot_us;
|
||||
|
||||
lll->evt_len_upd = 0;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
ready_delay = (lll->role) ?
|
||||
lll_radio_rx_ready_delay_get(lll->phy_rx, PHY_FLAGS_S8) :
|
||||
lll_radio_tx_ready_delay_get(lll->phy_tx, lll->phy_flags);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX)
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
||||
tx_time = lll->dle.eff.max_tx_time;
|
||||
rx_time = lll->dle.eff.max_rx_time;
|
||||
#else /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
|
||||
#else /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
tx_time = MAX(PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN, 0),
|
||||
PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN, lll->phy_tx));
|
||||
rx_time = MAX(PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN, 0),
|
||||
PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN, lll->phy_rx));
|
||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX */
|
||||
tx_time = PDU_MAX_US(0U, 0U, lll->phy_tx);
|
||||
rx_time = PDU_MAX_US(0U, 0U, lll->phy_rx);
|
||||
#endif /* !CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX */
|
||||
|
||||
#else /* CONFIG_BT_CTLR_PHY */
|
||||
ready_delay = (lll->role) ?
|
||||
lll_radio_rx_ready_delay_get(0, 0) :
|
||||
lll_radio_tx_ready_delay_get(0, 0);
|
||||
#if defined(CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX)
|
||||
tx_time = PDU_DC_MAX_US(lll->dle.eff.max_tx_octets, 0);
|
||||
rx_time = PDU_DC_MAX_US(lll->dle.eff.max_rx_octets, 0);
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX */
|
||||
tx_time = PDU_MAX_US(0U, 0U, PHY_1M);
|
||||
rx_time = PDU_MAX_US(0U, 0U, PHY_1M);
|
||||
#endif /* !CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX */
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
|
||||
/* Calculate event time reservation */
|
||||
|
|
|
@ -341,25 +341,40 @@ void ull_periph_setup(struct node_rx_pdu *rx, struct node_rx_ftr *ftr,
|
|||
|
||||
ll_rx_put_sched(link, rx);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX)
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
max_tx_time = lll->dle.eff.max_tx_time;
|
||||
max_rx_time = lll->dle.eff.max_rx_time;
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_PHY */
|
||||
max_tx_time = PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
|
||||
max_rx_time = PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
|
||||
#endif /* !CONFIG_BT_CTLR_PHY */
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
max_tx_time = PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
|
||||
max_rx_time = PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
max_tx_time = MAX(max_tx_time,
|
||||
PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN, lll->phy_tx));
|
||||
max_rx_time = MAX(max_rx_time,
|
||||
PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN, lll->phy_rx));
|
||||
#endif /* !CONFIG_BT_CTLR_PHY */
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
#endif /* !CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX */
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
max_tx_time = PDU_MAX_US(0U, 0U, lll->phy_tx);
|
||||
max_rx_time = PDU_MAX_US(0U, 0U, lll->phy_rx);
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_PHY */
|
||||
max_tx_time = PDU_MAX_US(0U, 0U, PHY_1M);
|
||||
max_rx_time = PDU_MAX_US(0U, 0U, PHY_1M);
|
||||
#endif /* !CONFIG_BT_CTLR_PHY */
|
||||
#endif /* !CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy_rx, PHY_FLAGS_S8);
|
||||
#else /* CONFIG_BT_CTLR_PHY */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue