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
13 #include "hal/cpu.h"
14 #include "hal/ccm.h"
15 #include "hal/radio.h"
16 #include "hal/ticker.h"
17
18 #include "util/util.h"
19 #include "util/mem.h"
20 #include "util/memq.h"
21
22 #include "pdu_df.h"
23 #include "lll/pdu_vendor.h"
24 #include "pdu.h"
25
26 #include "lll.h"
27 #include "lll_vendor.h"
28 #include "lll_clock.h"
29 #include "lll_chan.h"
30 #include "lll_sync_iso.h"
31
32 #include "lll_internal.h"
33 #include "lll_tim_internal.h"
34 #include "lll_prof_internal.h"
35
36 #include "ll_feat.h"
37
38 #include "hal/debug.h"
39
40 static int init_reset(void);
41 static void prepare(void *param);
42 static void create_prepare_bh(void *param);
43 static void prepare_bh(void *param);
44 static int create_prepare_cb(struct lll_prepare_param *p);
45 static int prepare_cb(struct lll_prepare_param *p);
46 static int prepare_cb_common(struct lll_prepare_param *p);
47 static void abort_cb(struct lll_prepare_param *prepare_param, void *param);
48 static void isr_rx_estab(void *param);
49 static void isr_rx(void *param);
50 static void isr_rx_done(void *param);
51 static void isr_done(void *param);
52 static void next_chan_calc(struct lll_sync_iso *lll, uint16_t event_counter,
53 uint16_t data_chan_id);
54 static void isr_rx_iso_data_valid(const struct lll_sync_iso *const lll,
55 uint16_t handle, struct node_rx_pdu *node_rx);
56 static void isr_rx_iso_data_invalid(const struct lll_sync_iso *const lll,
57 uint8_t bn, uint16_t handle,
58 struct node_rx_pdu *node_rx);
59 static void isr_rx_ctrl_recv(struct lll_sync_iso *lll, struct pdu_bis *pdu);
60
61 /* FIXME: Optimize by moving to a common place, as similar variable is used for
62 * connections too.
63 */
64 static uint8_t trx_cnt;
65 static uint8_t crc_ok_anchor;
66
lll_sync_iso_init(void)67 int lll_sync_iso_init(void)
68 {
69 int err;
70
71 err = init_reset();
72 if (err) {
73 return err;
74 }
75
76 return 0;
77 }
78
lll_sync_iso_reset(void)79 int lll_sync_iso_reset(void)
80 {
81 int err;
82
83 err = init_reset();
84 if (err) {
85 return err;
86 }
87
88 return 0;
89 }
90
lll_sync_iso_create_prepare(void * param)91 void lll_sync_iso_create_prepare(void *param)
92 {
93 prepare(param);
94 create_prepare_bh(param);
95 }
96
lll_sync_iso_prepare(void * param)97 void lll_sync_iso_prepare(void *param)
98 {
99 prepare(param);
100 prepare_bh(param);
101 }
102
init_reset(void)103 static int init_reset(void)
104 {
105 return 0;
106 }
107
prepare(void * param)108 static void prepare(void *param)
109 {
110 struct lll_prepare_param *p;
111 struct lll_sync_iso *lll;
112 uint16_t elapsed;
113 int err;
114
115 err = lll_hfclock_on();
116 LL_ASSERT(err >= 0);
117
118 p = param;
119
120 /* Instants elapsed */
121 elapsed = p->lazy + 1U;
122
123 lll = p->param;
124
125 /* Save the (latency + 1) for use in event */
126 lll->latency_prepare += elapsed;
127
128 /* Accumulate window widening */
129 lll->window_widening_prepare_us += lll->window_widening_periodic_us *
130 elapsed;
131 if (lll->window_widening_prepare_us > lll->window_widening_max_us) {
132 lll->window_widening_prepare_us = lll->window_widening_max_us;
133 }
134 }
135
create_prepare_bh(void * param)136 static void create_prepare_bh(void *param)
137 {
138 int err;
139
140 /* Invoke common pipeline handling of prepare */
141 err = lll_prepare(lll_is_abort_cb, abort_cb, create_prepare_cb, 0U,
142 param);
143 LL_ASSERT(!err || err == -EINPROGRESS);
144 }
145
prepare_bh(void * param)146 static void prepare_bh(void *param)
147 {
148 int err;
149
150 /* Invoke common pipeline handling of prepare */
151 err = lll_prepare(lll_is_abort_cb, abort_cb, prepare_cb, 0U, param);
152 LL_ASSERT(!err || err == -EINPROGRESS);
153 }
154
create_prepare_cb(struct lll_prepare_param * p)155 static int create_prepare_cb(struct lll_prepare_param *p)
156 {
157 int err;
158
159 err = prepare_cb_common(p);
160 if (err) {
161 DEBUG_RADIO_START_O(1);
162 return 0;
163 }
164
165 radio_isr_set(isr_rx_estab, p->param);
166
167 DEBUG_RADIO_START_O(1);
168 return 0;
169 }
170
prepare_cb(struct lll_prepare_param * p)171 static int prepare_cb(struct lll_prepare_param *p)
172 {
173 int err;
174
175 err = prepare_cb_common(p);
176 if (err) {
177 DEBUG_RADIO_START_O(1);
178 return 0;
179 }
180
181 radio_isr_set(isr_rx, p->param);
182
183 DEBUG_RADIO_START_O(1);
184 return 0;
185 }
186
prepare_cb_common(struct lll_prepare_param * p)187 static int prepare_cb_common(struct lll_prepare_param *p)
188 {
189 struct lll_sync_iso_stream *stream;
190 struct node_rx_pdu *node_rx;
191 struct lll_sync_iso *lll;
192 uint32_t ticks_at_event;
193 uint32_t ticks_at_start;
194 uint16_t stream_handle;
195 uint16_t event_counter;
196 uint8_t access_addr[4];
197 uint16_t data_chan_id;
198 uint8_t data_chan_use;
199 uint32_t remainder_us;
200 uint8_t crc_init[3];
201 struct ull_hdr *ull;
202 uint32_t remainder;
203 uint32_t hcto;
204 uint32_t ret;
205 uint8_t phy;
206
207 DEBUG_RADIO_START_O(1);
208
209 lll = p->param;
210
211 /* Deduce the latency */
212 lll->latency_event = lll->latency_prepare - 1U;
213
214 /* Calculate the current event counter value */
215 event_counter = (lll->payload_count / lll->bn) + lll->latency_event;
216
217 /* Update BIS packet counter to next value */
218 lll->payload_count += (lll->latency_prepare * lll->bn);
219
220 /* Reset accumulated latencies */
221 lll->latency_prepare = 0U;
222
223 /* Current window widening */
224 lll->window_widening_event_us += lll->window_widening_prepare_us;
225 lll->window_widening_prepare_us = 0U;
226 if (lll->window_widening_event_us > lll->window_widening_max_us) {
227 lll->window_widening_event_us = lll->window_widening_max_us;
228 }
229
230 /* Initialize trx chain count */
231 trx_cnt = 0U;
232
233 /* Initialize anchor point CRC ok flag */
234 crc_ok_anchor = 0U;
235
236 /* Initialize to mandatory parameter values */
237 lll->bis_curr = 1U;
238 lll->ptc_curr = 0U;
239 lll->irc_curr = 1U;
240 lll->bn_curr = 1U;
241
242 /* Initialize control subevent flag */
243 lll->ctrl = 0U;
244
245 /* Calculate the Access Address for the BIS event */
246 util_bis_aa_le32(lll->bis_curr, lll->seed_access_addr, access_addr);
247 data_chan_id = lll_chan_id(access_addr);
248
249 /* Calculate the radio channel to use for ISO event and hence store the
250 * channel to be used for control subevent.
251 */
252 data_chan_use = lll_chan_iso_event(event_counter, data_chan_id,
253 lll->data_chan_map,
254 lll->data_chan_count,
255 &lll->data_chan_prn_s,
256 &lll->data_chan_remap_idx);
257 lll->ctrl_chan_use = data_chan_use;
258
259 /* Initialize stream current */
260 lll->stream_curr = 0U;
261
262 /* Skip subevents until first selected BIS */
263 stream_handle = lll->stream_handle[lll->stream_curr];
264 stream = ull_sync_iso_lll_stream_get(stream_handle);
265 if ((stream->bis_index != lll->bis_curr) &&
266 (stream->bis_index <= lll->num_bis)) {
267 /* First selected BIS */
268 lll->bis_curr = stream->bis_index;
269
270 /* Calculate the Access Address for the current BIS */
271 util_bis_aa_le32(lll->bis_curr, lll->seed_access_addr,
272 access_addr);
273 data_chan_id = lll_chan_id(access_addr);
274
275 /* Calculate the channel id for the next BIS subevent */
276 data_chan_use = lll_chan_iso_event(event_counter,
277 data_chan_id,
278 lll->data_chan_map,
279 lll->data_chan_count,
280 &lll->data_chan_prn_s,
281 &lll->data_chan_remap_idx);
282 }
283
284 /* Calculate the CRC init value for the BIS event,
285 * preset with the BaseCRCInit value from the BIGInfo data the most
286 * significant 2 octets and the BIS_Number for the specific BIS in the
287 * least significant octet.
288 */
289 crc_init[0] = lll->bis_curr;
290 (void)memcpy(&crc_init[1], lll->base_crc_init, sizeof(uint16_t));
291
292 /* Start setting up of Radio h/w */
293 radio_reset();
294
295 phy = lll->phy;
296 radio_phy_set(phy, PHY_FLAGS_S8);
297 radio_aa_set(access_addr);
298 radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(crc_init));
299 lll_chan_set(data_chan_use);
300
301 /* By design, there shall alway be one free node rx available for
302 * setting up radio for new PDU reception.
303 */
304 node_rx = ull_iso_pdu_rx_alloc_peek(1U);
305 LL_ASSERT(node_rx);
306
307 /* Encryption */
308 if (lll->enc) {
309 uint64_t payload_count;
310 uint8_t pkt_flags;
311
312 payload_count = lll->payload_count - lll->bn;
313 lll->ccm_rx.counter = payload_count;
314
315 (void)memcpy(lll->ccm_rx.iv, lll->giv, 4U);
316 mem_xor_32(lll->ccm_rx.iv, lll->ccm_rx.iv, access_addr);
317
318 pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS,
319 phy,
320 RADIO_PKT_CONF_CTE_DISABLED);
321 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
322 (lll->max_pdu + PDU_MIC_SIZE), pkt_flags);
323 radio_pkt_rx_set(radio_ccm_iso_rx_pkt_set(&lll->ccm_rx, phy,
324 RADIO_PKT_CONF_PDU_TYPE_BIS,
325 node_rx->pdu));
326 } else {
327 uint8_t pkt_flags;
328
329 pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS,
330 phy,
331 RADIO_PKT_CONF_CTE_DISABLED);
332 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, lll->max_pdu,
333 pkt_flags);
334 radio_pkt_rx_set(node_rx->pdu);
335 }
336
337 radio_switch_complete_and_disable();
338
339 ticks_at_event = p->ticks_at_expire;
340 ull = HDR_LLL2ULL(lll);
341 ticks_at_event += lll_event_offset_get(ull);
342
343 ticks_at_start = ticks_at_event;
344 ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
345
346 remainder = p->remainder;
347 remainder_us = radio_tmr_start(0U, ticks_at_start, remainder);
348
349 radio_tmr_ready_save(remainder_us);
350 radio_tmr_aa_save(0U);
351 radio_tmr_aa_capture();
352
353 hcto = remainder_us +
354 ((EVENT_JITTER_US + EVENT_TICKER_RES_MARGIN_US +
355 lll->window_widening_event_us) << 1) +
356 lll->window_size_event_us;
357 hcto += radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8);
358 hcto += addr_us_get(lll->phy);
359 hcto += radio_rx_chain_delay_get(lll->phy, PHY_FLAGS_S8);
360 radio_tmr_hcto_configure(hcto);
361
362 radio_tmr_end_capture();
363 radio_rssi_measure();
364
365 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
366 radio_gpio_lna_setup();
367
368 radio_gpio_pa_lna_enable(remainder_us +
369 radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8) -
370 HAL_RADIO_GPIO_LNA_OFFSET);
371 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
372
373 #if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
374 (EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
375 uint32_t overhead;
376
377 overhead = lll_preempt_calc(ull, (TICKER_ID_SCAN_SYNC_ISO_BASE +
378 ull_sync_iso_lll_handle_get(lll)), ticks_at_event);
379 /* check if preempt to start has changed */
380 if (overhead) {
381 LL_ASSERT_OVERHEAD(overhead);
382
383 radio_isr_set(lll_isr_abort, lll);
384 radio_disable();
385
386 return -ECANCELED;
387 }
388 #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
389
390 ret = lll_prepare_done(lll);
391 LL_ASSERT(!ret);
392
393 /* Calculate ahead the next subevent channel index */
394 next_chan_calc(lll, event_counter, data_chan_id);
395
396 return 0;
397 }
398
abort_cb(struct lll_prepare_param * prepare_param,void * param)399 static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
400 {
401 struct event_done_extra *e;
402 int err;
403
404 /* NOTE: This is not a prepare being cancelled */
405 if (!prepare_param) {
406 radio_isr_set(isr_done, param);
407 radio_disable();
408 return;
409 }
410
411 /* NOTE: Else clean the top half preparations of the aborted event
412 * currently in preparation pipeline.
413 */
414 err = lll_hfclock_off();
415 LL_ASSERT(err >= 0);
416
417 /* Extra done event, to check sync lost */
418 e = ull_event_done_extra_get();
419 LL_ASSERT(e);
420
421 e->type = EVENT_DONE_EXTRA_TYPE_SYNC_ISO;
422 e->trx_cnt = 0U;
423 e->crc_valid = 0U;
424
425 lll_done(param);
426 }
427
isr_rx_estab(void * param)428 static void isr_rx_estab(void *param)
429 {
430 struct event_done_extra *e;
431 uint8_t trx_done;
432 uint8_t crc_ok;
433
434 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
435 lll_prof_latency_capture();
436 }
437
438 /* Read radio status and events */
439 trx_done = radio_is_done();
440 if (trx_done) {
441 crc_ok = radio_crc_is_valid();
442 trx_cnt++;
443 } else {
444 crc_ok = 0U;
445 }
446
447 /* Clear radio rx status and events */
448 lll_isr_rx_status_reset();
449
450 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
451 lll_prof_cputime_capture();
452 }
453
454 /* Calculate and place the drift information in done event */
455 e = ull_event_done_extra_get();
456 LL_ASSERT(e);
457
458 e->type = EVENT_DONE_EXTRA_TYPE_SYNC_ISO_ESTAB;
459 e->trx_cnt = trx_cnt;
460 e->crc_valid = crc_ok;
461
462 if (trx_cnt) {
463 struct lll_sync_iso *lll;
464
465 lll = param;
466 e->drift.preamble_to_addr_us = addr_us_get(lll->phy);
467 e->drift.start_to_address_actual_us =
468 radio_tmr_aa_get() - radio_tmr_ready_get();
469 e->drift.window_widening_event_us =
470 lll->window_widening_event_us;
471
472 /* Reset window widening, as anchor point sync-ed */
473 lll->window_widening_event_us = 0U;
474 lll->window_size_event_us = 0U;
475 }
476
477 lll_isr_cleanup(param);
478
479 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
480 lll_prof_send();
481 }
482 }
483
isr_rx(void * param)484 static void isr_rx(void *param)
485 {
486 struct lll_sync_iso_stream *stream;
487 struct node_rx_pdu *node_rx;
488 struct lll_sync_iso *lll;
489 uint8_t access_addr[4];
490 uint16_t data_chan_id;
491 uint8_t data_chan_use;
492 uint8_t crc_init[3];
493 uint8_t rssi_ready;
494 uint32_t start_us;
495 uint8_t new_burst;
496 uint8_t trx_done;
497 uint8_t bis_idx;
498 uint8_t skipped;
499 uint8_t crc_ok;
500 uint32_t hcto;
501 uint8_t bis;
502 uint8_t nse;
503
504 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
505 lll_prof_latency_capture();
506 }
507
508 /* Read radio status and events */
509 trx_done = radio_is_done();
510 if (!trx_done) {
511 /* Clear radio rx status and events */
512 lll_isr_rx_status_reset();
513
514 /* initialize LLL context reference */
515 lll = param;
516
517 /* BIS index */
518 bis_idx = lll->bis_curr - 1U;
519
520 goto isr_rx_done;
521 }
522
523 crc_ok = radio_crc_is_valid();
524 rssi_ready = radio_rssi_is_ready();
525 trx_cnt++;
526
527 /* initialize LLL context reference */
528 lll = param;
529
530 /* Save the AA captured for the first anchor point sync */
531 if (!radio_tmr_aa_restore()) {
532 const struct lll_sync_iso_stream *sync_stream;
533 uint32_t se_offset_us;
534 uint8_t se;
535
536 crc_ok_anchor = crc_ok;
537
538 sync_stream = ull_sync_iso_lll_stream_get(lll->stream_handle[0]);
539 se = ((lll->bis_curr - sync_stream->bis_index) *
540 ((lll->bn * lll->irc) + lll->ptc)) +
541 ((lll->irc_curr - 1U) * lll->bn) + (lll->bn_curr - 1U) +
542 lll->ptc_curr + lll->ctrl;
543 se_offset_us = lll->sub_interval * se;
544 radio_tmr_aa_save(radio_tmr_aa_get() - se_offset_us);
545 radio_tmr_ready_save(radio_tmr_ready_get() - se_offset_us);
546 }
547
548 /* Clear radio rx status and events */
549 lll_isr_rx_status_reset();
550
551 /* BIS index */
552 bis_idx = lll->bis_curr - 1U;
553
554 /* Check CRC and generate ISO Data PDU */
555 if (crc_ok) {
556 struct lll_sync_iso_stream *sync_stream;
557 uint16_t stream_handle;
558 uint8_t payload_offset;
559 uint8_t payload_index;
560 struct pdu_bis *pdu;
561
562 /* Check if Control Subevent being received */
563 if ((lll->bn_curr == lll->bn) &&
564 (lll->irc_curr == lll->irc) &&
565 (lll->ptc_curr == lll->ptc) &&
566 (lll->bis_curr == lll->num_bis) &&
567 lll->ctrl) {
568 lll->cssn_curr = lll->cssn_next;
569
570 /* Check the dedicated Control PDU buffer */
571 pdu = radio_pkt_big_ctrl_get();
572 if (pdu->ll_id == PDU_BIS_LLID_CTRL) {
573 isr_rx_ctrl_recv(lll, pdu);
574 }
575
576 goto isr_rx_done;
577 } else {
578 /* Check if there are 2 free rx buffers, one will be
579 * consumed to receive the current PDU, and the other
580 * is to ensure a PDU can be setup for the radio DMA to
581 * receive in the next sub_interval/iso_interval.
582 */
583 node_rx = ull_iso_pdu_rx_alloc_peek(2U);
584 if (!node_rx) {
585 goto isr_rx_done;
586 }
587 }
588
589 pdu = (void *)node_rx->pdu;
590
591 /* Check for new control PDU in control subevent */
592 if (pdu->cstf && (pdu->cssn != lll->cssn_curr)) {
593 lll->cssn_next = pdu->cssn;
594 /* TODO: check same CSSN is used in every subevent */
595 }
596
597 /* Check payload buffer overflow */
598 payload_offset = (lll->bn_curr - 1U) +
599 (lll->ptc_curr * lll->pto);
600 if (payload_offset > lll->payload_count_max) {
601 goto isr_rx_done;
602 }
603
604 /* Calculate the payload index in the sliding window */
605 payload_index = lll->payload_tail + payload_offset;
606 if (payload_index >= lll->payload_count_max) {
607 payload_index -= lll->payload_count_max;
608 }
609
610 /* Get reference to stream context */
611 stream_handle = lll->stream_handle[lll->stream_curr];
612 sync_stream = ull_sync_iso_lll_stream_get(stream_handle);
613
614 /* Store the received PDU if selected stream and not already
615 * received (say in previous event as pre-transmitted PDU.
616 */
617 if ((lll->bis_curr == sync_stream->bis_index) && pdu->len &&
618 !lll->payload[bis_idx][payload_index]) {
619 uint16_t handle;
620
621 if (lll->enc) {
622 uint32_t mic_failure;
623 uint32_t done;
624
625 done = radio_ccm_is_done();
626 LL_ASSERT(done);
627
628 mic_failure = !radio_ccm_mic_is_valid();
629 LL_ASSERT(!mic_failure);
630 }
631
632 ull_iso_pdu_rx_alloc();
633
634 handle = LL_BIS_SYNC_HANDLE_FROM_IDX(stream_handle);
635 isr_rx_iso_data_valid(lll, handle, node_rx);
636
637 lll->payload[bis_idx][payload_index] = node_rx;
638 }
639 }
640
641 isr_rx_done:
642 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
643 lll_prof_cputime_capture();
644 }
645
646 new_burst = 0U;
647 skipped = 0U;
648
649 isr_rx_find_subevent:
650 /* FIXME: Sequential or Interleaved BIS subevents decision */
651 /* NOTE: below code is for Sequential Rx only */
652
653 /* Find the next (bn_curr)th subevent to receive PDU */
654 while (lll->bn_curr < lll->bn) {
655 uint8_t payload_offset;
656 uint8_t payload_index;
657
658 /* Next burst number to check for reception required */
659 lll->bn_curr++;
660
661 /* Check payload buffer overflow */
662 payload_offset = (lll->bn_curr - 1U);
663 if (payload_offset > lll->payload_count_max) {
664 /* (bn_curr)th Rx PDU skip subevent */
665 skipped++;
666
667 continue;
668 }
669
670 /* Find the index of the (bn_curr)th Rx PDU buffer */
671 payload_index = lll->payload_tail + payload_offset;
672 if (payload_index >= lll->payload_count_max) {
673 payload_index -= lll->payload_count_max;
674 }
675
676 /* Check if (bn_curr)th Rx PDU has been received */
677 if (!lll->payload[bis_idx][payload_index]) {
678 /* Receive the (bn_curr)th Rx PDU of bis_curr */
679 bis = lll->bis_curr;
680
681 goto isr_rx_next_subevent;
682 }
683
684 /* (bn_curr)th Rx PDU already received, skip subevent */
685 skipped++;
686 }
687
688 /* Find the next repetition (irc_curr)th subevent to receive PDU */
689 if (lll->irc_curr < lll->irc) {
690 if (!new_burst) {
691 uint8_t payload_index;
692
693 /* Increment to next repetition count and be at first
694 * burst count for it.
695 */
696 lll->bn_curr = 1U;
697 lll->irc_curr++;
698
699 /* Find the index of the (irc_curr)th bn = 1 Rx PDU
700 * buffer.
701 */
702 payload_index = lll->payload_tail;
703
704 /* Check if (irc_curr)th bn = 1 Rx PDU has been
705 * received.
706 */
707 if (!lll->payload[bis_idx][payload_index]) {
708 /* Receive the (irc_curr)th bn = 1 Rx PDU of
709 * bis_curr.
710 */
711 bis = lll->bis_curr;
712
713 goto isr_rx_next_subevent;
714 } else {
715 /* bn = 1 Rx PDU already received, skip
716 * subevent.
717 */
718 skipped++;
719
720 /* flag to skip successive repetitions if all
721 * bn PDUs have been received. i.e. the bn
722 * loop above did not find a PDU to be received.
723 */
724 new_burst = 1U;
725
726 /* Find the missing (bn_curr)th Rx PDU of
727 * bis_curr
728 */
729 goto isr_rx_find_subevent;
730 }
731 } else {
732 /* Skip all successive repetition reception as all
733 * bn PDUs have been received.
734 */
735 skipped += (lll->irc - lll->irc_curr) * lll->bn;
736 lll->irc_curr = lll->irc;
737 }
738 }
739
740 /* Next pre-transmission subevent */
741 if (lll->ptc_curr < lll->ptc) {
742 lll->ptc_curr++;
743
744 /* TODO: optimize to skip pre-transmission subevent in case
745 * of insufficient buffers in sliding window.
746 */
747
748 /* Receive the (ptc_curr)th Rx PDU of bis_curr */
749 bis = lll->bis_curr;
750
751 goto isr_rx_next_subevent;
752 }
753
754 /* Next BIS */
755 if (lll->bis_curr < lll->num_bis) {
756 const uint8_t stream_curr = lll->stream_curr + 1U;
757 struct lll_sync_iso_stream *sync_stream;
758 uint16_t stream_handle;
759
760 /* Next selected stream */
761 if (stream_curr < lll->stream_count) {
762 lll->stream_curr = stream_curr;
763 stream_handle = lll->stream_handle[lll->stream_curr];
764 sync_stream = ull_sync_iso_lll_stream_get(stream_handle);
765 if (sync_stream->bis_index <= lll->num_bis) {
766 uint8_t payload_index;
767 uint8_t bis_idx_new;
768
769 lll->bis_curr = sync_stream->bis_index;
770 lll->ptc_curr = 0U;
771 lll->irc_curr = 1U;
772 lll->bn_curr = 1U;
773
774 /* new BIS index */
775 bis_idx_new = lll->bis_curr - 1U;
776
777 /* Find the index of the (irc_curr)th bn = 1 Rx
778 * PDU buffer.
779 */
780 payload_index = lll->payload_tail;
781
782 /* Check if (irc_curr)th bn = 1 Rx PDU has been
783 * received.
784 */
785 if (!lll->payload[bis_idx_new][payload_index]) {
786 /* bn = 1 Rx PDU not received */
787 skipped = (bis_idx_new - bis_idx - 1U) *
788 ((lll->bn * lll->irc) +
789 lll->ptc);
790
791 /* Receive the (irc_curr)th bn = 1 Rx
792 * PDU of bis_curr.
793 */
794 bis = lll->bis_curr;
795
796 goto isr_rx_next_subevent;
797 } else {
798 /* bn = 1 Rx PDU already received, skip
799 * subevent.
800 */
801 skipped = ((bis_idx_new - bis_idx -
802 1U) *
803 ((lll->bn * lll->irc) +
804 lll->ptc)) + 1U;
805
806 /* Find the missing (bn_curr)th Rx PDU
807 * of bis_curr
808 */
809 goto isr_rx_find_subevent;
810 }
811 } else {
812 lll->bis_curr = lll->num_bis;
813 }
814 } else {
815 lll->bis_curr = lll->num_bis;
816 }
817 }
818
819 /* Control subevent */
820 if (!lll->ctrl && (lll->cssn_next != lll->cssn_curr)) {
821 uint8_t pkt_flags;
822
823 /* Receive the control PDU and close the BIG event
824 * there after.
825 */
826 lll->ctrl = 1U;
827
828 /* control subevent to use bis = 0 and se_n = 1 */
829 bis = 0U;
830
831 /* Configure Radio to receive Control PDU that can have greater
832 * PDU length than max_pdu length.
833 */
834 pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS,
835 lll->phy,
836 RADIO_PKT_CONF_CTE_DISABLED);
837 if (lll->enc) {
838 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
839 (sizeof(struct pdu_big_ctrl) + PDU_MIC_SIZE),
840 pkt_flags);
841 } else {
842 radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
843 sizeof(struct pdu_big_ctrl),
844 pkt_flags);
845 }
846
847 goto isr_rx_next_subevent;
848 }
849
850 isr_rx_done(param);
851
852 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
853 lll_prof_send();
854 }
855
856 return;
857
858 isr_rx_next_subevent:
859 /* Calculate the Access Address for the BIS event */
860 util_bis_aa_le32(bis, lll->seed_access_addr, access_addr);
861 data_chan_id = lll_chan_id(access_addr);
862
863 /* Calculate the CRC init value for the BIS event,
864 * preset with the BaseCRCInit value from the BIGInfo data the most
865 * significant 2 octets and the BIS_Number for the specific BIS in the
866 * least significant octet.
867 */
868 crc_init[0] = bis;
869 (void)memcpy(&crc_init[1], lll->base_crc_init, sizeof(uint16_t));
870
871 radio_aa_set(access_addr);
872 radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(crc_init));
873
874 /* Set the channel to use */
875 if (!bis) {
876 data_chan_use = lll->ctrl_chan_use;
877 } else if (!skipped) {
878 data_chan_use = lll->next_chan_use;
879 } else {
880 uint8_t bis_idx_new = lll->bis_curr - 1U;
881
882 /* Initialise to avoid compile error */
883 data_chan_use = 0U;
884
885 if (bis_idx != bis_idx_new) {
886 const uint16_t event_counter =
887 (lll->payload_count / lll->bn) - 1U;
888
889 /* Calculate the radio channel to use for next BIS */
890 data_chan_use = lll_chan_iso_event(event_counter,
891 data_chan_id,
892 lll->data_chan_map,
893 lll->data_chan_count,
894 &lll->data_chan_prn_s,
895 &lll->data_chan_remap_idx);
896
897 skipped -= (bis_idx_new - bis_idx - 1U) *
898 ((lll->bn * lll->irc) + lll->ptc);
899 }
900
901 while (skipped--) {
902 /* Calculate the radio channel to use for subevent */
903 data_chan_use = lll_chan_iso_subevent(data_chan_id,
904 lll->data_chan_map,
905 lll->data_chan_count,
906 &lll->data_chan_prn_s,
907 &lll->data_chan_remap_idx);
908 }
909 }
910
911 lll_chan_set(data_chan_use);
912
913 /* Encryption */
914 if (lll->enc) {
915 uint64_t payload_count;
916 struct pdu_bis *pdu;
917
918 payload_count = lll->payload_count - lll->bn;
919 if (bis) {
920 payload_count += (lll->bn_curr - 1U) +
921 (lll->ptc_curr * lll->pto);
922
923 /* By design, there shall alway be one free node rx
924 * available for setting up radio for new PDU reception.
925 */
926 node_rx = ull_iso_pdu_rx_alloc_peek(1U);
927 LL_ASSERT(node_rx);
928
929 pdu = (void *)node_rx->pdu;
930 } else {
931 /* Use the dedicated Control PDU buffer */
932 pdu = radio_pkt_big_ctrl_get();
933 }
934
935 lll->ccm_rx.counter = payload_count;
936
937 (void)memcpy(lll->ccm_rx.iv, lll->giv, 4U);
938 mem_xor_32(lll->ccm_rx.iv, lll->ccm_rx.iv, access_addr);
939
940 radio_pkt_rx_set(radio_ccm_iso_rx_pkt_set(&lll->ccm_rx, lll->phy,
941 RADIO_PKT_CONF_PDU_TYPE_BIS,
942 pdu));
943
944 } else {
945 struct pdu_bis *pdu;
946
947 if (bis) {
948 /* By design, there shall alway be one free node rx
949 * available for setting up radio for new PDU reception.
950 */
951 node_rx = ull_iso_pdu_rx_alloc_peek(1U);
952 LL_ASSERT(node_rx);
953
954 pdu = (void *)node_rx->pdu;
955 } else {
956 /* Use the dedicated Control PDU buffer */
957 pdu = radio_pkt_big_ctrl_get();
958 }
959
960 radio_pkt_rx_set(pdu);
961 }
962
963 radio_switch_complete_and_disable();
964
965 /* PDU Header Complete TimeOut, calculate the absolute timeout in
966 * microseconds by when a PDU header is to be received for each
967 * subevent.
968 */
969 stream = ull_sync_iso_lll_stream_get(lll->stream_handle[0]);
970 nse = ((lll->bis_curr - stream->bis_index) *
971 ((lll->bn * lll->irc) + lll->ptc)) +
972 ((lll->irc_curr - 1U) * lll->bn) + (lll->bn_curr - 1U) +
973 lll->ptc_curr + lll->ctrl;
974 hcto = lll->sub_interval * nse;
975
976 if (trx_cnt) {
977 /* Setup radio packet timer header complete timeout for
978 * subsequent subevent PDU.
979 */
980
981 /* Calculate the radio start with consideration of the drift
982 * based on the access address capture timestamp.
983 * Listen early considering +/- 2 us active clock jitter, i.e.
984 * listen early by 4 us.
985 */
986 hcto += radio_tmr_aa_restore();
987 hcto -= radio_rx_chain_delay_get(lll->phy, PHY_FLAGS_S8);
988 hcto -= addr_us_get(lll->phy);
989 hcto -= radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8);
990 hcto -= (EVENT_CLOCK_JITTER_US << 1);
991
992 start_us = hcto;
993 hcto = radio_tmr_start_us(0U, start_us);
994 /* FIXME: Assertion check disabled until investigation as to
995 * why there is high ISR latency causing assertion here.
996 */
997 /* LL_ASSERT(hcto == (start_us + 1U)); */
998
999 /* Add 4 us + 4 us + (4 us * subevents so far), as radio
1000 * was setup to listen 4 us early and subevents could have
1001 * a 4 us drift each until the current subevent we are
1002 * listening.
1003 */
1004 hcto += ((EVENT_CLOCK_JITTER_US << 1) * (2U + nse)) +
1005 RANGE_DELAY_US + HCTO_START_DELAY_US;
1006 } else {
1007 /* First subevent PDU was not received, hence setup radio packet
1008 * timer header complete timeout from where the first subevent
1009 * PDU which is the BIG event anchor point would have been
1010 * received.
1011 */
1012 hcto += radio_tmr_ready_restore();
1013
1014 start_us = hcto;
1015 hcto = radio_tmr_start_us(0U, start_us);
1016 LL_ASSERT(hcto == (start_us + 1U));
1017
1018 hcto += ((EVENT_JITTER_US + EVENT_TICKER_RES_MARGIN_US +
1019 lll->window_widening_event_us) << 1) +
1020 lll->window_size_event_us;
1021 }
1022
1023 /* header complete timeout to consider the radio ready delay, chain
1024 * delay and access address duration.
1025 */
1026 hcto += radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8);
1027 hcto += addr_us_get(lll->phy);
1028 hcto += radio_rx_chain_delay_get(lll->phy, PHY_FLAGS_S8);
1029
1030 /* setup absolute PDU header reception timeout */
1031 radio_tmr_hcto_configure(hcto);
1032
1033 /* setup capture of PDU end timestamp */
1034 radio_tmr_end_capture();
1035
1036 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
1037 radio_gpio_lna_setup();
1038
1039 radio_gpio_pa_lna_enable(start_us +
1040 radio_rx_ready_delay_get(lll->phy,
1041 PHY_FLAGS_S8) -
1042 HAL_RADIO_GPIO_LNA_OFFSET);
1043 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
1044
1045 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1046 lll_prof_cputime_capture();
1047 }
1048
1049 /* Calculate ahead the next subevent channel index */
1050 const uint16_t event_counter = (lll->payload_count / lll->bn) - 1U;
1051
1052 next_chan_calc(lll, event_counter, data_chan_id);
1053
1054 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1055 lll_prof_send();
1056 }
1057 }
1058
isr_rx_done(void * param)1059 static void isr_rx_done(void *param)
1060 {
1061 struct node_rx_pdu *node_rx;
1062 struct event_done_extra *e;
1063 struct lll_sync_iso *lll;
1064 uint8_t payload_index;
1065 uint8_t bis_idx;
1066 uint8_t bn;
1067
1068 /* Enqueue PDUs to ULL */
1069 node_rx = NULL;
1070 lll = param;
1071 lll->stream_curr = 0U;
1072 payload_index = lll->payload_tail;
1073 for (bis_idx = 0U; bis_idx < lll->num_bis; bis_idx++) {
1074 struct lll_sync_iso_stream *stream;
1075 uint8_t payload_tail;
1076 uint8_t stream_curr;
1077 uint16_t stream_handle;
1078
1079 stream_handle = lll->stream_handle[lll->stream_curr];
1080 stream = ull_sync_iso_lll_stream_get(stream_handle);
1081 /* Skip BIS indices not synchronized. bis_index is 0x01 to 0x1F,
1082 * where as bis_idx is 0 indexed.
1083 */
1084 if ((bis_idx + 1U) != stream->bis_index) {
1085 continue;
1086 }
1087
1088 payload_tail = lll->payload_tail;
1089 bn = lll->bn;
1090 while (bn--) {
1091 if (lll->payload[bis_idx][payload_tail]) {
1092 node_rx = lll->payload[bis_idx][payload_tail];
1093 lll->payload[bis_idx][payload_tail] = NULL;
1094
1095 iso_rx_put(node_rx->hdr.link, node_rx);
1096 } else {
1097 /* Check if there are 2 free rx buffers, one
1098 * will be consumed to generate PDU with invalid
1099 * status, and the other is to ensure a PDU can
1100 * be setup for the radio DMA to receive in the
1101 * next sub_interval/iso_interval.
1102 */
1103 node_rx = ull_iso_pdu_rx_alloc_peek(2U);
1104 if (node_rx) {
1105 struct pdu_bis *pdu;
1106 uint16_t handle;
1107
1108 ull_iso_pdu_rx_alloc();
1109
1110 pdu = (void *)node_rx->pdu;
1111 pdu->ll_id = PDU_BIS_LLID_COMPLETE_END;
1112 pdu->len = 0U;
1113
1114 handle = LL_BIS_SYNC_HANDLE_FROM_IDX(stream_handle);
1115 isr_rx_iso_data_invalid(lll, bn, handle,
1116 node_rx);
1117
1118 iso_rx_put(node_rx->hdr.link, node_rx);
1119 }
1120 }
1121
1122 payload_index = payload_tail + 1U;
1123 if (payload_index >= lll->payload_count_max) {
1124 payload_index = 0U;
1125 }
1126 payload_tail = payload_index;
1127 }
1128
1129 stream_curr = lll->stream_curr + 1U;
1130 if (stream_curr < lll->stream_count) {
1131 lll->stream_curr = stream_curr;
1132 }
1133 }
1134 lll->payload_tail = payload_index;
1135
1136 #if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL)
1137 if (node_rx) {
1138 iso_rx_sched();
1139 }
1140 #endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */
1141
1142 e = ull_event_done_extra_get();
1143 LL_ASSERT(e);
1144
1145 /* Check if BIG terminate procedure received */
1146 if (lll->term_reason) {
1147 e->type = EVENT_DONE_EXTRA_TYPE_SYNC_ISO_TERMINATE;
1148
1149 goto isr_done_cleanup;
1150
1151 /* Check if BIG Channel Map Update */
1152 } else if (lll->chm_chan_count) {
1153 const uint16_t event_counter = lll->payload_count / lll->bn;
1154
1155 /* Bluetooth Core Specification v5.3 Vol 6, Part B,
1156 * Section 5.5.2 BIG Control Procedures
1157 *
1158 * When a Synchronized Receiver receives such a PDU where
1159 * (instant - bigEventCounter) mod 65536 is greater than or
1160 * equal to 32767 (because the instant is in the past), the
1161 * the Link Layer may stop synchronization with the BIG.
1162 */
1163
1164 /* Note: We are not validating whether the control PDU was
1165 * received after the instant but apply the new channel map.
1166 * If the channel map was new at or after the instant and the
1167 * the channel at the event counter did not match then the
1168 * control PDU would not have been received.
1169 */
1170 if (((event_counter - lll->ctrl_instant) & 0xFFFF) <= 0x7FFF) {
1171 (void)memcpy(lll->data_chan_map, lll->chm_chan_map,
1172 sizeof(lll->data_chan_map));
1173 lll->data_chan_count = lll->chm_chan_count;
1174 lll->chm_chan_count = 0U;
1175 }
1176 }
1177
1178 /* Calculate and place the drift information in done event */
1179 e->type = EVENT_DONE_EXTRA_TYPE_SYNC_ISO;
1180 e->trx_cnt = trx_cnt;
1181 e->crc_valid = crc_ok_anchor;
1182
1183 if (trx_cnt) {
1184 e->drift.preamble_to_addr_us = addr_us_get(lll->phy);
1185 e->drift.start_to_address_actual_us =
1186 radio_tmr_aa_restore() - radio_tmr_ready_restore();
1187 e->drift.window_widening_event_us =
1188 lll->window_widening_event_us;
1189
1190 /* Reset window widening, as anchor point sync-ed */
1191 lll->window_widening_event_us = 0U;
1192 lll->window_size_event_us = 0U;
1193 }
1194
1195 isr_done_cleanup:
1196 lll_isr_cleanup(param);
1197 }
1198
isr_done(void * param)1199 static void isr_done(void *param)
1200 {
1201 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1202 lll_prof_latency_capture();
1203 }
1204
1205 lll_isr_status_reset();
1206
1207 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1208 lll_prof_cputime_capture();
1209 }
1210
1211 isr_rx_done(param);
1212
1213 if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
1214 lll_prof_send();
1215 }
1216 }
1217
next_chan_calc(struct lll_sync_iso * lll,uint16_t event_counter,uint16_t data_chan_id)1218 static void next_chan_calc(struct lll_sync_iso *lll, uint16_t event_counter,
1219 uint16_t data_chan_id)
1220 {
1221 /* Calculate ahead the next subevent channel index */
1222 if ((lll->bn_curr < lll->bn) ||
1223 (lll->irc_curr < lll->irc) ||
1224 (lll->ptc_curr < lll->ptc)) {
1225 /* Calculate the radio channel to use for next subevent */
1226 lll->next_chan_use = lll_chan_iso_subevent(data_chan_id,
1227 lll->data_chan_map,
1228 lll->data_chan_count,
1229 &lll->data_chan_prn_s,
1230 &lll->data_chan_remap_idx);
1231 } else if (lll->bis_curr < lll->num_bis) {
1232 uint8_t access_addr[4];
1233
1234 /* Calculate the Access Address for the next BIS subevent */
1235 util_bis_aa_le32((lll->bis_curr + 1U), lll->seed_access_addr,
1236 access_addr);
1237 data_chan_id = lll_chan_id(access_addr);
1238
1239 /* Calculate the radio channel to use for next BIS */
1240 lll->next_chan_use = lll_chan_iso_event(event_counter,
1241 data_chan_id,
1242 lll->data_chan_map,
1243 lll->data_chan_count,
1244 &lll->data_chan_prn_s,
1245 &lll->data_chan_remap_idx);
1246 }
1247 }
1248
isr_rx_iso_data_valid(const struct lll_sync_iso * const lll,uint16_t handle,struct node_rx_pdu * node_rx)1249 static void isr_rx_iso_data_valid(const struct lll_sync_iso *const lll,
1250 uint16_t handle, struct node_rx_pdu *node_rx)
1251 {
1252 struct lll_sync_iso_stream *stream;
1253 struct node_rx_iso_meta *iso_meta;
1254
1255 node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU;
1256 node_rx->hdr.handle = handle;
1257
1258 iso_meta = &node_rx->hdr.rx_iso_meta;
1259 iso_meta->payload_number = lll->payload_count + (lll->bn_curr - 1U) +
1260 (lll->ptc_curr * lll->pto) - lll->bn;
1261
1262 stream = ull_sync_iso_lll_stream_get(lll->stream_handle[0]);
1263 iso_meta->timestamp = HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) +
1264 radio_tmr_aa_restore() +
1265 (DIV_ROUND_UP(lll->ptc_curr, lll->bn) *
1266 lll->pto * lll->iso_interval *
1267 PERIODIC_INT_UNIT_US) -
1268 addr_us_get(lll->phy) -
1269 ((stream->bis_index - 1U) *
1270 lll->sub_interval * ((lll->irc * lll->bn) +
1271 lll->ptc));
1272 iso_meta->timestamp %=
1273 HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U));
1274 iso_meta->status = 0U;
1275 }
1276
isr_rx_iso_data_invalid(const struct lll_sync_iso * const lll,uint8_t bn,uint16_t handle,struct node_rx_pdu * node_rx)1277 static void isr_rx_iso_data_invalid(const struct lll_sync_iso *const lll,
1278 uint8_t bn, uint16_t handle,
1279 struct node_rx_pdu *node_rx)
1280 {
1281 struct lll_sync_iso_stream *stream;
1282 struct node_rx_iso_meta *iso_meta;
1283
1284 node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU;
1285 node_rx->hdr.handle = handle;
1286
1287 iso_meta = &node_rx->hdr.rx_iso_meta;
1288 iso_meta->payload_number = lll->payload_count - bn - 1U;
1289
1290 stream = ull_sync_iso_lll_stream_get(lll->stream_handle[0]);
1291 iso_meta->timestamp = HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) +
1292 radio_tmr_aa_restore() - addr_us_get(lll->phy) -
1293 ((stream->bis_index - 1U) *
1294 lll->sub_interval * ((lll->irc * lll->bn) +
1295 lll->ptc));
1296 iso_meta->timestamp %=
1297 HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U));
1298 iso_meta->status = 1U;
1299 }
1300
isr_rx_ctrl_recv(struct lll_sync_iso * lll,struct pdu_bis * pdu)1301 static void isr_rx_ctrl_recv(struct lll_sync_iso *lll, struct pdu_bis *pdu)
1302 {
1303 const uint8_t opcode = pdu->ctrl.opcode;
1304
1305 if (opcode == PDU_BIG_CTRL_TYPE_TERM_IND) {
1306 if (!lll->term_reason) {
1307 struct pdu_big_ctrl_term_ind *term;
1308
1309 term = (void *)&pdu->ctrl.term_ind;
1310 lll->term_reason = term->reason;
1311 lll->ctrl_instant = term->instant;
1312 }
1313 } else if (opcode == PDU_BIG_CTRL_TYPE_CHAN_MAP_IND) {
1314 if (!lll->chm_chan_count) {
1315 struct pdu_big_ctrl_chan_map_ind *chm;
1316 uint8_t chan_count;
1317
1318 chm = (void *)&pdu->ctrl.chan_map_ind;
1319 chan_count =
1320 util_ones_count_get(chm->chm, sizeof(chm->chm));
1321 if (chan_count >= CHM_USED_COUNT_MIN) {
1322 lll->chm_chan_count = chan_count;
1323 (void)memcpy(lll->chm_chan_map, chm->chm,
1324 sizeof(lll->chm_chan_map));
1325 lll->ctrl_instant = chm->instant;
1326 }
1327 }
1328 } else {
1329 /* Unknown control PDU, ignore */
1330 }
1331 }
1332