1 /*
2 * Copyright (c) 2018-2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdint.h>
8 #include <stddef.h>
9
10 #include <zephyr/sys/byteorder.h>
11 #include <zephyr/bluetooth/hci_types.h>
12 #include <soc.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/mem.h"
21 #include "util/memq.h"
22 #include "util/dbuf.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_chan.h"
32 #include "lll_df_types.h"
33 #include "lll_conn.h"
34 #include "lll_adv_types.h"
35 #include "lll_adv.h"
36 #include "lll_adv_pdu.h"
37 #include "lll_adv_aux.h"
38 #include "lll_adv_sync.h"
39 #include "lll_filter.h"
40
41 #include "lll_internal.h"
42 #include "lll_tim_internal.h"
43 #include "lll_adv_internal.h"
44 #include "lll_prof_internal.h"
45
46 #include "ull_adv_types.h"
47
48 #include "hal/debug.h"
49
50 static int init_reset(void);
51 static int prepare_cb(struct lll_prepare_param *p);
52 #if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) || \
53 defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
54 static int aux_ptr_get(struct pdu_adv *pdu, struct pdu_adv_aux_ptr **aux_ptr);
55 #endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO ||
56 * CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK
57 */
58 #if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
59 static void isr_early_abort(void *param);
60 #endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
61 static void isr_done(void *param);
62 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
63 static void isr_tx_chain(void *param);
64 static void chain_pdu_aux_ptr_chan_idx_set(struct lll_adv_aux *lll);
65 static void aux_ptr_chan_idx_set(struct lll_adv_aux *lll, struct pdu_adv *pdu);
66 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
67 static void isr_tx_rx(void *param);
68 static void isr_rx(void *param);
69 static inline int isr_rx_pdu(struct lll_adv_aux *lll_aux, uint8_t phy_flags_rx,
70 uint8_t devmatch_ok, uint8_t devmatch_id,
71 uint8_t irkmatch_ok, uint8_t irkmatch_id,
72 uint8_t rssi_ready);
73 #if defined(CONFIG_BT_PERIPHERAL)
74 static struct pdu_adv *init_connect_rsp_pdu(struct pdu_adv *pdu_ci);
75 static void isr_tx_connect_rsp(void *param);
76 #endif /* CONFIG_BT_PERIPHERAL */
77
lll_adv_aux_init(void)78 int lll_adv_aux_init(void)
79 {
80 int err;
81
82 err = init_reset();
83 if (err) {
84 return err;
85 }
86
87 return 0;
88 }
89
lll_adv_aux_reset(void)90 int lll_adv_aux_reset(void)
91 {
92 int err;
93
94 err = init_reset();
95 if (err) {
96 return err;
97 }
98
99 return 0;
100 }
101
lll_adv_aux_prepare(void * param)102 void lll_adv_aux_prepare(void *param)
103 {
104 int err;
105
106 err = lll_hfclock_on();
107 LL_ASSERT(err >= 0);
108
109 err = lll_prepare(lll_is_abort_cb, lll_abort_cb, prepare_cb, 0, param);
110 LL_ASSERT(!err || err == -EINPROGRESS);
111 }
112
lll_adv_aux_pback_prepare(void * param)113 void lll_adv_aux_pback_prepare(void *param)
114 {
115 }
116
init_reset(void)117 static int init_reset(void)
118 {
119 return 0;
120 }
121
prepare_cb(struct lll_prepare_param * p)122 static int prepare_cb(struct lll_prepare_param *p)
123 {
124 uint32_t ticks_at_event, ticks_at_start;
125 struct pdu_adv_com_ext_adv *com_hdr;
126 struct pdu_adv *sec_pdu;
127 struct lll_adv_aux *lll;
128 struct lll_adv *lll_adv;
129 struct ull_hdr *ull;
130 uint32_t remainder;
131 uint32_t start_us;
132 uint8_t chan_idx;
133 uint8_t phy_s;
134 uint32_t ret;
135 uint8_t upd;
136 uint32_t aa;
137
138 DEBUG_RADIO_START_A(1);
139
140 lll = p->param;
141 lll_adv = lll->adv;
142
143 /* FIXME: get latest only when primary PDU without Aux PDUs */
144 upd = 0U;
145 sec_pdu = lll_adv_aux_data_latest_get(lll, &upd);
146 LL_ASSERT(sec_pdu);
147
148 #if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
149 struct ll_adv_aux_set *aux;
150
151 /* Get reference to extended header */
152 com_hdr = (void *)&sec_pdu->adv_ext_ind;
153
154 aux = HDR_LLL2ULL(lll);
155 chan_idx = lll_chan_sel_2(lll->data_chan_counter, aux->data_chan_id,
156 aux->chm[aux->chm_first].data_chan_map,
157 aux->chm[aux->chm_first].data_chan_count);
158
159 #else /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
160 struct pdu_adv_aux_ptr *aux_ptr;
161 struct pdu_adv *pri_pdu;
162 int err;
163
164 /* Get reference to primary PDU */
165 pri_pdu = lll_adv_data_curr_get(lll_adv);
166 LL_ASSERT(pri_pdu->type == PDU_ADV_TYPE_EXT_IND);
167
168 /* Get reference to common extended header */
169 com_hdr = (void *)&pri_pdu->adv_ext_ind;
170
171 /* Get reference to aux pointer structure */
172 err = aux_ptr_get(pri_pdu, &aux_ptr);
173 LL_ASSERT(!err);
174
175 /* Abort if no aux_ptr filled */
176 if (unlikely(!aux_ptr || !PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr))) {
177 radio_isr_set(isr_early_abort, lll);
178 radio_disable();
179
180 return 0;
181 }
182
183 chan_idx = aux_ptr->chan_idx;
184 #endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
185
186 /* Increment counter, for next channel index calculation */
187 lll->data_chan_counter++;
188
189 /* Set up Radio H/W */
190 radio_reset();
191
192 #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
193 radio_tx_power_set(lll_adv->tx_pwr_lvl);
194 #else
195 radio_tx_power_set(RADIO_TXP_DEFAULT);
196 #endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */
197
198 phy_s = lll_adv->phy_s;
199
200 /* TODO: if coded we use S8? */
201 radio_phy_set(phy_s, lll_adv->phy_flags);
202 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, PDU_AC_PAYLOAD_SIZE_MAX,
203 RADIO_PKT_CONF_PHY(phy_s));
204
205 /* Access address and CRC */
206 aa = sys_cpu_to_le32(PDU_AC_ACCESS_ADDR);
207 radio_aa_set((uint8_t *)&aa);
208 radio_crc_configure(PDU_CRC_POLYNOMIAL,
209 PDU_AC_CRC_IV);
210
211 /* Use channel idx calculated or that was in aux_ptr */
212 lll_chan_set(chan_idx);
213
214 /* Switch to Rx if connectable or scannable */
215 if (com_hdr->adv_mode & (BT_HCI_LE_ADV_PROP_CONN |
216 BT_HCI_LE_ADV_PROP_SCAN)) {
217
218 struct pdu_adv *scan_pdu;
219
220 scan_pdu = lll_adv_scan_rsp_latest_get(lll_adv, &upd);
221 LL_ASSERT(scan_pdu);
222
223 radio_isr_set(isr_tx_rx, lll);
224 radio_tmr_tifs_set(EVENT_IFS_US);
225 radio_switch_complete_and_rx(phy_s);
226
227 if (false) {
228
229 #if defined(CONFIG_BT_CTLR_PRIVACY)
230 } else if (upd) {
231 /* Copy the address from the adv packet we will send
232 * into the scan response.
233 */
234 memcpy(&scan_pdu->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
235 &sec_pdu->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
236 BDADDR_SIZE);
237 }
238
239 if (ull_filter_lll_rl_enabled()) {
240 struct lll_filter *filter =
241 ull_filter_lll_get(!!(lll_adv->filter_policy));
242
243 radio_filter_configure(filter->enable_bitmask,
244 filter->addr_type_bitmask,
245 (uint8_t *)filter->bdaddr);
246 #endif /* CONFIG_BT_CTLR_PRIVACY */
247
248 } else if (IS_ENABLED(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST) &&
249 lll_adv->filter_policy) {
250 struct lll_filter *fal = ull_filter_lll_get(true);
251
252 radio_filter_configure(fal->enable_bitmask,
253 fal->addr_type_bitmask,
254 (uint8_t *)fal->bdaddr);
255 ARG_UNUSED(scan_pdu);
256 ARG_UNUSED(upd);
257 } else {
258 ARG_UNUSED(scan_pdu);
259 ARG_UNUSED(upd);
260 }
261
262 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
263 } else if (sec_pdu->adv_ext_ind.ext_hdr_len &&
264 sec_pdu->adv_ext_ind.ext_hdr.aux_ptr) {
265 /* Set the last used auxiliary PDU for transmission */
266 lll->last_pdu = sec_pdu;
267
268 /* Populate chan idx for AUX_ADV_IND PDU */
269 aux_ptr_chan_idx_set(lll, sec_pdu);
270
271 radio_isr_set(isr_tx_chain, lll);
272 radio_tmr_tifs_set(EVENT_B2B_MAFS_US);
273 radio_switch_complete_and_b2b_tx(phy_s, lll_adv->phy_flags,
274 phy_s, lll_adv->phy_flags);
275 } else {
276 /* No chain PDU */
277 lll->last_pdu = NULL;
278
279 #else /* !CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
280 } else {
281 #endif /* !CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
282
283 radio_isr_set(isr_done, lll);
284 radio_switch_complete_and_disable();
285 }
286
287 if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC) &&
288 IS_ENABLED(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) &&
289 sec_pdu->adv_ext_ind.ext_hdr_len &&
290 sec_pdu->adv_ext_ind.ext_hdr.sync_info) {
291 ull_adv_sync_lll_syncinfo_fill(sec_pdu, lll);
292 }
293
294 /* Set the Radio Tx Packet */
295 radio_pkt_tx_set(sec_pdu);
296
297 ticks_at_event = p->ticks_at_expire;
298 ull = HDR_LLL2ULL(lll);
299 ticks_at_event += lll_event_offset_get(ull);
300
301 ticks_at_start = ticks_at_event;
302 ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
303
304 remainder = p->remainder;
305 start_us = radio_tmr_start(1, ticks_at_start, remainder);
306
307 /* capture end of Tx-ed PDU, used to calculate HCTO. */
308 radio_tmr_end_capture();
309
310 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
311 radio_gpio_pa_setup();
312 radio_gpio_pa_lna_enable(start_us +
313 radio_tx_ready_delay_get(phy_s,
314 lll_adv->phy_flags) -
315 HAL_RADIO_GPIO_PA_OFFSET);
316 #else /* !HAL_RADIO_GPIO_HAVE_PA_PIN */
317 ARG_UNUSED(start_us);
318 #endif /* !HAL_RADIO_GPIO_HAVE_PA_PIN */
319
320 #if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
321 (EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
322 uint32_t overhead;
323
324 overhead = lll_preempt_calc(ull, (TICKER_ID_ADV_AUX_BASE + ull_adv_aux_lll_handle_get(lll)),
325 ticks_at_event);
326 /* check if preempt to start has changed */
327 if (overhead) {
328 LL_ASSERT_OVERHEAD(overhead);
329
330 radio_isr_set(isr_done, lll);
331 radio_disable();
332
333 return -ECANCELED;
334 }
335 #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
336
337 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
338 /* Populate chan idx for AUX_CHAIN_IND PDU */
339 chain_pdu_aux_ptr_chan_idx_set(lll);
340 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
341
342 ret = lll_prepare_done(lll);
343 LL_ASSERT(!ret);
344
345 DEBUG_RADIO_START_A(1);
346
347 return 0;
348 }
349
350 #if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) || \
351 defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
aux_ptr_get(struct pdu_adv * pdu,struct pdu_adv_aux_ptr ** aux_ptr)352 static int aux_ptr_get(struct pdu_adv *pdu, struct pdu_adv_aux_ptr **aux_ptr)
353 {
354 struct pdu_adv_com_ext_adv *com_hdr;
355 struct pdu_adv_ext_hdr *hdr;
356 uint8_t *dptr;
357
358 /* Get reference to common extended header */
359 com_hdr = (void *)&pdu->adv_ext_ind;
360 if (com_hdr->ext_hdr_len == 0U) {
361 *aux_ptr = NULL;
362
363 return -EINVAL;
364 }
365
366 /* Get reference to extended header flags and header fields */
367 hdr = (void *)com_hdr->ext_hdr_adv_data;
368 dptr = hdr->data;
369
370 /* traverse through adv_addr, if present */
371 if (hdr->adv_addr) {
372 dptr += BDADDR_SIZE;
373 }
374
375 /* traverse through tgt_addr, if present */
376 if (hdr->tgt_addr) {
377 dptr += BDADDR_SIZE;
378 }
379
380 /* No CTEInfo flag in primary and secondary channel PDU */
381
382 /* traverse through adi, if present */
383 if (hdr->adi) {
384 dptr += sizeof(struct pdu_adv_adi);
385 }
386
387 /* check for aux_ptr flag */
388 if (hdr->aux_ptr) {
389 /* Return reference to aux pointer structure */
390 *aux_ptr = (void *)dptr;
391 } else {
392 *aux_ptr = NULL;
393 }
394
395 return 0;
396 }
397 #endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO ||
398 * CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK
399 */
400
401 #if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
isr_race(void * param)402 static void isr_race(void *param)
403 {
404 radio_status_reset();
405 }
406
isr_early_abort(void * param)407 static void isr_early_abort(void *param)
408 {
409 struct event_done_extra *extra;
410 int err;
411
412 /* Generate auxiliary radio event done */
413 extra = ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_ADV_AUX);
414 LL_ASSERT(extra);
415
416 radio_isr_set(isr_race, param);
417 if (!radio_is_idle()) {
418 radio_disable();
419 }
420
421 err = lll_hfclock_off();
422 LL_ASSERT(err >= 0);
423
424 lll_done(NULL);
425 }
426 #endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
427
isr_done(void * param)428 static void isr_done(void *param)
429 {
430 struct event_done_extra *extra;
431
432 /* Clear radio status and events */
433 lll_isr_status_reset();
434
435 /* Generate auxiliary radio event done */
436 extra = ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_ADV_AUX);
437 LL_ASSERT(extra);
438
439 /* Cleanup radio event and dispatch the done event */
440 lll_isr_cleanup(param);
441 }
442
443 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
isr_tx_chain(void * param)444 static void isr_tx_chain(void *param)
445 {
446 struct pdu_adv_aux_ptr *aux_ptr;
447 struct lll_adv_aux *lll_aux;
448 struct lll_adv *lll;
449 struct pdu_adv *pdu;
450 int err;
451
452 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
453 lll_prof_latency_capture();
454 }
455
456 /* Clear radio tx status and events */
457 lll_isr_tx_status_reset();
458
459 /* Get reference to auxiliary and primary advertising LLL contexts */
460 lll_aux = param;
461 lll = lll_aux->adv;
462
463 /* Get reference to aux pointer structure */
464 err = aux_ptr_get(lll_aux->last_pdu, &aux_ptr);
465 LL_ASSERT(!err && aux_ptr);
466
467 /* Use channel idx that was in aux_ptr */
468 lll_chan_set(aux_ptr->chan_idx);
469
470 /* Get reference to the auxiliary chain PDU */
471 pdu = lll_adv_pdu_linked_next_get(lll_aux->last_pdu);
472 LL_ASSERT(pdu);
473
474 /* Set the last used auxiliary PDU for transmission */
475 lll_aux->last_pdu = pdu;
476
477 /* setup tIFS switching */
478 if (pdu->adv_ext_ind.ext_hdr_len && pdu->adv_ext_ind.ext_hdr.aux_ptr) {
479 radio_isr_set(isr_tx_chain, lll_aux);
480 radio_tmr_tifs_set(EVENT_B2B_MAFS_US);
481 radio_switch_complete_and_b2b_tx(lll->phy_s, lll->phy_flags,
482 lll->phy_s, lll->phy_flags);
483 } else {
484 radio_isr_set(isr_done, lll_aux);
485 radio_switch_complete_and_b2b_tx_disable();
486 }
487
488 radio_pkt_tx_set(pdu);
489
490 /* assert if radio packet ptr is not set and radio started rx */
491 LL_ASSERT(!radio_is_ready());
492
493 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
494 lll_prof_cputime_capture();
495 }
496
497 /* capture end of AUX_SYNC_IND/AUX_CHAIN_IND PDU, used for calculating
498 * next PDU timestamp.
499 */
500 radio_tmr_end_capture();
501
502 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
503 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
504 /* PA/LNA enable is overwriting packet end used in ISR
505 * profiling, hence back it up for later use.
506 */
507 lll_prof_radio_end_backup();
508 }
509
510 radio_gpio_pa_setup();
511 radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
512 EVENT_B2B_MAFS_US -
513 (EVENT_CLOCK_JITTER_US << 1U) -
514 radio_tx_chain_delay_get(lll->phy_s,
515 lll->phy_flags) -
516 HAL_RADIO_GPIO_PA_OFFSET);
517 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
518
519 /* Populate chan idx for AUX_CHAIN_IND PDU */
520 chain_pdu_aux_ptr_chan_idx_set(lll_aux);
521
522 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
523 lll_prof_send();
524 }
525 }
526
chain_pdu_aux_ptr_chan_idx_set(struct lll_adv_aux * lll)527 static void chain_pdu_aux_ptr_chan_idx_set(struct lll_adv_aux *lll)
528 {
529 struct pdu_adv *chain_pdu;
530
531 /* No chain PDU */
532 if (!lll->last_pdu) {
533 return;
534 }
535
536 /* Get reference to the auxiliary chain PDU */
537 chain_pdu = lll_adv_pdu_linked_next_get(lll->last_pdu);
538
539 /* Check if there is further chain PDU */
540 if (chain_pdu && chain_pdu->adv_ext_ind.ext_hdr_len &&
541 chain_pdu->adv_ext_ind.ext_hdr.aux_ptr) {
542 aux_ptr_chan_idx_set(lll, chain_pdu);
543 }
544 }
545
aux_ptr_chan_idx_set(struct lll_adv_aux * lll,struct pdu_adv * pdu)546 static void aux_ptr_chan_idx_set(struct lll_adv_aux *lll, struct pdu_adv *pdu)
547 {
548 struct pdu_adv_aux_ptr *aux_ptr;
549 struct ll_adv_aux_set *aux;
550 uint8_t chan_idx;
551 int err;
552
553 /* Get reference to aux pointer structure */
554 err = aux_ptr_get(pdu, &aux_ptr);
555 LL_ASSERT(!err && aux_ptr);
556
557 /* Calculate a new channel index */
558 aux = HDR_LLL2ULL(lll);
559 chan_idx = lll_chan_sel_2(lll->data_chan_counter, aux->data_chan_id,
560 aux->chm[aux->chm_first].data_chan_map,
561 aux->chm[aux->chm_first].data_chan_count);
562
563 /* Increment counter, for next channel index calculation */
564 lll->data_chan_counter++;
565
566 /* Set the channel index for the auxiliary chain PDU */
567 aux_ptr->chan_idx = chan_idx;
568 }
569 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
570
isr_tx_rx(void * param)571 static void isr_tx_rx(void *param)
572 {
573 struct node_rx_pdu *node_rx_prof;
574 struct node_rx_pdu *node_rx;
575 struct lll_adv_aux *lll_aux;
576 struct lll_adv *lll;
577 uint32_t hcto;
578
579 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
580 lll_prof_latency_capture();
581 node_rx_prof = lll_prof_reserve();
582 }
583
584 /* Call to ensure packet/event timer accumulates the elapsed time
585 * under single timer use.
586 */
587 (void)radio_is_tx_done();
588
589 /* Clear radio tx status and events */
590 lll_isr_tx_status_reset();
591
592 lll_aux = param;
593 lll = lll_aux->adv;
594
595 /* setup tIFS switching */
596 radio_tmr_tifs_set(EVENT_IFS_US);
597 radio_switch_complete_and_tx(lll->phy_s, 0, lll->phy_s, lll->phy_flags);
598
599 /* setup Rx buffer */
600 node_rx = ull_pdu_rx_alloc_peek(1);
601 LL_ASSERT(node_rx);
602 radio_pkt_rx_set(node_rx->pdu);
603
604 /* assert if radio packet ptr is not set and radio started rx */
605 LL_ASSERT(!radio_is_ready());
606
607 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
608 lll_prof_cputime_capture();
609 }
610
611 radio_isr_set(isr_rx, param);
612
613 #if defined(CONFIG_BT_CTLR_PRIVACY)
614 if (ull_filter_lll_rl_enabled()) {
615 uint8_t count, *irks = ull_filter_lll_irks_get(&count);
616
617 radio_ar_configure(count, irks, (lll->phy_s << 2) | BIT(0));
618 }
619 #endif /* CONFIG_BT_CTLR_PRIVACY */
620
621 /* +/- 2us active clock jitter, +1 us PPI to timer start compensation */
622 hcto = radio_tmr_tifs_base_get() + EVENT_IFS_US +
623 (EVENT_CLOCK_JITTER_US << 1) + RANGE_DELAY_US +
624 HAL_RADIO_TMR_START_DELAY_US;
625 hcto += radio_rx_chain_delay_get(lll->phy_s, PHY_FLAGS_S8);
626 hcto += addr_us_get(lll->phy_s);
627 hcto -= radio_tx_chain_delay_get(lll->phy_s, PHY_FLAGS_S8);
628 radio_tmr_hcto_configure(hcto);
629
630 /* capture end of CONNECT_IND PDU, used for calculating first
631 * peripheral event.
632 */
633 radio_tmr_end_capture();
634
635 if (IS_ENABLED(CONFIG_BT_CTLR_SCAN_REQ_RSSI) ||
636 IS_ENABLED(CONFIG_BT_CTLR_CONN_RSSI)) {
637 radio_rssi_measure();
638 }
639
640 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
641 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
642 /* PA/LNA enable is overwriting packet end used in ISR
643 * profiling, hence back it up for later use.
644 */
645 lll_prof_radio_end_backup();
646 }
647
648 radio_gpio_lna_setup();
649 radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() + EVENT_IFS_US -
650 (EVENT_CLOCK_JITTER_US << 1U) -
651 radio_tx_chain_delay_get(lll->phy_s,
652 PHY_FLAGS_S8) -
653 HAL_RADIO_GPIO_LNA_OFFSET);
654 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
655
656 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
657 lll_prof_reserve_send(node_rx_prof);
658 }
659 }
660
isr_rx(void * param)661 static void isr_rx(void *param)
662 {
663 uint8_t phy_flags_rx;
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
672 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
673 lll_prof_latency_capture();
674 }
675
676 /* Read radio status and events */
677 trx_done = radio_is_done();
678 if (trx_done) {
679 crc_ok = radio_crc_is_valid();
680 phy_flags_rx = radio_phy_flags_rx_get();
681 devmatch_ok = radio_filter_has_match();
682 devmatch_id = radio_filter_match_get();
683 if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {
684 irkmatch_ok = radio_ar_has_match();
685 irkmatch_id = radio_ar_match_get();
686 } else {
687 irkmatch_ok = 0U;
688 irkmatch_id = FILTER_IDX_NONE;
689 }
690 rssi_ready = radio_rssi_is_ready();
691 } else {
692 crc_ok = devmatch_ok = irkmatch_ok = rssi_ready =
693 phy_flags_rx = 0U;
694 devmatch_id = irkmatch_id = FILTER_IDX_NONE;
695 }
696
697 /* Clear radio status and events */
698 lll_isr_status_reset();
699
700 /* No Rx */
701 if (!trx_done) {
702 goto isr_rx_do_close;
703 }
704
705 if (crc_ok) {
706 int err;
707
708 err = isr_rx_pdu(param, phy_flags_rx, devmatch_ok, devmatch_id,
709 irkmatch_ok, irkmatch_id, rssi_ready);
710 if (!err) {
711 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
712 lll_prof_send();
713 }
714
715 return;
716 }
717 }
718
719 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
720 lll_prof_cputime_capture();
721 lll_prof_send();
722 }
723
724 isr_rx_do_close:
725 radio_isr_set(isr_done, param);
726 radio_disable();
727 }
728
isr_rx_pdu(struct lll_adv_aux * lll_aux,uint8_t phy_flags_rx,uint8_t devmatch_ok,uint8_t devmatch_id,uint8_t irkmatch_ok,uint8_t irkmatch_id,uint8_t rssi_ready)729 static inline int isr_rx_pdu(struct lll_adv_aux *lll_aux, uint8_t phy_flags_rx,
730 uint8_t devmatch_ok, uint8_t devmatch_id,
731 uint8_t irkmatch_ok, uint8_t irkmatch_id,
732 uint8_t rssi_ready)
733 {
734 struct node_rx_pdu *node_rx;
735 struct pdu_adv_ext_hdr *hdr;
736 struct pdu_adv *pdu_adv;
737 struct pdu_adv *pdu_aux;
738 struct pdu_adv *pdu_rx;
739 struct lll_adv *lll;
740 uint8_t *tgt_addr;
741 uint8_t tx_addr;
742 uint8_t rx_addr;
743 uint8_t *addr;
744 uint8_t upd;
745
746 #if defined(CONFIG_BT_CTLR_PRIVACY)
747 /* An IRK match implies address resolution enabled */
748 uint8_t rl_idx = irkmatch_ok ? ull_filter_lll_rl_irk_idx(irkmatch_id) :
749 FILTER_IDX_NONE;
750 #else
751 uint8_t rl_idx = FILTER_IDX_NONE;
752 #endif /* CONFIG_BT_CTLR_PRIVACY */
753
754 lll = lll_aux->adv;
755
756 node_rx = ull_pdu_rx_alloc_peek(1);
757 LL_ASSERT(node_rx);
758
759 pdu_rx = (void *)node_rx->pdu;
760 pdu_adv = lll_adv_data_curr_get(lll);
761 pdu_aux = lll_adv_aux_data_latest_get(lll_aux, &upd);
762 LL_ASSERT(pdu_aux);
763
764 hdr = &pdu_aux->adv_ext_ind.ext_hdr;
765
766 addr = &pdu_aux->adv_ext_ind.ext_hdr.data[ADVA_OFFSET];
767 tx_addr = pdu_aux->tx_addr;
768
769 if (hdr->tgt_addr) {
770 tgt_addr = &pdu_aux->adv_ext_ind.ext_hdr.data[TGTA_OFFSET];
771 } else {
772 tgt_addr = NULL;
773 }
774 rx_addr = pdu_aux->rx_addr;
775
776 if ((pdu_rx->type == PDU_ADV_TYPE_AUX_SCAN_REQ) &&
777 (pdu_rx->len == sizeof(struct pdu_adv_scan_req)) &&
778 lll_adv_scan_req_check(lll, pdu_rx, tx_addr, addr, devmatch_ok,
779 &rl_idx)) {
780 struct pdu_adv *sr_pdu;
781
782 sr_pdu = lll_adv_scan_rsp_curr_get(lll);
783
784 if (0) {
785
786 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
787 } else if (sr_pdu->adv_ext_ind.ext_hdr_len &&
788 sr_pdu->adv_ext_ind.ext_hdr.aux_ptr) {
789 /* Set the last used auxiliary PDU for transmission */
790 lll_aux->last_pdu = sr_pdu;
791
792 radio_isr_set(isr_tx_chain, lll_aux);
793 radio_tmr_tifs_set(EVENT_B2B_MAFS_US);
794 radio_switch_complete_and_b2b_tx(lll->phy_s,
795 lll->phy_flags,
796 lll->phy_s,
797 lll->phy_flags);
798 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
799 radio_tmr_end_capture();
800 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
801
802 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
803
804 } else {
805 radio_isr_set(isr_done, lll_aux);
806 radio_switch_complete_and_disable();
807 }
808
809 radio_pkt_tx_set(sr_pdu);
810
811 /* assert if radio packet ptr is not set and radio started tx */
812 LL_ASSERT(!radio_is_ready());
813
814 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
815 lll_prof_cputime_capture();
816 }
817
818 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
819 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
820 /* PA/LNA enable is overwriting packet end used in ISR
821 * profiling, hence back it up for later use.
822 */
823 lll_prof_radio_end_backup();
824 }
825
826 radio_gpio_pa_setup();
827 radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
828 EVENT_IFS_US -
829 radio_rx_chain_delay_get(lll->phy_s,
830 phy_flags_rx) -
831 HAL_RADIO_GPIO_PA_OFFSET);
832 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
833
834 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
835 /* Populate chan idx for AUX_CHAIN_IND PDU */
836 chain_pdu_aux_ptr_chan_idx_set(lll_aux);
837 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
838
839 #if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY)
840 if (lll->scan_req_notify) {
841 uint32_t err;
842
843 /* Generate the scan request event */
844 err = lll_adv_scan_req_report(lll, pdu_rx, rl_idx,
845 rssi_ready);
846 if (err) {
847 /* Scan Response will not be transmitted */
848 return err;
849 }
850 }
851 #endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */
852
853 return 0;
854
855 #if defined(CONFIG_BT_PERIPHERAL)
856 } else if ((pdu_rx->type == PDU_ADV_TYPE_AUX_CONNECT_REQ) &&
857 (pdu_rx->len == sizeof(struct pdu_adv_connect_ind)) &&
858 lll->conn &&
859 lll_adv_connect_ind_check(lll, pdu_rx, tx_addr, addr,
860 rx_addr, tgt_addr,
861 devmatch_ok, &rl_idx)) {
862 struct node_rx_ftr *ftr;
863 struct node_rx_pdu *rx;
864 struct pdu_adv *pdu_tx;
865
866 if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
867 rx = ull_pdu_rx_alloc_peek(4);
868 } else {
869 rx = ull_pdu_rx_alloc_peek(3);
870 }
871
872 if (!rx) {
873 return -ENOBUFS;
874 }
875
876 /* rx is effectively allocated later, after critical isr steps
877 * are done */
878 radio_isr_set(isr_tx_connect_rsp, rx);
879 radio_switch_complete_and_disable();
880 pdu_tx = init_connect_rsp_pdu(pdu_rx);
881 radio_pkt_tx_set(pdu_tx);
882
883 /* assert if radio packet ptr is not set and radio started tx */
884 LL_ASSERT(!radio_is_ready());
885
886 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
887 lll_prof_cputime_capture();
888 }
889
890 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
891 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
892 /* PA/LNA enable is overwriting packet end used in ISR
893 * profiling, hence back it up for later use.
894 */
895 lll_prof_radio_end_backup();
896 }
897
898 radio_gpio_pa_setup();
899 radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
900 EVENT_IFS_US -
901 radio_rx_chain_delay_get(lll->phy_s,
902 phy_flags_rx) -
903 HAL_RADIO_GPIO_PA_OFFSET);
904 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
905
906 /* Note: this is the same as previous result from alloc_peek */
907 rx = ull_pdu_rx_alloc();
908
909 rx->hdr.type = NODE_RX_TYPE_CONNECTION;
910 rx->hdr.handle = 0xffff;
911
912 ftr = &(rx->rx_ftr);
913 ftr->param = lll;
914 ftr->ticks_anchor = radio_tmr_start_get();
915 ftr->radio_end_us = radio_tmr_end_get() -
916 radio_rx_chain_delay_get(lll->phy_s,
917 phy_flags_rx);
918
919 #if defined(CONFIG_BT_CTLR_PRIVACY)
920 ftr->rl_idx = irkmatch_ok ? rl_idx : FILTER_IDX_NONE;
921 #endif /* CONFIG_BT_CTLR_PRIVACY */
922
923 if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
924 ftr->extra = ull_pdu_rx_alloc();
925 }
926
927 return 0;
928 #endif /* CONFIG_BT_PERIPHERAL */
929 }
930
931 return -EINVAL;
932 }
933
934 #if defined(CONFIG_BT_PERIPHERAL)
init_connect_rsp_pdu(struct pdu_adv * pdu_ci)935 static struct pdu_adv *init_connect_rsp_pdu(struct pdu_adv *pdu_ci)
936 {
937 struct pdu_adv_com_ext_adv *cr_com_hdr;
938 struct pdu_adv_ext_hdr *cr_hdr;
939 struct pdu_adv *pdu_cr;
940 uint8_t *cr_dptr;
941
942 pdu_cr = radio_pkt_scratch_get();
943 pdu_cr->type = PDU_ADV_TYPE_AUX_CONNECT_RSP;
944 pdu_cr->rfu = 0;
945 pdu_cr->chan_sel = 0;
946 pdu_cr->tx_addr = pdu_ci->rx_addr;
947 pdu_cr->rx_addr = pdu_ci->tx_addr;
948
949 /* Common Extended Header Format Advertising Mode */
950 cr_com_hdr = &pdu_cr->adv_ext_ind;
951 cr_com_hdr->adv_mode = 0;
952
953 /* Clear Flags */
954 cr_hdr = &cr_com_hdr->ext_hdr;
955 cr_dptr = (void *)cr_hdr;
956 *cr_dptr = 0;
957 cr_dptr = cr_hdr->data;
958
959 /* AdvA */
960 cr_hdr->adv_addr = 1;
961 memcpy(cr_dptr, &pdu_ci->connect_ind.adv_addr, BDADDR_SIZE);
962 cr_dptr += BDADDR_SIZE;
963
964 /* InitA */
965 cr_hdr->tgt_addr = 1;
966 memcpy(cr_dptr, &pdu_ci->connect_ind.init_addr, BDADDR_SIZE);
967 cr_dptr += BDADDR_SIZE;
968
969 /* Common Extended Header Length */
970 cr_com_hdr->ext_hdr_len = cr_dptr - (uint8_t *)&cr_com_hdr->ext_hdr;
971
972 /* PDU length */
973 pdu_cr->len = cr_dptr - &pdu_cr->payload[0];
974
975 return pdu_cr;
976 }
977
isr_tx_connect_rsp(void * param)978 static void isr_tx_connect_rsp(void *param)
979 {
980 struct node_rx_ftr *ftr;
981 struct node_rx_pdu *rx;
982 struct lll_adv *lll;
983 bool is_done;
984
985 rx = param;
986 ftr = &(rx->rx_ftr);
987 lll = ftr->param;
988
989 is_done = radio_is_done();
990
991 if (!is_done) {
992 /* AUX_CONNECT_RSP was not sent properly, need to release
993 * allocated resources and keep advertising.
994 */
995
996 rx->hdr.type = NODE_RX_TYPE_RELEASE;
997
998 if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
999 ull_rx_put(rx->hdr.link, rx);
1000
1001 rx = ftr->extra;
1002 rx->hdr.type = NODE_RX_TYPE_RELEASE;
1003 }
1004 }
1005
1006 ull_rx_put_sched(rx->hdr.link, rx);
1007
1008 if (is_done) {
1009 /* Stop further LLL radio events */
1010 lll->conn->periph.initiated = 1;
1011 }
1012
1013 /* Clear radio status and events */
1014 lll_isr_status_reset();
1015 lll_isr_cleanup(lll);
1016 }
1017 #endif /* CONFIG_BT_PERIPHERAL */
1018