Skip to content

Commit c22f40a

Browse files
cvinayaknashif
authored andcommitted
Bluetooth: Controller: Fix max PDU len radio config for BIS Ctrl PDUs
Fix missing radio configuration that limits the maximum PDU len on reception to consider that Control PDU can be larger than the max PDU size in the BIS parameters. Use dedicated PDU buffer for transmission and reception of BIG Control PDUs so that it is independent of maximum ISO PDU length which can be less than BIG Control PDU length. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 11574c0 commit c22f40a

File tree

4 files changed

+82
-25
lines changed

4 files changed

+82
-25
lines changed

subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,18 @@ void *radio_pkt_decrypt_get(void)
667667
#error "Undefined HAL_RADIO_PDU_LEN_MAX."
668668
#endif
669669

670+
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_SYNC_ISO)
671+
/* Dedicated Rx PDU Buffer for Control PDU independent of node_rx with BIS Data
672+
* PDU buffer
673+
*/
674+
static uint8_t pkt_big_ctrl[sizeof(struct pdu_big_ctrl)];
675+
676+
void *radio_pkt_big_ctrl_get(void)
677+
{
678+
return pkt_big_ctrl;
679+
}
680+
#endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_SYNC_ISO */
681+
670682
#if !defined(CONFIG_BT_CTLR_TIFS_HW)
671683
static uint8_t sw_tifs_toggle;
672684
/**

subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ uint32_t radio_crc_is_valid(void);
9494
void *radio_pkt_empty_get(void);
9595
void *radio_pkt_scratch_get(void);
9696
void *radio_pkt_decrypt_get(void);
97+
void *radio_pkt_big_ctrl_get(void);
9798

9899
void radio_switch_complete_and_rx(uint8_t phy_rx);
99100
void radio_switch_complete_and_tx(uint8_t phy_rx, uint8_t flags_rx, uint8_t phy_tx,

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ static void isr_tx_common(void *param,
505505
*/
506506
struct pdu_big_ctrl_term_ind *term;
507507

508-
pdu = radio_pkt_scratch_get();
508+
pdu = radio_pkt_big_ctrl_get();
509509
pdu->ll_id = PDU_BIS_LLID_CTRL;
510510
pdu->cssn = lll->cssn;
511511
pdu->cstf = 0U;
@@ -529,7 +529,7 @@ static void isr_tx_common(void *param,
529529
*/
530530
struct pdu_big_ctrl_chan_map_ind *chm;
531531

532-
pdu = radio_pkt_scratch_get();
532+
pdu = radio_pkt_big_ctrl_get();
533533
pdu->ll_id = PDU_BIS_LLID_CTRL;
534534
pdu->cssn = lll->cssn;
535535
pdu->cstf = 0U;
@@ -696,6 +696,21 @@ static void isr_tx_common(void *param,
696696

697697
/* Control subevent, then complete subevent and close radio use */
698698
if (!bis) {
699+
uint8_t pkt_flags;
700+
701+
pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS,
702+
lll->phy,
703+
RADIO_PKT_CONF_CTE_DISABLED);
704+
if (lll->enc) {
705+
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
706+
(sizeof(struct pdu_big_ctrl) + PDU_MIC_SIZE),
707+
pkt_flags);
708+
} else {
709+
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
710+
sizeof(struct pdu_big_ctrl),
711+
pkt_flags);
712+
}
713+
699714
radio_switch_complete_and_disable();
700715

