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