1 /*
2  * Copyright (c) 2020 Demant
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <soc.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/sys/byteorder.h>
10 #include <zephyr/bluetooth/hci_types.h>
11 #include <zephyr/bluetooth/buf.h>
12 
13 #include "hal/cpu.h"
14 #include "hal/ccm.h"
15 #include "hal/ticker.h"
16 
17 #include "util/util.h"
18 #include "util/mem.h"
19 #include "util/memq.h"
20 #include "util/mfifo.h"
21 #include "util/mayfly.h"
22 #include "util/dbuf.h"
23 
24 #include "pdu_df.h"
25 #include "lll/pdu_vendor.h"
26 #include "pdu.h"
27 
28 #include "lll.h"
29 #include "lll/lll_adv_types.h"
30 #include "lll_adv.h"
31 #include "lll/lll_adv_pdu.h"
32 #include "lll_adv_iso.h"
33 #include "lll/lll_df_types.h"
34 #include "lll_sync.h"
35 #include "lll_sync_iso.h"
36 #include "lll_conn.h"
37 #include "lll_conn_iso.h"
38 #include "lll_iso_tx.h"
39 
40 #include "ll_sw/ull_tx_queue.h"
41 
42 #include "isoal.h"
43 
44 #include "ull_adv_types.h"
45 #include "ull_sync_types.h"
46 #include "ull_conn_types.h"
47 #include "ull_iso_types.h"
48 #include "ull_conn_iso_types.h"
49 #include "ull_llcp.h"
50 
51 #include "ull_internal.h"
52 #include "ull_adv_internal.h"
53 #include "ull_conn_internal.h"
54 #include "ull_iso_internal.h"
55 #include "ull_sync_iso_internal.h"
56 #include "ull_conn_iso_internal.h"
57 
58 #include "ll_feat.h"
59 
60 #include "hal/debug.h"
61 
62 #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
63 #include <zephyr/logging/log.h>
64 LOG_MODULE_REGISTER(bt_ctlr_ull_iso);
65 
66 #if defined(CONFIG_BT_CTLR_CONN_ISO_STREAMS)
67 #define BT_CTLR_CONN_ISO_STREAMS CONFIG_BT_CTLR_CONN_ISO_STREAMS
68 #else /* !CONFIG_BT_CTLR_CONN_ISO_STREAMS */
69 #define BT_CTLR_CONN_ISO_STREAMS 0
70 #endif /* !CONFIG_BT_CTLR_CONN_ISO_STREAMS */
71 
72 #if defined(CONFIG_BT_CTLR_ADV_ISO_STREAM_COUNT)
73 #define BT_CTLR_ADV_ISO_STREAMS (CONFIG_BT_CTLR_ADV_ISO_STREAM_COUNT)
74 #else /* !CONFIG_BT_CTLR_ADV_ISO_STREAM_COUNT */
75 #define BT_CTLR_ADV_ISO_STREAMS 0
76 #endif /* CONFIG_BT_CTLR_ADV_ISO_STREAM_COUNT */
77 
78 #if defined(CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT)
79 #define BT_CTLR_SYNC_ISO_STREAMS (CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT)
80 #else /* !CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT */
81 #define BT_CTLR_SYNC_ISO_STREAMS 0
82 #endif /* CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT */
83 
84 static int init_reset(void);
85 
86 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
87 static isoal_status_t ll_iso_pdu_alloc(struct isoal_pdu_buffer *pdu_buffer);
88 static isoal_status_t ll_iso_pdu_write(struct isoal_pdu_buffer *pdu_buffer,
89 				       const size_t   offset,
90 				       const uint8_t *sdu_payload,
91 				       const size_t   consume_len);
92 static isoal_status_t ll_iso_pdu_emit(struct node_tx_iso *node_tx,
93 				      const uint16_t handle);
94 static isoal_status_t ll_iso_pdu_release(struct node_tx_iso *node_tx,
95 					 const uint16_t handle,
96 					 const isoal_status_t status);
97 #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
98 
99 /* Allocate data path pools for RX/TX directions for each stream */
100 #define BT_CTLR_ISO_STREAMS ((2 * (BT_CTLR_CONN_ISO_STREAMS)) + \
101 			     BT_CTLR_ADV_ISO_STREAMS + \
102 			     BT_CTLR_SYNC_ISO_STREAMS)
103 #if BT_CTLR_ISO_STREAMS
104 static struct ll_iso_datapath datapath_pool[BT_CTLR_ISO_STREAMS];
105 #endif /* BT_CTLR_ISO_STREAMS */
106 
107 static void *datapath_free;
108 
109 #if defined(CONFIG_BT_CTLR_SYNC_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
110 #define NODE_RX_HEADER_SIZE (offsetof(struct node_rx_pdu, pdu))
111 /* ISO LL conformance tests require a PDU size of maximum 251 bytes + header */
112 #define ISO_RX_BUFFER_SIZE (2 + 251)
113 
114 /* Declare the ISO rx node RXFIFO. This is a composite pool-backed MFIFO for
115  * rx_nodes. The declaration constructs the following data structures:
116  * - mfifo_iso_rx:    FIFO with pointers to PDU buffers
117  * - mem_iso_rx:      Backing data pool for PDU buffer elements
118  * - mem_link_iso_rx: Pool of memq_link_t elements
119  *
120  * One extra rx buffer is reserved for empty ISO PDU reception.
121  * Two extra links are reserved for use by the ll_iso_rx and ull_iso_rx memq.
122  */
123 static RXFIFO_DEFINE(iso_rx, ((NODE_RX_HEADER_SIZE) + (ISO_RX_BUFFER_SIZE)),
124 			     (CONFIG_BT_CTLR_ISO_RX_BUFFERS + 1U), 2U);
125 
126 static MEMQ_DECLARE(ll_iso_rx);
127 #if defined(CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH)
128 static MEMQ_DECLARE(ull_iso_rx);
129 static void iso_rx_demux(void *param);
130 #endif /* CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH */
131 #endif /* CONFIG_BT_CTLR_SYNC_ISO) || CONFIG_BT_CTLR_CONN_ISO */
132 
133 #define ISO_TEST_PACKET_COUNTER_SIZE 4U
134 
135 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
136 void ll_iso_link_tx_release(void *link);
137 void ll_iso_tx_mem_release(void *node_tx);
138 
139 #define NODE_TX_BUFFER_SIZE MROUND(offsetof(struct node_tx_iso, pdu) + \
140 				   offsetof(struct pdu_iso, payload) + \
141 				   MAX(LL_BIS_OCTETS_TX_MAX, \
142 				       LL_CIS_OCTETS_TX_MAX))
143 
144 #define ISO_TEST_TX_BUFFER_SIZE 32U
145 
146 static struct {
147 	void *free;
148 	uint8_t pool[NODE_TX_BUFFER_SIZE * BT_CTLR_ISO_TX_BUFFERS];
149 } mem_iso_tx;
150 
151 static struct {
152 	void *free;
153 	uint8_t pool[sizeof(memq_link_t) * BT_CTLR_ISO_TX_BUFFERS];
154 } mem_link_iso_tx;
155 
156 #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
157 
ll_read_iso_tx_sync(uint16_t handle,uint16_t * seq,uint32_t * timestamp,uint32_t * offset)158 uint8_t ll_read_iso_tx_sync(uint16_t handle, uint16_t *seq,
159 			    uint32_t *timestamp, uint32_t *offset)
160 {
161 	if (IS_CIS_HANDLE(handle)) {
162 		struct ll_iso_datapath *dp = NULL;
163 		struct ll_conn_iso_stream *cis;
164 
165 		cis = ll_conn_iso_stream_get(handle);
166 
167 		if (cis) {
168 			dp = cis->hdr.datapath_in;
169 		}
170 
171 		if (dp &&
172 			isoal_tx_get_sync_info(dp->source_hdl, seq,
173 					timestamp, offset) == ISOAL_STATUS_OK) {
174 			return BT_HCI_ERR_SUCCESS;
175 		}
176 
177 		return BT_HCI_ERR_CMD_DISALLOWED;
178 
179 	} else if (IS_ADV_ISO_HANDLE(handle)) {
180 		const struct lll_adv_iso_stream *adv_stream;
181 		uint16_t stream_handle;
182 
183 		stream_handle = LL_BIS_ADV_IDX_FROM_HANDLE(handle);
184 		adv_stream = ull_adv_iso_stream_get(stream_handle);
185 		if (!adv_stream || !adv_stream->dp ||
186 		    isoal_tx_get_sync_info(adv_stream->dp->source_hdl, seq,
187 					   timestamp, offset) != ISOAL_STATUS_OK) {
188 			return BT_HCI_ERR_CMD_DISALLOWED;
189 		}
190 
191 		return BT_HCI_ERR_SUCCESS;
192 
193 	} else if (IS_SYNC_ISO_HANDLE(handle)) {
194 		return BT_HCI_ERR_CMD_DISALLOWED;
195 	}
196 
197 	return BT_HCI_ERR_UNKNOWN_CONN_ID;
198 }
199 
path_is_vendor_specific(uint8_t path_id)200 static inline bool path_is_vendor_specific(uint8_t path_id)
201 {
202 	return (path_id >= BT_HCI_DATAPATH_ID_VS &&
203 		path_id <= BT_HCI_DATAPATH_ID_VS_END);
204 }
205 
ll_setup_iso_path(uint16_t handle,uint8_t path_dir,uint8_t path_id,uint8_t coding_format,uint16_t company_id,uint16_t vs_codec_id,uint32_t controller_delay,uint8_t codec_config_len,uint8_t * codec_config)206 uint8_t ll_setup_iso_path(uint16_t handle, uint8_t path_dir, uint8_t path_id,
207 			  uint8_t coding_format, uint16_t company_id,
208 			  uint16_t vs_codec_id, uint32_t controller_delay,
209 			  uint8_t codec_config_len, uint8_t *codec_config)
210 {
211 	struct lll_sync_iso_stream *sync_stream = NULL;
212 	struct lll_adv_iso_stream *adv_stream = NULL;
213 	struct ll_conn_iso_stream *cis = NULL;
214 	struct ll_iso_datapath *dp;
215 	uint32_t stream_sync_delay;
216 	uint32_t group_sync_delay;
217 	uint8_t flush_timeout;
218 	uint16_t iso_interval;
219 	uint32_t sdu_interval;
220 	uint8_t  burst_number;
221 	uint8_t max_octets;
222 	uint8_t framed;
223 	uint8_t role;
224 
225 	ARG_UNUSED(controller_delay);
226 	ARG_UNUSED(codec_config);
227 
228 	if (false) {
229 
230 #if defined(CONFIG_BT_CTLR_CONN_ISO)
231 	} else if (IS_CIS_HANDLE(handle)) {
232 		struct ll_conn_iso_group *cig;
233 		struct ll_conn *conn;
234 
235 		/* If the Host attempts to set a data path with a Connection
236 		 * Handle that does not exist or that is not for a CIS or a BIS,
237 		 * the Controller shall return the error code Unknown Connection
238 		 * Identifier (0x02)
239 		 */
240 		cis = ll_conn_iso_stream_get(handle);
241 		if (!cis || !cis->group) {
242 			/* CIS does not belong to a CIG */
243 			return BT_HCI_ERR_UNKNOWN_CONN_ID;
244 		}
245 
246 		conn = ll_connected_get(cis->lll.acl_handle);
247 		if (conn) {
248 			/* If we're still waiting for accept/response from
249 			 * host, path setup is premature and we must return
250 			 * disallowed status.
251 			 */
252 #if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
253 			const uint8_t cis_waiting = ull_cp_cc_awaiting_reply(conn);
254 
255 			if (cis_waiting) {
256 				return BT_HCI_ERR_CMD_DISALLOWED;
257 			}
258 #endif /* CONFIG_BT_CTLR_PERIPHERAL_ISO */
259 		}
260 
261 		if ((path_dir == BT_HCI_DATAPATH_DIR_HOST_TO_CTLR && cis->hdr.datapath_in) ||
262 		    (path_dir == BT_HCI_DATAPATH_DIR_CTLR_TO_HOST && cis->hdr.datapath_out)) {
263 			/* Data path has been set up, can only do setup once */
264 			return BT_HCI_ERR_CMD_DISALLOWED;
265 		}
266 
267 		cig = cis->group;
268 
269 		role = cig->lll.role;
270 		iso_interval = cig->iso_interval;
271 		group_sync_delay = cig->sync_delay;
272 		stream_sync_delay = cis->sync_delay;
273 		framed = cis->framed;
274 
275 		if (path_dir == BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) {
276 			/* Create sink for RX data path */
277 			burst_number  = cis->lll.rx.bn;
278 			flush_timeout = cis->lll.rx.ft;
279 			max_octets    = cis->lll.rx.max_pdu;
280 
281 			if (role) {
282 				/* peripheral */
283 				sdu_interval = cig->c_sdu_interval;
284 			} else {
285 				/* central */
286 				sdu_interval = cig->p_sdu_interval;
287 			}
288 		} else {
289 			/* path_dir == BT_HCI_DATAPATH_DIR_HOST_TO_CTLR */
290 			burst_number  = cis->lll.tx.bn;
291 			flush_timeout = cis->lll.tx.ft;
292 			max_octets    = cis->lll.tx.max_pdu;
293 
294 			if (role) {
295 				/* peripheral */
296 				sdu_interval = cig->p_sdu_interval;
297 			} else {
298 				/* central */
299 				sdu_interval = cig->c_sdu_interval;
300 			}
301 		}
302 #endif /* CONFIG_BT_CTLR_CONN_ISO */
303 
304 #if defined(CONFIG_BT_CTLR_ADV_ISO)
305 	} else if (IS_ADV_ISO_HANDLE(handle)) {
306 		struct ll_adv_iso_set *adv_iso;
307 		struct lll_adv_iso *lll_iso;
308 		uint16_t stream_handle;
309 
310 		stream_handle = LL_BIS_ADV_IDX_FROM_HANDLE(handle);
311 		adv_stream = ull_adv_iso_stream_get(stream_handle);
312 		if (!adv_stream || adv_stream->dp) {
313 			return BT_HCI_ERR_CMD_DISALLOWED;
314 		}
315 
316 		adv_iso = ull_adv_iso_by_stream_get(stream_handle);
317 		lll_iso = &adv_iso->lll;
318 
319 		role = ISOAL_ROLE_BROADCAST_SOURCE;
320 		iso_interval = lll_iso->iso_interval;
321 		sdu_interval = lll_iso->sdu_interval;
322 		burst_number = lll_iso->bn;
323 		flush_timeout = 0U; /* Not used for Broadcast ISO */
324 		group_sync_delay = ull_iso_big_sync_delay(lll_iso->num_bis, lll_iso->bis_spacing,
325 							  lll_iso->nse, lll_iso->sub_interval,
326 							  lll_iso->phy, lll_iso->max_pdu,
327 							  lll_iso->enc);
328 		stream_sync_delay = group_sync_delay - stream_handle * lll_iso->bis_spacing;
329 		framed = lll_iso->framing;
330 		max_octets = lll_iso->max_pdu;
331 #endif /* CONFIG_BT_CTLR_ADV_ISO */
332 
333 #if defined(CONFIG_BT_CTLR_SYNC_ISO)
334 	} else if (IS_SYNC_ISO_HANDLE(handle)) {
335 		struct ll_sync_iso_set *sync_iso;
336 		struct lll_sync_iso *lll_iso;
337 		uint16_t stream_handle;
338 
339 		stream_handle = LL_BIS_SYNC_IDX_FROM_HANDLE(handle);
340 		sync_stream = ull_sync_iso_stream_get(stream_handle);
341 		if (!sync_stream || sync_stream->dp) {
342 			return BT_HCI_ERR_CMD_DISALLOWED;
343 		}
344 
345 		sync_iso = ull_sync_iso_by_stream_get(stream_handle);
346 		lll_iso = &sync_iso->lll;
347 
348 		role = ISOAL_ROLE_BROADCAST_SINK;
349 		iso_interval = lll_iso->iso_interval;
350 		sdu_interval = lll_iso->sdu_interval;
351 		burst_number = lll_iso->bn;
352 
353 		group_sync_delay = ull_iso_big_sync_delay(lll_iso->num_bis, lll_iso->bis_spacing,
354 							  lll_iso->nse, lll_iso->sub_interval,
355 							  lll_iso->phy, lll_iso->max_pdu,
356 							  lll_iso->enc);
357 		stream_sync_delay = group_sync_delay - stream_handle * lll_iso->bis_spacing;
358 		framed = lll_iso->framing;
359 		max_octets = lll_iso->max_pdu;
360 		flush_timeout = 0U; /* Not used for Broadcast ISO */
361 #endif /* CONFIG_BT_CTLR_SYNC_ISO */
362 
363 	} else {
364 		return BT_HCI_ERR_UNKNOWN_CONN_ID;
365 	}
366 
367 	if (path_is_vendor_specific(path_id) &&
368 	    (!IS_ENABLED(CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH) ||
369 	     !ll_data_path_configured(path_dir, path_id))) {
370 		/* Data path must be configured prior to setup */
371 		return BT_HCI_ERR_CMD_DISALLOWED;
372 	}
373 
374 	/* If Codec_Configuration_Length non-zero and Codec_ID set to
375 	 * transparent air mode, the Controller shall return the error code
376 	 * Invalid HCI Command Parameters (0x12).
377 	 */
378 	if (codec_config_len &&
379 	    (vs_codec_id == BT_HCI_CODING_FORMAT_TRANSPARENT)) {
380 		return BT_HCI_ERR_INVALID_PARAM;
381 	}
382 
383 	/* Allocate and configure datapath */
384 	dp = mem_acquire(&datapath_free);
385 	if (!dp) {
386 		return BT_HCI_ERR_CMD_DISALLOWED;
387 	}
388 
389 	dp->path_dir = path_dir;
390 	dp->path_id = path_id;
391 	dp->coding_format = coding_format;
392 	dp->company_id = company_id;
393 
394 	/* TODO dp->sync_delay    = controller_delay; ?*/
395 
396 	if (false) {
397 
398 #if defined(CONFIG_BT_CTLR_SYNC_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
399 	} else if ((path_dir == BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) &&
400 		   (cis || sync_stream)) {
401 		isoal_sink_handle_t sink_handle;
402 		isoal_status_t err;
403 
404 		if (path_id == BT_HCI_DATAPATH_ID_HCI) {
405 			/* Not vendor specific, thus alloc and emit functions
406 			 * known
407 			 */
408 			err = isoal_sink_create(handle, role, framed,
409 						burst_number, flush_timeout,
410 						sdu_interval, iso_interval,
411 						stream_sync_delay,
412 						group_sync_delay,
413 						sink_sdu_alloc_hci,
414 						sink_sdu_emit_hci,
415 						sink_sdu_write_hci,
416 						&sink_handle);
417 		} else {
418 			/* Set up vendor specific data path */
419 			isoal_sink_sdu_alloc_cb sdu_alloc;
420 			isoal_sink_sdu_emit_cb  sdu_emit;
421 			isoal_sink_sdu_write_cb sdu_write;
422 
423 			/* Request vendor sink callbacks for path */
424 			if (IS_ENABLED(CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH) &&
425 			    ll_data_path_sink_create(handle, dp, &sdu_alloc,
426 						     &sdu_emit, &sdu_write)) {
427 				err = isoal_sink_create(handle, role, framed,
428 							burst_number,
429 							flush_timeout,
430 							sdu_interval,
431 							iso_interval,
432 							stream_sync_delay,
433 							group_sync_delay,
434 							sdu_alloc, sdu_emit,
435 							sdu_write,
436 							&sink_handle);
437 			} else {
438 				ull_iso_datapath_release(dp);
439 
440 				return BT_HCI_ERR_CMD_DISALLOWED;
441 			}
442 		}
443 
444 		if (!err) {
445 			if (cis) {
446 				cis->hdr.datapath_out = dp;
447 			}
448 
449 			if (sync_stream) {
450 				sync_stream->dp = dp;
451 			}
452 
453 			dp->sink_hdl = sink_handle;
454 			isoal_sink_enable(sink_handle);
455 		} else {
456 			ull_iso_datapath_release(dp);
457 
458 			return BT_HCI_ERR_CMD_DISALLOWED;
459 		}
460 #else /* !CONFIG_BT_CTLR_SYNC_ISO && !CONFIG_BT_CTLR_CONN_ISO */
461 		ARG_UNUSED(sync_stream);
462 #endif /* !CONFIG_BT_CTLR_SYNC_ISO && !CONFIG_BT_CTLR_CONN_ISO */
463 
464 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
465 	} else if ((path_dir == BT_HCI_DATAPATH_DIR_HOST_TO_CTLR) &&
466 		   (cis || adv_stream)) {
467 		isoal_source_handle_t source_handle;
468 		isoal_status_t err;
469 
470 		/* Create source for TX data path */
471 		isoal_source_pdu_alloc_cb   pdu_alloc;
472 		isoal_source_pdu_write_cb   pdu_write;
473 		isoal_source_pdu_emit_cb    pdu_emit;
474 		isoal_source_pdu_release_cb pdu_release;
475 
476 		if (path_is_vendor_specific(path_id)) {
477 			if (!IS_ENABLED(CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH) ||
478 			    !ll_data_path_source_create(handle, dp,
479 							&pdu_alloc, &pdu_write,
480 							&pdu_emit,
481 							&pdu_release)) {
482 				ull_iso_datapath_release(dp);
483 
484 				return BT_HCI_ERR_CMD_DISALLOWED;
485 			}
486 		} else {
487 			/* Set default callbacks when not vendor specific
488 			 * or that the vendor specific path is the same.
489 			 */
490 			pdu_alloc   = ll_iso_pdu_alloc;
491 			pdu_write   = ll_iso_pdu_write;
492 			pdu_emit    = ll_iso_pdu_emit;
493 			pdu_release = ll_iso_pdu_release;
494 		}
495 
496 		err = isoal_source_create(handle, role, framed, burst_number,
497 					  flush_timeout, max_octets,
498 					  sdu_interval, iso_interval,
499 					  stream_sync_delay, group_sync_delay,
500 					  pdu_alloc, pdu_write, pdu_emit,
501 					  pdu_release, &source_handle);
502 
503 		if (!err) {
504 			if (IS_ENABLED(CONFIG_BT_CTLR_CONN_ISO) && cis != NULL) {
505 				cis->hdr.datapath_in = dp;
506 			}
507 
508 			if (IS_ENABLED(CONFIG_BT_CTLR_ADV_ISO) && adv_stream != NULL) {
509 				adv_stream->dp = dp;
510 			}
511 
512 			dp->source_hdl = source_handle;
513 			isoal_source_enable(source_handle);
514 		} else {
515 			ull_iso_datapath_release(dp);
516 
517 			return BT_HCI_ERR_CMD_DISALLOWED;
518 		}
519 
520 #else /* !CONFIG_BT_CTLR_ADV_ISO && !CONFIG_BT_CTLR_CONN_ISO */
521 		ARG_UNUSED(adv_stream);
522 #endif /* !CONFIG_BT_CTLR_ADV_ISO && !CONFIG_BT_CTLR_CONN_ISO */
523 
524 	} else {
525 		return BT_HCI_ERR_CMD_DISALLOWED;
526 	}
527 
528 	return BT_HCI_ERR_SUCCESS;
529 }
530 
ll_remove_iso_path(uint16_t handle,uint8_t path_dir)531 uint8_t ll_remove_iso_path(uint16_t handle, uint8_t path_dir)
532 {
533 	/* If the Host issues this command with a Connection_Handle that does
534 	 * not exist or is not for a CIS or a BIS, the Controller shall return
535 	 * the error code Unknown Connection Identifier (0x02).
536 	 */
537 	if (false) {
538 
539 #if defined(CONFIG_BT_CTLR_CONN_ISO)
540 	} else if (IS_CIS_HANDLE(handle)) {
541 		struct ll_conn_iso_stream *cis;
542 		struct ll_iso_stream_hdr *hdr;
543 		struct ll_iso_datapath *dp;
544 
545 		cis = ll_conn_iso_stream_get(handle);
546 		hdr = &cis->hdr;
547 
548 		if (path_dir & BIT(BT_HCI_DATAPATH_DIR_HOST_TO_CTLR)) {
549 			dp = hdr->datapath_in;
550 			if (dp) {
551 				isoal_source_destroy(dp->source_hdl);
552 
553 				hdr->datapath_in = NULL;
554 				ull_iso_datapath_release(dp);
555 			} else {
556 				/* Datapath was not previously set up */
557 				return BT_HCI_ERR_CMD_DISALLOWED;
558 			}
559 		}
560 
561 		if (path_dir & BIT(BT_HCI_DATAPATH_DIR_CTLR_TO_HOST)) {
562 			dp = hdr->datapath_out;
563 			if (dp) {
564 				isoal_sink_destroy(dp->sink_hdl);
565 
566 				hdr->datapath_out = NULL;
567 				ull_iso_datapath_release(dp);
568 			} else {
569 				/* Datapath was not previously set up */
570 				return BT_HCI_ERR_CMD_DISALLOWED;
571 			}
572 		}
573 #endif /* CONFIG_BT_CTLR_CONN_ISO */
574 
575 #if defined(CONFIG_BT_CTLR_ADV_ISO)
576 	} else if (IS_ADV_ISO_HANDLE(handle)) {
577 		struct lll_adv_iso_stream *adv_stream;
578 		struct ll_iso_datapath *dp;
579 		uint16_t stream_handle;
580 
581 		if (!(path_dir & BIT(BT_HCI_DATAPATH_DIR_HOST_TO_CTLR))) {
582 			return BT_HCI_ERR_CMD_DISALLOWED;
583 		}
584 
585 		stream_handle = LL_BIS_ADV_IDX_FROM_HANDLE(handle);
586 		adv_stream = ull_adv_iso_stream_get(stream_handle);
587 		if (!adv_stream) {
588 			return BT_HCI_ERR_CMD_DISALLOWED;
589 		}
590 
591 		dp = adv_stream->dp;
592 		if (dp) {
593 			adv_stream->dp = NULL;
594 			isoal_source_destroy(dp->source_hdl);
595 			ull_iso_datapath_release(dp);
596 		} else {
597 			/* Datapath was not previously set up */
598 			return BT_HCI_ERR_CMD_DISALLOWED;
599 		}
600 #endif /* CONFIG_BT_CTLR_ADV_ISO */
601 
602 #if defined(CONFIG_BT_CTLR_SYNC_ISO)
603 	} else if (IS_SYNC_ISO_HANDLE(handle)) {
604 		struct lll_sync_iso_stream *sync_stream;
605 		struct ll_iso_datapath *dp;
606 		uint16_t stream_handle;
607 
608 		if (!(path_dir & BIT(BT_HCI_DATAPATH_DIR_CTLR_TO_HOST))) {
609 			return BT_HCI_ERR_CMD_DISALLOWED;
610 		}
611 
612 		stream_handle = LL_BIS_SYNC_IDX_FROM_HANDLE(handle);
613 		sync_stream = ull_sync_iso_stream_get(stream_handle);
614 		if (!sync_stream) {
615 			return BT_HCI_ERR_CMD_DISALLOWED;
616 		}
617 
618 		dp = sync_stream->dp;
619 		if (dp) {
620 			sync_stream->dp = NULL;
621 			isoal_sink_destroy(dp->sink_hdl);
622 			ull_iso_datapath_release(dp);
623 		} else {
624 			/* Datapath was not previously set up */
625 			return BT_HCI_ERR_CMD_DISALLOWED;
626 		}
627 #endif /* CONFIG_BT_CTLR_SYNC_ISO */
628 
629 	} else {
630 		return BT_HCI_ERR_CMD_DISALLOWED;
631 	}
632 
633 	return 0;
634 }
635 
636 #if defined(CONFIG_BT_CTLR_SYNC_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
637 /* The sdu_alloc function is called before combining PDUs into an SDU. Here we
638  * store the paylaod number associated with the first PDU, for unframed usecase.
639  */
ll_iso_test_sdu_alloc(const struct isoal_sink * sink_ctx,const struct isoal_pdu_rx * valid_pdu,struct isoal_sdu_buffer * sdu_buffer)640 static isoal_status_t ll_iso_test_sdu_alloc(const struct isoal_sink *sink_ctx,
641 					    const struct isoal_pdu_rx *valid_pdu,
642 					    struct isoal_sdu_buffer *sdu_buffer)
643 {
644 	uint16_t handle;
645 
646 	handle = sink_ctx->session.handle;
647 
648 	if (IS_CIS_HANDLE(handle)) {
649 		if (!sink_ctx->session.framed) {
650 			struct ll_conn_iso_stream *cis;
651 
652 			cis = ll_iso_stream_connected_get(sink_ctx->session.handle);
653 			LL_ASSERT(cis);
654 
655 			/* For unframed, SDU counter is the payload number */
656 			cis->hdr.test_mode.rx.sdu_counter =
657 				(uint32_t)valid_pdu->meta->payload_number;
658 		}
659 	} else if (IS_SYNC_ISO_HANDLE(handle)) {
660 		if (!sink_ctx->session.framed) {
661 			struct lll_sync_iso_stream *sync_stream;
662 			uint16_t stream_handle;
663 
664 			stream_handle = LL_BIS_SYNC_IDX_FROM_HANDLE(handle);
665 			sync_stream = ull_sync_iso_stream_get(stream_handle);
666 			LL_ASSERT(sync_stream);
667 
668 			sync_stream->test_mode->sdu_counter =
669 				(uint32_t)valid_pdu->meta->payload_number;
670 		}
671 	}
672 
673 	return sink_sdu_alloc_hci(sink_ctx, valid_pdu, sdu_buffer);
674 }
675 
676 /* The sdu_emit function is called whenever an SDU is combined and ready to be sent
677  * further in the data path. This injected implementation performs statistics on
678  * the SDU and then discards it.
679  */
ll_iso_test_sdu_emit(const struct isoal_sink * sink_ctx,const struct isoal_emitted_sdu_frag * sdu_frag,const struct isoal_emitted_sdu * sdu)680 static isoal_status_t ll_iso_test_sdu_emit(const struct isoal_sink             *sink_ctx,
681 					   const struct isoal_emitted_sdu_frag *sdu_frag,
682 					   const struct isoal_emitted_sdu      *sdu)
683 {
684 	struct ll_iso_rx_test_mode *test_mode_rx;
685 	isoal_sdu_len_t length;
686 	isoal_status_t status;
687 	struct net_buf *buf;
688 	uint32_t sdu_counter;
689 	uint16_t max_sdu;
690 	uint16_t handle;
691 	uint8_t framed;
692 
693 	handle = sink_ctx->session.handle;
694 	buf = (struct net_buf *)sdu_frag->sdu.contents.dbuf;
695 
696 	if (IS_CIS_HANDLE(handle)) {
697 		struct ll_conn_iso_stream *cis;
698 
699 		cis = ll_iso_stream_connected_get(sink_ctx->session.handle);
700 		LL_ASSERT(cis);
701 
702 		test_mode_rx = &cis->hdr.test_mode.rx;
703 		max_sdu = cis->c_max_sdu;
704 #if defined(CONFIG_BT_CTLR_SYNC_ISO)
705 	} else if (IS_SYNC_ISO_HANDLE(handle)) {
706 		struct lll_sync_iso_stream *sync_stream;
707 		struct ll_sync_iso_set *sync_iso;
708 		uint16_t stream_handle;
709 
710 		stream_handle = LL_BIS_SYNC_IDX_FROM_HANDLE(handle);
711 		sync_stream = ull_sync_iso_stream_get(stream_handle);
712 		LL_ASSERT(sync_stream);
713 
714 		sync_iso = ull_sync_iso_by_stream_get(stream_handle);
715 
716 		test_mode_rx = sync_stream->test_mode;
717 		max_sdu = sync_iso->lll.max_sdu;
718 #endif /* CONFIG_BT_CTLR_SYNC_ISO */
719 	} else {
720 		/* Handle is out of range */
721 		status = ISOAL_STATUS_ERR_SDU_EMIT;
722 		net_buf_unref(buf);
723 
724 		return status;
725 	}
726 
727 	length = sink_ctx->sdu_production.sdu_written;
728 	framed = sink_ctx->session.framed;
729 
730 	/* In BT_HCI_ISO_TEST_ZERO_SIZE_SDU mode, all SDUs must have length 0 and there is
731 	 * no sdu_counter field. In the other modes, the first 4 bytes must contain a
732 	 * packet counter, which is used as SDU counter. The sdu_counter is extracted
733 	 * regardless of mode as a sanity check, unless the length does not allow it.
734 	 */
735 	if (length >= ISO_TEST_PACKET_COUNTER_SIZE) {
736 		sdu_counter = sys_get_le32(buf->data);
737 	} else {
738 		sdu_counter = 0U;
739 	}
740 
741 	switch (sdu_frag->sdu.status) {
742 	case ISOAL_SDU_STATUS_VALID:
743 		if (framed && test_mode_rx->sdu_counter == 0U) {
744 			/* BT 5.3, Vol 6, Part B, section 7.2:
745 			 * When using framed PDUs the expected value of the SDU counter
746 			 * shall be initialized with the value of the SDU counter of the
747 			 * first valid received SDU.
748 			 */
749 			test_mode_rx->sdu_counter = sdu_counter;
750 		}
751 
752 		switch (test_mode_rx->payload_type) {
753 		case BT_HCI_ISO_TEST_ZERO_SIZE_SDU:
754 			if (length == 0) {
755 				test_mode_rx->received_cnt++;
756 			} else {
757 				test_mode_rx->failed_cnt++;
758 			}
759 			break;
760 
761 		case BT_HCI_ISO_TEST_VARIABLE_SIZE_SDU:
762 			if ((length >= ISO_TEST_PACKET_COUNTER_SIZE) &&
763 			    (length <= max_sdu) &&
764 			    (sdu_counter == test_mode_rx->sdu_counter)) {
765 				test_mode_rx->received_cnt++;
766 			} else {
767 				test_mode_rx->failed_cnt++;
768 			}
769 			break;
770 
771 		case BT_HCI_ISO_TEST_MAX_SIZE_SDU:
772 			if ((length == max_sdu) &&
773 			    (sdu_counter == test_mode_rx->sdu_counter)) {
774 				test_mode_rx->received_cnt++;
775 			} else {
776 				test_mode_rx->failed_cnt++;
777 			}
778 			break;
779 
780 		default:
781 			LL_ASSERT(0);
782 			return ISOAL_STATUS_ERR_SDU_EMIT;
783 		}
784 		break;
785 
786 	case ISOAL_SDU_STATUS_ERRORS:
787 	case ISOAL_SDU_STATUS_LOST_DATA:
788 		test_mode_rx->missed_cnt++;
789 		break;
790 	}
791 
792 	/* In framed mode, we may start incrementing the SDU counter when rx_sdu_counter
793 	 * becomes non zero (initial state), or in case of zero-based counting, if zero
794 	 * is actually the first valid SDU counter received.
795 	 */
796 	if (framed && (test_mode_rx->sdu_counter ||
797 			(sdu_frag->sdu.status == ISOAL_SDU_STATUS_VALID))) {
798 		test_mode_rx->sdu_counter++;
799 	}
800 
801 	status = ISOAL_STATUS_OK;
802 	net_buf_unref(buf);
803 
804 	return status;
805 }
806 
ll_iso_receive_test(uint16_t handle,uint8_t payload_type)807 uint8_t ll_iso_receive_test(uint16_t handle, uint8_t payload_type)
808 {
809 	struct ll_iso_rx_test_mode *test_mode_rx;
810 	isoal_sink_handle_t sink_handle;
811 	struct ll_iso_datapath *dp;
812 	uint32_t sdu_interval;
813 	isoal_status_t err;
814 
815 	struct ll_iso_datapath **stream_dp;
816 
817 	uint32_t stream_sync_delay;
818 	uint32_t group_sync_delay;
819 #if defined(CONFIG_BT_CTLR_SYNC_ISO)
820 	uint16_t stream_handle;
821 #endif /* CONFIG_BT_CTLR_SYNC_ISO */
822 	uint16_t iso_interval;
823 	uint8_t framed;
824 	uint8_t role;
825 	uint8_t ft;
826 	uint8_t bn;
827 
828 	if (IS_CIS_HANDLE(handle)) {
829 		struct ll_conn_iso_stream *cis;
830 		struct ll_conn_iso_group *cig;
831 
832 		cis = ll_iso_stream_connected_get(handle);
833 		if (!cis) {
834 			/* CIS is not connected */
835 			return BT_HCI_ERR_UNKNOWN_CONN_ID;
836 		}
837 
838 		if (cis->lll.rx.bn == 0) {
839 			/* CIS is not configured for RX */
840 			return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
841 		}
842 
843 		test_mode_rx = &cis->hdr.test_mode.rx;
844 		stream_dp = &cis->hdr.datapath_out;
845 		cig = cis->group;
846 
847 		if (cig->lll.role == BT_HCI_ROLE_PERIPHERAL) {
848 			/* peripheral */
849 			sdu_interval = cig->c_sdu_interval;
850 		} else {
851 			/* central */
852 			sdu_interval = cig->p_sdu_interval;
853 		}
854 
855 		role = cig->lll.role;
856 		framed = cis->framed;
857 		bn = cis->lll.rx.bn;
858 		ft = cis->lll.rx.ft;
859 		iso_interval = cig->iso_interval;
860 		stream_sync_delay = cis->sync_delay;
861 		group_sync_delay = cig->sync_delay;
862 #if defined(CONFIG_BT_CTLR_SYNC_ISO)
863 	} else if (IS_SYNC_ISO_HANDLE(handle)) {
864 		/* Get the sync stream from the handle */
865 		struct lll_sync_iso_stream *sync_stream;
866 		struct ll_sync_iso_set *sync_iso;
867 		struct lll_sync_iso *lll_iso;
868 
869 		stream_handle = LL_BIS_SYNC_IDX_FROM_HANDLE(handle);
870 		sync_stream = ull_sync_iso_stream_get(stream_handle);
871 		if (!sync_stream) {
872 			return BT_HCI_ERR_UNKNOWN_CONN_ID;
873 		}
874 
875 		if (sync_stream->dp) {
876 			/* Data path already set up */
877 			return BT_HCI_ERR_CMD_DISALLOWED;
878 		}
879 
880 		sync_iso = ull_sync_iso_by_stream_get(stream_handle);
881 		lll_iso = &sync_iso->lll;
882 
883 		test_mode_rx = sync_stream->test_mode;
884 		stream_dp = &sync_stream->dp;
885 
886 		/* BT Core v5.4 - Vol 6, Part B, Section 4.4.6.4:
887 		 * BIG_Sync_Delay = (Num_BIS – 1) × BIS_Spacing
888 		 *			+ (NSE – 1) × Sub_Interval + MPT.
889 		 */
890 		group_sync_delay = ull_iso_big_sync_delay(lll_iso->num_bis, lll_iso->bis_spacing,
891 							  lll_iso->nse, lll_iso->sub_interval,
892 							  lll_iso->phy, lll_iso->max_pdu,
893 							  lll_iso->enc);
894 		stream_sync_delay = group_sync_delay - stream_handle * lll_iso->bis_spacing;
895 
896 		role = ISOAL_ROLE_BROADCAST_SINK;
897 		framed = lll_iso->framing;
898 		bn = lll_iso->bn;
899 		ft = 0;
900 		sdu_interval = lll_iso->sdu_interval;
901 		iso_interval = lll_iso->iso_interval;
902 #endif /* CONFIG_BT_CTLR_SYNC_ISO */
903 	} else {
904 		/* Handle is out of range */
905 		return BT_HCI_ERR_UNKNOWN_CONN_ID;
906 	}
907 
908 	if (*stream_dp) {
909 		/* Data path already set up */
910 		return BT_HCI_ERR_CMD_DISALLOWED;
911 	}
912 
913 	if (payload_type > BT_HCI_ISO_TEST_MAX_SIZE_SDU) {
914 		return BT_HCI_ERR_INVALID_LL_PARAM;
915 	}
916 
917 	/* Allocate and configure test datapath */
918 	dp = mem_acquire(&datapath_free);
919 	if (!dp) {
920 		return BT_HCI_ERR_CMD_DISALLOWED;
921 	}
922 
923 	dp->path_dir = BT_HCI_DATAPATH_DIR_CTLR_TO_HOST;
924 	dp->path_id  = BT_HCI_DATAPATH_ID_HCI;
925 
926 	*stream_dp = dp;
927 	memset(test_mode_rx, 0, sizeof(struct ll_iso_rx_test_mode));
928 
929 	err = isoal_sink_create(handle, role, framed, bn, ft,
930 				sdu_interval, iso_interval,
931 				stream_sync_delay, group_sync_delay,
932 				ll_iso_test_sdu_alloc,
933 				ll_iso_test_sdu_emit,
934 				sink_sdu_write_hci, &sink_handle);
935 	if (err) {
936 		/* Error creating test source - cleanup source and
937 		 * datapath
938 		 */
939 		isoal_sink_destroy(sink_handle);
940 		ull_iso_datapath_release(dp);
941 		*stream_dp = NULL;
942 
943 		return BT_HCI_ERR_CMD_DISALLOWED;
944 	}
945 
946 	dp->sink_hdl = sink_handle;
947 	isoal_sink_enable(sink_handle);
948 
949 	/* Enable Receive Test Mode */
950 	test_mode_rx->enabled = 1;
951 	test_mode_rx->payload_type = payload_type;
952 
953 	return BT_HCI_ERR_SUCCESS;
954 }
955 
ll_iso_read_test_counters(uint16_t handle,uint32_t * received_cnt,uint32_t * missed_cnt,uint32_t * failed_cnt)956 uint8_t ll_iso_read_test_counters(uint16_t handle, uint32_t *received_cnt,
957 				  uint32_t *missed_cnt,
958 				  uint32_t *failed_cnt)
959 {
960 	struct ll_iso_rx_test_mode *test_mode_rx;
961 
962 	*received_cnt = 0U;
963 	*missed_cnt   = 0U;
964 	*failed_cnt   = 0U;
965 
966 	if (IS_CIS_HANDLE(handle)) {
967 		struct ll_conn_iso_stream *cis;
968 
969 		cis = ll_iso_stream_connected_get(handle);
970 		if (!cis) {
971 			/* CIS is not connected */
972 			return BT_HCI_ERR_UNKNOWN_CONN_ID;
973 		}
974 
975 		test_mode_rx = &cis->hdr.test_mode.rx;
976 
977 	} else if (IS_SYNC_ISO_HANDLE(handle)) {
978 		/* Get the sync stream from the handle */
979 		struct lll_sync_iso_stream *sync_stream;
980 		uint16_t stream_handle;
981 
982 		stream_handle = LL_BIS_SYNC_IDX_FROM_HANDLE(handle);
983 		sync_stream = ull_sync_iso_stream_get(stream_handle);
984 		if (!sync_stream) {
985 			return BT_HCI_ERR_UNKNOWN_CONN_ID;
986 		}
987 
988 		test_mode_rx = sync_stream->test_mode;
989 
990 	} else {
991 		/* Handle is out of range */
992 		return BT_HCI_ERR_UNKNOWN_CONN_ID;
993 	}
994 
995 	if (!test_mode_rx->enabled) {
996 		/* ISO receive Test is not active */
997 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
998 	}
999 
1000 	/* Return SDU statistics */
1001 	*received_cnt = test_mode_rx->received_cnt;
1002 	*missed_cnt   = test_mode_rx->missed_cnt;
1003 	*failed_cnt   = test_mode_rx->failed_cnt;
1004 
1005 	return BT_HCI_ERR_SUCCESS;
1006 }
1007 
1008 #if defined(CONFIG_BT_CTLR_READ_ISO_LINK_QUALITY)
ll_read_iso_link_quality(uint16_t handle,uint32_t * tx_unacked_packets,uint32_t * tx_flushed_packets,uint32_t * tx_last_subevent_packets,uint32_t * retransmitted_packets,uint32_t * crc_error_packets,uint32_t * rx_unreceived_packets,uint32_t * duplicate_packets)1009 uint8_t ll_read_iso_link_quality(uint16_t  handle,
1010 				 uint32_t *tx_unacked_packets,
1011 				 uint32_t *tx_flushed_packets,
1012 				 uint32_t *tx_last_subevent_packets,
1013 				 uint32_t *retransmitted_packets,
1014 				 uint32_t *crc_error_packets,
1015 				 uint32_t *rx_unreceived_packets,
1016 				 uint32_t *duplicate_packets)
1017 {
1018 	uint8_t status;
1019 
1020 	*tx_unacked_packets = 0;
1021 	*tx_flushed_packets = 0;
1022 	*tx_last_subevent_packets = 0;
1023 	*retransmitted_packets = 0;
1024 	*crc_error_packets = 0;
1025 	*rx_unreceived_packets = 0;
1026 	*duplicate_packets = 0;
1027 
1028 	status = BT_HCI_ERR_SUCCESS;
1029 
1030 	if (IS_CIS_HANDLE(handle)) {
1031 		struct ll_conn_iso_stream *cis;
1032 
1033 		cis = ll_iso_stream_connected_get(handle);
1034 
1035 		if (!cis) {
1036 			/* CIS is not connected */
1037 			return BT_HCI_ERR_UNKNOWN_CONN_ID;
1038 		}
1039 
1040 		*tx_unacked_packets       = cis->hdr.link_quality.tx_unacked_packets;
1041 		*tx_flushed_packets       = cis->hdr.link_quality.tx_flushed_packets;
1042 		*tx_last_subevent_packets = cis->hdr.link_quality.tx_last_subevent_packets;
1043 		*retransmitted_packets    = cis->hdr.link_quality.retransmitted_packets;
1044 		*crc_error_packets        = cis->hdr.link_quality.crc_error_packets;
1045 		*rx_unreceived_packets    = cis->hdr.link_quality.rx_unreceived_packets;
1046 		*duplicate_packets        = cis->hdr.link_quality.duplicate_packets;
1047 
1048 	} else if (IS_SYNC_ISO_HANDLE(handle)) {
1049 		/* FIXME: Implement for sync receiver */
1050 		status = BT_HCI_ERR_CMD_DISALLOWED;
1051 	} else {
1052 		/* Handle is out of range */
1053 		status = BT_HCI_ERR_UNKNOWN_CONN_ID;
1054 	}
1055 
1056 	return status;
1057 }
1058 #endif /* CONFIG_BT_CTLR_READ_ISO_LINK_QUALITY */
1059 
1060 #endif /* CONFIG_BT_CTLR_SYNC_ISO || CONFIG_BT_CTLR_CONN_ISO */
1061 
1062 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
ll_iso_test_pdu_release(struct node_tx_iso * node_tx,const uint16_t handle,const isoal_status_t status)1063 static isoal_status_t ll_iso_test_pdu_release(struct node_tx_iso *node_tx,
1064 					      const uint16_t handle,
1065 					      const isoal_status_t status)
1066 {
1067 	/* Release back to memory pool */
1068 	if (node_tx->link) {
1069 		ll_iso_link_tx_release(node_tx->link);
1070 	}
1071 	ll_iso_tx_mem_release(node_tx);
1072 
1073 	return ISOAL_STATUS_OK;
1074 }
1075 
1076 #if defined(CONFIG_BT_CTLR_CONN_ISO)
ll_iso_transmit_test_send_sdu(uint16_t handle,uint32_t ticks_at_expire)1077 void ll_iso_transmit_test_send_sdu(uint16_t handle, uint32_t ticks_at_expire)
1078 {
1079 	isoal_source_handle_t source_handle;
1080 	struct isoal_sdu_tx sdu;
1081 	isoal_status_t err;
1082 	uint8_t tx_buffer[ISO_TEST_TX_BUFFER_SIZE];
1083 	uint64_t next_payload_number;
1084 	uint16_t remaining_tx;
1085 	uint32_t sdu_counter;
1086 
1087 	if (IS_CIS_HANDLE(handle)) {
1088 		struct ll_conn_iso_stream *cis;
1089 		struct ll_conn_iso_group *cig;
1090 		uint32_t rand_max_sdu;
1091 		uint8_t event_offset;
1092 		uint8_t max_sdu;
1093 		uint8_t rand_8;
1094 
1095 		cis = ll_iso_stream_connected_get(handle);
1096 		LL_ASSERT(cis);
1097 
1098 		if (!cis->hdr.test_mode.tx.enabled) {
1099 			/* Transmit Test Mode not enabled */
1100 			return;
1101 		}
1102 
1103 		cig = cis->group;
1104 		source_handle = cis->hdr.datapath_in->source_hdl;
1105 
1106 		max_sdu = IS_PERIPHERAL(cig) ? cis->p_max_sdu : cis->c_max_sdu;
1107 
1108 		switch (cis->hdr.test_mode.tx.payload_type) {
1109 		case BT_HCI_ISO_TEST_ZERO_SIZE_SDU:
1110 			remaining_tx = 0;
1111 			break;
1112 
1113 		case BT_HCI_ISO_TEST_VARIABLE_SIZE_SDU:
1114 			/* Randomize the length [4..max_sdu] */
1115 			lll_rand_get(&rand_8, sizeof(rand_8));
1116 			rand_max_sdu = rand_8 * (max_sdu - ISO_TEST_PACKET_COUNTER_SIZE);
1117 			remaining_tx = ISO_TEST_PACKET_COUNTER_SIZE + (rand_max_sdu >> 8);
1118 			break;
1119 
1120 		case BT_HCI_ISO_TEST_MAX_SIZE_SDU:
1121 			LL_ASSERT(max_sdu > ISO_TEST_PACKET_COUNTER_SIZE);
1122 			remaining_tx = max_sdu;
1123 			break;
1124 
1125 		default:
1126 			LL_ASSERT(0);
1127 			return;
1128 		}
1129 
1130 		if (remaining_tx > ISO_TEST_TX_BUFFER_SIZE) {
1131 			sdu.sdu_state = BT_ISO_START;
1132 		} else {
1133 			sdu.sdu_state = BT_ISO_SINGLE;
1134 		}
1135 
1136 		/* Configure SDU similarly to one delivered via HCI */
1137 		sdu.packet_sn = 0;
1138 		sdu.dbuf = tx_buffer;
1139 
1140 		/* We must ensure sufficient time for ISO-AL to fragment SDU and
1141 		 * deliver PDUs to the TX queue. By checking ull_ref_get, we
1142 		 * know if we are within the subevents of an ISO event. If so,
1143 		 * we can assume that we have enough time to deliver in the next
1144 		 * ISO event. If we're not active within the ISO event, we don't
1145 		 * know if there is enough time to deliver in the next event,
1146 		 * and for safety we set the target to current event + 2.
1147 		 *
1148 		 * For FT > 1, we have the opportunity to retransmit in later
1149 		 * event(s), in which case we have the option to target an
1150 		 * earlier event (this or next) because being late does not
1151 		 * instantly flush the payload.
1152 		 */
1153 		event_offset = ull_ref_get(&cig->ull) ? 1 : 2;
1154 		if (cis->lll.tx.ft > 1) {
1155 			/* FT > 1, target an earlier event */
1156 			event_offset -= 1;
1157 		}
1158 
1159 		sdu.grp_ref_point = isoal_get_wrapped_time_us(cig->cig_ref_point,
1160 						(event_offset * cig->iso_interval *
1161 							ISO_INT_UNIT_US));
1162 		sdu.target_event = cis->lll.event_count + event_offset;
1163 		sdu.iso_sdu_length = remaining_tx;
1164 
1165 		/* Send all SDU fragments */
1166 		do {
1167 			sdu.cntr_time_stamp = HAL_TICKER_TICKS_TO_US(ticks_at_expire);
1168 			sdu.time_stamp = sdu.cntr_time_stamp;
1169 			sdu.size = MIN(remaining_tx, ISO_TEST_TX_BUFFER_SIZE);
1170 			memset(tx_buffer, 0, sdu.size);
1171 
1172 			/* If this is the first fragment of a framed SDU, inject the SDU
1173 			 * counter.
1174 			 */
1175 			if ((sdu.size >= ISO_TEST_PACKET_COUNTER_SIZE) &&
1176 			    ((sdu.sdu_state == BT_ISO_START) || (sdu.sdu_state == BT_ISO_SINGLE))) {
1177 				if (cis->framed) {
1178 					sdu_counter = (uint32_t)cis->hdr.test_mode.tx.sdu_counter;
1179 				} else {
1180 					/* Unframed. Get the next payload counter.
1181 					 *
1182 					 * BT 5.3, Vol 6, Part B, Section 7.1:
1183 					 * When using unframed PDUs, the SDU counter shall be equal
1184 					 * to the payload counter.
1185 					 */
1186 					isoal_tx_unframed_get_next_payload_number(source_handle,
1187 									&sdu,
1188 									&next_payload_number);
1189 					sdu_counter = (uint32_t)next_payload_number;
1190 				}
1191 
1192 				sys_put_le32(sdu_counter, tx_buffer);
1193 			}
1194 
1195 			/* Send to ISOAL */
1196 			err = isoal_tx_sdu_fragment(source_handle, &sdu);
1197 			LL_ASSERT(!err);
1198 
1199 			remaining_tx -= sdu.size;
1200 
1201 			if (remaining_tx > ISO_TEST_TX_BUFFER_SIZE) {
1202 				sdu.sdu_state = BT_ISO_CONT;
1203 			} else {
1204 				sdu.sdu_state = BT_ISO_END;
1205 			}
1206 		} while (remaining_tx);
1207 
1208 		cis->hdr.test_mode.tx.sdu_counter++;
1209 
1210 	} else if (IS_ADV_ISO_HANDLE(handle)) {
1211 		/* FIXME: Implement for broadcaster */
1212 	} else {
1213 		LL_ASSERT(0);
1214 	}
1215 }
1216 #endif /* CONFIG_BT_CTLR_CONN_ISO */
1217 
ll_iso_transmit_test(uint16_t handle,uint8_t payload_type)1218 uint8_t ll_iso_transmit_test(uint16_t handle, uint8_t payload_type)
1219 {
1220 	isoal_source_handle_t source_handle;
1221 	struct ll_iso_datapath *dp;
1222 	uint32_t sdu_interval;
1223 	isoal_status_t err;
1224 	uint8_t status;
1225 
1226 	status = BT_HCI_ERR_SUCCESS;
1227 
1228 	if (IS_CIS_HANDLE(handle)) {
1229 		struct ll_conn_iso_stream *cis;
1230 		struct ll_conn_iso_group *cig;
1231 
1232 		cis = ll_iso_stream_connected_get(handle);
1233 		if (!cis) {
1234 			/* CIS is not connected */
1235 			return BT_HCI_ERR_UNKNOWN_CONN_ID;
1236 		}
1237 
1238 		if (cis->lll.tx.bn == 0U) {
1239 			/* CIS is not configured for TX */
1240 			return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1241 		}
1242 
1243 		if (cis->hdr.datapath_in) {
1244 			/* Data path already set up */
1245 			return BT_HCI_ERR_CMD_DISALLOWED;
1246 		}
1247 
1248 		if (payload_type > BT_HCI_ISO_TEST_MAX_SIZE_SDU) {
1249 			return BT_HCI_ERR_INVALID_LL_PARAM;
1250 		}
1251 
1252 		/* Allocate and configure test datapath */
1253 		dp = mem_acquire(&datapath_free);
1254 		if (!dp) {
1255 			return BT_HCI_ERR_CMD_DISALLOWED;
1256 		}
1257 
1258 		dp->path_dir = BT_HCI_DATAPATH_DIR_HOST_TO_CTLR;
1259 		dp->path_id  = BT_HCI_DATAPATH_ID_HCI;
1260 
1261 		cis->hdr.datapath_in = dp;
1262 		cig = cis->group;
1263 
1264 		sdu_interval = IS_PERIPHERAL(cig) ? cig->p_sdu_interval : cig->c_sdu_interval;
1265 
1266 		/* Setup the test source */
1267 		err = isoal_source_create(handle, cig->lll.role, cis->framed,
1268 					  cis->lll.tx.bn, cis->lll.tx.ft,
1269 					  cis->lll.tx.max_pdu, sdu_interval,
1270 					  cig->iso_interval, cis->sync_delay,
1271 					  cig->sync_delay, ll_iso_pdu_alloc,
1272 					  ll_iso_pdu_write, ll_iso_pdu_emit,
1273 					  ll_iso_test_pdu_release,
1274 					  &source_handle);
1275 
1276 		if (err) {
1277 			/* Error creating test source - cleanup source and datapath */
1278 			isoal_source_destroy(source_handle);
1279 			ull_iso_datapath_release(dp);
1280 			cis->hdr.datapath_in = NULL;
1281 
1282 			return BT_HCI_ERR_CMD_DISALLOWED;
1283 		}
1284 
1285 		dp->source_hdl = source_handle;
1286 		isoal_source_enable(source_handle);
1287 
1288 		/* Enable Transmit Test Mode */
1289 		cis->hdr.test_mode.tx.enabled = 1;
1290 		cis->hdr.test_mode.tx.payload_type = payload_type;
1291 
1292 	} else if (IS_ADV_ISO_HANDLE(handle)) {
1293 		struct lll_adv_iso_stream *stream;
1294 		uint16_t stream_handle;
1295 
1296 		stream_handle = LL_BIS_ADV_IDX_FROM_HANDLE(handle);
1297 		stream = ull_adv_iso_stream_get(stream_handle);
1298 		if (!stream) {
1299 			return BT_HCI_ERR_UNKNOWN_CONN_ID;
1300 		}
1301 
1302 		/* FIXME: Implement use of common header in stream to enable code sharing
1303 		 * between CIS and BIS for test commands (and other places).
1304 		 */
1305 		status = BT_HCI_ERR_CMD_DISALLOWED;
1306 	} else {
1307 		/* Handle is out of range */
1308 		status = BT_HCI_ERR_UNKNOWN_CONN_ID;
1309 	}
1310 
1311 	return status;
1312 }
1313 #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
1314 
ll_iso_test_end(uint16_t handle,uint32_t * received_cnt,uint32_t * missed_cnt,uint32_t * failed_cnt)1315 uint8_t ll_iso_test_end(uint16_t handle, uint32_t *received_cnt,
1316 			uint32_t *missed_cnt, uint32_t *failed_cnt)
1317 {
1318 	*received_cnt = 0U;
1319 	*missed_cnt   = 0U;
1320 	*failed_cnt   = 0U;
1321 
1322 	if (IS_CIS_HANDLE(handle)) {
1323 		struct ll_conn_iso_stream *cis;
1324 
1325 		cis = ll_iso_stream_connected_get(handle);
1326 		if (!cis) {
1327 			/* CIS is not connected */
1328 			return BT_HCI_ERR_UNKNOWN_CONN_ID;
1329 		}
1330 
1331 		if (!cis->hdr.test_mode.rx.enabled && !cis->hdr.test_mode.tx.enabled) {
1332 			/* Test Mode is not active */
1333 			return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1334 		}
1335 
1336 		if (cis->hdr.test_mode.rx.enabled) {
1337 			isoal_sink_destroy(cis->hdr.datapath_out->sink_hdl);
1338 			ull_iso_datapath_release(cis->hdr.datapath_out);
1339 			cis->hdr.datapath_out = NULL;
1340 
1341 			/* Return SDU statistics */
1342 			*received_cnt = cis->hdr.test_mode.rx.received_cnt;
1343 			*missed_cnt   = cis->hdr.test_mode.rx.missed_cnt;
1344 			*failed_cnt   = cis->hdr.test_mode.rx.failed_cnt;
1345 		}
1346 
1347 		if (cis->hdr.test_mode.tx.enabled) {
1348 			/* Tear down source and datapath */
1349 			isoal_source_destroy(cis->hdr.datapath_in->source_hdl);
1350 			ull_iso_datapath_release(cis->hdr.datapath_in);
1351 			cis->hdr.datapath_in = NULL;
1352 		}
1353 
1354 		/* Disable Test Mode */
1355 		(void)memset(&cis->hdr.test_mode, 0U, sizeof(cis->hdr.test_mode));
1356 
1357 	} else if (IS_ADV_ISO_HANDLE(handle)) {
1358 		/* FIXME: Implement for broadcaster */
1359 		return BT_HCI_ERR_CMD_DISALLOWED;
1360 
1361 	} else if (IS_SYNC_ISO_HANDLE(handle)) {
1362 		struct lll_sync_iso_stream *sync_stream;
1363 		uint16_t stream_handle;
1364 
1365 		stream_handle = LL_BIS_SYNC_IDX_FROM_HANDLE(handle);
1366 		sync_stream = ull_sync_iso_stream_get(stream_handle);
1367 		if (!sync_stream) {
1368 			return BT_HCI_ERR_UNKNOWN_CONN_ID;
1369 		}
1370 
1371 		if (!sync_stream->test_mode->enabled || !sync_stream->dp) {
1372 			/* Test Mode is not active */
1373 			return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1374 		}
1375 
1376 		isoal_sink_destroy(sync_stream->dp->sink_hdl);
1377 		ull_iso_datapath_release(sync_stream->dp);
1378 		sync_stream->dp = NULL;
1379 
1380 		/* Return SDU statistics */
1381 		*received_cnt = sync_stream->test_mode->received_cnt;
1382 		*missed_cnt   = sync_stream->test_mode->missed_cnt;
1383 		*failed_cnt   = sync_stream->test_mode->failed_cnt;
1384 
1385 		(void)memset(&sync_stream->test_mode, 0U, sizeof(sync_stream->test_mode));
1386 
1387 	} else {
1388 		/* Handle is out of range */
1389 		return BT_HCI_ERR_UNKNOWN_CONN_ID;
1390 	}
1391 
1392 	return BT_HCI_ERR_SUCCESS;
1393 }
1394 
1395 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
ll_iso_tx_mem_acquire(void)1396 void *ll_iso_tx_mem_acquire(void)
1397 {
1398 	return mem_acquire(&mem_iso_tx.free);
1399 }
1400 
ll_iso_tx_mem_release(void * node_tx)1401 void ll_iso_tx_mem_release(void *node_tx)
1402 {
1403 	mem_release(node_tx, &mem_iso_tx.free);
1404 }
1405 
ll_iso_tx_mem_enqueue(uint16_t handle,void * node_tx,void * link)1406 int ll_iso_tx_mem_enqueue(uint16_t handle, void *node_tx, void *link)
1407 {
1408 	if (IS_ENABLED(CONFIG_BT_CTLR_CONN_ISO) &&
1409 	    IS_CIS_HANDLE(handle)) {
1410 		struct ll_conn_iso_stream *cis;
1411 
1412 		cis = ll_conn_iso_stream_get(handle);
1413 		memq_enqueue(link, node_tx, &cis->lll.memq_tx.tail);
1414 
1415 	} else if (IS_ENABLED(CONFIG_BT_CTLR_ADV_ISO) &&
1416 		   IS_ADV_ISO_HANDLE(handle)) {
1417 		struct lll_adv_iso_stream *stream;
1418 		uint16_t stream_handle;
1419 
1420 		stream_handle = LL_BIS_ADV_IDX_FROM_HANDLE(handle);
1421 		stream = ull_adv_iso_stream_get(stream_handle);
1422 		memq_enqueue(link, node_tx, &stream->memq_tx.tail);
1423 
1424 	} else {
1425 		return -EINVAL;
1426 	}
1427 
1428 	return 0;
1429 }
1430 #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
1431 
ull_iso_init(void)1432 int ull_iso_init(void)
1433 {
1434 	int err;
1435 
1436 	err = init_reset();
1437 	if (err) {
1438 		return err;
1439 	}
1440 
1441 	return 0;
1442 }
1443 
ull_iso_reset(void)1444 int ull_iso_reset(void)
1445 {
1446 	int err;
1447 
1448 	err = init_reset();
1449 	if (err) {
1450 		return err;
1451 	}
1452 
1453 	return 0;
1454 }
1455 
1456 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
ull_iso_lll_ack_enqueue(uint16_t handle,struct node_tx_iso * node_tx)1457 void ull_iso_lll_ack_enqueue(uint16_t handle, struct node_tx_iso *node_tx)
1458 {
1459 	struct ll_iso_datapath *dp = NULL;
1460 
1461 	if (IS_ENABLED(CONFIG_BT_CTLR_CONN_ISO) && IS_CIS_HANDLE(handle)) {
1462 		struct ll_conn_iso_stream *cis;
1463 
1464 		cis = ll_conn_iso_stream_get(handle);
1465 		dp  = cis->hdr.datapath_in;
1466 
1467 		if (dp) {
1468 			isoal_tx_pdu_release(dp->source_hdl, node_tx);
1469 		} else {
1470 			/* Race with Data Path remove */
1471 			/* FIXME: ll_tx_ack_put is not LLL callable as it is
1472 			 * used by ACL connections in ULL context to dispatch
1473 			 * ack.
1474 			 */
1475 			ll_tx_ack_put(handle, (void *)node_tx);
1476 			ll_rx_sched();
1477 		}
1478 	} else if (IS_ENABLED(CONFIG_BT_CTLR_ADV_ISO) && IS_ADV_ISO_HANDLE(handle)) {
1479 		/* Process as TX ack. TODO: Can be unified with CIS and use
1480 		 * ISOAL.
1481 		 */
1482 		/* FIXME: ll_tx_ack_put is not LLL callable as it is
1483 		 * used by ACL connections in ULL context to dispatch
1484 		 * ack.
1485 		 */
1486 		ll_tx_ack_put(handle, (void *)node_tx);
1487 		ll_rx_sched();
1488 	} else {
1489 		LL_ASSERT(0);
1490 	}
1491 }
1492 
ull_iso_lll_event_prepare(uint16_t handle,uint64_t event_count)1493 void ull_iso_lll_event_prepare(uint16_t handle, uint64_t event_count)
1494 {
1495 	if (IS_CIS_HANDLE(handle)) {
1496 		struct ll_iso_datapath *dp = NULL;
1497 		struct ll_conn_iso_stream *cis;
1498 
1499 		cis = ll_iso_stream_connected_get(handle);
1500 
1501 		if (cis) {
1502 			dp  = cis->hdr.datapath_in;
1503 		}
1504 
1505 		if (dp) {
1506 			isoal_tx_event_prepare(dp->source_hdl, event_count);
1507 		}
1508 	} else if (IS_ADV_ISO_HANDLE(handle)) {
1509 		struct ll_iso_datapath *dp = NULL;
1510 		struct lll_adv_iso_stream *stream;
1511 		uint16_t stream_handle;
1512 
1513 		stream_handle = LL_BIS_ADV_IDX_FROM_HANDLE(handle);
1514 		stream = ull_adv_iso_stream_get(stream_handle);
1515 
1516 		if (stream) {
1517 			dp = stream->dp;
1518 		}
1519 
1520 		if (dp) {
1521 			isoal_tx_event_prepare(dp->source_hdl, event_count);
1522 		}
1523 	} else {
1524 		LL_ASSERT(0);
1525 	}
1526 }
1527 #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
1528 
1529 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_SYNC_ISO)
ull_iso_big_sync_delay(uint8_t num_bis,uint32_t bis_spacing,uint8_t nse,uint32_t sub_interval,uint8_t phy,uint8_t max_pdu,bool enc)1530 uint32_t ull_iso_big_sync_delay(uint8_t num_bis, uint32_t bis_spacing, uint8_t nse,
1531 				uint32_t sub_interval, uint8_t phy, uint8_t max_pdu, bool enc)
1532 {
1533 	/* BT Core v5.4 - Vol 6, Part B, Section 4.4.6.4:
1534 	 * BIG_Sync_Delay = (Num_BIS – 1) × BIS_Spacing + (NSE – 1) × Sub_Interval + MPT.
1535 	 */
1536 	return (num_bis - 1) * bis_spacing + (nse - 1) * sub_interval +
1537 	       BYTES2US(PDU_OVERHEAD_SIZE(phy) + max_pdu + (enc ? 4 : 0), phy);
1538 }
1539 #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_SYNC_ISO */
1540 
1541 #if defined(CONFIG_BT_CTLR_SYNC_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
ull_iso_pdu_rx_alloc_peek(uint8_t count)1542 void *ull_iso_pdu_rx_alloc_peek(uint8_t count)
1543 {
1544 	if (count > MFIFO_AVAIL_COUNT_GET(iso_rx)) {
1545 		return NULL;
1546 	}
1547 
1548 	return MFIFO_DEQUEUE_PEEK(iso_rx);
1549 }
1550 
ull_iso_pdu_rx_alloc(void)1551 void *ull_iso_pdu_rx_alloc(void)
1552 {
1553 	return MFIFO_DEQUEUE(iso_rx);
1554 }
1555 
1556 #if defined(CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH)
ull_iso_rx_put(memq_link_t * link,void * rx)1557 void ull_iso_rx_put(memq_link_t *link, void *rx)
1558 {
1559 	/* Enqueue the Rx object */
1560 	memq_enqueue(link, rx, &memq_ull_iso_rx.tail);
1561 }
1562 
ull_iso_rx_sched(void)1563 void ull_iso_rx_sched(void)
1564 {
1565 	static memq_link_t link;
1566 	static struct mayfly mfy = {0, 0, &link, NULL, iso_rx_demux};
1567 
1568 	/* Kick the ULL (using the mayfly, tailchain it) */
1569 	mayfly_enqueue(TICKER_USER_ID_LLL, TICKER_USER_ID_ULL_HIGH, 1, &mfy);
1570 }
1571 
1572 #if defined(CONFIG_BT_CTLR_CONN_ISO)
iso_rx_cig_ref_point_update(struct ll_conn_iso_group * cig,const struct ll_conn_iso_stream * cis,const struct node_rx_iso_meta * meta)1573 static void iso_rx_cig_ref_point_update(struct ll_conn_iso_group *cig,
1574 					const struct ll_conn_iso_stream *cis,
1575 					const struct node_rx_iso_meta  *meta)
1576 {
1577 	uint32_t cig_sync_delay;
1578 	uint32_t cis_sync_delay;
1579 	uint64_t event_count;
1580 	uint8_t burst_number;
1581 	uint8_t role;
1582 
1583 	role = cig->lll.role;
1584 	cig_sync_delay = cig->sync_delay;
1585 	cis_sync_delay = cis->sync_delay;
1586 	burst_number = cis->lll.rx.bn;
1587 	event_count = cis->lll.event_count;
1588 
1589 	if (role) {
1590 		/* Peripheral */
1591 
1592 		/* Check if this is the first payload received for this cis in
1593 		 * this event
1594 		 */
1595 		if (meta->payload_number == (burst_number * event_count)) {
1596 			/* Update the CIG reference point based on the CIS
1597 			 * anchor point
1598 			 */
1599 			cig->cig_ref_point = isoal_get_wrapped_time_us(meta->timestamp,
1600 						cis_sync_delay - cig_sync_delay);
1601 		}
1602 	}
1603 }
1604 #endif /* CONFIG_BT_CTLR_CONN_ISO */
1605 
iso_rx_demux(void * param)1606 static void iso_rx_demux(void *param)
1607 {
1608 #if defined(CONFIG_BT_CTLR_CONN_ISO) || \
1609 	defined(CONFIG_BT_CTLR_SYNC_ISO)
1610 	struct ll_iso_datapath *dp;
1611 #endif  /* CONFIG_BT_CTLR_CONN_ISO || CONFIG_BT_CTLR_SYNC_ISO */
1612 	struct node_rx_pdu *rx_pdu;
1613 	struct node_rx_hdr *rx;
1614 	memq_link_t *link;
1615 	uint16_t handle;
1616 
1617 	do {
1618 		link = memq_peek(memq_ull_iso_rx.head, memq_ull_iso_rx.tail,
1619 				 (void **)&rx);
1620 		if (link) {
1621 			/* Demux Rx objects */
1622 			switch (rx->type) {
1623 			case NODE_RX_TYPE_RELEASE:
1624 				(void)memq_dequeue(memq_ull_iso_rx.tail,
1625 						   &memq_ull_iso_rx.head, NULL);
1626 				ll_iso_rx_put(link, rx);
1627 				ll_rx_sched();
1628 				break;
1629 
1630 			case NODE_RX_TYPE_ISO_PDU:
1631 				/* Remove from receive-queue; ULL has received this now */
1632 				(void)memq_dequeue(memq_ull_iso_rx.tail, &memq_ull_iso_rx.head,
1633 						   NULL);
1634 
1635 				rx_pdu = (struct node_rx_pdu *)rx;
1636 				handle = rx_pdu->hdr.handle;
1637 				dp = NULL;
1638 
1639 				if (false) {
1640 #if defined(CONFIG_BT_CTLR_CONN_ISO)
1641 				} else if (IS_CIS_HANDLE(handle)) {
1642 					struct ll_conn_iso_stream *cis;
1643 					struct ll_conn_iso_group *cig;
1644 
1645 					cis = ll_conn_iso_stream_get(handle);
1646 					cig = cis->group;
1647 					dp  = cis->hdr.datapath_out;
1648 
1649 					iso_rx_cig_ref_point_update(cig, cis,
1650 								    &rx_pdu->hdr.rx_iso_meta);
1651 #endif /* CONFIG_BT_CTLR_CONN_ISO */
1652 #if defined(CONFIG_BT_CTLR_SYNC_ISO)
1653 				} else if (IS_SYNC_ISO_HANDLE(handle)) {
1654 					struct lll_sync_iso_stream *sync_stream;
1655 					uint16_t stream_handle;
1656 
1657 					stream_handle = LL_BIS_SYNC_IDX_FROM_HANDLE(handle);
1658 					sync_stream = ull_sync_iso_stream_get(stream_handle);
1659 					dp = sync_stream ? sync_stream->dp : NULL;
1660 #endif /* CONFIG_BT_CTLR_SYNC_ISO */
1661 				}
1662 
1663 #if defined(CONFIG_BT_CTLR_CONN_ISO) || defined(CONFIG_BT_CTLR_SYNC_ISO)
1664 				if (dp && dp->path_id != BT_HCI_DATAPATH_ID_HCI) {
1665 					/* If vendor specific datapath pass to ISO AL here,
1666 					 * in case of HCI destination it will be passed in
1667 					 * HCI context.
1668 					 */
1669 					struct isoal_pdu_rx pckt_meta = {
1670 						.meta = &rx_pdu->rx_iso_meta,
1671 						.pdu  = (struct pdu_iso *)&rx_pdu->pdu[0]
1672 					};
1673 
1674 					/* Pass the ISO PDU through ISO-AL */
1675 					const isoal_status_t err =
1676 						isoal_rx_pdu_recombine(dp->sink_hdl, &pckt_meta);
1677 
1678 					LL_ASSERT(err == ISOAL_STATUS_OK); /* TODO handle err */
1679 				}
1680 #endif /* CONFIG_BT_CTLR_CONN_ISO || CONFIG_BT_CTLR_SYNC_ISO */
1681 
1682 				/* Let ISO PDU start its long journey upwards */
1683 				ll_iso_rx_put(link, rx);
1684 				ll_rx_sched();
1685 				break;
1686 
1687 			default:
1688 				LL_ASSERT(0);
1689 				break;
1690 			}
1691 		}
1692 	} while (link);
1693 }
1694 #endif /* CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH */
1695 
ll_iso_rx_put(memq_link_t * link,void * rx)1696 void ll_iso_rx_put(memq_link_t *link, void *rx)
1697 {
1698 	/* Enqueue the Rx object */
1699 	memq_enqueue(link, rx, &memq_ll_iso_rx.tail);
1700 }
1701 
ll_iso_rx_get(void)1702 void *ll_iso_rx_get(void)
1703 {
1704 	struct node_rx_hdr *rx;
1705 	memq_link_t *link;
1706 
1707 	link = memq_peek(memq_ll_iso_rx.head, memq_ll_iso_rx.tail, (void **)&rx);
1708 	while (link) {
1709 		/* Do not send up buffers to Host thread that are
1710 		 * marked for release
1711 		 */
1712 		if (rx->type == NODE_RX_TYPE_RELEASE) {
1713 			(void)memq_dequeue(memq_ll_iso_rx.tail,
1714 						&memq_ll_iso_rx.head, NULL);
1715 			mem_release(link, &mem_link_iso_rx.free);
1716 			mem_release(rx, &mem_pool_iso_rx.free);
1717 			RXFIFO_ALLOC(iso_rx, 1);
1718 
1719 			link = memq_peek(memq_ll_iso_rx.head, memq_ll_iso_rx.tail, (void **)&rx);
1720 			continue;
1721 		}
1722 		return rx;
1723 	}
1724 
1725 	return NULL;
1726 }
1727 
ll_iso_rx_dequeue(void)1728 void ll_iso_rx_dequeue(void)
1729 {
1730 	struct node_rx_hdr *rx = NULL;
1731 	memq_link_t *link;
1732 
1733 	link = memq_dequeue(memq_ll_iso_rx.tail, &memq_ll_iso_rx.head,
1734 			    (void **)&rx);
1735 	LL_ASSERT(link);
1736 
1737 	mem_release(link, &mem_link_iso_rx.free);
1738 
1739 	/* Handle object specific clean up */
1740 	switch (rx->type) {
1741 	case NODE_RX_TYPE_ISO_PDU:
1742 		break;
1743 	default:
1744 		LL_ASSERT(0);
1745 		break;
1746 	}
1747 }
1748 
ll_iso_rx_mem_release(void ** node_rx)1749 void ll_iso_rx_mem_release(void **node_rx)
1750 {
1751 	struct node_rx_hdr *rx;
1752 
1753 	rx = *node_rx;
1754 	while (rx) {
1755 		struct node_rx_hdr *rx_free;
1756 
1757 		rx_free = rx;
1758 		rx = rx->next;
1759 
1760 		switch (rx_free->type) {
1761 		case NODE_RX_TYPE_ISO_PDU:
1762 			mem_release(rx_free, &mem_pool_iso_rx.free);
1763 			break;
1764 		default:
1765 			/* Ignore other types as node may have been initialized due to
1766 			 * race with HCI reset.
1767 			 */
1768 			break;
1769 		}
1770 	}
1771 
1772 	*node_rx = rx;
1773 
1774 	RXFIFO_ALLOC(iso_rx, UINT8_MAX);
1775 }
1776 #endif /* CONFIG_BT_CTLR_SYNC_ISO) || CONFIG_BT_CTLR_CONN_ISO */
1777 
ull_iso_datapath_alloc(void)1778 struct ll_iso_datapath *ull_iso_datapath_alloc(void)
1779 {
1780 	return mem_acquire(&datapath_free);
1781 }
1782 
ull_iso_datapath_release(struct ll_iso_datapath * dp)1783 void ull_iso_datapath_release(struct ll_iso_datapath *dp)
1784 {
1785 	mem_release(dp, &datapath_free);
1786 }
1787 
1788 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
ll_iso_link_tx_release(void * link)1789 void ll_iso_link_tx_release(void *link)
1790 {
1791 	mem_release(link, &mem_link_iso_tx.free);
1792 }
1793 
1794 /**
1795  * Allocate a PDU from the LL and store the details in the given buffer. Allocation
1796  * is not expected to fail as there must always be sufficient PDU buffers. Any
1797  * failure will trigger the assert.
1798  * @param[in]  pdu_buffer Buffer to store PDU details in
1799  * @return     Error status of operation
1800  */
ll_iso_pdu_alloc(struct isoal_pdu_buffer * pdu_buffer)1801 static isoal_status_t ll_iso_pdu_alloc(struct isoal_pdu_buffer *pdu_buffer)
1802 {
1803 	struct node_tx_iso *node_tx;
1804 
1805 	node_tx = ll_iso_tx_mem_acquire();
1806 	if (!node_tx) {
1807 		LOG_ERR("Tx Buffer Overflow");
1808 		/* TODO: Report overflow to HCI and remove assert
1809 		 * data_buf_overflow(evt, BT_OVERFLOW_LINK_ISO)
1810 		 */
1811 		LL_ASSERT(0);
1812 		return ISOAL_STATUS_ERR_PDU_ALLOC;
1813 	}
1814 
1815 	node_tx->link = NULL;
1816 
1817 	/* node_tx handle will be required to emit the PDU later */
1818 	pdu_buffer->handle = (void *)node_tx;
1819 	pdu_buffer->pdu    = (void *)node_tx->pdu;
1820 
1821 	/* Use TX buffer size as the limit here. Actual size will be decided in
1822 	 * the ISOAL based on the minimum of the buffer size and the respective
1823 	 * Max_PDU_C_To_P or Max_PDU_P_To_C.
1824 	 */
1825 	pdu_buffer->size = MAX(LL_BIS_OCTETS_TX_MAX, LL_CIS_OCTETS_TX_MAX);
1826 
1827 	return ISOAL_STATUS_OK;
1828 }
1829 
1830 /**
1831  * Write the given SDU payload to the target PDU buffer at the given offset.
1832  * @param[in,out]  pdu_buffer  Target PDU buffer
1833  * @param[in]      pdu_offset  Offset / current write position within PDU
1834  * @param[in]      sdu_payload Location of source data
1835  * @param[in]      consume_len Length of data to copy
1836  * @return         Error status of write operation
1837  */
ll_iso_pdu_write(struct isoal_pdu_buffer * pdu_buffer,const size_t pdu_offset,const uint8_t * sdu_payload,const size_t consume_len)1838 static isoal_status_t ll_iso_pdu_write(struct isoal_pdu_buffer *pdu_buffer,
1839 				       const size_t  pdu_offset,
1840 				       const uint8_t *sdu_payload,
1841 				       const size_t  consume_len)
1842 {
1843 	ARG_UNUSED(pdu_offset);
1844 	ARG_UNUSED(consume_len);
1845 
1846 	LL_ASSERT(pdu_buffer);
1847 	LL_ASSERT(pdu_buffer->pdu);
1848 	LL_ASSERT(sdu_payload);
1849 
1850 	if ((pdu_offset + consume_len) > pdu_buffer->size) {
1851 		/* Exceeded PDU buffer */
1852 		return ISOAL_STATUS_ERR_UNSPECIFIED;
1853 	}
1854 
1855 	/* Copy source to destination at given offset */
1856 	memcpy(&pdu_buffer->pdu->payload[pdu_offset], sdu_payload, consume_len);
1857 
1858 	return ISOAL_STATUS_OK;
1859 }
1860 
1861 /**
1862  * Emit the encoded node to the transmission queue
1863  * @param node_tx TX node to enqueue
1864  * @param handle  CIS/BIS handle
1865  * @return        Error status of enqueue operation
1866  */
ll_iso_pdu_emit(struct node_tx_iso * node_tx,const uint16_t handle)1867 static isoal_status_t ll_iso_pdu_emit(struct node_tx_iso *node_tx,
1868 				      const uint16_t handle)
1869 {
1870 	memq_link_t *link;
1871 
1872 	link = mem_acquire(&mem_link_iso_tx.free);
1873 	LL_ASSERT(link);
1874 
1875 	if (ll_iso_tx_mem_enqueue(handle, node_tx, link)) {
1876 		return ISOAL_STATUS_ERR_PDU_EMIT;
1877 	}
1878 
1879 	return ISOAL_STATUS_OK;
1880 }
1881 
1882 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
1883 /**
1884  * Release the given payload back to the memory pool.
1885  * @param node_tx TX node to release or forward
1886  * @param handle  CIS/BIS handle
1887  * @param status  Reason for release
1888  * @return        Error status of release operation
1889  */
ll_iso_pdu_release(struct node_tx_iso * node_tx,const uint16_t handle,const isoal_status_t status)1890 static isoal_status_t ll_iso_pdu_release(struct node_tx_iso *node_tx,
1891 					 const uint16_t handle,
1892 					 const isoal_status_t status)
1893 {
1894 	if (status == ISOAL_STATUS_OK) {
1895 		/* Process as TX ack, we are in LLL execution context here.
1896 		 * status == ISOAL_STATUS_OK when an ISO PDU has been acked.
1897 		 *
1898 		 * Call Path:
1899 		 *   ull_iso_lll_ack_enqueue() --> isoal_tx_pdu_release() -->
1900 		 *   pdu_release() == ll_iso_pdu_release() (this function).
1901 		 */
1902 		/* FIXME: ll_tx_ack_put is not LLL callable as it is used by
1903 		 * ACL connections in ULL context to dispatch ack.
1904 		 */
1905 		ll_tx_ack_put(handle, (void *)node_tx);
1906 		ll_rx_sched();
1907 	} else {
1908 		/* Release back to memory pool, we are in Thread context
1909 		 * Callers:
1910 		 *   isoal_source_deallocate() with ISOAL_STATUS_ERR_PDU_EMIT
1911 		 *   isoal_tx_pdu_emit with status != ISOAL_STATUS_OK
1912 		 */
1913 		if (node_tx->link) {
1914 			ll_iso_link_tx_release(node_tx->link);
1915 		}
1916 		ll_iso_tx_mem_release(node_tx);
1917 	}
1918 
1919 	return ISOAL_STATUS_OK;
1920 }
1921 #endif /* CONFIG_BT_CTLR_CONN_ISO */
1922 #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
1923 
init_reset(void)1924 static int init_reset(void)
1925 {
1926 #if defined(CONFIG_BT_CTLR_SYNC_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
1927 	memq_link_t *link;
1928 
1929 	RXFIFO_INIT(iso_rx);
1930 
1931 	/* Acquire a link to initialize ull rx memq */
1932 	link = mem_acquire(&mem_link_iso_rx.free);
1933 	LL_ASSERT(link);
1934 
1935 #if defined(CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH)
1936 	/* Initialize ull rx memq */
1937 	MEMQ_INIT(ull_iso_rx, link);
1938 #endif /* CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH */
1939 
1940 	/* Acquire a link to initialize ll_iso_rx memq */
1941 	link = mem_acquire(&mem_link_iso_rx.free);
1942 	LL_ASSERT(link);
1943 
1944 	/* Initialize ll_iso_rx memq */
1945 	MEMQ_INIT(ll_iso_rx, link);
1946 
1947 	RXFIFO_ALLOC(iso_rx, UINT8_MAX);
1948 #endif /* CONFIG_BT_CTLR_SYNC_ISO) || CONFIG_BT_CTLR_CONN_ISO */
1949 
1950 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
1951 	/* Initialize tx pool. */
1952 	mem_init(mem_iso_tx.pool, NODE_TX_BUFFER_SIZE, BT_CTLR_ISO_TX_BUFFERS,
1953 		 &mem_iso_tx.free);
1954 
1955 	/* Initialize tx link pool. */
1956 	mem_init(mem_link_iso_tx.pool, sizeof(memq_link_t),
1957 		 BT_CTLR_ISO_TX_BUFFERS, &mem_link_iso_tx.free);
1958 #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
1959 
1960 #if BT_CTLR_ISO_STREAMS
1961 	/* Initialize ISO Datapath pool */
1962 	mem_init(datapath_pool, sizeof(struct ll_iso_datapath),
1963 		 sizeof(datapath_pool) / sizeof(struct ll_iso_datapath), &datapath_free);
1964 #endif /* BT_CTLR_ISO_STREAMS */
1965 
1966 	/* Initialize ISO Adaptation Layer */
1967 	isoal_init();
1968 
1969 	return 0;
1970 }
1971