1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
8 #include <string.h>
9 
10 #include <soc.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/sys/util.h>
13 
14 #include "hal/cpu.h"
15 #include "hal/ccm.h"
16 #include "hal/radio.h"
17 #include "hal/ticker.h"
18 
19 #include "util/util.h"
20 #include "util/mem.h"
21 #include "util/memq.h"
22 
23 #include "pdu_df.h"
24 #include "pdu_vendor.h"
25 #include "pdu.h"
26 
27 #include "lll.h"
28 #include "lll_clock.h"
29 #include "lll_chan.h"
30 #include "lll_vendor.h"
31 #include "lll_adv_types.h"
32 #include "lll_adv.h"
33 #include "lll_adv_pdu.h"
34 #include "lll_adv_iso.h"
35 #include "lll_iso_tx.h"
36 
37 #include "lll_internal.h"
38 #include "lll_adv_iso_internal.h"
39 #include "lll_prof_internal.h"
40 
41 #include "ll_feat.h"
42 
43 #include "hal/debug.h"
44 
45 #define TEST_WITH_DUMMY_PDU 0
46 
47 static int init_reset(void);
48 static void prepare(void *param);
49 static void create_prepare_bh(void *param);
50 static void prepare_bh(void *param);
51 static int create_prepare_cb(struct lll_prepare_param *p);
52 static int prepare_cb(struct lll_prepare_param *p);
53 static int prepare_cb_common(struct lll_prepare_param *p);
54 static void isr_tx_create(void *param);
55 static void isr_tx_normal(void *param);
56 static void isr_tx_common(void *param,
57 			  radio_isr_cb_t isr_tx,
58 			  radio_isr_cb_t isr_done);
59 static void next_chan_calc(struct lll_adv_iso *lll, uint16_t event_counter,
60 			   uint16_t data_chan_id);
61 static void isr_done_create(void *param);
62 static void isr_done_term(void *param);
63 
lll_adv_iso_init(void)64 int lll_adv_iso_init(void)
65 {
66 	int err;
67 
68 	err = init_reset();
69 	if (err) {
70 		return err;
71 	}
72 
73 	return 0;
74 }
75 
lll_adv_iso_reset(void)76 int lll_adv_iso_reset(void)
77 {
78 	int err;
79 
80 	err = init_reset();
81 	if (err) {
82 		return err;
83 	}
84 
85 	return 0;
86 }
87 
lll_adv_iso_create_prepare(void * param)88 void lll_adv_iso_create_prepare(void *param)
89 {
90 	prepare(param);
91 	create_prepare_bh(param);
92 }
93 
lll_adv_iso_prepare(void * param)94 void lll_adv_iso_prepare(void *param)
95 {
96 	prepare(param);
97 	prepare_bh(param);
98 }
99 
init_reset(void)100 static int init_reset(void)
101 {
102 	return 0;
103 }
104 
prepare(void * param)105 static void prepare(void *param)
106 {
107 	struct lll_prepare_param *p;
108 	struct lll_adv_iso *lll;
109 	uint16_t elapsed;
110 	int err;
111 
112 	err = lll_hfclock_on();
113 	LL_ASSERT(err >= 0);
114 
115 	p = param;
116 
117 	/* Instants elapsed */
118 	elapsed = p->lazy + 1U;
119 
120 	lll = p->param;
121 
122 	/* Save the (latency + 1) for use in event */
123 	lll->latency_prepare += elapsed;
124 }
125 
create_prepare_bh(void * param)126 static void create_prepare_bh(void *param)
127 {
128 	int err;
129 
130 	/* Invoke common pipeline handling of prepare */
131 	err = lll_prepare(lll_is_abort_cb, lll_abort_cb, create_prepare_cb, 0U,
132 			  param);
133 	LL_ASSERT(!err || err == -EINPROGRESS);
134 }
135 
prepare_bh(void * param)136 static void prepare_bh(void *param)
137 {
138 	int err;
139 
140 	/* Invoke common pipeline handling of prepare */
141 	err = lll_prepare(lll_is_abort_cb, lll_abort_cb, prepare_cb, 0U, param);
142 	LL_ASSERT(!err || err == -EINPROGRESS);
143 }
144 
create_prepare_cb(struct lll_prepare_param * p)145 static int create_prepare_cb(struct lll_prepare_param *p)
146 {
147 	int err;
148 
149 	err = prepare_cb_common(p);
150 	if (err) {
151 		DEBUG_RADIO_START_A(1);
152 		return 0;
153 	}
154 
155 	radio_isr_set(isr_tx_create, p->param);
156 
157 	DEBUG_RADIO_START_A(1);
158 	return 0;
159 }
160 
prepare_cb(struct lll_prepare_param * p)161 static int prepare_cb(struct lll_prepare_param *p)
162 {
163 	int err;
164 
165 	err = prepare_cb_common(p);
166 	if (err) {
167 		DEBUG_RADIO_START_A(1);
168 		return 0;
169 	}
170 
171 	radio_isr_set(isr_tx_normal, p->param);
172 
173 	DEBUG_RADIO_START_A(1);
174 	return 0;
175 }
176 
prepare_cb_common(struct lll_prepare_param * p)177 static int prepare_cb_common(struct lll_prepare_param *p)
178 {
179 	struct lll_adv_iso *lll;
180 	uint32_t ticks_at_event;
181 	uint32_t ticks_at_start;
182 	uint16_t event_counter;
183 	uint8_t access_addr[4];
184 	uint64_t payload_count;
185 	uint16_t data_chan_id;
186 	uint8_t data_chan_use;
187 	uint8_t crc_init[3];
188 	struct pdu_bis *pdu;
189 	struct ull_hdr *ull;
190 	uint32_t remainder;
191 	uint32_t start_us;
192 	uint8_t pkt_flags;
193 	uint32_t ret;
194 	uint8_t phy;
195 
196 	DEBUG_RADIO_START_A(1);
197 
198 	lll = p->param;
199 
200 	/* Deduce the latency */
201 	lll->latency_event = lll->latency_prepare - 1U;
202 
203 	/* Calculate the current event counter value */
204 	event_counter = (lll->payload_count / lll->bn) + lll->latency_event;
205 
206 	/* Update BIS payload counter to next value */
207 	lll->payload_count += (lll->latency_prepare * lll->bn);
208 	payload_count = lll->payload_count - lll->bn;
209 
210 	/* Reset accumulated latencies */
211 	lll->latency_prepare = 0U;
212 
213 	/* Initialize to mandatory parameter values */
214 	lll->bis_curr = 1U;
215 	lll->ptc_curr = 0U;
216 	lll->irc_curr = 1U;
217 	lll->bn_curr = 1U;
218 
219 	/* Calculate the Access Address for the BIS event */
220 	util_bis_aa_le32(lll->bis_curr, lll->seed_access_addr, access_addr);
221 	data_chan_id = lll_chan_id(access_addr);
222 
223 	/* Calculate the CRC init value for the BIS event,
224 	 * preset with the BaseCRCInit value from the BIGInfo data the most
225 	 * significant 2 octets and the BIS_Number for the specific BIS in the
226 	 * least significant octet.
227 	 */
228 	crc_init[0] = lll->bis_curr;
229 	(void)memcpy(&crc_init[1], lll->base_crc_init, sizeof(uint16_t));
230 
231 	/* Calculate the radio channel to use for ISO event */
232 	data_chan_use = lll_chan_iso_event(event_counter, data_chan_id,
233 					   lll->data_chan_map,
234 					   lll->data_chan_count,
235 					   &lll->data_chan_prn_s,
236 					   &lll->data_chan_remap_idx);
237 
238 	/* Start setting up of Radio h/w */
239 	radio_reset();
240 
241 #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
242 	radio_tx_power_set(lll->adv->tx_pwr_lvl);
243 #else
244 	radio_tx_power_set(RADIO_TXP_DEFAULT);
245 #endif
246 
247 	phy = lll->phy;
248 	radio_phy_set(phy, lll->phy_flags);
249 	radio_aa_set(access_addr);
250 	radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(crc_init));
251 	lll_chan_set(data_chan_use);
252 
253 	/* Get ISO data PDU */
254 #if !TEST_WITH_DUMMY_PDU
255 	struct lll_adv_iso_stream *stream;
256 	memq_link_t *link = NULL;
257 	struct node_tx_iso *tx;
258 	uint16_t stream_handle;
259 	uint16_t handle;
260 	uint8_t bis_idx;
261 
262 	bis_idx = lll->num_bis;
263 	while (bis_idx--) {
264 		stream_handle = lll->stream_handle[bis_idx];
265 		handle = LL_BIS_ADV_HANDLE_FROM_IDX(stream_handle);
266 		stream = ull_adv_iso_lll_stream_get(stream_handle);
267 		LL_ASSERT(stream);
268 
269 		do {
270 			link = memq_peek(stream->memq_tx.head,
271 					 stream->memq_tx.tail, (void **)&tx);
272 			if (link) {
273 				if (tx->payload_count < payload_count) {
274 					memq_dequeue(stream->memq_tx.tail,
275 						     &stream->memq_tx.head,
276 						     NULL);
277 
278 					tx->next = link;
279 					ull_iso_lll_ack_enqueue(handle, tx);
280 				} else if (tx->payload_count >=
281 					   lll->payload_count) {
282 					link = NULL;
283 				} else {
284 					if (tx->payload_count !=
285 					    payload_count) {
286 						link = NULL;
287 					}
288 
289 					break;
290 				}
291 			}
292 		} while (link);
293 	}
294 
295 	if (!link) {
296 		pdu = radio_pkt_empty_get();
297 		pdu->ll_id = lll->framing ? PDU_BIS_LLID_FRAMED : PDU_BIS_LLID_START_CONTINUE;
298 		pdu->len = 0U;
299 	} else {
300 		pdu = (void *)tx->pdu;
301 	}
302 
303 #else /* TEST_WITH_DUMMY_PDU */
304 	pdu = radio_pkt_scratch_get();
305 	if (lll->bn_curr >= lll->bn) {
306 		pdu->ll_id = PDU_BIS_LLID_COMPLETE_END;
307 	} else {
308 		pdu->ll_id = PDU_BIS_LLID_START_CONTINUE;
309 	}
310 	pdu->len = LL_BIS_OCTETS_TX_MAX;
311 
312 	pdu->payload[0] = lll->bn_curr;
313 	pdu->payload[1] = lll->irc_curr;
314 	pdu->payload[2] = lll->ptc_curr;
315 	pdu->payload[3] = lll->bis_curr;
316 
317 	pdu->payload[4] = payload_count;
318 	pdu->payload[5] = payload_count >> 8;
319 	pdu->payload[6] = payload_count >> 16;
320 	pdu->payload[7] = payload_count >> 24;
321 	pdu->payload[8] = payload_count >> 32;
322 #endif /* TEST_WITH_DUMMY_PDU */
323 
324 	/* Initialize reserve bit */
325 	pdu->rfu = 0U;
326 
327 	/* Handle control procedure */
328 	if (unlikely(lll->term_req || !!(lll->chm_req - lll->chm_ack))) {
329 		if (lll->term_req) {
330 			if (!lll->term_ack) {
331 				lll->term_ack = 1U;
332 				lll->ctrl_expire = CONN_ESTAB_COUNTDOWN;
333 				lll->ctrl_instant = event_counter +
334 						    lll->ctrl_expire - 1U;
335 				lll->cssn++;
336 			}
337 		} else if (((lll->chm_req - lll->chm_ack) & CHM_STATE_MASK) ==
338 			   CHM_STATE_REQ) {
339 			lll->chm_ack--;
340 			lll->ctrl_expire = CONN_ESTAB_COUNTDOWN;
341 			lll->ctrl_instant = event_counter + lll->ctrl_expire;
342 			lll->cssn++;
343 		}
344 
345 		pdu->cstf = 1U;
346 	} else {
347 		pdu->cstf = 0U;
348 	}
349 	pdu->cssn = lll->cssn;
350 
351 	/* Radio packet configuration */
352 	pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS, phy,
353 					 RADIO_PKT_CONF_CTE_DISABLED);
354 	if (IS_ENABLED(CONFIG_BT_CTLR_BROADCAST_ISO_ENC) &&
355 	    pdu->len && lll->enc) {
356 		/* Encryption */
357 		lll->ccm_tx.counter = payload_count;
358 
359 		(void)memcpy(lll->ccm_tx.iv, lll->giv, 4U);
360 		mem_xor_32(lll->ccm_tx.iv, lll->ccm_tx.iv, access_addr);
361 
362 		radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
363 				    (lll->max_pdu + PDU_MIC_SIZE), pkt_flags);
364 
365 		radio_pkt_tx_set(radio_ccm_iso_tx_pkt_set(&lll->ccm_tx,
366 						RADIO_PKT_CONF_PDU_TYPE_BIS,
367 						pdu));
368 	} else {
369 		if (lll->enc) {
370 			radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
371 					    (lll->max_pdu + PDU_MIC_SIZE),
372 					    pkt_flags);
373 		} else {
374 			radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
375 					    lll->max_pdu, pkt_flags);
376 		}
377 
378 		radio_pkt_tx_set(pdu);
379 	}
380 
381 	/* Setup radio IFS switching */
382 	if ((lll->bn_curr == lll->bn) &&
383 	    (lll->irc_curr == lll->irc) &&
384 	    (lll->ptc_curr == lll->ptc) &&
385 	    (lll->bis_curr == lll->num_bis) &&
386 	    !pdu->cstf) {
387 		radio_switch_complete_and_disable();
388 	} else {
389 		uint16_t iss_us;
390 
391 		/* Calculate next subevent start based on previous PDU length */
392 		iss_us = lll->sub_interval -
393 			 PDU_BIS_US(pdu->len, ((pdu->len) ? lll->enc : 0U),
394 				    lll->phy, lll->phy_flags);
395 
396 		radio_tmr_tifs_set(iss_us);
397 		radio_switch_complete_and_b2b_tx(lll->phy, lll->phy_flags,
398 						 lll->phy, lll->phy_flags);
399 	}
400 
401 	ticks_at_event = p->ticks_at_expire;
402 	ull = HDR_LLL2ULL(lll);
403 	ticks_at_event += lll_event_offset_get(ull);
404 
405 	ticks_at_start = ticks_at_event;
406 	ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
407 
408 	remainder = p->remainder;
409 	start_us = radio_tmr_start(1U, ticks_at_start, remainder);
410 
411 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR) || IS_ENABLED(HAL_RADIO_GPIO_HAVE_PA_PIN)) {
412 		/* setup capture of PDU end timestamp */
413 		radio_tmr_end_capture();
414 	}
415 
416 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
417 	radio_gpio_pa_setup();
418 
419 	radio_gpio_pa_lna_enable(start_us +
420 				 radio_tx_ready_delay_get(lll->phy,
421 							  lll->phy_flags) -
422 				 HAL_RADIO_GPIO_PA_OFFSET);
423 #else /* !HAL_RADIO_GPIO_HAVE_PA_PIN */
424 	ARG_UNUSED(start_us);
425 #endif /* !HAL_RADIO_GPIO_HAVE_PA_PIN */
426 
427 #if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
428 	(EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
429 	uint32_t overhead;
430 
431 	overhead = lll_preempt_calc(ull, (TICKER_ID_ADV_ISO_BASE + lll->handle), ticks_at_event);
432 	/* check if preempt to start has changed */
433 	if (overhead) {
434 		LL_ASSERT_OVERHEAD(overhead);
435 
436 		radio_isr_set(lll_isr_abort, lll);
437 		radio_disable();
438 
439 		return -ECANCELED;
440 	}
441 #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
442 
443 	ret = lll_prepare_done(lll);
444 	LL_ASSERT(!ret);
445 
446 	/* Calculate ahead the next subevent channel index */
447 	next_chan_calc(lll, event_counter, data_chan_id);
448 
449 	return 0;
450 }
451 
isr_tx_create(void * param)452 static void isr_tx_create(void *param)
453 {
454 	isr_tx_common(param, isr_tx_create, isr_done_create);
455 }
456 
isr_tx_normal(void * param)457 static void isr_tx_normal(void *param)
458 {
459 	isr_tx_common(param, isr_tx_normal, lll_isr_done);
460 }
461 
isr_tx_common(void * param,radio_isr_cb_t isr_tx,radio_isr_cb_t isr_done)462 static void isr_tx_common(void *param,
463 			  radio_isr_cb_t isr_tx,
464 			  radio_isr_cb_t isr_done)
465 {
466 	struct pdu_bis *pdu = NULL;
467 	uint8_t data_chan_use = 0;
468 	struct lll_adv_iso *lll;
469 	uint8_t access_addr[4];
470 	uint64_t payload_count;
471 	uint16_t data_chan_id;
472 	uint8_t crc_init[3];
473 	uint8_t bis;
474 
475 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
476 	uint16_t pa_iss_us = 0U;
477 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
478 
479 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
480 		lll_prof_latency_capture();
481 	}
482 
483 	lll = param;
484 	/* FIXME: Sequential or Interleaved BIS subevents decision */
485 	/* Sequential Tx complete flow pseudo code */
486 	if (lll->bn_curr < lll->bn) {
487 		/* transmit the (bn_curr)th Tx PDU of bis_curr */
488 		lll->bn_curr++; /* post increment */
489 
490 		bis = lll->bis_curr;
491 
492 	} else if (lll->irc_curr < lll->irc) {
493 		/* transmit the (bn_curr)th Tx PDU of bis_curr */
494 		lll->bn_curr = 1U;
495 		lll->irc_curr++; /* post increment */
496 
497 		bis = lll->bis_curr;
498 
499 	} else if (lll->ptc_curr < lll->ptc) {
500 		lll->ptc_curr++; /* pre increment */
501 		/* transmit the (ptc_curr * bn)th Tx PDU */
502 
503 		bis = lll->bis_curr;
504 
505 	} else if (lll->bis_curr < lll->num_bis) {
506 		lll->bis_curr++;
507 		lll->ptc_curr = 0U;
508 		lll->irc_curr = 1U;
509 		/* transmit the (bn_curr)th PDU of bis_curr */
510 		lll->bn_curr = 1U;
511 
512 		bis = lll->bis_curr;
513 
514 	} else if (lll->term_ack) {
515 		/* Transmit the control PDU and close the BIG event
516 		 *  there after.
517 		 */
518 		struct pdu_big_ctrl_term_ind *term;
519 
520 		pdu = radio_pkt_big_ctrl_get();
521 		pdu->ll_id = PDU_BIS_LLID_CTRL;
522 		pdu->cssn = lll->cssn;
523 		pdu->cstf = 0U;
524 
525 		pdu->len = offsetof(struct pdu_big_ctrl, ctrl_data) +
526 			   sizeof(struct pdu_big_ctrl_term_ind);
527 		pdu->ctrl.opcode = PDU_BIG_CTRL_TYPE_TERM_IND;
528 
529 		term = (void *)&pdu->ctrl.term_ind;
530 		term->reason = lll->term_reason;
531 		term->instant = lll->ctrl_instant;
532 
533 		/* control subevent to use bis = 0 and se_n = 1 */
534 		bis = 0U;
535 		payload_count = lll->payload_count - lll->bn;
536 
537 	} else if (((lll->chm_req - lll->chm_ack) & CHM_STATE_MASK) ==
538 		   CHM_STATE_SEND) {
539 		/* Transmit the control PDU and stop after 6 intervals
540 		 */
541 		struct pdu_big_ctrl_chan_map_ind *chm;
542 
543 		pdu = radio_pkt_big_ctrl_get();
544 		pdu->ll_id = PDU_BIS_LLID_CTRL;
545 		pdu->cssn = lll->cssn;
546 		pdu->cstf = 0U;
547 
548 		pdu->len = offsetof(struct pdu_big_ctrl, ctrl_data) +
549 			   sizeof(struct pdu_big_ctrl_chan_map_ind);
550 		pdu->ctrl.opcode = PDU_BIG_CTRL_TYPE_CHAN_MAP_IND;
551 
552 		chm = (void *)&pdu->ctrl.chan_map_ind;
553 		(void)memcpy(chm->chm, lll->chm_chan_map, sizeof(chm->chm));
554 		chm->instant = lll->ctrl_instant;
555 
556 		/* control subevent to use bis = 0 and se_n = 1 */
557 		bis = 0U;
558 		payload_count = lll->payload_count - lll->bn;
559 
560 	} else {
561 		struct lll_adv_iso_stream *stream;
562 		uint16_t stream_handle;
563 		memq_link_t *link;
564 		uint16_t handle;
565 
566 		if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
567 			lll_prof_cputime_capture();
568 		}
569 
570 		for (uint8_t bis_idx = 0U; bis_idx < lll->num_bis; bis_idx++) {
571 			stream_handle = lll->stream_handle[bis_idx];
572 			handle = LL_BIS_ADV_HANDLE_FROM_IDX(stream_handle);
573 			stream = ull_adv_iso_lll_stream_get(stream_handle);
574 			LL_ASSERT(stream);
575 
576 			do {
577 				struct node_tx_iso *tx;
578 
579 				link = memq_peek(stream->memq_tx.head,
580 						 stream->memq_tx.tail,
581 						 (void **)&tx);
582 				if (link) {
583 					if (tx->payload_count >=
584 					    lll->payload_count) {
585 						break;
586 					}
587 
588 					memq_dequeue(stream->memq_tx.tail,
589 						     &stream->memq_tx.head,
590 						     NULL);
591 
592 					tx->next = link;
593 					ull_iso_lll_ack_enqueue(handle, tx);
594 				}
595 			} while (link);
596 		}
597 
598 		/* Close the BIG event as no more subevents */
599 		radio_isr_set(isr_done, lll);
600 		radio_disable();
601 
602 		if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
603 			lll_prof_send();
604 		}
605 
606 		return;
607 	}
608 
609 	lll_isr_tx_status_reset();
610 
611 	/* Calculate the Access Address for the BIS event */
612 	util_bis_aa_le32(bis, lll->seed_access_addr, access_addr);
613 	data_chan_id = lll_chan_id(access_addr);
614 
615 	/* Calculate the CRC init value for the BIS event,
616 	 * preset with the BaseCRCInit value from the BIGInfo data the most
617 	 * significant 2 octets and the BIS_Number for the specific BIS in the
618 	 * least significant octet.
619 	 */
620 	crc_init[0] = bis;
621 	(void)memcpy(&crc_init[1], lll->base_crc_init, sizeof(uint16_t));
622 
623 	radio_aa_set(access_addr);
624 	radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(crc_init));
625 
626 	/* Get ISO data PDU, not control subevent */
627 	if (!pdu) {
628 		uint8_t payload_index;
629 
630 		payload_index = (lll->bn_curr - 1U) +
631 				(lll->ptc_curr * lll->pto);
632 		payload_count = lll->payload_count + payload_index - lll->bn;
633 
634 #if !TEST_WITH_DUMMY_PDU
635 		struct lll_adv_iso_stream *stream;
636 		uint16_t stream_handle;
637 		struct node_tx_iso *tx;
638 		memq_link_t *link;
639 
640 		stream_handle = lll->stream_handle[lll->bis_curr - 1U];
641 		stream = ull_adv_iso_lll_stream_get(stream_handle);
642 		LL_ASSERT(stream);
643 
644 		link = memq_peek_n(stream->memq_tx.head, stream->memq_tx.tail,
645 				   payload_index, (void **)&tx);
646 		if (!link || (tx->payload_count != payload_count)) {
647 			payload_index = 0U;
648 			do {
649 				link = memq_peek_n(stream->memq_tx.head,
650 						   stream->memq_tx.tail,
651 						   payload_index, (void **)&tx);
652 				payload_index++;
653 			} while (link &&
654 				 (tx->payload_count < payload_count));
655 		}
656 		if (!link || (tx->payload_count != payload_count)) {
657 			pdu = radio_pkt_empty_get();
658 			pdu->ll_id = lll->framing ? PDU_BIS_LLID_FRAMED :
659 						    PDU_BIS_LLID_START_CONTINUE;
660 			pdu->len = 0U;
661 		} else {
662 			pdu = (void *)tx->pdu;
663 		}
664 		pdu->cssn = lll->cssn;
665 		pdu->cstf = (lll->term_req || !!(lll->chm_req - lll->chm_ack));
666 
667 #else /* TEST_WITH_DUMMY_PDU */
668 		pdu = radio_pkt_scratch_get();
669 		if (lll->bn_curr >= lll->bn && !(lll->ptc_curr % lll->bn)) {
670 			pdu->ll_id = PDU_BIS_LLID_COMPLETE_END;
671 		} else {
672 			pdu->ll_id = PDU_BIS_LLID_START_CONTINUE;
673 		}
674 		pdu->len = LL_BIS_OCTETS_TX_MAX;
675 		pdu->cssn = lll->cssn;
676 		pdu->cstf = 0U;
677 
678 		pdu->payload[0] = lll->bn_curr;
679 		pdu->payload[1] = lll->irc_curr;
680 		pdu->payload[2] = lll->ptc_curr;
681 		pdu->payload[3] = lll->bis_curr;
682 
683 		pdu->payload[4] = payload_count;
684 		pdu->payload[5] = payload_count >> 8;
685 		pdu->payload[6] = payload_count >> 16;
686 		pdu->payload[7] = payload_count >> 24;
687 		pdu->payload[8] = payload_count >> 32;
688 #endif /* TEST_WITH_DUMMY_PDU */
689 
690 		data_chan_use = lll->next_chan_use;
691 	}
692 	pdu->rfu = 0U;
693 
694 	if (!bis) {
695 		const uint16_t event_counter = payload_count / lll->bn;
696 
697 		/* Calculate the radio channel to use for ISO event */
698 		data_chan_use = lll_chan_iso_event(event_counter, data_chan_id,
699 						   lll->data_chan_map,
700 						   lll->data_chan_count,
701 						   &lll->data_chan_prn_s,
702 						   &lll->data_chan_remap_idx);
703 	}
704 
705 	lll_chan_set(data_chan_use);
706 
707 	/* Encryption */
708 	if (IS_ENABLED(CONFIG_BT_CTLR_BROADCAST_ISO_ENC) &&
709 	    pdu->len && lll->enc) {
710 		lll->ccm_tx.counter = payload_count;
711 
712 		(void)memcpy(lll->ccm_tx.iv, lll->giv, 4U);
713 		mem_xor_32(lll->ccm_tx.iv, lll->ccm_tx.iv, access_addr);
714 
715 		radio_pkt_tx_set(radio_ccm_iso_tx_pkt_set(&lll->ccm_tx,
716 						RADIO_PKT_CONF_PDU_TYPE_BIS,
717 						pdu));
718 	} else {
719 		radio_pkt_tx_set(pdu);
720 	}
721 
722 	/* Control subevent, then complete subevent and close radio use */
723 	if (!bis) {
724 		uint8_t pkt_flags;
725 
726 		pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS,
727 						 lll->phy,
728 						 RADIO_PKT_CONF_CTE_DISABLED);
729 		if (lll->enc) {
730 			radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
731 					    (sizeof(struct pdu_big_ctrl) + PDU_MIC_SIZE),
732 					    pkt_flags);
733 		} else {
734 			radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
735 					    sizeof(struct pdu_big_ctrl),
736 					    pkt_flags);
737 		}
738 
739 		radio_switch_complete_and_b2b_tx_disable();
740 
741 		radio_isr_set(isr_done_term, lll);
742 	} else {
743 		uint16_t iss_us;
744 
745 		/* Calculate next subevent start based on previous PDU length */
746 		iss_us = lll->sub_interval -
747 			 PDU_BIS_US(pdu->len, ((pdu->len) ? lll->enc : 0U),
748 				    lll->phy, lll->phy_flags);
749 
750 		radio_tmr_tifs_set(iss_us);
751 		radio_switch_complete_and_b2b_tx(lll->phy, lll->phy_flags,
752 						 lll->phy, lll->phy_flags);
753 
754 		radio_isr_set(isr_tx, lll);
755 
756 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
757 		/* local variable used later to store iss_us next subevent PA
758 		 * setup.
759 		 */
760 		pa_iss_us = iss_us;
761 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
762 	}
763 
764 	/* assert if radio packet ptr is not set and radio started tx */
765 	LL_ASSERT(!radio_is_ready());
766 
767 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
768 		lll_prof_cputime_capture();
769 	}
770 
771 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR) || IS_ENABLED(HAL_RADIO_GPIO_HAVE_PA_PIN)) {
772 		/* setup capture of PDU end timestamp */
773 		radio_tmr_end_capture();
774 	}
775 
776 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
777 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
778 		/* PA/LNA enable is overwriting packet end used in ISR
779 		 * profiling, hence back it up for later use.
780 		 */
781 		lll_prof_radio_end_backup();
782 	}
783 
784 	radio_gpio_pa_setup();
785 	radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
786 				 lll->pa_iss_us -
787 				 (EVENT_CLOCK_JITTER_US << 1U) -
788 				 radio_tx_chain_delay_get(lll->phy,
789 							  lll->phy_flags) -
790 				 HAL_RADIO_GPIO_PA_OFFSET);
791 
792 	/* Remember to use it for the next subevent PA setup */
793 	lll->pa_iss_us = pa_iss_us;
794 
795 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
796 
797 	/* Calculate ahead the next subevent channel index */
798 	const uint16_t event_counter = (lll->payload_count / lll->bn) - 1U;
799 
800 	next_chan_calc(lll, event_counter, data_chan_id);
801 
802 	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
803 		lll_prof_send();
804 	}
805 }
806 
next_chan_calc(struct lll_adv_iso * lll,uint16_t event_counter,uint16_t data_chan_id)807 static void next_chan_calc(struct lll_adv_iso *lll, uint16_t event_counter,
808 			   uint16_t data_chan_id)
809 {
810 	/* Calculate ahead the next subevent channel index */
811 	if ((lll->bn_curr < lll->bn) ||
812 	    (lll->irc_curr < lll->irc) ||
813 	    (lll->ptc_curr < lll->ptc)) {
814 		/* Calculate the radio channel to use for next subevent */
815 		lll->next_chan_use = lll_chan_iso_subevent(data_chan_id,
816 						lll->data_chan_map,
817 						lll->data_chan_count,
818 						&lll->data_chan_prn_s,
819 						&lll->data_chan_remap_idx);
820 	} else if (lll->bis_curr < lll->num_bis) {
821 		uint8_t access_addr[4];
822 
823 		/* Calculate the Access Address for the next BIS subevent */
824 		util_bis_aa_le32((lll->bis_curr + 1U), lll->seed_access_addr,
825 				 access_addr);
826 		data_chan_id = lll_chan_id(access_addr);
827 
828 		/* Calculate the radio channel to use for next BIS */
829 		lll->next_chan_use = lll_chan_iso_event(event_counter,
830 						data_chan_id,
831 						lll->data_chan_map,
832 						lll->data_chan_count,
833 						&lll->data_chan_prn_s,
834 						&lll->data_chan_remap_idx);
835 	}
836 }
837 
isr_done_create(void * param)838 static void isr_done_create(void *param)
839 {
840 	lll_isr_status_reset();
841 
842 	ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_ADV_ISO_COMPLETE);
843 
844 	lll_isr_cleanup(param);
845 }
846 
isr_done_term(void * param)847 static void isr_done_term(void *param)
848 {
849 	struct lll_adv_iso *lll;
850 	uint16_t elapsed_event;
851 
852 	lll_isr_status_reset();
853 
854 	lll = param;
855 	LL_ASSERT(lll->ctrl_expire);
856 
857 	elapsed_event = lll->latency_event + 1U;
858 	if (lll->ctrl_expire > elapsed_event) {
859 		lll->ctrl_expire -= elapsed_event;
860 	} else {
861 		lll->ctrl_expire = 0U;
862 
863 		if (lll->chm_req != lll->chm_ack) {
864 			struct lll_adv_sync *sync_lll;
865 			struct lll_adv *adv_lll;
866 
867 			/* Reset channel map procedure requested */
868 			lll->chm_ack = lll->chm_req;
869 
870 			/* Request periodic advertising to update channel map
871 			 * in the BIGInfo when filling BIG Offset until Thread
872 			 * context gets to update it using new PDU buffer.
873 			 */
874 			adv_lll = lll->adv;
875 			sync_lll = adv_lll->sync;
876 			if (sync_lll->iso_chm_done_req ==
877 			    sync_lll->iso_chm_done_ack) {
878 				struct node_rx_pdu *rx;
879 
880 				/* Request ULL to update the channel map in the
881 				 * BIGInfo struct present in the current PDU of
882 				 * Periodic Advertising radio events. Channel
883 				 * Map is updated when filling the BIG offset.
884 				 */
885 				sync_lll->iso_chm_done_req++;
886 
887 				/* Notify Thread context to update channel map
888 				 * in the BIGInfo struct present in the Periodic
889 				 * Advertising PDU.
890 				 */
891 				rx = ull_pdu_rx_alloc();
892 				LL_ASSERT(rx);
893 
894 				rx->hdr.type = NODE_RX_TYPE_BIG_CHM_COMPLETE;
895 				rx->rx_ftr.param = lll;
896 
897 				ull_rx_put_sched(rx->hdr.link, rx);
898 			}
899 
900 			/* Use new channel map */
901 			lll->data_chan_count = lll->chm_chan_count;
902 			(void)memcpy(lll->data_chan_map, lll->chm_chan_map,
903 				     sizeof(lll->data_chan_map));
904 		} else {
905 			ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_ADV_ISO_TERMINATE);
906 		}
907 	}
908 
909 	lll_isr_cleanup(param);
910 }
911