Skip to content

Commit 32c2f85

Browse files
committed
Bluetooth: controller: Fix post DLE/PHY update event length
Fix the controller implementation to perform connection event length reservation based on the completed Data Length Update and/or PHY Update Procedure. This fix with avoid states/roles from stepping on each others event length. Connection would have supervision timed out or have stalled data transmissions due to insufficient reserved air time. Relates to #15171. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent ffc71f2 commit 32c2f85

File tree

2 files changed

+98
-17
lines changed

2 files changed

+98
-17
lines changed

subsys/bluetooth/controller/ll_sw/ctrl.c

Lines changed: 93 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -276,11 +276,11 @@ static void ticker_update_adv_assert(u32_t status, void *params);
276276
#if defined(CONFIG_BT_CONN)
277277
#if defined(CONFIG_BT_PERIPHERAL)
278278
static void ticker_stop_adv_assert(u32_t status, void *params);
279-
static void ticker_update_slave_assert(u32_t status, void *params);
280279
#endif /* CONFIG_BT_PERIPHERAL */
281280
#if defined(CONFIG_BT_CENTRAL)
282281
static void ticker_stop_scan_assert(u32_t status, void *params);
283282
#endif /* CONFIG_BT_CENTRAL */
283+
static void ticker_update_conn_assert(u32_t status, void *params);
284284
static void ticker_stop_conn_assert(u32_t status, void *params);
285285
static void ticker_start_conn_assert(u32_t status, void *params);
286286
#endif /* CONFIG_BT_CONN */
@@ -2380,6 +2380,11 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx,
23802380
eff_tx_time;
23812381
#endif /* CONFIG_BT_CTLR_PHY */
23822382

2383+
/* flag an event length update*/
2384+
_radio.conn_curr->evt_len_upd = 1U;
2385+
_radio.conn_curr->evt_len_adv = 1U;
2386+
2387+
/* Request Rx buffer resize */
23832388
_radio.conn_curr->llcp_length.ack =
23842389
(_radio.conn_curr->llcp_length.req - 1);
23852390
_radio.conn_curr->llcp_length.state =
@@ -2420,6 +2425,10 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx,
24202425
_radio.conn_curr->max_tx_time = eff_tx_time;
24212426
#endif /* CONFIG_BT_CTLR_PHY */
24222427

2428+
/* flag an event length update*/
2429+
_radio.conn_curr->evt_len_upd = 1U;
2430+
_radio.conn_curr->evt_len_adv = 0U;
2431+
24232432
/* prepare event params */
24242433
lr->max_rx_octets = eff_rx_octets;
24252434
lr->max_tx_octets = eff_tx_octets;
@@ -4318,8 +4327,10 @@ static inline u32_t isr_close_scan(void)
43184327
#if defined(CONFIG_BT_CONN)
43194328
static inline void isr_close_conn(void)
43204329
{
4321-
u32_t ticks_drift_plus;
43224330
u32_t ticks_drift_minus;
4331+
u32_t ticks_drift_plus;
4332+
u32_t ticks_slot_minus;
4333+
u32_t ticks_slot_plus;
43234334
u16_t latency_event;
43244335
u16_t elapsed_event;
43254336
u8_t reason_peer;
@@ -4345,10 +4356,12 @@ static inline void isr_close_conn(void)
43454356
return;
43464357
}
43474358

4348-
ticks_drift_plus = 0U;
4349-
ticks_drift_minus = 0U;
43504359
latency_event = _radio.conn_curr->latency_event;
43514360
elapsed_event = latency_event + 1;
4361+
ticks_drift_minus = 0U;
4362+
ticks_drift_plus = 0U;
4363+
ticks_slot_minus = 0U;
4364+
ticks_slot_plus = 0U;
43524365

43534366
/* calculate drift if anchor point sync-ed */
43544367
if (_radio.packet_counter &&
@@ -4579,8 +4592,65 @@ static inline void isr_close_conn(void)
45794592
lazy = _radio.conn_curr->latency_event + 1;
45804593
}
45814594

