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