1 /*
2 * Copyright (c) 2018-2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdint.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/bluetooth/hci_types.h>
13
14 #include "hal/cpu.h"
15 #include "hal/ccm.h"
16 #include "hal/radio.h"
17 #include "hal/ticker.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 "ticker/ticker.h"
25
26 #include "pdu_df.h"
27 #include "pdu_vendor.h"
28 #include "pdu.h"
29
30 #include "lll.h"
31 #include "lll_vendor.h"
32 #include "lll_clock.h"
33 #include "lll_df_types.h"
34 #include "lll_scan.h"
35 #include "lll_sync.h"
36 #include "lll_conn.h"
37 #include "lll_chan.h"
38 #include "lll_filter.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
46 #include "hal/debug.h"
47
48 /* Maximum primary Advertising Radio Channels to scan */
49 #define ADV_CHAN_MAX 3U
50
51 static int init_reset(void);
52 static int prepare_cb(struct lll_prepare_param *p);
53 static int resume_prepare_cb(struct lll_prepare_param *p);
54 static int common_prepare_cb(struct lll_prepare_param *p, bool is_resume);
55 static int is_abort_cb(void *next, void *curr,
56 lll_prepare_cb_t *resume_cb);
57 static void abort_cb(struct lll_prepare_param *prepare_param, void *param);
58 static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
59 uint32_t remainder, uint16_t lazy, uint8_t force,
60 void *param);
61 static void ticker_op_start_cb(uint32_t status, void *param);
62 static void isr_rx(void *param);
63 static void isr_tx(void *param);
64 static void isr_done(void *param);
65 static void isr_window(void *param);
66 #if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
67 (EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
68 static void isr_abort(void *param);
69 #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED &&
70 * (EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
71 */
72 static void isr_done_cleanup(void *param);
73
74 static inline int isr_rx_pdu(struct lll_scan *lll, struct pdu_adv *pdu_adv_rx,
75 uint8_t devmatch_ok, uint8_t devmatch_id,
76 uint8_t irkmatch_ok, uint8_t irkmatch_id,
77 uint8_t rl_idx, uint8_t rssi_ready,
78 uint8_t phy_flags_rx);
79
80 #if defined(CONFIG_BT_CENTRAL)
81 static inline bool isr_scan_init_check(const struct lll_scan *lll,
82 const struct pdu_adv *pdu,
83 uint8_t rl_idx);
84 #endif /* CONFIG_BT_CENTRAL */
85
86 static bool isr_scan_tgta_check(const struct lll_scan *lll, bool init,
87 uint8_t addr_type, const uint8_t *addr,
88 uint8_t rl_idx, bool *const dir_report);
89 static inline bool isr_scan_tgta_rpa_check(const struct lll_scan *lll,
90 uint8_t addr_type,
91 const uint8_t *addr,
92 bool *const dir_report);
93 static inline bool isr_scan_rsp_adva_matches(struct pdu_adv *srsp);
94 static int isr_rx_scan_report(struct lll_scan *lll, uint8_t devmatch_ok,
95 uint8_t irkmatch_ok, uint8_t rl_idx,
96 uint8_t rssi_ready, uint8_t phy_flags_rx,
97 bool dir_report);
98
lll_scan_init(void)99 int lll_scan_init(void)
100 {
101 int err;
102
103 err = init_reset();
104 if (err) {
105 return err;
106 }
107
108 return 0;
109 }
110
lll_scan_reset(void)111 int lll_scan_reset(void)
112 {
113 int err;
114
115 err = init_reset();
116 if (err) {
117 return err;
118 }
119
120 return 0;
121 }
122
lll_scan_prepare(void * param)123 void lll_scan_prepare(void *param)
124 {
125 int err;
126
127 err = lll_hfclock_on();
128 LL_ASSERT(err >= 0);
129
130 err = lll_prepare(is_abort_cb, abort_cb, prepare_cb, 0, param);
131 LL_ASSERT(!err || err == -EINPROGRESS);
132 }
133
lll_scan_isr_resume(void * param)134 void lll_scan_isr_resume(void *param)
135 {
136 static struct lll_prepare_param p;
137
138 /* Clear radio status and events */
139 lll_isr_status_reset();
140
141 p.param = param;
142 resume_prepare_cb(&p);
143 }
144
lll_scan_isr_rx_check(const struct lll_scan * lll,uint8_t irkmatch_ok,uint8_t devmatch_ok,uint8_t rl_idx)145 bool lll_scan_isr_rx_check(const struct lll_scan *lll, uint8_t irkmatch_ok,
146 uint8_t devmatch_ok, uint8_t rl_idx)
147 {
148 #if defined(CONFIG_BT_CTLR_PRIVACY)
149 return (((lll->filter_policy & SCAN_FP_FILTER) == 0U) &&
150 (!devmatch_ok || ull_filter_lll_rl_idx_allowed(irkmatch_ok,
151 rl_idx))) ||
152 (((lll->filter_policy & SCAN_FP_FILTER) != 0U) &&
153 (devmatch_ok || ull_filter_lll_irk_in_fal(rl_idx)));
154 #else
155 return ((lll->filter_policy & SCAN_FP_FILTER) == 0U) ||
156 devmatch_ok;
157 #endif /* CONFIG_BT_CTLR_PRIVACY */
158 }
159
160 #if defined(CONFIG_BT_CENTRAL) || defined(CONFIG_BT_CTLR_ADV_EXT)
lll_scan_adva_check(const struct lll_scan * lll,uint8_t addr_type,const uint8_t * addr,uint8_t rl_idx)161 bool lll_scan_adva_check(const struct lll_scan *lll, uint8_t addr_type,
162 const uint8_t *addr, uint8_t rl_idx)
163 {
164 #if defined(CONFIG_BT_CTLR_PRIVACY)
165 /* Only applies to initiator with no filter accept list */
166 if (rl_idx != FILTER_IDX_NONE) {
167 return (rl_idx == lll->rl_idx);
168 } else if (!ull_filter_lll_rl_addr_allowed(addr_type, addr, &rl_idx)) {
169 return false;
170 }
171 #endif /* CONFIG_BT_CTLR_PRIVACY */
172
173 /* NOTE: This function to be used only to check AdvA when initiating,
174 * hence, otherwise we should not use the return value.
175 * This function is referenced in lll_scan_ext_tgta_check, but
176 * is not used when not being an initiator, hence return false
177 * is never reached.
178 */
179 #if defined(CONFIG_BT_CENTRAL)
180 return ((lll->adv_addr_type == addr_type) &&
181 !memcmp(lll->adv_addr, addr, BDADDR_SIZE));
182 #else /* CONFIG_BT_CENTRAL */
183 return false;
184 #endif /* CONFIG_BT_CENTRAL */
185 }
186 #endif /* CONFIG_BT_CENTRAL || CONFIG_BT_CTLR_ADV_EXT */
187
188 #if defined(CONFIG_BT_CTLR_ADV_EXT)
lll_scan_ext_tgta_check(const struct lll_scan * lll,bool pri,bool is_init,const struct pdu_adv * pdu,uint8_t rl_idx,bool * const dir_report)189 bool lll_scan_ext_tgta_check(const struct lll_scan *lll, bool pri, bool is_init,
190 const struct pdu_adv *pdu, uint8_t rl_idx,
191 bool *const dir_report)
192 {
193 const uint8_t *adva;
194 const uint8_t *tgta;
195 uint8_t is_directed;
196 uint8_t tx_addr;
197 uint8_t rx_addr;
198
199 if (pri && !pdu->adv_ext_ind.ext_hdr.adv_addr) {
200 return true;
201 }
202
203 if (pdu->len <
204 PDU_AC_EXT_HEADER_SIZE_MIN + sizeof(struct pdu_adv_ext_hdr) +
205 ADVA_SIZE) {
206 return false;
207 }
208
209 is_directed = pdu->adv_ext_ind.ext_hdr.tgt_addr;
210 if (is_directed && (pdu->len < PDU_AC_EXT_HEADER_SIZE_MIN +
211 sizeof(struct pdu_adv_ext_hdr) +
212 ADVA_SIZE + TARGETA_SIZE)) {
213 return false;
214 }
215
216 tx_addr = pdu->tx_addr;
217 rx_addr = pdu->rx_addr;
218 adva = &pdu->adv_ext_ind.ext_hdr.data[ADVA_OFFSET];
219 tgta = &pdu->adv_ext_ind.ext_hdr.data[TGTA_OFFSET];
220 return ((!is_init ||
221 ((lll->filter_policy & SCAN_FP_FILTER) != 0U) ||
222 lll_scan_adva_check(lll, tx_addr, adva, rl_idx)) &&
223 ((!is_directed) ||
224 (is_directed &&
225 isr_scan_tgta_check(lll, is_init, rx_addr, tgta, rl_idx,
226 dir_report))));
227 }
228 #endif /* CONFIG_BT_CTLR_ADV_EXT */
229
230 #if defined(CONFIG_BT_CENTRAL)
lll_scan_prepare_connect_req(struct lll_scan * lll,struct pdu_adv * pdu_tx,uint8_t phy,uint8_t phy_flags_rx,uint8_t adv_tx_addr,uint8_t * adv_addr,uint8_t init_tx_addr,uint8_t * init_addr,uint32_t * conn_space_us)231 void lll_scan_prepare_connect_req(struct lll_scan *lll, struct pdu_adv *pdu_tx,
232 uint8_t phy, uint8_t phy_flags_rx,
233 uint8_t adv_tx_addr, uint8_t *adv_addr,
234 uint8_t init_tx_addr, uint8_t *init_addr,
235 uint32_t *conn_space_us)
236 {
237 struct lll_conn *lll_conn;
238 uint32_t conn_interval_us;
239 uint32_t conn_offset_us;
240
241 lll_conn = lll->conn;
242
243 /* Note: this code is also valid for AUX_CONNECT_REQ */
244 pdu_tx->type = PDU_ADV_TYPE_CONNECT_IND;
245
246 if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
247 pdu_tx->chan_sel = 1;
248 } else {
249 pdu_tx->chan_sel = 0;
250 }
251
252 pdu_tx->tx_addr = init_tx_addr;
253 pdu_tx->rx_addr = adv_tx_addr;
254 pdu_tx->len = sizeof(struct pdu_adv_connect_ind);
255 memcpy(&pdu_tx->connect_ind.init_addr[0], init_addr, BDADDR_SIZE);
256 memcpy(&pdu_tx->connect_ind.adv_addr[0], adv_addr, BDADDR_SIZE);
257 memcpy(&pdu_tx->connect_ind.access_addr[0],
258 &lll_conn->access_addr[0], 4);
259 memcpy(&pdu_tx->connect_ind.crc_init[0], &lll_conn->crc_init[0], 3);
260 pdu_tx->connect_ind.win_size = 1;
261
262 conn_interval_us = (uint32_t)lll_conn->interval * CONN_INT_UNIT_US;
263 conn_offset_us = radio_tmr_end_get() + EVENT_IFS_US +
264 PDU_AC_MAX_US(sizeof(struct pdu_adv_connect_ind),
265 (phy == PHY_LEGACY) ? PHY_1M : phy) -
266 radio_rx_chain_delay_get(phy, phy_flags_rx);
267
268 /* Add transmitWindowDelay to default calculated connection offset:
269 * 1.25ms for a legacy PDU, 2.5ms for an LE Uncoded PHY and 3.75ms for
270 * an LE Coded PHY.
271 */
272 if (0) {
273 #if defined(CONFIG_BT_CTLR_ADV_EXT)
274 } else if (phy) {
275 if (phy & PHY_CODED) {
276 conn_offset_us += WIN_DELAY_CODED;
277 } else {
278 conn_offset_us += WIN_DELAY_UNCODED;
279 }
280 #endif
281 } else {
282 conn_offset_us += WIN_DELAY_LEGACY;
283 }
284
285 if (!IS_ENABLED(CONFIG_BT_CTLR_SCHED_ADVANCED) ||
286 lll->conn_win_offset_us == 0U) {
287 *conn_space_us = conn_offset_us;
288 pdu_tx->connect_ind.win_offset = sys_cpu_to_le16(0);
289 } else {
290 uint32_t win_offset_us =
291 lll->conn_win_offset_us +
292 radio_rx_ready_delay_get(phy, PHY_FLAGS_S8);
293
294 while ((win_offset_us & ((uint32_t)1 << 31)) ||
295 (win_offset_us < conn_offset_us)) {
296 win_offset_us += conn_interval_us;
297 }
298
299 *conn_space_us = win_offset_us;
300 pdu_tx->connect_ind.win_offset =
301 sys_cpu_to_le16((win_offset_us - conn_offset_us) /
302 CONN_INT_UNIT_US);
303 pdu_tx->connect_ind.win_size++;
304 }
305
306 pdu_tx->connect_ind.interval = sys_cpu_to_le16(lll_conn->interval);
307 pdu_tx->connect_ind.latency = sys_cpu_to_le16(lll_conn->latency);
308 pdu_tx->connect_ind.timeout = sys_cpu_to_le16(lll->conn_timeout);
309 memcpy(&pdu_tx->connect_ind.chan_map[0], &lll_conn->data_chan_map[0],
310 sizeof(pdu_tx->connect_ind.chan_map));
311 pdu_tx->connect_ind.hop = lll_conn->data_chan_hop;
312 pdu_tx->connect_ind.sca = lll_clock_sca_local_get();
313 }
314 #endif /* CONFIG_BT_CENTRAL */
315
init_reset(void)316 static int init_reset(void)
317 {
318 return 0;
319 }
320
prepare_cb(struct lll_prepare_param * p)321 static int prepare_cb(struct lll_prepare_param *p)
322 {
323 return common_prepare_cb(p, false);
324 }
325
resume_prepare_cb(struct lll_prepare_param * p)326 static int resume_prepare_cb(struct lll_prepare_param *p)
327 {
328 struct ull_hdr *ull;
329
330 ull = HDR_LLL2ULL(p->param);
331 p->ticks_at_expire = ticker_ticks_now_get() - lll_event_offset_get(ull);
332 p->remainder = 0;
333 p->lazy = 0;
334
335 return common_prepare_cb(p, true);
336 }
337
common_prepare_cb(struct lll_prepare_param * p,bool is_resume)338 static int common_prepare_cb(struct lll_prepare_param *p, bool is_resume)
339 {
340 uint32_t ticks_at_event, ticks_at_start;
341 struct node_rx_pdu *node_rx;
342 uint32_t remainder_us;
343 struct lll_scan *lll;
344 struct ull_hdr *ull;
345 uint32_t remainder;
346 uint32_t ret;
347 uint32_t aa;
348
349 DEBUG_RADIO_START_O(1);
350
351 lll = p->param;
352
353 #if defined(CONFIG_BT_CENTRAL)
354 /* Check if stopped (on connection establishment race between LLL and
355 * ULL.
356 */
357 if (unlikely(lll->is_stop ||
358 (lll->conn &&
359 (lll->conn->central.initiated ||
360 lll->conn->central.cancelled)))) {
361 radio_isr_set(lll_isr_early_abort, lll);
362 radio_disable();
363
364 return 0;
365 }
366 #endif /* CONFIG_BT_CENTRAL */
367
368 /* Initialize scanning state */
369 lll->state = 0U;
370
371 radio_reset();
372
373 #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
374 radio_tx_power_set(lll->tx_pwr_lvl);
375 #else
376 radio_tx_power_set(RADIO_TXP_DEFAULT);
377 #endif
378
379 #if defined(CONFIG_BT_CTLR_ADV_EXT)
380 /* TODO: if coded we use S8? */
381 radio_phy_set(lll->phy, PHY_FLAGS_S8);
382 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, PDU_AC_LEG_PAYLOAD_SIZE_MAX,
383 RADIO_PKT_CONF_PHY(lll->phy));
384
385 lll->is_adv_ind = 0U;
386 lll->is_aux_sched = 0U;
387 #else /* !CONFIG_BT_CTLR_ADV_EXT */
388 radio_phy_set(0, 0);
389 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, PDU_AC_LEG_PAYLOAD_SIZE_MAX,
390 RADIO_PKT_CONF_PHY(RADIO_PKT_CONF_PHY_LEGACY));
391 #endif /* !CONFIG_BT_CTLR_ADV_EXT */
392
393 node_rx = ull_pdu_rx_alloc_peek(1);
394 LL_ASSERT(node_rx);
395
396 radio_pkt_rx_set(node_rx->pdu);
397
398 aa = sys_cpu_to_le32(PDU_AC_ACCESS_ADDR);
399 radio_aa_set((uint8_t *)&aa);
400 radio_crc_configure(PDU_CRC_POLYNOMIAL,
401 PDU_AC_CRC_IV);
402
403 lll_chan_set(37 + lll->chan);
404
405 radio_isr_set(isr_rx, lll);
406
407 /* setup tIFS switching */
408 if (0) {
409 } else if (lll->type ||
410 #if defined(CONFIG_BT_CENTRAL)
411 lll->conn) {
412 #else /* !CONFIG_BT_CENTRAL */
413 0) {
414 #endif /* !CONFIG_BT_CENTRAL */
415 radio_tmr_tifs_set(EVENT_IFS_US);
416 radio_switch_complete_and_tx(0, 0, 0, 0);
417 } else {
418 radio_switch_complete_and_disable();
419 }
420
421 #if defined(CONFIG_BT_CTLR_PRIVACY)
422 if (ull_filter_lll_rl_enabled()) {
423 struct lll_filter *filter =
424 ull_filter_lll_get((lll->filter_policy &
425 SCAN_FP_FILTER) != 0U);
426 uint8_t count, *irks = ull_filter_lll_irks_get(&count);
427
428 radio_filter_configure(filter->enable_bitmask,
429 filter->addr_type_bitmask,
430 (uint8_t *)filter->bdaddr);
431
432 #if defined(CONFIG_BT_CTLR_ADV_EXT)
433 radio_ar_configure(count, irks, (lll->phy << 2));
434 #else
435 radio_ar_configure(count, irks, 0);
436 #endif
437 } else
438 #endif /* CONFIG_BT_CTLR_PRIVACY */
439
440 if (IS_ENABLED(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST) && lll->filter_policy) {
441 /* Setup Radio Filter */
442 struct lll_filter *fal = ull_filter_lll_get(true);
443
444 radio_filter_configure(fal->enable_bitmask,
445 fal->addr_type_bitmask,
446 (uint8_t *)fal->bdaddr);
447 }
448
449 ticks_at_event = p->ticks_at_expire;
450 ull = HDR_LLL2ULL(lll);
451 ticks_at_event += lll_event_offset_get(ull);
452
453 ticks_at_start = ticks_at_event;
454 ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
455
456 remainder = p->remainder;
457 remainder_us = radio_tmr_start(0, ticks_at_start, remainder);
458
459 /* capture end of Rx-ed PDU, for initiator to calculate first
460 * central event or extended scan to schedule auxiliary channel
461 * reception.
462 */
463 radio_tmr_end_capture();
464
465 /* scanner always measures RSSI */
466 radio_rssi_measure();
467
468 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
469 radio_gpio_lna_setup();
470 radio_gpio_pa_lna_enable(remainder_us +
471 radio_rx_ready_delay_get(0, 0) -
472 HAL_RADIO_GPIO_LNA_OFFSET);
473 #else /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
474 ARG_UNUSED(remainder_us);
475 #endif /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
476
477 #if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
478 (EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
479 uint32_t overhead;
480
481 overhead = lll_preempt_calc(ull, (TICKER_ID_SCAN_BASE + ull_scan_lll_handle_get(lll)),
482 ticks_at_event);
483 /* check if preempt to start has changed */
484 if (overhead) {
485 LL_ASSERT_OVERHEAD(overhead);
486
487 radio_isr_set(isr_abort, lll);
488 radio_disable();
489
490 return -ECANCELED;
491 }
492 #endif /* !CONFIG_BT_CTLR_XTAL_ADVANCED */
493
494 if (!is_resume && lll->ticks_window) {
495 /* start window close timeout */
496 ret = ticker_start(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_LLL, TICKER_ID_SCAN_STOP,
497 ticks_at_event, lll->ticks_window, TICKER_NULL_PERIOD,
498 TICKER_NULL_REMAINDER, TICKER_NULL_LAZY, TICKER_NULL_SLOT,
499 ticker_stop_cb, lll, ticker_op_start_cb, (void *)__LINE__);
500 LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
501 (ret == TICKER_STATUS_BUSY));
502 }
503
504 #if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_CTLR_SCHED_ADVANCED)
505 /* calc next group in us for the anchor where first connection
506 * event to be placed.
507 */
508 if (lll->conn) {
509 static memq_link_t link;
510 static struct mayfly mfy_after_cen_offset_get = {
511 0U, 0U, &link, NULL, ull_sched_mfy_after_cen_offset_get};
512 uint32_t retval;
513
514 mfy_after_cen_offset_get.param = p;
515
516 retval = mayfly_enqueue(TICKER_USER_ID_LLL, TICKER_USER_ID_ULL_LOW, 1U,
517 &mfy_after_cen_offset_get);
518 LL_ASSERT(!retval);
519 }
520 #endif /* CONFIG_BT_CENTRAL && CONFIG_BT_CTLR_SCHED_ADVANCED */
521
522 ret = lll_prepare_done(lll);
523 LL_ASSERT(!ret);
524
525 DEBUG_RADIO_START_O(1);
526
527 return 0;
528 }
529
530 static int is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb)
531 {
532 struct lll_scan *lll = curr;
533
534 #if defined(CONFIG_BT_CENTRAL)
535 /* Irrespective of same state/role (initiator radio event) or different
536 * state/role (example, advertising radio event) that overlaps the
537 * initiator, if a CONNECT_REQ PDU has been enqueued for transmission
538 * then initiator shall not abort.
539 */
540 if (lll->conn && lll->conn->central.initiated) {
541 /* Connection Establishment initiated, do not abort */
542 return 0;
543 }
544 #endif /* CONFIG_BT_CENTRAL */
545
546 /* Check if pre-emption by a different state/role radio event */
547 if (next != curr) {
548 #if defined(CONFIG_BT_CTLR_ADV_EXT)
549 /* Resume not to be used if duration being used */
550 if (unlikely(!lll->duration_reload || lll->duration_expire))
551 #endif /* CONFIG_BT_CTLR_ADV_EXT */
552 {
553 /* Put back to resume state for continuous scanning */
554 if (!lll->ticks_window) {
555 int err;
556
557 /* Set the resume prepare function to use for
558 * resumption after the pre-emptor is done.
559 */
560 *resume_cb = resume_prepare_cb;
561
562 /* Retain HF clock */
563 err = lll_hfclock_on();
564 LL_ASSERT(err >= 0);
565
566 /* Yield to the pre-emptor, but be
567 * resumed thereafter.
568 */
569 return -EAGAIN;
570 }
571
572 /* Yield to the pre-emptor */
573 return -ECANCELED;
574 }
575 }
576
577 if (0) {
578 #if defined(CONFIG_BT_CTLR_ADV_EXT)
579 } else if (unlikely(lll->duration_reload && !lll->duration_expire)) {
580 /* Duration expired, do not continue, close and generate
581 * done event.
582 */
583 radio_isr_set(isr_done_cleanup, lll);
584 } else if (lll->state || lll->is_aux_sched) {
585 /* Do not abort scan response reception or LLL scheduled
586 * auxiliary PDU scan.
587 */
588 return 0;
589 #endif /* CONFIG_BT_CTLR_ADV_EXT */
590 } else {
591 /* Switch scan window to next radio channel */
592 radio_isr_set(isr_window, lll);
593 }
594
595 radio_disable();
596
597 return 0;
598 }
599
600 static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
601 {
602 #if defined(CONFIG_BT_CENTRAL)
603 struct lll_scan *lll = param;
604 #endif /* CONFIG_BT_CENTRAL */
605 int err;
606
607 /* NOTE: This is not a prepare being cancelled */
608 if (!prepare_param) {
609 /* Perform event abort here.
610 * After event has been cleanly aborted, clean up resources
611 * and dispatch event done.
612 */
613 if (0) {
614 #if defined(CONFIG_BT_CENTRAL)
615 } else if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT) &&
616 lll->conn && lll->conn->central.initiated) {
617 while (!radio_has_disabled()) {
618 cpu_sleep();
619 }
620 #endif /* CONFIG_BT_CENTRAL */
621 } else {
622 radio_isr_set(isr_done_cleanup, param);
623 radio_disable();
624 }
625 return;
626 }
627
628 /* NOTE: Else clean the top half preparations of the aborted event
629 * currently in preparation pipeline.
630 */
631 err = lll_hfclock_off();
632 LL_ASSERT(err >= 0);
633
634 lll_done(param);
635 }
636
637 static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
638 uint32_t remainder, uint16_t lazy, uint8_t force,
639 void *param)
640 {
641 static memq_link_t link;
642 static struct mayfly mfy = {0, 0, &link, NULL, lll_disable};
643 uint32_t ret;
644
645 mfy.param = param;
646 ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_LLL, 0,
647 &mfy);
648 LL_ASSERT(!ret);
649 }
650
651 static void ticker_op_start_cb(uint32_t status, void *param)
652 {
653 ARG_UNUSED(param);
654
655 LL_ASSERT(status == TICKER_STATUS_SUCCESS);
656 }
657
658 static void isr_rx(void *param)
659 {
660 struct node_rx_pdu *node_rx;
661 uint8_t phy_flags_rx;
662 struct lll_scan *lll;
663 struct pdu_adv *pdu;
664 uint8_t devmatch_ok;
665 uint8_t devmatch_id;
666 uint8_t irkmatch_ok;
667 uint8_t irkmatch_id;
668 uint8_t rssi_ready;
669 uint8_t trx_done;
670 uint8_t crc_ok;
671 uint8_t rl_idx;
672 bool has_adva;
673 int err = 0U;
674
675 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
676 lll_prof_latency_capture();
677 }
678
679 /* Read radio status and events */
680 trx_done = radio_is_done();
681 if (trx_done) {
682 crc_ok = radio_crc_is_valid();
683 devmatch_ok = radio_filter_has_match();
684 devmatch_id = radio_filter_match_get();
685 if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {
686 irkmatch_ok = radio_ar_has_match();
687 irkmatch_id = radio_ar_match_get();
688 } else {
689 irkmatch_ok = 0U;
690 irkmatch_id = FILTER_IDX_NONE;
691 }
692 rssi_ready = radio_rssi_is_ready();
693 phy_flags_rx = radio_phy_flags_rx_get();
694 } else {
695 crc_ok = devmatch_ok = irkmatch_ok = rssi_ready =
696 phy_flags_rx = 0U;
697 devmatch_id = irkmatch_id = FILTER_IDX_NONE;
698 }
699
700 /* Clear radio status and events */
701 lll_isr_status_reset();
702
703 lll = param;
704
705 /* No Rx */
706 if (!trx_done || !crc_ok) {
707 goto isr_rx_do_close;
708 }
709
710 node_rx = ull_pdu_rx_alloc_peek(1);
711 LL_ASSERT(node_rx);
712
713 pdu = (void *)node_rx->pdu;
714
715 if (0) {
716 #if defined(CONFIG_BT_CTLR_ADV_EXT)
717 } else if (pdu->type == PDU_ADV_TYPE_EXT_IND) {
718 has_adva = lll_scan_aux_addr_match_get(lll, pdu,
719 &devmatch_ok,
720 &devmatch_id,
721 &irkmatch_ok,
722 &irkmatch_id);
723 #endif /* !CONFIG_BT_CTLR_ADV_EXT */
724 } else {
725 has_adva = true;
726 }
727
728 #if defined(CONFIG_BT_CTLR_PRIVACY)
729 rl_idx = devmatch_ok ?
730 ull_filter_lll_rl_idx(((lll->filter_policy &
731 SCAN_FP_FILTER) != 0U),
732 devmatch_id) :
733 irkmatch_ok ? ull_filter_lll_rl_irk_idx(irkmatch_id) :
734 FILTER_IDX_NONE;
735 #else
736 rl_idx = FILTER_IDX_NONE;
737 #endif /* CONFIG_BT_CTLR_PRIVACY */
738
739 if (has_adva) {
740 bool allow;
741
742 allow = lll_scan_isr_rx_check(lll, irkmatch_ok, devmatch_ok,
743 rl_idx);
744 if (false) {
745 #if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) && \
746 defined(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST)
747 } else if (allow || lll->is_sync) {
748 devmatch_ok = allow ? 1U : 0U;
749 #endif /* CONFIG_BT_CTLR_SYNC_PERIODIC && CONFIG_BT_CTLR_FILTER_ACCEPT_LIST */
750 } else if (!allow) {
751 goto isr_rx_do_close;
752 }
753 }
754
755 err = isr_rx_pdu(lll, pdu, devmatch_ok, devmatch_id, irkmatch_ok,
756 irkmatch_id, rl_idx, rssi_ready, phy_flags_rx);
757 if (!err) {
758 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
759 lll_prof_send();
760 }
761
762 return;
763 }
764
765 isr_rx_do_close:
766 if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT) && (err == -ECANCELED)) {
767 radio_isr_set(isr_done_cleanup, lll);
768 } else {
769 radio_isr_set(isr_done, lll);
770 }
771
772 radio_disable();
773 }
774
775 static void isr_tx(void *param)
776 {
777 #if defined(CONFIG_BT_CTLR_PRIVACY) && defined(CONFIG_BT_CTLR_ADV_EXT)
778 struct lll_scan *lll = param;
779 #endif
780 struct node_rx_pdu *node_rx;
781 uint32_t hcto;
782
783 /* Clear radio status and events */
784 lll_isr_tx_status_reset();
785
786 /* Complete currently setup Rx and disable radio */
787 radio_switch_complete_and_disable();
788
789 node_rx = ull_pdu_rx_alloc_peek(1);
790 LL_ASSERT(node_rx);
791 radio_pkt_rx_set(node_rx->pdu);
792
793 /* assert if radio packet ptr is not set and radio started rx */
794 LL_ASSERT(!radio_is_ready());
795
796 #if defined(CONFIG_BT_CTLR_PRIVACY)
797 if (ull_filter_lll_rl_enabled()) {
798 uint8_t count, *irks = ull_filter_lll_irks_get(&count);
799
800 #if defined(CONFIG_BT_CTLR_ADV_EXT)
801 radio_ar_configure(count, irks, (lll->phy << 2));
802 #else
803 radio_ar_configure(count, irks, 0);
804 #endif
805 }
806 #endif /* CONFIG_BT_CTLR_PRIVACY */
807
808 /* +/- 2us active clock jitter, +1 us PPI to timer start compensation */
809 hcto = radio_tmr_tifs_base_get() + EVENT_IFS_US +
810 (EVENT_CLOCK_JITTER_US << 1) + RANGE_DELAY_US +
811 HAL_RADIO_TMR_START_DELAY_US;
812 hcto += radio_rx_chain_delay_get(0, 0);
813 hcto += addr_us_get(0);
814 hcto -= radio_tx_chain_delay_get(0, 0);
815
816 radio_tmr_hcto_configure(hcto);
817
818 radio_rssi_measure();
819
820 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
821 radio_gpio_lna_setup();
822 radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() + EVENT_IFS_US - 4 -
823 radio_tx_chain_delay_get(0, 0) -
824 HAL_RADIO_GPIO_LNA_OFFSET);
825 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
826
827 radio_isr_set(isr_rx, param);
828 }
829
830 static void isr_common_done(void *param)
831 {
832 struct node_rx_pdu *node_rx;
833 struct lll_scan *lll;
834
835 /* Clear radio status and events */
836 lll_isr_status_reset();
837
838 /* Reset scanning state */
839 lll = param;
840 lll->state = 0U;
841
842 #if defined(CONFIG_BT_CTLR_ADV_EXT)
843 lll->is_adv_ind = 0U;
844 lll->is_aux_sched = 0U;
845 #endif /* CONFIG_BT_CTLR_ADV_EXT */
846
847 /* setup tIFS switching */
848 if (0) {
849 /* TODO: Add Rx-Rx switch usecase improvement in the future */
850 } else if (lll->type ||
851 #if defined(CONFIG_BT_CENTRAL)
852 lll->conn) {
853 #else /* !CONFIG_BT_CENTRAL */
854 0) {
855 #endif /* !CONFIG_BT_CENTRAL */
856 radio_tmr_tifs_set(EVENT_IFS_US);
857 radio_switch_complete_and_tx(0, 0, 0, 0);
858 } else {
859 radio_switch_complete_and_disable();
860 }
861
862 node_rx = ull_pdu_rx_alloc_peek(1);
863 LL_ASSERT(node_rx);
864 radio_pkt_rx_set(node_rx->pdu);
865
866 #if defined(CONFIG_BT_CTLR_PRIVACY)
867 if (ull_filter_lll_rl_enabled()) {
868 uint8_t count, *irks = ull_filter_lll_irks_get(&count);
869
870 #if defined(CONFIG_BT_CTLR_ADV_EXT)
871 radio_ar_configure(count, irks, (lll->phy << 2));
872 #else
873 ARG_UNUSED(lll);
874 radio_ar_configure(count, irks, 0);
875 #endif
876 }
877 #endif /* CONFIG_BT_CTLR_PRIVACY */
878
879 radio_rssi_measure();
880
881 radio_isr_set(isr_rx, param);
882 }
883
884 static void isr_done(void *param)
885 {
886 isr_common_done(param);
887
888 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
889 uint32_t start_us = radio_tmr_start_now(0);
890
891 radio_gpio_lna_setup();
892 radio_gpio_pa_lna_enable(start_us +
893 radio_rx_ready_delay_get(0, 0) -
894 HAL_RADIO_GPIO_LNA_OFFSET);
895 #else /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
896 radio_rx_enable();
897 #endif /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
898
899 /* capture end of Rx-ed PDU, for initiator to calculate first
900 * central event.
901 */
902 radio_tmr_end_capture();
903 }
904
905 static void isr_window(void *param)
906 {
907 uint32_t remainder_us;
908 struct lll_scan *lll;
909
910 isr_common_done(param);
911
912 lll = param;
913
914 /* Next radio channel to scan, round-robin 37, 38, and 39. */
915 if (++lll->chan == ADV_CHAN_MAX) {
916 lll->chan = 0U;
917 }
918 lll_chan_set(37 + lll->chan);
919
920 #if defined(CONFIG_BT_CENTRAL) || defined(CONFIG_BT_CTLR_ADV_EXT)
921 #if defined(CONFIG_BT_CENTRAL)
922 bool is_sched_advanced = IS_ENABLED(CONFIG_BT_CTLR_SCHED_ADVANCED) &&
923 lll->conn && lll->conn_win_offset_us;
924 uint32_t ticks_anchor_prev;
925
926 if (is_sched_advanced) {
927 /* Get the ticks_anchor when the offset to free time space for
928 * a new central event was last calculated at the start of the
929 * initiator window. This can be either the previous full window
930 * start or remainder resume start of the continuous initiator
931 * after it was preempted.
932 */
933 ticks_anchor_prev = radio_tmr_start_get();
934 } else {
935 ticks_anchor_prev = 0U;
936 }
937 #endif /* CONFIG_BT_CENTRAL */
938
939 uint32_t ticks_at_start;
940
941 ticks_at_start = ticker_ticks_now_get() +
942 HAL_TICKER_CNTR_CMP_OFFSET_MIN;
943 remainder_us = radio_tmr_start_tick(0, ticks_at_start);
944 #else /* !CONFIG_BT_CENTRAL && !CONFIG_BT_CTLR_ADV_EXT */
945
946 remainder_us = radio_tmr_start_now(0);
947 #endif /* !CONFIG_BT_CENTRAL && !CONFIG_BT_CTLR_ADV_EXT */
948
949 /* capture end of Rx-ed PDU, for initiator to calculate first
950 * central event.
951 */
952 radio_tmr_end_capture();
953
954 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
955 radio_gpio_lna_setup();
956 radio_gpio_pa_lna_enable(remainder_us +
957 radio_rx_ready_delay_get(0, 0) -
958 HAL_RADIO_GPIO_LNA_OFFSET);
959 #else /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
960 ARG_UNUSED(remainder_us);
961 #endif /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
962
963 #if defined(CONFIG_BT_CENTRAL)
964 if (is_sched_advanced) {
965 uint32_t ticks_anchor_new, ticks_delta, ticks_delta_us;
966
967 /* Calculation to reduce the conn_win_offset_us, as a new
968 * window is started here and the reference ticks_anchor is
969 * now at the start of this new window.
970 */
971 ticks_anchor_new = radio_tmr_start_get();
972 ticks_delta = ticker_ticks_diff_get(ticks_anchor_new,
973 ticks_anchor_prev);
974 ticks_delta_us = HAL_TICKER_TICKS_TO_US(ticks_delta);
975
976 /* Underflow is accepted, as it will be corrected at the time of
977 * connection establishment by incrementing it in connection
978 * interval units until it is in the future.
979 */
980 lll->conn_win_offset_us -= ticks_delta_us;
981 }
982 #endif /* CONFIG_BT_CENTRAL */
983 }
984
985 #if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
986 (EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
987 static void isr_abort(void *param)
988 {
989 /* Clear radio status and events */
990 lll_isr_status_reset();
991
992 /* Disable Rx filters when aborting scan prepare */
993 radio_filter_disable();
994
995 #if defined(CONFIG_BT_CTLR_ADV_EXT)
996 struct event_done_extra *extra;
997
998 /* Generate Scan done events so that duration and max expiry is
999 * detected in ULL.
1000 */
1001 extra = ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_SCAN);
1002 LL_ASSERT(extra);
1003 #endif /* CONFIG_BT_CTLR_ADV_EXT */
1004
1005 lll_isr_cleanup(param);
1006 }
1007 #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED &&
1008 * (EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
1009 */
1010
1011 static void isr_done_cleanup(void *param)
1012 {
1013 struct lll_scan *lll;
1014 bool is_resume;
1015
1016 /* Clear radio status and events */
1017 lll_isr_status_reset();
1018
1019 /* Under race between duration expire, is_stop is set in this function,
1020 * and event preemption, prevent generating duplicate scan done events.
1021 */
1022 if (lll_is_done(param, &is_resume)) {
1023 return;
1024 }
1025
1026 /* Disable Rx filters when yielding or stopping scan window */
1027 radio_filter_disable();
1028
1029 /* Next window to use next advertising radio channel */
1030 lll = param;
1031 if (++lll->chan == ADV_CHAN_MAX) {
1032 lll->chan = 0U;
1033 }
1034
1035 /* Scanner stop can expire while here in this ISR.
1036 * Deferred attempt to stop can fail as it would have
1037 * expired, hence ignore failure.
1038 */
1039 (void)ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_LLL,
1040 TICKER_ID_SCAN_STOP, NULL, NULL);
1041
1042 #if defined(CONFIG_BT_CTLR_SCAN_INDICATION)
1043 struct node_rx_pdu *node_rx;
1044
1045 /* Check if there are enough free node rx available:
1046 * 1. For generating this scan indication
1047 * 2. Keep one available free for reception of ACL connection Rx data
1048 * 3. Keep one available free for reception on ACL connection to NACK
1049 * the PDU
1050 */
1051 node_rx = ull_pdu_rx_alloc_peek(3);
1052 if (node_rx) {
1053 ull_pdu_rx_alloc();
1054
1055 /* TODO: add other info by defining a payload struct */
1056 node_rx->hdr.type = NODE_RX_TYPE_SCAN_INDICATION;
1057
1058 ull_rx_put_sched(node_rx->hdr.link, node_rx);
1059 }
1060 #endif /* CONFIG_BT_CTLR_SCAN_INDICATION */
1061
1062 #if defined(CONFIG_BT_HCI_MESH_EXT)
1063 if (_radio.advertiser.is_enabled && _radio.advertiser.is_mesh &&
1064 !_radio.advertiser.retry) {
1065 mayfly_mesh_stop(NULL);
1066 }
1067 #endif /* CONFIG_BT_HCI_MESH_EXT */
1068
1069 #if defined(CONFIG_BT_CTLR_ADV_EXT)
1070 /* If continuous scan then do not generate scan done when radio event
1071 * has been placed into prepare pipeline as a resume radio event.
1072 */
1073 if (!is_resume) {
1074 struct event_done_extra *extra;
1075
1076 /* Generate Scan done events so that duration and max expiry is
1077 * detected in ULL.
1078 */
1079 extra = ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_SCAN);
1080 LL_ASSERT(extra);
1081 }
1082
1083 /* Prevent scan events in pipeline from being scheduled if duration has
1084 * expired.
1085 */
1086 if (unlikely(lll->duration_reload && !lll->duration_expire)) {
1087 lll->is_stop = 1U;
1088 }
1089
1090 if (lll->is_aux_sched) {
1091 struct node_rx_pdu *node_rx2;
1092
1093 lll->is_aux_sched = 0U;
1094
1095 node_rx2 = ull_pdu_rx_alloc();
1096 LL_ASSERT(node_rx2);
1097
1098 node_rx2->hdr.type = NODE_RX_TYPE_EXT_AUX_RELEASE;
1099
1100 node_rx2->rx_ftr.param = lll;
1101
1102 ull_rx_put_sched(node_rx2->hdr.link, node_rx2);
1103 }
1104 #endif /* CONFIG_BT_CTLR_ADV_EXT */
1105
1106 lll_isr_cleanup(param);
1107 }
1108
1109 static inline int isr_rx_pdu(struct lll_scan *lll, struct pdu_adv *pdu_adv_rx,
1110 uint8_t devmatch_ok, uint8_t devmatch_id,
1111 uint8_t irkmatch_ok, uint8_t irkmatch_id,
1112 uint8_t rl_idx, uint8_t rssi_ready,
1113 uint8_t phy_flags_rx)
1114 {
1115 bool dir_report = false;
1116
1117 if (0) {
1118 #if defined(CONFIG_BT_CENTRAL)
1119 /* Initiator */
1120 /* Note: connectable ADV_EXT_IND is handled as any other ADV_EXT_IND
1121 * because we need to receive AUX_ADV_IND anyway.
1122 */
1123 } else if (lll->conn && !lll->conn->central.cancelled &&
1124 (pdu_adv_rx->type != PDU_ADV_TYPE_EXT_IND) &&
1125 isr_scan_init_check(lll, pdu_adv_rx, rl_idx)) {
1126 struct lll_conn *lll_conn;
1127 struct node_rx_ftr *ftr;
1128 struct node_rx_pdu *rx;
1129 struct pdu_adv *pdu_tx;
1130 uint32_t conn_space_us;
1131 struct ull_hdr *ull;
1132 uint32_t pdu_end_us;
1133 uint8_t init_tx_addr;
1134 uint8_t *init_addr;
1135 #if defined(CONFIG_BT_CTLR_PRIVACY)
1136 bt_addr_t *lrpa;
1137 #endif /* CONFIG_BT_CTLR_PRIVACY */
1138
1139 if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
1140 rx = ull_pdu_rx_alloc_peek(4);
1141 } else {
1142 rx = ull_pdu_rx_alloc_peek(3);
1143 }
1144
1145 if (!rx) {
1146 return -ENOBUFS;
1147 }
1148
1149 pdu_end_us = radio_tmr_end_get();
1150 if (!lll->ticks_window) {
1151 uint32_t scan_interval_us;
1152
1153 /* FIXME: is this correct for continuous scanning? */
1154 scan_interval_us = lll->interval * SCAN_INT_UNIT_US;
1155 pdu_end_us %= scan_interval_us;
1156 }
1157 ull = HDR_LLL2ULL(lll);
1158 if (pdu_end_us > (HAL_TICKER_TICKS_TO_US(ull->ticks_slot) -
1159 EVENT_IFS_US - 352 - EVENT_OVERHEAD_START_US -
1160 EVENT_TICKER_RES_MARGIN_US)) {
1161 return -ETIME;
1162 }
1163
1164 radio_switch_complete_and_disable();
1165
1166 /* Acquire the connection context */
1167 lll_conn = lll->conn;
1168
1169 #if defined(CONFIG_BT_CTLR_PRIVACY)
1170 lrpa = ull_filter_lll_lrpa_get(rl_idx);
1171 if (lll->rpa_gen && lrpa) {
1172 init_tx_addr = 1;
1173 init_addr = lrpa->val;
1174 } else {
1175 #else
1176 if (1) {
1177 #endif
1178 init_tx_addr = lll->init_addr_type;
1179 init_addr = lll->init_addr;
1180 }
1181
1182 pdu_tx = (void *)radio_pkt_scratch_get();
1183
1184 lll_scan_prepare_connect_req(lll, pdu_tx, PHY_LEGACY,
1185 PHY_FLAGS_S8, pdu_adv_rx->tx_addr,
1186 pdu_adv_rx->adv_ind.addr,
1187 init_tx_addr, init_addr,
1188 &conn_space_us);
1189
1190 radio_pkt_tx_set(pdu_tx);
1191
1192 /* assert if radio packet ptr is not set and radio started tx */
1193 LL_ASSERT(!radio_is_ready());
1194
1195 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1196 lll_prof_cputime_capture();
1197 }
1198
1199 radio_isr_set(isr_done_cleanup, lll);
1200
1201 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
1202 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1203 /* PA/LNA enable is overwriting packet end
1204 * used in ISR profiling, hence back it up
1205 * for later use.
1206 */
1207 lll_prof_radio_end_backup();
1208 }
1209 radio_gpio_pa_setup();
1210 radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
1211 EVENT_IFS_US -
1212 radio_rx_chain_delay_get(0, 0) -
1213 HAL_RADIO_GPIO_PA_OFFSET);
1214 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
1215
1216 #if defined(CONFIG_BT_CTLR_CONN_RSSI)
1217 if (rssi_ready) {
1218 lll_conn->rssi_latest = radio_rssi_get();
1219 }
1220 #endif /* CONFIG_BT_CTLR_CONN_RSSI */
1221
1222 /* block CPU so that there is no CRC error on pdu tx,
1223 * this is only needed if we want the CPU to sleep.
1224 * while(!radio_has_disabled())
1225 * {cpu_sleep();}
1226 * radio_status_reset();
1227 */
1228
1229 /* Stop further connection initiation */
1230 /* FIXME: for extended connection initiation, handle reset on
1231 * event aborted before connect_rsp is received.
1232 */
1233 lll->conn->central.initiated = 1U;
1234
1235 /* Stop further initiating events */
1236 lll->is_stop = 1U;
1237
1238 rx = ull_pdu_rx_alloc();
1239
1240 rx->hdr.type = NODE_RX_TYPE_CONNECTION;
1241 rx->hdr.handle = 0xffff;
1242
1243 uint8_t pdu_adv_rx_chan_sel = pdu_adv_rx->chan_sel;
1244 memcpy(rx->pdu, pdu_tx, (offsetof(struct pdu_adv, connect_ind) +
1245 sizeof(struct pdu_adv_connect_ind)));
1246
1247 /* Overwrite the sent chan sel with received chan sel, when
1248 * giving this PDU to the higher layer. */
1249 pdu_adv_rx = (void *)rx->pdu;
1250 pdu_adv_rx->chan_sel = pdu_adv_rx_chan_sel;
1251
1252 ftr = &(rx->rx_ftr);
1253
1254 ftr->param = lll;
1255 ftr->ticks_anchor = radio_tmr_start_get();
1256 ftr->radio_end_us = conn_space_us;
1257
1258 #if defined(CONFIG_BT_CTLR_PRIVACY)
1259 ftr->rl_idx = irkmatch_ok ? rl_idx : FILTER_IDX_NONE;
1260 ftr->lrpa_used = lll->rpa_gen && lrpa;
1261 #endif /* CONFIG_BT_CTLR_PRIVACY */
1262
1263 if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
1264 ftr->extra = ull_pdu_rx_alloc();
1265 }
1266
1267 ull_rx_put_sched(rx->hdr.link, rx);
1268
1269 return 0;
1270 #endif /* CONFIG_BT_CENTRAL */
1271
1272 /* Active scanner */
1273 } else if (((pdu_adv_rx->type == PDU_ADV_TYPE_ADV_IND) ||
1274 (pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND)) &&
1275 (pdu_adv_rx->len >= offsetof(struct pdu_adv_adv_ind, data)) &&
1276 (pdu_adv_rx->len <= sizeof(struct pdu_adv_adv_ind)) &&
1277 lll->type && !lll->state &&
1278 #if defined(CONFIG_BT_CENTRAL)
1279 !lll->conn) {
1280 #else /* !CONFIG_BT_CENTRAL */
1281 1) {
1282 #endif /* !CONFIG_BT_CENTRAL */
1283 struct pdu_adv *pdu_tx;
1284 #if defined(CONFIG_BT_CTLR_PRIVACY)
1285 bt_addr_t *lrpa;
1286 #endif /* CONFIG_BT_CTLR_PRIVACY */
1287 int err;
1288
1289 /* setup tIFS switching */
1290 radio_tmr_tifs_set(EVENT_IFS_US);
1291 radio_switch_complete_and_rx(0);
1292
1293 /* save the adv packet */
1294 err = isr_rx_scan_report(lll, devmatch_ok, irkmatch_ok, rl_idx,
1295 rssi_ready, phy_flags_rx, false);
1296 if (err) {
1297 return err;
1298 }
1299
1300 /* prepare the scan request packet */
1301 pdu_tx = (void *)radio_pkt_scratch_get();
1302 pdu_tx->type = PDU_ADV_TYPE_SCAN_REQ;
1303 pdu_tx->rx_addr = pdu_adv_rx->tx_addr;
1304 pdu_tx->len = sizeof(struct pdu_adv_scan_req);
1305 #if defined(CONFIG_BT_CTLR_PRIVACY)
1306 lrpa = ull_filter_lll_lrpa_get(rl_idx);
1307 if (lll->rpa_gen && lrpa) {
1308 pdu_tx->tx_addr = 1;
1309 memcpy(&pdu_tx->scan_req.scan_addr[0], lrpa->val,
1310 BDADDR_SIZE);
1311 } else {
1312 #else
1313 if (1) {
1314 #endif /* CONFIG_BT_CTLR_PRIVACY */
1315 pdu_tx->tx_addr = lll->init_addr_type;
1316 memcpy(&pdu_tx->scan_req.scan_addr[0],
1317 &lll->init_addr[0], BDADDR_SIZE);
1318 }
1319 memcpy(&pdu_tx->scan_req.adv_addr[0],
1320 &pdu_adv_rx->adv_ind.addr[0], BDADDR_SIZE);
1321
1322 radio_pkt_tx_set(pdu_tx);
1323
1324 /* assert if radio packet ptr is not set and radio started tx */
1325 LL_ASSERT(!radio_is_ready());
1326
1327 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1328 lll_prof_cputime_capture();
1329
1330 }
1331
1332 /* capture end of Tx-ed PDU, used to calculate HCTO. */
1333 radio_tmr_end_capture();
1334
1335 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
1336 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1337 /* PA/LNA enable is overwriting packet end
1338 * used in ISR profiling, hence back it up
1339 * for later use.
1340 */
1341 lll_prof_radio_end_backup();
1342 }
1343
1344 radio_gpio_pa_setup();
1345 radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
1346 EVENT_IFS_US -
1347 radio_rx_chain_delay_get(0, 0) -
1348 HAL_RADIO_GPIO_PA_OFFSET);
1349 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
1350
1351 /* switch scanner state to active */
1352 lll->state = 1U;
1353
1354 #if defined(CONFIG_BT_CTLR_ADV_EXT)
1355 if (pdu_adv_rx->type == PDU_ADV_TYPE_ADV_IND) {
1356 lll->is_adv_ind = 1U;
1357 }
1358 #endif /* CONFIG_BT_CTLR_ADV_EXT */
1359
1360 radio_isr_set(isr_tx, lll);
1361
1362 return 0;
1363 }
1364 /* Passive scanner or scan responses */
1365 else if (((((pdu_adv_rx->type == PDU_ADV_TYPE_ADV_IND) ||
1366 (pdu_adv_rx->type == PDU_ADV_TYPE_NONCONN_IND) ||
1367 (pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND)) &&
1368 (pdu_adv_rx->len >= offsetof(struct pdu_adv_adv_ind, data)) &&
1369 (pdu_adv_rx->len <= sizeof(struct pdu_adv_adv_ind))) ||
1370 ((pdu_adv_rx->type == PDU_ADV_TYPE_DIRECT_IND) &&
1371 (pdu_adv_rx->len == sizeof(struct pdu_adv_direct_ind)) &&
1372 (/* allow directed adv packets addressed to this device */
1373 isr_scan_tgta_check(lll, false, pdu_adv_rx->rx_addr,
1374 pdu_adv_rx->direct_ind.tgt_addr,
1375 rl_idx, &dir_report))) ||
1376 #if defined(CONFIG_BT_CTLR_ADV_EXT)
1377 ((pdu_adv_rx->type == PDU_ADV_TYPE_EXT_IND) &&
1378 lll->phy && lll_scan_ext_tgta_check(lll, true, false,
1379 pdu_adv_rx, rl_idx,
1380 &dir_report)) ||
1381 #endif /* CONFIG_BT_CTLR_ADV_EXT */
1382 ((pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_RSP) &&
1383 (pdu_adv_rx->len >= offsetof(struct pdu_adv_scan_rsp, data)) &&
1384 (pdu_adv_rx->len <= sizeof(struct pdu_adv_scan_rsp)) &&
1385 (lll->state != 0U) &&
1386 isr_scan_rsp_adva_matches(pdu_adv_rx))) &&
1387 (pdu_adv_rx->len != 0) &&
1388 #if defined(CONFIG_BT_CENTRAL)
1389 /* Note: ADV_EXT_IND is allowed here even if initiating
1390 * because we still need to get AUX_ADV_IND as for any
1391 * other ADV_EXT_IND.
1392 */
1393 (!lll->conn || (pdu_adv_rx->type == PDU_ADV_TYPE_EXT_IND))) {
1394 #else /* !CONFIG_BT_CENTRAL */
1395 1) {
1396 #endif /* !CONFIG_BT_CENTRAL */
1397 uint32_t err;
1398
1399 /* save the scan response packet */
1400 err = isr_rx_scan_report(lll, devmatch_ok, irkmatch_ok, rl_idx,
1401 rssi_ready, phy_flags_rx, dir_report);
1402 if (err) {
1403 /* Auxiliary PDU LLL scanning has been setup */
1404 if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) &&
1405 (err == -EBUSY)) {
1406 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1407 lll_prof_cputime_capture();
1408 }
1409
1410 return 0;
1411 }
1412
1413 return err;
1414 }
1415 }
1416 /* invalid PDU */
1417 else {
1418 /* ignore and close this rx/tx chain ( code below ) */
1419 return -EINVAL;
1420 }
1421
1422 return -ECANCELED;
1423 }
1424
1425 #if defined(CONFIG_BT_CENTRAL)
1426 static inline bool isr_scan_init_check(const struct lll_scan *lll,
1427 const struct pdu_adv *pdu,
1428 uint8_t rl_idx)
1429 {
1430 return ((((lll->filter_policy & SCAN_FP_FILTER) != 0U) ||
1431 lll_scan_adva_check(lll, pdu->tx_addr, pdu->adv_ind.addr,
1432 rl_idx)) &&
1433 (((pdu->type == PDU_ADV_TYPE_ADV_IND) &&
1434 (pdu->len >= offsetof(struct pdu_adv_adv_ind, data)) &&
1435 (pdu->len <= sizeof(struct pdu_adv_adv_ind))) ||
1436 ((pdu->type == PDU_ADV_TYPE_DIRECT_IND) &&
1437 (pdu->len == sizeof(struct pdu_adv_direct_ind)) &&
1438 (/* allow directed adv packets addressed to this device */
1439 isr_scan_tgta_check(lll, true, pdu->rx_addr,
1440 pdu->direct_ind.tgt_addr, rl_idx,
1441 NULL)))));
1442 }
1443 #endif /* CONFIG_BT_CENTRAL */
1444
1445 static bool isr_scan_tgta_check(const struct lll_scan *lll, bool init,
1446 uint8_t addr_type, const uint8_t *addr,
1447 uint8_t rl_idx, bool *dir_report)
1448 {
1449 #if defined(CONFIG_BT_CTLR_PRIVACY)
1450 if (ull_filter_lll_rl_addr_resolve(addr_type, addr, rl_idx)) {
1451 return true;
1452 } else if (init && lll->rpa_gen && ull_filter_lll_lrpa_get(rl_idx)) {
1453 /* Initiator generating RPAs, and could not resolve TargetA:
1454 * discard
1455 */
1456 return false;
1457 }
1458 #endif /* CONFIG_BT_CTLR_PRIVACY */
1459
1460 return (((lll->init_addr_type == addr_type) &&
1461 !memcmp(lll->init_addr, addr, BDADDR_SIZE))) ||
1462 /* allow directed adv packets where TargetA address
1463 * is resolvable private address (scanner only)
1464 */
1465 isr_scan_tgta_rpa_check(lll, addr_type, addr, dir_report);
1466 }
1467
1468 static inline bool isr_scan_tgta_rpa_check(const struct lll_scan *lll,
1469 uint8_t addr_type,
1470 const uint8_t *addr,
1471 bool *const dir_report)
1472 {
1473 if (((lll->filter_policy & SCAN_FP_EXT) != 0U) && (addr_type != 0U) &&
1474 ((addr[5] & 0xc0) == 0x40)) {
1475
1476 if (dir_report) {
1477 *dir_report = true;
1478 }
1479
1480 return true;
1481 }
1482
1483 return false;
1484 }
1485
1486 static inline bool isr_scan_rsp_adva_matches(struct pdu_adv *srsp)
1487 {
1488 struct pdu_adv *sreq = (void *)radio_pkt_scratch_get();
1489
1490 return ((sreq->rx_addr == srsp->tx_addr) &&
1491 (memcmp(&sreq->scan_req.adv_addr[0],
1492 &srsp->scan_rsp.addr[0], BDADDR_SIZE) == 0));
1493 }
1494
1495 static int isr_rx_scan_report(struct lll_scan *lll, uint8_t devmatch_ok,
1496 uint8_t irkmatch_ok, uint8_t rl_idx,
1497 uint8_t rssi_ready, uint8_t phy_flags_rx,
1498 bool dir_report)
1499 {
1500 struct node_rx_pdu *node_rx;
1501 int err = 0;
1502
1503 node_rx = ull_pdu_rx_alloc_peek(3);
1504 if (!node_rx) {
1505 return -ENOBUFS;
1506 }
1507 ull_pdu_rx_alloc();
1508
1509 /* Prepare the report (adv or scan resp) */
1510 node_rx->hdr.handle = 0xffff;
1511 if (0) {
1512
1513 #if defined(CONFIG_BT_HCI_MESH_EXT)
1514 } else if (_radio.advertiser.is_enabled &&
1515 _radio.advertiser.is_mesh) {
1516 node_rx->hdr.type = NODE_RX_TYPE_MESH_REPORT;
1517 #endif /* CONFIG_BT_HCI_MESH_EXT */
1518
1519 #if defined(CONFIG_BT_CTLR_ADV_EXT)
1520 } else if (lll->phy) {
1521 struct pdu_adv *pdu_adv_rx;
1522
1523 switch (lll->phy) {
1524 case PHY_1M:
1525 node_rx->hdr.type = NODE_RX_TYPE_EXT_1M_REPORT;
1526 break;
1527
1528 case PHY_CODED:
1529 node_rx->hdr.type = NODE_RX_TYPE_EXT_CODED_REPORT;
1530 break;
1531
1532 default:
1533 LL_ASSERT(0);
1534 break;
1535 }
1536
1537 pdu_adv_rx = (void *)node_rx->pdu;
1538 switch (pdu_adv_rx->type) {
1539 case PDU_ADV_TYPE_SCAN_RSP:
1540 if (lll->is_adv_ind) {
1541 pdu_adv_rx->type =
1542 PDU_ADV_TYPE_ADV_IND_SCAN_RSP;
1543 }
1544 break;
1545
1546 case PDU_ADV_TYPE_EXT_IND:
1547 {
1548 struct node_rx_ftr *ftr;
1549
1550 ftr = &(node_rx->rx_ftr);
1551 ftr->param = lll;
1552 ftr->ticks_anchor = radio_tmr_start_get();
1553 ftr->radio_end_us =
1554 radio_tmr_end_get() -
1555 radio_rx_chain_delay_get(lll->phy,
1556 phy_flags_rx);
1557 ftr->phy_flags = phy_flags_rx;
1558 ftr->aux_lll_sched =
1559 lll_scan_aux_setup(pdu_adv_rx, lll->phy,
1560 phy_flags_rx,
1561 lll_scan_aux_isr_aux_setup,
1562 lll);
1563 if (ftr->aux_lll_sched) {
1564 lll->is_aux_sched = 1U;
1565 err = -EBUSY;
1566 }
1567 }
1568 break;
1569 }
1570 #endif /* CONFIG_BT_CTLR_ADV_EXT */
1571 } else {
1572 node_rx->hdr.type = NODE_RX_TYPE_REPORT;
1573 }
1574
1575 node_rx->rx_ftr.rssi = (rssi_ready) ? radio_rssi_get() :
1576 BT_HCI_LE_RSSI_NOT_AVAILABLE;
1577 #if defined(CONFIG_BT_CTLR_PRIVACY)
1578 /* save the resolving list index. */
1579 node_rx->rx_ftr.rl_idx = irkmatch_ok ? rl_idx : FILTER_IDX_NONE;
1580
1581 #if defined(CONFIG_BT_CTLR_ADV_EXT)
1582 node_rx->rx_ftr.direct_resolved = (rl_idx != FILTER_IDX_NONE);
1583 #endif /* CONFIG_BT_CTLR_ADV_EXT */
1584 #endif /* CONFIG_BT_CTLR_PRIVACY */
1585
1586 #if defined(CONFIG_BT_CTLR_EXT_SCAN_FP)
1587 /* save the directed adv report flag */
1588 node_rx->rx_ftr.direct = dir_report;
1589 #endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */
1590
1591 #if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) && \
1592 defined(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST)
1593 node_rx->rx_ftr.devmatch = devmatch_ok;
1594 #endif /* CONFIG_BT_CTLR_SYNC_PERIODIC && CONFIG_BT_CTLR_FILTER_ACCEPT_LIST */
1595
1596 #if defined(CONFIG_BT_HCI_MESH_EXT)
1597 if (node_rx->hdr.type == NODE_RX_TYPE_MESH_REPORT) {
1598 /* save channel and anchor point ticks. */
1599 node_rx->rx_ftr.chan = _radio.scanner.chan - 1;
1600 node_rx->rx_ftr.ticks_anchor = _radio.ticks_anchor;
1601 }
1602 #endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */
1603
1604 ull_rx_put_sched(node_rx->hdr.link, node_rx);
1605
1606 return err;
1607 }
1608