fixup! Bluetooth: Controller: Fix incorrect CIS payload count at CIS Estab
Fix incorrect payload count at CIS Establish due to existing CIG event overlapping the ACL event at the instant when the CIS gets the active flag set. The overlapping CIG event picked up the new CIS that had its active flag set in the current CIG event instead of at the actual CIS offset which is in the next CIG event. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
306b6ecdfc
commit
dd1c3948ca
6 changed files with 25 additions and 22 deletions
|
@ -58,11 +58,14 @@ struct lll_conn_iso_stream {
|
|||
uint8_t datapath_ready_rx:1;/* 1 if datapath for RX is ready */
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||
/* A CIS LLL is active and established in a CIG radio event when ACL instant has passed
|
||||
* which set the `active` flag and then when CIG event prepare has picked up the set
|
||||
/* A CIS LLL is active and prepared in a CIG radio event when ACL instant has passed
|
||||
* which set the `active` flag and then when CIG event prepare in LLL has picked up the set
|
||||
* `active` flag.
|
||||
* FIXME: There is suspected possibility that ACL ULL Prepare that is processing LLCP could
|
||||
* execute between CIG ULL Prepare and deferred CIG LLL Prepare say when there is
|
||||
* already another state/role that the CIG tries to pre-empt.
|
||||
*/
|
||||
uint8_t established:1;
|
||||
uint8_t prepared:1;
|
||||
/* Lazy at CIS active. Number of previously skipped CIG events that is
|
||||
* determined when CIS is made active and subtracted from total CIG
|
||||
* events that where skipped when this CIS gets to use radio for the
|
||||
|
|
|
@ -144,11 +144,11 @@ static int prepare_cb(struct lll_prepare_param *p)
|
|||
|
||||
LL_ASSERT(cis_lll);
|
||||
|
||||
/* Unconditionally set the established flag.
|
||||
/* Unconditionally set the prepared flag.
|
||||
* This flag ensures current CIG event does not pick up a new CIS becoming active when the
|
||||
* ACL overlaps at the instant with this already started CIG events.
|
||||
*/
|
||||
cis_lll->established = 1U;
|
||||
cis_lll->prepared = 1U;
|
||||
|
||||
/* Save first active CIS offset */
|
||||
cis_offset_first = cis_lll->offset;
|
||||
|
@ -366,12 +366,12 @@ 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) {
|
||||
/* Unconditionally set the established flag.
|
||||
/* Unconditionally set the prepared flag.
|
||||
* This flag ensures current CIG event does not pick up a new CIS becoming
|
||||
* active when the ACL overlaps at the instant with this already started
|
||||
* CIG events.
|
||||
*/
|
||||
cis_lll->established = 1U;
|
||||
cis_lll->prepared = 1U;
|
||||
|
||||
/* Pick the event_count calculated in the ULL prepare */
|
||||
cis_lll->event_count = cis_lll->event_count_prepare;
|
||||
|
@ -417,7 +417,7 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
|
|||
do {
|
||||
next_cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll,
|
||||
&cis_handle_curr);
|
||||
if (next_cis_lll && next_cis_lll->established) {
|
||||
if (next_cis_lll && next_cis_lll->prepared) {
|
||||
payload_count_flush_or_inc_on_close(next_cis_lll);
|
||||
}
|
||||
} while (next_cis_lll);
|
||||
|
@ -599,7 +599,7 @@ static void isr_tx(void *param)
|
|||
cis_handle = cis_handle_curr;
|
||||
do {
|
||||
next_cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle);
|
||||
} while (next_cis_lll && !next_cis_lll->established);
|
||||
} while (next_cis_lll && !next_cis_lll->prepared);
|
||||
|
||||
if (!next_cis_lll) {
|
||||
return;
|
||||
|
@ -843,7 +843,7 @@ isr_rx_next_subevent:
|
|||
do {
|
||||
next_cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll,
|
||||
&cis_handle_curr);
|
||||
} while (next_cis_lll && !next_cis_lll->established);
|
||||
} while (next_cis_lll && !next_cis_lll->prepared);
|
||||
|
||||
if (!next_cis_lll) {
|
||||
goto isr_rx_done;
|
||||
|
|
|
@ -158,11 +158,11 @@ static int prepare_cb(struct lll_prepare_param *p)
|
|||
|
||||
LL_ASSERT(cis_lll);
|
||||
|
||||
/* Unconditionally set the established flag.
|
||||
/* Unconditionally set the prepared flag.
|
||||
* This flag ensures current CIG event does not pick up a new CIS becoming active when the
|
||||
* ACL overlaps at the instant with this already started CIG events.
|
||||
*/
|
||||
cis_lll->established = 1U;
|
||||
cis_lll->prepared = 1U;
|
||||
|
||||
/* Save first active CIS offset */
|
||||
cis_offset_first = cis_lll->offset;
|
||||
|
@ -383,11 +383,11 @@ static int prepare_cb(struct lll_prepare_param *p)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Unconditionally set the established flag.
|
||||
/* Unconditionally set the prepared flag.
|
||||
* This flag ensures current CIG event does not pick up a new CIS becoming active
|
||||
* when the ACL overlaps at the instant with this already started CIG events.
|
||||
*/
|
||||
cis_lll->established = 1U;
|
||||
cis_lll->prepared = 1U;
|
||||
|
||||
/* Pick the event_count calculated in the ULL prepare */
|
||||
cis_lll->event_count = cis_lll->event_count_prepare;
|
||||
|
@ -433,7 +433,7 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
|
|||
next_cis_lll =
|
||||
ull_conn_iso_lll_stream_sorted_get_by_group(cig_lll,
|
||||
&cis_handle_curr);
|
||||
if (next_cis_lll && next_cis_lll->established) {
|
||||
if (next_cis_lll && next_cis_lll->prepared) {
|
||||
payload_count_rx_flush_or_txrx_inc(next_cis_lll);
|
||||
}
|
||||
} while (next_cis_lll);
|
||||
|
@ -794,7 +794,7 @@ static void isr_rx(void *param)
|
|||
do {
|
||||
next_cis_lll =
|
||||
ull_conn_iso_lll_stream_sorted_get_by_group(cig_lll, &cis_handle);
|
||||
} while (next_cis_lll && !next_cis_lll->established);
|
||||
} while (next_cis_lll && !next_cis_lll->prepared);
|
||||
|
||||
if (!next_cis_lll) {
|
||||
/* ISO Event Done */
|
||||
|
@ -1006,7 +1006,7 @@ static void next_cis_prepare(void *param)
|
|||
cis_handle = cis_handle_curr;
|
||||
do {
|
||||
next_cis_lll = ull_conn_iso_lll_stream_sorted_get_by_group(cig_lll, &cis_handle);
|
||||
} while (next_cis_lll && !next_cis_lll->established);
|
||||
} while (next_cis_lll && !next_cis_lll->prepared);
|
||||
|
||||
if (!next_cis_lll) {
|
||||
/* ISO Event Done */
|
||||
|
|
|
@ -922,7 +922,7 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle,
|
|||
cis->offset = *cis_offset_min;
|
||||
}
|
||||
|
||||
cis->lll.established = 0U;
|
||||
cis->lll.prepared = 0U;
|
||||
#endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||
|
||||
cis->central.instant = instant;
|
||||
|
|
|
@ -1079,7 +1079,7 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle,
|
|||
|
||||
/* Initialize CIS event lazy at CIS create */
|
||||
cis->lll.lazy_active = 0U;
|
||||
cis->lll.established = 0U;
|
||||
cis->lll.prepared = 0U;
|
||||
#endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||
|
||||
/* Start CIS peripheral CIG ticker */
|
||||
|
@ -1183,7 +1183,7 @@ static void mfy_cis_lazy_fill(void *param)
|
|||
* CIG before the CIS gets active that be decremented when event_count
|
||||
* is incremented in ull_conn_iso_ticker_cb().
|
||||
*/
|
||||
cis->lll.established = 0U;
|
||||
cis->lll.prepared = 0U;
|
||||
cis->lll.active = 1U;
|
||||
cis->lll.lazy_active = lazy;
|
||||
}
|
||||
|
@ -1375,7 +1375,7 @@ static void cis_tx_lll_flush(void *param)
|
|||
lll->active = 0U;
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||
lll->established = 0U;
|
||||
lll->prepared = 0U;
|
||||
#endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl,
|
|||
cis->lll.active = 0U;
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||
cis->lll.established = 0U;
|
||||
cis->lll.prepared = 0U;
|
||||
#endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||
|
||||
cis->lll.handle = LLL_HANDLE_INVALID;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue