Bluetooth: Controller: Fix nRF CCM disable on connection event abort

Fix missing nRF CCM disable on connection event abort.

There can be a problem on nRF SoC for example when a S8
"encrypted" reception is aborted, and a 2M "cleartext"
reception starts; slow CCM (that is not stopped as part of
radio disable) will corrupt a fast received "cleartext" when
the same current free rx buffer is reused in the Controller.
This is not a problem when the connection being abort-ee is
on a faster PHY than the abort-er.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2025-04-05 02:30:03 +02:00 committed by Benjamin Cabé
parent d2ebe9c6de
commit 2fc54ae3bb
6 changed files with 41 additions and 0 deletions

View File

@ -2511,6 +2511,12 @@ uint32_t radio_ccm_mic_is_valid(void)
return (NRF_CCM->MICSTATUS != 0);
}
void radio_ccm_disable(void)
{
nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_STOP);
nrf_ccm_disable(NRF_CCM);
}
#if defined(CONFIG_BT_CTLR_PRIVACY)
static uint8_t MALIGN(4) _aar_scratch[3];

View File

@ -179,6 +179,7 @@ void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt);
void *radio_ccm_iso_tx_pkt_set(struct ccm *ccm, uint8_t pdu_type, void *pkt);
uint32_t radio_ccm_is_done(void);
uint32_t radio_ccm_mic_is_valid(void);
void radio_ccm_disable(void);
void radio_ar_configure(uint32_t nirk, void *irk, uint8_t flags);
uint32_t radio_ar_match_get(void);

View File

@ -429,6 +429,15 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
radio_isr_set(isr_done, cis_lll);
radio_disable();
#if defined(CONFIG_BT_CTLR_LE_ENC)
/* Get reference to ACL context */
const struct lll_conn *conn_lll = ull_conn_lll_get(cis_lll->acl_handle);
if (conn_lll->enc_rx) {
radio_ccm_disable();
}
#endif /* CONFIG_BT_CTLR_LE_ENC */
return;
}

View File

@ -228,6 +228,13 @@ void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param)
*/
radio_isr_set(isr_done, param);
radio_disable();
#if defined(CONFIG_BT_CTLR_LE_ENC)
if (lll->enc_rx) {
radio_ccm_disable();
}
#endif /* CONFIG_BT_CTLR_LE_ENC */
return;
}

View File

@ -445,6 +445,15 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
radio_isr_set(isr_done, cis_lll);
radio_disable();
#if defined(CONFIG_BT_CTLR_LE_ENC)
/* Get reference to ACL context */
const struct lll_conn *conn_lll = ull_conn_lll_get(cis_lll->acl_handle);
if (conn_lll->enc_rx) {
radio_ccm_disable();
}
#endif /* CONFIG_BT_CTLR_LE_ENC */
return;
}

View File

@ -482,6 +482,15 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
if (!prepare_param) {
radio_isr_set(isr_done, param);
radio_disable();
if (IS_ENABLED(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)) {
const struct lll_sync_iso *lll = param;
if (lll->enc) {
radio_ccm_disable();
}
}
return;
}