4582-
#if defined(CONFIG_BT_PERIPHERAL)
4595+
#if defined(CONFIG_BT_CTLR_DATA_LENGTH) || defined(CONFIG_BT_CTLR_PHY)
4596+
/* TODO: Design connection event length use. for only reserve for single
4597+
* trx.
4598+
*/
4599+
if (_radio.conn_curr->evt_len_upd) {
4600+
u32_t ready_delay, rx_time, tx_time, ticks_slot;
4601+
struct connection *conn = _radio.conn_curr;
4602+
4603+
/* Reset event length update flag */
4604+
conn->evt_len_upd = 0U;
4605+
4606+
#if defined(CONFIG_BT_CTLR_PHY)
4607+
ready_delay = (conn->role) ?
4608+
radio_rx_ready_delay_get(conn->phy_rx, 1) :
4609+
radio_tx_ready_delay_get(conn->phy_tx,
4610+
conn->phy_flags);
4611+
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
4612+
tx_time = conn->max_tx_time;
4613+
if (conn->evt_len_adv) {
4614+
rx_time = conn->llcp_length.rx_time;
4615+
} else {
4616+
rx_time = conn->max_rx_time;
4617+
}
4618+
#else /* !CONFIG_BT_CTLR_DATA_LENGTH */
4619+
tx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0),
4620+
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
4621+
conn->phy_tx));
4622+
rx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0),
4623+
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
4624+
conn->phy_rx));
4625+
#endif /* !CONFIG_BT_CTLR_DATA_LENGTH */
4626+
#else /* !CONFIG_BT_CTLR_PHY */
4627+
ready_delay = (conn->role) ?
4628+
radio_rx_ready_delay_get(0, 0) :
4629+
radio_tx_ready_delay_get(0, 0);
4630+
tx_time = RADIO_PKT_TIME(conn->max_tx_octets, 0);
4631+
if (conn->evt_len_adv) {
4632+
rx_time = RADIO_PKT_TIME(conn->llcp_length.rx_octets,
4633+
0);
4634+
} else {
4635+
rx_time = RADIO_PKT_TIME(conn->max_rx_octets, 0);
4636+
}
4637+
#endif /* !CONFIG_BT_CTLR_PHY */
4638+
4639+
ticks_slot = HAL_TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US +
4640+
ready_delay + RADIO_TIFS +
4641+
rx_time + tx_time + 4);
4642+
4643+
if (ticks_slot > conn->hdr.ticks_slot) {
4644+
ticks_slot_plus = ticks_slot - conn->hdr.ticks_slot;
4645+
} else {
4646+
ticks_slot_minus = conn->hdr.ticks_slot - ticks_slot;
4647+
}
4648+
conn->hdr.ticks_slot = ticks_slot;
4649+
}
4650+
#endif
4651+
45834652
if ((ticks_drift_plus != 0) || (ticks_drift_minus != 0) ||
4653+
(ticks_slot_plus != 0) || (ticks_slot_minus != 0) ||
45844654
(lazy != 0) || (force != 0)) {
45854655
u32_t ticker_status;
45864656
u8_t ticker_id = RADIO_TICKER_ID_FIRST_CONNECTION +
@@ -4596,14 +4666,14 @@ static inline void isr_close_conn(void)
45964666
ticker_update(RADIO_TICKER_INSTANCE_ID_RADIO,
45974667
RADIO_TICKER_USER_ID_WORKER,
45984668
ticker_id,
4599-
ticks_drift_plus, ticks_drift_minus, 0, 0,
4600-
lazy, force, ticker_update_slave_assert,
4669+
ticks_drift_plus, ticks_drift_minus,
4670+
ticks_slot_plus, ticks_slot_minus,
4671+
lazy, force, ticker_update_conn_assert,
46014672
(void *)(u32_t)ticker_id);
46024673
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
46034674
(ticker_status == TICKER_STATUS_BUSY) ||
46044675
(_radio.ticker_id_stop == ticker_id));
46054676
}
4606-
#endif /* CONFIG_BT_PERIPHERAL */
46074677
}
46084678
#endif /* CONFIG_BT_CONN */
46094679

@@ -4809,15 +4879,6 @@ static void ticker_stop_adv_assert(u32_t status, void *params)
48094879
LL_ASSERT(_radio.ticker_id_prepare != RADIO_TICKER_ID_ADV);
48104880
}
48114881
}
4812-
4813-
static void ticker_update_slave_assert(u32_t status, void *params)
4814-
{
4815-
u8_t ticker_id = (u32_t)params & 0xFF;
4816-
4817-
LL_ASSERT((status == TICKER_STATUS_SUCCESS) ||
4818-
(_radio.ticker_id_stop == ticker_id) ||
4819-
(_radio.ticker_id_upd == ticker_id));
4820-
}
48214882
#endif /* CONFIG_BT_PERIPHERAL */
48224883

48234884
#if defined(CONFIG_BT_CENTRAL)
@@ -4847,6 +4908,15 @@ static void ticker_stop_scan_assert(u32_t status, void *params)
48474908
}
48484909
#endif /* CONFIG_BT_CENTRAL */
48494910

4911+
static void ticker_update_conn_assert(u32_t status, void *params)
4912+
{
4913+
u8_t ticker_id = (u32_t)params & 0xFF;
4914+
4915+
LL_ASSERT((status == TICKER_STATUS_SUCCESS) ||
4916+
(_radio.ticker_id_stop == ticker_id) ||
4917+
(_radio.ticker_id_upd == ticker_id));
4918+
}
4919+
48504920
static void ticker_stop_conn_assert(u32_t status, void *params)
48514921
{
48524922
LL_ASSERT(status == TICKER_STATUS_SUCCESS);
@@ -8105,6 +8175,9 @@ static inline int event_len_prep(struct connection *conn)
81058175
conn->max_rx_time = conn->llcp_length.rx_time;
81068176
#endif /* CONFIG_BT_CTLR_PHY */
81078177

8178+
/* Reset event length update advanced flag */
8179+
conn->evt_len_adv = 0U;
8180+
81088181
/** TODO This design is exception as memory initialization
81098182
* and allocation is done in radio context here, breaking the
81108183
* rule that the rx buffers are allocated in application
@@ -8492,6 +8565,9 @@ static inline void event_phy_upd_ind_prep(struct connection *conn,
84928565
conn->max_tx_time = eff_tx_time;
84938566
conn->max_rx_time = eff_rx_time;
84948567

8568+
/* flag an event length update*/
8569+
conn->evt_len_upd = 1U;
8570+
84958571
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
84968572
/* Prepare the rx packet structure */
84978573
node_rx = packet_rx_reserve_get(2);

subsys/bluetooth/controller/ll_sw/ctrl_internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,11 @@ struct connection {
295295
/* Detect empty L2CAP start frame */
296296
u8_t start_empty:1;
297297

298+
#if defined(CONFIG_BT_CTLR_DATA_LENGTH) || defined(CONFIG_BT_CTLR_PHY)
299+
u8_t evt_len_upd:1;
300+
u8_t evt_len_adv:1;
301+
#endif
302+
298303
#if defined(CONFIG_BT_CTLR_CONN_RSSI)
299304
u8_t rssi_latest;
300305
u8_t rssi_reported;

0 commit comments

Comments
 (0)