From 9a340fec4c264b2df0dd007642ff22406a4376bb Mon Sep 17 00:00:00 2001
From: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
Date: Mon, 23 Sep 2024 05:55:01 +0200
Subject: [PATCH] Bluetooth: Controller: Add NRF_CCM support in nRF54L15 SoC

Add NRF_CCM h/w based encryption support in nRF54L15 SoCs.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
---
 .../bluetooth/controller/Kconfig.ll_sw_split  |   6 +-
 .../ll_sw/nordic/hal/nrf5/radio/radio.c       | 297 +++++++++++++++---
 .../nordic/hal/nrf5/radio/radio_nrf54lx.h     |  13 +
 .../nordic/hal/nrf5/radio/radio_nrf5_dppi.h   |  18 +-
 .../nrf5/radio/radio_nrf5_dppi_resources.h    |   8 +
 5 files changed, 302 insertions(+), 40 deletions(-)

diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split
index ee422f1230e1b2f..b4572c05d3bcf90 100644
--- a/subsys/bluetooth/controller/Kconfig.ll_sw_split
+++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split
@@ -21,8 +21,7 @@ config BT_LLL_VENDOR_NORDIC
 	select BT_CTLR_CRYPTO_SUPPORT
 	select BT_CTLR_LE_ENC_SUPPORT if BT_CTLR_CRYPTO_SUPPORT && \
 					 !BT_CTLR_DATA_LENGTH_CLEAR && \
-					 !BT_CTLR_PHY_2M_NRF && \
-					 !SOC_COMPATIBLE_NRF54LX
+					 !BT_CTLR_PHY_2M_NRF
 	select BT_CTLR_PRIVACY_SUPPORT if BT_CTLR_CRYPTO_SUPPORT && \
 					  !SOC_SERIES_NRF51X && \
 					  !SOC_COMPATIBLE_NRF54LX
@@ -31,6 +30,7 @@ config BT_LLL_VENDOR_NORDIC
 	select BT_CTLR_PER_INIT_FEAT_XCHG_SUPPORT
 	select BT_CTLR_DATA_LEN_UPDATE_SUPPORT if !BT_CTLR_LE_ENC_SUPPORT || \
 						  HAS_HW_NRF_CCM_LFLEN_8BIT || \
+						  SOC_COMPATIBLE_NRF54LX || \
 						  BT_CTLR_DATA_LENGTH_CLEAR
 	select BT_CTLR_EXT_SCAN_FP_SUPPORT
 	select BT_CTLR_PHY_2M_SUPPORT if HAS_HW_NRF_RADIO_BLE_2M || \
@@ -43,7 +43,7 @@ config BT_LLL_VENDOR_NORDIC
 	select BT_CTLR_SYNC_PERIODIC_SUPPORT
 	select BT_CTLR_ADV_ISO_SUPPORT
 	select BT_CTLR_SYNC_ISO_SUPPORT
-	select BT_CTLR_BROADCAST_ISO_ENC_SUPPORT if !SOC_COMPATIBLE_NRF54LX
+	select BT_CTLR_BROADCAST_ISO_ENC_SUPPORT
 	select BT_CTLR_CENTRAL_ISO_SUPPORT
 	select BT_CTLR_PERIPHERAL_ISO_SUPPORT
 	select BT_CTLR_DF_SUPPORT if HAS_HW_NRF_RADIO_DFE
diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c
index 7f125e2245014dd..0dff57eb70869df 100644
--- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c
+++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c
@@ -7,6 +7,7 @@
 
 #include <zephyr/toolchain.h>
 #include <zephyr/dt-bindings/gpio/gpio.h>
+#include <zephyr/sys/byteorder.h>
 #include <soc.h>
 
 #include <nrfx_gpiote.h>
@@ -2036,7 +2037,33 @@ void radio_gpio_pa_lna_disable(void)
 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN || HAL_RADIO_GPIO_HAVE_LNA_PIN */
 
 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
