1 /*
2  * Copyright (c) 2016 - 2020 Nordic Semiconductor ASA
3  * Copyright (c) 2016 Vinayak Kariappa Chettimada
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/toolchain.h>
9 #include <zephyr/dt-bindings/gpio/gpio.h>
10 #include <zephyr/sys/byteorder.h>
11 #include <soc.h>
12 
13 #include <nrfx_gpiote.h>
14 
15 #include "util/mem.h"
16 
17 #include "hal/cpu.h"
18 #include "hal/ccm.h"
19 #include "hal/cntr.h"
20 #include "hal/radio.h"
21 #include "hal/radio_df.h"
22 #include "hal/ticker.h"
23 
24 #include "ll_sw/pdu_df.h"
25 #include "lll/pdu_vendor.h"
26 #include "ll_sw/pdu.h"
27 
28 #include "radio_internal.h"
29 
30 /* Converts the GPIO controller in a FEM property's GPIO specification
31  * to its nRF register map pointer.
32  *
33  * Make sure to use NRF_DT_CHECK_GPIO_CTLR_IS_SOC to check the GPIO
34  * controller has the right compatible wherever you use this.
35  */
36 #define NRF_FEM_GPIO(prop) \
37 	((NRF_GPIO_Type *)DT_REG_ADDR(DT_GPIO_CTLR(FEM_NODE, prop)))
38 
39 /* Converts GPIO specification to a PSEL value. */
40 #define NRF_FEM_PSEL(prop) NRF_DT_GPIOS_TO_PSEL(FEM_NODE, prop)
41 
42 /* Check if GPIO flags are active low. */
43 #define ACTIVE_LOW(flags) ((flags) & GPIO_ACTIVE_LOW)
44 
45 /* Check if GPIO flags contain unsupported values. */
46 #define BAD_FLAGS(flags) ((flags) & ~GPIO_ACTIVE_LOW)
47 
48 /* GPIOTE OUTINIT setting for a pin's inactive level, from its
49  * devicetree flags.
50  */
51 #define OUTINIT_INACTIVE(flags)			\
52 	(ACTIVE_LOW(flags) ?				\
53 	 GPIOTE_CONFIG_OUTINIT_High :			\
54 	 GPIOTE_CONFIG_OUTINIT_Low)
55 
56 #if defined(FEM_NODE)
57 BUILD_ASSERT(!HAL_RADIO_GPIO_PA_OFFSET_MISSING,
58 	     "fem node " DT_NODE_PATH(FEM_NODE) " has property "
59 	     HAL_RADIO_GPIO_PA_PROP_NAME " set, so you must also set "
60 	     HAL_RADIO_GPIO_PA_OFFSET_PROP_NAME);
61 
62 BUILD_ASSERT(!HAL_RADIO_GPIO_LNA_OFFSET_MISSING,
63 	     "fem node " DT_NODE_PATH(FEM_NODE) " has property "
64 	     HAL_RADIO_GPIO_LNA_PROP_NAME " set, so you must also set "
65 	     HAL_RADIO_GPIO_LNA_OFFSET_PROP_NAME);
66 #endif	/* FEM_NODE */
67 
68 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
69 static const nrfx_gpiote_t gpiote_palna = NRFX_GPIOTE_INSTANCE(
70 	NRF_DT_GPIOTE_INST(FEM_NODE, HAL_RADIO_GPIO_PA_PROP));
71 static uint8_t gpiote_ch_palna;
72 
73 BUILD_ASSERT(NRF_DT_GPIOTE_INST(FEM_NODE, HAL_RADIO_GPIO_PA_PROP) ==
74 	     NRF_DT_GPIOTE_INST(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP),
75 	HAL_RADIO_GPIO_PA_PROP_NAME " and " HAL_RADIO_GPIO_LNA_PROP_NAME
76 	" GPIOs must use the same GPIOTE instance.");
77 #endif
78 
79 #if defined(HAL_RADIO_FEM_IS_NRF21540)
80 static const nrfx_gpiote_t gpiote_pdn = NRFX_GPIOTE_INSTANCE(
81 	NRF_DT_GPIOTE_INST(FEM_NODE, pdn_gpios));
82 static uint8_t gpiote_ch_pdn;
83 #endif
84 
85 /* These headers require the above gpiote-related variables to be declared. */
86 #if defined(PPI_PRESENT)
87 #include "radio_nrf5_ppi_gpiote.h"
88 #elif defined(DPPI_PRESENT)
89 #include "radio_nrf5_dppi_gpiote.h"
90 #endif
91 
92 /*
93  * "Manual" conversions of devicetree values to register bits. We
94  * can't use the Zephyr GPIO API here, so we need this extra
95  * boilerplate.
96  */
97 
98 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
99 #define NRF_GPIO_PA       NRF_FEM_GPIO(HAL_RADIO_GPIO_PA_PROP)
100 #define NRF_GPIO_PA_PIN   DT_GPIO_PIN(FEM_NODE, HAL_RADIO_GPIO_PA_PROP)
101 #define NRF_GPIO_PA_FLAGS DT_GPIO_FLAGS(FEM_NODE, HAL_RADIO_GPIO_PA_PROP)
102 #define NRF_GPIO_PA_PSEL  NRF_FEM_PSEL(HAL_RADIO_GPIO_PA_PROP)
103 NRF_DT_CHECK_GPIO_CTLR_IS_SOC(FEM_NODE, HAL_RADIO_GPIO_PA_PROP,
104 			      HAL_RADIO_GPIO_PA_PROP_NAME);
105 BUILD_ASSERT(!BAD_FLAGS(NRF_GPIO_PA_FLAGS),
106 	     "fem node " DT_NODE_PATH(FEM_NODE) " has invalid GPIO flags in "
107 	     HAL_RADIO_GPIO_PA_PROP_NAME
108 	     "; only GPIO_ACTIVE_LOW or GPIO_ACTIVE_HIGH are supported");
109 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
110 
111 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
112 #define NRF_GPIO_LNA       NRF_FEM_GPIO(HAL_RADIO_GPIO_LNA_PROP)
113 #define NRF_GPIO_LNA_PIN   DT_GPIO_PIN(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP)
114 #define NRF_GPIO_LNA_FLAGS DT_GPIO_FLAGS(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP)
115 #define NRF_GPIO_LNA_PSEL  NRF_FEM_PSEL(HAL_RADIO_GPIO_LNA_PROP)
116 NRF_DT_CHECK_GPIO_CTLR_IS_SOC(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP,
117 			      HAL_RADIO_GPIO_LNA_PROP_NAME);
118 BUILD_ASSERT(!BAD_FLAGS(NRF_GPIO_LNA_FLAGS),
119 	     "fem node " DT_NODE_PATH(FEM_NODE) " has invalid GPIO flags in "
120 	     HAL_RADIO_GPIO_LNA_PROP_NAME
121 	     "; only GPIO_ACTIVE_LOW or GPIO_ACTIVE_HIGH are supported");
122 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
123 
124 #if defined(HAL_RADIO_FEM_IS_NRF21540)
125 
126 #if DT_NODE_HAS_PROP(FEM_NODE, pdn_gpios)
127 #define NRF_GPIO_PDN        NRF_FEM_GPIO(pdn_gpios)
128 #define NRF_GPIO_PDN_PIN    DT_GPIO_PIN(FEM_NODE, pdn_gpios)
129 #define NRF_GPIO_PDN_FLAGS  DT_GPIO_FLAGS(FEM_NODE, pdn_gpios)
130 #define NRF_GPIO_PDN_PSEL   NRF_FEM_PSEL(pdn_gpios)
131 #define NRF_GPIO_PDN_OFFSET DT_PROP(FEM_NODE, pdn_settle_time_us)
132 NRF_DT_CHECK_GPIO_CTLR_IS_SOC(FEM_NODE, pdn_gpios, "pdn-gpios");
133 #endif	/* DT_NODE_HAS_PROP(FEM_NODE, pdn_gpios) */
134 
135 #endif	/* HAL_RADIO_FEM_IS_NRF21540 */
136 
137 /* CTEINLINE S0_MASK for periodic advertising PUDs. It allows to accept all types of extended
138  * advertising PDUs to have CTE included.
139  */
140 #define DF_S0_ALLOW_ALL_PER_ADV_PDU 0x0
141 /* CTEINLINE S0_MASK for data channel PDUs. It points to CP bit in S0 byte to check if is it set
142  * to 0x1. In that is true then S1 byte (CTEInfo) is considered as present in a PDU.
143  */
144 #define DF_S0_MASK_CP_BIT_IN_DATA_CHANNEL_PDU 0x20
145 
146 static radio_isr_cb_t isr_cb;
147 static void           *isr_cb_param;
148 
isr_radio(void)149 void isr_radio(void)
150 {
151 	if (radio_has_disabled()) {
152 		isr_cb(isr_cb_param);
153 	}
154 }
155 
radio_isr_set(radio_isr_cb_t cb,void * param)156 void radio_isr_set(radio_isr_cb_t cb, void *param)
157 {
158 	irq_disable(HAL_RADIO_IRQn);
159 
160 	isr_cb_param = param;
161 	isr_cb = cb;
162 
163 	nrf_radio_int_enable(NRF_RADIO, HAL_RADIO_INTENSET_DISABLED_Msk);
164 
165 	NVIC_ClearPendingIRQ(HAL_RADIO_IRQn);
166 	irq_enable(HAL_RADIO_IRQn);
167 }
168 
radio_setup(void)169 void radio_setup(void)
170 {
171 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
172 	NRF_GPIO_PA->DIRSET = BIT(NRF_GPIO_PA_PIN);
173 	if (ACTIVE_LOW(NRF_GPIO_PA_FLAGS)) {
174 		NRF_GPIO_PA->OUTSET = BIT(NRF_GPIO_PA_PIN);
175 	} else {
176 		NRF_GPIO_PA->OUTCLR = BIT(NRF_GPIO_PA_PIN);
177 	}
178 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
179 
180 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
181 	NRF_GPIO_LNA->DIRSET = BIT(NRF_GPIO_LNA_PIN);
182 
183 	radio_gpio_lna_off();
184 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
185 
186 #if defined(NRF_GPIO_PDN_PIN)
187 	NRF_GPIO_PDN->DIRSET = BIT(NRF_GPIO_PDN_PIN);
188 	if (ACTIVE_LOW(NRF_GPIO_PDN_FLAGS)) {
189 		NRF_GPIO_PDN->OUTSET = BIT(NRF_GPIO_PDN_PIN);
190 	} else {
191 		NRF_GPIO_PDN->OUTCLR = BIT(NRF_GPIO_PDN_PIN);
192 	}
193 #endif /* NRF_GPIO_PDN_PIN */
194 
195 	hal_radio_ram_prio_setup();
196 }
197 
radio_reset(void)198 void radio_reset(void)
199 {
200 	irq_disable(HAL_RADIO_IRQn);
201 
202 	/* nRF SoC generic radio reset/initializations
203 	 * Note: Only registers whose bits are partially modified across
204 	 *       functions are assigned back the power-on reset values.
205 	 *       Ignore other registers for reset which will have all bits
206 	 *       explicitly assigned by functions in this file.
207 	 */
208 	NRF_RADIO->PCNF1 = HAL_RADIO_RESET_VALUE_PCNF1;
209 
210 #if defined(CONFIG_BT_CTLR_DF) && !defined(CONFIG_ZTEST)
211 	radio_df_reset();
212 #endif /* CONFIG_BT_CTLR_DF && !CONFIG_ZTEST */
213 
214 	/* nRF SoC specific reset/initializations, if any */
215 	hal_radio_reset();
216 
217 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
218 	hal_radio_sw_switch_ppi_group_setup();
219 #endif
220 
221 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
222 #if defined(CONFIG_BT_CTLR_TIFS_HW)
223 	NRF_RADIO->TIMING = (RADIO_TIMING_RU_Legacy << RADIO_TIMING_RU_Pos) &
224 			    RADIO_TIMING_RU_Msk;
225 #else /* !CONFIG_BT_CTLR_TIFS_HW */
226 	NRF_RADIO->TIMING = (RADIO_TIMING_RU_Fast << RADIO_TIMING_RU_Pos) &
227 			    RADIO_TIMING_RU_Msk;
228 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
229 
230 	NRF_POWER->TASKS_CONSTLAT = 1U;
231 #endif /* CONFIG_SOC_COMPATIBLE_NRF54LX */
232 
233 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
234 	hal_palna_ppi_setup();
235 #endif
236 #if defined(HAL_RADIO_FEM_IS_NRF21540)
237 	hal_fem_ppi_setup();
238 #endif
239 }
240 
radio_stop(void)241 void radio_stop(void)
242 {
243 	/* nRF SoC specific radio stop/cleanup, if any */
244 	hal_radio_stop();
245 
246 	/* nRF SoC generic radio stop/cleanup
247 	 * TODO: Initialize NRF_RADIO registers used by Controller to power-on
248 	 *       reset values.
249 	 *       This is required in case NRF_RADIO is share/used between
250 	 *       Bluetooth radio events by application defined radio protocols.
251 	 *       The application too shall restore the registers it uses to the
252 	 *       power-on reset values once it has stopped using the radio.
253 	 *
254 	 *       Registers used for Bluetooth Low Energy Controller:
255 	 *       - MODE
256 	 *       - MODECNF0
257 	 *       - TXPOWER
258 	 *       - FREQUENCY
259 	 *       - DATAWHITEIV
260 	 *       - PCNF0
261 	 *       - PCNF1
262 	 *       - TXADDRESS
263 	 *       - RXADDRESSES
264 	 *       - PREFIX0
265 	 *       - BASE0
266 	 *       - PACKETPTR
267 	 *       - CRCCNF
268 	 *       - CRCPOLY
269 	 *       - CRCINIT
270 	 *       - DAB
271 	 *       - DAP
272 	 *       - DACNF
273 	 *       - BCC
274 	 *       - TIFS
275 	 *       - SHORTS
276 	 *
277 	 *       Additional registers used for Direction Finding feature:
278 	 *       - SWITCHPATTERN
279 	 *       - DFEMODE
280 	 *       - CTEINLINECONF
281 	 *       - DFECTRL1
282 	 *       - DEFCTRL2
283 	 *       - CLEARPATTERN
284 	 *       - PSEL.DFEGPIO[n]
285 	 *       - DFEPACKET.PTR
286 	 */
287 }
288 
radio_phy_set(uint8_t phy,uint8_t flags)289 void radio_phy_set(uint8_t phy, uint8_t flags)
290 {
291 	uint32_t mode;
292 
293 	mode = hal_radio_phy_mode_get(phy, flags);
294 
295 	NRF_RADIO->MODE = (mode << RADIO_MODE_MODE_Pos) & RADIO_MODE_MODE_Msk;
296 
297 #if !defined(CONFIG_SOC_SERIES_NRF51X) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
298 #if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST)
299 	NRF_RADIO->MODECNF0 = ((RADIO_MODECNF0_DTX_Center <<
300 				RADIO_MODECNF0_DTX_Pos) &
301 			       RADIO_MODECNF0_DTX_Msk) |
302 			      ((RADIO_MODECNF0_RU_Fast <<
303 				RADIO_MODECNF0_RU_Pos) &
304 			       RADIO_MODECNF0_RU_Msk);
305 #else /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */
306 	NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_DTX_Center <<
307 			       RADIO_MODECNF0_DTX_Pos) &
308 			      RADIO_MODECNF0_DTX_Msk;
309 #endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */
310 #endif /* !CONFIG_SOC_SERIES_NRF51X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
311 }
312 
radio_tx_power_set(int8_t power)313 void radio_tx_power_set(int8_t power)
314 {
315 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
316 	uint32_t value;
317 
318 	value = hal_radio_tx_power_value(power);
319 	NRF_RADIO->TXPOWER = value;
320 
321 #elif defined(CONFIG_SOC_COMPATIBLE_NRF53X)
322 	uint32_t value;
323 
324 	/* NOTE: TXPOWER register only accepts upto 0dBm, hence use the HAL
325 	 * floor value for the TXPOWER register. Permit +3dBm by using high
326 	 * voltage being set for radio.
327 	 */
328 	value = hal_radio_tx_power_floor(power);
329 	NRF_RADIO->TXPOWER = value;
330 	hal_radio_tx_power_high_voltage_set(power);
331 
332 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X  && !CONFIG_SOC_COMPATIBLE_NRF54LX */
333 
334 	/* NOTE: valid value range is passed by Kconfig define. */
335 	NRF_RADIO->TXPOWER = (uint32_t)power;
336 
337 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
338 }
339 
radio_tx_power_max_set(void)340 void radio_tx_power_max_set(void)
341 {
342 	int8_t power;
343 
344 	power = radio_tx_power_max_get();
345 	radio_tx_power_set(power);
346 }
347 
radio_tx_power_min_get(void)348 int8_t radio_tx_power_min_get(void)
349 {
350 	return (int8_t)hal_radio_tx_power_min_get();
351 }
352 
radio_tx_power_max_get(void)353 int8_t radio_tx_power_max_get(void)
354 {
355 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X)
356 	return RADIO_TXPOWER_TXPOWER_Pos3dBm;
357 
358 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X */
359 	return (int8_t)hal_radio_tx_power_max_get();
360 
361 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */
362 }
363 
radio_tx_power_floor(int8_t power)364 int8_t radio_tx_power_floor(int8_t power)
365 {
366 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X)
367 	/* NOTE: TXPOWER register only accepts upto 0dBm, +3dBm permitted by
368 	 * use of high voltage being set for radio when TXPOWER register is set.
369 	 */
370 	if (power >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) {
371 		return RADIO_TXPOWER_TXPOWER_Pos3dBm;
372 	}
373 #endif /* CONFIG_SOC_COMPATIBLE_NRF53X */
374 
375 	return (int8_t)hal_radio_tx_power_floor(power);
376 }
377 
radio_freq_chan_set(uint32_t chan)378 void radio_freq_chan_set(uint32_t chan)
379 {
380 	NRF_RADIO->FREQUENCY = chan;
381 }
382 
radio_whiten_iv_set(uint32_t iv)383 void radio_whiten_iv_set(uint32_t iv)
384 {
385 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
386 #if defined(RADIO_DATAWHITEIV_DATAWHITEIV_Msk)
387 	NRF_RADIO->DATAWHITEIV = HAL_RADIO_RESET_VALUE_DATAWHITE | iv;
388 #else /* !RADIO_DATAWHITEIV_DATAWHITEIV_Msk */
389 	NRF_RADIO->DATAWHITE = HAL_RADIO_RESET_VALUE_DATAWHITE | iv;
390 #endif /* !RADIO_DATAWHITEIV_DATAWHITEIV_Msk */
391 #else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
392 	nrf_radio_datawhiteiv_set(NRF_RADIO, iv);
393 #endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
394 
395 	NRF_RADIO->PCNF1 &= ~RADIO_PCNF1_WHITEEN_Msk;
396 	NRF_RADIO->PCNF1 |= ((1UL) << RADIO_PCNF1_WHITEEN_Pos) &
397 			    RADIO_PCNF1_WHITEEN_Msk;
398 }
399 
radio_aa_set(const uint8_t * aa)400 void radio_aa_set(const uint8_t *aa)
401 {
402 	NRF_RADIO->TXADDRESS =
403 	    (((0UL) << RADIO_TXADDRESS_TXADDRESS_Pos) &
404 	     RADIO_TXADDRESS_TXADDRESS_Msk);
405 	NRF_RADIO->RXADDRESSES =
406 	    ((RADIO_RXADDRESSES_ADDR0_Enabled) << RADIO_RXADDRESSES_ADDR0_Pos);
407 	NRF_RADIO->PREFIX0 = aa[3];
408 	NRF_RADIO->BASE0 = sys_get_le24(aa) << 8;
409 }
410 
radio_pkt_configure(uint8_t bits_len,uint8_t max_len,uint8_t flags)411 void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags)
412 {
413 	const uint8_t pdu_type = RADIO_PKT_CONF_PDU_TYPE_GET(flags); /* Adv or Data channel */
414 	uint8_t bits_s1;
415 	uint32_t extra;
416 	uint8_t phy;
417 
418 #if defined(CONFIG_SOC_SERIES_NRF51X)
419 	ARG_UNUSED(phy);
420 
421 	extra = 0U;
422 
423 	/* nRF51 supports only 27 byte PDU when using h/w CCM for encryption. */
424 	if (!IS_ENABLED(CONFIG_BT_CTLR_DATA_LENGTH_CLEAR) &&
425 	    pdu_type == RADIO_PKT_CONF_PDU_TYPE_DC) {
426 		bits_len = RADIO_PKT_CONF_LENGTH_5BIT;
427 	}
428 	bits_s1 = RADIO_PKT_CONF_LENGTH_8BIT - bits_len;
429 
430 #elif defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
431 	defined(CONFIG_SOC_COMPATIBLE_NRF53X) || \
432 	defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
433 	extra = 0U;
434 
435 	phy = RADIO_PKT_CONF_PHY_GET(flags);
436 	switch (phy) {
437 	case PHY_1M:
438 	default:
439 		extra |= (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos) &
440 			 RADIO_PCNF0_PLEN_Msk;
441 		break;
442 
443 	case PHY_2M:
444 		extra |= (RADIO_PCNF0_PLEN_16bit << RADIO_PCNF0_PLEN_Pos) &
445 			 RADIO_PCNF0_PLEN_Msk;
446 		break;
447 
448 #if defined(CONFIG_BT_CTLR_PHY_CODED)
449 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
450 	case PHY_CODED:
451 		extra |= (RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) &
452 			 RADIO_PCNF0_PLEN_Msk;
453 		extra |= (2UL << RADIO_PCNF0_CILEN_Pos) & RADIO_PCNF0_CILEN_Msk;
454 		extra |= (3UL << RADIO_PCNF0_TERMLEN_Pos) &
455 			 RADIO_PCNF0_TERMLEN_Msk;
456 		break;
457 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
458 #endif /* CONFIG_BT_CTLR_PHY_CODED */
459 	}
460 
461 	/* To use same Data Channel PDU structure with nRF5 specific overhead
462 	 * byte, include the S1 field in radio packet configuration.
463 	 */
464 	if ((pdu_type == RADIO_PKT_CONF_PDU_TYPE_DC) ||
465 	    (pdu_type == RADIO_PKT_CONF_PDU_TYPE_BIS) ||
466 	    (pdu_type == RADIO_PKT_CONF_PDU_TYPE_CIS)) {
467 		extra |= (RADIO_PCNF0_S1INCL_Include <<
468 			  RADIO_PCNF0_S1INCL_Pos) & RADIO_PCNF0_S1INCL_Msk;
469 #if defined(CONFIG_BT_CTLR_DF)
470 		if (RADIO_PKT_CONF_CTE_GET(flags) == RADIO_PKT_CONF_CTE_ENABLED) {
471 			bits_s1 = RADIO_PKT_CONF_S1_8BIT;
472 		} else
473 #endif /* CONFIG_BT_CTLR_DF */
474 		{
475 			bits_s1 = 0U;
476 		}
477 	} else {
478 		bits_s1 = 0U;
479 	}
480 #endif /* CONFIG_SOC_COMPATIBLE_NRF52X */
481 
482 	NRF_RADIO->PCNF0 =
483 		(((1UL) << RADIO_PCNF0_S0LEN_Pos) & RADIO_PCNF0_S0LEN_Msk) |
484 		((((uint32_t)bits_len) << RADIO_PCNF0_LFLEN_Pos) & RADIO_PCNF0_LFLEN_Msk) |
485 		((((uint32_t)bits_s1) << RADIO_PCNF0_S1LEN_Pos) & RADIO_PCNF0_S1LEN_Msk) | extra;
486 
487 	NRF_RADIO->PCNF1 &= ~(RADIO_PCNF1_MAXLEN_Msk | RADIO_PCNF1_STATLEN_Msk |
488 			      RADIO_PCNF1_BALEN_Msk | RADIO_PCNF1_ENDIAN_Msk);
489 	NRF_RADIO->PCNF1 |=
490 		((((uint32_t)max_len) << RADIO_PCNF1_MAXLEN_Pos) & RADIO_PCNF1_MAXLEN_Msk) |
491 		(((0UL) << RADIO_PCNF1_STATLEN_Pos) & RADIO_PCNF1_STATLEN_Msk) |
492 		(((3UL) << RADIO_PCNF1_BALEN_Pos) & RADIO_PCNF1_BALEN_Msk) |
493 		(((RADIO_PCNF1_ENDIAN_Little) << RADIO_PCNF1_ENDIAN_Pos) & RADIO_PCNF1_ENDIAN_Msk);
494 }
495 
radio_pkt_rx_set(void * rx_packet)496 void radio_pkt_rx_set(void *rx_packet)
497 {
498 	NRF_RADIO->PACKETPTR = (uint32_t)rx_packet;
499 }
500 
radio_pkt_tx_set(void * tx_packet)501 void radio_pkt_tx_set(void *tx_packet)
502 {
503 	NRF_RADIO->PACKETPTR = (uint32_t)tx_packet;
504 }
505 
radio_tx_ready_delay_get(uint8_t phy,uint8_t flags)506 uint32_t radio_tx_ready_delay_get(uint8_t phy, uint8_t flags)
507 {
508 	return hal_radio_tx_ready_delay_us_get(phy, flags);
509 }
510 
radio_tx_chain_delay_get(uint8_t phy,uint8_t flags)511 uint32_t radio_tx_chain_delay_get(uint8_t phy, uint8_t flags)
512 {
513 	return hal_radio_tx_chain_delay_us_get(phy, flags);
514 }
515 
radio_rx_ready_delay_get(uint8_t phy,uint8_t flags)516 uint32_t radio_rx_ready_delay_get(uint8_t phy, uint8_t flags)
517 {
518 	return hal_radio_rx_ready_delay_us_get(phy, flags);
519 }
520 
radio_rx_chain_delay_get(uint8_t phy,uint8_t flags)521 uint32_t radio_rx_chain_delay_get(uint8_t phy, uint8_t flags)
522 {
523 	return hal_radio_rx_chain_delay_us_get(phy, flags);
524 }
525 
radio_rx_enable(void)526 void radio_rx_enable(void)
527 {
528 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
529 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
530 	/* NOTE: Timer clear DPPI configuration is needed only for nRF53
531 	 *       because of calls to radio_disable() and
532 	 *       radio_switch_complete_and_disable() inside a radio event call
533 	 *       hal_radio_sw_switch_disable(), which in the case of nRF53
534 	 *       cancels the task subscription.
535 	 */
536 	/* FIXME: hal_sw_switch_timer_clear_ppi_config() sets both task and
537 	 *        event. Consider a new interface to only set the task, or
538 	 *        change the design to not clear task subscription inside a
539 	 *        radio event but when the radio event is done.
540 	 */
541 	hal_sw_switch_timer_clear_ppi_config();
542 #endif /* CONFIG_SOC_COMPATIBLE_NRF53X || CONFIG_SOC_COMPATIBLE_NRF54LX */
543 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
544 
545 	nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RXEN);
546 }
547 
radio_tx_enable(void)548 void radio_tx_enable(void)
549 {
550 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
551 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
552 	/* NOTE: Timer clear DPPI configuration is needed only for nRF53
553 	 *       because of calls to radio_disable() and
554 	 *       radio_switch_complete_and_disable() inside a radio event call
555 	 *       hal_radio_sw_switch_disable(), which in the case of nRF53
556 	 *       cancels the task subscription.
557 	 */
558 	/* FIXME: hal_sw_switch_timer_clear_ppi_config() sets both task and
559 	 *        event. Consider a new interface to only set the task, or
560 	 *        change the design to not clear task subscription inside a
561 	 *        radio event but when the radio event is done.
562 	 */
563 	hal_sw_switch_timer_clear_ppi_config();
564 #endif /* CONFIG_SOC_COMPATIBLE_NRF53X || CONFIG_SOC_COMPATIBLE_NRF54LX */
565 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
566 
567 	nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_TXEN);
568 }
569 
radio_disable(void)570 void radio_disable(void)
571 {
572 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
573 	hal_radio_sw_switch_cleanup();
574 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
575 
576 	NRF_RADIO->SHORTS = 0;
577 	nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
578 }
579 
radio_status_reset(void)580 void radio_status_reset(void)
581 {
582 	/* NOTE: Only EVENTS_* registers read (checked) by software needs reset
583 	 *       between Radio IRQs. In PPI use, irrespective of stored EVENT_*
584 	 *       register value, PPI task will be triggered. Hence, other
585 	 *       EVENT_* registers are not reset to save code and CPU time.
586 	 */
587 	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY);
588 	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS);
589 	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_END);
590 #if defined(CONFIG_BT_CTLR_DF_SUPPORT) && !defined(CONFIG_ZTEST)
591 	/* Clear it only for SoCs supporting DF extension */
592 	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND);
593 	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CTEPRESENT);
594 	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH);
595 #endif /* CONFIG_BT_CTLR_DF_SUPPORT && !CONFIG_ZTEST */
596 	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
597 #if defined(CONFIG_BT_CTLR_PHY_CODED)
598 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
599 	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RATEBOOST);
600 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
601 #endif /* CONFIG_BT_CTLR_PHY_CODED */
602 }
603 
radio_is_ready(void)604 uint32_t radio_is_ready(void)
605 {
606 	return (NRF_RADIO->EVENTS_READY != 0);
607 }
608 
radio_is_address(void)609 uint32_t radio_is_address(void)
610 {
611 	return (NRF_RADIO->EVENTS_ADDRESS != 0);
612 }
613 
614 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
615 static uint32_t last_pdu_end_latency_us;
616 static uint32_t last_pdu_end_us;
617 
last_pdu_end_us_init(uint32_t latency_us)618 static void last_pdu_end_us_init(uint32_t latency_us)
619 {
620 	last_pdu_end_latency_us = latency_us;
621 	last_pdu_end_us = 0U;
622 }
623 
radio_is_done(void)624 uint32_t radio_is_done(void)
625 {
626 	if (NRF_RADIO->HAL_RADIO_TRX_EVENTS_END != 0) {
627 		/* On packet END event increment last packet end time value.
628 		 * Note: this depends on the function being called exactly once
629 		 * in the ISR function.
630 		 */
631 		last_pdu_end_us += EVENT_TIMER->CC[HAL_EVENT_TIMER_TRX_END_CC_OFFSET];
632 		return 1;
633 	} else {
634 		return 0;
635 	}
636 }
637 
638 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
radio_is_done(void)639 uint32_t radio_is_done(void)
640 {
641 	return (NRF_RADIO->HAL_RADIO_TRX_EVENTS_END != 0);
642 }
643 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
644 
radio_is_tx_done(void)645 uint32_t radio_is_tx_done(void)
646 {
647 	if (IS_ENABLED(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)) {
648 		return radio_is_done();
649 	} else {
650 		return 1U;
651 	}
652 }
653 
radio_has_disabled(void)654 uint32_t radio_has_disabled(void)
655 {
656 	return (NRF_RADIO->EVENTS_DISABLED != 0);
657 }
658 
radio_is_idle(void)659 uint32_t radio_is_idle(void)
660 {
661 	return (NRF_RADIO->STATE == 0);
662 }
663 
radio_crc_configure(uint32_t polynomial,uint32_t iv)664 void radio_crc_configure(uint32_t polynomial, uint32_t iv)
665 {
666 	nrf_radio_crc_configure(NRF_RADIO,
667 				RADIO_CRCCNF_LEN_Three,
668 				NRF_RADIO_CRC_ADDR_SKIP,
669 				polynomial);
670 	NRF_RADIO->CRCINIT = iv;
671 }
672 
radio_crc_is_valid(void)673 uint32_t radio_crc_is_valid(void)
674 {
675 	return (NRF_RADIO->CRCSTATUS != 0);
676 }
677 
678 /* Note: Only 3 bytes (PDU_EM_LL_SIZE_MAX) is required for empty PDU
679  *       transmission, but in case of Radio ISR latency if rx packet pointer
680  *       is not setup then Radio DMA will use previously assigned buffer which
681  *       can be this empty PDU buffer. Radio DMA will overrun this buffer and
682  *       cause memory corruption. Any detection of ISR latency will not happen
683  *       if the ISR function pointer in RAM is corrupted by this overrun.
684  *       Increasing ISR latencies in OS and CPU usage in the ULL_HIGH priority
685  *       if it is same as LLL priority in Controller implementation then it is
686  *       making it tight to execute Controller code in the tIFS between Tx-Rx
687  *       PDU's Radio ISRs.
688  */
689 static uint8_t MALIGN(4) _pkt_empty[MAX(HAL_RADIO_PDU_LEN_MAX,
690 					PDU_EM_LL_SIZE_MAX)];
691 static uint8_t MALIGN(4) _pkt_scratch[MAX((HAL_RADIO_PDU_LEN_MAX + 3),
692 				       PDU_AC_LL_SIZE_MAX)];
693 
radio_pkt_empty_get(void)694 void *radio_pkt_empty_get(void)
695 {
696 	return _pkt_empty;
697 }
698 
radio_pkt_scratch_get(void)699 void *radio_pkt_scratch_get(void)
700 {
701 	return _pkt_scratch;
702 }
703 
704 #if defined(CONFIG_SOC_NRF52832) && \
705 	defined(CONFIG_BT_CTLR_LE_ENC) && \
706 	defined(HAL_RADIO_PDU_LEN_MAX) && \
707 	(!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \
708 	 (CONFIG_BT_CTLR_DATA_LENGTH_MAX < (HAL_RADIO_PDU_LEN_MAX - 4)))
709 static uint8_t MALIGN(4) _pkt_decrypt[MAX((HAL_RADIO_PDU_LEN_MAX + 3),
710 				       PDU_AC_LL_SIZE_MAX)];
711 
radio_pkt_decrypt_get(void)712 void *radio_pkt_decrypt_get(void)
713 {
714 	return _pkt_decrypt;
715 }
716 #elif !defined(HAL_RADIO_PDU_LEN_MAX)
717 #error "Undefined HAL_RADIO_PDU_LEN_MAX."
718 #endif
719 
720 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_SYNC_ISO)
721 /* Dedicated Rx PDU Buffer for Control PDU independent of node_rx with BIS Data
722  * PDU buffer. Note this buffer will be used to store whole PDUs, not just the BIG control payload.
723  */
724 static uint8_t pkt_big_ctrl[offsetof(struct pdu_bis, payload) + sizeof(struct pdu_big_ctrl)];
725 
radio_pkt_big_ctrl_get(void)726 void *radio_pkt_big_ctrl_get(void)
727 {
728 	return pkt_big_ctrl;
729 }
730 #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_SYNC_ISO */
731 
732 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
733 static uint8_t sw_tifs_toggle;
734 /**
735  * @brief Implementation of Radio operation software switch.
736  *
737  * In case the switch is from RX to TX or from RX to RX and CTEINLINE is enabled then PDU end event
738  * (EVENTS_PHYEND) may be delayed after actual PDU end. The delay occurs when received PDU does not
739  * include CTE. To maintain TIFS the delay must be compensated.
740  * To handle that, two timer EVENTS_COMPARE are prepared: without and without delay compensation.
741  * If EVENTS_CTEPRESENT is fired then EVENTS_COMPARE for delayed EVENTS_PHYEND event is cancelled.
742  * In other case EVENTS_COMPARE for delayed compensation will timeout first and disable group of
743  * PPIs related with the Radio operation switch.
744  * Enable of end event compensation is controller by @p end_evt_delay_en.
745  *
746  * @param dir_curr         Current direction the Radio is working: SW_SWITCH_TX or SW_SWITCH_RX
747  * @param dir_next         Next direction the Radio is preparing for: SW_SWITCH_TX or SW_SWITCH_RX
748  * @param phy_curr         PHY the Radio is working on.
749  * @param flags_curr       Flags related with current PHY, the Radio is working on.
750  * @param phy_next         Next PHY the Radio is preparing for.
751  * @param flags_next       Flags related with next PHY, the Radio is preparing for.
752  * @param end_evt_delay_en Enable end event delay compensation for TIFS after switch from current
753  *                         direction to next direction.
754  */
sw_switch(uint8_t dir_curr,uint8_t dir_next,uint8_t phy_curr,uint8_t flags_curr,uint8_t phy_next,uint8_t flags_next,enum radio_end_evt_delay_state end_evt_delay_en)755 void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t flags_curr,
756 	       uint8_t phy_next, uint8_t flags_next,
757 	       enum radio_end_evt_delay_state end_evt_delay_en)
758 {
759 	uint8_t ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(sw_tifs_toggle);
760 	uint8_t cc = SW_SWITCH_TIMER_EVTS_COMP(sw_tifs_toggle);
761 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
762 	uint8_t phyend_delay_cc =
763 		SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_EVTS_COMP(sw_tifs_toggle);
764 	uint8_t radio_enable_ppi =
765 		HAL_SW_SWITCH_RADIO_ENABLE_PHYEND_DELAY_COMPENSATION_PPI(sw_tifs_toggle);
766 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
767 	uint32_t delay;
768 
769 	hal_radio_sw_switch_setup(sw_tifs_toggle);
770 
771 	/* NOTE: As constants are passed to dir_curr and dir_next, the
772 	 *       compiler should optimize out the redundant code path
773 	 *       during the optimization.
774 	 */
775 	if (dir_next == SW_SWITCH_TX) {
776 		/* TX */
777 
778 		/* Calculate delay with respect to current and next PHY.
779 		 */
780 		if (dir_curr == SW_SWITCH_TX) {
781 			delay = HAL_RADIO_NS2US_ROUND(
782 			    hal_radio_tx_ready_delay_ns_get(phy_next,
783 							    flags_next) +
784 			    hal_radio_tx_chain_delay_ns_get(phy_curr,
785 							    flags_curr));
786 
787 			hal_radio_b2b_txen_on_sw_switch(cc, ppi);
788 		} else {
789 			/* If RX PHY is LE Coded, calculate for S8 coding.
790 			 * Assumption being, S8 has higher delay.
791 			 */
792 			delay = HAL_RADIO_NS2US_ROUND(
793 			    hal_radio_tx_ready_delay_ns_get(phy_next,
794 							    flags_next) +
795 			    hal_radio_rx_chain_delay_ns_get(phy_curr, 1));
796 
797 			hal_radio_txen_on_sw_switch(cc, ppi);
798 		}
799 
800 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
801 		if (dir_curr == SW_SWITCH_RX && end_evt_delay_en == END_EVT_DELAY_ENABLED &&
802 		    !(phy_curr & PHY_CODED)) {
803 			nrf_timer_cc_set(SW_SWITCH_TIMER, phyend_delay_cc,
804 					 SW_SWITCH_TIMER->CC[cc] - RADIO_EVENTS_PHYEND_DELAY_US);
805 			if (delay < SW_SWITCH_TIMER->CC[cc]) {
806 				nrf_timer_cc_set(SW_SWITCH_TIMER, phyend_delay_cc,
807 						 (SW_SWITCH_TIMER->CC[phyend_delay_cc] - delay));
808 			} else {
809 				nrf_timer_cc_set(SW_SWITCH_TIMER, phyend_delay_cc, 1);
810 			}
811 
812 			hal_radio_sw_switch_phyend_delay_compensation_config_set(radio_enable_ppi,
813 										 phyend_delay_cc);
814 		} else {
815 			hal_radio_sw_switch_phyend_delay_compensation_config_clear(radio_enable_ppi,
816 										   phyend_delay_cc);
817 		}
818 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
819 
820 #if defined(CONFIG_BT_CTLR_PHY_CODED)
821 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
822 		uint8_t ppi_en = HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(sw_tifs_toggle);
823 		uint8_t ppi_dis = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(sw_tifs_toggle);
824 		uint8_t cc_s2 = SW_SWITCH_TIMER_S2_EVTS_COMP(sw_tifs_toggle);
825 
826 		if (dir_curr == SW_SWITCH_RX && (phy_curr & PHY_CODED)) {
827 			/* Switching to TX after RX on LE Coded PHY. */
828 			uint32_t delay_s2;
829 			uint32_t new_cc_s2_value;
830 
831 			/* Calculate assuming reception on S2 coding scheme. */
832 			delay_s2 = HAL_RADIO_NS2US_ROUND(
833 				hal_radio_tx_ready_delay_ns_get(phy_next,
834 								flags_next) +
835 				hal_radio_rx_chain_delay_ns_get(phy_curr, 0));
836 
837 			new_cc_s2_value = SW_SWITCH_TIMER->CC[cc];
838 
839 			if (delay_s2 < new_cc_s2_value) {
840 				new_cc_s2_value -= delay_s2;
841 			} else {
842 				new_cc_s2_value = 1;
843 			}
844 			nrf_timer_cc_set(SW_SWITCH_TIMER, cc_s2,
845 					 new_cc_s2_value);
846 
847 			/* Setup the Tx start for S2 using a dedicated compare,
848 			 * setup a PPI to disable PPI group on that compare
849 			 * event, and then importantly setup a capture PPI to
850 			 * disable the Tx start for S8 on RATEBOOST event.
851 			 */
852 			hal_radio_sw_switch_coded_tx_config_set(ppi_en, ppi_dis,
853 				cc_s2, sw_tifs_toggle);
854 
855 		} else {
856 			/* Switching to TX after RX on LE 1M/2M PHY.
857 			 *
858 			 * NOTE: PHYEND delay compensation and switching between Coded S2 and S8 PHY
859 			 *       may not happen at once. PHYEND delay may not happen when Code PHY
860 			 *       is used. Both functionalities use the same EVENTS_COMPARE channels,
861 			 *       hence when PHYEND delay is applied, coded config clear may not be
862 			 *       called.
863 			 *
864 			 * TODO: This has to be refactored. It is temporarily implemented this way
865 			 *       because the code is very fragile and hard to debug.
866 			 */
867 			if (end_evt_delay_en != END_EVT_DELAY_ENABLED) {
868 				hal_radio_sw_switch_coded_config_clear(ppi_en, ppi_dis, cc_s2,
869 								       sw_tifs_toggle);
870 			}
871 
872 			hal_radio_sw_switch_disable_group_clear(ppi_dis, cc, sw_tifs_toggle);
873 		}
874 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
875 #endif /* CONFIG_BT_CTLR_PHY_CODED */
876 	} else {
877 		/* RX */
878 
879 		/* Calculate delay with respect to current and next PHY. */
880 		if (dir_curr) {
881 			delay = HAL_RADIO_NS2US_CEIL(
882 				hal_radio_rx_ready_delay_ns_get(phy_next,
883 								flags_next) +
884 				hal_radio_tx_chain_delay_ns_get(phy_curr,
885 								flags_curr)) +
886 				(EVENT_CLOCK_JITTER_US << 1);
887 
888 			hal_radio_rxen_on_sw_switch(cc, ppi);
889 		} else {
890 			delay = HAL_RADIO_NS2US_CEIL(
891 				hal_radio_rx_ready_delay_ns_get(phy_next,
892 								flags_next) +
893 				hal_radio_rx_chain_delay_ns_get(phy_curr,
894 								flags_curr)) +
895 				(EVENT_CLOCK_JITTER_US << 1);
896 
897 			hal_radio_b2b_rxen_on_sw_switch(cc, ppi);
898 		}
899 
900 
901 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
902 		hal_radio_sw_switch_phyend_delay_compensation_config_clear(radio_enable_ppi,
903 									   phyend_delay_cc);
904 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
905 
906 #if defined(CONFIG_BT_CTLR_PHY_CODED)
907 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
908 		if (1) {
909 			uint8_t ppi_en = HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(sw_tifs_toggle);
910 			uint8_t ppi_dis = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(sw_tifs_toggle);
911 			uint8_t cc_s2 = SW_SWITCH_TIMER_S2_EVTS_COMP(sw_tifs_toggle);
912 
913 			hal_radio_sw_switch_coded_config_clear(ppi_en, ppi_dis, cc_s2,
914 							       sw_tifs_toggle);
915 			hal_radio_sw_switch_disable_group_clear(ppi_dis, cc, sw_tifs_toggle);
916 		}
917 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
918 #endif /* CONFIG_BT_CTLR_PHY_CODED */
919 	}
920 
921 	if (delay < SW_SWITCH_TIMER->CC[cc]) {
922 		nrf_timer_cc_set(SW_SWITCH_TIMER,
923 				 cc,
924 				 (SW_SWITCH_TIMER->CC[cc] - delay));
925 	} else {
926 		nrf_timer_cc_set(SW_SWITCH_TIMER, cc, 1);
927 	}
928 
929 	hal_radio_nrf_ppi_channels_enable(BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) |
930 				BIT(HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI));
931 
932 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
933 	/* NOTE: For single timer configuration nRF5340 shares the DPPI channel being
934 	 *       triggered by Radio End for End time capture and sw_switch DPPI channel toggling
935 	 *       hence always need to capture End time. Or when using single event timer since
936 	 *       the timer is cleared on Radio End, we always need to capture the Radio End
937 	 *       time-stamp.
938 	 */
939 	hal_radio_end_time_capture_ppi_config();
940 #if !defined(CONFIG_SOC_COMPATIBLE_NRF53X) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
941 	/* The function is not called for nRF5340 single timer configuration because
942 	 * HAL_SW_SWITCH_TIMER_CLEAR_PPI is equal to HAL_RADIO_END_TIME_CAPTURE_PPI,
943 	 * so channel is already enabled.
944 	 */
945 	hal_radio_nrf_ppi_channels_enable(BIT(HAL_RADIO_END_TIME_CAPTURE_PPI));
946 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
947 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
948 
949 	sw_tifs_toggle += 1U;
950 	sw_tifs_toggle &= 1U;
951 }
952 #endif /* CONFIG_BT_CTLR_TIFS_HW */
953 
radio_switch_complete_and_rx(uint8_t phy_rx)954 void radio_switch_complete_and_rx(uint8_t phy_rx)
955 {
956 #if defined(CONFIG_BT_CTLR_TIFS_HW)
957 	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk |
958 			    NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk |
959 			    RADIO_SHORTS_DISABLED_RXEN_Msk;
960 #else /* !CONFIG_BT_CTLR_TIFS_HW */
961 	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk;
962 
963 	/* NOTE: As Tx chain delays are negligible constant values (~1 us)
964 	 *	 across nRF5x radios, sw_switch assumes the 1M chain delay for
965 	 *       calculations.
966 	 */
967 	sw_switch(SW_SWITCH_TX, SW_SWITCH_RX, SW_SWITCH_PHY_1M, SW_SWITCH_FLAGS_DONTCARE, phy_rx,
968 		  SW_SWITCH_FLAGS_DONTCARE, END_EVT_DELAY_DISABLED);
969 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
970 }
971 
radio_switch_complete_and_tx(uint8_t phy_rx,uint8_t flags_rx,uint8_t phy_tx,uint8_t flags_tx)972 void radio_switch_complete_and_tx(uint8_t phy_rx, uint8_t flags_rx,
973 				  uint8_t phy_tx, uint8_t flags_tx)
974 {
975 #if defined(CONFIG_BT_CTLR_TIFS_HW)
976 	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk |
977 			    NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk |
978 			    RADIO_SHORTS_DISABLED_TXEN_Msk;
979 #else /* !CONFIG_BT_CTLR_TIFS_HW */
980 	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk;
981 
982 	sw_switch(SW_SWITCH_RX, SW_SWITCH_TX, phy_rx, flags_rx, phy_tx, flags_tx,
983 		  END_EVT_DELAY_DISABLED);
984 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
985 }
986 
radio_switch_complete_with_delay_compensation_and_tx(uint8_t phy_rx,uint8_t flags_rx,uint8_t phy_tx,uint8_t flags_tx,enum radio_end_evt_delay_state end_delay_en)987 void radio_switch_complete_with_delay_compensation_and_tx(
988 	uint8_t phy_rx, uint8_t flags_rx, uint8_t phy_tx, uint8_t flags_tx,
989 	enum radio_end_evt_delay_state end_delay_en)
990 {
991 #if defined(CONFIG_BT_CTLR_TIFS_HW)
992 	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk |
993 			    RADIO_SHORTS_DISABLED_TXEN_Msk;
994 #else /* !CONFIG_BT_CTLR_TIFS_HW */
995 	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk;
996 
997 	sw_switch(SW_SWITCH_RX, SW_SWITCH_TX, phy_rx, flags_rx, phy_tx, flags_tx, end_delay_en);
998 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
999 }
1000 
radio_switch_complete_and_b2b_tx(uint8_t phy_curr,uint8_t flags_curr,uint8_t phy_next,uint8_t flags_next)1001 void radio_switch_complete_and_b2b_tx(uint8_t phy_curr, uint8_t flags_curr,
1002 				      uint8_t phy_next, uint8_t flags_next)
1003 {
1004 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1005 	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk |
1006 			    NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk |
1007 			    RADIO_SHORTS_DISABLED_TXEN_Msk;
1008 #else /* !CONFIG_BT_CTLR_TIFS_HW */
1009 	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk;
1010 
1011 	sw_switch(SW_SWITCH_TX, SW_SWITCH_TX, phy_curr, flags_curr, phy_next, flags_next,
1012 		  END_EVT_DELAY_DISABLED);
1013 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1014 }
1015 
radio_switch_complete_and_b2b_rx(uint8_t phy_curr,uint8_t flags_curr,uint8_t phy_next,uint8_t flags_next)1016 void radio_switch_complete_and_b2b_rx(uint8_t phy_curr, uint8_t flags_curr,
1017 				      uint8_t phy_next, uint8_t flags_next)
1018 {
1019 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1020 	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk |
1021 			    NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk |
1022 			    RADIO_SHORTS_DISABLED_RXEN_Msk;
1023 #else /* !CONFIG_BT_CTLR_TIFS_HW */
1024 	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk;
1025 
1026 	sw_switch(SW_SWITCH_RX, SW_SWITCH_RX, phy_curr, flags_curr, phy_next, flags_next,
1027 		  END_EVT_DELAY_DISABLED);
1028 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1029 }
1030 
radio_switch_complete_and_b2b_tx_disable(void)1031 void radio_switch_complete_and_b2b_tx_disable(void)
1032 {
1033 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1034 	NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1035 #else /* CONFIG_BT_CTLR_TIFS_HW */
1036 	NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1037 	hal_radio_sw_switch_b2b_tx_disable(sw_tifs_toggle);
1038 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1039 }
1040 
radio_switch_complete_and_b2b_rx_disable(void)1041 void radio_switch_complete_and_b2b_rx_disable(void)
1042 {
1043 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1044 	NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1045 #else /* CONFIG_BT_CTLR_TIFS_HW */
1046 	NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1047 	hal_radio_sw_switch_b2b_rx_disable(sw_tifs_toggle);
1048 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1049 }
1050 
radio_switch_complete_and_disable(void)1051 void radio_switch_complete_and_disable(void)
1052 {
1053 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1054 	NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1055 #else /* CONFIG_BT_CTLR_TIFS_HW */
1056 	NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1057 	hal_radio_sw_switch_disable();
1058 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1059 }
1060 
radio_phy_flags_rx_get(void)1061 uint8_t radio_phy_flags_rx_get(void)
1062 {
1063 #if defined(CONFIG_BT_CTLR_PHY_CODED)
1064 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
1065 	return (NRF_RADIO->EVENTS_RATEBOOST) ? 0U : 1U;
1066 #else /* !CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1067 	return 0;
1068 #endif /* !CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1069 #else /* !CONFIG_BT_CTLR_PHY_CODED */
1070 	return 0;
1071 #endif /* !CONFIG_BT_CTLR_PHY_CODED */
1072 }
1073 
radio_rssi_measure(void)1074 void radio_rssi_measure(void)
1075 {
1076 	NRF_RADIO->SHORTS |=
1077 	    (RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
1078 #if defined(CONFIG_SOC_SERIES_NRF51X) || \
1079 	defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
1080 	defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET)
1081 	     RADIO_SHORTS_DISABLED_RSSISTOP_Msk |
1082 #endif
1083 	     0);
1084 }
1085 
radio_rssi_get(void)1086 uint32_t radio_rssi_get(void)
1087 {
1088 	return NRF_RADIO->RSSISAMPLE;
1089 }
1090 
radio_rssi_status_reset(void)1091 void radio_rssi_status_reset(void)
1092 {
1093 #if defined(CONFIG_SOC_SERIES_NRF51X) || \
1094 	defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
1095 	defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET)
1096 	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND);
1097 #endif
1098 }
1099 
radio_rssi_is_ready(void)1100 uint32_t radio_rssi_is_ready(void)
1101 {
1102 #if defined(CONFIG_SOC_SERIES_NRF51X) || \
1103 	defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
1104 	defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET)
1105 	return (NRF_RADIO->EVENTS_RSSIEND != 0);
1106 #else
1107 	return 1U;
1108 #endif
1109 }
1110 
radio_filter_configure(uint8_t bitmask_enable,uint8_t bitmask_addr_type,uint8_t * bdaddr)1111 void radio_filter_configure(uint8_t bitmask_enable, uint8_t bitmask_addr_type,
1112 			    uint8_t *bdaddr)
1113 {
1114 	uint8_t index;
1115 
1116 	for (index = 0U; index < 8; index++) {
1117 		NRF_RADIO->DAB[index] = ((uint32_t)bdaddr[3] << 24) |
1118 			((uint32_t)bdaddr[2] << 16) |
1119 			((uint32_t)bdaddr[1] << 8) |
1120 			bdaddr[0];
1121 		NRF_RADIO->DAP[index] = ((uint32_t)bdaddr[5] << 8) | bdaddr[4];
1122 		bdaddr += 6;
1123 	}
1124 
1125 	NRF_RADIO->DACNF = ((uint32_t)bitmask_addr_type << 8) | bitmask_enable;
1126 }
1127 
radio_filter_disable(void)1128 void radio_filter_disable(void)
1129 {
1130 	NRF_RADIO->DACNF &= ~(0x000000FF);
1131 }
1132 
radio_filter_status_reset(void)1133 void radio_filter_status_reset(void)
1134 {
1135 	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DEVMATCH);
1136 }
1137 
radio_filter_has_match(void)1138 uint32_t radio_filter_has_match(void)
1139 {
1140 	return (NRF_RADIO->EVENTS_DEVMATCH != 0);
1141 }
1142 
radio_filter_match_get(void)1143 uint32_t radio_filter_match_get(void)
1144 {
1145 	return NRF_RADIO->DAI;
1146 }
1147 
radio_bc_configure(uint32_t n)1148 void radio_bc_configure(uint32_t n)
1149 {
1150 	NRF_RADIO->BCC = n;
1151 	NRF_RADIO->SHORTS |= RADIO_SHORTS_ADDRESS_BCSTART_Msk;
1152 }
1153 
radio_bc_status_reset(void)1154 void radio_bc_status_reset(void)
1155 {
1156 	nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH);
1157 }
1158 
radio_bc_has_match(void)1159 uint32_t radio_bc_has_match(void)
1160 {
1161 	return (NRF_RADIO->EVENTS_BCMATCH != 0);
1162 }
1163 
1164 #if defined(CONFIG_BT_CTLR_RADIO_TIMER_ISR)
1165 static radio_isr_cb_t isr_radio_tmr_cb;
1166 static void           *isr_radio_tmr_cb_param;
1167 
isr_radio_tmr(void)1168 void isr_radio_tmr(void)
1169 {
1170 	irq_disable(TIMER0_IRQn);
1171 	nrf_timer_int_disable(EVENT_TIMER, TIMER_INTENSET_COMPARE2_Msk);
1172 	nrf_timer_event_clear(EVENT_TIMER, HAL_EVENT_TIMER_DEFERRED_TX_EVENT);
1173 
1174 	isr_radio_tmr_cb(isr_radio_tmr_cb_param);
1175 }
1176 
radio_tmr_isr_set(uint32_t start_us,radio_isr_cb_t cb,void * param)1177 uint32_t radio_tmr_isr_set(uint32_t start_us, radio_isr_cb_t cb, void *param)
1178 {
1179 	irq_disable(TIMER0_IRQn);
1180 
1181 	isr_radio_tmr_cb_param = param;
1182 	isr_radio_tmr_cb = cb;
1183 
1184 	/* start_us could be the current count in the timer */
1185 	uint32_t now_us = start_us;
1186 
1187 	/* Setup timer compare while determining the latency in doing so */
1188 	do {
1189 		/* Set start to be, now plus the determined latency */
1190 		start_us = (now_us << 1) - start_us;
1191 
1192 		/* Setup compare event with min. 1 us offset */
1193 		nrf_timer_event_clear(EVENT_TIMER, HAL_EVENT_TIMER_DEFERRED_TX_EVENT);
1194 		nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_DEFERRED_TRX_CC_OFFSET,
1195 				 start_us + 1U);
1196 
1197 		/* Capture the current time */
1198 		nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK);
1199 
1200 		now_us = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1201 	} while ((now_us > start_us) &&
1202 		 (EVENT_TIMER->EVENTS_COMPARE[HAL_EVENT_TIMER_DEFERRED_TRX_CC_OFFSET] == 0U));
1203 
1204 	nrf_timer_int_enable(EVENT_TIMER, TIMER_INTENSET_COMPARE2_Msk);
1205 
1206 	NVIC_ClearPendingIRQ(TIMER0_IRQn);
1207 
1208 	irq_enable(TIMER0_IRQn);
1209 
1210 	return start_us + 1U;
1211 }
1212 #endif /* CONFIG_BT_CTLR_RADIO_TIMER_ISR */
1213 
radio_tmr_status_reset(void)1214 void radio_tmr_status_reset(void)
1215 {
1216 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1217 	nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1218 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1219 	nrf_rtc_event_disable(NRF_RTC, RTC_EVTENCLR_COMPARE2_Msk);
1220 #endif  /* !CONFIG_BT_CTLR_NRF_GRTC */
1221 
1222 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1223 	hal_trigger_crypt_ppi_disable();
1224 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1225 
1226 	hal_radio_nrf_ppi_channels_disable(
1227 			BIT(HAL_RADIO_ENABLE_TX_ON_TICK_PPI) |
1228 			BIT(HAL_RADIO_ENABLE_RX_ON_TICK_PPI) |
1229 			BIT(HAL_EVENT_TIMER_START_PPI) |
1230 			BIT(HAL_RADIO_READY_TIME_CAPTURE_PPI) |
1231 			BIT(HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI) |
1232 			BIT(HAL_RADIO_DISABLE_ON_HCTO_PPI) |
1233 			BIT(HAL_RADIO_END_TIME_CAPTURE_PPI) |
1234 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1235 			BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) |
1236 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1237 #if defined(CONFIG_BT_CTLR_PHY_CODED)
1238 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
1239 			BIT(HAL_TRIGGER_RATEOVERRIDE_PPI) |
1240 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1241 			BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI) |
1242 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1243 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1244 #endif /* CONFIG_BT_CTLR_PHY_CODED */
1245 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
1246 			BIT(HAL_SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_DISABLE_PPI) |
1247 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
1248 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX)
1249 			BIT(HAL_TRIGGER_CRYPT_DELAY_PPI) |
1250 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */
1251 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1252 			BIT(HAL_TRIGGER_CRYPT_PPI) |
1253 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1254 			0);
1255 }
1256 
radio_tmr_tx_status_reset(void)1257 void radio_tmr_tx_status_reset(void)
1258 {
1259 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1260 	nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1261 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1262 	nrf_rtc_event_disable(NRF_RTC, RTC_EVTENCLR_COMPARE2_Msk);
1263 #endif  /* !CONFIG_BT_CTLR_NRF_GRTC */
1264 
1265 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1266 	hal_trigger_crypt_ppi_disable();
1267 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1268 
1269 	hal_radio_nrf_ppi_channels_disable(
1270 #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI != HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && \
1271 	!defined(DPPI_PRESENT)
1272 			BIT(HAL_RADIO_ENABLE_TX_ON_TICK_PPI) |
1273 #endif /* (HAL_RADIO_ENABLE_TX_ON_TICK_PPI !=
1274 	*  HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && !DPPI_PRESENT
1275 	*/
1276 			BIT(HAL_EVENT_TIMER_START_PPI) |
1277 			BIT(HAL_RADIO_READY_TIME_CAPTURE_PPI) |
1278 			BIT(HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI) |
1279 			BIT(HAL_RADIO_DISABLE_ON_HCTO_PPI) |
1280 			BIT(HAL_RADIO_END_TIME_CAPTURE_PPI) |
1281 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1282 			BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) |
1283 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1284 #if defined(CONFIG_BT_CTLR_PHY_CODED)
1285 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
1286 			BIT(HAL_TRIGGER_RATEOVERRIDE_PPI) |
1287 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1288 			BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI) |
1289 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1290 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1291 #endif /* CONFIG_BT_CTLR_PHY_CODED */
1292 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
1293 			BIT(HAL_SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_DISABLE_PPI) |
1294 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
1295 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX)
1296 			BIT(HAL_TRIGGER_CRYPT_DELAY_PPI) |
1297 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */
1298 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1299 			BIT(HAL_TRIGGER_CRYPT_PPI) |
1300 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1301 			0);
1302 }
1303 
radio_tmr_rx_status_reset(void)1304 void radio_tmr_rx_status_reset(void)
1305 {
1306 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1307 	nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1308 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1309 	nrf_rtc_event_disable(NRF_RTC, RTC_EVTENCLR_COMPARE2_Msk);
1310 #endif  /* !CONFIG_BT_CTLR_NRF_GRTC */
1311 
1312 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1313 	hal_trigger_crypt_ppi_disable();
1314 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1315 
1316 	hal_radio_nrf_ppi_channels_disable(
1317 #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI != HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && \
1318 	!defined(DPPI_PRESENT)
1319 			BIT(HAL_RADIO_ENABLE_RX_ON_TICK_PPI) |
1320 #endif /* (HAL_RADIO_ENABLE_TX_ON_TICK_PPI !=
1321 	*  HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && !DPPI_PRESENT
1322 	*/
1323 			BIT(HAL_EVENT_TIMER_START_PPI) |
1324 			BIT(HAL_RADIO_READY_TIME_CAPTURE_PPI) |
1325 			BIT(HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI) |
1326 			BIT(HAL_RADIO_DISABLE_ON_HCTO_PPI) |
1327 			BIT(HAL_RADIO_END_TIME_CAPTURE_PPI) |
1328 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1329 			BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) |
1330 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1331 #if defined(CONFIG_BT_CTLR_PHY_CODED)
1332 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
1333 			BIT(HAL_TRIGGER_RATEOVERRIDE_PPI) |
1334 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1335 			BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI) |
1336 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1337 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1338 #endif /* CONFIG_BT_CTLR_PHY_CODED */
1339 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
1340 			BIT(HAL_SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_DISABLE_PPI) |
1341 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
1342 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX)
1343 			BIT(HAL_TRIGGER_CRYPT_DELAY_PPI) |
1344 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */
1345 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1346 			BIT(HAL_TRIGGER_CRYPT_PPI) |
1347 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1348 			0);
1349 }
1350 
radio_tmr_tx_enable(void)1351 void radio_tmr_tx_enable(void)
1352 {
1353 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1354 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1355 #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI)
1356 	hal_radio_enable_on_tick_ppi_config_and_enable(1U);
1357 #endif /* HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI */
1358 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1359 }
1360 
radio_tmr_rx_enable(void)1361 void radio_tmr_rx_enable(void)
1362 {
1363 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1364 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1365 #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI)
1366 	hal_radio_enable_on_tick_ppi_config_and_enable(0U);
1367 #endif /* HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI */
1368 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1369 }
1370 
radio_tmr_tx_disable(void)1371 void radio_tmr_tx_disable(void)
1372 {
1373 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1374 	nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN);
1375 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1376 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1377 }
1378 
radio_tmr_rx_disable(void)1379 void radio_tmr_rx_disable(void)
1380 {
1381 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1382 	nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RXEN);
1383 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1384 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1385 }
1386 
radio_tmr_tifs_set(uint32_t tifs)1387 void radio_tmr_tifs_set(uint32_t tifs)
1388 {
1389 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1390 	NRF_RADIO->TIFS = tifs;
1391 #else /* !CONFIG_BT_CTLR_TIFS_HW */
1392 	nrf_timer_cc_set(SW_SWITCH_TIMER,
1393 			 SW_SWITCH_TIMER_EVTS_COMP(sw_tifs_toggle), tifs);
1394 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1395 }
1396 
radio_tmr_start(uint8_t trx,uint32_t ticks_start,uint32_t remainder)1397 uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)
1398 {
1399 	uint32_t remainder_us;
1400 
1401 	/* Convert jitter to positive offset remainder in microseconds */
1402 	hal_ticker_remove_jitter(&ticks_start, &remainder);
1403 	remainder_us = remainder;
1404 
1405 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1406 	/* When using single timer for software tIFS switching, ensure that
1407 	 * the timer compare value is large enough to consider radio ISR
1408 	 * latency so that the ISR is able to disable the PPI/DPPI that again
1409 	 * could trigger the TXEN/RXEN task.
1410 	 * The timer is cleared on Radio End and if the PPI/DPPI is not disabled
1411 	 * by the Radio ISR, the compare will trigger again.
1412 	 */
1413 	uint32_t latency_ticks;
1414 	uint32_t latency_us;
1415 
1416 	latency_us = MAX(remainder_us, HAL_RADIO_ISR_LATENCY_MAX_US) - remainder_us;
1417 	latency_ticks = HAL_TICKER_US_TO_TICKS(latency_us);
1418 	ticks_start -= latency_ticks;
1419 	remainder_us += latency_us;
1420 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1421 
1422 	nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_CLEAR);
1423 	EVENT_TIMER->MODE = 0;
1424 	EVENT_TIMER->PRESCALER = HAL_EVENT_TIMER_PRESCALER_VALUE;
1425 	EVENT_TIMER->BITMODE = 2;	/* 24 - bit */
1426 
1427 	nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_CC_OFFSET, remainder_us);
1428 
1429 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1430 	uint32_t cntr_l, cntr_h, cntr_h_overflow, stale;
1431 
1432 	/* Disable capture/compare */
1433 	nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1434 
1435 	/* NOTE: We are going to use TASKS_CAPTURE to read current
1436 	 *       SYSCOUNTER H and L, so that COMPARE registers can be set
1437 	 *       considering that we need to set H compare value too.
1438 	 */
1439 
1440 	/* Read current syscounter value */
1441 	do {
1442 		cntr_h = nrf_grtc_sys_counter_high_get(NRF_GRTC);
1443 		cntr_l = nrf_grtc_sys_counter_low_get(NRF_GRTC);
1444 		cntr_h_overflow = nrf_grtc_sys_counter_high_get(NRF_GRTC);
1445 	} while ((cntr_h & GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Msk) ||
1446 		 (cntr_h_overflow & GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk));
1447 
1448 	/* Set a stale value in capture value */
1449 	stale = cntr_l - 1U;
1450 	NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL = stale;
1451 
1452 	/* Trigger a capture */
1453 	nrf_grtc_task_trigger(NRF_GRTC, (NRF_GRTC_TASK_CAPTURE_0 +
1454 					 (HAL_CNTR_GRTC_CC_IDX_RADIO * sizeof(uint32_t))));
1455 
1456 	/* Wait to get a new L value */
1457 	do {
1458 		cntr_l = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL;
1459 	} while (cntr_l == stale);
1460 
1461 	/* Read H value */
1462 	cntr_h = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCH;
1463 
1464 	/* NOTE: HERE, we have cntr_h and cntr_l in sync. */
1465 
1466 	/* Handle rollover between current and expected value */
1467 	if (ticks_start < cntr_l) {
1468 		cntr_h++;
1469 	}
1470 
1471 	/* Clear compare event, if any */
1472 	nrf_grtc_event_clear(NRF_GRTC, HAL_CNTR_GRTC_EVENT_COMPARE_RADIO);
1473 
1474 	/* Set compare register values */
1475 	nrf_grtc_sys_counter_cc_set(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO,
1476 				    ((((uint64_t)cntr_h & GRTC_CC_CCH_CCH_Msk) << 32) |
1477 				     ticks_start));
1478 
1479 	/* Enable compare */
1480 	nrf_grtc_sys_counter_compare_event_enable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1481 
1482 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1483 	nrf_rtc_cc_set(NRF_RTC, 2, ticks_start);
1484 	nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE2_Msk);
1485 #endif  /* !CONFIG_BT_CTLR_NRF_GRTC */
1486 
1487 	hal_event_timer_start_ppi_config();
1488 	hal_radio_nrf_ppi_channels_enable(BIT(HAL_EVENT_TIMER_START_PPI));
1489 
1490 	hal_radio_enable_on_tick_ppi_config_and_enable(trx);
1491 
1492 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1493 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1494 	last_pdu_end_us_init(latency_us);
1495 
1496 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1497 	nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_CLEAR);
1498 	SW_SWITCH_TIMER->MODE = 0;
1499 	SW_SWITCH_TIMER->PRESCALER = HAL_EVENT_TIMER_PRESCALER_VALUE;
1500 	SW_SWITCH_TIMER->BITMODE = 0; /* 16 bit */
1501 	/* FIXME: start along with EVENT_TIMER, to save power */
1502 	nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_START);
1503 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1504 
1505 	hal_sw_switch_timer_clear_ppi_config();
1506 
1507 #if !defined(CONFIG_BT_CTLR_PHY_CODED) || \
1508 	!defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
1509 	/* Software switch group's disable PPI can be configured one time here
1510 	 * at timer setup when only 1M and/or 2M is supported.
1511 	 */
1512 	hal_radio_group_task_disable_ppi_setup();
1513 
1514 #else /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1515 	/* Software switch group's disable PPI needs to be configured at every
1516 	 * sw_switch() as they depend on the actual PHYs used in TX/RX mode.
1517 	 */
1518 #endif /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1519 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1520 
1521 	return remainder_us;
1522 }
1523 
radio_tmr_start_tick(uint8_t trx,uint32_t ticks_start)1524 uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start)
1525 {
1526 	uint32_t remainder_us;
1527 
1528 	/* Setup compare event with min. 1 us offset */
1529 	remainder_us = 1U;
1530 
1531 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1532 	/* When using single timer for software tIFS switching, ensure that
1533 	 * the timer compare value is large enough to consider radio ISR
1534 	 * latency so that the ISR is able to disable the PPI/DPPI that again
1535 	 * could trigger the TXEN/RXEN task.
1536 	 * The timer is cleared on Radio End and if the PPI/DPPI is not disabled
1537 	 * by the Radio ISR, the compare will trigger again.
1538 	 */
1539 	uint32_t latency_ticks;
1540 	uint32_t latency_us;
1541 
1542 	latency_us = MAX(remainder_us, HAL_RADIO_ISR_LATENCY_MAX_US) - remainder_us;
1543 	latency_ticks = HAL_TICKER_US_TO_TICKS(latency_us);
1544 	ticks_start -= latency_ticks;
1545 	remainder_us += latency_us;
1546 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1547 
1548 	nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_STOP);
1549 	nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_CLEAR);
1550 
1551 	nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_CC_OFFSET, remainder_us);
1552 
1553 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1554 	uint32_t cntr_l, cntr_h, cntr_h_overflow, stale;
1555 
1556 	/* Disable capture/compare */
1557 	nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1558 
1559 	/* NOTE: We are going to use TASKS_CAPTURE to read current
1560 	 *       SYSCOUNTER H and L, so that COMPARE registers can be set
1561 	 *       considering that we need to set H compare value too.
1562 	 */
1563 
1564 	/* Read current syscounter value */
1565 	do {
1566 		cntr_h = nrf_grtc_sys_counter_high_get(NRF_GRTC);
1567 		cntr_l = nrf_grtc_sys_counter_low_get(NRF_GRTC);
1568 		cntr_h_overflow = nrf_grtc_sys_counter_high_get(NRF_GRTC);
1569 	} while ((cntr_h & GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Msk) ||
1570 		 (cntr_h_overflow & GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk));
1571 
1572 	/* Set a stale value in capture value */
1573 	stale = cntr_l - 1U;
1574 	NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL = stale;
1575 
1576 	/* Trigger a capture */
1577 	nrf_grtc_task_trigger(NRF_GRTC, (NRF_GRTC_TASK_CAPTURE_0 +
1578 					 (HAL_CNTR_GRTC_CC_IDX_RADIO * sizeof(uint32_t))));
1579 
1580 	/* Wait to get a new L value */
1581 	do {
1582 		cntr_l = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL;
1583 	} while (cntr_l == stale);
1584 
1585 	/* Read H value */
1586 	cntr_h = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCH;
1587 
1588 	/* NOTE: HERE, we have cntr_h and cntr_l in sync. */
1589 
1590 	/* Handle rollover between current and expected value */
1591 	if (ticks_start < cntr_l) {
1592 		cntr_h++;
1593 	}
1594 
1595 	/* Clear compare event, if any */
1596 	nrf_grtc_event_clear(NRF_GRTC, HAL_CNTR_GRTC_EVENT_COMPARE_RADIO);
1597 
1598 	/* Set compare register values */
1599 	nrf_grtc_sys_counter_cc_set(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO,
1600 				    ((((uint64_t)cntr_h & GRTC_CC_CCH_CCH_Msk) << 32) |
1601 				     ticks_start));
1602 
1603 	/* Enable compare */
1604 	nrf_grtc_sys_counter_compare_event_enable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1605 
1606 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1607 	nrf_rtc_cc_set(NRF_RTC, 2, ticks_start);
1608 	nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE2_Msk);
1609 #endif  /* !CONFIG_BT_CTLR_NRF_GRTC */
1610 
1611 	hal_event_timer_start_ppi_config();
1612 	hal_radio_nrf_ppi_channels_enable(BIT(HAL_EVENT_TIMER_START_PPI));
1613 
1614 	hal_radio_enable_on_tick_ppi_config_and_enable(trx);
1615 
1616 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1617 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1618 	last_pdu_end_us_init(latency_us);
1619 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1620 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1621 	/* NOTE: Timer clear DPPI configuration is needed only for nRF53
1622 	 *       because of calls to radio_disable() and
1623 	 *       radio_switch_complete_and_disable() inside a radio event call
1624 	 *       hal_radio_sw_switch_disable(), which in the case of nRF53
1625 	 *       cancels the task subscription.
1626 	 */
1627 	/* FIXME: hal_sw_switch_timer_clear_ppi_config() sets both task and
1628 	 *        event. Consider a new interface to only set the task, or
1629 	 *        change the design to not clear task subscription inside a
1630 	 *        radio event but when the radio event is done.
1631 	 */
1632 	hal_sw_switch_timer_clear_ppi_config();
1633 #endif /* CONFIG_SOC_COMPATIBLE_NRF53X || CONFIG_SOC_COMPATIBLE_NRF54LX */
1634 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1635 
1636 	return remainder_us;
1637 }
1638 
radio_tmr_start_us(uint8_t trx,uint32_t start_us)1639 uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us)
1640 {
1641 	hal_radio_enable_on_tick_ppi_config_and_enable(trx);
1642 
1643 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1644 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1645 	/* As timer is reset on every radio end, remove the accumulated
1646 	 * last_pdu_end_us in the given start_us.
1647 	 */
1648 	start_us -= last_pdu_end_us;
1649 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1650 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1651 	/* NOTE: Timer clear DPPI configuration is needed only for nRF53
1652 	 *       because of calls to radio_disable() and
1653 	 *       radio_switch_complete_and_disable() inside a radio event call
1654 	 *       hal_radio_sw_switch_disable(), which in the case of nRF53
1655 	 *       cancels the task subscription.
1656 	 */
1657 	/* FIXME: hal_sw_switch_timer_clear_ppi_config() sets both task and
1658 	 *        event. Consider a new interface to only set the task, or
1659 	 *        change the design to not clear task subscription inside a
1660 	 *        radio event but when the radio event is done.
1661 	 */
1662 	hal_sw_switch_timer_clear_ppi_config();
1663 #endif /* CONFIG_SOC_COMPATIBLE_NRF53X || CONFIG_SOC_COMPATIBLE_NRF54LX */
1664 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1665 
1666 	/* start_us could be the current count in the timer */
1667 	uint32_t now_us = start_us;
1668 	uint32_t actual_us;
1669 
1670 	/* Setup timer compare while determining the latency in doing so */
1671 	do {
1672 		/* Set start to be, now plus the determined latency */
1673 		start_us = (now_us << 1) - start_us;
1674 
1675 		/* Setup compare event with min. 1 us offset */
1676 		actual_us = start_us + 1U;
1677 
1678 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1679 		/* When using single timer for software tIFS switching, ensure that
1680 		 * the timer compare value is large enough to consider radio ISR
1681 		 * latency so that the ISR is able to disable the PPI/DPPI that again
1682 		 * could trigger the TXEN/RXEN task.
1683 		 * The timer is cleared on Radio End and if the PPI/DPPI is not disabled
1684 		 * by the Radio ISR, the compare will trigger again.
1685 		 */
1686 		uint32_t latency_us;
1687 
1688 		latency_us = MAX(actual_us, HAL_RADIO_ISR_LATENCY_MAX_US) - actual_us;
1689 		actual_us += latency_us;
1690 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1691 
1692 		nrf_timer_event_clear(EVENT_TIMER, HAL_EVENT_TIMER_TRX_EVENT);
1693 		nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_CC_OFFSET, actual_us);
1694 
1695 		/* Capture the current time */
1696 		nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK);
1697 
1698 		now_us = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1699 	} while ((now_us > start_us) &&
1700 		 (EVENT_TIMER->EVENTS_COMPARE[HAL_EVENT_TIMER_TRX_CC_OFFSET] == 0U));
1701 
1702 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1703 	actual_us += last_pdu_end_us;
1704 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1705 
1706 	return actual_us;
1707 }
1708 
radio_tmr_start_now(uint8_t trx)1709 uint32_t radio_tmr_start_now(uint8_t trx)
1710 {
1711 	uint32_t start_us;
1712 
1713 	/* PPI/DPPI configuration will be done in radio_tmr_start_us() */
1714 
1715 	/* Capture the current time */
1716 	nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK);
1717 	start_us = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1718 
1719 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1720 	/* As timer is reset on every radio end, add the accumulated
1721 	 * last_pdu_end_us to the captured current time.
1722 	 */
1723 	start_us += last_pdu_end_us;
1724 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1725 
1726 	/* Setup radio start at current time */
1727 	start_us = radio_tmr_start_us(trx, start_us);
1728 
1729 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1730 	/* Remove the single timer start latency used to mitigate use of too
1731 	 * small compare register value. Thus, start_us returned be always
1732 	 * the value corresponding to the captured radio ready timestamp.
1733 	 * This is used in the calculation of aux_offset in subsequent
1734 	 * ADV_EXT_IND PDUs.
1735 	 */
1736 	start_us -= last_pdu_end_latency_us;
1737 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1738 
1739 	return start_us;
1740 }
1741 
radio_tmr_start_get(void)1742 uint32_t radio_tmr_start_get(void)
1743 {
1744 	uint32_t start_ticks;
1745 
1746 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1747 	uint64_t cc;
1748 
1749 	cc = nrf_grtc_sys_counter_cc_get(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1750 
1751 	start_ticks = cc & 0xffffffffUL;
1752 
1753 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1754 	start_ticks = nrf_rtc_cc_get(NRF_RTC, 2);
1755 #endif  /* !CONFIG_BT_CTLR_NRF_GRTC */
1756 
1757 	return start_ticks;
1758 }
1759 
radio_tmr_start_latency_get(void)1760 uint32_t radio_tmr_start_latency_get(void)
1761 {
1762 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1763 	return last_pdu_end_latency_us;
1764 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1765 	return 0U;
1766 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1767 }
1768 
radio_tmr_stop(void)1769 void radio_tmr_stop(void)
1770 {
1771 	nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_STOP);
1772 #if defined(TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk)
1773 	nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_SHUTDOWN);
1774 #endif /* TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk */
1775 
1776 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1777 #if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1778 	nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_STOP);
1779 #if defined(TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk)
1780 	nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_SHUTDOWN);
1781 #endif /* TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk */
1782 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1783 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1784 
1785 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1786 	NRF_POWER->TASKS_LOWPWR = 1U;
1787 #endif /* CONFIG_SOC_COMPATIBLE_NRF54LX */
1788 }
1789 
radio_tmr_hcto_configure(uint32_t hcto_us)1790 void radio_tmr_hcto_configure(uint32_t hcto_us)
1791 {
1792 	nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_HCTO_CC_OFFSET, hcto_us);
1793 
1794 	hal_radio_recv_timeout_cancel_ppi_config();
1795 	hal_radio_disable_on_hcto_ppi_config();
1796 	hal_radio_nrf_ppi_channels_enable(
1797 		BIT(HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI) |
1798 		BIT(HAL_RADIO_DISABLE_ON_HCTO_PPI));
1799 }
1800 
radio_tmr_hcto_configure_abs(uint32_t hcto_from_start_us)1801 void radio_tmr_hcto_configure_abs(uint32_t hcto_from_start_us)
1802 {
1803 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1804 	/* As timer is reset on every radio end, remove the accumulated
1805 	 * last_pdu_end_us in the given hcto_us.
1806 	 */
1807 	hcto_from_start_us -= last_pdu_end_us;
1808 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1809 
1810 	radio_tmr_hcto_configure(hcto_from_start_us);
1811 }
1812 
radio_tmr_aa_capture(void)1813 void radio_tmr_aa_capture(void)
1814 {
1815 	hal_radio_ready_time_capture_ppi_config();
1816 	hal_radio_recv_timeout_cancel_ppi_config();
1817 	hal_radio_nrf_ppi_channels_enable(
1818 		BIT(HAL_RADIO_READY_TIME_CAPTURE_PPI) |
1819 		BIT(HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI));
1820 }
1821 
radio_tmr_aa_get(void)1822 uint32_t radio_tmr_aa_get(void)
1823 {
1824 	return EVENT_TIMER->CC[HAL_EVENT_TIMER_HCTO_CC_OFFSET];
1825 }
1826 
1827 static uint32_t radio_tmr_aa;
1828 
radio_tmr_aa_save(uint32_t aa)1829 void radio_tmr_aa_save(uint32_t aa)
1830 {
1831 	radio_tmr_aa = aa;
1832 }
1833 
radio_tmr_aa_restore(void)1834 uint32_t radio_tmr_aa_restore(void)
1835 {
1836 	/* NOTE: we dont need to restore for now, but return the saved value. */
1837 	return radio_tmr_aa;
1838 }
1839 
radio_tmr_ready_get(void)1840 uint32_t radio_tmr_ready_get(void)
1841 {
1842 	return EVENT_TIMER->CC[HAL_EVENT_TIMER_TRX_CC_OFFSET];
1843 }
1844 
1845 static uint32_t radio_tmr_ready;
1846 
radio_tmr_ready_save(uint32_t ready)1847 void radio_tmr_ready_save(uint32_t ready)
1848 {
1849 	radio_tmr_ready = ready;
1850 }
1851 
radio_tmr_ready_restore(void)1852 uint32_t radio_tmr_ready_restore(void)
1853 {
1854 	return radio_tmr_ready;
1855 }
1856 
radio_tmr_end_capture(void)1857 void radio_tmr_end_capture(void)
1858 {
1859 	/* NOTE: nRF5340 for single timer configuration shares the DPPI channel being triggered
1860 	 *       by Radio End for End time capture and sw_switch DPPI channel toggling hence
1861 	 *       always need to capture End time. Hence, the below code is present in
1862 	 *       hal_sw_switch_timer_clear_ppi_config() and sw_switch(). There is no need to
1863 	 *       configure the channel again in this function.
1864 	 */
1865 #if (!defined(CONFIG_SOC_COMPATIBLE_NRF53X) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX)) || \
1866 	((defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)) && \
1867 	 !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER))
1868 	hal_radio_end_time_capture_ppi_config();
1869 	hal_radio_nrf_ppi_channels_enable(BIT(HAL_RADIO_END_TIME_CAPTURE_PPI));
1870 #endif /* (!CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX) ||
1871 	* ((CONFIG_SOC_COMPATIBLE_NRF53X || CONFIG_SOC_COMPATIBLE_NRF54LX) &&
1872 	*  !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1873 	*/
1874 }
1875 
radio_tmr_end_get(void)1876 uint32_t radio_tmr_end_get(void)
1877 {
1878 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1879 	return last_pdu_end_us;
1880 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1881 	return EVENT_TIMER->CC[HAL_EVENT_TIMER_TRX_END_CC_OFFSET];
1882 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1883 }
1884 
radio_tmr_tifs_base_get(void)1885 uint32_t radio_tmr_tifs_base_get(void)
1886 {
1887 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1888 	return 0U;
1889 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1890 	return radio_tmr_end_get();
1891 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1892 }
1893 
1894 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1895 static uint32_t tmr_sample_val;
1896 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1897 
radio_tmr_sample(void)1898 void radio_tmr_sample(void)
1899 {
1900 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1901 	uint32_t cc;
1902 
1903 	cc = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1904 	nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK);
1905 
1906 	tmr_sample_val = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1907 	nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_CC_OFFSET, cc);
1908 
1909 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1910 	nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK);
1911 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1912 }
1913 
radio_tmr_sample_get(void)1914 uint32_t radio_tmr_sample_get(void)
1915 {
1916 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1917 	return tmr_sample_val;
1918 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1919 	return EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1920 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1921 }
1922 
1923 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || \
1924 	defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
radio_gpio_pa_lna_init(void)1925 int radio_gpio_pa_lna_init(void)
1926 {
1927 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
1928 	if (nrfx_gpiote_channel_alloc(&gpiote_palna, &gpiote_ch_palna) != NRFX_SUCCESS) {
1929 		return -ENOMEM;
1930 	}
1931 #endif
1932 
1933 #if defined(NRF_GPIO_PDN_PIN)
1934 	if (nrfx_gpiote_channel_alloc(&gpiote_pdn, &gpiote_ch_pdn) != NRFX_SUCCESS) {
1935 		return -ENOMEM;
1936 	}
1937 #endif
1938 
1939 	return 0;
1940 }
1941 
radio_gpio_pa_lna_deinit(void)1942 void radio_gpio_pa_lna_deinit(void)
1943 {
1944 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
1945 	(void)nrfx_gpiote_channel_free(&gpiote_palna, gpiote_ch_palna);
1946 #endif
1947 
1948 #if defined(NRF_GPIO_PDN_PIN)
1949 	(void)nrfx_gpiote_channel_free(&gpiote_pdn, gpiote_ch_pdn);
1950 #endif
1951 }
1952 
1953 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
radio_gpio_pa_setup(void)1954 void radio_gpio_pa_setup(void)
1955 {
1956 	gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] =
1957 		(GPIOTE_CONFIG_MODE_Task <<
1958 		 GPIOTE_CONFIG_MODE_Pos) |
1959 		(NRF_GPIO_PA_PSEL <<
1960 		 GPIOTE_CONFIG_PSEL_Pos) |
1961 		(GPIOTE_CONFIG_POLARITY_Toggle <<
1962 		 GPIOTE_CONFIG_POLARITY_Pos) |
1963 		(OUTINIT_INACTIVE(NRF_GPIO_PA_FLAGS) <<
1964 		 GPIOTE_CONFIG_OUTINIT_Pos);
1965 
1966 #if defined(HAL_RADIO_FEM_IS_NRF21540)
1967 	hal_pa_ppi_setup();
1968 	radio_gpio_pdn_setup();
1969 #endif
1970 }
1971 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
1972 
1973 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
radio_gpio_lna_setup(void)1974 void radio_gpio_lna_setup(void)
1975 {
1976 	gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] =
1977 		(GPIOTE_CONFIG_MODE_Task <<
1978 		 GPIOTE_CONFIG_MODE_Pos) |
1979 		(NRF_GPIO_LNA_PSEL <<
1980 		 GPIOTE_CONFIG_PSEL_Pos) |
1981 		(GPIOTE_CONFIG_POLARITY_Toggle <<
1982 		 GPIOTE_CONFIG_POLARITY_Pos) |
1983 		(OUTINIT_INACTIVE(NRF_GPIO_LNA_FLAGS) <<
1984 		 GPIOTE_CONFIG_OUTINIT_Pos);
1985 
1986 #if defined(HAL_RADIO_FEM_IS_NRF21540)
1987 	hal_lna_ppi_setup();
1988 	radio_gpio_pdn_setup();
1989 #endif
1990 }
1991 
radio_gpio_pdn_setup(void)1992 void radio_gpio_pdn_setup(void)
1993 {
1994 	/* Note: the pdn-gpios property is optional. */
1995 #if defined(NRF_GPIO_PDN)
1996 	gpiote_pdn.p_reg->CONFIG[gpiote_ch_pdn] =
1997 		(GPIOTE_CONFIG_MODE_Task <<
1998 		 GPIOTE_CONFIG_MODE_Pos) |
1999 		(NRF_GPIO_PDN_PSEL <<
2000 		 GPIOTE_CONFIG_PSEL_Pos) |
2001 		(GPIOTE_CONFIG_POLARITY_Toggle <<
2002 		 GPIOTE_CONFIG_POLARITY_Pos) |
2003 		(OUTINIT_INACTIVE(NRF_GPIO_PDN_FLAGS) <<
2004 		 GPIOTE_CONFIG_OUTINIT_Pos);
2005 #endif /* NRF_GPIO_PDN_PIN */
2006 }
2007 
radio_gpio_lna_on(void)2008 void radio_gpio_lna_on(void)
2009 {
2010 	if (ACTIVE_LOW(NRF_GPIO_LNA_FLAGS)) {
2011 		NRF_GPIO_LNA->OUTCLR = BIT(NRF_GPIO_LNA_PIN);
2012 	} else {
2013 		NRF_GPIO_LNA->OUTSET = BIT(NRF_GPIO_LNA_PIN);
2014 	}
2015 }
2016 
radio_gpio_lna_off(void)2017 void radio_gpio_lna_off(void)
2018 {
2019 	if (ACTIVE_LOW(NRF_GPIO_LNA_FLAGS)) {
2020 		NRF_GPIO_LNA->OUTSET = BIT(NRF_GPIO_LNA_PIN);
2021 	} else {
2022 		NRF_GPIO_LNA->OUTCLR = BIT(NRF_GPIO_LNA_PIN);
2023 	}
2024 }
2025 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
2026 
radio_gpio_pa_lna_enable(uint32_t trx_us)2027 void radio_gpio_pa_lna_enable(uint32_t trx_us)
2028 {
2029 	nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_PA_LNA_CC_OFFSET, trx_us);
2030 #if defined(HAL_RADIO_FEM_IS_NRF21540) && DT_NODE_HAS_PROP(FEM_NODE, pdn_gpios)
2031 	nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_PA_LNA_PDN_CC_OFFSET,
2032 			 (trx_us - NRF_GPIO_PDN_OFFSET));
2033 	hal_radio_nrf_ppi_channels_enable(BIT(HAL_ENABLE_PALNA_PPI) |
2034 					  BIT(HAL_DISABLE_PALNA_PPI) |
2035 					  BIT(HAL_ENABLE_FEM_PPI) |
2036 					  BIT(HAL_DISABLE_FEM_PPI));
2037 #else
2038 	hal_radio_nrf_ppi_channels_enable(BIT(HAL_ENABLE_PALNA_PPI) |
2039 					  BIT(HAL_DISABLE_PALNA_PPI));
2040 #endif
2041 }
2042 
radio_gpio_pa_lna_disable(void)2043 void radio_gpio_pa_lna_disable(void)
2044 {
2045 #if defined(HAL_RADIO_FEM_IS_NRF21540)
2046 	hal_radio_nrf_ppi_channels_disable(BIT(HAL_ENABLE_PALNA_PPI) |
2047 					   BIT(HAL_DISABLE_PALNA_PPI) |
2048 					   BIT(HAL_ENABLE_FEM_PPI) |
2049 					   BIT(HAL_DISABLE_FEM_PPI));
2050 	gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] = 0;
2051 	gpiote_pdn.p_reg->CONFIG[gpiote_ch_pdn] = 0;
2052 #else
2053 	hal_radio_nrf_ppi_channels_disable(BIT(HAL_ENABLE_PALNA_PPI) |
2054 					   BIT(HAL_DISABLE_PALNA_PPI));
2055 	gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] = 0;
2056 #endif
2057 }
2058 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN || HAL_RADIO_GPIO_HAVE_LNA_PIN */
2059 
2060 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
2061 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2062 struct ccm_job_ptr {
2063 	void *ptr;
2064 	struct {
2065 		uint32_t length:24;
2066 		uint32_t attribute:8;
2067 	} __packed;
2068 } __packed;
2069 
2070 #define CCM_JOB_PTR_ATTRIBUTE_ALEN  11U
2071 #define CCM_JOB_PTR_ATTRIBUTE_MLEN  12U
2072 #define CCM_JOB_PTR_ATTRIBUTE_ADATA 13U
2073 #define CCM_JOB_PTR_ATTRIBUTE_MDATA 14U
2074 
2075 static struct {
2076 	uint16_t in_alen;
2077 	uint16_t in_mlen;
2078 	uint8_t  in_mlen_msb;
2079 	uint8_t  out_mlen_msb;
2080 	uint16_t out_alen;
2081 	struct ccm_job_ptr in[6];
2082 	struct ccm_job_ptr out[6];
2083 } ccm_job;
2084 
2085 #else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2086 static uint8_t MALIGN(4) _ccm_scratch[(HAL_RADIO_PDU_LEN_MAX - 4) + 16];
2087 #endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2088 
2089 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_SYNC_ISO)
radio_ccm_ext_rx_pkt_set(struct ccm * cnf,uint8_t phy,uint8_t pdu_type,void * pkt)2090 static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_type, void *pkt)
2091 {
2092 	uint32_t mode;
2093 
2094 	NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
2095 	NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
2096 
2097 	mode = (CCM_MODE_MODE_Decryption << CCM_MODE_MODE_Pos) &
2098 	       CCM_MODE_MODE_Msk;
2099 
2100 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2101 	/* Enable CCM Protocol Mode Bluetooth LE */
2102 	mode |= (CCM_MODE_PROTOCOL_Ble << CCM_MODE_PROTOCOL_Pos) &
2103 		CCM_MODE_PROTOCOL_Msk;
2104 
2105 	/* Enable CCM MAC Length 4 bytes */
2106 	mode |= (CCM_MODE_MACLEN_M4 << CCM_MODE_MACLEN_Pos) &
2107 		CCM_MODE_MACLEN_Msk;
2108 
2109 #elif !defined(CONFIG_SOC_SERIES_NRF51X)
2110 	/* Enable CCM support for 8-bit length field PDUs. */
2111 	mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
2112 		CCM_MODE_LENGTH_Msk;
2113 #endif /* !CONFIG_SOC_SERIES_NRF51X */
2114 
2115 	/* Select CCM data rate based on current PHY in use. */
2116 	switch (phy) {
2117 	default:
2118 	case PHY_1M:
2119 #if !defined(CONFIG_SOC_SERIES_NRF51X)
2120 		mode |= (CCM_MODE_DATARATE_1Mbit <<
2121 			 CCM_MODE_DATARATE_Pos) &
2122 			CCM_MODE_DATARATE_Msk;
2123 #endif /* !CONFIG_SOC_SERIES_NRF51X */
2124 
2125 		if (false) {
2126 
2127 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX)
2128 		} else if (pdu_type == RADIO_PKT_CONF_PDU_TYPE_DC) {
2129 			/* When direction finding CTE receive feature is enabled then on-the-fly
2130 			 * PDU parsing for CTEInfo is always done. In such situation, the CCM
2131 			 * TASKS_CRYPT must be started with short delay. That give the Radio time
2132 			 * to store received bits in shared memory.
2133 			 */
2134 			radio_bc_configure(CCM_TASKS_CRYPT_DELAY_BITS);
2135 			radio_bc_status_reset();
2136 			hal_trigger_crypt_by_bcmatch_ppi_config();
2137 			hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_DELAY_PPI));
2138 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */
2139 		} else {
2140 			hal_trigger_crypt_ppi_config();
2141 			hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI));
2142 		}
2143 		break;
2144 
2145 	case PHY_2M:
2146 #if !defined(CONFIG_SOC_SERIES_NRF51X)
2147 		mode |= (CCM_MODE_DATARATE_2Mbit <<
2148 			 CCM_MODE_DATARATE_Pos) &
2149 			CCM_MODE_DATARATE_Msk;
2150 #endif /* !CONFIG_SOC_SERIES_NRF51X */
2151 
2152 		hal_trigger_crypt_ppi_config();
2153 		hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI));
2154 
2155 		break;
2156 
2157 #if defined(CONFIG_BT_CTLR_PHY_CODED)
2158 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
2159 	case PHY_CODED:
2160 		mode |= (CCM_MODE_DATARATE_125Kbps <<
2161 			 CCM_MODE_DATARATE_Pos) &
2162 			CCM_MODE_DATARATE_Msk;
2163 
2164 		NRF_CCM->RATEOVERRIDE =
2165 			(CCM_RATEOVERRIDE_RATEOVERRIDE_500Kbps <<
2166 			 CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) &
2167 			CCM_RATEOVERRIDE_RATEOVERRIDE_Msk;
2168 
2169 		hal_trigger_rateoverride_ppi_config();
2170 		hal_radio_nrf_ppi_channels_enable(
2171 			BIT(HAL_TRIGGER_RATEOVERRIDE_PPI));
2172 
2173 		hal_trigger_crypt_ppi_config();
2174 		hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI));
2175 
2176 		break;
2177 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
2178 #endif /* CONFIG_BT_CTLR_PHY_CODED */
2179 	}
2180 
2181 	NRF_CCM->MODE = mode;
2182 
2183 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) || \
2184 	defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2185 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
2186 #define ADATAMASK HEADERMASK
2187 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
2188 	switch (pdu_type) {
2189 	case RADIO_PKT_CONF_PDU_TYPE_BIS:
2190 		NRF_CCM->ADATAMASK = 0xC3; /* mask CSSN and CSTF */
2191 		break;
2192 	case RADIO_PKT_CONF_PDU_TYPE_CIS:
2193 		NRF_CCM->ADATAMASK = 0xA3; /* mask SN, NESN, CIE and NPI */
2194 		break;
2195 	default:
2196 		/* Using default reset value of ADATAMASK */
2197 		NRF_CCM->ADATAMASK = 0xE3; /* mask SN, NESN and MD */
2198 		break;
2199 	}
2200 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
2201 #undef ADATAMASK
2202 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
2203 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK ||
2204 	* CONFIG_SOC_COMPATIBLE_NRF54LX
2205 	*/
2206 
2207 #if !defined(CONFIG_SOC_SERIES_NRF51X) && \
2208 	!defined(CONFIG_SOC_NRF52832) && \
2209 	!defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \
2210 	(!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \
2211 	 (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4U)))
2212 	const uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >>
2213 				RADIO_PCNF1_MAXLEN_Pos;
2214 
2215 	/* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */
2216 	NRF_CCM->MAXPACKETSIZE = max_len - 4U;
2217 #endif
2218 
2219 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2220 	/* Configure the CCM key, nonce and pointers */
2221 	NRF_CCM->KEY.VALUE[3] = sys_get_be32(&cnf->key[0]);
2222 	NRF_CCM->KEY.VALUE[2] = sys_get_be32(&cnf->key[4]);
2223 	NRF_CCM->KEY.VALUE[1] = sys_get_be32(&cnf->key[8]);
2224 	NRF_CCM->KEY.VALUE[0] = sys_get_be32(&cnf->key[12]);
2225 
2226 	NRF_CCM->NONCE.VALUE[3] = ((uint8_t *)&cnf->counter)[0];
2227 	NRF_CCM->NONCE.VALUE[2] = sys_get_be32(&((uint8_t *)&cnf->counter)[1]) |
2228 				  (cnf->direction << 7);
2229 	NRF_CCM->NONCE.VALUE[1] = sys_get_be32(&cnf->iv[0]);
2230 	NRF_CCM->NONCE.VALUE[0] = sys_get_be32(&cnf->iv[4]);
2231 
2232 	const uint8_t mlen = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >>
2233 			     RADIO_PCNF1_MAXLEN_Pos;
2234 
2235 	const uint8_t alen = sizeof(uint8_t);
2236 
2237 	ccm_job.in_alen = alen;
2238 	ccm_job.in[0].ptr = &ccm_job.in_alen;
2239 	ccm_job.in[0].length = sizeof(ccm_job.in_alen);
2240 	ccm_job.in[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
2241 
2242 	ccm_job.in[1].ptr = (void *)((uint8_t *)_pkt_scratch + 1U);
2243 	ccm_job.in[1].length = sizeof(uint8_t);
2244 	ccm_job.in[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2245 
2246 	ccm_job.in_mlen_msb = 0U;
2247 	ccm_job.in[2].ptr = &ccm_job.in_mlen_msb;
2248 	ccm_job.in[2].length = sizeof(ccm_job.in_mlen_msb);
2249 	ccm_job.in[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2250 
2251 	ccm_job.in[3].ptr = (void *)((uint8_t *)_pkt_scratch + 0U);
2252 	ccm_job.in[3].length = sizeof(uint8_t);
2253 	ccm_job.in[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
2254 
2255 	ccm_job.in[4].ptr = (void *)((uint8_t *)_pkt_scratch + 3U);
2256 	ccm_job.in[4].length = mlen;
2257 	ccm_job.in[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
2258 
2259 	ccm_job.in[5].ptr = NULL;
2260 	ccm_job.in[5].length = 0U;
2261 	ccm_job.in[5].attribute = 0U;
2262 
2263 	ccm_job.out[0].ptr = &ccm_job.out_alen;
2264 	ccm_job.out[0].length = sizeof(ccm_job.out_alen);
2265 	ccm_job.out[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
2266 
2267 	ccm_job.out[1].ptr = (void *)((uint8_t *)pkt + 1U);
2268 	ccm_job.out[1].length = sizeof(uint8_t);
2269 	ccm_job.out[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2270 
2271 	ccm_job.out[2].ptr = &ccm_job.out_mlen_msb;
2272 	ccm_job.out[2].length = sizeof(ccm_job.out_mlen_msb);
2273 	ccm_job.out[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2274 
2275 	ccm_job.out[3].ptr = (void *)((uint8_t *)pkt + 0U);
2276 	ccm_job.out[3].length = sizeof(uint8_t);
2277 	ccm_job.out[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
2278 
2279 	ccm_job.out[4].ptr = (void *)((uint8_t *)pkt + 3U);
2280 	ccm_job.out[4].length = mlen - sizeof(uint32_t);
2281 	ccm_job.out[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
2282 
2283 	ccm_job.out[5].ptr = NULL;
2284 	ccm_job.out[5].length = 0U;
2285 	ccm_job.out[5].attribute = 0U;
2286 
2287 	NRF_CCM->IN.PTR = (uint32_t)ccm_job.in;
2288 	NRF_CCM->OUT.PTR = (uint32_t)ccm_job.out;
2289 
2290 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
2291 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
2292 
2293 #else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2294 	NRF_CCM->CNFPTR = (uint32_t)cnf;
2295 	NRF_CCM->INPTR = (uint32_t)_pkt_scratch;
2296 	NRF_CCM->OUTPTR = (uint32_t)pkt;
2297 	NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch;
2298 	NRF_CCM->SHORTS = 0;
2299 
2300 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN);
2301 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
2302 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
2303 
2304 	nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN);
2305 #endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2306 
2307 	return _pkt_scratch;
2308 }
2309 
radio_ccm_rx_pkt_set(struct ccm * cnf,uint8_t phy,void * pkt)2310 void *radio_ccm_rx_pkt_set(struct ccm *cnf, uint8_t phy, void *pkt)
2311 {
2312 	return radio_ccm_ext_rx_pkt_set(cnf, phy, RADIO_PKT_CONF_PDU_TYPE_DC, pkt);
2313 }
2314 
radio_ccm_iso_rx_pkt_set(struct ccm * cnf,uint8_t phy,uint8_t pdu_type,void * pkt)2315 void *radio_ccm_iso_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_type, void *pkt)
2316 {
2317 	return radio_ccm_ext_rx_pkt_set(cnf, phy, pdu_type, pkt);
2318 }
2319 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_SYNC_ISO */
2320 
2321 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_ADV_ISO)
radio_ccm_ext_tx_pkt_set(struct ccm * cnf,uint8_t pdu_type,void * pkt)2322 static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *pkt)
2323 {
2324 	uint32_t mode;
2325 
2326 	NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
2327 	NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
2328 
2329 	mode = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) &
2330 	       CCM_MODE_MODE_Msk;
2331 
2332 #if defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
2333 	defined(CONFIG_SOC_COMPATIBLE_NRF53X)
2334 	/* Enable CCM support for 8-bit length field PDUs. */
2335 	mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
2336 		CCM_MODE_LENGTH_Msk;
2337 
2338 	/* NOTE: use fastest data rate as tx data needs to be prepared before
2339 	 * radio Tx on any PHY.
2340 	 */
2341 	mode |= (CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos) &
2342 		CCM_MODE_DATARATE_Msk;
2343 
2344 #elif defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2345 	/* Enable CCM Protocol Mode Bluetooth LE */
2346 	mode |= (CCM_MODE_PROTOCOL_Ble << CCM_MODE_PROTOCOL_Pos) &
2347 		CCM_MODE_PROTOCOL_Msk;
2348 
2349 	/* NOTE: use fastest data rate as tx data needs to be prepared before
2350 	 * radio Tx on any PHY.
2351 	 */
2352 	mode |= (CCM_MODE_DATARATE_4Mbit << CCM_MODE_DATARATE_Pos) &
2353 		CCM_MODE_DATARATE_Msk;
2354 
2355 	/* Enable CCM MAC Length 4 bytes */
2356 	mode |= (CCM_MODE_MACLEN_M4 << CCM_MODE_MACLEN_Pos) &
2357 		CCM_MODE_MACLEN_Msk;
2358 #endif
2359 
2360 	NRF_CCM->MODE = mode;
2361 
2362 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) || \
2363 	defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2364 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
2365 #define ADATAMASK HEADERMASK
2366 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
2367 	switch (pdu_type) {
2368 	case RADIO_PKT_CONF_PDU_TYPE_BIS:
2369 		NRF_CCM->ADATAMASK = 0xC3; /* mask CSSN and CSTF */
2370 		break;
2371 	case RADIO_PKT_CONF_PDU_TYPE_CIS:
2372 		NRF_CCM->ADATAMASK = 0xA3; /* mask SN, NESN, CIE and NPI */
2373 		break;
2374 	default:
2375 		/* Using default reset value of ADATAMASK */
2376 		NRF_CCM->ADATAMASK = 0xE3; /* mask SN, NESN and MD */
2377 		break;
2378 	}
2379 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
2380 #undef ADATAMASK
2381 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
2382 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK ||
2383 	* CONFIG_SOC_COMPATIBLE_NRF54LX
2384 	*/
2385 
2386 #if !defined(CONFIG_SOC_SERIES_NRF51X) && \
2387 	!defined(CONFIG_SOC_NRF52832) && \
2388 	!defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \
2389 	(!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \
2390 	 (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4U)))
2391 	const uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >>
2392 				RADIO_PCNF1_MAXLEN_Pos;
2393 
2394 	/* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */
2395 	NRF_CCM->MAXPACKETSIZE = max_len - 4U;
2396 #endif
2397 
2398 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2399 	/* Configure the CCM key, nonce and pointers */
2400 	NRF_CCM->KEY.VALUE[3] = sys_get_be32(&cnf->key[0]);
2401 	NRF_CCM->KEY.VALUE[2] = sys_get_be32(&cnf->key[4]);
2402 	NRF_CCM->KEY.VALUE[1] = sys_get_be32(&cnf->key[8]);
2403 	NRF_CCM->KEY.VALUE[0] = sys_get_be32(&cnf->key[12]);
2404 
2405 	NRF_CCM->NONCE.VALUE[3] = ((uint8_t *)&cnf->counter)[0];
2406 	NRF_CCM->NONCE.VALUE[2] = sys_get_be32(&((uint8_t *)&cnf->counter)[1]) |
2407 				  (cnf->direction << 7);
2408 	NRF_CCM->NONCE.VALUE[1] = sys_get_be32(&cnf->iv[0]);
2409 	NRF_CCM->NONCE.VALUE[0] = sys_get_be32(&cnf->iv[4]);
2410 
2411 	const uint8_t alen = sizeof(uint8_t);
2412 
2413 	ccm_job.in_alen = alen;
2414 	ccm_job.in[0].ptr = &ccm_job.in_alen;
2415 	ccm_job.in[0].length = sizeof(ccm_job.in_alen);
2416 	ccm_job.in[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
2417 
2418 	const uint8_t mlen = *((uint8_t *)pkt + 1U);
2419 
2420 	ccm_job.in_mlen = mlen;
2421 	ccm_job.in[1].ptr = &ccm_job.in_mlen;
2422 	ccm_job.in[1].length = sizeof(ccm_job.in_mlen);
2423 	ccm_job.in[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2424 
2425 	ccm_job.in[2].ptr = (void *)((uint8_t *)pkt + 0U);
2426 	ccm_job.in[2].length = alen;
2427 	ccm_job.in[2].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
2428 
2429 	ccm_job.in[3].ptr = (void *)((uint8_t *)pkt + 3U);
2430 	ccm_job.in[3].length = mlen;
2431 	ccm_job.in[3].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
2432 
2433 	ccm_job.in[4].ptr = NULL;
2434 	ccm_job.in[4].length = 0U;
2435 	ccm_job.in[4].attribute = 0U;
2436 
2437 	ccm_job.out[0].ptr = &ccm_job.out_alen;
2438 	ccm_job.out[0].length = sizeof(ccm_job.out_alen);
2439 	ccm_job.out[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
2440 
2441 	ccm_job.out[1].ptr = (void *)((uint8_t *)_pkt_scratch + 1U);
2442 	ccm_job.out[1].length = sizeof(uint8_t);
2443 	ccm_job.out[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2444 
2445 	ccm_job.out[2].ptr = &ccm_job.out_mlen_msb;
2446 	ccm_job.out[2].length = sizeof(ccm_job.out_mlen_msb);
2447 	ccm_job.out[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2448 
2449 	ccm_job.out[3].ptr = (void *)((uint8_t *)_pkt_scratch + 0U);
2450 	ccm_job.out[3].length = sizeof(uint8_t);
2451 	ccm_job.out[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
2452 
2453 	ccm_job.out[4].ptr = (void *)((uint8_t *)_pkt_scratch + 3U);
2454 	ccm_job.out[4].length = mlen + sizeof(uint32_t);
2455 	ccm_job.out[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
2456 
2457 	ccm_job.out[5].ptr = NULL;
2458 	ccm_job.out[5].length = 0U;
2459 	ccm_job.out[5].attribute = 0U;
2460 
2461 	NRF_CCM->IN.PTR = (uint32_t)ccm_job.in;
2462 	NRF_CCM->OUT.PTR = (uint32_t)ccm_job.out;
2463 
2464 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
2465 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
2466 
2467 	nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_START);
2468 
2469 #else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2470 	NRF_CCM->CNFPTR = (uint32_t)cnf;
2471 	NRF_CCM->INPTR = (uint32_t)pkt;
2472 	NRF_CCM->OUTPTR = (uint32_t)_pkt_scratch;
2473 	NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch;
2474 	NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk;
2475 
2476 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN);
2477 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
2478 	nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
2479 
2480 	nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN);
2481 #endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2482 
2483 	return _pkt_scratch;
2484 }
2485 
radio_ccm_tx_pkt_set(struct ccm * cnf,void * pkt)2486 void *radio_ccm_tx_pkt_set(struct ccm *cnf, void *pkt)
2487 {
2488 	return radio_ccm_ext_tx_pkt_set(cnf, RADIO_PKT_CONF_PDU_TYPE_DC, pkt);
2489 }
2490 
radio_ccm_iso_tx_pkt_set(struct ccm * cnf,uint8_t pdu_type,void * pkt)2491 void *radio_ccm_iso_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *pkt)
2492 {
2493 	return radio_ccm_ext_tx_pkt_set(cnf, pdu_type, pkt);
2494 }
2495 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_ADV_ISO */
2496 
radio_ccm_is_done(void)2497 uint32_t radio_ccm_is_done(void)
2498 {
2499 	nrf_ccm_int_enable(NRF_CCM, CCM_INTENSET_ENDCRYPT_Msk);
2500 	while (NRF_CCM->EVENTS_ENDCRYPT == 0) {
2501 		cpu_sleep();
2502 	}
2503 	nrf_ccm_int_disable(NRF_CCM, CCM_INTENCLR_ENDCRYPT_Msk);
2504 	NVIC_ClearPendingIRQ(nrfx_get_irq_number(NRF_CCM));
2505 
2506 	return (NRF_CCM->EVENTS_ERROR == 0);
2507 }
2508 
radio_ccm_mic_is_valid(void)2509 uint32_t radio_ccm_mic_is_valid(void)
2510 {
2511 	return (NRF_CCM->MICSTATUS != 0);
2512 }
2513 
2514 #if defined(CONFIG_BT_CTLR_PRIVACY)
2515 static uint8_t MALIGN(4) _aar_scratch[3];
2516 
radio_ar_configure(uint32_t nirk,void * irk,uint8_t flags)2517 void radio_ar_configure(uint32_t nirk, void *irk, uint8_t flags)
2518 {
2519 	uint32_t addrptr;
2520 	uint8_t bcc;
2521 	uint8_t phy;
2522 
2523 	/* Flags provide hint on how to setup AAR:
2524 	 * ....Xb - legacy PDU
2525 	 * ...X.b - extended PDU
2526 	 * XXX..b = RX PHY
2527 	 * 00000b = default case mapped to 00101b (legacy, 1M)
2528 	 *
2529 	 * If neither legacy not extended bit is set, legacy PDU is selected for
2530 	 * 1M PHY and extended PDU otherwise.
2531 	 */
2532 
2533 	phy = flags >> 2;
2534 
2535 	/* Check if extended PDU or non-1M and not legacy PDU */
2536 	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) &&
2537 	    ((flags & BIT(1)) || (!(flags & BIT(0)) && (phy > PHY_1M)))) {
2538 		addrptr = NRF_RADIO->PACKETPTR + 1;
2539 		bcc = 80;
2540 	} else {
2541 		addrptr = NRF_RADIO->PACKETPTR - 1;
2542 		bcc = 64;
2543 	}
2544 
2545 	/* For Coded PHY adjust for CI and TERM1 */
2546 	if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) && (phy == PHY_CODED)) {
2547 		bcc += 5;
2548 	}
2549 
2550 	NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Enabled << AAR_ENABLE_ENABLE_Pos) &
2551 			  AAR_ENABLE_ENABLE_Msk;
2552 	NRF_AAR->NIRK = nirk;
2553 	NRF_AAR->IRKPTR = (uint32_t)irk;
2554 	NRF_AAR->ADDRPTR = addrptr;
2555 	NRF_AAR->SCRATCHPTR = (uint32_t)&_aar_scratch[0];
2556 
2557 	nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_END);
2558 	nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_RESOLVED);
2559 	nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_NOTRESOLVED);
2560 
2561 	radio_bc_configure(bcc);
2562 	radio_bc_status_reset();
2563 
2564 	hal_trigger_aar_ppi_config();
2565 	hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_AAR_PPI));
2566 }
2567 
radio_ar_match_get(void)2568 uint32_t radio_ar_match_get(void)
2569 {
2570 	return NRF_AAR->STATUS;
2571 }
2572 
radio_ar_status_reset(void)2573 void radio_ar_status_reset(void)
2574 {
2575 	radio_bc_status_reset();
2576 
2577 	NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Disabled << AAR_ENABLE_ENABLE_Pos) &
2578 			  AAR_ENABLE_ENABLE_Msk;
2579 
2580 	hal_radio_nrf_ppi_channels_disable(BIT(HAL_TRIGGER_AAR_PPI));
2581 }
2582 
radio_ar_has_match(void)2583 uint32_t radio_ar_has_match(void)
2584 {
2585 	if (!radio_bc_has_match()) {
2586 		return 0U;
2587 	}
2588 
2589 	nrf_aar_int_enable(NRF_AAR, AAR_INTENSET_END_Msk);
2590 
2591 	while (NRF_AAR->EVENTS_END == 0U) {
2592 		cpu_sleep();
2593 	}
2594 
2595 	nrf_aar_int_disable(NRF_AAR, AAR_INTENCLR_END_Msk);
2596 
2597 	NVIC_ClearPendingIRQ(nrfx_get_irq_number(NRF_AAR));
2598 
2599 	if (NRF_AAR->EVENTS_RESOLVED && !NRF_AAR->EVENTS_NOTRESOLVED) {
2600 		return 1U;
2601 	}
2602 
2603 	return 0U;
2604 }
2605 
radio_ar_resolve(const uint8_t * addr)2606 uint8_t radio_ar_resolve(const uint8_t *addr)
2607 {
2608 	uint8_t retval;
2609 
2610 	NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Enabled << AAR_ENABLE_ENABLE_Pos) &
2611 			  AAR_ENABLE_ENABLE_Msk;
2612 
2613 	NRF_AAR->ADDRPTR = (uint32_t)addr - 3;
2614 
2615 	nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_END);
2616 	nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_RESOLVED);
2617 	nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_NOTRESOLVED);
2618 
2619 	NVIC_ClearPendingIRQ(nrfx_get_irq_number(NRF_AAR));
2620 
2621 	nrf_aar_int_enable(NRF_AAR, AAR_INTENSET_END_Msk);
2622 
2623 	nrf_aar_task_trigger(NRF_AAR, NRF_AAR_TASK_START);
2624 
2625 	while (NRF_AAR->EVENTS_END == 0) {
2626 		cpu_sleep();
2627 	}
2628 
2629 	nrf_aar_int_disable(NRF_AAR, AAR_INTENCLR_END_Msk);
2630 
2631 	NVIC_ClearPendingIRQ(nrfx_get_irq_number(NRF_AAR));
2632 
2633 	retval = (NRF_AAR->EVENTS_RESOLVED && !NRF_AAR->EVENTS_NOTRESOLVED) ?
2634 		 1U : 0U;
2635 
2636 	NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Disabled << AAR_ENABLE_ENABLE_Pos) &
2637 			  AAR_ENABLE_ENABLE_Msk;
2638 
2639 	return retval;
2640 
2641 }
2642 #endif /* CONFIG_BT_CTLR_PRIVACY */
2643 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
2644 
2645 #if defined(CONFIG_BT_CTLR_DF_SUPPORT) && !defined(CONFIG_ZTEST)
2646 /* @brief Function configures CTE inline register to start sampling of CTE
2647  *        according to information parsed from CTEInfo field of received PDU.
2648  *
2649  * @param[in] cte_info_in_s1    Informs where to expect CTEInfo field in PDU:
2650  *                              in S1 for data pdu, not in S1 for adv. PDU
2651  */
radio_df_cte_inline_set_enabled(bool cte_info_in_s1)2652 void radio_df_cte_inline_set_enabled(bool cte_info_in_s1)
2653 {
2654 	const nrf_radio_cteinline_conf_t inline_conf = {
2655 		.enable = true,
2656 		/* Indicates whether CTEInfo is in S1 byte or not. */
2657 		.info_in_s1 = cte_info_in_s1,
2658 		/* Enable or disable switching and sampling when CRC is not OK. */
2659 #if defined(CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC)
2660 		.err_handling = true,
2661 #else
2662 		.err_handling = false,
2663 #endif /* CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC */
2664 		/* Maximum range of CTE time. 20 * 8us according to BT spec.*/
2665 		.time_range = NRF_RADIO_CTEINLINE_TIME_RANGE_20,
2666 		/* Spacing between samples for 1us AoD or AoA is set to 2us. */
2667 		.rx1us = NRF_RADIO_CTEINLINE_RX_MODE_2US,
2668 		/* Spacing between samples for 2us AoD or AoA is set to 4us. */
2669 		.rx2us = NRF_RADIO_CTEINLINE_RX_MODE_4US,
2670 		/* S0 bit pattern to match all types of adv. PDUs or CP bit in conn PDU*/
2671 		.s0_pattern = (cte_info_in_s1 ? DF_S0_MASK_CP_BIT_IN_DATA_CHANNEL_PDU :
2672 							DF_S0_ALLOW_ALL_PER_ADV_PDU),
2673 		/* S0 bit mask set to don't match any bit in SO octet or match CP bit in conn PDU */
2674 		.s0_mask = (cte_info_in_s1 ? DF_S0_MASK_CP_BIT_IN_DATA_CHANNEL_PDU :
2675 							DF_S0_ALLOW_ALL_PER_ADV_PDU)
2676 	};
2677 
2678 	nrf_radio_cteinline_configure(NRF_RADIO, &inline_conf);
2679 }
2680 #endif /* CONFIG_BT_CTLR_DF_SUPPORT && !CONFIG_ZTEST */
2681