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