Skip to content

Commit 9c95dce

Browse files
cvinayakaescolar
authored andcommitted
Bluetooth: Controller: Fix incorrect use of rx buffer in Tx ISR
Do not enqueue node rx buffers for generating invalid ISO data from Tx ISR while supplying the node rx buffer to Radio. This causes node rx pool corruption and also MIC failures in the central ISO LLL. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 038c89b commit 9c95dce

File tree

1 file changed

+36
-83
lines changed

1 file changed

+36
-83
lines changed

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c

Lines changed: 36 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,6 @@ static void isr_tx(void *param)
540540
&data_chan_prn_s,
541541
&data_chan_remap_idx);
542542
} else {
543-
struct lll_conn_iso_stream *old_cis_lll;
544543
struct lll_conn_iso_stream *next_cis_lll;
545544
struct lll_conn_iso_group *cig_lll;
546545
struct lll_conn *next_conn_lll;
@@ -552,7 +551,6 @@ static void isr_tx(void *param)
552551
uint16_t cis_handle;
553552
uint32_t start_us;
554553
memq_link_t *link;
555-
uint8_t bn;
556554

557555
/* Calculate channel for next CIS */
558556
cig_lll = ull_conn_iso_lll_group_get_by_stream(cis_lll);
@@ -585,7 +583,6 @@ static void isr_tx(void *param)
585583
start_us = radio_tmr_start_us(1U, subevent_us);
586584
LL_ASSERT(start_us == (subevent_us + 1U));
587585

588-
old_cis_lll = cis_lll;
589586
cis_lll = next_cis_lll;
590587

591588
/* Tx Ack stale ISO Data */
@@ -618,49 +615,6 @@ static void isr_tx(void *param)
618615
break;
619616
}
620617
} while (link);
621-
622-
cis_lll = old_cis_lll;
623-
624-
/* Generate ISO Data Invalid Status */
625-
bn = bn_rx;
626-
while (bn <= cis_lll->rx.bn) {
627-
struct node_rx_iso_meta *iso_meta;
628-
struct node_rx_pdu *node_rx;
629-
630-
/* Ensure there is always one free for reception of
631-
* ISO PDU by the radio h/w DMA, hence peek for two
632-
* available ISO PDU when using one for generating
633-
* invalid ISO data.
634-
*/
635-
node_rx = ull_iso_pdu_rx_alloc_peek(2U);
636-
if (!node_rx) {
637-
break;
638-
}
639-
640-
node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU;
641-
node_rx->hdr.handle = cis_lll->handle;
642-
iso_meta = &node_rx->hdr.rx_iso_meta;
643-
iso_meta->payload_number = (cis_lll->event_count *
644-
cis_lll->rx.bn) + (bn - 1U);
645-
iso_meta->timestamp =
646-
HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) +
647-
radio_tmr_ready_restore();
648-
iso_meta->timestamp %=
649-
HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U));
650-
iso_meta->status = 1U;
651-
652-
ull_iso_pdu_rx_alloc();
653-
iso_rx_put(node_rx->hdr.link, node_rx);
654-
655-
bn++;
656-
}
657-
658-
#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL)
659-
if (bn != bn_rx) {
660-
iso_rx_sched();
661-
}
662-
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */
663-
664618
}
665619
}
666620

@@ -823,6 +777,7 @@ static void isr_rx(void *param)
823777
struct lll_conn_iso_group *cig_lll;
824778
struct lll_conn *next_conn_lll;
825779
uint8_t phy;
780+
uint8_t bn;
826781

827782
/* Fetch next CIS */
828783
/* TODO: Use a new ull_conn_iso_lll_stream_get_active_by_group()
@@ -864,7 +819,6 @@ static void isr_rx(void *param)
864819
uint32_t subevent_us;
865820
uint32_t start_us;
866821
memq_link_t *link;
867-
uint8_t bn;
868822

869823
/* Event counter value, 0-15 bit of cisEventCounter */
870824
event_counter = next_cis_lll->event_count;
@@ -918,49 +872,48 @@ static void isr_rx(void *param)
918872
} while (link);
919873

920874
cis_lll = old_cis_lll;
875+
}
921876

922-
/* Generate ISO Data Invalid Status */
923-
bn = bn_rx;
924-
while (bn <= cis_lll->rx.bn) {
925-
struct node_rx_iso_meta *iso_meta;
926-
struct node_rx_pdu *node_rx;
927-
928-
/* Ensure there is always one free for reception
929-
* of ISO PDU by the radio h/w DMA, hence peek
930-
* for two available ISO PDU when using one for
931-
* generating invalid ISO data.
932-
*/
933-
node_rx = ull_iso_pdu_rx_alloc_peek(2U);
934-
if (!node_rx) {
935-
break;
936-
}
877+
/* Generate ISO Data Invalid Status */
878+
bn = bn_rx;
879+
while (bn <= cis_lll->rx.bn) {
880+
struct node_rx_iso_meta *iso_meta;
881+
struct node_rx_pdu *node_rx;
937882

938-
node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU;
939-
node_rx->hdr.handle = cis_lll->handle;
940-
iso_meta = &node_rx->hdr.rx_iso_meta;
941-
iso_meta->payload_number = (cis_lll->event_count *
942-
cis_lll->rx.bn) + (bn - 1U);
943-
iso_meta->timestamp =
944-
HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) +
945-
radio_tmr_ready_restore();
946-
iso_meta->timestamp %=
947-
HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U));
948-
iso_meta->status = 1U;
949-
950-
ull_iso_pdu_rx_alloc();
951-
iso_rx_put(node_rx->hdr.link, node_rx);
952-
953-
bn++;
883+
/* Ensure there is always one free for reception
884+
* of ISO PDU by the radio h/w DMA, hence peek
885+
* for two available ISO PDU when using one for
886+
* generating invalid ISO data.
887+
*/
888+
node_rx = ull_iso_pdu_rx_alloc_peek(2U);
889+
if (!node_rx) {
890+
break;
954891
}
955892

956-
#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL)
957-
if (bn != bn_rx) {
958-
iso_rx_sched();
959-
}
960-
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */
893+
node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU;
894+
node_rx->hdr.handle = cis_lll->handle;
895+
iso_meta = &node_rx->hdr.rx_iso_meta;
896+
iso_meta->payload_number = (cis_lll->event_count *
897+
cis_lll->rx.bn) + (bn - 1U);
898+
iso_meta->timestamp =
899+
HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) +
900+
radio_tmr_ready_restore();
901+
iso_meta->timestamp %=
902+
HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U));
903+
iso_meta->status = 1U;
961904

905+
ull_iso_pdu_rx_alloc();
906+
iso_rx_put(node_rx->hdr.link, node_rx);
907+
908+
bn++;
962909
}
963910

911+
#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL)
912+
if (bn != bn_rx) {
913+
iso_rx_sched();
914+
}
915+
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */
916+
964917
/* Reset indices for the next CIS */
965918
se_curr = 0U; /* isr_prepare_subevent() will increase se_curr */
966919
bn_tx = 1U;

0 commit comments

Comments
 (0)