Bluetooth: Controller: Initial ISO Sync Receiver datapath integration
Initial attempt at integrating the ISOAL datapath with ISO Synchronized Receiver implementation to generate HCI ISO data packets. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
ff1e3a80cf
commit
2c65856ee8
5 changed files with 169 additions and 44 deletions
|
@ -38,11 +38,11 @@
|
|||
#include "ll_sw/lll_adv.h"
|
||||
#include "lll/lll_adv_pdu.h"
|
||||
#include "ll_sw/lll_scan.h"
|
||||
#include "lll/lll_df_types.h"
|
||||
#include "ll_sw/lll_sync.h"
|
||||
#include "ll_sw/lll_sync_iso.h"
|
||||
#include "ll_sw/lll_conn.h"
|
||||
#include "ll_sw/lll_conn_iso.h"
|
||||
#include "lll/lll_df_types.h"
|
||||
|
||||
#include "ll_sw/isoal.h"
|
||||
|
||||
|
@ -6448,7 +6448,16 @@ static void le_sync_iso_pdu(struct pdu_data *pdu,
|
|||
struct node_rx_pdu *node_rx,
|
||||
struct net_buf *buf)
|
||||
{
|
||||
/* FIXME: integrate with ISOAL interface */
|
||||
/* If HCI datapath pass to ISO AL here */
|
||||
const struct lll_sync_iso_stream *stream;
|
||||
struct isoal_pdu_rx isoal_rx;
|
||||
isoal_status_t err;
|
||||
|
||||
stream = ull_sync_iso_stream_get(node_rx->hdr.handle);
|
||||
isoal_rx.meta = &node_rx->hdr.rx_iso_meta;
|
||||
isoal_rx.pdu = (void *)node_rx->pdu;
|
||||
err = isoal_rx_pdu_recombine(stream->dp->sink_hdl, &isoal_rx);
|
||||
LL_ASSERT(err == ISOAL_STATUS_OK || err == ISOAL_STATUS_ERR_SDU_ALLOC);
|
||||
}
|
||||
|
||||
static void le_big_sync_lost(struct pdu_data *pdu,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
struct lll_sync_iso_stream {
|
||||
uint8_t big_handle;
|
||||
void *rfi;
|
||||
struct ll_iso_datapath *dp;
|
||||
};
|
||||
|
||||
struct lll_sync_iso {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "hal/cpu.h"
|
||||
#include "hal/ccm.h"
|
||||
|
||||
#include "util/util.h"
|
||||
#include "util/memq.h"
|
||||
#include "util/mem.h"
|
||||
#include "util/mfifo.h"
|
||||
|
@ -17,28 +18,48 @@
|
|||
#include "pdu.h"
|
||||
|
||||
#include "lll.h"
|
||||
#include "lll_conn.h" /* for `struct lll_tx` */
|
||||
#include "lll_sync.h"
|
||||
#include "lll_sync_iso.h"
|
||||
#include "lll_conn.h"
|
||||
#include "lll_conn_iso.h"
|
||||
|
||||
#include "isoal.h"
|
||||
|
||||
#include "ull_sync_types.h"
|
||||
#include "ull_iso_types.h"
|
||||
#include "ull_conn_iso_types.h"
|
||||
|
||||
#include "ull_conn_internal.h"
|
||||
#include "ull_sync_iso_internal.h"
|
||||
#include "ull_conn_iso_internal.h"
|
||||
|
||||
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
|
||||
#define LOG_MODULE_NAME bt_ctlr_ull_iso
|
||||
#include "common/log.h"
|
||||
#include "hal/debug.h"
|
||||
|
||||
#include "lll_conn_iso.h"
|
||||
#include "ull_conn_iso_types.h"
|
||||
#include "isoal.h"
|
||||
#include "ull_iso_types.h"
|
||||
#include "ull_conn_internal.h"
|
||||
#include "ull_conn_iso_internal.h"
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_CONN_ISO_STREAMS)
|
||||
/* Allocate data path pools for RX/TX directions for each stream */
|
||||
static struct ll_iso_datapath datapath_pool[2*CONFIG_BT_CTLR_CONN_ISO_STREAMS];
|
||||
static void *datapath_free;
|
||||
#endif
|
||||
#define BT_CTLR_CONN_ISO_STREAMS CONFIG_BT_CTLR_CONN_ISO_STREAMS
|
||||
#else /* !CONFIG_BT_CTLR_CONN_ISO_STREAMS */
|
||||
#define BT_CTLR_CONN_ISO_STREAMS 0
|
||||
#endif /* !CONFIG_BT_CTLR_CONN_ISO_STREAMS */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT)
|
||||
#define BT_CTLR_SYNC_ISO_STREAMS (CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT)
|
||||
#else /* !CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT */
|
||||
#define BT_CTLR_SYNC_ISO_STREAMS 0
|
||||
#endif /* CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT */
|
||||
|
||||
static int init_reset(void);
|
||||
|
||||
/* Allocate data path pools for RX/TX directions for each stream */
|
||||
#define BT_CTLR_ISO_STREAMS ((2 * (BT_CTLR_CONN_ISO_STREAMS)) + \
|
||||
BT_CTLR_SYNC_ISO_STREAMS)
|
||||
#if BT_CTLR_ISO_STREAMS
|
||||
static struct ll_iso_datapath datapath_pool[BT_CTLR_ISO_STREAMS];
|
||||
#endif
|
||||
static void *datapath_free;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
|
||||
static MFIFO_DEFINE(iso_tx, sizeof(struct lll_tx),
|
||||
CONFIG_BT_CTLR_ISO_TX_BUFFERS);
|
||||
|
@ -228,6 +249,71 @@ uint8_t ll_setup_iso_path(uint16_t handle, uint8_t path_dir, uint8_t path_id,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_SYNC_ISO)
|
||||
struct lll_sync_iso_stream *stream;
|
||||
struct ll_sync_iso_set *sync_iso;
|
||||
isoal_sink_handle_t sink_handle;
|
||||
struct lll_sync_iso *lll_iso;
|
||||
struct ll_iso_datapath *dp;
|
||||
uint16_t stream_handle;
|
||||
uint32_t sdu_interval;
|
||||
uint16_t iso_interval;
|
||||
uint8_t burst_number;
|
||||
int err;
|
||||
|
||||
if (path_dir != BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) {
|
||||
/* FIXME: workaround to succeed datapath setup for ISO
|
||||
* broadcaster until Tx datapath is implemented, in the
|
||||
* future.
|
||||
*/
|
||||
return BT_HCI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
if (handle < BT_CTLR_SYNC_ISO_STREAM_HANDLE_BASE) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
stream_handle = handle - BT_CTLR_SYNC_ISO_STREAM_HANDLE_BASE;
|
||||
|
||||
stream = ull_sync_iso_stream_get(stream_handle);
|
||||
if (stream->dp) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
/* Allocate and configure datapath */
|
||||
dp = mem_acquire(&datapath_free);
|
||||
if (!dp) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
dp->path_dir = path_dir;
|
||||
dp->path_id = path_id;
|
||||
dp->coding_format = coding_format;
|
||||
dp->company_id = company_id;
|
||||
|
||||
/* TODO dp->sync_delay = controller_delay; ?*/
|
||||
|
||||
sync_iso = ull_sync_iso_by_stream_get(stream_handle);
|
||||
lll_iso = &sync_iso->lll;
|
||||
|
||||
burst_number = lll_iso->bn;
|
||||
sdu_interval = lll_iso->sdu_interval;
|
||||
iso_interval = lll_iso->iso_interval;
|
||||
|
||||
err = isoal_sink_create(&sink_handle, handle, burst_number,
|
||||
sdu_interval, iso_interval, sink_sdu_alloc_hci,
|
||||
sink_sdu_emit_hci, sink_sdu_write_hci);
|
||||
if (err) {
|
||||
mem_release(dp, &datapath_free);
|
||||
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
dp->sink_hdl = sink_handle;
|
||||
stream->dp = dp;
|
||||
|
||||
isoal_sink_enable(sink_handle);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -260,6 +346,21 @@ uint8_t ll_remove_iso_path(uint16_t handle, uint8_t path_dir)
|
|||
}
|
||||
#endif /* CONFIG_BT_CTLR_CONN_ISO */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_SYNC_ISO)
|
||||
struct lll_sync_iso_stream *stream;
|
||||
|
||||
if (path_dir != BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
stream = ull_sync_iso_stream_get(handle);
|
||||
dp = stream->dp;
|
||||
if (dp) {
|
||||
stream->dp = NULL;
|
||||
mem_release(dp, &datapath_free);
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
|
||||
|
||||
if (!dp) {
|
||||
/* Datapath was not previously set up */
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
|
@ -336,6 +437,36 @@ uint8_t ll_iso_test_end(uint16_t handle, uint32_t *received_cnt,
|
|||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
|
||||
void *ll_iso_tx_mem_acquire(void)
|
||||
{
|
||||
return mem_acquire(&mem_iso_tx.free);
|
||||
}
|
||||
|
||||
void ll_iso_tx_mem_release(void *node_tx)
|
||||
{
|
||||
mem_release(node_tx, &mem_iso_tx.free);
|
||||
}
|
||||
|
||||
int ll_iso_tx_mem_enqueue(uint16_t handle, void *node_tx)
|
||||
{
|
||||
struct lll_tx *tx;
|
||||
uint8_t idx;
|
||||
|
||||
idx = MFIFO_ENQUEUE_GET(iso_tx, (void **) &tx);
|
||||
if (!tx) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
tx->handle = handle;
|
||||
tx->node = node_tx;
|
||||
|
||||
MFIFO_ENQUEUE(iso_tx, idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
|
||||
|
||||
int ull_iso_init(void)
|
||||
{
|
||||
int err;
|
||||
|
@ -365,36 +496,11 @@ int ull_iso_reset(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
|
||||
void *ll_iso_tx_mem_acquire(void)
|
||||
void ull_iso_datapath_release(struct ll_iso_datapath *dp)
|
||||
{
|
||||
return mem_acquire(&mem_iso_tx.free);
|
||||
mem_release(dp, &datapath_free);
|
||||
}
|
||||
|
||||
void ll_iso_tx_mem_release(void *tx)
|
||||
{
|
||||
mem_release(tx, &mem_iso_tx.free);
|
||||
}
|
||||
|
||||
int ll_iso_tx_mem_enqueue(uint16_t handle, void *tx)
|
||||
{
|
||||
struct lll_tx *lll_tx;
|
||||
uint8_t idx;
|
||||
|
||||
idx = MFIFO_ENQUEUE_GET(iso_tx, (void **) &lll_tx);
|
||||
if (!lll_tx) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
lll_tx->handle = handle;
|
||||
lll_tx->node = tx;
|
||||
|
||||
MFIFO_ENQUEUE(iso_tx, idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
|
||||
|
||||
static int init_reset(void)
|
||||
{
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
|
||||
|
@ -403,7 +509,7 @@ static int init_reset(void)
|
|||
CONFIG_BT_CTLR_ISO_TX_BUFFERS, &mem_iso_tx.free);
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_CONN_ISO_STREAMS)
|
||||
#if BT_CTLR_ISO_STREAMS
|
||||
/* Initialize ISO Datapath pool */
|
||||
mem_init(datapath_pool, sizeof(struct ll_iso_datapath),
|
||||
sizeof(datapath_pool) / sizeof(struct ll_iso_datapath), &datapath_free);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2020-2021 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
int ull_iso_init(void);
|
||||
int ull_iso_reset(void);
|
||||
void ull_iso_datapath_release(struct ll_iso_datapath *dp);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "ull_internal.h"
|
||||
#include "ull_scan_internal.h"
|
||||
#include "ull_sync_internal.h"
|
||||
#include "ull_iso_internal.h"
|
||||
#include "ull_sync_iso_internal.h"
|
||||
|
||||
#include "ll.h"
|
||||
|
@ -145,6 +146,7 @@ uint8_t ll_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
|
|||
|
||||
stream = (void *)sync_iso_stream_acquire();
|
||||
stream->big_handle = big_handle;
|
||||
stream->dp = NULL;
|
||||
lll->stream_handle[i] = sync_iso_stream_handle_get(stream);
|
||||
}
|
||||
|
||||
|
@ -280,10 +282,17 @@ void ull_sync_iso_stream_release(struct ll_sync_iso_set *sync_iso)
|
|||
lll = &sync_iso->lll;
|
||||
while (lll->stream_count--) {
|
||||
struct lll_sync_iso_stream *stream;
|
||||
struct ll_iso_datapath *dp;
|
||||
uint16_t handle;
|
||||
|
||||
handle = lll->stream_handle[lll->stream_count];
|
||||
stream = ull_sync_iso_stream_get(handle);
|
||||
|
||||
dp = stream->dp;
|
||||
if (dp) {
|
||||
ull_iso_datapath_release(dp);
|
||||
}
|
||||
|
||||
mem_release(stream, &stream_free);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue