1 /*
2  * Copyright (c) 2017-2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <soc.h>
9 #include <zephyr/bluetooth/hci_types.h>
10 #include <zephyr/sys/byteorder.h>
11 
12 #include "hal/cpu.h"
13 #include "hal/ccm.h"
14 #include "hal/ticker.h"
15 
16 #include "util/util.h"
17 #include "util/mem.h"
18 #include "util/memq.h"
19 #include "util/mayfly.h"
20 #include "util/dbuf.h"
21 
22 #include "ticker/ticker.h"
23 
24 #include "pdu_df.h"
25 #include "lll/pdu_vendor.h"
26 #include "pdu.h"
27 
28 #include "lll.h"
29 #include "lll_clock.h"
30 #include "lll/lll_vendor.h"
31 #include "lll_chan.h"
32 #include "lll/lll_adv_types.h"
33 #include "lll_adv.h"
34 #include "lll/lll_adv_pdu.h"
35 #include "lll_adv_aux.h"
36 #include "lll/lll_df_types.h"
37 #include "lll_conn.h"
38 
39 #include "ull_adv_types.h"
40 
41 #include "ull_internal.h"
42 #include "ull_chan_internal.h"
43 #include "ull_adv_internal.h"
44 #include "ull_sched_internal.h"
45 
46 #include "ll.h"
47 
48 #include "hal/debug.h"
49 
50 static int init_reset(void);
51 
52 #if (CONFIG_BT_CTLR_ADV_AUX_SET > 0)
53 static inline struct ll_adv_aux_set *aux_acquire(void);
54 static inline void aux_release(struct ll_adv_aux_set *aux);
55 static uint32_t aux_time_get(const struct ll_adv_aux_set *aux,
56 			     const struct pdu_adv *pdu,
57 			     uint8_t pdu_len, uint8_t pdu_scan_len);
58 static uint32_t aux_time_min_get(const struct ll_adv_aux_set *aux);
59 static uint8_t aux_time_update(struct ll_adv_aux_set *aux, struct pdu_adv *pdu,
60 			       struct pdu_adv *pdu_scan);
61 
62 #if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
63 static void mfy_aux_offset_get(void *param);
64 static void ticker_op_cb(uint32_t status, void *param);
65 #endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
66 
67 static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
68 		      uint32_t remainder, uint16_t lazy, uint8_t force,
69 		      void *param);
70 
71 static struct ll_adv_aux_set ll_adv_aux_pool[CONFIG_BT_CTLR_ADV_AUX_SET];
72 static void *adv_aux_free;
73 
74 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
75 static void ticker_update_op_cb(uint32_t status, void *param);
76 
77 static struct ticker_ext ll_adv_aux_ticker_ext[CONFIG_BT_CTLR_ADV_AUX_SET];
78 #endif /* !CONFIG_BT_CTLR_ADV_PERIODIC && CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
79 #endif /* (CONFIG_BT_CTLR_ADV_AUX_SET > 0) */
80 
81 static uint16_t did_unique[PDU_ADV_SID_COUNT];
82 
ll_adv_aux_random_addr_set(uint8_t handle,uint8_t const * const addr)83 uint8_t ll_adv_aux_random_addr_set(uint8_t handle, uint8_t const *const addr)
84 {
85 	struct ll_adv_set *adv;
86 
87 	adv = ull_adv_is_created_get(handle);
88 	if (!adv) {
89 		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
90 	}
91 
92 	/* TODO: Fail if connectable advertising is enabled */
93 	if (0) {
94 		return BT_HCI_ERR_CMD_DISALLOWED;
95 	}
96 
97 	(void)memcpy(adv->rnd_addr, addr, BDADDR_SIZE);
98 
99 	return 0;
100 }
101 
ll_adv_aux_ad_data_set(uint8_t handle,uint8_t op,uint8_t frag_pref,uint8_t len,uint8_t const * const data)102 uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref,
103 			       uint8_t len, uint8_t const *const data)
104 {
105 	uint8_t hdr_data[ULL_ADV_HDR_DATA_LEN_SIZE +
106 			 ULL_ADV_HDR_DATA_DATA_PTR_SIZE +
107 			 ULL_ADV_HDR_DATA_LEN_SIZE +
108 			 ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE +
109 			 ULL_ADV_HDR_DATA_LEN_SIZE];
110 	uint8_t pri_idx, sec_idx;
111 	struct ll_adv_set *adv;
112 	uint8_t *val_ptr;
113 	uint8_t err;
114 
115 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK)
116 	struct pdu_adv *pdu_prev;
117 	uint8_t ad_len_overflow;
118 	uint8_t ad_len_chain;
119 	struct pdu_adv *pdu;
120 	uint8_t ad_len = 0U;
121 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */
122 
123 	/* Get the advertising set instance */
124 	adv = ull_adv_is_created_get(handle);
125 	if (!adv) {
126 		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
127 	}
128 
129 	/* Reject setting fragment when Extended Advertising is enabled */
130 	if (adv->is_enabled && (op <= BT_HCI_LE_EXT_ADV_OP_LAST_FRAG)) {
131 		return BT_HCI_ERR_CMD_DISALLOWED;
132 	}
133 
134 	/* Reject intermediate op before first op */
135 	if (adv->is_ad_data_cmplt &&
136 	    ((op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG) ||
137 	     (op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG))) {
138 		return BT_HCI_ERR_CMD_DISALLOWED;
139 	}
140 
141 	/* Reject unchanged op before complete status */
142 	if (!adv->is_ad_data_cmplt &&
143 	    (op == BT_HCI_LE_EXT_ADV_OP_UNCHANGED_DATA)) {
144 		return BT_HCI_ERR_CMD_DISALLOWED;
145 	}
146 
147 	/* Reject len > 191 bytes if chain PDUs unsupported */
148 	if (!IS_ENABLED(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK) &&
149 	    (len > PDU_AC_EXT_AD_DATA_LEN_MAX)) {
150 		return BT_HCI_ERR_CMD_DISALLOWED;
151 	}
152 
153 	/* Prepare the AD data as parameter to update in PDU */
154 	/* Use length = 0 and NULL pointer to retain old data in the PDU.
155 	 * Use length = 0 and valid pointer of `data` (auto/local variable) to
156 	 * remove old data.
157 	 * User length > 0 and valid pointer of `data` (auto/local variable) to
158 	 * set new data.
159 	 */
160 	val_ptr = hdr_data;
161 	if ((IS_ENABLED(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK) && (
162 	     op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG ||
163 	     op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG)) ||
164 	    op == BT_HCI_LE_EXT_ADV_OP_UNCHANGED_DATA) {
165 		*val_ptr++ = 0U;
166 		(void)memset((void *)val_ptr, 0U,
167 			     ULL_ADV_HDR_DATA_DATA_PTR_SIZE);
168 	} else {
169 		*val_ptr++ = len;
170 		(void)memcpy(val_ptr, &data, sizeof(data));
171 	}
172 
173 	if ((!IS_ENABLED(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK) &&
174 	     (op == BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA ||
175 	      op == BT_HCI_LE_EXT_ADV_OP_FIRST_FRAG)) ||
176 	    (op == BT_HCI_LE_EXT_ADV_OP_UNCHANGED_DATA)) {
177 		err = ull_adv_aux_hdr_set_clear(adv,
178 						ULL_ADV_PDU_HDR_FIELD_AD_DATA,
179 						0U, hdr_data, &pri_idx,
180 						&sec_idx);
181 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK)
182 		/* No AD data overflow */
183 		ad_len_overflow = 0U;
184 
185 		/* No AD data in chain PDU */
186 		ad_len_chain = 0U;
187 
188 		/* local variables not used due to overflow being 0 */
189 		pdu_prev = NULL;
190 		pdu = NULL;
191 	} else if (op == BT_HCI_LE_EXT_ADV_OP_FIRST_FRAG ||
192 		    op == BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA) {
193 		/* Add AD Data and remove any prior presence of Aux Ptr */
194 		err = ull_adv_aux_hdr_set_clear(adv,
195 						ULL_ADV_PDU_HDR_FIELD_AD_DATA,
196 						ULL_ADV_PDU_HDR_FIELD_AUX_PTR,
197 						hdr_data, &pri_idx, &sec_idx);
198 		if (err == BT_HCI_ERR_PACKET_TOO_LONG) {
199 			ad_len_overflow =
200 				hdr_data[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET +
201 					 ULL_ADV_HDR_DATA_DATA_PTR_SIZE];
202 			/* Prepare the AD data as parameter to update in
203 			 * PDU
204 			 */
205 			val_ptr = hdr_data;
206 			*val_ptr++ = len - ad_len_overflow;
207 			(void)memcpy(val_ptr, &data, sizeof(data));
208 
209 			err = ull_adv_aux_hdr_set_clear(adv,
210 						ULL_ADV_PDU_HDR_FIELD_AD_DATA,
211 						ULL_ADV_PDU_HDR_FIELD_AUX_PTR,
212 						hdr_data, &pri_idx, &sec_idx);
213 		}
214 
215 		if (!err && adv->lll.aux) {
216 			/* Fragment into chain PDU if len > 191 bytes */
217 			if (len > PDU_AC_EXT_AD_DATA_LEN_MAX) {
218 				uint8_t idx;
219 
220 				/* Prepare the AD data as parameter to update in
221 				 * PDU
222 				 */
223 				val_ptr = hdr_data;
224 				*val_ptr++ = PDU_AC_EXT_AD_DATA_LEN_MAX;
225 				(void)memcpy(val_ptr, &data, sizeof(data));
226 
227 				/* Traverse to next set clear hdr data
228 				 * parameter, as aux ptr reference to be
229 				 * returned, hence second parameter will be for
230 				 * AD data field.
231 				 */
232 				val_ptr += sizeof(data);
233 
234 				*val_ptr = PDU_AC_EXT_AD_DATA_LEN_MAX;
235 				(void)memcpy(&val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET],
236 					     &data, sizeof(data));
237 
238 				/* Calculate the overflow chain PDU's AD data
239 				 * length
240 				 */
241 				ad_len_overflow =
242 					len - PDU_AC_EXT_AD_DATA_LEN_MAX;
243 
244 				/* No AD data in chain PDU besides the
245 				 * overflow
246 				 */
247 				ad_len_chain = 0U;
248 
249 				/* Get the reference to auxiliary PDU chain */
250 				pdu_prev = lll_adv_aux_data_alloc(adv->lll.aux,
251 								  &idx);
252 				LL_ASSERT(idx == sec_idx);
253 
254 				/* Current auxiliary PDU */
255 				pdu = pdu_prev;
256 			} else {
257 				struct pdu_adv *pdu_parent;
258 				struct pdu_adv *pdu_chain;
259 				uint8_t idx;
260 
261 				/* Get the reference to auxiliary PDU chain */
262 				pdu_parent =
263 					lll_adv_aux_data_alloc(adv->lll.aux,
264 							       &idx);
265 				LL_ASSERT(idx == sec_idx);
266 
267 				/* Remove/Release any previous chain PDU
268 				 * allocations
269 				 */
270 				pdu_chain =
271 					lll_adv_pdu_linked_next_get(pdu_parent);
272 				if (pdu_chain) {
273 					lll_adv_pdu_linked_append(NULL,
274 								  pdu_parent);
275 					lll_adv_pdu_linked_release_all(pdu_chain);
276 				}
277 
278 				/* No AD data overflow */
279 				ad_len_overflow = 0U;
280 
281 				/* No AD data in chain PDU */
282 				ad_len_chain = 0U;
283 
284 				/* local variables not used due to overflow
285 				 * being 0
286 				 */
287 				pdu_prev = NULL;
288 				pdu = NULL;
289 			}
290 		} else {
291 			/* No AD data overflow */
292 			ad_len_overflow = 0U;
293 
294 			/* No AD data in chain PDU */
295 			ad_len_chain = 0U;
296 
297 			/* local variables not used due to overflow being 0 */
298 			pdu_prev = NULL;
299 			pdu = NULL;
300 		}
301 	} else {
302 		struct pdu_adv *pdu_chain_prev;
303 		struct pdu_adv *pdu_chain;
304 		uint16_t ad_len_total;
305 		uint8_t ad_len_prev = 0U;
306 
307 		/* Traverse to next set clear hdr data parameter */
308 		val_ptr += sizeof(data);
309 
310 		/* Get reference to previous secondary PDU data */
311 		pdu_prev = lll_adv_aux_data_peek(adv->lll.aux);
312 
313 		/* Get the reference to auxiliary PDU chain */
314 		pdu = lll_adv_aux_data_alloc(adv->lll.aux,
315 					     &sec_idx);
316 
317 		/* Traverse to the last chain PDU */
318 		ad_len_total = 0U;
319 		pdu_chain_prev = pdu_prev;
320 		pdu_chain = pdu;
321 		/* make a copy of the previous chain, until we reach the end */
322 		do {
323 			val_ptr = hdr_data;
324 			*val_ptr++ = 0U;
325 			(void)memset((void *)val_ptr, 0U,
326 				     ULL_ADV_HDR_DATA_DATA_PTR_SIZE);
327 
328 			pdu_prev = pdu_chain_prev;
329 			pdu = pdu_chain;
330 
331 			err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu,
332 							ULL_ADV_PDU_HDR_FIELD_AD_DATA,
333 							0U, hdr_data);
334 			ad_len_prev = hdr_data[ULL_ADV_HDR_DATA_LEN_OFFSET];
335 
336 			LL_ASSERT(!err || (err == BT_HCI_ERR_PACKET_TOO_LONG));
337 
338 			/* Check of max supported AD data len */
339 			ad_len_total += ad_len_prev;
340 			if ((ad_len_total + len) >
341 			    CONFIG_BT_CTLR_ADV_DATA_LEN_MAX) {
342 				/* NOTE: latest PDU was not consumed by LLL and
343 				 * as ull_adv_sync_pdu_alloc() has reverted back
344 				 * the double buffer with the first PDU, and
345 				 * returned the latest PDU as the new PDU, we
346 				 * need to enqueue back the new PDU which is
347 				 * infact the latest PDU.
348 				 */
349 				if (pdu_prev == pdu) {
350 					lll_adv_aux_data_enqueue(adv->lll.aux,
351 								 sec_idx);
352 				}
353 
354 				return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
355 			}
356 
357 			pdu_chain_prev = lll_adv_pdu_linked_next_get(pdu_prev);
358 			pdu_chain = lll_adv_pdu_linked_next_get(pdu);
359 			LL_ASSERT((pdu_chain_prev && pdu_chain) ||
360 				  (!pdu_chain_prev && !pdu_chain));
361 		} while (pdu_chain_prev);
362 
363 		/* No AD data overflow */
364 		ad_len_overflow = 0U;
365 		/* No AD data in chain PDU */
366 		ad_len_chain = 0U;
367 	}
368 #else /* !CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */
369 	} else {
370 		/* Append new fragment */
371 		err = ull_adv_aux_hdr_set_clear(adv,
372 						ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND,
373 						0U, hdr_data, &pri_idx,
374 						&sec_idx);
375 	}
376 #endif /* !CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */
377 
378 	if (err) {
379 		return err;
380 	}
381 
382 	if (!adv->lll.aux) {
383 		return 0;
384 	}
385 
386 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK)
387 	if ((op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG) ||
388 	    (op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG)) {
389 		/* in the previous step we duplicated the chain
390 		 * the next step is to append new data in the last existing pdu in the chain,
391 		 */
392 
393 		uint8_t chain_err = 0U;
394 
395 		val_ptr = hdr_data;
396 		*val_ptr++ = len;
397 		(void)memcpy(val_ptr, &data, sizeof(data));
398 
399 		/* Append data to the last PDU */
400 		chain_err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu,
401 						      ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND,
402 						      0U, hdr_data);
403 
404 		LL_ASSERT((!chain_err) || (chain_err == BT_HCI_ERR_PACKET_TOO_LONG));
405 
406 		/* FIXME: the code has become quite complex, an alternative and simpler
407 		 * implementation would be to first fill an array with all data that
408 		 * must be send, and create the chained PDUs from this array
409 		 */
410 		if (chain_err == BT_HCI_ERR_PACKET_TOO_LONG) {
411 			/* We could not fit all the data, append as much as possible
412 			 * ad_len_overflow is how much overflows with the AUX ptr
413 			 */
414 			const uint16_t chain_add_fields = ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND |
415 							  ULL_ADV_PDU_HDR_FIELD_AUX_PTR;
416 
417 			val_ptr = hdr_data;
418 			*val_ptr++ = len;
419 			(void)memcpy(val_ptr, &data, sizeof(data));
420 			val_ptr += sizeof(data);
421 			*val_ptr++ = len;
422 			(void)memcpy(val_ptr, &data, sizeof(data));
423 			chain_err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu,
424 							      chain_add_fields,
425 							      0U, hdr_data);
426 			ad_len_chain = hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET +
427 						ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE +
428 						ULL_ADV_HDR_DATA_DATA_PTR_OFFSET +
429 						ULL_ADV_HDR_DATA_DATA_PTR_SIZE];
430 
431 			/* len is the total amount of datawe want to add
432 			 * ad_len_chain is the amount of data that does
433 			 * not fit in the current PDU
434 			 * the difference of the two is the amount that
435 			 * we can fit in the current PDU
436 			 */
437 			ad_len = len - ad_len_chain;
438 
439 			val_ptr = hdr_data;
440 			*val_ptr++ =  ad_len;
441 			(void)memcpy(val_ptr, &data, sizeof(data));
442 			val_ptr += sizeof(data);
443 			*val_ptr++ =  ad_len;
444 			(void)memcpy(val_ptr, &data, sizeof(data));
445 
446 			/* we now know how much data we can add to the
447 			 * last PDU without getting an overflow
448 			 */
449 			chain_err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu,
450 							      chain_add_fields,
451 							      0U, hdr_data);
452 			LL_ASSERT(chain_err == 0U);
453 			/*
454 			 * in the next PDU we still need to add ad_len_chain bytes of data
455 			 * but we do not have overflow, since we already added
456 			 * the exact amount that would fit. We explicitly set overflow to 0.
457 			 * FIXME: ad_len_overflow already should be 0, to be verified. We wait
458 			 * fixing this until rewriting this whole function
459 			 */
460 			ad_len_overflow = 0U;
461 		} else {
462 			ad_len_overflow = 0U;
463 		}
464 	}
465 
466 	if (ad_len_chain || ad_len_overflow) {
467 		struct pdu_adv_com_ext_adv *com_hdr_chain;
468 		struct pdu_adv_com_ext_adv *com_hdr;
469 		struct pdu_adv_ext_hdr *hdr_chain;
470 		struct pdu_adv_aux_ptr *aux_ptr;
471 		struct pdu_adv *pdu_chain_prev;
472 		struct pdu_adv_ext_hdr hdr;
473 		struct pdu_adv *pdu_chain;
474 		uint8_t *dptr_chain;
475 		uint32_t offs_us;
476 		uint16_t sec_len;
477 		uint8_t *dptr;
478 
479 		len = ad_len_chain;
480 		/* Get reference to flags in superior PDU */
481 		com_hdr = &pdu->adv_ext_ind;
482 		if (com_hdr->ext_hdr_len) {
483 			hdr = com_hdr->ext_hdr;
484 		} else {
485 			*(uint8_t *)&hdr = 0U;
486 		}
487 		dptr = com_hdr->ext_hdr.data;
488 
489 		/* Allocate new PDU */
490 		pdu_chain = lll_adv_pdu_alloc_pdu_adv();
491 		LL_ASSERT(pdu_chain);
492 
493 		/* Populate the appended chain PDU */
494 		pdu_chain->type = PDU_ADV_TYPE_AUX_CHAIN_IND;
495 		pdu_chain->rfu = 0U;
496 		pdu_chain->chan_sel = 0U;
497 		pdu_chain->tx_addr = 0U;
498 		pdu_chain->rx_addr = 0U;
499 		pdu_chain->len = 0U;
500 
501 		com_hdr_chain = &pdu_chain->adv_ext_ind;
502 		hdr_chain = (void *)&com_hdr_chain->ext_hdr_adv_data[0];
503 		dptr_chain = (void *)hdr_chain;
504 
505 		LL_ASSERT(dptr_chain);
506 		/* Flags */
507 		*dptr_chain = 0U;
508 
509 		/* ADI flag, mandatory if superior PDU has it */
510 		if (hdr.adi) {
511 			hdr_chain->adi = 1U;
512 		}
513 
514 		/* Proceed to next byte if any flags present */
515 		if (*dptr_chain) {
516 			dptr_chain++;
517 		}
518 
519 		/* Start adding fields corresponding to flags here, if any */
520 
521 		/* AdvA flag */
522 		if (hdr.adv_addr) {
523 			dptr += BDADDR_SIZE;
524 		}
525 
526 		/* TgtA flag */
527 		if (hdr.tgt_addr) {
528 			dptr += BDADDR_SIZE;
529 		}
530 
531 		/* No CTEInfo in Extended Advertising */
532 
533 		/* ADI flag */
534 		if (hdr_chain->adi) {
535 			(void)memcpy(dptr_chain, dptr,
536 				     sizeof(struct pdu_adv_adi));
537 
538 			dptr += sizeof(struct pdu_adv_adi);
539 			dptr_chain += sizeof(struct pdu_adv_adi);
540 		}
541 
542 		/* non-connectable non-scannable chain pdu */
543 		com_hdr_chain->adv_mode = 0;
544 
545 		/* Calc current chain PDU len */
546 		sec_len = ull_adv_aux_hdr_len_calc(com_hdr_chain, &dptr_chain);
547 
548 		/* Prefix overflowed data to chain PDU and reduce the AD data in
549 		 * in the current PDU.
550 		 */
551 		if (ad_len_overflow) {
552 			uint8_t *ad_overflow;
553 
554 			val_ptr = hdr_data;
555 			/* Copy overflowed AD data from previous PDU into this
556 			 * new chain PDU
557 			 */
558 			(void)memcpy(&ad_overflow,
559 				     &val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET],
560 				     sizeof(ad_overflow));
561 			ad_overflow += *val_ptr;
562 
563 			(void)memcpy(dptr_chain, ad_overflow, ad_len_overflow);
564 			dptr_chain += ad_len_overflow;
565 
566 			/* Reduce the AD data in the previous PDU */
567 			err = ull_adv_aux_pdu_set_clear(adv, pdu_prev, pdu,
568 							(ULL_ADV_PDU_HDR_FIELD_AD_DATA |
569 							 ULL_ADV_PDU_HDR_FIELD_AUX_PTR),
570 							0U, hdr_data);
571 			if (err) {
572 				/* NOTE: latest PDU was not consumed by LLL and
573 				 * as ull_adv_sync_pdu_alloc() has reverted back
574 				 * the double buffer with the first PDU, and
575 				 * returned the latest PDU as the new PDU, we
576 				 * need to enqueue back the new PDU which is
577 				 * infact the latest PDU.
578 				 */
579 				if (pdu_prev == pdu) {
580 					lll_adv_aux_data_enqueue(adv->lll.aux,
581 								 sec_idx);
582 				}
583 
584 				return err;
585 			}
586 
587 		}
588 
589 		/* Check AdvData overflow */
590 		if ((sec_len + ad_len_overflow + len) >
591 		    PDU_AC_PAYLOAD_SIZE_MAX) {
592 			/* NOTE: latest PDU was not consumed by LLL and
593 			 * as ull_adv_sync_pdu_alloc() has reverted back
594 			 * the double buffer with the first PDU, and
595 			 * returned the latest PDU as the new PDU, we
596 			 * need to enqueue back the new PDU which is
597 			 * infact the latest PDU.
598 			 */
599 			if (pdu_prev == pdu) {
600 				lll_adv_aux_data_enqueue(adv->lll.aux, sec_idx);
601 			}
602 
603 			return BT_HCI_ERR_PACKET_TOO_LONG;
604 		}
605 
606 		/* Fill the chain PDU length */
607 		ull_adv_aux_hdr_len_fill(com_hdr_chain, sec_len);
608 		pdu_chain->len = sec_len + ad_len_overflow + len;
609 
610 		/* Fill AD Data in chain PDU */
611 		if (ad_len_overflow != 0U) {
612 			(void)memcpy(dptr_chain, data, ad_len_overflow);
613 		}
614 
615 		if (ad_len_chain != 0U) {
616 			(void)memcpy(dptr_chain, &data[ad_len + ad_len_overflow], ad_len_chain);
617 		}
618 
619 		/* Get reference to aux ptr in superior PDU */
620 		(void)memcpy(&aux_ptr,
621 			     &hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET],
622 			     sizeof(aux_ptr));
623 
624 		/* Fill the aux offset in the previous AUX_SYNC_IND PDU */
625 		offs_us = PDU_AC_US(pdu->len, adv->lll.phy_s,
626 				    adv->lll.phy_flags) +
627 			  EVENT_B2B_MAFS_US;
628 		ull_adv_aux_ptr_fill(aux_ptr, offs_us, adv->lll.phy_s);
629 
630 		/* Remove/Release any previous chain PDUs */
631 		pdu_chain_prev = lll_adv_pdu_linked_next_get(pdu);
632 		if (pdu_chain_prev) {
633 			lll_adv_pdu_linked_append(NULL, pdu);
634 			lll_adv_pdu_linked_release_all(pdu_chain_prev);
635 		}
636 
637 		/* Chain the PDU */
638 		lll_adv_pdu_linked_append(pdu_chain, pdu);
639 	}
640 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */
641 
642 	if (adv->is_enabled) {
643 		struct ll_adv_aux_set *aux;
644 		struct pdu_adv *chan_res_pdu;
645 		uint8_t tmp_idx;
646 
647 		aux = HDR_LLL2ULL(adv->lll.aux);
648 		if (!aux->is_started) {
649 			uint32_t ticks_slot_overhead;
650 			uint32_t ticks_anchor;
651 			uint32_t ret;
652 
653 			/* Keep aux interval equal or higher than primary PDU
654 			 * interval.
655 			 * Use periodic interval units to represent the
656 			 * periodic behavior of scheduling of AUX_ADV_IND PDUs
657 			 * so that it is grouped with similar interval units
658 			 * used for ACL Connections, Periodic Advertising and
659 			 * BIG radio events.
660 			 */
661 			aux->interval =
662 				DIV_ROUND_UP(((uint64_t)adv->interval *
663 						  ADV_INT_UNIT_US) +
664 						 HAL_TICKER_TICKS_TO_US(
665 							ULL_ADV_RANDOM_DELAY),
666 						 PERIODIC_INT_UNIT_US);
667 
668 			/* TODO: Find the anchor before the group of
669 			 *       active Periodic Advertising events, so
670 			 *       that auxiliary sets are grouped such
671 			 *       that auxiliary sets and Periodic
672 			 *       Advertising sets are non-overlapping
673 			 *       for the same event interval.
674 			 */
675 			ticks_anchor =
676 				ticker_ticks_now_get() +
677 				HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
678 
679 			ticks_slot_overhead =
680 				ull_adv_aux_evt_init(aux, &ticks_anchor);
681 
682 			ret = ull_adv_aux_start(aux, ticks_anchor,
683 						ticks_slot_overhead);
684 			if (ret) {
685 				/* NOTE: This failure, to start an auxiliary
686 				 * channel radio event shall not occur unless
687 				 * a defect in the controller design.
688 				 */
689 				return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
690 			}
691 
692 			aux->is_started = 1;
693 		}
694 
695 		/* Update primary channel reservation */
696 		chan_res_pdu = lll_adv_data_alloc(&adv->lll, &tmp_idx);
697 		err = ull_adv_time_update(adv, chan_res_pdu, NULL);
698 		if (err) {
699 			return err;
700 		}
701 
702 		ARG_UNUSED(tmp_idx);
703 	}
704 
705 	lll_adv_aux_data_enqueue(adv->lll.aux, sec_idx);
706 
707 	if (!IS_ENABLED(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK) ||
708 	    op == BT_HCI_LE_EXT_ADV_OP_FIRST_FRAG ||
709 	    op == BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA ||
710 	    op == BT_HCI_LE_EXT_ADV_OP_UNCHANGED_DATA) {
711 		lll_adv_data_enqueue(&adv->lll, pri_idx);
712 	}
713 
714 	/* Check if Extended Advertising Data is complete */
715 	adv->is_ad_data_cmplt = (op >= BT_HCI_LE_EXT_ADV_OP_LAST_FRAG);
716 
717 	return 0;
718 }
719 
ll_adv_aux_sr_data_set(uint8_t handle,uint8_t op,uint8_t frag_pref,uint8_t len,uint8_t const * const data)720 uint8_t ll_adv_aux_sr_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref,
721 			       uint8_t len, uint8_t const *const data)
722 {
723 	uint8_t hdr_data[ULL_ADV_HDR_DATA_LEN_SIZE +
724 			 ULL_ADV_HDR_DATA_ADI_PTR_SIZE +
725 			 ULL_ADV_HDR_DATA_LEN_SIZE +
726 			 ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE +
727 			 ULL_ADV_HDR_DATA_LEN_SIZE +
728 			 ULL_ADV_HDR_DATA_DATA_PTR_SIZE +
729 			 ULL_ADV_HDR_DATA_LEN_SIZE];
730 	struct pdu_adv *pri_pdu_prev;
731 	struct pdu_adv *sec_pdu_prev;
732 	struct pdu_adv *sr_pdu_prev;
733 	uint8_t pri_idx, sec_idx;
734 	uint16_t hdr_add_fields;
735 	struct ll_adv_set *adv;
736 	struct pdu_adv *sr_pdu;
737 	struct lll_adv *lll;
738 	uint8_t *val_ptr;
739 	uint8_t sr_idx;
740 	uint8_t err;
741 
742 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK)
743 	uint8_t ad_len_overflow;
744 	uint8_t ad_len_chain;
745 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */
746 
747 	/* Get the advertising set instance */
748 	adv = ull_adv_is_created_get(handle);
749 	if (!adv) {
750 		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
751 	}
752 
753 	/* Do not use Common Extended Advertising Header Format if not extended
754 	 * advertising.
755 	 */
756 	lll = &adv->lll;
757 	pri_pdu_prev = lll_adv_data_peek(lll);
758 	if (pri_pdu_prev->type != PDU_ADV_TYPE_EXT_IND) {
759 		if ((op != BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA) ||
760 		    (len > PDU_AC_LEG_DATA_SIZE_MAX)) {
761 			return BT_HCI_ERR_INVALID_PARAM;
762 		}
763 		return ull_scan_rsp_set(adv, len, data);
764 	}
765 
766 	/* Can only set complete data if advertising is enabled */
767 	if (adv->is_enabled && (op != BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA)) {
768 		return BT_HCI_ERR_CMD_DISALLOWED;
769 	}
770 
771 	/* Data can be discarded only using 0x03 op */
772 	if ((op != BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA) && !len) {
773 		return BT_HCI_ERR_INVALID_PARAM;
774 	}
775 
776 	/* Scannable advertising shall have aux context allocated */
777 	LL_ASSERT(lll->aux);
778 
779 	/* Get reference to previous secondary channel PDU */
780 	sec_pdu_prev = lll_adv_aux_data_peek(lll->aux);
781 
782 	/* Can only discard data on non-scannable instances */
783 	if (!(sec_pdu_prev->adv_ext_ind.adv_mode & BT_HCI_LE_ADV_PROP_SCAN) &&
784 	    len) {
785 		return BT_HCI_ERR_INVALID_PARAM;
786 	}
787 
788 	/* Cannot discard scan response if scannable advertising is enabled */
789 	if (adv->is_enabled &&
790 	    (sec_pdu_prev->adv_ext_ind.adv_mode & BT_HCI_LE_ADV_PROP_SCAN) &&
791 	    !len) {
792 		return BT_HCI_ERR_CMD_DISALLOWED;
793 	}
794 
795 	/* Get reference to previous scan response PDU */
796 	sr_pdu_prev = lll_adv_scan_rsp_peek(lll);
797 
798 	/* Get reference to next scan response  PDU */
799 	sr_pdu = lll_adv_aux_scan_rsp_alloc(lll, &sr_idx);
800 
801 	/* Prepare the AD data as parameter to update in PDU */
802 	/* Use length = 0 and NULL pointer to retain old data in the PDU.
803 	 * Use length = 0 and valid pointer of `data` (auto/local variable) to
804 	 * remove old data.
805 	 * User length > 0 and valid pointer of `data` (auto/local variable) to
806 	 * set new data.
807 	 */
808 	val_ptr = hdr_data;
809 	if ((IS_ENABLED(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK) && (
810 	     op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG ||
811 	     op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG)) ||
812 	    op == BT_HCI_LE_EXT_ADV_OP_UNCHANGED_DATA) {
813 		*val_ptr++ = 0U;
814 		(void)memset((void *)val_ptr, 0U,
815 			     ULL_ADV_HDR_DATA_DATA_PTR_SIZE);
816 	} else {
817 		*val_ptr++ = len;
818 		(void)memcpy(val_ptr, &data, sizeof(data));
819 	}
820 
821 	if (false) {
822 
823 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK)
824 	} else if (op == BT_HCI_LE_EXT_ADV_OP_UNCHANGED_DATA) {
825 		hdr_add_fields = ULL_ADV_PDU_HDR_FIELD_AD_DATA;
826 		err = ull_adv_aux_pdu_set_clear(adv, sr_pdu_prev, sr_pdu,
827 						hdr_add_fields, 0U, hdr_data);
828 
829 		/* No AD data overflow */
830 		ad_len_overflow = 0U;
831 
832 		/* No AD data in chain PDU */
833 		ad_len_chain = 0U;
834 
835 		/* pri_idx and sec_idx not used later in code in this function
836 		 */
837 		pri_idx = 0U;
838 		sec_idx = 0U;
839 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */
840 
841 	} else if (!IS_ENABLED(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK) ||
842 		   (op == BT_HCI_LE_EXT_ADV_OP_FIRST_FRAG ||
843 		    op == BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA)) {
844 		struct pdu_adv_adi *adi;
845 
846 		/* If ADI in scan response is not supported then we do not
847 		 * need reference to ADI in auxiliary PDU
848 		 */
849 		hdr_add_fields = 0U;
850 
851 		/* Add ADI if support enabled */
852 		if (IS_ENABLED(CONFIG_BT_CTRL_ADV_ADI_IN_SCAN_RSP)) {
853 			/* We need to get reference to ADI in auxiliary PDU */
854 			hdr_add_fields |= ULL_ADV_PDU_HDR_FIELD_ADI;
855 
856 			/* Update DID by passing NULL reference for ADI */
857 			(void)memset((void *)val_ptr, 0,
858 				     sizeof(struct pdu_adv_adi *));
859 
860 			/* Data place holder is after ADI */
861 			val_ptr += sizeof(struct pdu_adv_adi *);
862 
863 			/* Place holder and reference to data passed and
864 			 * old reference to be returned
865 			 */
866 			*val_ptr++ = len;
867 			(void)memcpy(val_ptr, &data, sizeof(data));
868 		}
869 
870 		/* Trigger DID update */
871 		err = ull_adv_aux_hdr_set_clear(adv, hdr_add_fields, 0U,
872 						hdr_data, &pri_idx, &sec_idx);
873 		if (err) {
874 			return err;
875 		}
876 
877 		if ((op == BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA) && !len) {
878 			sr_pdu->len = 0;
879 			goto sr_data_set_did_update;
880 		}
881 
882 		if (IS_ENABLED(CONFIG_BT_CTRL_ADV_ADI_IN_SCAN_RSP)) {
883 			(void)memcpy(&adi,
884 				     &hdr_data[ULL_ADV_HDR_DATA_ADI_PTR_OFFSET],
885 				     sizeof(struct pdu_adv_adi *));
886 		}
887 
888 		if (op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG ||
889 		    op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG) {
890 			/* Append fragment to existing data */
891 			hdr_add_fields |= ULL_ADV_PDU_HDR_FIELD_ADVA |
892 					  ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND;
893 			err = ull_adv_aux_pdu_set_clear(adv, sr_pdu_prev, sr_pdu,
894 							hdr_add_fields,
895 							0U,
896 							hdr_data);
897 		} else {
898 			/* Add AD Data and remove any prior presence of Aux Ptr */
899 			hdr_add_fields |= ULL_ADV_PDU_HDR_FIELD_ADVA |
900 					  ULL_ADV_PDU_HDR_FIELD_AD_DATA;
901 			err = ull_adv_aux_pdu_set_clear(adv, sr_pdu_prev, sr_pdu,
902 						hdr_add_fields,
903 						ULL_ADV_PDU_HDR_FIELD_AUX_PTR,
904 						hdr_data);
905 		}
906 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK)
907 		if (err == BT_HCI_ERR_PACKET_TOO_LONG) {
908 			uint8_t ad_len_offset;
909 
910 			ad_len_offset = ULL_ADV_HDR_DATA_DATA_PTR_OFFSET +
911 					ULL_ADV_HDR_DATA_DATA_PTR_SIZE;
912 			if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_ADI) {
913 				ad_len_offset +=
914 					ULL_ADV_HDR_DATA_ADI_PTR_OFFSET +
915 					ULL_ADV_HDR_DATA_ADI_PTR_SIZE;
916 			}
917 			ad_len_overflow = hdr_data[ad_len_offset];
918 
919 			/* Prepare the AD data as parameter to update in
920 			 * PDU
921 			 */
922 			val_ptr = hdr_data;
923 
924 			/* Place holder for ADI field reference to be
925 			 * returned
926 			 */
927 			if (hdr_add_fields &
928 			    ULL_ADV_PDU_HDR_FIELD_ADI) {
929 				val_ptr++;
930 				(void)memcpy(val_ptr, &adi,
931 					     sizeof(struct pdu_adv_adi *));
932 				val_ptr += sizeof(struct pdu_adv_adi *);
933 			}
934 
935 			/* Place holder and reference to data passed and
936 			 * old reference to be returned
937 			 */
938 			*val_ptr++ = len - ad_len_overflow;
939 			(void)memcpy(val_ptr, &data, sizeof(data));
940 
941 			err = ull_adv_aux_pdu_set_clear(adv, sr_pdu_prev,
942 						sr_pdu, hdr_add_fields,
943 						ULL_ADV_PDU_HDR_FIELD_AUX_PTR,
944 						hdr_data);
945 		}
946 
947 		if (!err) {
948 			/* Fragment into chain PDU if len > 191 bytes */
949 			if (len > PDU_AC_EXT_AD_DATA_LEN_MAX) {
950 				/* Prepare the AD data as parameter to update in
951 				 * PDU
952 				 */
953 				val_ptr = hdr_data;
954 
955 				/* Place holder for ADI field reference to be
956 				 * returned
957 				 */
958 				if (hdr_add_fields &
959 				    ULL_ADV_PDU_HDR_FIELD_ADI) {
960 					val_ptr++;
961 					val_ptr += sizeof(struct pdu_adv_adi *);
962 				}
963 
964 				/* Place holder for aux ptr reference to be
965 				 * returned
966 				 */
967 				val_ptr++;
968 				val_ptr += sizeof(uint8_t *);
969 
970 				/* Place holder and reference to data passed and
971 				 * old reference to be returned
972 				 */
973 				*val_ptr = PDU_AC_EXT_AD_DATA_LEN_MAX;
974 				(void)memcpy(&val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET],
975 					     &data, sizeof(data));
976 
977 				/* Calculate the overflow chain PDU's AD data
978 				 * length
979 				 */
980 				ad_len_overflow =
981 					len - PDU_AC_EXT_AD_DATA_LEN_MAX;
982 
983 				/* No AD data in chain PDU besides the
984 				 * overflow
985 				 */
986 				ad_len_chain = 0U;
987 			} else {
988 				struct pdu_adv *pdu_chain;
989 
990 				/* Remove/Release any previous chain PDU
991 				 * allocations
992 				 */
993 				pdu_chain = lll_adv_pdu_linked_next_get(sr_pdu);
994 				if (pdu_chain) {
995 					lll_adv_pdu_linked_append(NULL, sr_pdu);
996 					lll_adv_pdu_linked_release_all(pdu_chain);
997 				}
998 
999 				/* No AD data overflow */
1000 				ad_len_overflow = 0U;
1001 
1002 				/* No AD data in chain PDU */
1003 				ad_len_chain = 0U;
1004 			}
1005 		} else {
1006 			/* No AD data overflow */
1007 			ad_len_overflow = 0U;
1008 
1009 			/* No AD data in chain PDU */
1010 			ad_len_chain = 0U;
1011 		}
1012 	} else {
1013 		struct pdu_adv *pdu_chain_prev;
1014 		struct pdu_adv *pdu_chain;
1015 		uint16_t ad_len_total;
1016 		uint8_t ad_len_prev;
1017 
1018 		/* Traverse to next set clear hdr data parameter */
1019 		val_ptr += sizeof(data);
1020 
1021 		/* Traverse to the last chain PDU */
1022 		ad_len_total = 0U;
1023 		pdu_chain_prev = sr_pdu_prev;
1024 		pdu_chain = sr_pdu;
1025 		do {
1026 			/* Prepare for aux ptr field reference to be returned, hence
1027 			 * second parameter will be for AD data field.
1028 			 */
1029 			*val_ptr = 0U;
1030 			(void)memset((void *)&val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET],
1031 				     0U, ULL_ADV_HDR_DATA_DATA_PTR_SIZE);
1032 
1033 			sr_pdu_prev = pdu_chain_prev;
1034 			sr_pdu = pdu_chain;
1035 
1036 			/* Add Aux Ptr field if not already present */
1037 			hdr_add_fields = ULL_ADV_PDU_HDR_FIELD_AD_DATA |
1038 					 ULL_ADV_PDU_HDR_FIELD_AUX_PTR;
1039 			err = ull_adv_aux_pdu_set_clear(adv, sr_pdu_prev,
1040 							sr_pdu, hdr_add_fields,
1041 							0U, hdr_data);
1042 			LL_ASSERT(!err || (err == BT_HCI_ERR_PACKET_TOO_LONG));
1043 
1044 			/* Get PDUs previous AD data length */
1045 			ad_len_prev =
1046 				hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET +
1047 					 ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE];
1048 
1049 			/* Check of max supported AD data len */
1050 			ad_len_total += ad_len_prev;
1051 			if ((ad_len_total + len) >
1052 			    CONFIG_BT_CTLR_ADV_DATA_LEN_MAX) {
1053 				/* NOTE: latest PDU was not consumed by LLL and
1054 				 * as ull_adv_sync_pdu_alloc() has reverted back
1055 				 * the double buffer with the first PDU, and
1056 				 * returned the latest PDU as the new PDU, we
1057 				 * need to enqueue back the new PDU which is
1058 				 * infact the latest PDU.
1059 				 */
1060 				if (sr_pdu_prev == sr_pdu) {
1061 					lll_adv_scan_rsp_enqueue(lll, sr_idx);
1062 				}
1063 
1064 				return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
1065 			}
1066 
1067 			pdu_chain_prev = lll_adv_pdu_linked_next_get(sr_pdu_prev);
1068 			pdu_chain = lll_adv_pdu_linked_next_get(sr_pdu);
1069 			LL_ASSERT((pdu_chain_prev && pdu_chain) ||
1070 				  (!pdu_chain_prev && !pdu_chain));
1071 		} while (pdu_chain_prev);
1072 
1073 		if (err == BT_HCI_ERR_PACKET_TOO_LONG) {
1074 			ad_len_overflow =
1075 				hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET +
1076 					 ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE +
1077 					 ULL_ADV_HDR_DATA_DATA_PTR_OFFSET +
1078 					 ULL_ADV_HDR_DATA_DATA_PTR_SIZE];
1079 
1080 			/* Prepare for aux ptr field reference to be returned,
1081 			 * hence second parameter will be for AD data field.
1082 			 * Fill it with reduced AD data length.
1083 			 */
1084 			*val_ptr = ad_len_prev - ad_len_overflow;
1085 
1086 			/* AD data len in chain PDU */
1087 			ad_len_chain = len;
1088 
1089 			/* Proceed to add chain PDU */
1090 			err = 0U;
1091 		} else {
1092 			/* No AD data overflow */
1093 			ad_len_overflow = 0U;
1094 
1095 			/* No AD data in chain PDU */
1096 			ad_len_chain = 0U;
1097 		}
1098 
1099 		/* pri_idx and sec_idx not used later in code in this function
1100 		 */
1101 		pri_idx = 0U;
1102 		sec_idx = 0U;
1103 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */
1104 	}
1105 	if (err) {
1106 		return err;
1107 	}
1108 
1109 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK)
1110 	if ((op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG) ||
1111 	    (op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG) ||
1112 	    ad_len_overflow) {
1113 		struct pdu_adv_com_ext_adv *com_hdr_chain;
1114 		struct pdu_adv_com_ext_adv *com_hdr;
1115 		struct pdu_adv_ext_hdr *hdr_chain;
1116 		struct pdu_adv_aux_ptr *aux_ptr;
1117 		struct pdu_adv *pdu_chain_prev;
1118 		struct pdu_adv_ext_hdr hdr;
1119 		struct pdu_adv *pdu_chain;
1120 		uint8_t aux_ptr_offset;
1121 		uint8_t *dptr_chain;
1122 		uint32_t offs_us;
1123 		uint16_t sec_len;
1124 		uint8_t *dptr;
1125 
1126 		/* Get reference to flags in superior PDU */
1127 		com_hdr = &sr_pdu->adv_ext_ind;
1128 		if (com_hdr->ext_hdr_len) {
1129 			hdr = com_hdr->ext_hdr;
1130 		} else {
1131 			*(uint8_t *)&hdr = 0U;
1132 		}
1133 		dptr = com_hdr->ext_hdr.data;
1134 
1135 		/* Allocate new PDU */
1136 		pdu_chain = lll_adv_pdu_alloc_pdu_adv();
1137 		LL_ASSERT(pdu_chain);
1138 
1139 		/* Populate the appended chain PDU */
1140 		pdu_chain->type = PDU_ADV_TYPE_AUX_CHAIN_IND;
1141 		pdu_chain->rfu = 0U;
1142 		pdu_chain->chan_sel = 0U;
1143 		pdu_chain->tx_addr = 0U;
1144 		pdu_chain->rx_addr = 0U;
1145 		pdu_chain->len = 0U;
1146 
1147 		com_hdr_chain = &pdu_chain->adv_ext_ind;
1148 		hdr_chain = (void *)&com_hdr_chain->ext_hdr_adv_data[0];
1149 		dptr_chain = (void *)hdr_chain;
1150 
1151 		/* Flags */
1152 		*dptr_chain = 0U;
1153 
1154 		/* ADI flag, mandatory if superior PDU has it */
1155 		if (hdr.adi) {
1156 			hdr_chain->adi = 1U;
1157 		}
1158 
1159 		/* Proceed to next byte if any flags present */
1160 		if (*dptr_chain) {
1161 			dptr_chain++;
1162 		}
1163 
1164 		/* Start adding fields corresponding to flags here, if any */
1165 
1166 		/* AdvA flag */
1167 		if (hdr.adv_addr) {
1168 			dptr += BDADDR_SIZE;
1169 		}
1170 
1171 		/* TgtA flag */
1172 		if (hdr.tgt_addr) {
1173 			dptr += BDADDR_SIZE;
1174 		}
1175 
1176 		/* No CTEInfo in Extended Advertising */
1177 
1178 		/* ADI flag */
1179 		if (hdr_chain->adi) {
1180 			(void)memcpy(dptr_chain, dptr,
1181 				     sizeof(struct pdu_adv_adi));
1182 
1183 			dptr += sizeof(struct pdu_adv_adi);
1184 			dptr_chain += sizeof(struct pdu_adv_adi);
1185 		}
1186 
1187 		/* non-connectable non-scannable chain pdu */
1188 		com_hdr_chain->adv_mode = 0;
1189 
1190 		/* Calc current chain PDU len */
1191 		sec_len = ull_adv_aux_hdr_len_calc(com_hdr_chain, &dptr_chain);
1192 
1193 		/* Prefix overflowed data to chain PDU and reduce the AD data in
1194 		 * in the current PDU.
1195 		 */
1196 		if (ad_len_overflow) {
1197 			uint8_t *ad_overflow;
1198 
1199 			/* Copy overflowed AD data from previous PDU into this
1200 			 * new chain PDU
1201 			 */
1202 			(void)memcpy(&ad_overflow,
1203 				     &val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET],
1204 				     sizeof(ad_overflow));
1205 			ad_overflow += *val_ptr;
1206 			(void)memcpy(dptr_chain, ad_overflow, ad_len_overflow);
1207 			dptr_chain += ad_len_overflow;
1208 
1209 			hdr_add_fields |= ULL_ADV_PDU_HDR_FIELD_AUX_PTR;
1210 
1211 			/* Reduce the AD data in the previous PDU */
1212 			err = ull_adv_aux_pdu_set_clear(adv, sr_pdu_prev,
1213 							sr_pdu, hdr_add_fields,
1214 							0U, hdr_data);
1215 			if (err) {
1216 				/* NOTE: latest PDU was not consumed by LLL and
1217 				 * as ull_adv_sync_pdu_alloc() has reverted back
1218 				 * the double buffer with the first PDU, and
1219 				 * returned the latest PDU as the new PDU, we
1220 				 * need to enqueue back the new PDU which is
1221 				 * infact the latest PDU.
1222 				 */
1223 				if (sr_pdu_prev == sr_pdu) {
1224 					lll_adv_scan_rsp_enqueue(lll, sr_idx);
1225 				}
1226 
1227 				return err;
1228 			}
1229 
1230 			/* AD data len in chain PDU besides the overflow */
1231 			len = ad_len_chain;
1232 		}
1233 
1234 		/* Check AdvData overflow */
1235 		if ((sec_len + ad_len_overflow + len) >
1236 		    PDU_AC_PAYLOAD_SIZE_MAX) {
1237 			/* NOTE: latest PDU was not consumed by LLL and
1238 			 * as ull_adv_sync_pdu_alloc() has reverted back
1239 			 * the double buffer with the first PDU, and
1240 			 * returned the latest PDU as the new PDU, we
1241 			 * need to enqueue back the new PDU which is
1242 			 * infact the latest PDU.
1243 			 */
1244 			if (sr_pdu_prev == sr_pdu) {
1245 				lll_adv_aux_data_enqueue(adv->lll.aux, sr_idx);
1246 			}
1247 
1248 			return BT_HCI_ERR_PACKET_TOO_LONG;
1249 		}
1250 
1251 		/* Fill the chain PDU length */
1252 		ull_adv_aux_hdr_len_fill(com_hdr_chain, sec_len);
1253 		pdu_chain->len = sec_len + ad_len_overflow + len;
1254 
1255 		/* Fill AD Data in chain PDU */
1256 		(void)memcpy(dptr_chain, data, len);
1257 
1258 		/* Get reference to aux ptr in superior PDU */
1259 		aux_ptr_offset = ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET;
1260 		if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_ADI) {
1261 			aux_ptr_offset +=  ULL_ADV_HDR_DATA_ADI_PTR_OFFSET +
1262 					   ULL_ADV_HDR_DATA_ADI_PTR_SIZE;
1263 		}
1264 		(void)memcpy(&aux_ptr, &hdr_data[aux_ptr_offset],
1265 			     sizeof(aux_ptr));
1266 
1267 		/* Fill the aux offset in the previous AUX_SYNC_IND PDU */
1268 		offs_us = PDU_AC_US(sr_pdu->len, adv->lll.phy_s,
1269 				    adv->lll.phy_flags) +
1270 			  EVENT_B2B_MAFS_US;
1271 		ull_adv_aux_ptr_fill(aux_ptr, offs_us, adv->lll.phy_s);
1272 
1273 		/* Remove/Release any previous chain PDUs */
1274 		pdu_chain_prev = lll_adv_pdu_linked_next_get(sr_pdu);
1275 		if (pdu_chain_prev) {
1276 			lll_adv_pdu_linked_append(NULL, sr_pdu);
1277 			lll_adv_pdu_linked_release_all(pdu_chain_prev);
1278 		}
1279 
1280 		/* Chain the PDU */
1281 		lll_adv_pdu_linked_append(pdu_chain, sr_pdu);
1282 	}
1283 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */
1284 
1285 sr_data_set_did_update:
1286 	if ((!IS_ENABLED(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK) &&
1287 	     (op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG ||
1288 	      op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG)) ||
1289 	    (op == BT_HCI_LE_EXT_ADV_OP_FIRST_FRAG) ||
1290 	    (op == BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA)) {
1291 		/* NOTE: No update to primary channel PDU time reservation  */
1292 
1293 		lll_adv_aux_data_enqueue(adv->lll.aux, sec_idx);
1294 		lll_adv_data_enqueue(&adv->lll, pri_idx);
1295 
1296 		sr_pdu->type = PDU_ADV_TYPE_AUX_SCAN_RSP;
1297 		sr_pdu->rfu = 0U;
1298 		sr_pdu->chan_sel = 0U;
1299 		sr_pdu->rx_addr = 0U;
1300 		if (sr_pdu->len) {
1301 			sr_pdu->adv_ext_ind.adv_mode = 0U;
1302 			sr_pdu->tx_addr = sec_pdu_prev->tx_addr;
1303 			(void)memcpy(&sr_pdu->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
1304 				     &sec_pdu_prev->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
1305 				     BDADDR_SIZE);
1306 		} else {
1307 			sr_pdu->tx_addr = 0U;
1308 		}
1309 	}
1310 
1311 	lll_adv_scan_rsp_enqueue(lll, sr_idx);
1312 
1313 	return 0;
1314 }
1315 
ll_adv_aux_max_data_length_get(void)1316 uint16_t ll_adv_aux_max_data_length_get(void)
1317 {
1318 	return CONFIG_BT_CTLR_ADV_DATA_LEN_MAX;
1319 }
1320 
ll_adv_aux_set_count_get(void)1321 uint8_t ll_adv_aux_set_count_get(void)
1322 {
1323 	return BT_CTLR_ADV_SET;
1324 }
1325 
ll_adv_aux_set_remove(uint8_t handle)1326 uint8_t ll_adv_aux_set_remove(uint8_t handle)
1327 {
1328 	struct ll_adv_set *adv;
1329 	struct lll_adv *lll;
1330 
1331 	/* Get the advertising set instance */
1332 	adv = ull_adv_is_created_get(handle);
1333 	if (!adv) {
1334 		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
1335 	}
1336 
1337 	if (adv->is_enabled) {
1338 		return BT_HCI_ERR_CMD_DISALLOWED;
1339 	}
1340 
1341 	lll = &adv->lll;
1342 
1343 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
1344 	if (lll->sync) {
1345 		struct ll_adv_sync_set *sync;
1346 
1347 		sync = HDR_LLL2ULL(lll->sync);
1348 
1349 		if (sync->is_enabled) {
1350 			return BT_HCI_ERR_CMD_DISALLOWED;
1351 		}
1352 		lll->sync = NULL;
1353 
1354 		ull_adv_sync_release(sync);
1355 	}
1356 #endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
1357 
1358 #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
1359 	if (adv->df_cfg) {
1360 		if (adv->df_cfg->is_enabled) {
1361 			return BT_HCI_ERR_CMD_DISALLOWED;
1362 		}
1363 
1364 		ull_df_adv_cfg_release(adv->df_cfg);
1365 		adv->df_cfg = NULL;
1366 	}
1367 #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
1368 
1369 	/* Release auxiliary channel set */
1370 	if (lll->aux) {
1371 		struct ll_adv_aux_set *aux;
1372 
1373 		aux = HDR_LLL2ULL(lll->aux);
1374 		lll->aux = NULL;
1375 
1376 		ull_adv_aux_release(aux);
1377 	}
1378 
1379 	/* Dequeue and release, advertising and scan response data, to keep
1380 	 * one initial primary channel PDU each for the advertising set.
1381 	 * This is done to prevent common extended payload format contents from
1382 	 * being overwritten and corrupted due to same primary PDU buffer being
1383 	 * used to remove AdvA and other fields are moved over in its place when
1384 	 * auxiliary PDU is allocated to new advertising set.
1385 	 */
1386 	(void)lll_adv_data_dequeue(&adv->lll.adv_data);
1387 	(void)lll_adv_data_dequeue(&adv->lll.scan_rsp);
1388 
1389 	/* Make the advertising set available for new advertisements */
1390 	adv->is_created = 0;
1391 
1392 	return BT_HCI_ERR_SUCCESS;
1393 }
1394 
ll_adv_aux_set_clear(void)1395 uint8_t ll_adv_aux_set_clear(void)
1396 {
1397 	uint8_t retval = BT_HCI_ERR_SUCCESS;
1398 	uint8_t handle;
1399 	uint8_t err;
1400 
1401 	for (handle = 0; handle < BT_CTLR_ADV_SET; ++handle) {
1402 		err = ll_adv_aux_set_remove(handle);
1403 		if (err == BT_HCI_ERR_CMD_DISALLOWED) {
1404 			retval = err;
1405 		}
1406 	}
1407 
1408 	return retval;
1409 }
1410 
ull_adv_aux_init(void)1411 int ull_adv_aux_init(void)
1412 {
1413 	int err;
1414 
1415 	err = lll_rand_get(&did_unique, sizeof(did_unique));
1416 	if (err) {
1417 		return err;
1418 	}
1419 
1420 	err = init_reset();
1421 	if (err) {
1422 		return err;
1423 	}
1424 
1425 	return 0;
1426 }
1427 
ull_adv_aux_reset_finalize(void)1428 int ull_adv_aux_reset_finalize(void)
1429 {
1430 	int err;
1431 
1432 	err = init_reset();
1433 	if (err) {
1434 		return err;
1435 	}
1436 
1437 	return 0;
1438 }
1439 
ull_adv_aux_chm_update(void)1440 uint8_t ull_adv_aux_chm_update(void)
1441 {
1442 	/* For each created extended advertising set */
1443 	for (uint8_t handle = 0; handle < BT_CTLR_ADV_SET; ++handle) {
1444 		struct ll_adv_aux_set *aux;
1445 		struct ll_adv_set *adv;
1446 		uint8_t chm_last;
1447 
1448 		adv = ull_adv_is_created_get(handle);
1449 		if (!adv || !adv->lll.aux) {
1450 			continue;
1451 		}
1452 
1453 		aux = HDR_LLL2ULL(adv->lll.aux);
1454 		if (aux->chm_last != aux->chm_first) {
1455 			/* TODO: Handle previous Channel Map Update being in
1456 			 * progress
1457 			 */
1458 			continue;
1459 		}
1460 
1461 		/* Append the channelMapNew that will be picked up by ULL */
1462 		chm_last = aux->chm_last + 1;
1463 		if (chm_last == DOUBLE_BUFFER_SIZE) {
1464 			chm_last = 0U;
1465 		}
1466 		aux->chm[chm_last].data_chan_count =
1467 			ull_chan_map_get(aux->chm[chm_last].data_chan_map);
1468 		aux->chm_last = chm_last;
1469 
1470 		if (IS_ENABLED(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) && !aux->is_started) {
1471 			/* Ticker not started yet, apply new channel map now
1472 			 * Note that it should be safe to modify chm_first here
1473 			 * since advertising is not active
1474 			 */
1475 			aux->chm_first = aux->chm_last;
1476 		}
1477 	}
1478 
1479 	/* TODO: Should failure due to Channel Map Update being already in
1480 	 *       progress be returned to caller?
1481 	 */
1482 	return 0;
1483 }
1484 
ull_adv_aux_hdr_set_clear(struct ll_adv_set * adv,uint16_t sec_hdr_add_fields,uint16_t sec_hdr_rem_fields,void * hdr_data,uint8_t * pri_idx,uint8_t * sec_idx)1485 uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
1486 				  uint16_t sec_hdr_add_fields,
1487 				  uint16_t sec_hdr_rem_fields,
1488 				  void *hdr_data,
1489 				  uint8_t *pri_idx, uint8_t *sec_idx)
1490 {
1491 	struct pdu_adv_com_ext_adv *pri_com_hdr, *pri_com_hdr_prev;
1492 	struct pdu_adv_com_ext_adv *sec_com_hdr, *sec_com_hdr_prev;
1493 	struct pdu_adv_ext_hdr *hdr, pri_hdr, pri_hdr_prev;
1494 	struct pdu_adv_ext_hdr sec_hdr, sec_hdr_prev;
1495 	struct pdu_adv *pri_pdu, *pri_pdu_prev;
1496 	struct pdu_adv *sec_pdu_prev, *sec_pdu;
1497 	struct pdu_adv_adi *pri_adi, *sec_adi;
1498 	uint8_t *pri_dptr, *pri_dptr_prev;
1499 	uint8_t *sec_dptr, *sec_dptr_prev;
1500 	struct pdu_adv_aux_ptr *aux_ptr;
1501 	uint8_t pri_len, sec_len_prev;
1502 	struct lll_adv_aux *lll_aux;
1503 	uint8_t *ad_fragment = NULL;
1504 	uint8_t ad_fragment_len = 0;
1505 	struct ll_adv_aux_set *aux;
1506 	struct pdu_adv_adi *adi;
1507 	struct lll_adv *lll;
1508 	uint8_t is_aux_new;
1509 	uint8_t *ad_data;
1510 	uint16_t sec_len;
1511 	uint8_t ad_len;
1512 	uint16_t did;
1513 
1514 	lll = &adv->lll;
1515 
1516 	/* Can't have both flags set here since both use 'hdr_data' param */
1517 	LL_ASSERT(!(sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_ADVA) ||
1518 		  !(sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AD_DATA));
1519 
1520 	/* Get reference to previous primary PDU data */
1521 	pri_pdu_prev = lll_adv_data_peek(lll);
1522 	if (pri_pdu_prev->type != PDU_ADV_TYPE_EXT_IND) {
1523 		if (sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AD_DATA) {
1524 			/* pick the data length */
1525 			ad_len = *((uint8_t *)hdr_data);
1526 			hdr_data = (uint8_t *)hdr_data + sizeof(ad_len);
1527 
1528 			/* pick the reference to data */
1529 			(void)memcpy(&ad_data, hdr_data, sizeof(ad_data));
1530 
1531 			return ull_adv_data_set(adv, ad_len, ad_data);
1532 		}
1533 
1534 		return BT_HCI_ERR_CMD_DISALLOWED;
1535 	}
1536 
1537 	pri_com_hdr_prev = (void *)&pri_pdu_prev->adv_ext_ind;
1538 	hdr = (void *)pri_com_hdr_prev->ext_hdr_adv_data;
1539 	if (pri_com_hdr_prev->ext_hdr_len) {
1540 		pri_hdr_prev = *hdr;
1541 	} else {
1542 		*(uint8_t *)&pri_hdr_prev = 0U;
1543 	}
1544 	pri_dptr_prev = hdr->data;
1545 
1546 	/* Advertising data are not supported by scannable instances */
1547 	if ((sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AD_DATA) &&
1548 	    (pri_com_hdr_prev->adv_mode & BT_HCI_LE_ADV_PROP_SCAN)) {
1549 		return BT_HCI_ERR_INVALID_PARAM;
1550 	}
1551 
1552 	/* Get reference to new primary PDU data buffer */
1553 	pri_pdu = lll_adv_data_alloc(lll, pri_idx);
1554 	pri_pdu->type = pri_pdu_prev->type;
1555 	pri_pdu->rfu = 0U;
1556 	pri_pdu->chan_sel = 0U;
1557 	pri_com_hdr = (void *)&pri_pdu->adv_ext_ind;
1558 	pri_com_hdr->adv_mode = pri_com_hdr_prev->adv_mode;
1559 	hdr = (void *)pri_com_hdr->ext_hdr_adv_data;
1560 	pri_dptr = hdr->data;
1561 	*(uint8_t *)&pri_hdr = 0U;
1562 
1563 	/* Get the reference to aux instance */
1564 	lll_aux = lll->aux;
1565 	if (!lll_aux) {
1566 		aux = ull_adv_aux_acquire(lll);
1567 		if (!aux) {
1568 			LL_ASSERT(pri_pdu != pri_pdu_prev);
1569 
1570 			return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
1571 		}
1572 
1573 		lll_aux = &aux->lll;
1574 
1575 		if (IS_ENABLED(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)) {
1576 			ull_adv_aux_created(adv);
1577 		}
1578 
1579 		is_aux_new = 1U;
1580 	} else {
1581 		aux = HDR_LLL2ULL(lll_aux);
1582 		is_aux_new = 0U;
1583 	}
1584 
1585 	/* Get reference to previous secondary PDU data */
1586 	sec_pdu_prev = lll_adv_aux_data_peek(lll_aux);
1587 	sec_com_hdr_prev = (void *)&sec_pdu_prev->adv_ext_ind;
1588 	hdr = (void *)sec_com_hdr_prev->ext_hdr_adv_data;
1589 	if (!is_aux_new) {
1590 		sec_hdr_prev = *hdr;
1591 	} else {
1592 		/* Initialize only those fields used to copy into new PDU
1593 		 * buffer.
1594 		 */
1595 		sec_pdu_prev->tx_addr = 0U;
1596 		sec_pdu_prev->rx_addr = 0U;
1597 		sec_pdu_prev->len = PDU_AC_EXT_HEADER_SIZE_MIN;
1598 		*(uint8_t *)hdr = 0U;
1599 		*(uint8_t *)&sec_hdr_prev = 0U;
1600 	}
1601 	sec_dptr_prev = hdr->data;
1602 
1603 	/* Get reference to new secondary PDU data buffer */
1604 	sec_pdu = lll_adv_aux_data_alloc(lll_aux, sec_idx);
1605 	sec_pdu->type = pri_pdu->type;
1606 	sec_pdu->rfu = 0U;
1607 	sec_pdu->chan_sel = 0U;
1608 
1609 	sec_pdu->tx_addr = sec_pdu_prev->tx_addr;
1610 	sec_pdu->rx_addr = sec_pdu_prev->rx_addr;
1611 
1612 	sec_com_hdr = (void *)&sec_pdu->adv_ext_ind;
1613 	sec_com_hdr->adv_mode = pri_com_hdr->adv_mode;
1614 	hdr = (void *)sec_com_hdr->ext_hdr_adv_data;
1615 	sec_dptr = hdr->data;
1616 	*(uint8_t *)&sec_hdr = 0U;
1617 
1618 	/* AdvA flag */
1619 	/* NOTE: as we will use auxiliary packet, we remove AdvA in primary
1620 	 * channel, i.e. do nothing to not add AdvA in the primary PDU.
1621 	 * AdvA can be either set explicitly (i.e. needs own_addr_type to be
1622 	 * set), can be copied from primary PDU (i.e. adding AD to existing set)
1623 	 * or can be copied from previous secondary PDU.
1624 	 */
1625 	sec_hdr.adv_addr = 1;
1626 	if (sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_ADVA) {
1627 		uint8_t own_addr_type = *(uint8_t *)hdr_data;
1628 
1629 		/* Move to next hdr_data */
1630 		hdr_data = (uint8_t *)hdr_data + sizeof(own_addr_type);
1631 
1632 		sec_pdu->tx_addr = own_addr_type & 0x1;
1633 	} else if (pri_hdr_prev.adv_addr) {
1634 		sec_pdu->tx_addr = pri_pdu_prev->tx_addr;
1635 	} else if (sec_hdr_prev.adv_addr) {
1636 		sec_pdu->tx_addr = sec_pdu_prev->tx_addr;
1637 	} else {
1638 		/* We do not have valid address info, this should not happen */
1639 		return BT_HCI_ERR_UNSPECIFIED;
1640 	}
1641 	pri_pdu->tx_addr = 0U;
1642 
1643 	if (pri_hdr_prev.adv_addr) {
1644 		pri_dptr_prev += BDADDR_SIZE;
1645 	}
1646 	if (sec_hdr_prev.adv_addr) {
1647 		sec_dptr_prev += BDADDR_SIZE;
1648 	}
1649 	sec_dptr += BDADDR_SIZE;
1650 
1651 	/* No TargetA in primary and secondary channel for undirected.
1652 	 * Move from primary to secondary PDU, if present in primary PDU.
1653 	 */
1654 	if (pri_hdr_prev.tgt_addr) {
1655 		sec_hdr.tgt_addr = 1U;
1656 		sec_pdu->rx_addr = pri_pdu_prev->rx_addr;
1657 		sec_dptr += BDADDR_SIZE;
1658 
1659 	/* Retain the target address if present in the previous PDU */
1660 	} else if (!(sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_ADVA) &&
1661 		   sec_hdr_prev.tgt_addr) {
1662 		sec_hdr.tgt_addr = 1U;
1663 		sec_pdu->rx_addr = sec_pdu_prev->rx_addr;
1664 		sec_dptr += BDADDR_SIZE;
1665 	}
1666 	pri_pdu->rx_addr = 0U;
1667 
1668 	if (pri_hdr_prev.tgt_addr) {
1669 		pri_dptr_prev += BDADDR_SIZE;
1670 	}
1671 
1672 	if (sec_hdr_prev.tgt_addr) {
1673 		sec_dptr_prev += BDADDR_SIZE;
1674 	}
1675 
1676 	/* No CTEInfo flag in primary and secondary channel PDU */
1677 
1678 	/* ADI flag */
1679 	if (pri_hdr_prev.adi) {
1680 		pri_dptr_prev += sizeof(struct pdu_adv_adi);
1681 	}
1682 	pri_hdr.adi = 1;
1683 	pri_dptr += sizeof(struct pdu_adv_adi);
1684 	if (sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_ADI) {
1685 		sec_hdr.adi = 1U;
1686 		/* return the size of ADI structure */
1687 		*(uint8_t *)hdr_data = sizeof(struct pdu_adv_adi);
1688 		hdr_data = (uint8_t *)hdr_data + sizeof(uint8_t);
1689 		/* pick the reference to ADI param */
1690 		(void)memcpy(&adi, hdr_data, sizeof(struct pdu_adv_adi *));
1691 		/* return the pointer to ADI struct inside the PDU */
1692 		(void)memcpy(hdr_data, &sec_dptr, sizeof(sec_dptr));
1693 		hdr_data = (uint8_t *)hdr_data + sizeof(sec_dptr);
1694 		sec_dptr += sizeof(struct pdu_adv_adi);
1695 	} else {
1696 		sec_hdr.adi = 1;
1697 		adi = NULL;
1698 		sec_dptr += sizeof(struct pdu_adv_adi);
1699 	}
1700 	if (sec_hdr_prev.adi) {
1701 		sec_dptr_prev += sizeof(struct pdu_adv_adi);
1702 	}
1703 
1704 	/* AuxPtr flag */
1705 	if (pri_hdr_prev.aux_ptr) {
1706 		pri_dptr_prev += sizeof(struct pdu_adv_aux_ptr);
1707 	}
1708 	pri_hdr.aux_ptr = 1;
1709 	pri_dptr += sizeof(struct pdu_adv_aux_ptr);
1710 
1711 	if (sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AUX_PTR) {
1712 		sec_hdr.aux_ptr = 1;
1713 		aux_ptr = NULL;
1714 
1715 		/* return the size of aux pointer structure */
1716 		*(uint8_t *)hdr_data = sizeof(struct pdu_adv_aux_ptr);
1717 		hdr_data = (uint8_t *)hdr_data + sizeof(uint8_t);
1718 
1719 		/* return the pointer to aux pointer struct inside the PDU
1720 		 * buffer
1721 		 */
1722 		(void)memcpy(hdr_data, &sec_dptr, sizeof(sec_dptr));
1723 		hdr_data = (uint8_t *)hdr_data + sizeof(sec_dptr);
1724 	} else if (!(sec_hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_AUX_PTR) &&
1725 		   sec_hdr_prev.aux_ptr) {
1726 		sec_hdr.aux_ptr = 1;
1727 		aux_ptr = (void *)sec_dptr_prev;
1728 	} else {
1729 		aux_ptr = NULL;
1730 	}
1731 	if (sec_hdr_prev.aux_ptr) {
1732 		sec_dptr_prev += sizeof(struct pdu_adv_aux_ptr);
1733 	}
1734 	if (sec_hdr.aux_ptr) {
1735 		sec_dptr += sizeof(struct pdu_adv_aux_ptr);
1736 	}
1737 
1738 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
1739 	struct pdu_adv_sync_info *sync_info;
1740 
1741 	/* No SyncInfo flag in primary channel PDU */
1742 	/* Add/Remove SyncInfo flag in secondary channel PDU */
1743 	if (sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_SYNC_INFO) {
1744 		sec_hdr.sync_info = 1;
1745 		sync_info = NULL;
1746 
1747 		/* return the size of sync info structure */
1748 		*(uint8_t *)hdr_data = sizeof(*sync_info);
1749 		hdr_data = (uint8_t *)hdr_data + sizeof(uint8_t);
1750 
1751 		/* return the pointer to sync info struct inside the PDU
1752 		 * buffer
1753 		 */
1754 		(void)memcpy(hdr_data, &sec_dptr, sizeof(sec_dptr));
1755 		hdr_data = (uint8_t *)hdr_data + sizeof(sec_dptr);
1756 	} else if (!(sec_hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_SYNC_INFO) &&
1757 		   sec_hdr_prev.sync_info) {
1758 		sec_hdr.sync_info = 1;
1759 		sync_info = (void *)sec_dptr_prev;
1760 	} else {
1761 		sync_info = NULL;
1762 	}
1763 	if (sec_hdr_prev.sync_info) {
1764 		sec_dptr_prev += sizeof(*sync_info);
1765 	}
1766 	if (sec_hdr.sync_info) {
1767 		sec_dptr += sizeof(*sync_info);
1768 	}
1769 #endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
1770 
1771 	/* Tx Power flag */
1772 	if (pri_hdr_prev.tx_pwr) {
1773 		pri_dptr_prev++;
1774 
1775 		/* C1, Tx Power is optional on the LE 1M PHY, and
1776 		 * reserved for future use on the LE Coded PHY.
1777 		 */
1778 		if (lll->phy_p != PHY_CODED) {
1779 			pri_hdr.tx_pwr = 1;
1780 			pri_dptr++;
1781 		} else {
1782 			sec_hdr.tx_pwr = 1;
1783 		}
1784 	}
1785 	if (sec_hdr_prev.tx_pwr) {
1786 		sec_dptr_prev++;
1787 
1788 		sec_hdr.tx_pwr = 1;
1789 	}
1790 	if (sec_hdr.tx_pwr) {
1791 		sec_dptr++;
1792 	}
1793 
1794 	/* No ACAD in primary channel PDU */
1795 	/* TODO: ACAD in secondary channel PDU */
1796 
1797 	/* Calc primary PDU len */
1798 	pri_len = ull_adv_aux_hdr_len_calc(pri_com_hdr, &pri_dptr);
1799 
1800 	/* Calc previous secondary PDU len */
1801 	sec_len_prev = ull_adv_aux_hdr_len_calc(sec_com_hdr_prev,
1802 					       &sec_dptr_prev);
1803 
1804 	/* Did we parse beyond PDU length? */
1805 	if (sec_len_prev > sec_pdu_prev->len) {
1806 		/* we should not encounter invalid length */
1807 		/* FIXME: release allocations */
1808 		return BT_HCI_ERR_UNSPECIFIED;
1809 	}
1810 
1811 	/* Calc current secondary PDU len */
1812 	sec_len = ull_adv_aux_hdr_len_calc(sec_com_hdr, &sec_dptr);
1813 
1814 	/* AD Data, add or remove */
1815 	if (sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AD_DATA) {
1816 		uint8_t ad_len_prev;
1817 
1818 		/* remember the new ad data len */
1819 		ad_len = *(uint8_t *)hdr_data;
1820 
1821 		/* return prev ad data length */
1822 		ad_len_prev = sec_pdu_prev->len - sec_len_prev;
1823 		*(uint8_t *)hdr_data = ad_len_prev;
1824 		hdr_data = (uint8_t *)hdr_data + sizeof(ad_len);
1825 
1826 		/* remember the reference to new ad data */
1827 		(void)memcpy(&ad_data, hdr_data, sizeof(ad_data));
1828 
1829 		/* return the reference to prev ad data */
1830 		(void)memcpy(hdr_data, &sec_dptr_prev, sizeof(sec_dptr_prev));
1831 		hdr_data = (uint8_t *)hdr_data + sizeof(sec_dptr_prev);
1832 
1833 		/* unchanged data */
1834 		if (!ad_len && !ad_data) {
1835 			ad_len = ad_len_prev;
1836 			ad_data = sec_dptr_prev;
1837 		}
1838 	} else if (sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND) {
1839 		/* Calc the previous AD data length in auxiliary PDU */
1840 		ad_len = sec_pdu_prev->len - sec_len_prev;
1841 		ad_data = sec_dptr_prev;
1842 
1843 		/* Append the new ad data fragment */
1844 		ad_fragment_len = *(uint8_t *)hdr_data;
1845 		hdr_data = (uint8_t *)hdr_data + sizeof(ad_fragment_len);
1846 		(void)memcpy(&ad_fragment, hdr_data, sizeof(ad_fragment));
1847 		hdr_data = (uint8_t *)hdr_data + sizeof(ad_fragment);
1848 	} else if (!(sec_hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_AD_DATA)) {
1849 		/* Calc the previous AD data length in auxiliary PDU */
1850 		ad_len = sec_pdu_prev->len - sec_len_prev;
1851 		ad_data = sec_dptr_prev;
1852 	} else {
1853 		ad_len = 0U;
1854 		ad_data = NULL;
1855 	}
1856 
1857 	/* Check Max Advertising Data Length */
1858 	if (ad_len + ad_fragment_len > CONFIG_BT_CTLR_ADV_DATA_LEN_MAX) {
1859 		return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
1860 	}
1861 
1862 	/* Check AdvData overflow */
1863 	/* TODO: need aux_chain_ind support */
1864 	if ((sec_len + ad_len + ad_fragment_len) > PDU_AC_PAYLOAD_SIZE_MAX) {
1865 		/* return excess length */
1866 		*(uint8_t *)hdr_data = sec_len + ad_len + ad_fragment_len -
1867 				       PDU_AC_PAYLOAD_SIZE_MAX;
1868 
1869 		if (pri_pdu == pri_pdu_prev) {
1870 			lll_adv_data_enqueue(&adv->lll, *pri_idx);
1871 		}
1872 		if (sec_pdu == sec_pdu_prev) {
1873 			lll_adv_aux_data_enqueue(adv->lll.aux, *sec_idx);
1874 		}
1875 
1876 		/* Will use packet too long error to determine fragmenting
1877 		 * long data
1878 		 */
1879 		return BT_HCI_ERR_PACKET_TOO_LONG;
1880 	}
1881 
1882 	/* set the primary PDU len */
1883 	ull_adv_aux_hdr_len_fill(pri_com_hdr, pri_len);
1884 	pri_pdu->len = pri_len;
1885 
1886 	/* set the secondary PDU len */
1887 	ull_adv_aux_hdr_len_fill(sec_com_hdr, sec_len);
1888 	sec_pdu->len = sec_len + ad_len + ad_fragment_len;
1889 
1890 	/* Start filling pri and sec PDU payload based on flags from here
1891 	 * ==============================================================
1892 	 */
1893 
1894 	/* No AdvData in primary channel PDU */
1895 	/* Fill AdvData in secondary PDU */
1896 	(void)memmove(sec_dptr, ad_data, ad_len);
1897 
1898 	if (ad_fragment) {
1899 		(void)memcpy(sec_dptr + ad_len, ad_fragment, ad_fragment_len);
1900 	}
1901 
1902 	/* Early exit if no flags set */
1903 	if (!sec_com_hdr->ext_hdr_len) {
1904 		return 0;
1905 	}
1906 
1907 	/* No ACAD in primary channel PDU */
1908 	/* TODO: Fill ACAD in secondary channel PDU */
1909 
1910 	/* Tx Power */
1911 	if (pri_hdr.tx_pwr) {
1912 		*--pri_dptr = *--pri_dptr_prev;
1913 	} else if (sec_hdr.tx_pwr) {
1914 		*--sec_dptr = *--sec_dptr_prev;
1915 	}
1916 
1917 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
1918 	/* No SyncInfo in primary channel PDU */
1919 	/* Fill SyncInfo in secondary channel PDU */
1920 	if (sec_hdr_prev.sync_info) {
1921 		sec_dptr_prev -= sizeof(*sync_info);
1922 	}
1923 
1924 	if (sec_hdr.sync_info) {
1925 		sec_dptr -= sizeof(*sync_info);
1926 	}
1927 
1928 	if (sync_info) {
1929 		(void)memmove(sec_dptr, sync_info, sizeof(*sync_info));
1930 	}
1931 #endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
1932 
1933 	/* AuxPtr */
1934 	if (pri_hdr_prev.aux_ptr) {
1935 		pri_dptr_prev -= sizeof(struct pdu_adv_aux_ptr);
1936 	}
1937 	pri_dptr -= sizeof(struct pdu_adv_aux_ptr);
1938 	ull_adv_aux_ptr_fill((void *)pri_dptr, 0U, lll->phy_s);
1939 
1940 	if (sec_hdr_prev.aux_ptr) {
1941 		sec_dptr_prev -= sizeof(struct pdu_adv_aux_ptr);
1942 	}
1943 	if (sec_hdr.aux_ptr) {
1944 		sec_dptr -= sizeof(struct pdu_adv_aux_ptr);
1945 	}
1946 
1947 	if (aux_ptr) {
1948 		(void)memmove(sec_dptr, aux_ptr, sizeof(*aux_ptr));
1949 	}
1950 
1951 	/* ADI */
1952 	if (pri_hdr_prev.adi) {
1953 		pri_dptr_prev -= sizeof(struct pdu_adv_adi);
1954 	}
1955 	if (sec_hdr_prev.adi) {
1956 		sec_dptr_prev -= sizeof(struct pdu_adv_adi);
1957 	}
1958 
1959 	pri_dptr -= sizeof(struct pdu_adv_adi);
1960 	sec_dptr -= sizeof(struct pdu_adv_adi);
1961 
1962 	pri_adi = (void *)pri_dptr;
1963 	sec_adi = (void *)sec_dptr;
1964 
1965 	if (!adi) {
1966 		/* The DID for a specific SID shall be unique.
1967 		 */
1968 		did = ull_adv_aux_did_next_unique_get(adv->sid);
1969 	} else {
1970 		did = PDU_ADV_ADI_DID_GET(adi);
1971 	}
1972 
1973 	did = sys_cpu_to_le16(did);
1974 	PDU_ADV_ADI_DID_SID_SET(pri_adi, did, adv->sid);
1975 	PDU_ADV_ADI_DID_SID_SET(sec_adi, did, adv->sid);
1976 
1977 	/* No CTEInfo field in primary channel PDU */
1978 
1979 	/* No TargetA non-conn non-scan advertising, but present in directed
1980 	 * advertising.
1981 	 */
1982 	if (sec_hdr.tgt_addr) {
1983 		void *bdaddr;
1984 
1985 		if (sec_hdr_prev.tgt_addr) {
1986 			sec_dptr_prev -= BDADDR_SIZE;
1987 			bdaddr = sec_dptr_prev;
1988 		} else {
1989 			pri_dptr_prev -= BDADDR_SIZE;
1990 			bdaddr = pri_dptr_prev;
1991 		}
1992 
1993 		sec_dptr -= BDADDR_SIZE;
1994 
1995 		(void)memcpy(sec_dptr, bdaddr, BDADDR_SIZE);
1996 	}
1997 
1998 	/* No AdvA in primary channel due to AuxPtr being added */
1999 
2000 	/* NOTE: AdvA in aux channel is also filled at enable and RPA
2001 	 * timeout
2002 	 */
2003 	if (sec_hdr.adv_addr) {
2004 		void *bdaddr;
2005 
2006 		if (sec_hdr_prev.adv_addr) {
2007 			sec_dptr_prev -= BDADDR_SIZE;
2008 			bdaddr = sec_dptr_prev;
2009 		} else {
2010 			pri_dptr_prev -= BDADDR_SIZE;
2011 			bdaddr = pri_dptr_prev;
2012 		}
2013 
2014 		sec_dptr -= BDADDR_SIZE;
2015 
2016 		(void)memcpy(sec_dptr, bdaddr, BDADDR_SIZE);
2017 	}
2018 
2019 	/* Set the common extended header format flags in the current primary
2020 	 * PDU
2021 	 */
2022 	if (pri_com_hdr->ext_hdr_len != 0) {
2023 		pri_com_hdr->ext_hdr = pri_hdr;
2024 	}
2025 
2026 	/* Set the common extended header format flags in the current secondary
2027 	 * PDU
2028 	 */
2029 	if (sec_com_hdr->ext_hdr_len != 0) {
2030 		sec_com_hdr->ext_hdr = sec_hdr;
2031 	}
2032 
2033 #if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_LINK)
2034 	ull_adv_aux_chain_pdu_duplicate(sec_pdu_prev, sec_pdu, aux_ptr,
2035 					adv->lll.phy_s, adv->lll.phy_flags,
2036 					EVENT_B2B_MAFS_US);
2037 #endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_LINK */
2038 
2039 	/* Update auxiliary channel event time reservation */
2040 	if (aux->is_started) {
2041 		struct pdu_adv *pdu_scan;
2042 		uint8_t err;
2043 
2044 		pdu_scan = lll_adv_scan_rsp_peek(lll);
2045 		err = aux_time_update(aux, sec_pdu, pdu_scan);
2046 		if (err) {
2047 			return err;
2048 		}
2049 	}
2050 
2051 	return 0;
2052 }
2053 
ull_adv_aux_pdu_set_clear(struct ll_adv_set * adv,struct pdu_adv * pdu_prev,struct pdu_adv * pdu,uint16_t hdr_add_fields,uint16_t hdr_rem_fields,void * hdr_data)2054 uint8_t ull_adv_aux_pdu_set_clear(struct ll_adv_set *adv,
2055 				  struct pdu_adv *pdu_prev,
2056 				  struct pdu_adv *pdu,
2057 				  uint16_t hdr_add_fields,
2058 				  uint16_t hdr_rem_fields,
2059 				  void *hdr_data)
2060 {
2061 	struct pdu_adv_com_ext_adv *com_hdr, *com_hdr_prev;
2062 	struct pdu_adv_ext_hdr hdr = { 0 }, hdr_prev = { 0 };
2063 	struct pdu_adv_aux_ptr *aux_ptr, *aux_ptr_prev;
2064 	uint8_t *ad_fragment = NULL;
2065 	uint8_t ad_fragment_len = 0;
2066 	uint8_t *dptr, *dptr_prev;
2067 	struct pdu_adv_adi *adi;
2068 	uint8_t acad_len_prev;
2069 	uint8_t hdr_buf_len;
2070 	uint8_t len_prev;
2071 	uint8_t *ad_data;
2072 	uint8_t acad_len;
2073 #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
2074 	uint8_t cte_info;
2075 #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
2076 	uint8_t ad_len;
2077 	uint16_t len;
2078 
2079 	/* Get common pointers from reference to previous tertiary PDU data */
2080 	com_hdr_prev = (void *)&pdu_prev->adv_ext_ind;
2081 	if (pdu_prev->len && com_hdr_prev->ext_hdr_len) {
2082 		hdr_prev = com_hdr_prev->ext_hdr;
2083 	} else {
2084 		com_hdr_prev->ext_hdr_len = 0U;
2085 	}
2086 	dptr_prev = com_hdr_prev->ext_hdr.data;
2087 
2088 	/* Set common fields in reference to new tertiary PDU data buffer */
2089 	pdu->type = pdu_prev->type;
2090 	pdu->rfu = 0U;
2091 	pdu->chan_sel = 0U;
2092 
2093 	pdu->tx_addr = pdu_prev->tx_addr;
2094 	pdu->rx_addr = pdu_prev->rx_addr;
2095 
2096 	/* Get common pointers from current tertiary PDU data.
2097 	 * It is possible that the current tertiary is the same as
2098 	 * previous one. It may happen if update periodic advertising
2099 	 * chain in place.
2100 	 */
2101 	com_hdr = (void *)&pdu->adv_ext_ind;
2102 	com_hdr->adv_mode = com_hdr_prev->adv_mode;
2103 	dptr = com_hdr->ext_hdr.data;
2104 
2105 	/* AdvA flag */
2106 	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_ADVA) {
2107 		hdr.adv_addr = 1U;
2108 		dptr += BDADDR_SIZE;
2109 	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_ADVA) &&
2110 		   hdr_prev.adv_addr) {
2111 		hdr.adv_addr = 1U;
2112 		pdu->tx_addr = pdu_prev->tx_addr;
2113 
2114 		dptr += BDADDR_SIZE;
2115 	}
2116 	if (hdr_prev.adv_addr) {
2117 		dptr_prev += BDADDR_SIZE;
2118 	}
2119 
2120 	/* TargetA flag */
2121 	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_TARGETA) {
2122 		hdr.tgt_addr = 1U;
2123 		dptr += BDADDR_SIZE;
2124 	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_TARGETA) &&
2125 		   hdr_prev.tgt_addr) {
2126 		hdr.tgt_addr = 1U;
2127 		pdu->rx_addr = pdu_prev->rx_addr;
2128 
2129 		dptr += BDADDR_SIZE;
2130 	}
2131 	if (hdr_prev.tgt_addr) {
2132 		dptr_prev += BDADDR_SIZE;
2133 	}
2134 
2135 #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
2136 	/* If requested add or update CTEInfo */
2137 	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) {
2138 		hdr.cte_info = 1;
2139 		cte_info = *(uint8_t *)hdr_data;
2140 		hdr_data = (uint8_t *)hdr_data + 1;
2141 		dptr += sizeof(struct pdu_cte_info);
2142 	/* If CTEInfo exists in prev and is not requested to be removed */
2143 	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) &&
2144 		   hdr_prev.cte_info) {
2145 		hdr.cte_info = 1;
2146 		cte_info = 0U; /* value not used, will be read from prev PDU */
2147 		dptr += sizeof(struct pdu_cte_info);
2148 	} else {
2149 		cte_info = 0U; /* value not used */
2150 	}
2151 
2152 	/* If CTEInfo exists in prev PDU */
2153 	if (hdr_prev.cte_info) {
2154 		dptr_prev += sizeof(struct pdu_cte_info);
2155 	}
2156 #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
2157 
2158 	/* ADI */
2159 	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_ADI) {
2160 		hdr.adi = 1U;
2161 		/* return the size of ADI structure */
2162 		*(uint8_t *)hdr_data = sizeof(struct pdu_adv_adi);
2163 		hdr_data = (uint8_t *)hdr_data + sizeof(uint8_t);
2164 		/* pick the reference to ADI param */
2165 		(void)memcpy(&adi, hdr_data, sizeof(struct pdu_adv_adi *));
2166 		/* return the pointer to ADI struct inside the PDU */
2167 		(void)memcpy(hdr_data, &dptr, sizeof(dptr));
2168 		hdr_data = (uint8_t *)hdr_data + sizeof(dptr);
2169 		dptr += sizeof(struct pdu_adv_adi);
2170 	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_ADI) &&
2171 		   hdr_prev.adi) {
2172 		hdr.adi = 1U;
2173 		adi = (void *)dptr_prev;
2174 		dptr += sizeof(struct pdu_adv_adi);
2175 	} else {
2176 		adi = NULL;
2177 	}
2178 	if (hdr_prev.adi) {
2179 		dptr_prev += sizeof(struct pdu_adv_adi);
2180 	}
2181 
2182 	/* AuxPtr - will be added if AUX_CHAIN_IND is required */
2183 	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AUX_PTR) {
2184 		hdr.aux_ptr = 1;
2185 		aux_ptr_prev = NULL;
2186 		aux_ptr = (void *)dptr;
2187 
2188 		/* return the size of aux pointer structure */
2189 		*(uint8_t *)hdr_data = sizeof(struct pdu_adv_aux_ptr);
2190 		hdr_data = (uint8_t *)hdr_data + sizeof(uint8_t);
2191 
2192 		/* return the pointer to aux pointer struct inside the PDU
2193 		 * buffer
2194 		 */
2195 		(void)memcpy(hdr_data, &dptr, sizeof(dptr));
2196 		hdr_data = (uint8_t *)hdr_data + sizeof(dptr);
2197 	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_AUX_PTR) &&
2198 		   hdr_prev.aux_ptr) {
2199 		hdr.aux_ptr = 1;
2200 		aux_ptr_prev = (void *)dptr_prev;
2201 		aux_ptr = (void *)dptr;
2202 	} else {
2203 		aux_ptr_prev = NULL;
2204 		aux_ptr = NULL;
2205 	}
2206 	if (hdr_prev.aux_ptr) {
2207 		dptr_prev += sizeof(struct pdu_adv_aux_ptr);
2208 	}
2209 	if (hdr.aux_ptr) {
2210 		dptr += sizeof(struct pdu_adv_aux_ptr);
2211 	}
2212 
2213 	/* SyncInfo flag */
2214 	if (hdr_prev.sync_info) {
2215 		hdr.sync_info = 1;
2216 		dptr_prev += sizeof(struct pdu_adv_sync_info);
2217 		dptr += sizeof(struct pdu_adv_sync_info);
2218 	}
2219 
2220 	/* Tx Power flag */
2221 	if (hdr_prev.tx_pwr) {
2222 		dptr_prev++;
2223 
2224 		hdr.tx_pwr = 1;
2225 		dptr++;
2226 	}
2227 
2228 	/* Calc previous ACAD len and update PDU len */
2229 	len_prev = dptr_prev - (uint8_t *)com_hdr_prev;
2230 	hdr_buf_len = com_hdr_prev->ext_hdr_len +
2231 		      PDU_AC_EXT_HEADER_SIZE_MIN;
2232 	if (len_prev <= hdr_buf_len) {
2233 		/* There are some data, except ACAD, in extended header if len_prev
2234 		 * equals to hdr_buf_len. There is ACAD if the size of len_prev
2235 		 * is smaller than hdr_buf_len.
2236 		 */
2237 		acad_len_prev = hdr_buf_len - len_prev;
2238 		len_prev += acad_len_prev;
2239 		dptr_prev += acad_len_prev;
2240 	} else {
2241 		/* There are no data in extended header, all flags are zeros. */
2242 		acad_len_prev = 0;
2243 		/* NOTE: If no flags are set then extended header length will be
2244 		 *       zero. Under this condition the current len_prev
2245 		 *       value will be greater than extended header length,
2246 		 *       hence set len_prev to size of the length/mode
2247 		 *       field.
2248 		 */
2249 		len_prev = (pdu_prev->len) ? PDU_AC_EXT_HEADER_SIZE_MIN : 0U;
2250 		dptr_prev = (uint8_t *)com_hdr_prev + len_prev;
2251 	}
2252 
2253 	/* Did we parse beyond PDU length? */
2254 	if (len_prev > pdu_prev->len) {
2255 		/* we should not encounter invalid length */
2256 		return BT_HCI_ERR_UNSPECIFIED;
2257 	}
2258 
2259 	/* Add/Retain/Remove ACAD */
2260 	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_ACAD) {
2261 		acad_len = *(uint8_t *)hdr_data;
2262 		/* If zero length ACAD then do not reduce ACAD but return
2263 		 * return previous ACAD length.
2264 		 */
2265 		if (!acad_len) {
2266 			acad_len = acad_len_prev;
2267 		}
2268 		/* return prev ACAD length */
2269 		*(uint8_t *)hdr_data = acad_len_prev;
2270 		hdr_data = (uint8_t *)hdr_data + 1;
2271 		/* return the pointer to ACAD offset */
2272 		(void)memcpy(hdr_data, &dptr, sizeof(dptr));
2273 		hdr_data = (uint8_t *)hdr_data + sizeof(dptr);
2274 		dptr += acad_len;
2275 	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_ACAD)) {
2276 		acad_len = acad_len_prev;
2277 		dptr += acad_len_prev;
2278 	} else {
2279 		acad_len = 0U;
2280 	}
2281 
2282 	/* Calc current tertiary PDU len so far without AD data added */
2283 	len = ull_adv_aux_hdr_len_calc(com_hdr, &dptr);
2284 
2285 	/* Get Adv data from function parameters */
2286 	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AD_DATA) {
2287 		uint8_t ad_len_prev;
2288 
2289 		/* remember the new ad data len */
2290 		ad_len = *(uint8_t *)hdr_data;
2291 
2292 		/* return prev ad data length */
2293 		ad_len_prev = pdu_prev->len - len_prev;
2294 		*(uint8_t *)hdr_data = ad_len_prev;
2295 		hdr_data = (uint8_t *)hdr_data + sizeof(ad_len);
2296 
2297 		/* remember the reference to new ad data */
2298 		(void)memcpy(&ad_data, hdr_data, sizeof(ad_data));
2299 
2300 		/* return the reference to prev ad data */
2301 		(void)memcpy(hdr_data, &dptr_prev, sizeof(dptr_prev));
2302 		hdr_data = (uint8_t *)hdr_data + sizeof(dptr_prev);
2303 
2304 		/* unchanged data */
2305 		if (!ad_len && !ad_data) {
2306 			ad_len = ad_len_prev;
2307 			ad_data = dptr_prev;
2308 		}
2309 	} else if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AD_DATA_APPEND) {
2310 		ad_len = pdu_prev->len - len_prev;
2311 		ad_data = dptr_prev;
2312 
2313 		/* Append the new ad data fragment */
2314 		ad_fragment_len = *(uint8_t *)hdr_data;
2315 		hdr_data = (uint8_t *)hdr_data + sizeof(ad_fragment_len);
2316 		(void)memcpy(&ad_fragment, hdr_data, sizeof(ad_fragment));
2317 		hdr_data = (uint8_t *)hdr_data + sizeof(ad_fragment);
2318 	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_AD_DATA)) {
2319 		ad_len = pdu_prev->len - len_prev;
2320 		ad_data = dptr_prev;
2321 	} else {
2322 		ad_len = 0;
2323 		ad_data = NULL;
2324 	}
2325 
2326 	/* Check Max Advertising Data Length */
2327 	if (ad_len + ad_fragment_len > CONFIG_BT_CTLR_ADV_DATA_LEN_MAX) {
2328 		return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
2329 	}
2330 
2331 	/* Check AdvData overflow */
2332 	if ((len + ad_len + ad_fragment_len) > PDU_AC_PAYLOAD_SIZE_MAX) {
2333 		/* return excess length */
2334 		*(uint8_t *)hdr_data = len + ad_len + ad_fragment_len -
2335 				       PDU_AC_PAYLOAD_SIZE_MAX;
2336 
2337 		/* Will use packet too long error to determine fragmenting
2338 		 * long data
2339 		 */
2340 		return BT_HCI_ERR_PACKET_TOO_LONG;
2341 	}
2342 
2343 	/* set the tertiary extended header and PDU length */
2344 	ull_adv_aux_hdr_len_fill(com_hdr, len);
2345 	pdu->len = len + ad_len + ad_fragment_len;
2346 
2347 	/* Start filling tertiary PDU payload based on flags from here
2348 	 * ==============================================================
2349 	 */
2350 
2351 	/* Fill AdvData in tertiary PDU */
2352 	(void)memmove(dptr, ad_data, ad_len);
2353 
2354 	if (ad_fragment) {
2355 		(void)memcpy(dptr + ad_len, ad_fragment, ad_fragment_len);
2356 	}
2357 
2358 	/* Early exit if no flags set */
2359 	if (!com_hdr->ext_hdr_len) {
2360 		return 0;
2361 	}
2362 
2363 	/* Retain ACAD in tertiary PDU */
2364 	dptr_prev -= acad_len_prev;
2365 	if (acad_len) {
2366 		dptr -= acad_len;
2367 		(void)memmove(dptr, dptr_prev, acad_len_prev);
2368 	}
2369 
2370 	/* Tx Power */
2371 	if (hdr.tx_pwr) {
2372 		*--dptr = *--dptr_prev;
2373 	}
2374 
2375 	/* SyncInfo */
2376 	if (hdr.sync_info) {
2377 		dptr_prev -= sizeof(struct pdu_adv_sync_info);
2378 		dptr -= sizeof(struct pdu_adv_sync_info);
2379 
2380 		(void)memmove(dptr, dptr_prev,
2381 			      sizeof(struct pdu_adv_sync_info));
2382 	}
2383 
2384 	/* AuxPtr */
2385 	if (hdr_prev.aux_ptr) {
2386 		dptr_prev -= sizeof(struct pdu_adv_aux_ptr);
2387 	}
2388 	if (hdr.aux_ptr) {
2389 		dptr -= sizeof(struct pdu_adv_aux_ptr);
2390 	}
2391 	if (aux_ptr_prev) {
2392 		(void)memmove(dptr, aux_ptr_prev, sizeof(*aux_ptr_prev));
2393 	}
2394 
2395 	/* ADI */
2396 	if (hdr_prev.adi) {
2397 		dptr_prev -= sizeof(struct pdu_adv_adi);
2398 	}
2399 	if (hdr.adi) {
2400 		struct pdu_adv_adi *adi_pdu;
2401 
2402 		dptr -= sizeof(struct pdu_adv_adi);
2403 		adi_pdu = (void *)dptr;
2404 
2405 		if (!adi) {
2406 			/* The DID for a specific SID shall be unique.
2407 			 */
2408 			const uint16_t did =
2409 				sys_cpu_to_le16(ull_adv_aux_did_next_unique_get(adv->sid));
2410 			PDU_ADV_ADI_DID_SID_SET(adi_pdu, did, adv->sid);
2411 		} else {
2412 			adi_pdu->did_sid_packed[0] = adi->did_sid_packed[0];
2413 			adi_pdu->did_sid_packed[1] = adi->did_sid_packed[1];
2414 		}
2415 	}
2416 
2417 #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
2418 	if (hdr.cte_info) {
2419 		if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) {
2420 			*--dptr = cte_info;
2421 		} else {
2422 			*--dptr = *--dptr_prev;
2423 		}
2424 	}
2425 #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
2426 
2427 	/* No TargetA in non-conn non-scan advertising, but present in directed
2428 	 * advertising.
2429 	 */
2430 	if (hdr.tgt_addr) {
2431 		dptr_prev -= BDADDR_SIZE;
2432 		dptr -= BDADDR_SIZE;
2433 
2434 		(void)memmove(dptr, dptr_prev, BDADDR_SIZE);
2435 	}
2436 
2437 	/* NOTE: AdvA in aux channel is also filled at enable and RPA
2438 	 * timeout
2439 	 */
2440 	if (hdr.adv_addr) {
2441 		dptr_prev -= BDADDR_SIZE;
2442 		dptr -= BDADDR_SIZE;
2443 
2444 		(void)memmove(dptr, dptr_prev, BDADDR_SIZE);
2445 	}
2446 
2447 	if (com_hdr->ext_hdr_len != 0) {
2448 		com_hdr->ext_hdr = hdr;
2449 	}
2450 
2451 	return 0;
2452 }
2453 
ull_adv_aux_did_next_unique_get(uint8_t sid)2454 uint16_t ull_adv_aux_did_next_unique_get(uint8_t sid)
2455 {
2456 	/* The DID is 12 bits and did_unique may overflow without any negative
2457 	 * consequences.
2458 	 */
2459 	return BIT_MASK(12) & did_unique[sid]++;
2460 }
2461 
ull_adv_aux_ptr_fill(struct pdu_adv_aux_ptr * aux_ptr,uint32_t offs_us,uint8_t phy_s)2462 void ull_adv_aux_ptr_fill(struct pdu_adv_aux_ptr *aux_ptr, uint32_t offs_us,
2463 			  uint8_t phy_s)
2464 {
2465 	uint32_t offs;
2466 	uint8_t phy;
2467 
2468 	/* NOTE: Channel Index and Aux Offset will be set on every advertiser's
2469 	 * event prepare when finding the auxiliary event's ticker offset.
2470 	 * Here we fill initial values.
2471 	 */
2472 	aux_ptr->chan_idx = 0U;
2473 
2474 	aux_ptr->ca = (lll_clock_ppm_local_get() <= SCA_50_PPM) ?
2475 		      SCA_VALUE_50_PPM : SCA_VALUE_500_PPM;
2476 
2477 	offs = offs_us / OFFS_UNIT_30_US;
2478 	if (!!(offs >> OFFS_UNIT_BITS)) {
2479 		offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US);
2480 		aux_ptr->offs_units = OFFS_UNIT_VALUE_300_US;
2481 	} else {
2482 		aux_ptr->offs_units = OFFS_UNIT_VALUE_30_US;
2483 	}
2484 	phy = find_lsb_set(phy_s) - 1;
2485 
2486 	aux_ptr->offs_phy_packed[0] = offs & 0xFF;
2487 	aux_ptr->offs_phy_packed[1] = ((offs>>8) & 0x1F) + (phy << 5);
2488 }
2489 
2490 #if (CONFIG_BT_CTLR_ADV_AUX_SET > 0)
ull_adv_aux_handle_get(struct ll_adv_aux_set * aux)2491 inline uint8_t ull_adv_aux_handle_get(struct ll_adv_aux_set *aux)
2492 {
2493 	return mem_index_get(aux, ll_adv_aux_pool,
2494 			     sizeof(struct ll_adv_aux_set));
2495 }
2496 
ull_adv_aux_lll_handle_get(struct lll_adv_aux * lll)2497 uint8_t ull_adv_aux_lll_handle_get(struct lll_adv_aux *lll)
2498 {
2499 	return ull_adv_aux_handle_get((void *)lll->hdr.parent);
2500 }
2501 
ull_adv_aux_evt_init(struct ll_adv_aux_set * aux,uint32_t * ticks_anchor)2502 uint32_t ull_adv_aux_evt_init(struct ll_adv_aux_set *aux,
2503 			      uint32_t *ticks_anchor)
2504 {
2505 	uint32_t ticks_slot_overhead;
2506 	uint32_t time_us;
2507 
2508 	time_us = aux_time_min_get(aux);
2509 
2510 	/* TODO: active_to_start feature port */
2511 	aux->ull.ticks_active_to_start = 0;
2512 	aux->ull.ticks_prepare_to_start =
2513 		HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US);
2514 	aux->ull.ticks_preempt_to_start =
2515 		HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US);
2516 	aux->ull.ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us);
2517 
2518 	if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) {
2519 		ticks_slot_overhead = MAX(aux->ull.ticks_active_to_start,
2520 					  aux->ull.ticks_prepare_to_start);
2521 	} else {
2522 		ticks_slot_overhead = 0;
2523 	}
2524 
2525 #if defined(CONFIG_BT_CTLR_SCHED_ADVANCED)
2526 	uint32_t ticks_anchor_aux;
2527 	uint32_t ticks_slot;
2528 	int err;
2529 
2530 #if defined(CONFIG_BT_CTLR_ADV_RESERVE_MAX)
2531 	time_us = ull_adv_aux_time_get(aux, PDU_AC_PAYLOAD_SIZE_MAX,
2532 				       PDU_AC_PAYLOAD_SIZE_MAX);
2533 	ticks_slot = HAL_TICKER_US_TO_TICKS_CEIL(time_us);
2534 #else
2535 	ticks_slot = aux->ull.ticks_slot;
2536 #endif
2537 
2538 	err = ull_sched_adv_aux_sync_free_anchor_get((ticks_slot +
2539 						      ticks_slot_overhead),
2540 						     &ticks_anchor_aux);
2541 	if (!err) {
2542 		*ticks_anchor = ticks_anchor_aux;
2543 		*ticks_anchor += HAL_TICKER_US_TO_TICKS(
2544 					MAX(EVENT_MAFS_US,
2545 					    EVENT_OVERHEAD_START_US) -
2546 					EVENT_OVERHEAD_START_US +
2547 					(EVENT_TICKER_RES_MARGIN_US << 1));
2548 	}
2549 #endif /* CONFIG_BT_CTLR_SCHED_ADVANCED */
2550 
2551 	return ticks_slot_overhead;
2552 }
2553 
2554 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
ull_adv_sync_started_stopped(struct ll_adv_aux_set * aux)2555 void ull_adv_sync_started_stopped(struct ll_adv_aux_set *aux)
2556 {
2557 	if (aux->is_started) {
2558 		struct lll_adv_sync *lll_sync = aux->lll.adv->sync;
2559 		struct ll_adv_sync_set *sync;
2560 		uint8_t aux_handle;
2561 
2562 		LL_ASSERT(lll_sync);
2563 
2564 		sync = HDR_LLL2ULL(lll_sync);
2565 		aux_handle = ull_adv_aux_handle_get(aux);
2566 
2567 		if (sync->is_started) {
2568 			uint8_t sync_handle = ull_adv_sync_handle_get(sync);
2569 
2570 			ticker_update_ext(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
2571 			   (TICKER_ID_ADV_AUX_BASE + aux_handle), 0, 0, 0, 0, 0, 0,
2572 			   ticker_update_op_cb, aux, 0,
2573 			   TICKER_ID_ADV_SYNC_BASE + sync_handle);
2574 		} else {
2575 			ticker_update_ext(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
2576 			   (TICKER_ID_ADV_AUX_BASE + aux_handle), 0, 0, 0, 0, 0, 0,
2577 			   ticker_update_op_cb, aux, 0,
2578 			   TICKER_NULL);
2579 		}
2580 	}
2581 }
2582 #endif /* CONFIG_BT_CTLR_ADV_PERIODIC && CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
2583 
ull_adv_aux_start(struct ll_adv_aux_set * aux,uint32_t ticks_anchor,uint32_t ticks_slot_overhead)2584 uint32_t ull_adv_aux_start(struct ll_adv_aux_set *aux, uint32_t ticks_anchor,
2585 			   uint32_t ticks_slot_overhead)
2586 {
2587 	uint32_t volatile ret_cb;
2588 	uint32_t interval_us;
2589 	uint8_t aux_handle;
2590 	uint32_t ret;
2591 
2592 	ull_hdr_init(&aux->ull);
2593 	aux_handle = ull_adv_aux_handle_get(aux);
2594 	interval_us = aux->interval * PERIODIC_INT_UNIT_US;
2595 
2596 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
2597 	if (aux->lll.adv->sync) {
2598 		const struct ll_adv_sync_set *sync = HDR_LLL2ULL(aux->lll.adv->sync);
2599 		uint8_t sync_handle = ull_adv_sync_handle_get(sync);
2600 
2601 		ll_adv_aux_ticker_ext[aux_handle].expire_info_id = TICKER_ID_ADV_SYNC_BASE +
2602 								  sync_handle;
2603 	} else {
2604 		ll_adv_aux_ticker_ext[aux_handle].expire_info_id = TICKER_NULL;
2605 	}
2606 
2607 	ll_adv_aux_ticker_ext[aux_handle].ext_timeout_func = ticker_cb;
2608 
2609 	ret_cb = TICKER_STATUS_BUSY;
2610 	ret = ticker_start_ext(
2611 #else /* !CONFIG_BT_CTLR_ADV_PERIODIC || !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
2612 
2613 	ret_cb = TICKER_STATUS_BUSY;
2614 	ret = ticker_start(
2615 #endif /* !CONFIG_BT_CTLR_ADV_PERIODIC || !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
2616 			   TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
2617 			   (TICKER_ID_ADV_AUX_BASE + aux_handle),
2618 			   ticks_anchor, 0U,
2619 			   HAL_TICKER_US_TO_TICKS(interval_us),
2620 			   HAL_TICKER_REMAINDER(interval_us), TICKER_NULL_LAZY,
2621 			   (aux->ull.ticks_slot + ticks_slot_overhead),
2622 			   ticker_cb, aux,
2623 			   ull_ticker_status_give, (void *)&ret_cb
2624 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
2625 			   ,
2626 			   &ll_adv_aux_ticker_ext[aux_handle]
2627 #endif /* !CONFIG_BT_CTLR_ADV_PERIODIC || !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
2628 			   );
2629 	ret = ull_ticker_status_take(ret, &ret_cb);
2630 
2631 	return ret;
2632 }
2633 
ull_adv_aux_stop(struct ll_adv_aux_set * aux)2634 int ull_adv_aux_stop(struct ll_adv_aux_set *aux)
2635 {
2636 	uint8_t aux_handle;
2637 	int err;
2638 
2639 	aux_handle = ull_adv_aux_handle_get(aux);
2640 
2641 	err = ull_ticker_stop_with_mark(TICKER_ID_ADV_AUX_BASE + aux_handle,
2642 					aux, &aux->lll);
2643 	LL_ASSERT(err == 0 || err == -EALREADY);
2644 	if (err) {
2645 		return err;
2646 	}
2647 
2648 	aux->is_started = 0U;
2649 
2650 	return 0;
2651 }
2652 
ull_adv_aux_acquire(struct lll_adv * lll)2653 struct ll_adv_aux_set *ull_adv_aux_acquire(struct lll_adv *lll)
2654 {
2655 	struct lll_adv_aux *lll_aux;
2656 	struct ll_adv_aux_set *aux;
2657 	uint8_t chm_last;
2658 	int err;
2659 
2660 	aux = aux_acquire();
2661 	if (!aux) {
2662 		return aux;
2663 	}
2664 
2665 	lll_aux = &aux->lll;
2666 	lll->aux = lll_aux;
2667 	lll_aux->adv = lll;
2668 
2669 	lll_adv_data_reset(&lll_aux->data);
2670 	err = lll_adv_aux_data_init(&lll_aux->data);
2671 	if (err) {
2672 		return NULL;
2673 	}
2674 
2675 	/* Initialize data channel calculation counter, data channel identifier,
2676 	 * and channel map to use.
2677 	 */
2678 	lll_csrand_get(&lll_aux->data_chan_counter,
2679 		       sizeof(lll_aux->data_chan_counter));
2680 	lll_csrand_get(&aux->data_chan_id, sizeof(aux->data_chan_id));
2681 	chm_last = aux->chm_first;
2682 	aux->chm_last = chm_last;
2683 	aux->chm[chm_last].data_chan_count =
2684 		ull_chan_map_get(aux->chm[chm_last].data_chan_map);
2685 
2686 
2687 	/* NOTE: ull_hdr_init(&aux->ull); is done on start */
2688 	lll_hdr_init(lll_aux, aux);
2689 
2690 	aux->is_started = 0U;
2691 
2692 	return aux;
2693 }
2694 
ull_adv_aux_release(struct ll_adv_aux_set * aux)2695 void ull_adv_aux_release(struct ll_adv_aux_set *aux)
2696 {
2697 	lll_adv_data_release(&aux->lll.data);
2698 	aux_release(aux);
2699 }
2700 
ull_adv_aux_get(uint8_t handle)2701 struct ll_adv_aux_set *ull_adv_aux_get(uint8_t handle)
2702 {
2703 	if (handle >= CONFIG_BT_CTLR_ADV_AUX_SET) {
2704 		return NULL;
2705 	}
2706 
2707 	return &ll_adv_aux_pool[handle];
2708 }
2709 
ull_adv_aux_time_get(const struct ll_adv_aux_set * aux,uint8_t pdu_len,uint8_t pdu_scan_len)2710 uint32_t ull_adv_aux_time_get(const struct ll_adv_aux_set *aux, uint8_t pdu_len,
2711 			      uint8_t pdu_scan_len)
2712 {
2713 	const struct pdu_adv *pdu;
2714 
2715 	pdu = lll_adv_aux_data_peek(&aux->lll);
2716 
2717 	return aux_time_get(aux, pdu, pdu_len, pdu_scan_len);
2718 }
2719 
2720 #if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
ull_adv_aux_offset_get(struct ll_adv_set * adv)2721 void ull_adv_aux_offset_get(struct ll_adv_set *adv)
2722 {
2723 	static memq_link_t link;
2724 	static struct mayfly mfy = {0, 0, &link, NULL, mfy_aux_offset_get};
2725 	uint32_t ret;
2726 
2727 	/* NOTE: Single mayfly instance is sufficient as primary channel PDUs
2728 	 *       use time reservation, and this mayfly shall complete within
2729 	 *       the radio event. Multiple advertising sets do not need
2730 	 *       independent mayfly allocations.
2731 	 */
2732 	mfy.param = adv;
2733 	ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_ULL_LOW, 1,
2734 			     &mfy);
2735 	LL_ASSERT(!ret);
2736 }
2737 #endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
2738 
ull_adv_aux_lll_offset_fill(struct pdu_adv * pdu,uint32_t ticks_offset,uint32_t remainder_us,uint32_t start_us)2739 struct pdu_adv_aux_ptr *ull_adv_aux_lll_offset_fill(struct pdu_adv *pdu,
2740 						    uint32_t ticks_offset,
2741 						    uint32_t remainder_us,
2742 						    uint32_t start_us)
2743 {
2744 	struct pdu_adv_com_ext_adv *pri_com_hdr;
2745 	struct pdu_adv_aux_ptr *aux_ptr;
2746 	struct pdu_adv_ext_hdr *h;
2747 	uint32_t offs;
2748 	uint8_t *ptr;
2749 
2750 	pri_com_hdr = (void *)&pdu->adv_ext_ind;
2751 	h = (void *)pri_com_hdr->ext_hdr_adv_data;
2752 	ptr = h->data;
2753 
2754 	/* traverse through adv_addr, if present */
2755 	if (h->adv_addr) {
2756 		ptr += BDADDR_SIZE;
2757 	}
2758 
2759 	/* traverse through tgt_addr, if present */
2760 	if (h->tgt_addr) {
2761 		ptr += BDADDR_SIZE;
2762 	}
2763 
2764 	/* No CTEInfo flag in primary and secondary channel PDU */
2765 
2766 	/* traverse through adi, if present */
2767 	if (h->adi) {
2768 		ptr += sizeof(struct pdu_adv_adi);
2769 	}
2770 
2771 	aux_ptr = (void *)ptr;
2772 	offs = HAL_TICKER_TICKS_TO_US(ticks_offset) + remainder_us - start_us;
2773 	offs = offs / OFFS_UNIT_30_US;
2774 	if (!!(offs >> OFFS_UNIT_BITS)) {
2775 		offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US);
2776 		aux_ptr->offs_units = OFFS_UNIT_VALUE_300_US;
2777 	} else {
2778 		aux_ptr->offs_units = OFFS_UNIT_VALUE_30_US;
2779 	}
2780 	aux_ptr->offs_phy_packed[0] = offs & 0xFF;
2781 	aux_ptr->offs_phy_packed[1] = ((offs>>8) & 0x1F) + (aux_ptr->offs_phy_packed[1] & 0xE0);
2782 
2783 	return aux_ptr;
2784 }
2785 
ull_adv_aux_done(struct node_rx_event_done * done)2786 void ull_adv_aux_done(struct node_rx_event_done *done)
2787 {
2788 	struct lll_adv_aux *lll_aux;
2789 	struct ll_adv_aux_set *aux;
2790 	struct ll_adv_set *adv;
2791 
2792 	/* Get reference to ULL context */
2793 	aux = CONTAINER_OF(done->param, struct ll_adv_aux_set, ull);
2794 	lll_aux = &aux->lll;
2795 	adv = HDR_LLL2ULL(lll_aux->adv);
2796 
2797 	/* Call the primary channel advertising done */
2798 	done->param = &adv->ull;
2799 	ull_adv_done(done);
2800 }
2801 
2802 #if defined(CONFIG_BT_CTLR_ADV_PDU_LINK)
2803 /* @brief Duplicate previous chain of PDUs into current chain of PDUs, fill the
2804  *        aux ptr field of the parent primary channel PDU with the aux offset,
2805  *        and the secondary channel PDU's PHY.
2806  *
2807  * @param[in] pdu_prev    Pointer to previous PDU's chain PDU
2808  * @param[in] pdu         Pointer to current PDU's chain PDU
2809  * @param[in] aux_ptr     Pointer to aux ptr field in the primary channel PDU
2810  * @param[in] phy_s       Secondary/auxiliary PDU PHY
2811  * @param[in] phy_flags   Secondary/auxiliary PDU coded PHY encoding (S2/S8)
2812  * @param[in] mafs_us     Minimum Aux Frame Spacing to use, in microseconds
2813  */
ull_adv_aux_chain_pdu_duplicate(struct pdu_adv * pdu_prev,struct pdu_adv * pdu,struct pdu_adv_aux_ptr * aux_ptr,uint8_t phy_s,uint8_t phy_flags,uint32_t mafs_us)2814 void ull_adv_aux_chain_pdu_duplicate(struct pdu_adv *pdu_prev,
2815 				     struct pdu_adv *pdu,
2816 				     struct pdu_adv_aux_ptr *aux_ptr,
2817 				     uint8_t phy_s, uint8_t phy_flags,
2818 				     uint32_t mafs_us)
2819 {
2820 	/* Duplicate any chain PDUs */
2821 	while (aux_ptr) {
2822 		struct pdu_adv_com_ext_adv *com_hdr_chain;
2823 		struct pdu_adv_com_ext_adv *com_hdr;
2824 		struct pdu_adv_ext_hdr *hdr_chain;
2825 		struct pdu_adv_adi *adi_parent;
2826 		struct pdu_adv *pdu_chain_prev;
2827 		struct pdu_adv_ext_hdr *hdr;
2828 		struct pdu_adv *pdu_chain;
2829 		uint8_t *dptr_chain;
2830 		uint32_t offs_us;
2831 		uint8_t *dptr;
2832 
2833 		/* Get the next chain PDU */
2834 		pdu_chain_prev = lll_adv_pdu_linked_next_get(pdu_prev);
2835 		if (!pdu_chain_prev) {
2836 			break;
2837 		}
2838 
2839 		/* Fill the aux offset in the (first iteration, it is the
2840 		 * primary channel ADV_EXT_IND PDU, rest it is AUX_ADV_IND and
2841 		 * AUX_CHAIN_IND) parent PDU
2842 		 */
2843 		offs_us = PDU_AC_US(pdu->len, phy_s, phy_flags) + mafs_us;
2844 		ull_adv_aux_ptr_fill(aux_ptr, offs_us, phy_s);
2845 
2846 		/* Get reference to flags in superior PDU */
2847 		com_hdr = &pdu->adv_ext_ind;
2848 		hdr = (void *)&com_hdr->ext_hdr_adv_data[0];
2849 		dptr = (void *)hdr;
2850 
2851 		/* Get the next new chain PDU */
2852 		pdu_chain = lll_adv_pdu_linked_next_get(pdu);
2853 		if (!pdu_chain) {
2854 			/* Get a new chain PDU */
2855 			pdu_chain = lll_adv_pdu_alloc_pdu_adv();
2856 			LL_ASSERT(pdu_chain);
2857 
2858 			/* Copy previous chain PDU into new chain PDU */
2859 			(void)memcpy(pdu_chain, pdu_chain_prev,
2860 				     offsetof(struct pdu_adv, payload) +
2861 				     pdu_chain_prev->len);
2862 
2863 			/* Link the chain PDU to parent PDU */
2864 			lll_adv_pdu_linked_append(pdu_chain, pdu);
2865 		}
2866 
2867 		/* Get reference to common header format */
2868 		com_hdr_chain = &pdu_chain_prev->adv_ext_ind;
2869 		hdr_chain = (void *)&com_hdr_chain->ext_hdr_adv_data[0];
2870 		dptr_chain = (void *)hdr_chain;
2871 
2872 		/* Check for no Flags */
2873 		if (!com_hdr_chain->ext_hdr_len) {
2874 			break;
2875 		}
2876 
2877 		/* Proceed to next byte if any flags present */
2878 		if (*dptr) {
2879 			dptr++;
2880 		}
2881 		if (*dptr_chain) {
2882 			dptr_chain++;
2883 		}
2884 
2885 		/* AdvA flag */
2886 		if (hdr->adv_addr) {
2887 			dptr += BDADDR_SIZE;
2888 		}
2889 		if (hdr_chain->adv_addr) {
2890 			dptr_chain += BDADDR_SIZE;
2891 		}
2892 
2893 		/* TgtA flag */
2894 		if (hdr->tgt_addr) {
2895 			dptr += BDADDR_SIZE;
2896 		}
2897 		if (hdr_chain->tgt_addr) {
2898 			dptr_chain += BDADDR_SIZE;
2899 		}
2900 
2901 		/* CTE Info */
2902 		if (hdr->cte_info) {
2903 			dptr += sizeof(struct pdu_cte_info);
2904 		}
2905 		if (hdr_chain->cte_info) {
2906 			dptr_chain += sizeof(struct pdu_cte_info);
2907 		}
2908 
2909 		/* ADI */
2910 		if (hdr->adi) {
2911 			adi_parent = (void *)dptr;
2912 
2913 			dptr += sizeof(struct pdu_adv_adi);
2914 		} else {
2915 			adi_parent = NULL;
2916 		}
2917 		if (hdr_chain->adi) {
2918 			struct pdu_adv_adi *adi;
2919 
2920 			/* update ADI to superior PDU ADI */
2921 			adi = (void *)dptr_chain;
2922 			if (adi_parent) {
2923 				adi->did_sid_packed[0] = adi_parent->did_sid_packed[0];
2924 				adi->did_sid_packed[1] = adi_parent->did_sid_packed[1];
2925 			}
2926 
2927 			dptr_chain += sizeof(struct pdu_adv_adi);
2928 		}
2929 
2930 		/* No aux ptr, no further chain PDUs */
2931 		if (!hdr_chain->aux_ptr) {
2932 			break;
2933 		}
2934 
2935 		/* Remember the aux ptr to be populated */
2936 		aux_ptr = (void *)dptr_chain;
2937 
2938 		/* Progress to next chain PDU */
2939 		pdu_prev = pdu_chain_prev;
2940 		pdu = pdu_chain;
2941 	}
2942 }
2943 #endif /* CONFIG_BT_CTLR_ADV_PDU_LINK */
2944 
init_reset(void)2945 static int init_reset(void)
2946 {
2947 	/* Initialize adv aux pool. */
2948 	mem_init(ll_adv_aux_pool, sizeof(struct ll_adv_aux_set),
2949 		 sizeof(ll_adv_aux_pool) / sizeof(struct ll_adv_aux_set),
2950 		 &adv_aux_free);
2951 
2952 	return 0;
2953 }
2954 
aux_acquire(void)2955 static inline struct ll_adv_aux_set *aux_acquire(void)
2956 {
2957 	return mem_acquire(&adv_aux_free);
2958 }
2959 
aux_release(struct ll_adv_aux_set * aux)2960 static inline void aux_release(struct ll_adv_aux_set *aux)
2961 {
2962 	mem_release(aux, &adv_aux_free);
2963 }
2964 
aux_time_get(const struct ll_adv_aux_set * aux,const struct pdu_adv * pdu,uint8_t pdu_len,uint8_t pdu_scan_len)2965 static uint32_t aux_time_get(const struct ll_adv_aux_set *aux,
2966 			     const struct pdu_adv *pdu,
2967 			     uint8_t pdu_len, uint8_t pdu_scan_len)
2968 {
2969 	const struct lll_adv_aux *lll_aux;
2970 	const struct lll_adv *lll;
2971 	uint32_t time_us;
2972 
2973 	lll_aux = &aux->lll;
2974 	lll = lll_aux->adv;
2975 
2976 	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_RESERVE_MAX) &&
2977 	    (lll->phy_s == PHY_CODED)) {
2978 		pdu_len = PDU_AC_EXT_PAYLOAD_OVERHEAD;
2979 		pdu_scan_len = PDU_AC_EXT_PAYLOAD_OVERHEAD;
2980 	}
2981 
2982 	/* NOTE: 16-bit values are sufficient for minimum radio event time
2983 	 *       reservation, 32-bit are used here so that reservations for
2984 	 *       whole back-to-back chaining of PDUs can be accomodated where
2985 	 *       the required microseconds could overflow 16-bits, example,
2986 	 *       back-to-back chained Coded PHY PDUs.
2987 	 */
2988 	time_us = PDU_AC_US(pdu_len, lll->phy_s, lll->phy_flags) +
2989 		  EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US;
2990 
2991 	if ((pdu->adv_ext_ind.adv_mode & BT_HCI_LE_ADV_PROP_CONN) ==
2992 	    BT_HCI_LE_ADV_PROP_CONN) {
2993 		const uint16_t conn_req_us =
2994 			PDU_AC_MAX_US((INITA_SIZE + ADVA_SIZE + LLDATA_SIZE),
2995 				      lll->phy_s);
2996 		const uint16_t conn_rsp_us =
2997 			PDU_AC_US((PDU_AC_EXT_HEADER_SIZE_MIN + ADVA_SIZE +
2998 				   TARGETA_SIZE), lll->phy_s, lll->phy_flags);
2999 
3000 		time_us += EVENT_IFS_MAX_US * 2 + conn_req_us + conn_rsp_us;
3001 	} else if ((pdu->adv_ext_ind.adv_mode & BT_HCI_LE_ADV_PROP_SCAN) ==
3002 		   BT_HCI_LE_ADV_PROP_SCAN) {
3003 		const uint16_t scan_req_us  =
3004 			PDU_AC_MAX_US((SCANA_SIZE + ADVA_SIZE), lll->phy_s);
3005 		const uint16_t scan_rsp_us =
3006 			PDU_AC_US(pdu_scan_len, lll->phy_s, lll->phy_flags);
3007 
3008 		time_us += EVENT_IFS_MAX_US * 2 + scan_req_us + scan_rsp_us;
3009 
3010 		/* FIXME: Calculate additional time reservations for scan
3011 		 *        response chain PDUs, if any.
3012 		 */
3013 	} else {
3014 		/* Non-connectable Non-Scannable */
3015 
3016 		/* FIXME: Calculate additional time reservations for chain PDUs,
3017 		 *        if any.
3018 		 */
3019 	}
3020 
3021 	return time_us;
3022 }
3023 
aux_time_min_get(const struct ll_adv_aux_set * aux)3024 static uint32_t aux_time_min_get(const struct ll_adv_aux_set *aux)
3025 {
3026 	const struct lll_adv_aux *lll_aux;
3027 	const struct pdu_adv *pdu_scan;
3028 	const struct lll_adv *lll;
3029 	const struct pdu_adv *pdu;
3030 	uint8_t pdu_scan_len;
3031 	uint8_t pdu_len;
3032 
3033 	lll_aux = &aux->lll;
3034 	lll = lll_aux->adv;
3035 	pdu = lll_adv_aux_data_peek(lll_aux);
3036 	pdu_scan = lll_adv_scan_rsp_peek(lll);
3037 
3038 	/* Calculate the PDU Tx Time and hence the radio event length,
3039 	 * Always use maximum length for common extended header format so that
3040 	 * ACAD could be update when periodic advertising is active and the
3041 	 * time reservation need not be updated everytime avoiding overlapping
3042 	 * with other active states/roles.
3043 	 */
3044 	pdu_len = pdu->len - pdu->adv_ext_ind.ext_hdr_len -
3045 		  PDU_AC_EXT_HEADER_SIZE_MIN + PDU_AC_EXT_HEADER_SIZE_MAX;
3046 	pdu_scan_len = pdu_scan->len - pdu_scan->adv_ext_ind.ext_hdr_len -
3047 		       PDU_AC_EXT_HEADER_SIZE_MIN + PDU_AC_EXT_HEADER_SIZE_MAX;
3048 
3049 	return aux_time_get(aux, pdu, pdu_len, pdu_scan_len);
3050 }
3051 
aux_time_update(struct ll_adv_aux_set * aux,struct pdu_adv * pdu,struct pdu_adv * pdu_scan)3052 static uint8_t aux_time_update(struct ll_adv_aux_set *aux, struct pdu_adv *pdu,
3053 			       struct pdu_adv *pdu_scan)
3054 {
3055 	uint32_t time_ticks;
3056 	uint32_t time_us;
3057 
3058 	time_us = aux_time_min_get(aux);
3059 	time_ticks = HAL_TICKER_US_TO_TICKS_CEIL(time_us);
3060 
3061 #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
3062 	uint32_t volatile ret_cb;
3063 	uint32_t ticks_minus;
3064 	uint32_t ticks_plus;
3065 	uint32_t ret;
3066 
3067 	if (aux->ull.ticks_slot > time_ticks) {
3068 		ticks_minus = aux->ull.ticks_slot - time_ticks;
3069 		ticks_plus = 0U;
3070 	} else if (aux->ull.ticks_slot < time_ticks) {
3071 		ticks_minus = 0U;
3072 		ticks_plus = time_ticks - aux->ull.ticks_slot;
3073 	} else {
3074 		return BT_HCI_ERR_SUCCESS;
3075 	}
3076 
3077 	ret_cb = TICKER_STATUS_BUSY;
3078 	ret = ticker_update(TICKER_INSTANCE_ID_CTLR,
3079 			    TICKER_USER_ID_THREAD,
3080 			    (TICKER_ID_ADV_AUX_BASE +
3081 			     ull_adv_aux_handle_get(aux)),
3082 			    0, 0, ticks_plus, ticks_minus, 0, 0,
3083 			    ull_ticker_status_give, (void *)&ret_cb);
3084 	ret = ull_ticker_status_take(ret, &ret_cb);
3085 	if (ret != TICKER_STATUS_SUCCESS) {
3086 		return BT_HCI_ERR_CMD_DISALLOWED;
3087 	}
3088 #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */
3089 
3090 	aux->ull.ticks_slot = time_ticks;
3091 
3092 	return BT_HCI_ERR_SUCCESS;
3093 }
3094 
3095 #if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
ull_adv_aux_lll_auxptr_fill(struct pdu_adv * pdu,struct lll_adv * adv)3096 void ull_adv_aux_lll_auxptr_fill(struct pdu_adv *pdu, struct lll_adv *adv)
3097 {
3098 	struct lll_adv_aux *lll_aux = adv->aux;
3099 	struct pdu_adv_aux_ptr *aux_ptr;
3100 	struct ll_adv_aux_set *aux;
3101 	uint8_t data_chan_count;
3102 	uint8_t *data_chan_map;
3103 	uint16_t chan_counter;
3104 	uint32_t offset_us;
3105 	uint16_t pdu_us;
3106 
3107 	aux = HDR_LLL2ULL(lll_aux);
3108 
3109 	chan_counter = lll_aux->data_chan_counter;
3110 
3111 	/* The offset has to be at least T_MAFS microseconds from the end of packet
3112 	 * In addition, the offset recorded in the aux ptr has the same requirement and this
3113 	 * offset is in steps of 30 microseconds; So use the quantized value in check
3114 	 */
3115 	pdu_us = PDU_AC_US(pdu->len, adv->phy_p, adv->phy_flags);
3116 	offset_us = HAL_TICKER_TICKS_TO_US(lll_aux->ticks_pri_pdu_offset) +
3117 		    lll_aux->us_pri_pdu_offset;
3118 	if ((offset_us/OFFS_UNIT_30_US)*OFFS_UNIT_30_US < EVENT_MAFS_US + pdu_us) {
3119 		uint32_t interval_us;
3120 
3121 		/* Offset too small, point to next aux packet instead */
3122 		interval_us = aux->interval * PERIODIC_INT_UNIT_US;
3123 		offset_us = offset_us + interval_us;
3124 		lll_aux->ticks_pri_pdu_offset = HAL_TICKER_US_TO_TICKS(offset_us);
3125 		lll_aux->us_pri_pdu_offset = offset_us -
3126 					     HAL_TICKER_TICKS_TO_US(lll_aux->ticks_pri_pdu_offset);
3127 		chan_counter++;
3128 	}
3129 
3130 	/* Fill the aux offset */
3131 	aux_ptr = ull_adv_aux_lll_offset_fill(pdu, lll_aux->ticks_pri_pdu_offset,
3132 					      lll_aux->us_pri_pdu_offset, 0U);
3133 
3134 
3135 	/* Calculate and fill the radio channel to use */
3136 	data_chan_map = aux->chm[aux->chm_first].data_chan_map;
3137 	data_chan_count = aux->chm[aux->chm_first].data_chan_count;
3138 	aux_ptr->chan_idx = lll_chan_sel_2(chan_counter,
3139 					   aux->data_chan_id,
3140 					   data_chan_map, data_chan_count);
3141 }
3142 
3143 #else /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
mfy_aux_offset_get(void * param)3144 static void mfy_aux_offset_get(void *param)
3145 {
3146 	struct pdu_adv_aux_ptr *aux_ptr;
3147 	struct lll_adv_aux *lll_aux;
3148 	struct ll_adv_aux_set *aux;
3149 	uint32_t ticks_to_expire;
3150 	uint8_t data_chan_count;
3151 	uint8_t *data_chan_map;
3152 	uint32_t ticks_current;
3153 	struct ll_adv_set *adv;
3154 	struct pdu_adv *pdu;
3155 	uint32_t remainder;
3156 	uint8_t ticker_id;
3157 	uint8_t retry;
3158 	uint8_t id;
3159 
3160 	adv = param;
3161 	lll_aux = adv->lll.aux;
3162 	aux = HDR_LLL2ULL(lll_aux);
3163 	ticker_id = TICKER_ID_ADV_AUX_BASE + ull_adv_aux_handle_get(aux);
3164 
3165 	id = TICKER_NULL;
3166 	ticks_to_expire = 0U;
3167 	ticks_current = 0U;
3168 	retry = 4U;
3169 	do {
3170 		uint32_t volatile ret_cb;
3171 		uint32_t ticks_previous;
3172 		uint32_t ret;
3173 		bool success;
3174 
3175 		ticks_previous = ticks_current;
3176 
3177 		ret_cb = TICKER_STATUS_BUSY;
3178 		ret = ticker_next_slot_get_ext(TICKER_INSTANCE_ID_CTLR,
3179 					       TICKER_USER_ID_ULL_LOW,
3180 					       &id, &ticks_current,
3181 					       &ticks_to_expire, &remainder,
3182 					       NULL, NULL, NULL,
3183 					       ticker_op_cb, (void *)&ret_cb);
3184 		if (ret == TICKER_STATUS_BUSY) {
3185 			while (ret_cb == TICKER_STATUS_BUSY) {
3186 				ticker_job_sched(TICKER_INSTANCE_ID_CTLR,
3187 						 TICKER_USER_ID_ULL_LOW);
3188 			}
3189 		}
3190 
3191 		success = (ret_cb == TICKER_STATUS_SUCCESS);
3192 		LL_ASSERT(success);
3193 
3194 		LL_ASSERT((ticks_current == ticks_previous) || retry--);
3195 
3196 		LL_ASSERT(id != TICKER_NULL);
3197 	} while (id != ticker_id);
3198 
3199 	/* Adjust ticks to expire based on remainder value */
3200 	hal_ticker_remove_jitter(&ticks_to_expire, &remainder);
3201 
3202 	/* Store the ticks offset for population in other advertising primary
3203 	 * channel PDUs.
3204 	 */
3205 	lll_aux->ticks_pri_pdu_offset = ticks_to_expire;
3206 
3207 	/* NOTE: as first primary channel PDU does not use remainder, the packet
3208 	 * timer is started one tick in advance to start the radio with
3209 	 * microsecond precision, hence compensate for the higher start_us value
3210 	 * captured at radio start of the first primary channel PDU.
3211 	 */
3212 	lll_aux->ticks_pri_pdu_offset += 1U;
3213 
3214 	/* Store the microsecond remainder offset for population in other
3215 	 * advertising primary channel PDUs.
3216 	 */
3217 	lll_aux->us_pri_pdu_offset = remainder;
3218 
3219 	/* Fill the aux offset in the first Primary channel PDU */
3220 	/* FIXME: we are in ULL_LOW context, fill offset in LLL context? */
3221 	pdu = lll_adv_data_latest_peek(&adv->lll);
3222 	aux_ptr = ull_adv_aux_lll_offset_fill(pdu, ticks_to_expire, remainder,
3223 					      0U);
3224 
3225 	/* Process channel map update, if any */
3226 	if (aux->chm_first != aux->chm_last) {
3227 		/* Use channelMapNew */
3228 		aux->chm_first = aux->chm_last;
3229 	}
3230 
3231 	/* Calculate the radio channel to use */
3232 	data_chan_map = aux->chm[aux->chm_first].data_chan_map;
3233 	data_chan_count = aux->chm[aux->chm_first].data_chan_count;
3234 	aux_ptr->chan_idx = lll_chan_sel_2(lll_aux->data_chan_counter,
3235 					   aux->data_chan_id,
3236 					   data_chan_map, data_chan_count);
3237 }
3238 
ticker_op_cb(uint32_t status,void * param)3239 static void ticker_op_cb(uint32_t status, void *param)
3240 {
3241 	*((uint32_t volatile *)param) = status;
3242 }
3243 #endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
3244 
ticker_cb(uint32_t ticks_at_expire,uint32_t ticks_drift,uint32_t remainder,uint16_t lazy,uint8_t force,void * param)3245 static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
3246 		      uint32_t remainder, uint16_t lazy, uint8_t force,
3247 		      void *param)
3248 {
3249 	static memq_link_t link;
3250 	static struct mayfly mfy = {0, 0, &link, NULL, lll_adv_aux_prepare};
3251 	static struct lll_prepare_param p;
3252 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
3253 	struct ticker_ext_context *context = param;
3254 	struct ll_adv_aux_set *aux = context->context;
3255 #else /* !CONFIG_BT_CTLR_ADV_PERIODIC || !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
3256 	struct ll_adv_aux_set *aux = param;
3257 #endif /* !CONFIG_BT_CTLR_ADV_PERIODIC || !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
3258 	struct lll_adv_aux *lll;
3259 	uint32_t ret;
3260 	uint8_t ref;
3261 
3262 	DEBUG_RADIO_PREPARE_A(1);
3263 
3264 	lll = &aux->lll;
3265 
3266 	/* Increment prepare reference count */
3267 	ref = ull_ref_inc(&aux->ull);
3268 	LL_ASSERT(ref);
3269 
3270 #if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
3271 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
3272 	struct ll_adv_set *adv;
3273 
3274 	adv = HDR_LLL2ULL(lll->adv);
3275 	if (adv->lll.sync) {
3276 		struct lll_adv_sync *lll_sync = adv->lll.sync;
3277 		struct ll_adv_sync_set *sync;
3278 
3279 		sync = HDR_LLL2ULL(adv->lll.sync);
3280 		if (sync->is_started) {
3281 			uint32_t ticks_to_expire;
3282 			uint32_t sync_remainder_us;
3283 
3284 			LL_ASSERT(context->other_expire_info);
3285 
3286 			/* Reduce a tick for negative remainder and return positive remainder
3287 			 * value.
3288 			 */
3289 			ticks_to_expire = context->other_expire_info->ticks_to_expire;
3290 			sync_remainder_us = context->other_expire_info->remainder;
3291 			hal_ticker_remove_jitter(&ticks_to_expire, &sync_remainder_us);
3292 
3293 			/* Add a tick for negative remainder and return positive remainder
3294 			 * value.
3295 			 */
3296 			hal_ticker_add_jitter(&ticks_to_expire, &remainder);
3297 
3298 			/* Store the offset in us */
3299 			lll_sync->us_adv_sync_pdu_offset = HAL_TICKER_TICKS_TO_US(ticks_to_expire) +
3300 						  sync_remainder_us - remainder;
3301 
3302 			/* store the lazy value */
3303 			lll_sync->sync_lazy = context->other_expire_info->lazy;
3304 		}
3305 	}
3306 #endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
3307 
3308 	/* Process channel map update, if any */
3309 	if (aux->chm_first != aux->chm_last) {
3310 		/* Use channelMapNew */
3311 		aux->chm_first = aux->chm_last;
3312 	}
3313 #endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
3314 
3315 	/* Append timing parameters */
3316 	p.ticks_at_expire = ticks_at_expire;
3317 	p.remainder = remainder;
3318 	p.lazy = lazy;
3319 	p.force = force;
3320 	p.param = lll;
3321 	mfy.param = &p;
3322 
3323 	/* Kick LLL prepare */
3324 	ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
3325 			     TICKER_USER_ID_LLL, 0, &mfy);
3326 	LL_ASSERT(!ret);
3327 
3328 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC) && !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
3329 	struct ll_adv_set *adv;
3330 
3331 	adv = HDR_LLL2ULL(lll->adv);
3332 	if (adv->lll.sync) {
3333 		struct ll_adv_sync_set *sync;
3334 
3335 		sync = HDR_LLL2ULL(adv->lll.sync);
3336 		if (sync->is_started) {
3337 			sync->aux_remainder = remainder;
3338 			ull_adv_sync_offset_get(adv);
3339 		}
3340 	}
3341 #endif /* CONFIG_BT_CTLR_ADV_PERIODIC && !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
3342 
3343 	DEBUG_RADIO_PREPARE_A(1);
3344 }
3345 
3346 #if defined(CONFIG_BT_CTLR_ADV_PERIODIC) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
ticker_update_op_cb(uint32_t status,void * param)3347 static void ticker_update_op_cb(uint32_t status, void *param)
3348 {
3349 	LL_ASSERT(status == TICKER_STATUS_SUCCESS ||
3350 		  param == ull_disable_mark_get());
3351 }
3352 #endif /* !CONFIG_BT_CTLR_ADV_PERIODIC && CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
3353 
3354 #else /* !(CONFIG_BT_CTLR_ADV_AUX_SET > 0) */
3355 
init_reset(void)3356 static int init_reset(void)
3357 {
3358 	return 0;
3359 }
3360 #endif /* !(CONFIG_BT_CTLR_ADV_AUX_SET > 0) */
3361