+#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
+struct ccm_job_ptr {
+	void *ptr;
+	struct {
+		uint32_t length:24;
+		uint32_t attribute:8;
+	} __packed;
+} __packed;
+
+#define CCM_JOB_PTR_ATTRIBUTE_ALEN  11U
+#define CCM_JOB_PTR_ATTRIBUTE_MLEN  12U
+#define CCM_JOB_PTR_ATTRIBUTE_ADATA 13U
+#define CCM_JOB_PTR_ATTRIBUTE_MDATA 14U
+
+static struct {
+	uint16_t in_alen;
+	uint16_t in_mlen;
+	uint8_t  in_mlen_msb;
+	uint8_t  out_mlen_msb;
+	uint16_t out_alen;
+	struct ccm_job_ptr in[6];
+	struct ccm_job_ptr out[6];
+} ccm_job;
+
+#else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
 static uint8_t MALIGN(4) _ccm_scratch[(HAL_RADIO_PDU_LEN_MAX - 4) + 16];
+#endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
 
 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_SYNC_ISO)
 static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_type, void *pkt)
@@ -2045,14 +2072,30 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_
 
 	NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
 	NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
+
 	mode = (CCM_MODE_MODE_Decryption << CCM_MODE_MODE_Pos) &
 	       CCM_MODE_MODE_Msk;
 
-#if !defined(CONFIG_SOC_SERIES_NRF51X)
+#if defined(CONFIG_SOC_SERIES_NRF51X)
+	hal_trigger_crypt_ppi_config();
+	hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI));
+
+#elif defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
+	/* Enable CCM Protocol Mode BLE */
+	mode |= (CCM_MODE_PROTOCOL_Ble << CCM_MODE_PROTOCOL_Pos) &
+		CCM_MODE_PROTOCOL_Msk;
+
+	/* Enable CCM MAC Length 4 bytes */
+	mode |= (CCM_MODE_MACLEN_M4 << CCM_MODE_MACLEN_Pos) &
+		CCM_MODE_MACLEN_Msk;
+
+#else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
 	/* Enable CCM support for 8-bit length field PDUs. */
 	mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
 		CCM_MODE_LENGTH_Msk;
 
+#endif /* CONFIG_SOC_COMPATIBLE_NRF54LX */
+
 	/* Select CCM data rate based on current PHY in use. */
 	switch (phy) {
 	default:
@@ -2115,47 +2158,130 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_
 #endif /* CONFIG_BT_CTLR_PHY_CODED */
 	}
 
-#if !defined(CONFIG_SOC_NRF52832) && \
-	(!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \
-	 (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4U)))
-	uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >>
-			RADIO_PCNF1_MAXLEN_Pos;
-
-	/* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */
-	NRF_CCM->MAXPACKETSIZE = max_len - 4U;
-#endif
+	NRF_CCM->MODE = mode;
 
+#if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) || \
+	defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
+#define ADATAMASK HEADERMASK
+#endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
 	switch (pdu_type) {
 	case RADIO_PKT_CONF_PDU_TYPE_BIS:
-		NRF_CCM->HEADERMASK = 0xC3; /* mask CSSN and CSTF */
+		NRF_CCM->ADATAMASK = 0xC3; /* mask CSSN and CSTF */
 		break;
 	case RADIO_PKT_CONF_PDU_TYPE_CIS:
-		NRF_CCM->HEADERMASK = 0xA3; /* mask SN, NESN, CIE and NPI */
+		NRF_CCM->ADATAMASK = 0xA3; /* mask SN, NESN, CIE and NPI */
 		break;
 	default:
-		/* Using default reset value of HEADERMASK */
-		NRF_CCM->HEADERMASK = 0xE3; /* mask SN, NESN and MD */
+		/* Using default reset value of ADATAMASK */
+		NRF_CCM->ADATAMASK = 0xE3; /* mask SN, NESN and MD */
 		break;
 	}
+#if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
+#undef ADATAMASK
 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
+#endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK ||
+	* CONFIG_SOC_COMPATIBLE_NRF54LX
+	*/
 
