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