701716
radio_isr_set(isr_done_term, lll);

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

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -563,22 +563,12 @@ static void isr_rx(void *param)
563563
lll->ctrl) {
564564
lll->cssn_curr = lll->cssn_next;
565565

566-
/* By design, there shall alway be one free node rx
567-
* available for setting up radio for new PDU reception.
568-
* Control procedure handling does not consume any
569-
* node rx, hence checking for one free node rx is
570-
* sufficient.
571-
*/
572-
node_rx = ull_iso_pdu_rx_alloc_peek(1U);
573-
LL_ASSERT(node_rx);
574-
575-
pdu = (void *)node_rx->pdu;
576-
if (pdu->ll_id != PDU_BIS_LLID_CTRL) {
577-
goto isr_rx_done;
566+
/* Check the dedicated Control PDU buffer */
567+
pdu = radio_pkt_big_ctrl_get();
568+
if (pdu->ll_id == PDU_BIS_LLID_CTRL) {
569+
isr_rx_ctrl_recv(lll, pdu);
578570
}
579571

580-
isr_rx_ctrl_recv(lll, pdu);
581-
582572
goto isr_rx_done;
583573
} else {
584574
/* Check if there are 2 free rx buffers, one will be
@@ -794,6 +784,8 @@ static void isr_rx(void *param)
794784

795785
/* Control subevent */
796786
if (!lll->ctrl && (lll->cssn_next != lll->cssn_curr)) {
787+
uint8_t pkt_flags;
788+
797789
/* Receive the control PDU and close the BIG event
798790
* there after.
799791
*/
@@ -802,6 +794,22 @@ static void isr_rx(void *param)
802794
/* control subevent to use bis = 0 and se_n = 1 */
803795
bis = 0U;
804796

797+
/* Configure Radio to receive Control PDU that can have greater
798+
* PDU length than max_pdu length.
799+
*/
800+
pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS,
801+
lll->phy,
802+
RADIO_PKT_CONF_CTE_DISABLED);
803+
if (lll->enc) {
804+
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
805+
(sizeof(struct pdu_big_ctrl) + PDU_MIC_SIZE),
806+
pkt_flags);
807+
} else {
808+
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
809+
sizeof(struct pdu_big_ctrl),
810+
pkt_flags);
811+
}
812+
805813
goto isr_rx_next_subevent;
806814
}
807815

@@ -997,31 +1005,52 @@ static void isr_rx(void *param)
9971005

9981006
lll_chan_set(data_chan_use);
9991007

1000-
/* By design, there shall alway be one free node rx available for
1001-
* setting up radio for new PDU reception.
1002-
*/
1003-
node_rx = ull_iso_pdu_rx_alloc_peek(1U);
1004-
LL_ASSERT(node_rx);
1005-
10061008
/* Encryption */
10071009
if (lll->enc) {
10081010
uint64_t payload_count;
1011+
struct pdu_bis *pdu;
10091012

10101013
payload_count = lll->payload_count - lll->bn;
10111014
if (bis) {
10121015
payload_count += (lll->bn_curr - 1U) +
10131016
(lll->ptc_curr * lll->pto);
1017+
1018+
/* By design, there shall alway be one free node rx
1019+
* available for setting up radio for new PDU reception.
1020+
*/
1021+
node_rx = ull_iso_pdu_rx_alloc_peek(1U);
1022+
LL_ASSERT(node_rx);
1023+
1024+
pdu = (void *)node_rx->pdu;
1025+
} else {
1026+
/* Use the dedicated Control PDU buffer */
1027+
pdu = radio_pkt_big_ctrl_get();
10141028
}
10151029

10161030
lll->ccm_rx.counter = payload_count;
10171031

10181032
(void)memcpy(lll->ccm_rx.iv, lll->giv, 4U);
10191033
mem_xor_32(lll->ccm_rx.iv, lll->ccm_rx.iv, access_addr);
10201034

1021-
radio_pkt_rx_set(radio_ccm_rx_pkt_set(&lll->ccm_rx, lll->phy,
1022-
node_rx->pdu));
1035+
radio_pkt_rx_set(radio_ccm_rx_pkt_set(&lll->ccm_rx, lll->phy, pdu));
1036+
10231037
} else {
1024-
radio_pkt_rx_set(node_rx->pdu);
1038+
struct pdu_bis *pdu;
1039+
1040+
if (bis) {
1041+
/* By design, there shall alway be one free node rx
1042+
* available for setting up radio for new PDU reception.
1043+
*/
1044+
node_rx = ull_iso_pdu_rx_alloc_peek(1U);
1045+
LL_ASSERT(node_rx);
1046+
1047+
pdu = (void *)node_rx->pdu;
1048+
} else {
1049+
/* Use the dedicated Control PDU buffer */
1050+
pdu = radio_pkt_big_ctrl_get();
1051+
}
1052+
1053+
radio_pkt_rx_set(pdu);
10251054
}
10261055

10271056
radio_switch_complete_and_disable();

0 commit comments

Comments
 (0)