Refactor only. The surrounding ifdefs are intentionally not changed in this patch. They will be in the near future. Rename the pool and generalize the documentation to allow using this pool for other events that fit the same criteria. This pool can be used for any buffer that is processed synchronously, without negatively affecting 'num complete' messages. E.g. 'cmd complete/status' can be put in this pool already. We will be working towards making the host process all event buffers synchronously. This is because events have no dedicated flow control, and discarding events in the driver without informing the host creates problems. Discarding should instead happen in the host higher layers when unavoidable. Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
150 lines
3.9 KiB
C
150 lines
3.9 KiB
C
/*
|
|
* Copyright (c) 2017 Nordic Semiconductor ASA
|
|
* Copyright (c) 2015 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/bluetooth/buf.h>
|
|
#include <zephyr/bluetooth/l2cap.h>
|
|
|
|
#include "hci_core.h"
|
|
#include "conn_internal.h"
|
|
#include "iso_internal.h"
|
|
|
|
#include <zephyr/bluetooth/hci.h>
|
|
|
|
#if defined(CONFIG_BT_CONN)
|
|
#if defined(CONFIG_BT_ISO)
|
|
#define MAX_EVENT_COUNT CONFIG_BT_MAX_CONN + CONFIG_BT_ISO_MAX_CHAN
|
|
#else
|
|
#define MAX_EVENT_COUNT CONFIG_BT_MAX_CONN
|
|
#endif /* CONFIG_BT_ISO */
|
|
#elif defined(CONFIG_BT_ISO)
|
|
#define MAX_EVENT_COUNT CONFIG_BT_ISO_MAX_CHAN
|
|
#endif /* CONFIG_BT_CONN */
|
|
|
|
#if defined(CONFIG_BT_CONN) || defined(CONFIG_BT_ISO)
|
|
#define NUM_COMLETE_EVENT_SIZE BT_BUF_EVT_SIZE( \
|
|
sizeof(struct bt_hci_cp_host_num_completed_packets) + \
|
|
MAX_EVENT_COUNT * sizeof(struct bt_hci_handle_count))
|
|
|
|
/* Pool for RX HCI buffers that are always freed by `bt_recv`
|
|
* before it returns.
|
|
*
|
|
* A singleton buffer shall be sufficient for correct operation.
|
|
* The buffer count may be increased as an optimization to allow
|
|
* the HCI transport to fill buffers in parallel with `bt_recv`
|
|
* consuming them.
|
|
*/
|
|
#define SYNC_EVT_SIZE NUM_COMLETE_EVENT_SIZE
|
|
NET_BUF_POOL_FIXED_DEFINE(sync_evt_pool, 1, SYNC_EVT_SIZE, sizeof(struct bt_buf_data), NULL);
|
|
#endif /* CONFIG_BT_CONN || CONFIG_BT_ISO */
|
|
|
|
NET_BUF_POOL_FIXED_DEFINE(discardable_pool, CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT,
|
|
BT_BUF_EVT_SIZE(CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE),
|
|
sizeof(struct bt_buf_data), NULL);
|
|
|
|
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
|
|
NET_BUF_POOL_DEFINE(acl_in_pool, CONFIG_BT_BUF_ACL_RX_COUNT,
|
|
BT_BUF_ACL_SIZE(CONFIG_BT_BUF_ACL_RX_SIZE),
|
|
sizeof(struct acl_data), bt_hci_host_num_completed_packets);
|
|
|
|
NET_BUF_POOL_FIXED_DEFINE(evt_pool, CONFIG_BT_BUF_EVT_RX_COUNT,
|
|
BT_BUF_EVT_RX_SIZE, sizeof(struct bt_buf_data),
|
|
NULL);
|
|
#else
|
|
NET_BUF_POOL_FIXED_DEFINE(hci_rx_pool, BT_BUF_RX_COUNT,
|
|
BT_BUF_RX_SIZE, sizeof(struct bt_buf_data),
|
|
NULL);
|
|
#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */
|
|
|
|
struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout)
|
|
{
|
|
struct net_buf *buf;
|
|
|
|
__ASSERT(type == BT_BUF_EVT || type == BT_BUF_ACL_IN ||
|
|
type == BT_BUF_ISO_IN, "Invalid buffer type requested");
|
|
|
|
if (IS_ENABLED(CONFIG_BT_ISO_RX) && type == BT_BUF_ISO_IN) {
|
|
return bt_iso_get_rx(timeout);
|
|
}
|
|
|
|
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
|
|
if (type == BT_BUF_EVT) {
|
|
buf = net_buf_alloc(&evt_pool, timeout);
|
|
} else {
|
|
buf = net_buf_alloc(&acl_in_pool, timeout);
|
|
}
|
|
#else
|
|
buf = net_buf_alloc(&hci_rx_pool, timeout);
|
|
#endif
|
|
|
|
if (buf) {
|
|
net_buf_reserve(buf, BT_BUF_RESERVE);
|
|
bt_buf_set_type(buf, type);
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable,
|
|
k_timeout_t timeout)
|
|
{
|
|
struct net_buf *buf;
|
|
|
|
switch (evt) {
|
|
#if defined(CONFIG_BT_CONN) || defined(CONFIG_BT_ISO)
|
|
case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
|
|
buf = net_buf_alloc(&sync_evt_pool, timeout);
|
|
break;
|
|
#endif /* CONFIG_BT_CONN || CONFIG_BT_ISO */
|
|
default:
|
|
if (discardable) {
|
|
buf = net_buf_alloc(&discardable_pool, timeout);
|
|
} else {
|
|
return bt_buf_get_rx(BT_BUF_EVT, timeout);
|
|
}
|
|
}
|
|
|
|
if (buf) {
|
|
net_buf_reserve(buf, BT_BUF_RESERVE);
|
|
bt_buf_set_type(buf, BT_BUF_EVT);
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
#ifdef ZTEST_UNITTEST
|
|
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
|
|
struct net_buf_pool *bt_buf_get_evt_pool(void)
|
|
{
|
|
return &evt_pool;
|
|
}
|
|
|
|
struct net_buf_pool *bt_buf_get_acl_in_pool(void)
|
|
{
|
|
return &acl_in_pool;
|
|
}
|
|
#else
|
|
struct net_buf_pool *bt_buf_get_hci_rx_pool(void)
|
|
{
|
|
return &hci_rx_pool;
|
|
}
|
|
#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */
|
|
|
|
#if defined(CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT)
|
|
struct net_buf_pool *bt_buf_get_discardable_pool(void)
|
|
{
|
|
return &discardable_pool;
|
|
}
|
|
#endif /* CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT */
|
|
|
|
#if defined(CONFIG_BT_CONN) || defined(CONFIG_BT_ISO)
|
|
struct net_buf_pool *bt_buf_get_num_complete_pool(void)
|
|
{
|
|
return &sync_evt_pool;
|
|
}
|
|
#endif /* CONFIG_BT_CONN || CONFIG_BT_ISO */
|
|
#endif /* ZTEST_UNITTEST */
|