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 #if defined(CONFIG_BT_CTLR_ADV_ISO_SEQUENTIAL)
60 static void next_chan_calc_seq(struct lll_adv_iso *lll, uint16_t event_counter,
61 uint16_t data_chan_id);
62 #endif /* CONFIG_BT_CTLR_ADV_ISO_SEQUENTIAL */
63 #if defined(CONFIG_BT_CTLR_ADV_ISO_INTERLEAVED)
64 static void next_chan_calc_int(struct lll_adv_iso *lll, uint16_t event_counter);
65 #endif /* CONFIG_BT_CTLR_ADV_ISO_INTERLEAVED */
66 static void isr_done_create(void *param);
67 static void isr_done_term(void *param);
68
lll_adv_iso_init(void)69 int lll_adv_iso_init(void)
70 {
71 int err;
72
73 err = init_reset();
74 if (err) {
75 return err;
76 }
77
78 return 0;
79 }
80
lll_adv_iso_reset(void)81 int lll_adv_iso_reset(void)
82 {
83 int err;
84
85 err = init_reset();
86 if (err) {
87 return err;
88 }
89
90 return 0;
91 }
92
lll_adv_iso_create_prepare(void * param)93 void lll_adv_iso_create_prepare(void *param)
94 {
95 prepare(param);
96 create_prepare_bh(param);
97 }
98
lll_adv_iso_prepare(void * param)99 void lll_adv_iso_prepare(void *param)
100 {
101 prepare(param);
102 prepare_bh(param);
103 }
104
init_reset(void)105 static int init_reset(void)
106 {
107 return 0;
108 }
109
prepare(void * param)110 static void prepare(void *param)
111 {
112 struct lll_prepare_param *p;
113 struct lll_adv_iso *lll;
114 uint16_t elapsed;
115 int err;
116
117 err = lll_hfclock_on();
118 LL_ASSERT(err >= 0);
119
120 p = param;
121
122 /* Instants elapsed */
123 elapsed = p->lazy + 1U;
124
125 lll = p->param;
126
127 /* Save the (latency + 1) for use in event */
128 lll->latency_prepare += elapsed;
129 }
130
create_prepare_bh(void * param)131 static void create_prepare_bh(void *param)
132 {
133 int err;
134
135 /* Invoke common pipeline handling of prepare */
136 err = lll_prepare(lll_is_abort_cb, lll_abort_cb, create_prepare_cb, 0U,
137 param);
138 LL_ASSERT(!err || err == -EINPROGRESS);
139 }
140
prepare_bh(void * param)141 static void prepare_bh(void *param)
142 {
143 int err;
144
145 /* Invoke common pipeline handling of prepare */
146 err = lll_prepare(lll_is_abort_cb, lll_abort_cb, prepare_cb, 0U, param);
147 LL_ASSERT(!err || err == -EINPROGRESS);
148 }
149
create_prepare_cb(struct lll_prepare_param * p)150 static int create_prepare_cb(struct lll_prepare_param *p)
151 {
152 int err;
153
154 err = prepare_cb_common(p);
155 if (err) {
156 DEBUG_RADIO_START_A(1);
157 return 0;
158 }
159
160 radio_isr_set(isr_tx_create, p->param);
161
162 DEBUG_RADIO_START_A(1);
163 return 0;
164 }
165
prepare_cb(struct lll_prepare_param * p)166 static int prepare_cb(struct lll_prepare_param *p)
167 {
168 int err;
169
170 err = prepare_cb_common(p);
171 if (err) {
172 DEBUG_RADIO_START_A(1);
173 return 0;
174 }
175
176 radio_isr_set(isr_tx_normal, p->param);
177
178 DEBUG_RADIO_START_A(1);
179 return 0;
180 }
181
prepare_cb_common(struct lll_prepare_param * p)182 static int prepare_cb_common(struct lll_prepare_param *p)
183 {
184 struct lll_adv_iso *lll;
185 uint32_t ticks_at_event;
186 uint32_t ticks_at_start;
187 uint16_t event_counter;
188 uint8_t access_addr[4];
189 uint64_t payload_count;
190 uint16_t data_chan_id;
191 uint8_t data_chan_use;
192 uint8_t crc_init[3];
193 struct pdu_bis *pdu;
194 struct ull_hdr *ull;
195 uint32_t remainder;
196 uint32_t start_us;
197 uint8_t pkt_flags;
198 uint32_t ret;
199 uint8_t phy;
200
201 DEBUG_RADIO_START_A(1);
202
203 lll = p->param;
204
205 /* Deduce the latency */
206 lll->latency_event = lll->latency_prepare - 1U;
207
208 /* Calculate the current event counter value */
209 event_counter = (lll->payload_count / lll->bn) + lll->latency_event;
210
211 /* Update BIS payload counter to next value */
212 lll->payload_count += (lll->latency_prepare * lll->bn);
213 payload_count = lll->payload_count - lll->bn;
214
215 /* Reset accumulated latencies */
216 lll->latency_prepare = 0U;
217
218 /* Initialize to mandatory parameter values */
219 lll->bis_curr = 1U;
220 lll->ptc_curr = 0U;
221 lll->irc_curr = 1U;
222 lll->bn_curr = 1U;
223
224 /* Calculate the Access Address for the BIS event */
225 util_bis_aa_le32(lll->bis_curr, lll->seed_access_addr, access_addr);
226 data_chan_id = lll_chan_id(access_addr);
227
228 /* Calculate the CRC init value for the BIS event,
229 * preset with the BaseCRCInit value from the BIGInfo data the most
230 * significant 2 octets and the BIS_Number for the specific BIS in the
231 * least significant octet.
232 */
233 crc_init[0] = lll->bis_curr;
234 (void)memcpy(&crc_init[1], lll->base_crc_init, sizeof(uint16_t));
235
236 /* Calculate the radio channel to use for ISO event */
237 data_chan_use = lll_chan_iso_event(event_counter, data_chan_id,
238 lll->data_chan_map,
239 lll->data_chan_count,
240 &lll->data_chan.prn_s,
241 &lll->data_chan.remap_idx);
242
243 /* Start setting up of Radio h/w */
244 radio_reset();
245
246 #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
247 radio_tx_power_set(lll->adv->tx_pwr_lvl);
248 #else
249 radio_tx_power_set(RADIO_TXP_DEFAULT);
250 #endif
251
252 phy = lll->phy;
253 radio_phy_set(phy, lll->phy_flags);
254 radio_aa_set(access_addr);
255 radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(crc_init));
256 lll_chan_set(data_chan_use);
257
258 /* Get ISO data PDU */
259 #if !TEST_WITH_DUMMY_PDU
260 struct lll_adv_iso_stream *stream;
261 memq_link_t *link = NULL;
262 struct node_tx_iso *tx;
263 uint16_t stream_handle;
264 uint16_t handle;
265 uint8_t bis_idx;
266
267 bis_idx = lll->num_bis;
268 while (bis_idx--) {
269 stream_handle = lll->stream_handle[bis_idx];
270 handle = LL_BIS_ADV_HANDLE_FROM_IDX(stream_handle);
271 stream = ull_adv_iso_lll_stream_get(stream_handle);
272 LL_ASSERT(stream);
273
274 do {
275 link = memq_peek(stream->memq_tx.head,
276 stream->memq_tx.tail, (void **)&tx);
277 if (link) {
278 if (tx->payload_count < payload_count) {
279 memq_dequeue(stream->memq_tx.tail,
280 &stream->memq_tx.head,
281 NULL);
282
283 tx->next = link;
284 ull_iso_lll_ack_enqueue(handle, tx);
285 } else if (tx->payload_count >=
286 lll->payload_count) {
287 link = NULL;
288 } else {
289 if (tx->payload_count !=
290 payload_count) {
291 link = NULL;
292 }
293
294 break;
295 }
296 }
297 } while (link);
298 }
299
300 if (!link) {
301 pdu = radio_pkt_empty_get();
302 pdu->ll_id = lll->framing ? PDU_BIS_LLID_FRAMED : PDU_BIS_LLID_START_CONTINUE;
303 pdu->len = 0U;
304 } else {
305 pdu = (void *)tx->pdu;
306 }
307
308 #else /* TEST_WITH_DUMMY_PDU */
309 pdu = radio_pkt_scratch_get();
310 if (lll->bn_curr >= lll->bn) {
311 pdu->ll_id = PDU_BIS_LLID_COMPLETE_END;
312 } else {
313 pdu->ll_id = PDU_BIS_LLID_START_CONTINUE;
314 }
315 pdu->len = LL_BIS_OCTETS_TX_MAX;
316
317 pdu->payload[0] = lll->bn_curr;
318 pdu->payload[1] = lll->irc_curr;
319 pdu->payload[2] = lll->ptc_curr;
320 pdu->payload[3] = lll->bis_curr;
321
322 pdu->payload[4] = payload_count;
323 pdu->payload[5] = payload_count >> 8;
324 pdu->payload[6] = payload_count >> 16;
325 pdu->payload[7] = payload_count >> 24;
326 pdu->payload[8] = payload_count >> 32;
327 #endif /* TEST_WITH_DUMMY_PDU */
328
329 /* Initialize reserve bit */
330 pdu->rfu = 0U;
331
332 /* Handle control procedure */
333 if (unlikely(lll->term_req || !!(lll->chm_req - lll->chm_ack))) {
334 if (lll->term_req) {
335 if (!lll->term_ack) {
336 lll->term_ack = 1U;
337 lll->ctrl_expire = CONN_ESTAB_COUNTDOWN;
338 lll->ctrl_instant = event_counter +
339 lll->ctrl_expire - 1U;
340 lll->cssn++;
341 }
342 } else if (((lll->chm_req - lll->chm_ack) & CHM_STATE_MASK) ==
343 CHM_STATE_REQ) {
344 lll->chm_ack--;
345 lll->ctrl_expire = CONN_ESTAB_COUNTDOWN;
346 lll->ctrl_instant = event_counter + lll->ctrl_expire;
347 lll->cssn++;
348 }
349
350 pdu->cstf = 1U;
351 } else {
352 pdu->cstf = 0U;
353 }
354 pdu->cssn = lll->cssn;
355
356 /* Radio packet configuration */
357 pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS, phy,
358 RADIO_PKT_CONF_CTE_DISABLED);
359 if (IS_ENABLED(CONFIG_BT_CTLR_BROADCAST_ISO_ENC) &&
360 pdu->len && lll->enc) {
361 /* Encryption */
362 lll->ccm_tx.counter = payload_count;
363
364 (void)memcpy(lll->ccm_tx.iv, lll->giv, 4U);
365 mem_xor_32(lll->ccm_tx.iv, lll->ccm_tx.iv, access_addr);
366
367 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
368 (lll->max_pdu + PDU_MIC_SIZE), pkt_flags);
369
370 radio_pkt_tx_set(radio_ccm_iso_tx_pkt_set(&lll->ccm_tx,
371 RADIO_PKT_CONF_PDU_TYPE_BIS,
372 pdu));
373 } else {
374 if (lll->enc) {
375 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
376 (lll->max_pdu + PDU_MIC_SIZE),
377 pkt_flags);
378 } else {
379 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
380 lll->max_pdu, pkt_flags);
381 }
382
383 radio_pkt_tx_set(pdu);
384 }
385
386 const bool is_sequential_packing = (lll->bis_spacing >= (lll->sub_interval * lll->nse));
387
388 /* Setup radio IFS switching */
389 if ((lll->bn_curr == lll->bn) &&
390 (lll->irc_curr == lll->irc) &&
391 (lll->ptc_curr == lll->ptc) &&
392 (lll->bis_curr == lll->num_bis) &&
393 !pdu->cstf) {
394 radio_switch_complete_and_disable();
395 } else {
396 uint16_t iss_us;
397
398 /* Calculate next subevent start based on previous PDU length */
399 iss_us = is_sequential_packing ? lll->sub_interval : lll->bis_spacing;
400 iss_us -= PDU_BIS_US(pdu->len, ((pdu->len) ? lll->enc : 0U),
401 lll->phy, lll->phy_flags);
402
403 radio_tmr_tifs_set(iss_us);
404 radio_switch_complete_and_b2b_tx(lll->phy, lll->phy_flags,
405 lll->phy, lll->phy_flags);
406 }
407
408 ticks_at_event = p->ticks_at_expire;
409 ull = HDR_LLL2ULL(lll);
410 ticks_at_event += lll_event_offset_get(ull);
411
412 ticks_at_start = ticks_at_event;
413 ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
414
415 remainder = p->remainder;
416 start_us = radio_tmr_start(1U, ticks_at_start, remainder);
417
418 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR) || IS_ENABLED(HAL_RADIO_GPIO_HAVE_PA_PIN)) {
419 /* setup capture of PDU end timestamp */
420 radio_tmr_end_capture();
421 }
422
423 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
424 radio_gpio_pa_setup();
425
426 radio_gpio_pa_lna_enable(start_us +
427 radio_tx_ready_delay_get(lll->phy,
428 lll->phy_flags) -
429 HAL_RADIO_GPIO_PA_OFFSET);
430 #else /* !HAL_RADIO_GPIO_HAVE_PA_PIN */
431 ARG_UNUSED(start_us);
432 #endif /* !HAL_RADIO_GPIO_HAVE_PA_PIN */
433
434 #if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
435 (EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
436 uint32_t overhead;
437
438 overhead = lll_preempt_calc(ull, (TICKER_ID_ADV_ISO_BASE + lll->handle), ticks_at_event);
439 /* check if preempt to start has changed */
440 if (overhead) {
441 LL_ASSERT_OVERHEAD(overhead);
442
443 radio_isr_set(lll_isr_abort, lll);
444 radio_disable();
445
446 return -ECANCELED;
447 }
448 #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
449
450 ret = lll_prepare_done(lll);
451 LL_ASSERT(!ret);
452
453 /* Calculate ahead the next subevent channel index */
454 if (false) {
455
456 #if defined(CONFIG_BT_CTLR_ADV_ISO_SEQUENTIAL)
457 } else if (is_sequential_packing) {
458 next_chan_calc_seq(lll, event_counter, data_chan_id);
459 #endif /* CONFIG_BT_CTLR_ADV_ISO_SEQUENTIAL */
460
461 #if defined(CONFIG_BT_CTLR_ADV_ISO_INTERLEAVED)
462 } else if (!is_sequential_packing) {
463 struct lll_adv_iso_data_chan_interleaved *interleaved_data_chan;
464
465 interleaved_data_chan =
466 &lll->interleaved_data_chan[lll->bis_curr - 1U];
467 interleaved_data_chan->id = data_chan_id;
468
469 next_chan_calc_int(lll, event_counter);
470 #endif /* CONFIG_BT_CTLR_ADV_ISO_INTERLEAVED */
471
472 } else {
473 LL_ASSERT(false);
474 }
475
476 return 0;
477 }
478
isr_tx_create(void * param)479 static void isr_tx_create(void *param)
480 {
481 isr_tx_common(param, isr_tx_create, isr_done_create);
482 }
483
isr_tx_normal(void * param)484 static void isr_tx_normal(void *param)
485 {
486 isr_tx_common(param, isr_tx_normal, lll_isr_done);
487 }
488
isr_tx_common(void * param,radio_isr_cb_t isr_tx,radio_isr_cb_t isr_done)489 static void isr_tx_common(void *param,
490 radio_isr_cb_t isr_tx,
491 radio_isr_cb_t isr_done)
492 {
493 struct pdu_bis *pdu = NULL;
494 uint8_t data_chan_use = 0;
495 struct lll_adv_iso *lll;
496 uint8_t access_addr[4];
497 uint64_t payload_count;
498 uint16_t data_chan_id;
499 uint8_t crc_init[3];
500 uint8_t is_ctrl;
501 uint8_t bis;
502
503 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
504 uint16_t pa_iss_us = 0U;
505 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
506
507 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
508 lll_prof_latency_capture();
509 }
510
511 lll = param;
512
513 /* Sequential or Interleaved BIS subevents decision */
514 const bool is_sequential_packing = (lll->bis_spacing >= (lll->sub_interval * lll->nse));
515
516 is_ctrl = 0U;
517 if (false) {
518
519 #if defined(CONFIG_BT_CTLR_ADV_ISO_SEQUENTIAL)
520 } else if (is_sequential_packing) {
521 /* Sequential Tx complete flow */
522 if (lll->bn_curr < lll->bn) {
523 /* transmit the (bn_curr)th Tx PDU of bis_curr */
524 lll->bn_curr++; /* post increment */
525
526 bis = lll->bis_curr;
527
528 } else if (lll->irc_curr < lll->irc) {
529 /* transmit the (bn_curr)th Tx PDU of bis_curr */
530 lll->bn_curr = 1U;
531 lll->irc_curr++; /* post increment */
532
533 bis = lll->bis_curr;
534
535 } else if (lll->ptc_curr < lll->ptc) {
536 lll->ptc_curr++; /* pre increment */
537 /* transmit the (ptc_curr * bn)th Tx PDU */
538
539 bis = lll->bis_curr;
540
541 } else if (lll->bis_curr < lll->num_bis) {
542 lll->bis_curr++;
543 lll->ptc_curr = 0U;
544 lll->irc_curr = 1U;
545 /* transmit the (bn_curr)th PDU of bis_curr */
546 lll->bn_curr = 1U;
547
548 bis = lll->bis_curr;
549 } else {
550 is_ctrl = 1U;
551 }
552 #endif /* CONFIG_BT_CTLR_ADV_ISO_SEQUENTIAL */
553
554 #if defined(CONFIG_BT_CTLR_ADV_ISO_INTERLEAVED)
555 } else if (!is_sequential_packing) {
556 /* Interleaved Tx complete flow */
557 if (lll->bis_curr < lll->num_bis) {
558 lll->bis_curr++;
559
560 bis = lll->bis_curr;
561 } else if (lll->bn_curr < lll->bn) {
562 lll->bn_curr++;
563 lll->bis_curr = 1U;
564
565 bis = lll->bis_curr;
566 } else if (lll->irc_curr < lll->irc) {
567 lll->irc_curr++;
568 lll->bn_curr = 1U;
569 lll->bis_curr = 1U;
570
571 bis = lll->bis_curr;
572 } else if (lll->ptc_curr < lll->ptc) {
573 lll->ptc_curr++;
574 lll->bis_curr = 1U;
575
576 bis = lll->bis_curr;
577 } else {
578 is_ctrl = 1U;
579 }
580 #endif /* CONFIG_BT_CTLR_ADV_ISO_INTERLEAVED */
581
582 } else {
583 bis = 0U;
584
585 LL_ASSERT(false);
586 }
587
588 if (!is_ctrl) {
589 /* ISO data subevent, nothing to do here */
590
591 } else if (lll->term_ack) {
592 /* Transmit the control PDU and close the BIG event
593 * there after.
594 */
595 struct pdu_big_ctrl_term_ind *term;
596
597 pdu = radio_pkt_big_ctrl_get();
598 pdu->ll_id = PDU_BIS_LLID_CTRL;
599 pdu->cssn = lll->cssn;
600 pdu->cstf = 0U;
601
602 pdu->len = offsetof(struct pdu_big_ctrl, ctrl_data) +
603 sizeof(struct pdu_big_ctrl_term_ind);
604 pdu->ctrl.opcode = PDU_BIG_CTRL_TYPE_TERM_IND;
605
606 term = (void *)&pdu->ctrl.term_ind;
607 term->reason = lll->term_reason;
608 term->instant = lll->ctrl_instant;
609
610 /* control subevent to use bis = 0 and se_n = 1 */
611 bis = 0U;
612 payload_count = lll->payload_count - lll->bn;
613
614 } else if (((lll->chm_req - lll->chm_ack) & CHM_STATE_MASK) ==
615 CHM_STATE_SEND) {
616 /* Transmit the control PDU and stop after 6 intervals
617 */
618 struct pdu_big_ctrl_chan_map_ind *chm;
619
620 pdu = radio_pkt_big_ctrl_get();
621 pdu->ll_id = PDU_BIS_LLID_CTRL;
622 pdu->cssn = lll->cssn;
623 pdu->cstf = 0U;
624
625 pdu->len = offsetof(struct pdu_big_ctrl, ctrl_data) +
626 sizeof(struct pdu_big_ctrl_chan_map_ind);
627 pdu->ctrl.opcode = PDU_BIG_CTRL_TYPE_CHAN_MAP_IND;
628
629 chm = (void *)&pdu->ctrl.chan_map_ind;
630 (void)memcpy(chm->chm, lll->chm_chan_map, sizeof(chm->chm));
631 chm->instant = lll->ctrl_instant;
632
633 /* control subevent to use bis = 0 and se_n = 1 */
634 bis = 0U;
635 payload_count = lll->payload_count - lll->bn;
636
637 } else {
638 /* All subevents in the ISO interval is done. */
639 struct lll_adv_iso_stream *stream;
640 uint16_t stream_handle;
641 memq_link_t *link;
642 uint16_t handle;
643
644 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
645 lll_prof_cputime_capture();
646 }
647
648 for (uint8_t bis_idx = 0U; bis_idx < lll->num_bis; bis_idx++) {
649 stream_handle = lll->stream_handle[bis_idx];
650 handle = LL_BIS_ADV_HANDLE_FROM_IDX(stream_handle);
651 stream = ull_adv_iso_lll_stream_get(stream_handle);
652 LL_ASSERT(stream);
653
654 do {
655 struct node_tx_iso *tx;
656
657 link = memq_peek(stream->memq_tx.head,
658 stream->memq_tx.tail,
659 (void **)&tx);
660 if (link) {
661 if (tx->payload_count >=
662 lll->payload_count) {
663 break;
664 }
665
666 memq_dequeue(stream->memq_tx.tail,
667 &stream->memq_tx.head,
668 NULL);
669
670 tx->next = link;
671 ull_iso_lll_ack_enqueue(handle, tx);
672 }
673 } while (link);
674 }
675
676 /* Close the BIG event as no more subevents */
677 radio_isr_set(isr_done, lll);
678 radio_disable();
679
680 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
681 lll_prof_send();
682 }
683
684 return;
685 }
686
687 lll_isr_tx_status_reset();
688
689 /* Calculate the Access Address for the BIS event */
690 util_bis_aa_le32(bis, lll->seed_access_addr, access_addr);
691 data_chan_id = lll_chan_id(access_addr);
692
693 /* Calculate the CRC init value for the BIS event,
694 * preset with the BaseCRCInit value from the BIGInfo data the most
695 * significant 2 octets and the BIS_Number for the specific BIS in the
696 * least significant octet.
697 */
698 crc_init[0] = bis;
699 (void)memcpy(&crc_init[1], lll->base_crc_init, sizeof(uint16_t));
700
701 radio_aa_set(access_addr);
702 radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(crc_init));
703
704 /* Get ISO data PDU, not control subevent */
705 if (!pdu) {
706 uint16_t payload_index;
707
708 if (lll->ptc_curr) {
709 /* FIXME: Do not remember why ptc is 4 bits, it should be 5 bits as ptc is a
710 * running buffer offset related to nse.
711 * Fix ptc and ptc_curr definitions, until then there is an assertion
712 * check when ptc is calculated in ptc_calc function.
713 */
714 uint8_t ptx_idx = lll->ptc_curr - 1U; /* max. nse 5 bits */
715 uint8_t ptx_payload_idx;
716 uint16_t ptx_group_mult;
717 uint8_t ptx_group_idx;
718
719 /* Calculate group index and multiplier for deriving
720 * pre-transmission payload index.
721 */
722 ptx_group_idx = ptx_idx / lll->bn; /* 5 bits */
723 ptx_payload_idx = ptx_idx - ptx_group_idx * lll->bn; /* 8 bits */
724 ptx_group_mult = (ptx_group_idx + 1U) * lll->pto; /* 9 bits */
725 payload_index = ptx_payload_idx + ptx_group_mult * lll->bn; /* 13 bits */
726
727 /* FIXME: memq_peek_n function does not support indices > UINT8_MAX,
728 * add assertion check to honor this limitation.
729 */
730 LL_ASSERT(payload_index <= UINT8_MAX);
731 } else {
732 payload_index = lll->bn_curr - 1U; /* 3 bits */
733 }
734
735 payload_count = lll->payload_count + payload_index - lll->bn;
736
737 #if !TEST_WITH_DUMMY_PDU
738 struct lll_adv_iso_stream *stream;
739 uint16_t stream_handle;
740 struct node_tx_iso *tx;
741 memq_link_t *link;
742
743 stream_handle = lll->stream_handle[lll->bis_curr - 1U];
744 stream = ull_adv_iso_lll_stream_get(stream_handle);
745 LL_ASSERT(stream);
746
747 link = memq_peek_n(stream->memq_tx.head, stream->memq_tx.tail,
748 payload_index, (void **)&tx);
749 if (!link || (tx->payload_count != payload_count)) {
750 payload_index = 0U;
751 do {
752 link = memq_peek_n(stream->memq_tx.head,
753 stream->memq_tx.tail,
754 payload_index, (void **)&tx);
755 payload_index++;
756 } while (link &&
757 (tx->payload_count < payload_count));
758 }
759 if (!link || (tx->payload_count != payload_count)) {
760 /* FIXME: Do not transmit on air an empty PDU if this is a Pre-Transmission
761 * subevent, instead use radio_tmr_start_us() to schedule next valid
762 * subevent.
763 */
764 pdu = radio_pkt_empty_get();
765 pdu->ll_id = lll->framing ? PDU_BIS_LLID_FRAMED :
766 PDU_BIS_LLID_START_CONTINUE;
767 pdu->len = 0U;
768 } else {
769 pdu = (void *)tx->pdu;
770 }
771 pdu->cssn = lll->cssn;
772 pdu->cstf = (lll->term_req || !!(lll->chm_req - lll->chm_ack));
773
774 #else /* TEST_WITH_DUMMY_PDU */
775 pdu = radio_pkt_scratch_get();
776 if (lll->bn_curr >= lll->bn && !(lll->ptc_curr % lll->bn)) {
777 pdu->ll_id = PDU_BIS_LLID_COMPLETE_END;
778 } else {
779 pdu->ll_id = PDU_BIS_LLID_START_CONTINUE;
780 }
781 pdu->len = LL_BIS_OCTETS_TX_MAX;
782 pdu->cssn = lll->cssn;
783 pdu->cstf = 0U;
784
785 pdu->payload[0] = lll->bn_curr;
786 pdu->payload[1] = lll->irc_curr;
787 pdu->payload[2] = lll->ptc_curr;
788 pdu->payload[3] = lll->bis_curr;
789
790 pdu->payload[4] = payload_count;
791 pdu->payload[5] = payload_count >> 8;
792 pdu->payload[6] = payload_count >> 16;
793 pdu->payload[7] = payload_count >> 24;
794 pdu->payload[8] = payload_count >> 32;
795 #endif /* TEST_WITH_DUMMY_PDU */
796
797 data_chan_use = lll->next_chan_use;
798 }
799 pdu->rfu = 0U;
800
801 if (!bis) {
802 const uint16_t event_counter = payload_count / lll->bn;
803
804 /* Calculate the radio channel to use for ISO event */
805 data_chan_use = lll_chan_iso_event(event_counter, data_chan_id,
806 lll->data_chan_map,
807 lll->data_chan_count,
808 &lll->data_chan.prn_s,
809 &lll->data_chan.remap_idx);
810 }
811
812 lll_chan_set(data_chan_use);
813
814 /* Encryption */
815 if (IS_ENABLED(CONFIG_BT_CTLR_BROADCAST_ISO_ENC) &&
816 pdu->len && lll->enc) {
817 lll->ccm_tx.counter = payload_count;
818
819 (void)memcpy(lll->ccm_tx.iv, lll->giv, 4U);
820 mem_xor_32(lll->ccm_tx.iv, lll->ccm_tx.iv, access_addr);
821
822 radio_pkt_tx_set(radio_ccm_iso_tx_pkt_set(&lll->ccm_tx,
823 RADIO_PKT_CONF_PDU_TYPE_BIS,
824 pdu));
825 } else {
826 radio_pkt_tx_set(pdu);
827 }
828
829 /* Control subevent, then complete subevent and close radio use */
830 if (!bis) {
831 uint8_t pkt_flags;
832
833 pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS,
834 lll->phy,
835 RADIO_PKT_CONF_CTE_DISABLED);
836 if (lll->enc) {
837 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
838 (sizeof(struct pdu_big_ctrl) + PDU_MIC_SIZE),
839 pkt_flags);
840 } else {
841 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
842 sizeof(struct pdu_big_ctrl),
843 pkt_flags);
844 }
845
846 radio_switch_complete_and_b2b_tx_disable();
847
848 radio_isr_set(isr_done_term, lll);
849 } else {
850 uint16_t iss_us;
851
852 /* Calculate next subevent start based on previous PDU length */
853 iss_us = is_sequential_packing ? lll->sub_interval : lll->bis_spacing;
854 iss_us -= PDU_BIS_US(pdu->len, ((pdu->len) ? lll->enc : 0U),
855 lll->phy, lll->phy_flags);
856
857 radio_tmr_tifs_set(iss_us);
858 radio_switch_complete_and_b2b_tx(lll->phy, lll->phy_flags,
859 lll->phy, lll->phy_flags);
860
861 radio_isr_set(isr_tx, lll);
862
863 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
864 /* local variable used later to store iss_us next subevent PA
865 * setup.
866 */
867 pa_iss_us = iss_us;
868 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
869 }
870
871 /* assert if radio packet ptr is not set and radio started tx */
872 LL_ASSERT(!radio_is_ready());
873
874 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
875 lll_prof_cputime_capture();
876 }
877
878 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR) || IS_ENABLED(HAL_RADIO_GPIO_HAVE_PA_PIN)) {
879 /* setup capture of PDU end timestamp */
880 radio_tmr_end_capture();
881 }
882
883 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
884 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
885 /* PA/LNA enable is overwriting packet end used in ISR
886 * profiling, hence back it up for later use.
887 */
888 lll_prof_radio_end_backup();
889 }
890
891 radio_gpio_pa_setup();
892 radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
893 lll->pa_iss_us -
894 (EVENT_CLOCK_JITTER_US << 1U) -
895 radio_tx_chain_delay_get(lll->phy,
896 lll->phy_flags) -
897 HAL_RADIO_GPIO_PA_OFFSET);
898
899 /* Remember to use it for the next subevent PA setup */
900 lll->pa_iss_us = pa_iss_us;
901
902 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
903
904 /* Calculate ahead the next subevent channel index */
905 const uint16_t event_counter = (lll->payload_count / lll->bn) - 1U;
906
907 if (false) {
908
909 #if defined(CONFIG_BT_CTLR_ADV_ISO_SEQUENTIAL)
910 } else if (is_sequential_packing) {
911 next_chan_calc_seq(lll, event_counter, data_chan_id);
912 #endif /* CONFIG_BT_CTLR_ADV_ISO_SEQUENTIAL */
913
914 #if defined(CONFIG_BT_CTLR_ADV_ISO_INTERLEAVED)
915 } else if (!is_sequential_packing) {
916 next_chan_calc_int(lll, event_counter);
917 #endif /* CONFIG_BT_CTLR_ADV_ISO_INTERLEAVED */
918
919 } else {
920 LL_ASSERT(false);
921 }
922
923 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
924 lll_prof_send();
925 }
926 }
927
928 #if defined(CONFIG_BT_CTLR_ADV_ISO_SEQUENTIAL)
next_chan_calc_seq(struct lll_adv_iso * lll,uint16_t event_counter,uint16_t data_chan_id)929 static void next_chan_calc_seq(struct lll_adv_iso *lll, uint16_t event_counter,
930 uint16_t data_chan_id)
931 {
932 /* Calculate ahead the next subevent channel index */
933 if ((lll->bn_curr < lll->bn) ||
934 (lll->irc_curr < lll->irc) ||
935 (lll->ptc_curr < lll->ptc)) {
936 /* Calculate the radio channel to use for next subevent */
937 lll->next_chan_use =
938 lll_chan_iso_subevent(data_chan_id,
939 lll->data_chan_map,
940 lll->data_chan_count,
941 &lll->data_chan.prn_s,
942 &lll->data_chan.remap_idx);
943 } else if (lll->bis_curr < lll->num_bis) {
944 uint8_t access_addr[4];
945
946 /* Calculate the Access Address for the next BIS subevent */
947 util_bis_aa_le32((lll->bis_curr + 1U), lll->seed_access_addr,
948 access_addr);
949 data_chan_id = lll_chan_id(access_addr);
950
951 /* Calculate the radio channel to use for next BIS */
952 lll->next_chan_use =
953 lll_chan_iso_event(event_counter,
954 data_chan_id,
955 lll->data_chan_map,
956 lll->data_chan_count,
957 &lll->data_chan.prn_s,
958 &lll->data_chan.remap_idx);
959 }
960 }
961 #endif /* CONFIG_BT_CTLR_ADV_ISO_SEQUENTIAL */
962
963 #if defined(CONFIG_BT_CTLR_ADV_ISO_INTERLEAVED)
next_chan_calc_int(struct lll_adv_iso * lll,uint16_t event_counter)964 static void next_chan_calc_int(struct lll_adv_iso *lll, uint16_t event_counter)
965 {
966 struct lll_adv_iso_data_chan_interleaved *interleaved_data_chan;
967
968 if ((lll->bis_curr >= lll->num_bis) &&
969 (lll->bn_curr >= lll->bn) &&
970 (lll->irc_curr >= lll->irc) &&
971 (lll->ptc_curr >= lll->ptc)) {
972 return;
973 }
974
975 if ((lll->bis_curr < lll->num_bis) &&
976 (lll->bn_curr == 1U) &&
977 (lll->irc_curr == 1U) &&
978 (lll->ptc_curr == 0U)) {
979 uint8_t access_addr[4];
980
981 /* Calculate the Access Address for the next BIS subevent */
982 util_bis_aa_le32((lll->bis_curr + 1U), lll->seed_access_addr,
983 access_addr);
984
985 interleaved_data_chan =
986 &lll->interleaved_data_chan[lll->bis_curr];
987 interleaved_data_chan->id = lll_chan_id(access_addr);
988
989 /* Calculate the radio channel to use for next BIS */
990 lll->next_chan_use =
991 lll_chan_iso_event(event_counter,
992 interleaved_data_chan->id,
993 lll->data_chan_map,
994 lll->data_chan_count,
995 &interleaved_data_chan->prn_s,
996 &interleaved_data_chan->remap_idx);
997 } else {
998 uint8_t bis_idx;
999
1000 if (lll->bis_curr >= lll->num_bis) {
1001 bis_idx = 0U;
1002 } else {
1003 bis_idx = lll->bis_curr;
1004 }
1005
1006 interleaved_data_chan = &lll->interleaved_data_chan[bis_idx];
1007
1008 /* Calculate the radio channel to use for next subevent */
1009 lll->next_chan_use =
1010 lll_chan_iso_subevent(interleaved_data_chan->id,
1011 lll->data_chan_map,
1012 lll->data_chan_count,
1013 &interleaved_data_chan->prn_s,
1014 &interleaved_data_chan->remap_idx);
1015 }
1016 }
1017 #endif /* CONFIG_BT_CTLR_ADV_ISO_INTERLEAVED */
1018
isr_done_create(void * param)1019 static void isr_done_create(void *param)
1020 {
1021 lll_isr_status_reset();
1022
1023 ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_ADV_ISO_COMPLETE);
1024
1025 lll_isr_cleanup(param);
1026 }
1027
isr_done_term(void * param)1028 static void isr_done_term(void *param)
1029 {
1030 struct lll_adv_iso *lll;
1031 uint16_t elapsed_event;
1032
1033 lll_isr_status_reset();
1034
1035 lll = param;
1036 LL_ASSERT(lll->ctrl_expire);
1037
1038 elapsed_event = lll->latency_event + 1U;
1039 if (lll->ctrl_expire > elapsed_event) {
1040 lll->ctrl_expire -= elapsed_event;
1041 } else {
1042 lll->ctrl_expire = 0U;
1043
1044 if (lll->chm_req != lll->chm_ack) {
1045 struct lll_adv_sync *sync_lll;
1046 struct lll_adv *adv_lll;
1047
1048 /* Reset channel map procedure requested */
1049 lll->chm_ack = lll->chm_req;
1050
1051 /* Request periodic advertising to update channel map
1052 * in the BIGInfo when filling BIG Offset until Thread
1053 * context gets to update it using new PDU buffer.
1054 */
1055 adv_lll = lll->adv;
1056 sync_lll = adv_lll->sync;
1057 if (sync_lll->iso_chm_done_req ==
1058 sync_lll->iso_chm_done_ack) {
1059 struct node_rx_pdu *rx;
1060
1061 /* Request ULL to update the channel map in the
1062 * BIGInfo struct present in the current PDU of
1063 * Periodic Advertising radio events. Channel
1064 * Map is updated when filling the BIG offset.
1065 */
1066 sync_lll->iso_chm_done_req++;
1067
1068 /* Notify Thread context to update channel map
1069 * in the BIGInfo struct present in the Periodic
1070 * Advertising PDU.
1071 */
1072 rx = ull_pdu_rx_alloc();
1073 LL_ASSERT(rx);
1074
1075 rx->hdr.type = NODE_RX_TYPE_BIG_CHM_COMPLETE;
1076 rx->rx_ftr.param = lll;
1077
1078 ull_rx_put_sched(rx->hdr.link, rx);
1079 }
1080
1081 /* Use new channel map */
1082 lll->data_chan_count = lll->chm_chan_count;
1083 (void)memcpy(lll->data_chan_map, lll->chm_chan_map,
1084 sizeof(lll->data_chan_map));
1085 } else {
1086 ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_ADV_ISO_TERMINATE);
1087 }
1088 }
1089
1090 lll_isr_cleanup(param);
1091 }
1092