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