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