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
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue