From d67416321e6b2526ba55e8c176405b555dbc034d Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 12 Nov 2019 17:02:13 +0200 Subject: [PATCH] Bluetooth: hci_raw: Add support for specifying buffer headroom The HCI transport implemented by an application using the HCI raw interface may have its own buffer headroom requirements. Currently the available headroom gets completely determined by the selected HCI driver. E.g. most of the time this is the native controller driver which doesn't reserve any headroom at all. To cover for the needs of HCI raw users, add a new Kconfig variable for the apps to set to whatever they need. Correspondingly, use the maximum of the HCI driver and HCI raw headroom requirements for the buffer pool definitions and the headroom initializations. Signed-off-by: Johan Hedberg --- drivers/bluetooth/hci/h5.c | 2 +- include/bluetooth/buf.h | 8 +++++++- include/bluetooth/l2cap.h | 4 ++-- subsys/bluetooth/Kconfig | 8 ++++++++ subsys/bluetooth/host/conn.c | 2 +- subsys/bluetooth/host/hci_core.c | 10 +++++----- subsys/bluetooth/host/hci_raw.c | 2 +- subsys/bluetooth/host/rfcomm_internal.h | 2 +- subsys/usb/class/bluetooth.c | 4 ++-- 9 files changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/bluetooth/hci/h5.c b/drivers/bluetooth/hci/h5.c index cf35f8cb50a..3a6b7b0c767 100644 --- a/drivers/bluetooth/hci/h5.c +++ b/drivers/bluetooth/hci/h5.c @@ -122,7 +122,7 @@ static const u8_t conf_rsp[] = { 0x04, 0x7b }; /* H5 signal buffers pool */ #define MAX_SIG_LEN 3 #define SIGNAL_COUNT 2 -#define SIG_BUF_SIZE (CONFIG_BT_HCI_RESERVE + MAX_SIG_LEN) +#define SIG_BUF_SIZE (BT_BUF_RESERVE + MAX_SIG_LEN) NET_BUF_POOL_DEFINE(h5_pool, SIGNAL_COUNT, SIG_BUF_SIZE, 0, NULL); static struct device *h5_dev; diff --git a/include/bluetooth/buf.h b/include/bluetooth/buf.h index 0cc138a4721..0d25f6de3c1 100644 --- a/include/bluetooth/buf.h +++ b/include/bluetooth/buf.h @@ -37,8 +37,14 @@ enum bt_buf_type { /** Minimum amount of user data size for buffers passed to the stack. */ #define BT_BUF_USER_DATA_MIN 8 +#if defined(CONFIG_BT_HCI_RAW) +#define BT_BUF_RESERVE MAX(CONFIG_BT_HCI_RESERVE, CONFIG_BT_HCI_RAW_RESERVE) +#else +#define BT_BUF_RESERVE CONFIG_BT_HCI_RESERVE +#endif + /** Data size neeed for HCI RX buffers */ -#define BT_BUF_RX_SIZE (CONFIG_BT_HCI_RESERVE + CONFIG_BT_RX_BUF_LEN) +#define BT_BUF_RX_SIZE (BT_BUF_RESERVE + CONFIG_BT_RX_BUF_LEN) /** Allocate a buffer for incoming data * diff --git a/include/bluetooth/l2cap.h b/include/bluetooth/l2cap.h index 2696ddab439..e55202e6421 100644 --- a/include/bluetooth/l2cap.h +++ b/include/bluetooth/l2cap.h @@ -38,7 +38,7 @@ extern "C" { * * @return Needed buffer size to match the requested L2CAP MTU. */ -#define BT_L2CAP_BUF_SIZE(mtu) (CONFIG_BT_HCI_RESERVE + \ +#define BT_L2CAP_BUF_SIZE(mtu) (BT_BUF_RESERVE + \ BT_HCI_ACL_HDR_SIZE + BT_L2CAP_HDR_SIZE + \ (mtu)) @@ -250,7 +250,7 @@ struct bt_l2cap_chan_ops { /** @def BT_L2CAP_CHAN_SEND_RESERVE * @brief Headroom needed for outgoing buffers */ -#define BT_L2CAP_CHAN_SEND_RESERVE (CONFIG_BT_HCI_RESERVE + 4 + 4) +#define BT_L2CAP_CHAN_SEND_RESERVE (BT_BUF_RESERVE + 4 + 4) /** @brief L2CAP Server structure. */ struct bt_l2cap_server { diff --git a/subsys/bluetooth/Kconfig b/subsys/bluetooth/Kconfig index 8d94cf8675f..8c8915915d6 100644 --- a/subsys/bluetooth/Kconfig +++ b/subsys/bluetooth/Kconfig @@ -48,6 +48,14 @@ config BT_HCI_RAW This option allows to access Bluetooth controller from the application with the RAW HCI protocol. +config BT_HCI_RAW_RESERVE + int "Buffer headroom needed for HCI transport" + depends on BT_HCI_RAW + default 0 + help + This option is used by the HCI raw transport implementation to + declare how much headroom it needs for any HCI transport headers. + config BT_PERIPHERAL bool "Peripheral Role support" select BT_BROADCASTER diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index e9c0c6010ce..a835914baca 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -2326,7 +2326,7 @@ struct net_buf *bt_conn_create_pdu_timeout(struct net_buf_pool *pool, return NULL; } - reserve += sizeof(struct bt_hci_acl_hdr) + CONFIG_BT_HCI_RESERVE; + reserve += sizeof(struct bt_hci_acl_hdr) + BT_BUF_RESERVE; net_buf_reserve(buf, reserve); return buf; diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 7f3045b8444..e42f81a948c 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -269,7 +269,7 @@ struct net_buf *bt_hci_cmd_create(u16_t opcode, u8_t param_len) BT_DBG("buf %p", buf); - net_buf_reserve(buf, CONFIG_BT_HCI_RESERVE); + net_buf_reserve(buf, BT_BUF_RESERVE); cmd(buf)->type = BT_BUF_CMD; cmd(buf)->opcode = opcode; @@ -6023,7 +6023,7 @@ struct net_buf *bt_buf_get_rx(enum bt_buf_type type, s32_t timeout) #endif if (buf) { - net_buf_reserve(buf, CONFIG_BT_HCI_RESERVE); + net_buf_reserve(buf, BT_BUF_RESERVE); bt_buf_set_type(buf, type); } @@ -6045,7 +6045,7 @@ struct net_buf *bt_buf_get_cmd_complete(s32_t timeout) if (buf) { bt_buf_set_type(buf, BT_BUF_EVT); buf->len = 0U; - net_buf_reserve(buf, CONFIG_BT_HCI_RESERVE); + net_buf_reserve(buf, BT_BUF_RESERVE); return buf; } @@ -6063,7 +6063,7 @@ struct net_buf *bt_buf_get_evt(u8_t evt, bool discardable, s32_t timeout) buf = net_buf_alloc(&num_complete_pool, timeout); if (buf) { - net_buf_reserve(buf, CONFIG_BT_HCI_RESERVE); + net_buf_reserve(buf, BT_BUF_RESERVE); bt_buf_set_type(buf, BT_BUF_EVT); } @@ -6080,7 +6080,7 @@ struct net_buf *bt_buf_get_evt(u8_t evt, bool discardable, s32_t timeout) buf = net_buf_alloc(&discardable_pool, timeout); if (buf) { - net_buf_reserve(buf, CONFIG_BT_HCI_RESERVE); + net_buf_reserve(buf, BT_BUF_RESERVE); bt_buf_set_type(buf, BT_BUF_EVT); } diff --git a/subsys/bluetooth/host/hci_raw.c b/subsys/bluetooth/host/hci_raw.c index f6a1d9650a7..9a9385b7916 100644 --- a/subsys/bluetooth/host/hci_raw.c +++ b/subsys/bluetooth/host/hci_raw.c @@ -54,7 +54,7 @@ struct net_buf *bt_buf_get_rx(enum bt_buf_type type, s32_t timeout) buf = net_buf_alloc(&hci_rx_pool, timeout); if (buf) { - net_buf_reserve(buf, CONFIG_BT_HCI_RESERVE); + net_buf_reserve(buf, BT_BUF_RESERVE); bt_buf_set_type(buf, type); } diff --git a/subsys/bluetooth/host/rfcomm_internal.h b/subsys/bluetooth/host/rfcomm_internal.h index 3b176b77fcc..dc4bf0a521a 100644 --- a/subsys/bluetooth/host/rfcomm_internal.h +++ b/subsys/bluetooth/host/rfcomm_internal.h @@ -132,7 +132,7 @@ struct bt_rfcomm_rpn { * Length in rfcomm header can be two bytes depending on user data length. * One byte in the tail should be reserved for FCS. */ -#define BT_RFCOMM_BUF_SIZE(mtu) (CONFIG_BT_HCI_RESERVE + \ +#define BT_RFCOMM_BUF_SIZE(mtu) (BT_BUF_RESERVE + \ BT_HCI_ACL_HDR_SIZE + BT_L2CAP_HDR_SIZE + \ sizeof(struct bt_rfcomm_hdr) + 1 + (mtu) + \ BT_RFCOMM_FCS_SIZE) diff --git a/subsys/usb/class/bluetooth.c b/subsys/usb/class/bluetooth.c index 3fccf09a177..bb1c0b449d3 100644 --- a/subsys/usb/class/bluetooth.c +++ b/subsys/usb/class/bluetooth.c @@ -200,7 +200,7 @@ static void acl_read_cb(u8_t ep, int size, void *priv) buf = net_buf_alloc(&acl_tx_pool, K_FOREVER); __ASSERT_NO_MSG(buf); - net_buf_reserve(buf, CONFIG_BT_HCI_RESERVE); + net_buf_reserve(buf, BT_BUF_RESERVE); /* Start a new read transfer */ usb_transfer(bluetooth_ep_data[HCI_OUT_EP_IDX].ep_addr, buf->data, @@ -269,7 +269,7 @@ static int bluetooth_class_handler(struct usb_setup_packet *setup, return -ENOMEM; } - net_buf_reserve(buf, CONFIG_BT_HCI_RESERVE); + net_buf_reserve(buf, BT_BUF_RESERVE); bt_buf_set_type(buf, BT_BUF_CMD); net_buf_add_mem(buf, *data, *len);