1 /*
2  * Copyright (c) 2020 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
8 
9 #include <zephyr/sys/byteorder.h>
10 #include <zephyr/sys/util.h>
11 
12 #include <zephyr/bluetooth/hci_types.h>
13 
14 #include "hal/ccm.h"
15 #include "hal/radio.h"
16 #include "hal/ticker.h"
17 #include "hal/radio_df.h"
18 
19 #include "util/util.h"
20 #include "util/memq.h"
21 #include "util/dbuf.h"
22 #include "util/mayfly.h"
23 
24 #include "pdu_df.h"
25 #include "pdu_vendor.h"
26 #include "pdu.h"
27 
28 #include "lll.h"
29 #include "lll_vendor.h"
30 #include "lll_clock.h"
31 #include "lll_filter.h"
32 #include "lll_scan.h"
33 #include "lll_scan_aux.h"
34 #include "lll_df_types.h"
35 #include "lll_df_internal.h"
36 #include "lll_sync.h"
37 #include "lll_sync_iso.h"
38 #include "lll_conn.h"
39 #include "lll_sched.h"
40 
41 #include "lll_internal.h"
42 #include "lll_tim_internal.h"
43 #include "lll_prof_internal.h"
44 #include "lll_scan_internal.h"
45 #include "lll_sync_internal.h"
46 
47 #include "ll_feat.h"
48 
49 #include <soc.h>
50 #include <ull_scan_types.h>
51 #include "hal/debug.h"
52 
53 static int init_reset(void);
54 static int prepare_cb(struct lll_prepare_param *p);
55 static int is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb);
56 static void abort_cb(struct lll_prepare_param *prepare_param, void *param);
57 static void isr_done(void *param);
58 static void isr_rx_ull_schedule(void *param);
59 static void isr_rx_lll_schedule(void *param);
60 static void isr_rx(struct lll_scan *lll, struct lll_scan_aux *lll_aux,
61 		   uint8_t phy_aux);
62 static int isr_rx_pdu(struct lll_scan *lll, struct lll_scan_aux *lll_aux,
63 		      struct node_rx_pdu *node_rx, struct pdu_adv *pdu,
64 		      uint8_t phy_aux, uint8_t phy_aux_flags_rx,
65 		      uint8_t devmatch_ok, uint8_t devmatch_id,
66 		      uint8_t irkmatch_ok, uint8_t irkmatch_id, uint8_t rl_idx,
67 		      uint8_t rssi_ready);
68 static void isr_tx_scan_req_ull_schedule(void *param);
69 static void isr_tx_scan_req_lll_schedule(void *param);
70 #if defined(CONFIG_BT_CENTRAL)
71 static void isr_tx_connect_req(void *param);
72 static void isr_rx_connect_rsp(void *param);
73 static bool isr_rx_connect_rsp_check(struct lll_scan *lll,
74 				     struct pdu_adv *pdu_tx,
75 				     struct pdu_adv *pdu_rx, uint8_t rl_idx);
76 static void isr_early_abort(void *param);
77 #endif /* CONFIG_BT_CENTRAL */
78 
79 static uint16_t trx_cnt; /* TODO: move to a union in lll.c, common to all roles
80 			  */
81 
lll_scan_aux_init(void)82 int lll_scan_aux_init(void)
83 {
84 	int err;
85 
86 	err = init_reset();
87 	if (err) {
88 		return err;
89 	}
90 
91 	return 0;
92 }
93 
lll_scan_aux_reset(void)94 int lll_scan_aux_reset(void)
95 {
96 	int err;
97 
98 	err = init_reset();
99 	if (err) {
100 		return err;
101 	}
102 
103 	return 0;
104 }
105 
lll_scan_aux_prepare(void * param)106 void lll_scan_aux_prepare(void *param)
107 {
108 	int err;
109 
110 	err = lll_hfclock_on();
111 	LL_ASSERT(err >= 0);
112 
113 	err = lll_prepare(is_abort_cb, abort_cb, prepare_cb, 0, param);
114 	LL_ASSERT(!err || err == -EINPROGRESS);
115 }
116 
lll_scan_aux_setup(struct pdu_adv * pdu,uint8_t pdu_phy,uint8_t pdu_phy_flags_rx,radio_isr_cb_t setup_cb,void * param)117 uint8_t lll_scan_aux_setup(struct pdu_adv *pdu, uint8_t pdu_phy,
118 			   uint8_t pdu_phy_flags_rx, radio_isr_cb_t setup_cb,
119 			   void *param)
120 {
121 	struct pdu_adv_com_ext_adv *pri_com_hdr;
122 	struct pdu_adv_ext_hdr *pri_hdr;
123 	struct pdu_adv_aux_ptr *aux_ptr;
124 	struct pdu_cte_info *cte_info;
125 	struct node_rx_pdu *node_rx;
126 	uint32_t window_widening_us;
127 	uint32_t window_size_us;
128 	struct node_rx_ftr *ftr;
129 	uint32_t aux_offset_us;
130 	uint32_t overhead_us;
131 	uint8_t *pri_dptr;
132 	uint8_t phy;
133 
134 	LL_ASSERT(pdu->type == PDU_ADV_TYPE_EXT_IND);
135 
136 	/* Get reference to extended header */
137 	pri_com_hdr = (void *)&pdu->adv_ext_ind;
138 	if (!pdu->len || !pri_com_hdr->ext_hdr_len) {
139 		return 0U;
140 	}
141 
142 	/* Get reference to flags and contents */
143 	pri_hdr = (void *)pri_com_hdr->ext_hdr_adv_data;
144 	pri_dptr = pri_hdr->data;
145 
146 	/* traverse through adv_addr, if present */
147 	if (pri_hdr->adv_addr) {
148 		pri_dptr += BDADDR_SIZE;
149 	}
150 
151 	/* traverse through tgt_addr, if present */
152 	if (pri_hdr->tgt_addr) {
153 		pri_dptr += BDADDR_SIZE;
154 	}
155 
156 	/* traverse through cte_info, if present */
157 	if (pri_hdr->cte_info) {
158 		cte_info = (void *)pri_dptr;
159 		pri_dptr += sizeof(struct pdu_cte_info);
160 	} else {
161 		cte_info = NULL;
162 	}
163 
164 	/* traverse through adi, if present */
165 	if (pri_hdr->adi) {
166 		pri_dptr += sizeof(struct pdu_adv_adi);
167 	}
168 
169 	/* No need to scan further if no aux_ptr filled */
170 	aux_ptr = (void *)pri_dptr;
171 	if (unlikely(!pri_hdr->aux_ptr || !PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr) ||
172 		     (PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) > EXT_ADV_AUX_PHY_LE_CODED))) {
173 		return 0;
174 	}
175 
176 	/* Determine the window size */
177 	if (aux_ptr->offs_units) {
178 		window_size_us = OFFS_UNIT_300_US;
179 	} else {
180 		window_size_us = OFFS_UNIT_30_US;
181 	}
182 
183 	/* Calculate the aux offset from start of the scan window */
184 	aux_offset_us = (uint32_t)PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr) * window_size_us;
185 
186 	/* Calculate the window widening that needs to be deducted */
187 	if (aux_ptr->ca) {
188 		window_widening_us = SCA_DRIFT_50_PPM_US(aux_offset_us);
189 	} else {
190 		window_widening_us = SCA_DRIFT_500_PPM_US(aux_offset_us);
191 	}
192 
193 	phy = BIT(PDU_ADV_AUX_PTR_PHY_GET(aux_ptr));
194 
195 	/* Calculate the minimum overhead to decide if LLL or ULL scheduling
196 	 * to be used for auxiliary PDU reception.
197 	 */
198 	overhead_us = PDU_AC_US(pdu->len, pdu_phy, pdu_phy_flags_rx);
199 #if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
200 	/* Add CTE time if samples are available (8us unit) */
201 	/* TODO: check if CTE was actually enabled for rx */
202 	if (cte_info && radio_df_iq_samples_amount_get()) {
203 		overhead_us += cte_info->time << 3;
204 	}
205 #endif
206 	overhead_us += radio_rx_chain_delay_get(pdu_phy, pdu_phy_flags_rx);
207 	overhead_us += lll_radio_rx_ready_delay_get(phy, PHY_FLAGS_S8);
208 	overhead_us += window_widening_us;
209 	overhead_us += EVENT_TICKER_RES_MARGIN_US;
210 	overhead_us += EVENT_JITTER_US;
211 
212 	/* Minimum prepare tick offset + minimum preempt tick offset are the
213 	 * overheads before ULL scheduling can setup radio for reception
214 	 */
215 	overhead_us +=
216 		HAL_TICKER_TICKS_TO_US(HAL_TICKER_CNTR_CMP_OFFSET_MIN << 1);
217 
218 	/* CPU execution overhead to setup the radio for reception */
219 	overhead_us += EVENT_OVERHEAD_END_US + EVENT_OVERHEAD_START_US;
220 
221 	/* Sufficient offset to ULL schedule the auxiliary PDU scan? */
222 	if (aux_offset_us > overhead_us) {
223 		return 0;
224 	}
225 
226 	node_rx = ull_pdu_rx_alloc_peek(1);
227 	LL_ASSERT(node_rx);
228 
229 	/* Store the lll context, aux_ptr and start of PDU in footer */
230 	ftr = &(node_rx->rx_ftr);
231 	ftr->param = param;
232 	ftr->aux_ptr = aux_ptr;
233 	ftr->radio_end_us = radio_tmr_end_get() -
234 			    radio_rx_chain_delay_get(pdu_phy,
235 						     pdu_phy_flags_rx) -
236 			    PDU_AC_US(pdu->len, pdu_phy, pdu_phy_flags_rx);
237 
238 	radio_isr_set(setup_cb, node_rx);
239 	radio_disable();
240 
241 	return 1;
242 }
243 
lll_scan_aux_isr_aux_setup(void * param)244 void lll_scan_aux_isr_aux_setup(void *param)
245 {
246 	struct pdu_adv_aux_ptr *aux_ptr;
247 	struct node_rx_pdu *node_rx;
248 	uint32_t window_widening_us;
249 	uint32_t window_size_us;
250 	struct node_rx_ftr *ftr;
251 	uint32_t aux_offset_us;
252 	uint32_t aux_start_us;
253 	struct lll_scan *lll;
254 	uint32_t start_us;
255 	uint8_t phy_aux;
256 	uint32_t hcto;
257 
258 	lll_isr_status_reset();
259 
260 	node_rx = param;
261 	ftr = &node_rx->rx_ftr;
262 	aux_ptr = ftr->aux_ptr;
263 	phy_aux = BIT(PDU_ADV_AUX_PTR_PHY_GET(aux_ptr));
264 	ftr->aux_phy = phy_aux;
265 
266 	lll = ftr->param;
267 
268 	/* Determine the window size */
269 	if (aux_ptr->offs_units) {
270 		window_size_us = OFFS_UNIT_300_US;
271 	} else {
272 		window_size_us = OFFS_UNIT_30_US;
273 	}
274 
275 	/* Calculate the aux offset from start of the scan window */
276 	aux_offset_us = (uint32_t)PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr) * window_size_us;
277 
278 	/* Calculate the window widening that needs to be deducted */
279 	if (aux_ptr->ca) {
280 		window_widening_us = SCA_DRIFT_50_PPM_US(aux_offset_us);
281 	} else {
282 		window_widening_us = SCA_DRIFT_500_PPM_US(aux_offset_us);
283 	}
284 
285 	/* Reset Tx/rx count */
286 	trx_cnt = 0U;
287 
288 	/* Setup radio for auxiliary PDU scan */
289 	radio_phy_set(phy_aux, PHY_FLAGS_S8);
290 	radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, LL_EXT_OCTETS_RX_MAX,
291 			    RADIO_PKT_CONF_PHY(phy_aux));
292 	lll_chan_set(aux_ptr->chan_idx);
293 
294 	radio_pkt_rx_set(node_rx->pdu);
295 
296 	/* FIXME: we could (?) use isr_rx_ull_schedule if already have aux
297 	 *        context allocated, i.e. some previous aux was scheduled from
298 	 *        ull already.
299 	 */
300 	radio_isr_set(isr_rx_lll_schedule, node_rx);
301 
302 	/* setup tIFS switching */
303 	radio_tmr_tifs_set(EVENT_IFS_US);
304 	/* TODO: for passive scanning use complete_and_disable */
305 	radio_switch_complete_and_tx(phy_aux, 0, phy_aux, 1);
306 
307 	/* TODO: skip filtering if AdvA was already found in previous PDU */
308 
309 	if (0) {
310 #if defined(CONFIG_BT_CTLR_PRIVACY)
311 	} else if (ull_filter_lll_rl_enabled()) {
312 		const struct lll_filter *fal =
313 			ull_filter_lll_get((lll->filter_policy &
314 					    SCAN_FP_FILTER) != 0U);
315 		uint8_t count, *irks = ull_filter_lll_irks_get(&count);
316 
317 		radio_filter_configure(fal->enable_bitmask,
318 				       fal->addr_type_bitmask,
319 				       (uint8_t *)fal->bdaddr);
320 
321 		radio_ar_configure(count, irks, (phy_aux << 2) | BIT(1));
322 #endif /* CONFIG_BT_CTLR_PRIVACY */
323 	} else if (IS_ENABLED(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST) && lll->filter_policy) {
324 		/* Setup Radio Filter */
325 		const struct lll_filter *fal = ull_filter_lll_get(true);
326 
327 		radio_filter_configure(fal->enable_bitmask,
328 				       fal->addr_type_bitmask,
329 				       (uint8_t *)fal->bdaddr);
330 	}
331 
332 	/* Setup radio rx on micro second offset. Note that radio_end_us stores
333 	 * PDU start time in this case.
334 	 */
335 	aux_start_us = ftr->radio_end_us + aux_offset_us;
336 	aux_start_us -= lll_radio_rx_ready_delay_get(phy_aux, PHY_FLAGS_S8);
337 	aux_start_us -= window_widening_us;
338 	aux_start_us -= EVENT_JITTER_US;
339 
340 	start_us = radio_tmr_start_us(0, aux_start_us);
341 
342 	/* Setup header complete timeout */
343 	hcto = start_us;
344 	hcto += EVENT_JITTER_US;
345 	hcto += window_widening_us;
346 	hcto += lll_radio_rx_ready_delay_get(phy_aux, PHY_FLAGS_S8);
347 	hcto += window_size_us;
348 	hcto += radio_rx_chain_delay_get(phy_aux, PHY_FLAGS_S8);
349 	hcto += addr_us_get(phy_aux);
350 	radio_tmr_hcto_configure(hcto);
351 
352 	/* capture end of Rx-ed PDU, extended scan to schedule auxiliary
353 	 * channel chaining, create connection or to create periodic sync.
354 	 */
355 	radio_tmr_end_capture();
356 
357 	/* scanner always measures RSSI */
358 	radio_rssi_measure();
359 
360 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
361 	radio_gpio_lna_setup();
362 
363 	radio_gpio_pa_lna_enable(start_us +
364 				 radio_rx_ready_delay_get(phy_aux,
365 							  PHY_FLAGS_S8) -
366 				 HAL_RADIO_GPIO_LNA_OFFSET);
367 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
368 }
369 
lll_scan_aux_addr_match_get(const struct lll_scan * lll,const struct pdu_adv * pdu,uint8_t * const devmatch_ok,uint8_t * const devmatch_id,uint8_t * const irkmatch_ok,uint8_t * const irkmatch_id)370 bool lll_scan_aux_addr_match_get(const struct lll_scan *lll,
371 				 const struct pdu_adv *pdu,
372 				 uint8_t *const devmatch_ok,
373 				 uint8_t *const devmatch_id,
374 				 uint8_t *const irkmatch_ok,
375 				 uint8_t *const irkmatch_id)
376 {
377 	const struct pdu_adv_ext_hdr *ext_hdr;
378 
379 	ext_hdr = &pdu->adv_ext_ind.ext_hdr;
380 	if (!ext_hdr->adv_addr) {
381 		return false;
382 	}
383 
384 	if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY) && ull_filter_lll_rl_enabled()) {
385 		const struct lll_filter *fal =
386 			ull_filter_lll_get((lll->filter_policy &
387 					    SCAN_FP_FILTER) != 0);
388 		const uint8_t *adva = &ext_hdr->data[ADVA_OFFSET];
389 
390 		*devmatch_ok = ull_filter_lll_fal_match(fal, pdu->tx_addr, adva,
391 							devmatch_id);
392 		if (!*devmatch_ok && pdu->tx_addr) {
393 			uint8_t count;
394 
395 			(void)ull_filter_lll_irks_get(&count);
396 			if (count) {
397 				*irkmatch_ok = radio_ar_resolve(adva);
398 				*irkmatch_id = radio_ar_match_get();
399 			}
400 		}
401 	} else if (IS_ENABLED(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST) &&
402 		   lll->filter_policy) {
403 		const struct lll_filter *fal = ull_filter_lll_get(true);
404 		const uint8_t *adva = &ext_hdr->data[ADVA_OFFSET];
405 
406 		*devmatch_ok = ull_filter_lll_fal_match(fal, pdu->tx_addr, adva,
407 							devmatch_id);
408 	}
409 
410 	return true;
411 }
412 
init_reset(void)413 static int init_reset(void)
414 {
415 	return 0;
416 }
417 
prepare_cb(struct lll_prepare_param * p)418 static int prepare_cb(struct lll_prepare_param *p)
419 {
420 	struct lll_scan_aux *lll_aux;
421 	struct node_rx_pdu *node_rx;
422 	uint32_t ticks_at_event;
423 	uint32_t ticks_at_start;
424 	uint32_t remainder_us;
425 	struct lll_scan *lll;
426 	struct ull_hdr *ull;
427 	uint8_t is_lll_scan;
428 	uint32_t remainder;
429 	uint32_t hcto;
430 	uint32_t ret;
431 	uint32_t aa;
432 
433 	DEBUG_RADIO_START_O(1);
434 
435 	lll_aux = p->param;
436 	lll = ull_scan_aux_lll_parent_get(lll_aux, &is_lll_scan);
437 
438 	/* Check if this aux scan is for periodic advertising train */
439 	if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && !is_lll_scan) {
440 		lll_sync_aux_prepare_cb((void *)lll, lll_aux);
441 
442 		lll = NULL;
443 
444 		goto sync_aux_prepare_done;
445 	}
446 
447 #if defined(CONFIG_BT_CENTRAL)
448 	/* Check if stopped (on connection establishment race between
449 	 * LL and ULL.
450 	 */
451 	if (unlikely(lll->is_stop ||
452 		     (lll->conn &&
453 		      (lll->conn->central.initiated ||
454 		       lll->conn->central.cancelled)))) {
455 		radio_isr_set(isr_early_abort, lll_aux);
456 		radio_disable();
457 
458 		return 0;
459 	}
460 #endif /* CONFIG_BT_CENTRAL */
461 
462 	/* Initialize scanning state */
463 	lll_aux->state = 0U;
464 
465 	/* Reset Tx/rx count */
466 	trx_cnt = 0U;
467 
468 	/* Start setting up Radio h/w */
469 	radio_reset();
470 
471 #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
472 	radio_tx_power_set(lll->tx_pwr_lvl);
473 #else
474 	radio_tx_power_set(RADIO_TXP_DEFAULT);
475 #endif
476 
477 	radio_phy_set(lll_aux->phy, PHY_FLAGS_S8);
478 	radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, LL_EXT_OCTETS_RX_MAX,
479 			    RADIO_PKT_CONF_PHY(lll_aux->phy));
480 
481 	node_rx = ull_pdu_rx_alloc_peek(1);
482 	LL_ASSERT(node_rx);
483 
484 	radio_pkt_rx_set(node_rx->pdu);
485 
486 	aa = sys_cpu_to_le32(PDU_AC_ACCESS_ADDR);
487 	radio_aa_set((uint8_t *)&aa);
488 	radio_crc_configure(PDU_CRC_POLYNOMIAL,
489 				PDU_AC_CRC_IV);
490 
491 	lll_chan_set(lll_aux->chan);
492 
493 	radio_isr_set(isr_rx_ull_schedule, lll_aux);
494 
495 	/* setup tIFS switching */
496 	radio_tmr_tifs_set(EVENT_IFS_US);
497 	/* TODO: for passive scanning use complete_and_disable */
498 	radio_switch_complete_and_tx(lll_aux->phy, 0, lll_aux->phy, 1);
499 
500 	/* TODO: skip filtering if AdvA was already found in previous PDU */
501 
502 	if (0) {
503 #if defined(CONFIG_BT_CTLR_PRIVACY)
504 	} else if (ull_filter_lll_rl_enabled()) {
505 		struct lll_filter *filter =
506 			ull_filter_lll_get((lll->filter_policy &
507 					    SCAN_FP_FILTER) != 0);
508 		uint8_t count, *irks = ull_filter_lll_irks_get(&count);
509 
510 		radio_filter_configure(filter->enable_bitmask,
511 				       filter->addr_type_bitmask,
512 				       (uint8_t *) filter->bdaddr);
513 
514 		radio_ar_configure(count, irks, (lll_aux->phy << 2) | BIT(1));
515 #endif /* CONFIG_BT_CTLR_PRIVACY */
516 	} else if (IS_ENABLED(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST) &&
517 		   lll->filter_policy) {
518 		/* Setup Radio Filter */
519 		struct lll_filter *fal = ull_filter_lll_get(true);
520 
521 		radio_filter_configure(fal->enable_bitmask,
522 				       fal->addr_type_bitmask,
523 				       (uint8_t *)fal->bdaddr);
524 	}
525 
526 sync_aux_prepare_done:
527 	/* Calculate event timings, coarse and fine */
528 	ticks_at_event = p->ticks_at_expire;
529 	ull = HDR_LLL2ULL(lll_aux);
530 	ticks_at_event += lll_event_offset_get(ull);
531 
532 	ticks_at_start = ticks_at_event;
533 	ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
534 
535 	remainder = p->remainder;
536 	remainder_us = radio_tmr_start(0, ticks_at_start, remainder);
537 
538 	hcto = remainder_us + lll_aux->window_size_us;
539 	hcto += radio_rx_ready_delay_get(lll_aux->phy, PHY_FLAGS_S8);
540 	hcto += addr_us_get(lll_aux->phy);
541 	hcto += radio_rx_chain_delay_get(lll_aux->phy, PHY_FLAGS_S8);
542 	radio_tmr_hcto_configure(hcto);
543 
544 	/* capture end of Rx-ed PDU, extended scan to schedule auxiliary
545 	 * channel chaining, create connection or to create periodic sync.
546 	 */
547 	radio_tmr_end_capture();
548 
549 	/* scanner always measures RSSI */
550 	radio_rssi_measure();
551 
552 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
553 	radio_gpio_lna_setup();
554 
555 	radio_gpio_pa_lna_enable(remainder_us +
556 				 radio_rx_ready_delay_get(lll_aux->phy,
557 							  PHY_FLAGS_S8) -
558 				 HAL_RADIO_GPIO_LNA_OFFSET);
559 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
560 
561 #if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
562 	(EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
563 	uint32_t overhead;
564 
565 	overhead = lll_preempt_calc(ull, (TICKER_ID_SCAN_AUX_BASE +
566 					  ull_scan_aux_lll_handle_get(lll_aux)), ticks_at_event);
567 	/* check if preempt to start has changed */
568 	if (overhead) {
569 		LL_ASSERT_OVERHEAD(overhead);
570 
571 		radio_isr_set(isr_done, lll_aux);
572 		radio_disable();
573 
574 		return -ECANCELED;
575 	}
576 #endif /* !CONFIG_BT_CTLR_XTAL_ADVANCED */
577 
578 #if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_CTLR_SCHED_ADVANCED)
579 	/* calc end of group in us for the anchor where next connection
580 	 * event to be placed.
581 	 */
582 	if (lll && lll->conn) {
583 		static memq_link_t link;
584 		static struct mayfly mfy_after_cen_offset_get = {
585 			0U, 0U, &link, NULL, ull_sched_mfy_after_cen_offset_get};
586 
587 		/* NOTE: LLL scan instance passed, as done when
588 		 *       establishing legacy connections.
589 		 */
590 		p->param = lll;
591 		mfy_after_cen_offset_get.param = p;
592 
593 		ret = mayfly_enqueue(TICKER_USER_ID_LLL, TICKER_USER_ID_ULL_LOW, 1U,
594 				     &mfy_after_cen_offset_get);
595 		LL_ASSERT(!ret);
596 	}
597 #endif /* CONFIG_BT_CENTRAL && CONFIG_BT_CTLR_SCHED_ADVANCED */
598 
599 	ret = lll_prepare_done(lll_aux);
600 	LL_ASSERT(!ret);
601 
602 	DEBUG_RADIO_START_O(1);
603 
604 	return 0;
605 }
606 
is_abort_cb(void * next,void * curr,lll_prepare_cb_t * resume_cb)607 static int is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb)
608 {
609 	struct lll_scan *lll;
610 
611 	/* Auxiliary context shall not resume when being preempted, i.e. they
612 	 * shall not use -EAGAIN as return value.
613 	 */
614 	ARG_UNUSED(resume_cb);
615 
616 	/* Auxiliary event shall not overlap as they are not periodically
617 	 * scheduled.
618 	 */
619 	LL_ASSERT(next != curr);
620 
621 	lll = ull_scan_lll_is_valid_get(next);
622 	if (lll) {
623 		/* Next event is scan context, let the current auxiliary scan
624 		 * continue.
625 		 */
626 		return 0;
627 	}
628 
629 	/* Yield current auxiliary event to other than scan events */
630 	return -ECANCELED;
631 }
632 
abort_cb(struct lll_prepare_param * prepare_param,void * param)633 static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
634 {
635 	struct event_done_extra *e;
636 	int err;
637 
638 	/* NOTE: This is not a prepare being cancelled */
639 	if (!prepare_param) {
640 		/* Perform event abort here.
641 		 * After event has been cleanly aborted, clean up resources
642 		 * and dispatch event done.
643 		 */
644 		radio_isr_set(isr_done, param);
645 		radio_disable();
646 		return;
647 	}
648 
649 	/* NOTE: Else clean the top half preparations of the aborted event
650 	 * currently in preparation pipeline.
651 	 */
652 	err = lll_hfclock_off();
653 	LL_ASSERT(err >= 0);
654 
655 	e = ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_SCAN_AUX);
656 	LL_ASSERT(e);
657 
658 	lll_done(param);
659 }
660 
isr_done(void * param)661 static void isr_done(void *param)
662 {
663 	struct lll_sync *lll;
664 	uint8_t is_lll_scan;
665 
666 	lll_isr_status_reset();
667 
668 	if (param) {
669 		lll = ull_scan_aux_lll_parent_get(param, &is_lll_scan);
670 	} else {
671 		lll = NULL;
672 	}
673 
674 	/* Check if this aux scan is for periodic advertising train */
675 	if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && lll && !is_lll_scan) {
676 		struct node_rx_pdu *node_rx;
677 
678 		/* Generate message to release aux context and flag the report
679 		 * generated thereafter by HCI as incomplete.
680 		 */
681 		node_rx = ull_pdu_rx_alloc();
682 		LL_ASSERT(node_rx);
683 
684 		node_rx->hdr.type = NODE_RX_TYPE_EXT_AUX_RELEASE;
685 
686 		node_rx->rx_ftr.param = lll;
687 		node_rx->rx_ftr.aux_failed = 1U;
688 
689 		ull_rx_put_sched(node_rx->hdr.link, node_rx);
690 
691 	} else if (!trx_cnt) {
692 		struct event_done_extra *e;
693 
694 		e = ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_SCAN_AUX);
695 		LL_ASSERT(e);
696 	}
697 
698 	lll_isr_cleanup(param);
699 }
700 
isr_rx_ull_schedule(void * param)701 static void isr_rx_ull_schedule(void *param)
702 {
703 	struct lll_scan_aux *lll_aux;
704 	struct lll_scan *lll;
705 
706 	lll_aux = param;
707 	lll = ull_scan_aux_lll_parent_get(lll_aux, NULL);
708 
709 	isr_rx(lll, lll_aux, lll_aux->phy);
710 }
711 
isr_rx_lll_schedule(void * param)712 static void isr_rx_lll_schedule(void *param)
713 {
714 	struct node_rx_pdu *node_rx;
715 	struct lll_scan *lll;
716 	uint8_t phy_aux;
717 
718 	node_rx = param;
719 	lll = node_rx->rx_ftr.param;
720 	phy_aux = node_rx->rx_ftr.aux_phy; /* PHY remembered in node rx */
721 
722 	/* scan context has used LLL scheduling for aux reception */
723 	if (lll->is_aux_sched) {
724 		isr_rx(lll, NULL, phy_aux);
725 	} else {
726 		/* `lll->lll_aux` would be allocated in ULL for LLL scheduled
727 		 * auxiliary PDU reception by scan context and for case
728 		 * where LLL scheduled chain PDU reception by aux context, it
729 		 * is assigned with the current aux context's LLL context.
730 		 */
731 		isr_rx(lll, lll->lll_aux, phy_aux);
732 	}
733 }
734 
isr_rx(struct lll_scan * lll,struct lll_scan_aux * lll_aux,uint8_t phy_aux)735 static void isr_rx(struct lll_scan *lll, struct lll_scan_aux *lll_aux,
736 		   uint8_t phy_aux)
737 {
738 	struct node_rx_pdu *node_rx;
739 	uint8_t phy_aux_flags_rx;
740 	uint8_t devmatch_ok;
741 	uint8_t devmatch_id;
742 	uint8_t irkmatch_ok;
743 	uint8_t irkmatch_id;
744 	struct pdu_adv *pdu;
745 	uint8_t rssi_ready;
746 	uint8_t trx_done;
747 	uint8_t crc_ok;
748 	uint8_t rl_idx;
749 	bool has_adva;
750 	int err;
751 
752 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
753 		lll_prof_latency_capture();
754 	}
755 
756 	/* Read radio status and events */
757 	trx_done = radio_is_done();
758 	if (trx_done) {
759 		crc_ok = radio_crc_is_valid();
760 		devmatch_ok = radio_filter_has_match();
761 		devmatch_id = radio_filter_match_get();
762 		if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {
763 			irkmatch_ok = radio_ar_has_match();
764 			irkmatch_id = radio_ar_match_get();
765 		} else {
766 			irkmatch_ok = 0U;
767 			irkmatch_id = FILTER_IDX_NONE;
768 		}
769 		rssi_ready = radio_rssi_is_ready();
770 		phy_aux_flags_rx = radio_phy_flags_rx_get();
771 	} else {
772 		crc_ok = devmatch_ok = irkmatch_ok = rssi_ready =
773 			phy_aux_flags_rx = 0U;
774 		devmatch_id = irkmatch_id = FILTER_IDX_NONE;
775 	}
776 
777 	/* Clear radio rx status and events */
778 	lll_isr_rx_status_reset();
779 
780 	/* No Rx */
781 	if (!trx_done || !crc_ok) {
782 		/* TODO: Combine the early exit with above if-then-else block
783 		 */
784 		err = -EINVAL;
785 
786 		goto isr_rx_do_close;
787 	}
788 
789 	node_rx = ull_pdu_rx_alloc_peek(3);
790 	if (!node_rx) {
791 		err = -ENOBUFS;
792 
793 		goto isr_rx_do_close;
794 	}
795 
796 	pdu = (void *)node_rx->pdu;
797 	if ((pdu->type != PDU_ADV_TYPE_EXT_IND) || !pdu->len) {
798 		err = -EINVAL;
799 
800 		goto isr_rx_do_close;
801 	}
802 
803 	has_adva = lll_scan_aux_addr_match_get(lll, pdu, &devmatch_ok,
804 					       &devmatch_id, &irkmatch_ok,
805 					       &irkmatch_id);
806 
807 #if defined(CONFIG_BT_CTLR_PRIVACY)
808 	rl_idx = devmatch_ok ?
809 		 ull_filter_lll_rl_idx(((lll->filter_policy &
810 					 SCAN_FP_FILTER) != 0U),
811 				       devmatch_id) :
812 		 irkmatch_ok ? ull_filter_lll_rl_irk_idx(irkmatch_id) :
813 		 FILTER_IDX_NONE;
814 #else
815 	rl_idx = FILTER_IDX_NONE;
816 #endif /* CONFIG_BT_CTLR_PRIVACY */
817 
818 	if (has_adva) {
819 		bool allow;
820 
821 		allow = lll_scan_isr_rx_check(lll, irkmatch_ok, devmatch_ok,
822 					      rl_idx);
823 		if (false) {
824 #if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) && \
825 	defined(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST)
826 		} else if (allow || lll->is_sync) {
827 			devmatch_ok = allow ? 1U : 0U;
828 #endif /* CONFIG_BT_CTLR_SYNC_PERIODIC && CONFIG_BT_CTLR_FILTER_ACCEPT_LIST */
829 		} else if (!allow) {
830 			err = -EINVAL;
831 
832 			goto isr_rx_do_close;
833 		}
834 	}
835 
836 	err = isr_rx_pdu(lll, lll_aux, node_rx, pdu, phy_aux, phy_aux_flags_rx,
837 			 devmatch_ok, devmatch_id, irkmatch_ok, irkmatch_ok,
838 			 rl_idx, rssi_ready);
839 	if (!err) {
840 		if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
841 			lll_prof_send();
842 		}
843 
844 		return;
845 	}
846 
847 isr_rx_do_close:
848 	if (lll_aux) {
849 		radio_isr_set(isr_done, NULL);
850 	} else {
851 		/* Send message to flush Auxiliary PDU list */
852 		if (lll->is_aux_sched && err != -ECANCELED) {
853 			struct node_rx_pdu *node_rx2;
854 
855 			node_rx2 = ull_pdu_rx_alloc();
856 			LL_ASSERT(node_rx2);
857 
858 			node_rx2->hdr.type = NODE_RX_TYPE_EXT_AUX_RELEASE;
859 
860 			/* Use LLL scan context pointer which will be resolved
861 			 * to LLL aux context in the `ull_scan_aux_release`
862 			 * function in ULL execution context.
863 			 * As ULL execution context is the one assigning the
864 			 * `lll->lll_aux`, if it has not been assigned then
865 			 * `ull_scan_aux_release` will not dereference it, but
866 			 * under race, if ULL execution did assign one, it will
867 			 * free it.
868 			 */
869 			node_rx2->rx_ftr.param = lll;
870 
871 			ull_rx_put_sched(node_rx2->hdr.link, node_rx2);
872 		}
873 
874 		/* Check if LLL scheduled auxiliary PDU reception by scan
875 		 * context or auxiliary PDU reception by aux context
876 		 */
877 		if (lll->is_aux_sched) {
878 			lll->is_aux_sched = 0U;
879 
880 			/* Go back to resuming primary channel scanning */
881 			radio_isr_set(lll_scan_isr_resume, lll);
882 		} else {
883 			/* auxiliary channel radio event done */
884 			radio_isr_set(isr_done, NULL);
885 		}
886 	}
887 	radio_disable();
888 }
889 
isr_rx_pdu(struct lll_scan * lll,struct lll_scan_aux * lll_aux,struct node_rx_pdu * node_rx,struct pdu_adv * pdu,uint8_t phy_aux,uint8_t phy_aux_flags_rx,uint8_t devmatch_ok,uint8_t devmatch_id,uint8_t irkmatch_ok,uint8_t irkmatch_id,uint8_t rl_idx,uint8_t rssi_ready)890 static int isr_rx_pdu(struct lll_scan *lll, struct lll_scan_aux *lll_aux,
891 		      struct node_rx_pdu *node_rx, struct pdu_adv *pdu,
892 		      uint8_t phy_aux, uint8_t phy_aux_flags_rx,
893 		      uint8_t devmatch_ok, uint8_t devmatch_id,
894 		      uint8_t irkmatch_ok, uint8_t irkmatch_id, uint8_t rl_idx,
895 		      uint8_t rssi_ready)
896 {
897 	struct node_rx_ftr *ftr;
898 
899 	bool dir_report = false;
900 
901 	if (0) {
902 #if defined(CONFIG_BT_CENTRAL)
903 	/* Initiator */
904 	} else if (lll->conn && !lll->conn->central.cancelled &&
905 		   (pdu->adv_ext_ind.adv_mode & BT_HCI_LE_ADV_PROP_CONN) &&
906 		   lll_scan_ext_tgta_check(lll, false, true, pdu,
907 					   rl_idx, NULL)) {
908 		struct lll_scan_aux *lll_aux_to_use;
909 		struct node_rx_pdu *rx;
910 		struct pdu_adv *pdu_tx;
911 		uint32_t conn_space_us;
912 		struct ull_hdr *ull;
913 		uint32_t pdu_end_us;
914 		uint8_t init_tx_addr;
915 		uint8_t *init_addr;
916 #if defined(CONFIG_BT_CTLR_PRIVACY)
917 		bt_addr_t *lrpa;
918 #endif /* CONFIG_BT_CTLR_PRIVACY */
919 
920 		if (!lll_aux) {
921 			lll_aux_to_use = lll->lll_aux;
922 		} else {
923 			lll_aux_to_use = lll_aux;
924 		}
925 
926 		if (!lll_aux_to_use) {
927 			/* Return -ECHILD, as ULL execution has not yet assigned
928 			 * an aux context. This can happen only under LLL
929 			 * scheduling where in LLL auxiliary channel PDU
930 			 * reception is spawn from LLL primary channel scanning
931 			 * and on completion will join back to resume primary
932 			 * channel PDU scanning.
933 			 */
934 			return -ECHILD;
935 		}
936 
937 		/* Always use CSA#2 on secondary channel, we need 2 nodes for conn
938 		 * and CSA#2 events and 2 nodes are always reserved for connection.
939 		 */
940 		rx = ull_pdu_rx_alloc_peek(4);
941 		if (!rx) {
942 			return -ENOBUFS;
943 		}
944 
945 		pdu_end_us = radio_tmr_end_get();
946 		if (!lll->ticks_window) {
947 			uint32_t scan_interval_us;
948 
949 			/* FIXME: is this correct for continuous scanning? */
950 			scan_interval_us = lll->interval * SCAN_INT_UNIT_US;
951 			pdu_end_us %= scan_interval_us;
952 		}
953 
954 		/* AUX_CONNECT_REQ is the same as CONNECT_IND */
955 		const uint8_t aux_connect_req_len =
956 			sizeof(struct pdu_adv_connect_ind);
957 		/* AUX_CONNECT_RSP has only AdvA and TargetA in extended common
958 		 * header
959 		 */
960 		const uint8_t aux_connect_rsp_len =
961 			PDU_AC_EXT_HEADER_SIZE_MIN +
962 			sizeof(struct pdu_adv_ext_hdr) +
963 			ADVA_SIZE + TARGETA_SIZE;
964 
965 		ull = HDR_LLL2ULL(lll);
966 		if (pdu_end_us > (HAL_TICKER_TICKS_TO_US(ull->ticks_slot) -
967 				  EVENT_IFS_US -
968 				  PDU_AC_MAX_US(aux_connect_req_len, phy_aux) -
969 				  EVENT_IFS_US -
970 				  PDU_AC_MAX_US(aux_connect_rsp_len, phy_aux) -
971 				  EVENT_OVERHEAD_START_US -
972 				  EVENT_TICKER_RES_MARGIN_US)) {
973 			return -ETIME;
974 		}
975 
976 #if defined(CONFIG_BT_CTLR_PRIVACY)
977 		lrpa = ull_filter_lll_lrpa_get(rl_idx);
978 		if (lll->rpa_gen && lrpa) {
979 			init_tx_addr = 1;
980 			init_addr = lrpa->val;
981 		} else {
982 #else
983 		if (1) {
984 #endif
985 			init_tx_addr = lll->init_addr_type;
986 			init_addr = lll->init_addr;
987 		}
988 
989 		pdu_tx = radio_pkt_scratch_get();
990 
991 		lll_scan_prepare_connect_req(lll, pdu_tx, phy_aux,
992 					     phy_aux_flags_rx, pdu->tx_addr,
993 					     pdu->adv_ext_ind.ext_hdr.data,
994 					     init_tx_addr, init_addr,
995 					     &conn_space_us);
996 
997 		radio_pkt_tx_set(pdu_tx);
998 
999 		/* assert if radio packet ptr is not set and radio started tx */
1000 		LL_ASSERT(!radio_is_ready());
1001 
1002 		if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1003 			lll_prof_cputime_capture();
1004 		}
1005 
1006 		/* capture end of Tx-ed PDU, used to calculate HCTO. */
1007 		radio_tmr_end_capture();
1008 
1009 		radio_tmr_tifs_set(EVENT_IFS_US);
1010 		radio_switch_complete_and_rx(phy_aux);
1011 		radio_isr_set(isr_tx_connect_req, lll_aux_to_use);
1012 
1013 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
1014 		if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1015 			/* PA/LNA enable is overwriting packet end
1016 			 * used in ISR profiling, hence back it up
1017 			 * for later use.
1018 			 */
1019 			lll_prof_radio_end_backup();
1020 		}
1021 		radio_gpio_pa_setup();
1022 		radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
1023 					 EVENT_IFS_US -
1024 					 radio_rx_chain_delay_get(phy_aux,
1025 						phy_aux_flags_rx) -
1026 					 HAL_RADIO_GPIO_PA_OFFSET);
1027 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
1028 
1029 #if defined(CONFIG_BT_CTLR_CONN_RSSI)
1030 		if (rssi_ready) {
1031 			lll->conn->rssi_latest =  radio_rssi_get();
1032 		}
1033 #endif /* CONFIG_BT_CTLR_CONN_RSSI */
1034 
1035 		/* block CPU so that there is no CRC error on pdu tx,
1036 		 * this is only needed if we want the CPU to sleep.
1037 		 * while(!radio_has_disabled())
1038 		 * {cpu_sleep();}
1039 		 * radio_status_reset();
1040 		 */
1041 
1042 		/* Stop further connection initiation */
1043 		lll->conn->central.initiated = 1U;
1044 
1045 		/* Stop further initiating events */
1046 		lll->is_stop = 1U;
1047 
1048 		/* Populate the connection complete message */
1049 		rx = ull_pdu_rx_alloc();
1050 		rx->hdr.type = NODE_RX_TYPE_CONNECTION;
1051 		rx->hdr.handle = 0xffff;
1052 
1053 		(void)memcpy(rx->pdu, pdu_tx,
1054 			     (offsetof(struct pdu_adv, connect_ind) +
1055 			      sizeof(struct pdu_adv_connect_ind)));
1056 
1057 		/* ChSel is RFU in AUX_ADV_IND but we do need to use CSA#2 for
1058 		 * connections initiated on the secondary advertising channel
1059 		 * thus overwrite chan_sel to make it work seamlessly.
1060 		 */
1061 		pdu = (void *)rx->pdu;
1062 		pdu->chan_sel = 1;
1063 
1064 		ftr = &(rx->rx_ftr);
1065 		ftr->param = lll;
1066 		ftr->ticks_anchor = radio_tmr_start_get();
1067 		ftr->radio_end_us = conn_space_us;
1068 
1069 #if defined(CONFIG_BT_CTLR_PRIVACY)
1070 		ftr->rl_idx = irkmatch_ok ? rl_idx : FILTER_IDX_NONE;
1071 		ftr->lrpa_used = lll->rpa_gen && lrpa;
1072 #endif /* CONFIG_BT_CTLR_PRIVACY */
1073 
1074 		ftr->extra = ull_pdu_rx_alloc();
1075 
1076 		/* Hold onto connection event message until after successful
1077 		 * reception of CONNECT_RSP
1078 		 */
1079 		lll_aux_to_use->node_conn_rx = rx;
1080 
1081 		/* Increase trx count so as to not generate done extra event
1082 		 * when LLL scheduling of Auxiliary PDU reception
1083 		 */
1084 		if (!lll_aux) {
1085 			trx_cnt++;
1086 		}
1087 
1088 		return 0;
1089 
1090 	/* Active scanner */
1091 	} else if (!lll->conn &&
1092 		   lll->type &&
1093 		   ((lll_aux && !lll_aux->state) ||
1094 		    (lll->lll_aux && !lll->lll_aux->state)) &&
1095 		   (pdu->adv_ext_ind.adv_mode & BT_HCI_LE_ADV_PROP_SCAN) &&
1096 		   lll_scan_ext_tgta_check(lll, false, false, pdu, rl_idx,
1097 					   &dir_report)) {
1098 #else /* !CONFIG_BT_CENTRAL */
1099 	} else if (lll && lll->type &&
1100 		   ((lll_aux && !lll_aux->state) ||
1101 		    (lll->lll_aux && !lll->lll_aux->state)) &&
1102 		   (pdu->adv_ext_ind.adv_mode & BT_HCI_LE_ADV_PROP_SCAN) &&
1103 		   lll_scan_ext_tgta_check(lll, false, false, pdu, rl_idx,
1104 					   &dir_report)) {
1105 #endif /* !CONFIG_BT_CENTRAL */
1106 		struct node_rx_pdu *rx;
1107 		struct pdu_adv *pdu_tx;
1108 #if defined(CONFIG_BT_CTLR_PRIVACY)
1109 		bt_addr_t *lrpa;
1110 #endif /* CONFIG_BT_CTLR_PRIVACY */
1111 
1112 		/* Check if 4 nodes free, 2 will be utilized for aux PDU and
1113 		 * scan response PDU; 2 more to ensure connections have them.
1114 		 */
1115 		rx = ull_pdu_rx_alloc_peek(4);
1116 		if (!rx) {
1117 			return -ENOBUFS;
1118 		}
1119 
1120 		/* setup tIFS switching */
1121 		radio_tmr_tifs_set(EVENT_IFS_US);
1122 		radio_switch_complete_and_rx(phy_aux);
1123 
1124 		/* prepare the scan request packet */
1125 		pdu_tx = (void *)radio_pkt_scratch_get();
1126 		pdu_tx->type = PDU_ADV_TYPE_SCAN_REQ;
1127 		pdu_tx->rx_addr = pdu->tx_addr;
1128 		pdu_tx->len = sizeof(struct pdu_adv_scan_req);
1129 #if defined(CONFIG_BT_CTLR_PRIVACY)
1130 		lrpa = ull_filter_lll_lrpa_get(rl_idx);
1131 		if (lll->rpa_gen && lrpa) {
1132 			pdu_tx->tx_addr = 1;
1133 			(void)memcpy(pdu_tx->scan_req.scan_addr, lrpa->val,
1134 				     BDADDR_SIZE);
1135 		} else {
1136 #else
1137 		if (1) {
1138 #endif /* CONFIG_BT_CTLR_PRIVACY */
1139 			pdu_tx->tx_addr = lll->init_addr_type;
1140 			(void)memcpy(pdu_tx->scan_req.scan_addr, lll->init_addr,
1141 				     BDADDR_SIZE);
1142 		}
1143 		(void)memcpy(pdu_tx->scan_req.adv_addr,
1144 			     &pdu->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
1145 			     BDADDR_SIZE);
1146 
1147 		radio_pkt_tx_set(pdu_tx);
1148 
1149 		/* assert if radio packet ptr is not set and radio started tx */
1150 		LL_ASSERT(!radio_is_ready());
1151 
1152 		if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1153 			lll_prof_cputime_capture();
1154 		}
1155 
1156 		/* capture end of Tx-ed PDU, used to calculate HCTO. */
1157 		radio_tmr_end_capture();
1158 
1159 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
1160 		if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1161 			/* PA/LNA enable is overwriting packet end
1162 			 * used in ISR profiling, hence back it up
1163 			 * for later use.
1164 			 */
1165 			lll_prof_radio_end_backup();
1166 		}
1167 
1168 		radio_gpio_pa_setup();
1169 		radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
1170 					 EVENT_IFS_US -
1171 					 radio_rx_chain_delay_get(phy_aux,
1172 						phy_aux_flags_rx) -
1173 					 HAL_RADIO_GPIO_PA_OFFSET);
1174 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
1175 
1176 		(void)ull_pdu_rx_alloc();
1177 
1178 		node_rx->hdr.type = NODE_RX_TYPE_EXT_AUX_REPORT;
1179 
1180 		ftr = &(node_rx->rx_ftr);
1181 		if (lll_aux) {
1182 			ftr->param = lll_aux;
1183 			radio_isr_set(isr_tx_scan_req_ull_schedule,
1184 				      lll_aux);
1185 			lll_aux->state = 1U;
1186 		} else {
1187 			ftr->param = lll;
1188 			radio_isr_set(isr_tx_scan_req_lll_schedule,
1189 				      node_rx);
1190 			lll->lll_aux->state = 1U;
1191 		}
1192 		ftr->ticks_anchor = radio_tmr_start_get();
1193 		ftr->radio_end_us = radio_tmr_end_get() -
1194 				    radio_rx_chain_delay_get(phy_aux,
1195 							     phy_aux_flags_rx);
1196 		ftr->rssi = (rssi_ready) ? radio_rssi_get() :
1197 			    BT_HCI_LE_RSSI_NOT_AVAILABLE;
1198 		ftr->scan_req = 1U;
1199 		ftr->scan_rsp = 0U;
1200 
1201 #if defined(CONFIG_BT_CTLR_PRIVACY)
1202 		ftr->rl_idx = irkmatch_ok ? rl_idx : FILTER_IDX_NONE;
1203 #endif /* CONFIG_BT_CTLR_PRIVACY */
1204 
1205 #if defined(CONFIG_BT_CTLR_EXT_SCAN_FP)
1206 		ftr->direct = dir_report;
1207 #endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */
1208 
1209 #if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) && \
1210 	defined(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST)
1211 		ftr->devmatch = devmatch_ok;
1212 #endif /* CONFIG_BT_CTLR_SYNC_PERIODIC && CONFIG_BT_CTLR_FILTER_ACCEPT_LIST */
1213 
1214 		ftr->aux_lll_sched = 0U;
1215 
1216 		ull_rx_put_sched(node_rx->hdr.link, node_rx);
1217 
1218 		return 0;
1219 
1220 	/* Passive scanner or scan responses */
1221 #if defined(CONFIG_BT_CENTRAL)
1222 	} else if (!lll->conn &&
1223 		   ((lll_aux && lll_aux->is_chain_sched) ||
1224 		    (lll->lll_aux && lll->lll_aux->is_chain_sched) ||
1225 		    lll_scan_ext_tgta_check(lll, false, false, pdu, rl_idx,
1226 					    &dir_report))) {
1227 #else /* !CONFIG_BT_CENTRAL */
1228 	} else if ((lll_aux && lll_aux->is_chain_sched) ||
1229 		   (lll->lll_aux && lll->lll_aux->is_chain_sched) ||
1230 		   lll_scan_ext_tgta_check(lll, false, false, pdu, rl_idx,
1231 					   &dir_report)) {
1232 #endif /* !CONFIG_BT_CENTRAL */
1233 
1234 		ftr = &(node_rx->rx_ftr);
1235 		if (lll_aux) {
1236 			ftr->param = lll_aux;
1237 			ftr->scan_rsp = lll_aux->state;
1238 
1239 			/* Further auxiliary PDU reception will be chain PDUs */
1240 			lll_aux->is_chain_sched = 1U;
1241 		} else if (lll->lll_aux) {
1242 			ftr->param = lll;
1243 			ftr->scan_rsp = lll->lll_aux->state;
1244 
1245 			/* Further auxiliary PDU reception will be chain PDUs */
1246 			lll->lll_aux->is_chain_sched = 1U;
1247 		} else {
1248 			/* Return -ECHILD, as ULL execution has not yet assigned
1249 			 * an aux context. This can happen only under LLL
1250 			 * scheduling where in LLL auxiliary channel PDU
1251 			 * reception is spawn from LLL primary channel scanning
1252 			 * and on completion will join back to resume primary
1253 			 * channel PDU scanning.
1254 			 */
1255 			return -ECHILD;
1256 		}
1257 
1258 		/* Allocate before `lll_scan_aux_setup` call, so that a new
1259 		 * free PDU buffer is used to receive auxiliary PDU when using
1260 		 * LLL scheduling.
1261 		 */
1262 		(void)ull_pdu_rx_alloc();
1263 
1264 		ftr->ticks_anchor = radio_tmr_start_get();
1265 		ftr->radio_end_us = radio_tmr_end_get() -
1266 				    radio_rx_chain_delay_get(phy_aux,
1267 							     phy_aux_flags_rx);
1268 		ftr->phy_flags = phy_aux_flags_rx;
1269 		ftr->rssi = (rssi_ready) ? radio_rssi_get() :
1270 			    BT_HCI_LE_RSSI_NOT_AVAILABLE;
1271 		ftr->scan_req = 0U;
1272 
1273 #if defined(CONFIG_BT_CTLR_PRIVACY)
1274 		ftr->rl_idx = irkmatch_ok ? rl_idx : FILTER_IDX_NONE;
1275 #endif /* CONFIG_BT_CTLR_PRIVACY */
1276 
1277 #if defined(CONFIG_BT_CTLR_EXT_SCAN_FP)
1278 		ftr->direct = dir_report;
1279 #endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */
1280 
1281 #if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) && \
1282 	defined(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST)
1283 		ftr->devmatch = devmatch_ok;
1284 #endif /* CONFIG_BT_CTLR_SYNC_PERIODIC && CONFIG_BT_CTLR_FILTER_ACCEPT_LIST */
1285 
1286 		ftr->aux_lll_sched = lll_scan_aux_setup(pdu, phy_aux,
1287 							phy_aux_flags_rx,
1288 							lll_scan_aux_isr_aux_setup,
1289 							lll);
1290 
1291 		node_rx->hdr.type = NODE_RX_TYPE_EXT_AUX_REPORT;
1292 
1293 		ull_rx_put_sched(node_rx->hdr.link, node_rx);
1294 
1295 		/* Next aux scan is scheduled from LLL, we already handled radio
1296 		 * disable so prevent caller from doing it again.
1297 		 */
1298 		if (ftr->aux_lll_sched) {
1299 			if (!lll_aux) {
1300 				lll->is_aux_sched = 1U;
1301 			}
1302 
1303 			if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1304 				lll_prof_cputime_capture();
1305 			}
1306 
1307 			return 0;
1308 		}
1309 
1310 		/* Increase trx count so as to not generate done extra event
1311 		 * as a valid Auxiliary PDU node rx is being reported to ULL.
1312 		 */
1313 		trx_cnt++;
1314 
1315 		return -ECANCELED;
1316 	}
1317 
1318 	return -EINVAL;
1319 }
1320 
1321 static void isr_tx(struct lll_scan_aux *lll_aux, void *pdu_rx,
1322 		   void (*isr)(void *), void *param)
1323 {
1324 	uint32_t hcto;
1325 
1326 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1327 		lll_prof_latency_capture();
1328 	}
1329 
1330 	/* Clear radio tx status and events */
1331 	lll_isr_tx_status_reset();
1332 
1333 	/* complete the reception and disable radio  */
1334 	radio_switch_complete_and_disable();
1335 
1336 	radio_pkt_rx_set(pdu_rx);
1337 
1338 	/* assert if radio packet ptr is not set and radio started rx */
1339 	LL_ASSERT(!radio_is_ready());
1340 
1341 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1342 		lll_prof_cputime_capture();
1343 	}
1344 
1345 #if defined(CONFIG_BT_CTLR_PRIVACY)
1346 	if (ull_filter_lll_rl_enabled()) {
1347 		uint8_t count, *irks = ull_filter_lll_irks_get(&count);
1348 
1349 		radio_ar_configure(count, irks, (lll_aux->phy << 2) | BIT(1));
1350 	}
1351 #endif /* CONFIG_BT_CTLR_PRIVACY */
1352 
1353 	/* +/- 2us active clock jitter, +1 us PPI to timer start compensation */
1354 	hcto = radio_tmr_tifs_base_get() + EVENT_IFS_US +
1355 	       (EVENT_CLOCK_JITTER_US << 1) + RANGE_DELAY_US +
1356 	       HAL_RADIO_TMR_START_DELAY_US;
1357 	hcto += radio_rx_chain_delay_get(lll_aux->phy, PHY_FLAGS_S8);
1358 	hcto += addr_us_get(lll_aux->phy);
1359 	hcto -= radio_tx_chain_delay_get(lll_aux->phy, PHY_FLAGS_S8);
1360 	radio_tmr_hcto_configure(hcto);
1361 
1362 	/* capture end of Rx-ed PDU, extended scan to schedule auxiliary
1363 	 * channel chaining.
1364 	 */
1365 	radio_tmr_end_capture();
1366 
1367 	/* scanner always measures RSSI */
1368 	radio_rssi_measure();
1369 
1370 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
1371 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1372 		/* PA/LNA enable is overwriting packet end used in ISR
1373 		 * profiling, hence back it up for later use.
1374 		 */
1375 		lll_prof_radio_end_backup();
1376 	}
1377 
1378 	radio_gpio_lna_setup();
1379 	radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() + EVENT_IFS_US -
1380 				 (EVENT_CLOCK_JITTER_US << 1U) -
1381 				 radio_tx_chain_delay_get(lll_aux->phy,
1382 							  PHY_FLAGS_S8) -
1383 				 HAL_RADIO_GPIO_LNA_OFFSET);
1384 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
1385 
1386 	radio_isr_set(isr, param);
1387 
1388 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1389 		/* NOTE: as scratch packet is used to receive, it is safe to
1390 		 * generate profile event using rx nodes.
1391 		 */
1392 		lll_prof_send();
1393 	}
1394 }
1395 
1396 static void isr_tx_scan_req_ull_schedule(void *param)
1397 {
1398 	struct node_rx_pdu *node_rx;
1399 
1400 	node_rx = ull_pdu_rx_alloc_peek(1);
1401 	LL_ASSERT(node_rx);
1402 
1403 	isr_tx(param, node_rx->pdu, isr_rx_ull_schedule, param);
1404 }
1405 
1406 static void isr_tx_scan_req_lll_schedule(void *param)
1407 {
1408 	struct node_rx_pdu *node_rx_adv = param;
1409 	struct node_rx_pdu *node_rx;
1410 	struct lll_scan *lll;
1411 
1412 	lll = node_rx_adv->rx_ftr.param;
1413 
1414 	node_rx = ull_pdu_rx_alloc_peek(1);
1415 	LL_ASSERT(node_rx);
1416 
1417 	isr_tx(lll->lll_aux, node_rx->pdu, isr_rx_lll_schedule, param);
1418 }
1419 
1420 #if defined(CONFIG_BT_CENTRAL)
1421 static void isr_tx_connect_req(void *param)
1422 {
1423 	struct node_rx_pdu *node_rx;
1424 
1425 	node_rx = ull_pdu_rx_alloc_peek(1);
1426 	LL_ASSERT(node_rx);
1427 
1428 	isr_tx(param, (void *)node_rx->pdu, isr_rx_connect_rsp, param);
1429 }
1430 
1431 static void isr_rx_connect_rsp(void *param)
1432 {
1433 	struct lll_scan_aux *lll_aux;
1434 	uint8_t phy_aux_flags_rx;
1435 	struct pdu_adv *pdu_rx;
1436 	struct node_rx_pdu *rx;
1437 	struct lll_scan *lll;
1438 	uint8_t irkmatch_ok;
1439 	uint8_t irkmatch_id;
1440 	uint8_t trx_done;
1441 	uint8_t rl_idx;
1442 	uint8_t crc_ok;
1443 
1444 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1445 		lll_prof_latency_capture();
1446 	}
1447 
1448 	/* Read radio status */
1449 	trx_done = radio_is_done();
1450 	if (trx_done) {
1451 		crc_ok = radio_crc_is_valid();
1452 		if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {
1453 			irkmatch_ok = radio_ar_has_match();
1454 			irkmatch_id = radio_ar_match_get();
1455 		} else {
1456 			irkmatch_ok = 0U;
1457 			irkmatch_id = FILTER_IDX_NONE;
1458 		}
1459 		phy_aux_flags_rx = radio_phy_flags_rx_get();
1460 	} else {
1461 		crc_ok = irkmatch_ok = phy_aux_flags_rx = 0U;
1462 		irkmatch_id = FILTER_IDX_NONE;
1463 	}
1464 
1465 	/* Clear radio rx status and events */
1466 	lll_isr_rx_status_reset();
1467 
1468 	/* Get the reference to primary scanner's LLL context */
1469 	lll_aux = param;
1470 	lll = ull_scan_aux_lll_parent_get(lll_aux, NULL);
1471 
1472 	/* Use the reserved/saved node rx to generate connection complete or
1473 	 * release it if failed to receive AUX_CONNECT_RSP PDU.
1474 	 */
1475 	rx = lll_aux->node_conn_rx;
1476 	LL_ASSERT(rx);
1477 	lll_aux->node_conn_rx = NULL;
1478 
1479 #if defined(CONFIG_BT_CTLR_PRIVACY)
1480 	rl_idx = irkmatch_ok ? ull_filter_lll_rl_irk_idx(irkmatch_id) :
1481 			       FILTER_IDX_NONE;
1482 #else
1483 	rl_idx = FILTER_IDX_NONE;
1484 #endif /* CONFIG_BT_CTLR_PRIVACY */
1485 
1486 	/* Check for PDU reception */
1487 	if (trx_done && crc_ok) {
1488 		struct node_rx_pdu *node_rx;
1489 		struct pdu_adv *pdu_tx;
1490 
1491 		pdu_tx = radio_pkt_scratch_get();
1492 
1493 		node_rx = ull_pdu_rx_alloc_peek(1);
1494 		LL_ASSERT(node_rx);
1495 		pdu_rx = (void *)node_rx->pdu;
1496 
1497 		trx_done = isr_rx_connect_rsp_check(lll, pdu_tx, pdu_rx,
1498 						    rl_idx);
1499 	} else {
1500 		trx_done = 0U;
1501 	}
1502 
1503 	/* No Rx or invalid PDU received */
1504 	if (!trx_done) {
1505 		struct node_rx_ftr *ftr;
1506 
1507 		/* Try again with connection initiation */
1508 		lll->conn->central.initiated = 0U;
1509 
1510 		/* Dont stop initiating events on primary channels */
1511 		lll->is_stop = 0U;
1512 
1513 		ftr = &(rx->rx_ftr);
1514 
1515 		rx->hdr.type = NODE_RX_TYPE_RELEASE;
1516 		ull_rx_put(rx->hdr.link, rx);
1517 
1518 		rx = ftr->extra;
1519 		rx->hdr.type = NODE_RX_TYPE_RELEASE;
1520 		goto isr_rx_connect_rsp_do_close;
1521 	}
1522 
1523 	/* Update the max Tx and Rx time; and connection PHY based on the
1524 	 * extended advertising PHY used to establish the connection.
1525 	 */
1526 #if defined(CONFIG_BT_CTLR_PHY)
1527 	struct lll_conn *conn_lll = lll->conn;
1528 
1529 #if defined(CONFIG_BT_CTLR_DATA_LENGTH)
1530 	conn_lll->dle.eff.max_tx_time = MAX(conn_lll->dle.eff.max_tx_time,
1531 					    PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN,
1532 							  lll_aux->phy));
1533 	conn_lll->dle.eff.max_rx_time = MAX(conn_lll->dle.eff.max_rx_time,
1534 					    PDU_DC_MAX_US(PDU_DC_PAYLOAD_SIZE_MIN,
1535 							  lll_aux->phy));
1536 #endif /* CONFIG_BT_CTLR_DATA_LENGTH*/
1537 
1538 	conn_lll->phy_tx = lll_aux->phy;
1539 	conn_lll->phy_tx_time = lll_aux->phy;
1540 	conn_lll->phy_flags = phy_aux_flags_rx;
1541 	conn_lll->phy_rx = lll_aux->phy;
1542 #endif /* CONFIG_BT_CTLR_PHY */
1543 
1544 #if defined(CONFIG_BT_CTLR_PRIVACY)
1545 	if (irkmatch_ok) {
1546 		struct node_rx_ftr *ftr;
1547 		struct pdu_adv *pdu;
1548 
1549 		pdu = (void *)rx->pdu;
1550 		pdu->rx_addr = pdu_rx->tx_addr;
1551 		(void)memcpy(pdu->connect_ind.adv_addr,
1552 			     &pdu_rx->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
1553 			     BDADDR_SIZE);
1554 		ftr = &(rx->rx_ftr);
1555 		ftr->rl_idx = rl_idx;
1556 	}
1557 #endif /* CONFIG_BT_CTLR_PRIVACY */
1558 
1559 isr_rx_connect_rsp_do_close:
1560 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1561 		lll_prof_cputime_capture();
1562 	}
1563 
1564 	ull_rx_put_sched(rx->hdr.link, rx);
1565 
1566 	if (lll->lll_aux) {
1567 		struct node_rx_pdu *node_rx;
1568 
1569 		/* Send message to flush Auxiliary PDU list */
1570 		node_rx = ull_pdu_rx_alloc();
1571 		LL_ASSERT(node_rx);
1572 
1573 		node_rx->hdr.type = NODE_RX_TYPE_EXT_AUX_RELEASE;
1574 
1575 		node_rx->rx_ftr.param = lll->lll_aux;
1576 
1577 		ull_rx_put_sched(node_rx->hdr.link, node_rx);
1578 
1579 		radio_isr_set(lll_scan_isr_resume, lll);
1580 	} else {
1581 		radio_isr_set(isr_done, NULL);
1582 	}
1583 
1584 	radio_disable();
1585 
1586 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1587 		lll_prof_send();
1588 	}
1589 }
1590 
1591 static bool isr_rx_connect_rsp_check(struct lll_scan *lll,
1592 				     struct pdu_adv *pdu_tx,
1593 				     struct pdu_adv *pdu_rx, uint8_t rl_idx)
1594 {
1595 	if (pdu_rx->type != PDU_ADV_TYPE_AUX_CONNECT_RSP) {
1596 		return false;
1597 	}
1598 
1599 	if (pdu_rx->len != offsetof(struct pdu_adv_com_ext_adv,
1600 				    ext_hdr_adv_data) +
1601 			   offsetof(struct pdu_adv_ext_hdr, data) + ADVA_SIZE +
1602 			   TARGETA_SIZE) {
1603 		return false;
1604 	}
1605 
1606 	if (pdu_rx->adv_ext_ind.adv_mode ||
1607 	    !pdu_rx->adv_ext_ind.ext_hdr.adv_addr ||
1608 	    !pdu_rx->adv_ext_ind.ext_hdr.tgt_addr) {
1609 		return false;
1610 	}
1611 
1612 	return lll_scan_adva_check(lll, pdu_rx->tx_addr,
1613 			&pdu_rx->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
1614 			rl_idx) &&
1615 	       (pdu_rx->rx_addr == pdu_tx->tx_addr) &&
1616 	       (memcmp(&pdu_rx->adv_ext_ind.ext_hdr.data[TGTA_OFFSET],
1617 		       pdu_tx->connect_ind.init_addr, BDADDR_SIZE) == 0);
1618 }
1619 
1620 static void isr_early_abort(void *param)
1621 {
1622 	struct event_done_extra *e;
1623 
1624 	e = ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_SCAN_AUX);
1625 	LL_ASSERT(e);
1626 
1627 	lll_isr_early_abort(param);
1628 }
1629 #endif /* CONFIG_BT_CENTRAL */
1630