/* * Copyright (c) 2020 Demant * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include "hal/cpu.h" #include "hal/ccm.h" #include "util/memq.h" #include "util/mem.h" #include "util/mfifo.h" #include "pdu.h" #include "lll.h" #include "lll_conn.h" /* for `struct lll_tx` */ #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" static int init_reset(void); static MFIFO_DEFINE(iso_tx, sizeof(struct lll_tx), CONFIG_BT_CTLR_ISO_TX_BUFFERS); static struct { void *free; uint8_t pool[CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE * CONFIG_BT_CTLR_ISO_TX_BUFFERS]; } mem_iso_tx; /* Contains vendor specific argument, function to be implemented by vendors */ __weak uint8_t ll_configure_data_path(uint8_t data_path_dir, uint8_t data_path_id, uint8_t vs_config_len, uint8_t *vs_config) { ARG_UNUSED(data_path_dir); ARG_UNUSED(data_path_id); ARG_UNUSED(vs_config_len); ARG_UNUSED(vs_config); return BT_HCI_ERR_CMD_DISALLOWED; } uint8_t ll_read_iso_tx_sync(uint16_t handle, uint16_t *seq, uint32_t *timestamp, uint32_t *offset) { ARG_UNUSED(handle); ARG_UNUSED(seq); ARG_UNUSED(timestamp); ARG_UNUSED(offset); return BT_HCI_ERR_CMD_DISALLOWED; } uint8_t 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) { ARG_UNUSED(handle); ARG_UNUSED(path_dir); ARG_UNUSED(path_id); ARG_UNUSED(coding_format); ARG_UNUSED(company_id); ARG_UNUSED(vs_codec_id); ARG_UNUSED(controller_delay); ARG_UNUSED(codec_config_len); ARG_UNUSED(codec_config); return BT_HCI_ERR_CMD_DISALLOWED; } uint8_t ll_remove_iso_path(uint16_t handle, uint8_t path_dir) { ARG_UNUSED(handle); ARG_UNUSED(path_dir); return BT_HCI_ERR_CMD_DISALLOWED; } uint8_t ll_iso_receive_test(uint16_t handle, uint8_t payload_type) { ARG_UNUSED(handle); ARG_UNUSED(payload_type); return BT_HCI_ERR_CMD_DISALLOWED; } uint8_t ll_iso_transmit_test(uint16_t handle, uint8_t payload_type) { ARG_UNUSED(handle); ARG_UNUSED(payload_type); return BT_HCI_ERR_CMD_DISALLOWED; } uint8_t ll_iso_test_end(uint16_t handle, uint32_t *received_cnt, uint32_t *missed_cnt, uint32_t *failed_cnt) { ARG_UNUSED(handle); ARG_UNUSED(received_cnt); ARG_UNUSED(missed_cnt); ARG_UNUSED(failed_cnt); return BT_HCI_ERR_CMD_DISALLOWED; } uint8_t ll_iso_read_test_counters(uint16_t handle, uint32_t *received_cnt, uint32_t *missed_cnt, uint32_t *failed_cnt) { ARG_UNUSED(handle); ARG_UNUSED(received_cnt); ARG_UNUSED(missed_cnt); ARG_UNUSED(failed_cnt); return BT_HCI_ERR_CMD_DISALLOWED; } uint8_t 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) { ARG_UNUSED(handle); ARG_UNUSED(tx_unacked_packets); ARG_UNUSED(tx_flushed_packets); ARG_UNUSED(tx_last_subevent_packets); ARG_UNUSED(retransmitted_packets); ARG_UNUSED(crc_error_packets); ARG_UNUSED(rx_unreceived_packets); ARG_UNUSED(duplicate_packets); return BT_HCI_ERR_CMD_DISALLOWED; } int ull_iso_init(void) { int err; err = init_reset(); if (err) { return err; } return 0; } int ull_iso_reset(void) { int err; /* Re-initialize the Tx mfifo */ MFIFO_INIT(iso_tx); err = init_reset(); if (err) { return err; } return 0; } void *ll_iso_tx_mem_acquire(void) { return mem_acquire(&mem_iso_tx.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; } static int init_reset(void) { /* Initialize tx pool. */ mem_init(mem_iso_tx.pool, CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE, CONFIG_BT_CTLR_ISO_TX_BUFFERS, &mem_iso_tx.free); return 0; }