Bluetooth: Controller: Fix incorrect event_count when CIG overlaps
Fix incorrect event_count use in CIG events when the next CIG interval's prepare overlaps with the current CIG event. Use separate event_count_prepare variable in ULL and copy the value in LLL event. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
3bf330855e
commit
be91cfedfb
@ -45,7 +45,8 @@ struct lll_conn_iso_stream {
|
||||
struct lll_conn_iso_stream_rxtx tx; /* TX parameters */
|
||||
|
||||
/* Event and payload counters */
|
||||
uint64_t event_count:39; /* cisEventCount */
|
||||
uint64_t event_count_prepare:39; /* cisEventCount in overlapping CIG prepare */
|
||||
uint64_t event_count:39; /* cisEventCount in current CIG event */
|
||||
|
||||
/* Acknowledgment and flow control */
|
||||
uint8_t sn:1; /* Sequence number */
|
||||
|
||||
@ -150,6 +150,9 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||
/* Get reference to ACL context */
|
||||
conn_lll = ull_conn_lll_get(cis_lll->acl_handle);
|
||||
|
||||
/* Pick the event_count calculated in the ULL prepare */
|
||||
cis_lll->event_count = cis_lll->event_count_prepare;
|
||||
|
||||
/* Event counter value, 0-15 bit of cisEventCounter */
|
||||
event_counter = cis_lll->event_count;
|
||||
|
||||
@ -357,6 +360,9 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||
do {
|
||||
cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle);
|
||||
if (cis_lll && cis_lll->active) {
|
||||
/* Pick the event_count calculated in the ULL prepare */
|
||||
cis_lll->event_count = cis_lll->event_count_prepare;
|
||||
|
||||
/* Adjust sn and nesn for skipped CIG events */
|
||||
payload_count_lazy_update(cis_lll, cig_lll->latency_event);
|
||||
|
||||
|
||||
@ -164,6 +164,9 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||
/* Get reference to ACL context */
|
||||
conn_lll = ull_conn_lll_get(cis_lll->acl_handle);
|
||||
|
||||
/* Pick the event_count calculated in the ULL prepare */
|
||||
cis_lll->event_count = cis_lll->event_count_prepare;
|
||||
|
||||
/* Event counter value, 0-15 bit of cisEventCounter */
|
||||
event_counter = cis_lll->event_count;
|
||||
|
||||
@ -374,6 +377,9 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Pick the event_count calculated in the ULL prepare */
|
||||
cis_lll->event_count = cis_lll->event_count_prepare;
|
||||
|
||||
/* Adjust sn and nesn for skipped CIG events */
|
||||
payload_count_lazy(cis_lll, cig_lll->latency_event);
|
||||
|
||||
|
||||
@ -929,6 +929,11 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle,
|
||||
#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE)
|
||||
cis->pkt_seq_num = 0U;
|
||||
#endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */
|
||||
/* It is intentional to initialize to the 39 bit maximum value and rollover to 0 in the
|
||||
* prepare function, the event counter is pre-incremented in prepare function for the
|
||||
* current ISO event.
|
||||
*/
|
||||
cis->lll.event_count_prepare = LLL_CONN_ISO_EVENT_COUNT_MAX;
|
||||
cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX;
|
||||
cis->lll.next_subevent = 0U;
|
||||
cis->lll.tifs_us = conn->lll.tifs_cis_us;
|
||||
|
||||
@ -711,17 +711,17 @@ void ull_conn_iso_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
* has been reached, and offset calculated.
|
||||
*/
|
||||
if (cis->lll.handle != 0xFFFF && cis->lll.active) {
|
||||
cis->lll.event_count += (lazy + 1U);
|
||||
cis->lll.event_count_prepare += (lazy + 1U);
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||
cis->lll.event_count -= cis->lll.lazy_active;
|
||||
cis->lll.event_count_prepare -= cis->lll.lazy_active;
|
||||
cis->lll.lazy_active = 0U;
|
||||
#endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||
|
||||
leading_event_count = MAX(leading_event_count,
|
||||
cis->lll.event_count);
|
||||
cis->lll.event_count_prepare);
|
||||
|
||||
ull_iso_lll_event_prepare(cis->lll.handle, cis->lll.event_count);
|
||||
ull_iso_lll_event_prepare(cis->lll.handle, cis->lll.event_count_prepare);
|
||||
}
|
||||
|
||||
/* Latch datapath validity entering event */
|
||||
@ -975,7 +975,7 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle,
|
||||
cis_offset = cis->offset + iso_interval_us - acl_latency_us;
|
||||
}
|
||||
|
||||
cis->lll.event_count += lost_cig_events;
|
||||
cis->lll.event_count_prepare += lost_cig_events;
|
||||
|
||||
lost_payloads = (lost_cig_events - (cis->lll.rx.ft - 1)) * cis->lll.rx.bn;
|
||||
cis->lll.rx.payload_count += lost_payloads;
|
||||
@ -1520,7 +1520,7 @@ void ull_conn_iso_transmit_test_cig_interval(uint16_t handle, uint32_t ticks_at_
|
||||
* on 64-bit sdu_counter:
|
||||
* (39 bits x 22 bits (4x10^6 us) = 61 bits / 8 bits (255 us) = 53 bits)
|
||||
*/
|
||||
sdu_counter = DIV_ROUND_UP((cis->lll.event_count + 1U) * iso_interval,
|
||||
sdu_counter = DIV_ROUND_UP((cis->lll.event_count_prepare + 1U) * iso_interval,
|
||||
sdu_interval);
|
||||
|
||||
if (cis->hdr.test_mode.tx.sdu_counter == 0U) {
|
||||
|
||||
@ -333,6 +333,11 @@ uint8_t ull_peripheral_iso_setup(struct pdu_data_llctrl_cis_ind *ind,
|
||||
#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE)
|
||||
cis->pkt_seq_num = 0U;
|
||||
#endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */
|
||||
/* It is intentional to initialize to the 39 bit maximum value and rollover to 0 in the
|
||||
* prepare function, the event counter is pre-incremented in prepare function for the
|
||||
* current ISO event.
|
||||
*/
|
||||
cis->lll.event_count_prepare = LLL_CONN_ISO_EVENT_COUNT_MAX;
|
||||
cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX;
|
||||
cis->lll.next_subevent = 0U;
|
||||
cis->lll.tifs_us = conn->lll.tifs_cis_us;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user