-#else /* CONFIG_SOC_SERIES_NRF51X */
-	hal_trigger_crypt_ppi_config();
-	hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI));
-#endif /* CONFIG_SOC_SERIES_NRF51X */
+#if !defined(CONFIG_SOC_NRF52832) && \
+	!defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \
+	(!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \
+	 (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4U)))
+	const uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >>
+				RADIO_PCNF1_MAXLEN_Pos;
 
-	NRF_CCM->MODE = mode;
+	/* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */
+	NRF_CCM->MAXPACKETSIZE = max_len - 4U;
+#endif
+
+#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
+	/* Configure the CCM key, nonce and pointers */
+	NRF_CCM->KEY.VALUE[3] = sys_get_be32(&cnf->key[0]);
+	NRF_CCM->KEY.VALUE[2] = sys_get_be32(&cnf->key[4]);
+	NRF_CCM->KEY.VALUE[1] = sys_get_be32(&cnf->key[8]);
+	NRF_CCM->KEY.VALUE[0] = sys_get_be32(&cnf->key[12]);
+
+	NRF_CCM->NONCE.VALUE[3] = ((uint8_t *)&cnf->counter)[0];
+	NRF_CCM->NONCE.VALUE[2] = sys_get_be32(&((uint8_t *)&cnf->counter)[1]) |
+				  (cnf->direction << 7);
+	NRF_CCM->NONCE.VALUE[1] = sys_get_be32(&cnf->iv[0]);
+	NRF_CCM->NONCE.VALUE[0] = sys_get_be32(&cnf->iv[4]);
+
+	const uint8_t mlen = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >>
+			     RADIO_PCNF1_MAXLEN_Pos;
+
+	const uint8_t alen = sizeof(uint8_t);
+
+	ccm_job.in_alen = alen;
+	ccm_job.in[0].ptr = &ccm_job.in_alen;
+	ccm_job.in[0].length = sizeof(ccm_job.in_alen);
+	ccm_job.in[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
+
+	ccm_job.in[1].ptr = (void *)((uint8_t *)_pkt_scratch + 1U);
+	ccm_job.in[1].length = sizeof(uint8_t);
+	ccm_job.in[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
+
+	ccm_job.in_mlen_msb = 0U;
+	ccm_job.in[2].ptr = &ccm_job.in_mlen_msb;
+	ccm_job.in[2].length = sizeof(ccm_job.in_mlen_msb);
+	ccm_job.in[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
+
+	ccm_job.in[3].ptr = (void *)((uint8_t *)_pkt_scratch + 0U);
+	ccm_job.in[3].length = sizeof(uint8_t);
+	ccm_job.in[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
+
+	ccm_job.in[4].ptr = (void *)((uint8_t *)_pkt_scratch + 3U);
+	ccm_job.in[4].length = mlen;
+	ccm_job.in[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
+
+	ccm_job.in[5].ptr = NULL;
+	ccm_job.in[5].length = 0U;
+	ccm_job.in[5].attribute = 0U;
+
+	ccm_job.out[0].ptr = &ccm_job.out_alen;
+	ccm_job.out[0].length = sizeof(ccm_job.out_alen);
+	ccm_job.out[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
+
+	ccm_job.out[1].ptr = (void *)((uint8_t *)pkt + 1U);
+	ccm_job.out[1].length = sizeof(uint8_t);
+	ccm_job.out[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
+
+	ccm_job.out[2].ptr = &ccm_job.out_mlen_msb;
+	ccm_job.out[2].length = sizeof(ccm_job.out_mlen_msb);
+	ccm_job.out[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
+
+	ccm_job.out[3].ptr = (void *)((uint8_t *)pkt + 0U);
+	ccm_job.out[3].length = sizeof(uint8_t);
+	ccm_job.out[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
+
+	ccm_job.out[4].ptr = (void *)((uint8_t *)pkt + 3U);
+	ccm_job.out[4].length = mlen - sizeof(uint32_t);
+	ccm_job.out[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
+
+	ccm_job.out[5].ptr = NULL;
+	ccm_job.out[5].length = 0U;
+	ccm_job.out[5].attribute = 0U;
+
+	NRF_CCM->IN.PTR = (uint32_t)ccm_job.in;
+	NRF_CCM->OUT.PTR = (uint32_t)ccm_job.out;
+
+	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
+	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
+
+#else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
 	NRF_CCM->CNFPTR = (uint32_t)cnf;
 	NRF_CCM->INPTR = (uint32_t)_pkt_scratch;
 	NRF_CCM->OUTPTR = (uint32_t)pkt;
 	NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch;
 	NRF_CCM->SHORTS = 0;
+
 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN);
 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
 
 	nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN);
+#endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
 
 	return _pkt_scratch;
 }
@@ -2178,11 +2304,12 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p
 
 	NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
 	NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
+
 	mode = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) &
 	       CCM_MODE_MODE_Msk;
+
 #if defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
-	defined(CONFIG_SOC_COMPATIBLE_NRF53X) || \
-	defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
+	defined(CONFIG_SOC_COMPATIBLE_NRF53X)
 	/* Enable CCM support for 8-bit length field PDUs. */
 	mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
 		CCM_MODE_LENGTH_Msk;
@@ -2192,45 +2319,145 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p
 	 */
 	mode |= (CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos) &
 		CCM_MODE_DATARATE_Msk;
-#endif
 
-#if !defined(CONFIG_SOC_SERIES_NRF51X) && \
-	!defined(CONFIG_SOC_NRF52832) && \
-	(!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \
-	 (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4)))
-	uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >>
-			RADIO_PCNF1_MAXLEN_Pos;
+#elif defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
+	/* Enable CCM Protocol Mode BLE */
+	mode |= (CCM_MODE_PROTOCOL_Ble << CCM_MODE_PROTOCOL_Pos) &
+		CCM_MODE_PROTOCOL_Msk;
 
-	/* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */
-	NRF_CCM->MAXPACKETSIZE = max_len - 4U;
+	/* NOTE: use fastest data rate as tx data needs to be prepared before
+	 * radio Tx on any PHY.
+	 */
+	mode |= (CCM_MODE_DATARATE_4Mbit << CCM_MODE_DATARATE_Pos) &
+		CCM_MODE_DATARATE_Msk;
+
+	/* Enable CCM MAC Length 4 bytes */
+	mode |= (CCM_MODE_MACLEN_M4 << CCM_MODE_MACLEN_Pos) &
+		CCM_MODE_MACLEN_Msk;
 #endif
 
+	NRF_CCM->MODE = mode;
+
+#if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) || \
+	defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
+#define ADATAMASK HEADERMASK
+#endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
 	switch (pdu_type) {
 	case RADIO_PKT_CONF_PDU_TYPE_BIS:
-		NRF_CCM->HEADERMASK = 0xC3; /* mask CSSN and CSTF */
+		NRF_CCM->ADATAMASK = 0xC3; /* mask CSSN and CSTF */
 		break;
 	case RADIO_PKT_CONF_PDU_TYPE_CIS:
-		NRF_CCM->HEADERMASK = 0xA3; /* mask SN, NESN, CIE and NPI */
+		NRF_CCM->ADATAMASK = 0xA3; /* mask SN, NESN, CIE and NPI */
 		break;
 	default:
-		/* Using default reset value of HEADERMASK */
-		NRF_CCM->HEADERMASK = 0xE3; /* mask SN, NESN and MD */
+		/* Using default reset value of ADATAMASK */
+		NRF_CCM->ADATAMASK = 0xE3; /* mask SN, NESN and MD */
 		break;
 	}
+#if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
+#undef ADATAMASK
 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
+#endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK ||
+	* CONFIG_SOC_COMPATIBLE_NRF54LX
+	*/
 
-	NRF_CCM->MODE = mode;
+#if !defined(CONFIG_SOC_SERIES_NRF51X) && \
+	!defined(CONFIG_SOC_NRF52832) && \
+	!defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \
+	(!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \
+	 (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4)))
+	const uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >>
+				RADIO_PCNF1_MAXLEN_Pos;
+
+	/* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */
+	NRF_CCM->MAXPACKETSIZE = max_len - 4U;
+#endif
+
+#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
+	/* Configure the CCM key, nonce and pointers */
+	NRF_CCM->KEY.VALUE[3] = sys_get_be32(&cnf->key[0]);
+	NRF_CCM->KEY.VALUE[2] = sys_get_be32(&cnf->key[4]);
+	NRF_CCM->KEY.VALUE[1] = sys_get_be32(&cnf->key[8]);
+	NRF_CCM->KEY.VALUE[0] = sys_get_be32(&cnf->key[12]);
+
+	NRF_CCM->NONCE.VALUE[3] = ((uint8_t *)&cnf->counter)[0];
+	NRF_CCM->NONCE.VALUE[2] = sys_get_be32(&((uint8_t *)&cnf->counter)[1]) |
+				  (cnf->direction << 7);
+	NRF_CCM->NONCE.VALUE[1] = sys_get_be32(&cnf->iv[0]);
+	NRF_CCM->NONCE.VALUE[0] = sys_get_be32(&cnf->iv[4]);
+
+	const uint8_t alen = sizeof(uint8_t);
+
+	ccm_job.in_alen = alen;
+	ccm_job.in[0].ptr = &ccm_job.in_alen;
+	ccm_job.in[0].length = sizeof(ccm_job.in_alen);
+	ccm_job.in[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
+
+	const uint8_t mlen = *((uint8_t *)pkt + 1U);
+
+	ccm_job.in_mlen = mlen;
+	ccm_job.in[1].ptr = &ccm_job.in_mlen;
+	ccm_job.in[1].length = sizeof(ccm_job.in_mlen);
+	ccm_job.in[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
+
+	ccm_job.in[2].ptr = (void *)((uint8_t *)pkt + 0U);
+	ccm_job.in[2].length = alen;
+	ccm_job.in[2].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
+
+	ccm_job.in[3].ptr = (void *)((uint8_t *)pkt + 3U);
+	ccm_job.in[3].length = mlen;
+	ccm_job.in[3].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
+
+	ccm_job.in[4].ptr = NULL;
+	ccm_job.in[4].length = 0U;
+	ccm_job.in[4].attribute = 0U;
+
+	ccm_job.out[0].ptr = &ccm_job.out_alen;
+	ccm_job.out[0].length = sizeof(ccm_job.out_alen);
+	ccm_job.out[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
+
+	ccm_job.out[1].ptr = (void *)((uint8_t *)_pkt_scratch + 1U);
+	ccm_job.out[1].length = sizeof(uint8_t);
+	ccm_job.out[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
+
+	ccm_job.out[2].ptr = &ccm_job.out_mlen_msb;
+	ccm_job.out[2].length = sizeof(ccm_job.out_mlen_msb);
+	ccm_job.out[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
+
+	ccm_job.out[3].ptr = (void *)((uint8_t *)_pkt_scratch + 0U);
+	ccm_job.out[3].length = sizeof(uint8_t);
+	ccm_job.out[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
+
+	ccm_job.out[4].ptr = (void *)((uint8_t *)_pkt_scratch + 3U);
+	ccm_job.out[4].length = mlen + sizeof(uint32_t);
+	ccm_job.out[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
+
+	ccm_job.out[5].ptr = NULL;
+	ccm_job.out[5].length = 0U;
+	ccm_job.out[5].attribute = 0U;
+
+	NRF_CCM->IN.PTR = (uint32_t)ccm_job.in;
+	NRF_CCM->OUT.PTR = (uint32_t)ccm_job.out;
+
+	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
+	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
+
+	nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_START);
+
+#else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
 	NRF_CCM->CNFPTR = (uint32_t)cnf;
 	NRF_CCM->INPTR = (uint32_t)pkt;
 	NRF_CCM->OUTPTR = (uint32_t)_pkt_scratch;
 	NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch;
 	NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk;
+
 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN);
 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
 
 	nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN);
+#endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
 
 	return _pkt_scratch;
 }
diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf54lx.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf54lx.h
index bc0cc2993c563b8..b4546a3eb580a59 100644
--- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf54lx.h
+++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf54lx.h
@@ -379,6 +379,19 @@
 #define HAL_RADIO_RESET_VALUE_CTEINLINECONF 0x00002800UL
 #define HAL_RADIO_RESET_VALUE_DATAWHITE     0x00890040UL
 
+/* HAL abstraction of CCM h/w */
+#define NRF_CCM                               NRF_CCM00
+#define NRF_CCM_TASK_CRYPT                    NRF_CCM_TASK_START
+#define EVENTS_ENDCRYPT                       EVENTS_END
+#define INPTR                                 IN.PTR
+#define OUTPTR                                OUT.PTR
+#define MICSTATUS                             MACSTATUS
+#define CCM_INTENSET_ENDCRYPT_Msk             CCM_INTENSET_END_Msk
+#define CCM_INTENCLR_ENDCRYPT_Msk             CCM_INTENCLR_END_Msk
+#define CCM_MODE_DATARATE_125Kbps             CCM_MODE_DATARATE_125Kbit
+#define CCM_MODE_DATARATE_500Kbps             CCM_MODE_DATARATE_500Kbit
+#define CCM_RATEOVERRIDE_RATEOVERRIDE_500Kbps CCM_RATEOVERRIDE_RATEOVERRIDE_500Kbit
+
 static inline void hal_radio_reset(void)
 {
 	/* TODO: Add any required setup for each radio event
diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h
index c5d7f01ef9d1215..e9631988a66dcc8 100644
--- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h
+++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h
@@ -147,9 +147,23 @@ static inline void hal_radio_ready_time_capture_ppi_config(void)
  */
 static inline void hal_trigger_crypt_ppi_config(void)
 {
-	nrf_radio_publish_set(NRF_RADIO,
-			      NRF_RADIO_EVENT_ADDRESS, HAL_TRIGGER_CRYPT_PPI);
 	nrf_ccm_subscribe_set(NRF_CCM, NRF_CCM_TASK_START, HAL_TRIGGER_CRYPT_PPI);
+
+#if !defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
+	nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS, HAL_TRIGGER_CRYPT_PPI);
+
+#else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
+	nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_PAYLOAD, HAL_TRIGGER_CRYPT_PPI);
+
+	/* Enable same DPPI in MCU  domain */
+	nrf_dppi_channels_enable(NRF_DPPIC00, BIT(HAL_TRIGGER_CRYPT_PPI));
+
+	/* Setup PPIB send subscribe */
+	nrf_ppib_subscribe_set(NRF_PPIB10, HAL_PPIB_SEND_TRIGGER_CRYPT_PPI, HAL_TRIGGER_CRYPT_PPI);
+
+	/* Setup PPIB receive publish */
+	nrf_ppib_publish_set(NRF_PPIB00, HAL_PPIB_RECEIVE_TRIGGER_CRYPT_PPI, HAL_TRIGGER_CRYPT_PPI);
+#endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
 }
 
 /*******************************************************************************
diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h
index cf696693c0deffd..a86d9e18c9c022f 100644
--- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h
+++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h
@@ -56,7 +56,15 @@
  * Note: we do not need an additional PPI, since we have already set up
  * a PPI to publish RADIO ADDRESS event.
  */
+#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
+#define HAL_TRIGGER_CRYPT_PPI 6
+#else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
 #define HAL_TRIGGER_CRYPT_PPI HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI
+#endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
+#define HAL_PPIB_SEND_TRIGGER_CRYPT_PPI \
+	_CONCAT(NRF_PPIB_TASK_SEND_, HAL_TRIGGER_CRYPT_PPI)
+#define HAL_PPIB_RECEIVE_TRIGGER_CRYPT_PPI \
+	_CONCAT(NRF_PPIB_EVENT_RECEIVE_, HAL_TRIGGER_CRYPT_PPI)
 
 /*******************************************************************************
  * Trigger automatic address resolution on Bit counter match: