Bluetooth: Controller: Option to ignore Tx ISO Data Packet Seq Num
Kconfig option to turn off ISO Data Packet Sequence Number use to place the ISO Data in the correct radio event, instead simply buffer it to next radio event. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
e3ecab3142
commit
61d00467b4
5 changed files with 111 additions and 16 deletions
|
@ -499,7 +499,8 @@ config BT_CTLR_SCAN_ENABLE_STRICT
|
|||
|
||||
config BT_CTLR_ISOAL_SN_STRICT
|
||||
bool "Enforce Strict Tx ISO Data Sequence Number use"
|
||||
depends on BT_CTLR_ADV_ISO || BT_CTLR_CONN_ISO
|
||||
depends on !BT_CTLR_ISOAL_PSN_IGNORE && (BT_CTLR_ADV_ISO || \
|
||||
BT_CTLR_CONN_ISO)
|
||||
default y
|
||||
help
|
||||
Enforce strict sequencing of released payloads based on the TX SDU's
|
||||
|
@ -517,6 +518,12 @@ config BT_CTLR_ISOAL_SN_STRICT
|
|||
dropped. This will result in better delivery of data to the receiver
|
||||
but at the cost of creating skews in the received stream of SDUs.
|
||||
|
||||
config BT_CTLR_ISOAL_PSN_IGNORE
|
||||
bool "Ignore Tx ISO Data Packet Sequence Number use"
|
||||
depends on BT_CTLR_ADV_ISO || BT_CTLR_CONN_ISO
|
||||
help
|
||||
Ignore the use of Tx ISO Data Packet Sequence Number.
|
||||
|
||||
config BT_CTLR_ZLI
|
||||
bool "Use Zero Latency IRQs"
|
||||
depends on ZERO_LATENCY_IRQS
|
||||
|
|
|
@ -5657,8 +5657,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt)
|
|||
struct bt_hci_iso_data_hdr *iso_data_hdr;
|
||||
struct isoal_sdu_tx sdu_frag_tx;
|
||||
struct bt_hci_iso_hdr *iso_hdr;
|
||||
struct ll_iso_datapath *dp_in;
|
||||
struct ll_iso_stream_hdr *hdr;
|
||||
uint32_t *time_stamp;
|
||||
uint16_t handle;
|
||||
uint8_t pb_flag;
|
||||
|
@ -5668,8 +5666,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt)
|
|||
|
||||
iso_data_hdr = NULL;
|
||||
*evt = NULL;
|
||||
hdr = NULL;
|
||||
dp_in = NULL;
|
||||
|
||||
if (buf->len < sizeof(*iso_hdr)) {
|
||||
LOG_ERR("No HCI ISO header");
|
||||
|
@ -5747,16 +5743,49 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt)
|
|||
* data path
|
||||
*/
|
||||
} else if (IS_CIS_HANDLE(handle)) {
|
||||
struct ll_conn_iso_stream *cis =
|
||||
ll_iso_stream_connected_get(handle);
|
||||
struct ll_conn_iso_stream *cis;
|
||||
struct ll_conn_iso_group *cig;
|
||||
struct ll_iso_stream_hdr *hdr;
|
||||
struct ll_iso_datapath *dp_in;
|
||||
|
||||
cis = ll_iso_stream_connected_get(handle);
|
||||
if (!cis) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct ll_conn_iso_group *cig = cis->group;
|
||||
uint8_t event_offset;
|
||||
cig = cis->group;
|
||||
|
||||
hdr = &(cis->hdr);
|
||||
#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE)
|
||||
uint64_t event_count;
|
||||
uint64_t pkt_seq_num;
|
||||
|
||||
/* Catch up local pkt_seq_num with internal pkt_seq_num */
|
||||
event_count = cis->lll.event_count;
|
||||
pkt_seq_num = event_count + 1U;
|
||||
if (!(pb_flag & 0x01) &&
|
||||
(((pkt_seq_num - cis->pkt_seq_num) &
|
||||
BIT64_MASK(39)) <= BIT64_MASK(38))) {
|
||||
cis->pkt_seq_num = pkt_seq_num;
|
||||
} else {
|
||||
pkt_seq_num = cis->pkt_seq_num;
|
||||
}
|
||||
|
||||
/* Pre-increment, for next ISO data packet seq num comparison */
|
||||
if (pb_flag & 0x10) {
|
||||
cis->pkt_seq_num++;
|
||||
}
|
||||
|
||||
/* Target next event to avoid overlapping with current event */
|
||||
pkt_seq_num++;
|
||||
sdu_frag_tx.target_event = pkt_seq_num;
|
||||
sdu_frag_tx.grp_ref_point =
|
||||
isoal_get_wrapped_time_us(cig->cig_ref_point,
|
||||
((pkt_seq_num - event_count) *
|
||||
cig->iso_interval *
|
||||
ISO_INT_UNIT_US));
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */
|
||||
uint8_t event_offset;
|
||||
|
||||
/* We must ensure sufficient time for ISO-AL to fragment SDU and
|
||||
* deliver PDUs to the TX queue. By checking ull_ref_get, we
|
||||
|
@ -5780,11 +5809,15 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt)
|
|||
}
|
||||
|
||||
sdu_frag_tx.target_event = cis->lll.event_count + event_offset;
|
||||
sdu_frag_tx.grp_ref_point = isoal_get_wrapped_time_us(cig->cig_ref_point,
|
||||
(event_offset * cig->iso_interval *
|
||||
ISO_INT_UNIT_US));
|
||||
sdu_frag_tx.grp_ref_point =
|
||||
isoal_get_wrapped_time_us(cig->cig_ref_point,
|
||||
(event_offset *
|
||||
cig->iso_interval *
|
||||
ISO_INT_UNIT_US));
|
||||
#endif /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */
|
||||
|
||||
/* Get controller's input data path for CIS */
|
||||
hdr = &(cis->hdr);
|
||||
dp_in = hdr->datapath_in;
|
||||
if (!dp_in || dp_in->path_id != BT_HCI_DATAPATH_ID_HCI) {
|
||||
LOG_ERR("Input data path not set for HCI");
|
||||
|
@ -5817,8 +5850,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt)
|
|||
struct ll_adv_iso_set *adv_iso;
|
||||
struct lll_adv_iso *lll_iso;
|
||||
uint16_t stream_handle;
|
||||
uint8_t target_event;
|
||||
uint8_t event_offset;
|
||||
uint16_t slen;
|
||||
|
||||
/* FIXME: Code only expects header present */
|
||||
|
@ -5844,6 +5875,53 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
lll_iso = &adv_iso->lll;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE)
|
||||
uint64_t event_count;
|
||||
uint64_t pkt_seq_num;
|
||||
|
||||
/* Catch up local pkt_seq_num with internal pkt_seq_num */
|
||||
event_count = lll_iso->payload_count / lll_iso->bn;
|
||||
pkt_seq_num = event_count;
|
||||
if (!(pb_flag & 0x01) &&
|
||||
(((pkt_seq_num - stream->pkt_seq_num) &
|
||||
BIT64_MASK(39)) <= BIT64_MASK(38))) {
|
||||
stream->pkt_seq_num = pkt_seq_num;
|
||||
} else {
|
||||
pkt_seq_num = stream->pkt_seq_num;
|
||||
}
|
||||
|
||||
/* Pre-increment, for next ISO data packet seq num comparison */
|
||||
if (pb_flag & 0x10) {
|
||||
stream->pkt_seq_num++;
|
||||
}
|
||||
|
||||
/* Target next event to avoid overlapping with current event */
|
||||
/* FIXME: Implement ISO Tx ack generation early in done compared
|
||||
* to currently only in prepare. I.e. to ensure upper
|
||||
* layer has the number of completed packet before the
|
||||
* next BIG event, so as to supply new ISO data packets.
|
||||
* Without which upper layers need extra buffers to
|
||||
* buffer next ISO data packet.
|
||||
*
|
||||
* Enable below increment once early Tx ack is
|
||||
* implemented.
|
||||
*
|
||||
* pkt_seq_num++;
|
||||
*/
|
||||
sdu_frag_tx.target_event = pkt_seq_num;
|
||||
sdu_frag_tx.grp_ref_point =
|
||||
isoal_get_wrapped_time_us(adv_iso->big_ref_point,
|
||||
(((pkt_seq_num + 1U) -
|
||||
event_count) *
|
||||
lll_iso->iso_interval *
|
||||
ISO_INT_UNIT_US));
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */
|
||||
uint8_t target_event;
|
||||
uint8_t event_offset;
|
||||
|
||||
/* Determine the target event and the first event offset after
|
||||
* datapath setup.
|
||||
* event_offset mitigates the possibility of first SDU being
|
||||
|
@ -5861,7 +5939,6 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt)
|
|||
* BIG event by incrementing the previous elapsed big_ref_point
|
||||
* by one additional ISO interval.
|
||||
*/
|
||||
lll_iso = &adv_iso->lll;
|
||||
target_event = lll_iso->payload_count / lll_iso->bn;
|
||||
event_offset = ull_ref_get(&adv_iso->ull) ? 0U : 1U;
|
||||
event_offset += lll_iso->latency_prepare;
|
||||
|
@ -5872,6 +5949,7 @@ int hci_iso_handle(struct net_buf *buf, struct net_buf **evt)
|
|||
((event_offset + 1U) *
|
||||
lll_iso->iso_interval *
|
||||
ISO_INT_UNIT_US));
|
||||
#endif /* !CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */
|
||||
|
||||
/* Start Fragmentation */
|
||||
/* FIXME: need to ensure ISO-AL returns proper isoal_status.
|
||||
|
|
|
@ -883,6 +883,9 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle,
|
|||
#endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||
|
||||
cis->central.instant = instant;
|
||||
#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE)
|
||||
cis->pkt_seq_num = 0U;
|
||||
#endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */
|
||||
cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX;
|
||||
cis->lll.next_subevent = 0U;
|
||||
cis->lll.sn = 0U;
|
||||
|
|
|
@ -48,6 +48,10 @@ struct ll_conn_iso_stream {
|
|||
*/
|
||||
uint8_t terminate_reason;
|
||||
uint8_t cis_id;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE)
|
||||
uint64_t pkt_seq_num:39;
|
||||
#endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */
|
||||
};
|
||||
|
||||
struct ll_conn_iso_group {
|
||||
|
|
|
@ -326,6 +326,9 @@ uint8_t ull_peripheral_iso_setup(struct pdu_data_llctrl_cis_ind *ind,
|
|||
cis->sync_delay = sys_get_le24(ind->cis_sync_delay);
|
||||
cis->offset = cis_offset;
|
||||
memcpy(cis->lll.access_addr, ind->aa, sizeof(ind->aa));
|
||||
#if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE)
|
||||
cis->pkt_seq_num = 0U;
|
||||
#endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */
|
||||
cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX;
|
||||
cis->lll.next_subevent = 0U;
|
||||
cis->lll.sn = 0U;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue