diff --git a/include/zephyr/bluetooth/buf.h b/include/zephyr/bluetooth/buf.h index dd452342ef7..8684bd94e85 100644 --- a/include/zephyr/bluetooth/buf.h +++ b/include/zephyr/bluetooth/buf.h @@ -97,13 +97,13 @@ struct bt_buf_data { * available for the HCI driver to allocate from. * * TODO: When CONFIG_BT_BUF_ACL_RX_COUNT is removed, - * remove the MAX and only keep (CONFIG_BT_MAX_CONN + 1) + * remove the MAX and only keep the 1. */ -#define BT_BUF_ACL_RX_COUNT \ - (MAX(CONFIG_BT_BUF_ACL_RX_COUNT, (CONFIG_BT_MAX_CONN + 1)) + \ - CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA) +#define BT_BUF_ACL_RX_COUNT_EXTRA CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA +#define BT_BUF_ACL_RX_COUNT (MAX(CONFIG_BT_BUF_ACL_RX_COUNT, 1) + BT_BUF_ACL_RX_COUNT_EXTRA) #else -#define BT_BUF_ACL_RX_COUNT 0 +#define BT_BUF_ACL_RX_COUNT_EXTRA 0 +#define BT_BUF_ACL_RX_COUNT 0 #endif /* CONFIG_BT_CONN && CONFIG_BT_HCI_HOST */ #if defined(CONFIG_BT_BUF_ACL_RX_COUNT) && CONFIG_BT_BUF_ACL_RX_COUNT > 0 @@ -117,10 +117,15 @@ BUILD_ASSERT(BT_BUF_ACL_RX_COUNT <= BT_BUF_ACL_RX_COUNT_MAX, #define BT_BUF_RX_SIZE (MAX(MAX(BT_BUF_ACL_RX_SIZE, BT_BUF_EVT_RX_SIZE), \ BT_BUF_ISO_RX_SIZE)) -/** Buffer count needed for HCI ACL, HCI ISO or Event RX buffers */ -#define BT_BUF_RX_COUNT (MAX(MAX(CONFIG_BT_BUF_EVT_RX_COUNT, \ - BT_BUF_ACL_RX_COUNT), \ - BT_BUF_ISO_RX_COUNT)) +/* Controller can generate up to CONFIG_BT_BUF_ACL_TX_COUNT number of unique HCI Number of Completed + * Packets events. + */ +BUILD_ASSERT(CONFIG_BT_BUF_EVT_RX_COUNT > CONFIG_BT_BUF_ACL_TX_COUNT, + "Increase Event RX buffer count to be greater than ACL TX buffer count"); + +/** Buffer count needed for HCI ACL or HCI ISO plus Event RX buffers */ +#define BT_BUF_RX_COUNT (CONFIG_BT_BUF_EVT_RX_COUNT + \ + MAX(BT_BUF_ACL_RX_COUNT, BT_BUF_ISO_RX_COUNT)) /** Data size needed for HCI Command buffers. */ #define BT_BUF_CMD_TX_SIZE BT_BUF_CMD_SIZE(CONFIG_BT_BUF_CMD_TX_SIZE) diff --git a/samples/bluetooth/central_hr/prj_minimal.conf b/samples/bluetooth/central_hr/prj_minimal.conf index be0ed341b78..2a4b31d5f03 100644 --- a/samples/bluetooth/central_hr/prj_minimal.conf +++ b/samples/bluetooth/central_hr/prj_minimal.conf @@ -94,7 +94,7 @@ CONFIG_BT_CTLR_PHY_2M=n # Reduce Bluetooth buffers CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT=1 CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=45 -CONFIG_BT_BUF_EVT_RX_COUNT=2 +CONFIG_BT_BUF_EVT_RX_COUNT=4 CONFIG_BT_L2CAP_TX_BUF_COUNT=2 CONFIG_BT_CTLR_RX_BUFFERS=1 diff --git a/samples/bluetooth/hci_ipc/nrf5340_cpunet_bis-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_bis-bt_ll_sw_split.conf index f58d44035a7..56a405d1c59 100644 --- a/samples/bluetooth/hci_ipc/nrf5340_cpunet_bis-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_ipc/nrf5340_cpunet_bis-bt_ll_sw_split.conf @@ -10,12 +10,7 @@ CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_BT=y CONFIG_BT_HCI_RAW=y -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_EVT_RX_COUNT=16 - CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 diff --git a/samples/bluetooth/hci_ipc/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf index 8a031231c5a..89ba46ff357 100644 --- a/samples/bluetooth/hci_ipc/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_ipc/nrf5340_cpunet_bt_mesh-bt_ll_sw_split.conf @@ -10,11 +10,6 @@ CONFIG_BT=y CONFIG_BT_HCI_RAW=y CONFIG_BT_MAX_CONN=16 - -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 - # Controller CONFIG_BT_LL_SW_SPLIT=y diff --git a/samples/bluetooth/hci_ipc/nrf5340_cpunet_cis-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_cis-bt_ll_sw_split.conf index db4705c7b1e..11413bb7593 100644 --- a/samples/bluetooth/hci_ipc/nrf5340_cpunet_cis-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_ipc/nrf5340_cpunet_cis-bt_ll_sw_split.conf @@ -10,12 +10,7 @@ CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_BT=y CONFIG_BT_HCI_RAW=y -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_EVT_RX_COUNT=16 - CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 diff --git a/samples/bluetooth/hci_ipc/nrf5340_cpunet_df-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_df-bt_ll_sw_split.conf index 19adc889598..538d965c12a 100644 --- a/samples/bluetooth/hci_ipc/nrf5340_cpunet_df-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_ipc/nrf5340_cpunet_df-bt_ll_sw_split.conf @@ -10,12 +10,7 @@ CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_BT=y CONFIG_BT_HCI_RAW=y -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_EVT_RX_COUNT=16 - CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 diff --git a/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf index 6c28a4537e6..a05016b2c11 100644 --- a/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf @@ -14,12 +14,7 @@ CONFIG_LTO=y CONFIG_BT=y CONFIG_BT_HCI_RAW=y -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_EVT_RX_COUNT=16 - CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 diff --git a/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf index 0fec7c0d824..aee391a0063 100644 --- a/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_broadcast-bt_ll_sw_split.conf @@ -10,10 +10,6 @@ CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_BT=y CONFIG_BT_HCI_RAW=y -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 - # Host and Controller common dependencies CONFIG_BT_BROADCASTER=y CONFIG_BT_OBSERVER=n diff --git a/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_central-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_central-bt_ll_sw_split.conf index 58469a0309b..4e606ce9705 100644 --- a/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_central-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_central-bt_ll_sw_split.conf @@ -10,10 +10,6 @@ CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_BT=y CONFIG_BT_HCI_RAW=y -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 diff --git a/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_peripheral-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_peripheral-bt_ll_sw_split.conf index 1ff7ad685cf..712f9aaaacd 100644 --- a/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_peripheral-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_peripheral-bt_ll_sw_split.conf @@ -10,10 +10,6 @@ CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_BT=y CONFIG_BT_HCI_RAW=y -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 diff --git a/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf index 0375097d091..ed0ccb14ef7 100644 --- a/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf +++ b/samples/bluetooth/hci_ipc/nrf5340_cpunet_iso_receive-bt_ll_sw_split.conf @@ -10,10 +10,6 @@ CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_BT=y CONFIG_BT_HCI_RAW=y -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 - # Host and Controller common dependencies CONFIG_BT_BROADCASTER=n CONFIG_BT_OBSERVER=y diff --git a/samples/bluetooth/hci_ipc/prj.conf b/samples/bluetooth/hci_ipc/prj.conf index 08b1aed9e7f..f73553b47e6 100644 --- a/samples/bluetooth/hci_ipc/prj.conf +++ b/samples/bluetooth/hci_ipc/prj.conf @@ -10,11 +10,6 @@ CONFIG_BT=y CONFIG_BT_HCI_RAW=y CONFIG_BT_MAX_CONN=16 - -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 - # Enable and adjust the below value as necessary # CONFIG_BT_BUF_EVT_RX_COUNT=16 # CONFIG_BT_BUF_EVT_RX_SIZE=255 diff --git a/samples/bluetooth/hci_spi/prj.conf b/samples/bluetooth/hci_spi/prj.conf index fbab977c266..54fa4acf0c5 100644 --- a/samples/bluetooth/hci_spi/prj.conf +++ b/samples/bluetooth/hci_spi/prj.conf @@ -5,7 +5,3 @@ CONFIG_MAIN_STACK_SIZE=512 CONFIG_BT=y CONFIG_BT_HCI_RAW=y CONFIG_BT_MAX_CONN=16 - -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 diff --git a/samples/bluetooth/hci_uart/prj.conf b/samples/bluetooth/hci_uart/prj.conf index bb4a25b2886..b5b1a30fee6 100644 --- a/samples/bluetooth/hci_uart/prj.conf +++ b/samples/bluetooth/hci_uart/prj.conf @@ -16,7 +16,3 @@ CONFIG_BT_MAX_CONN=16 CONFIG_BT_CTLR_DTM_HCI=y CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 - -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 diff --git a/samples/bluetooth/hci_uart_3wire/prj.conf b/samples/bluetooth/hci_uart_3wire/prj.conf index d9a03554f9f..b8fb9fef61f 100644 --- a/samples/bluetooth/hci_uart_3wire/prj.conf +++ b/samples/bluetooth/hci_uart_3wire/prj.conf @@ -15,7 +15,3 @@ CONFIG_BT_MAX_CONN=16 CONFIG_BT_CTLR_DTM_HCI=y CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 - -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 diff --git a/samples/bluetooth/hci_usb/prj.conf b/samples/bluetooth/hci_usb/prj.conf index 0f809e424d6..7f0a2d9fe6a 100644 --- a/samples/bluetooth/hci_usb/prj.conf +++ b/samples/bluetooth/hci_usb/prj.conf @@ -11,7 +11,3 @@ CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n CONFIG_SERIAL=n CONFIG_CONSOLE=n CONFIG_UART_CONSOLE=n - -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 diff --git a/samples/bluetooth/mesh/boards/bbc_microbit.conf b/samples/bluetooth/mesh/boards/bbc_microbit.conf index 053053e7818..d71bc9400ae 100644 --- a/samples/bluetooth/mesh/boards/bbc_microbit.conf +++ b/samples/bluetooth/mesh/boards/bbc_microbit.conf @@ -13,9 +13,11 @@ CONFIG_BT_PERIPHERAL=n CONFIG_BT_EXT_ADV=n CONFIG_BT_RX_STACK_SIZE=1100 CONFIG_BT_BUF_EVT_RX_COUNT=3 -CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA=1 CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT=3 +# CONFIG_BT_BUF_ACL_TX_COUNT has to be less than CONFIG_BT_BUF_EVT_RX_COUNT +CONFIG_BT_BUF_ACL_TX_COUNT=1 + CONFIG_BT_CTLR_ADV_EXT=n CONFIG_BT_MESH_ADV_BUF_COUNT=3 diff --git a/samples/bluetooth/peripheral_hr/prj_minimal.conf b/samples/bluetooth/peripheral_hr/prj_minimal.conf index 203ab47808d..5e3f92c91cb 100644 --- a/samples/bluetooth/peripheral_hr/prj_minimal.conf +++ b/samples/bluetooth/peripheral_hr/prj_minimal.conf @@ -100,7 +100,7 @@ CONFIG_BT_CTLR_PHY_2M=n # Reduce Bluetooth buffers CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT=1 CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=45 -CONFIG_BT_BUF_EVT_RX_COUNT=2 +CONFIG_BT_BUF_EVT_RX_COUNT=4 CONFIG_BT_L2CAP_TX_BUF_COUNT=2 CONFIG_BT_CTLR_RX_BUFFERS=1 diff --git a/subsys/bluetooth/common/Kconfig b/subsys/bluetooth/common/Kconfig index a9c17ebceec..56dd33c73fe 100644 --- a/subsys/bluetooth/common/Kconfig +++ b/subsys/bluetooth/common/Kconfig @@ -78,15 +78,23 @@ config BT_BUF_ACL_RX_SIZE that the Controller will send to the Host. config BT_BUF_ACL_RX_COUNT_EXTRA - int "Number of extra incoming ACL data buffers" + # As Host implementation unconditionally references this Kconfig, we + # hide it for !BT_CONN and default to 0. + int "Number of extra incoming ACL data buffers" if BT_CONN + range 1 65535 if BT_CONN + default BT_MAX_CONN if BT_CONN + range 0 0 default 0 - range 0 65535 help Number of incoming extra ACL data buffers sent from the Controller to the Host. - By default, the number of incoming ACL data buffers is equal to - CONFIG_BT_MAX_CONN + 1. + By default, the total number of incoming ACL data buffers is equal to + CONFIG_BT_MAX_CONN + 1, to support L2CAP recombination. + + The L2CAP recombination in the Host keeps the first Rx buffer for each + connection and uses one Rx buffer across all connections to receive a + fragment from the Controller. config BT_BUF_ACL_RX_COUNT int "[DEPRECATED] Number of incoming ACL data buffers" @@ -183,12 +191,48 @@ config BT_BUF_CMD_TX_SIZE to the maximum of 255. config BT_BUF_CMD_TX_COUNT - int "Number of HCI command buffers" - default 2 - range 2 64 + # This option is only visible for a user when Host and Controller are build together, or for + # Host-only builds. + int "Number of HCI command buffers" if !BT_HCI_RAW || !HAS_BT_CTLR + # This option is present when Host and Controller are build together, or + # for Host only builds, or when Controller-to-Host ACL data flow control + # is disabled. + depends on !BT_HCI_RAW || !HAS_BT_CTLR || !BT_HCI_ACL_FLOW_CONTROL + # The Mesh stack usage in applications and tests can start both advertising and scanning in + # parallel. Also, when BT_MESH_WORKQ_SYS is enabled, the Mesh stack is starting Extended + # Advertising in the receive callback run in the system work queue and as the Host also uses + # the system work queue for HCI command Tx towards the Controller, one additional HCI + # command buffer is needed. + range 2 64 if BT_MESH + range 1 64 + default 2 if BT_MESH + default 1 help Number of buffers available for outgoing HCI commands from the Host. + HCI Controllers may not support Num_HCI_Command_Packets > 1, hence they default to 1 when + not enabling Controller to Host data flow control (BT_HCI_ACL_FLOW_CONTROL), Read Remote + Version Information (BT_REMOTE_VERSION), Auto-Initiate PHY update (BT_AUTO_PHY_UPDATE), or + Auto-Initiate Data Length Update (BT_AUTO_DATA_LEN_UPDATE). + + Normal HCI commands follow the HCI command flow control using Num_HCI_Command_Packets + return in HCI command complete and status. + + The Host Number of Completed Packets command does not follow normal flow control of HCI + commands and the Controller side HCI drivers that allocates HCI command buffers with + K_NO_WAIT can end up running out of command buffers. + + When Controller to Host data flow control is enabled in the Host-only or combined + Host plus Controller build, the internal BT_BUF_CMD_TX_COUNT is adjusted accordingly + taking into considerations the enabled auto-initiated procedures, and to follow the normal + HCI command flow control to be able to send Ncmd normal HCI commands and + BT_BUF_ACL_RX_COUNT of Host Number of Completed Packets command down to the Controller. + + When Controller to Host data flow control is supported in the Controller-only build, + the internal BT_BUF_CMD_TX_COUNT is adjusted to be equal to (BT_BUF_RX_COUNT + Ncmd). + + Where Ncmd is supported maximum Num_HCI_Command_Packets in the Controller implementation. + endmenu # Workaround to have commas on function arguments diff --git a/subsys/bluetooth/common/hci_common_internal.h b/subsys/bluetooth/common/hci_common_internal.h new file mode 100644 index 00000000000..910ea4b4af3 --- /dev/null +++ b/subsys/bluetooth/common/hci_common_internal.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if !defined(CONFIG_BT_HCI_RAW) || !defined(CONFIG_HAS_BT_CTLR) || \ + !defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) +/* Following build configurations use configurable CONFIG_BT_BUF_CMD_TX_COUNT: + * 1. Host + Controller build with and without Controller to Host data flow control, or + * 2. Host-only with and without Controller to Host data flow control, or + * 3. Controller-only without Controller to Host data flow control support + */ +#if !defined(CONFIG_BT_HCI_RAW) +/* Host + Controller build, and Host-only build */ + +/* Auto initiated additional HCI command buffers enqueued in the Host */ +#define BT_BUF_CMD_TX_REMOTE_VERSION COND_CODE_1(CONFIG_BT_REMOTE_VERSION, (1), (0)) +#define BT_BUF_CMD_TX_AUTO_PHY_UPDATE COND_CODE_1(CONFIG_BT_AUTO_PHY_UPDATE, (1), (0)) +#define BT_BUF_CMD_TX_AUTO_DATA_LEN_UPDATE COND_CODE_1(CONFIG_BT_AUTO_DATA_LEN_UPDATE, (1), (0)) + +#else /* CONFIG_BT_HCI_RAW */ +#if defined(CONFIG_HAS_BT_CTLR) +/* Controller-only build need no additional HCI command buffers */ +BUILD_ASSERT((CONFIG_BT_BUF_CMD_TX_COUNT == CONFIG_BT_CTLR_HCI_NUM_CMD_PKT_MAX), + "Mismatch in allocated HCI command buffers compared to Controller supported value."); +#endif /* CONFIG_HAS_BT_CTLR */ + +/* Controller-only build do not enqueue auto initiated HCI commands */ +#define BT_BUF_CMD_TX_REMOTE_VERSION 0 +#define BT_BUF_CMD_TX_AUTO_PHY_UPDATE 0 +#define BT_BUF_CMD_TX_AUTO_DATA_LEN_UPDATE 0 +#endif /* !CONFIG_BT_HCI_RAW */ + +#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) +/* When Controller to Host data flow control is supported in Host plus Controller build, or + * Host-only build, then we need additional BT_BUF_ACL_RX_COUNT number of HCI command buffers for + * enqueuing Host Number of Completed Packets command. + * + * Host keeps the first, and subsequent, Rx buffers (that comes from the driver) for each connection + * to do re-assembly into, up to the L2CAP SDU length required number of Rx buffers. + * BT_BUF_ACL_RX_COUNT_EXTRA holds the application configured number of buffers across active + * connections for recombination of HCI data packets to L2CAP SDUs. + * + * BT_BUF_HCI_EVT_RX_COUNT defines the number of available buffers reserved for "synchronous" + * processing of HCI events like Number of Completed Packets, disconnection complete etc. + * + * BT_BUF_HCI_ACL_RX_COUNT defines the number of available buffers for Controller to Host data + * flow control; keeping the application configured BT_BUF_ACL_RX_COUNT_EXTRA number of buffers + * available for L2CAP recombination, and a reserved number of buffers for processing HCI events. + */ + +/* FIXME: Calculate the maximum number of HCI events of different types that a connection can + * enqueue while the Host is slow at processing HCI events. + * + * 1. Disconnection Complete event + * 2. LE Connection Update Complete event + * 3. LE Long Term Key Request event + * 4. LE Remote Connection Parameter Request Event + * 5. LE Data Length Change event + * 6. LE PHY Update Complete event + * 7. ... + * + * As there is no HCI event flow control defined, implementations will need a transport level flow + * control to restrict buffers required on resource constraint devices, i.e. if these events are not + * processed "synchronous". + */ +#define BT_BUF_HCI_EVT_RX_COUNT 1 +#define BT_BUF_HCI_ACL_RX_COUNT (BT_BUF_RX_COUNT - BT_BUF_HCI_EVT_RX_COUNT - \ + BT_BUF_ACL_RX_COUNT_EXTRA) +#define BT_BUF_CMD_TX_HOST_NUM_CMPLT_PKT (BT_BUF_HCI_ACL_RX_COUNT) + +#else /* !CONFIG_BT_HCI_ACL_FLOW_CONTROL */ +#define BT_BUF_CMD_TX_HOST_NUM_CMPLT_PKT 0 +#endif /* !CONFIG_BT_HCI_ACL_FLOW_CONTROL */ + +/* Based on Host + Controller, Host-only or Controller-only; Calculate the HCI Command Tx count. */ +#define BT_BUF_CMD_TX_COUNT (CONFIG_BT_BUF_CMD_TX_COUNT + \ + BT_BUF_CMD_TX_HOST_NUM_CMPLT_PKT + \ + BT_BUF_CMD_TX_REMOTE_VERSION + \ + BT_BUF_CMD_TX_AUTO_PHY_UPDATE + \ + BT_BUF_CMD_TX_AUTO_DATA_LEN_UPDATE) + +#elif defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) +/* When Controller to Host data flow control is supported in the Controller-only build, ensure + * that BT_BUF_CMD_TX_COUNT is greater than or equal to (BT_BUF_RX_COUNT + Ncmd), + * where Ncmd is supported maximum Num_HCI_Command_Packets in the Controller implementation. + */ +BUILD_ASSERT(!IS_ENABLED(CONFIG_BT_BUF_CMD_TX_COUNT), + "Configurable HCI command buffer count disallowed."); +BUILD_ASSERT(IS_ENABLED(CONFIG_BT_CTLR_HCI_NUM_CMD_PKT_MAX), + "Undefined Controller implementation supported Num_HCI_Command_Packets value."); + +/** Can use all of buffer count needed for HCI ACL, HCI ISO or Event RX buffers for ACL RX */ +#define BT_BUF_HCI_ACL_RX_COUNT (BT_BUF_RX_COUNT) + +/* Controller-only with Controller to Host data flow control */ +#define BT_BUF_CMD_TX_COUNT (BT_BUF_RX_COUNT + CONFIG_BT_CTLR_HCI_NUM_CMD_PKT_MAX) + +#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */ diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index fd3f3d05a63..04781a76534 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -159,6 +159,16 @@ config BT_CTLR_HCI This should almost always be enabled, except in a few special cases, like for unit testing. +config BT_CTLR_HCI_NUM_CMD_PKT_MAX + # Hidden Controller implementation supported Num_HCI_Command_Packets value. + # This value will be used to calculate the total number of HCI command buffers to be + # allocated, BT_BUF_CMD_TX_COUNT, dependent on HCI Controller to Host data flow control + # being enabled. + int + depends on BT_CTLR_HCI + default 1 if BT_LL_SW_SPLIT + default 1 + if HAS_BT_CTLR comment "Bluetooth Controller configuration" diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index ba6609f7532..815a9198e95 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -21,6 +21,8 @@ #include #include +#include "common/hci_common_internal.h" + #include "util/util.h" #include "util/memq.h" #include "util/mem.h" @@ -182,13 +184,13 @@ static uint8_t sf_curr; #endif #if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) -int32_t hci_hbuf_total; -uint32_t hci_hbuf_sent; -uint32_t hci_hbuf_acked; -uint16_t hci_hbuf_pend[CONFIG_BT_MAX_CONN]; +int32_t hci_hbuf_total; +uint32_t hci_hbuf_sent; +uint32_t hci_hbuf_acked; +uint16_t hci_hbuf_pend[CONFIG_BT_MAX_CONN]; atomic_t hci_state_mask; static struct k_poll_signal *hbuf_signal; -#endif +#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */ #if defined(CONFIG_BT_CONN) static uint32_t conn_count; @@ -473,7 +475,7 @@ static void reset(struct net_buf *buf, struct net_buf **evt) atomic_set_bit(&hci_state_mask, HCI_STATE_BIT_RESET); k_poll_signal_raise(hbuf_signal, 0x0); } -#endif +#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */ hci_recv_fifo_reset(); } @@ -521,6 +523,22 @@ static void set_ctl_to_host_flow(struct net_buf *buf, struct net_buf **evt) hci_hbuf_total = -hci_hbuf_total; } +/* Host Number of Completed Packets command does not follow normal flow + * control of HCI commands and the Controller side HCI drivers that + * allocates HCI command buffers with K_NO_WAIT can end up running out + * of command buffers. + * + * Host will generate up to acl_pkts number of Host Number of Completed + * Packets command plus a number of normal HCI commands. + * + * Normal HCI commands follow the HCI command flow control using + * Num_HCI_Command_Packets return in HCI command complete and status. + * + * Note: Zephyr Controller does not support Num_HCI_Command_Packets > 1. + */ +BUILD_ASSERT(BT_BUF_HCI_ACL_RX_COUNT < BT_BUF_CMD_TX_COUNT, + "Too low HCI command buffers compare to ACL Rx buffers."); + static void host_buffer_size(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_host_buffer_size *cmd = (void *)buf->data; @@ -534,15 +552,38 @@ static void host_buffer_size(struct net_buf *buf, struct net_buf **evt) ccst->status = BT_HCI_ERR_CMD_DISALLOWED; return; } - /* fragmentation from controller to host not supported, require + + /* Fragmentation from Controller to Host not supported, require * ACL MTU to be at least the LL MTU */ if (acl_mtu < LL_LENGTH_OCTETS_RX_MAX) { + LOG_ERR("FC: Require Host ACL MTU (%u) >= LL Max Data Length (%u)", acl_mtu, + LL_LENGTH_OCTETS_RX_MAX); ccst->status = BT_HCI_ERR_INVALID_PARAM; return; } - LOG_DBG("FC: host buf size: %d", acl_pkts); + /* Host Number of Completed Packets command does not follow normal flow + * control of HCI commands and the Controller side HCI drivers that + * allocates HCI command buffers with K_NO_WAIT can end up running out + * of command buffers. + * + * Host will generate up to acl_pkts number of Host Number of Completed + * Packets command plus a number of normal HCI commands. + * + * Normal HCI commands follow the HCI command flow control using + * Num_HCI_Command_Packets return in HCI command complete and status. + * + * Note: Zephyr Controller does not support Num_HCI_Command_Packets > 1. + */ + if (acl_pkts >= BT_BUF_CMD_TX_COUNT) { + LOG_WRN("FC: Host ACL packets (%u), BT_BUF_CMD_TX_COUNT (%u)", acl_pkts, + BT_BUF_CMD_TX_COUNT); + acl_pkts = BT_BUF_CMD_TX_COUNT - CONFIG_BT_CTLR_HCI_NUM_CMD_PKT_MAX; + } + + LOG_DBG("FC: host buf size %u count %u", acl_mtu, acl_pkts); + hci_hbuf_total = -acl_pkts; } @@ -584,7 +625,7 @@ static void host_num_completed_packets(struct net_buf *buf, hci_hbuf_acked += count; k_poll_signal_raise(hbuf_signal, 0x0); } -#endif +#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */ #if defined(CONFIG_BT_CTLR_LE_PING) static void read_auth_payload_timeout(struct net_buf *buf, struct net_buf **evt) @@ -745,7 +786,7 @@ static int ctrl_bb_cmd_handle(uint16_t ocf, struct net_buf *cmd, case BT_OCF(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS): host_num_completed_packets(cmd, evt); break; -#endif +#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */ #if defined(CONFIG_BT_CTLR_LE_PING) case BT_OCF(BT_HCI_OP_READ_AUTH_PAYLOAD_TIMEOUT): @@ -9119,7 +9160,7 @@ void hci_acl_encode(struct node_rx_pdu *node_rx, struct net_buf *buf) LL_ASSERT(handle < ARRAY_SIZE(hci_hbuf_pend)); hci_hbuf_pend[handle]++; } -#endif +#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */ break; default: @@ -9325,6 +9366,7 @@ void hci_init(struct k_poll_signal *signal_host_buf) { #if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) hbuf_signal = signal_host_buf; -#endif +#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */ + reset(NULL, NULL); } diff --git a/subsys/bluetooth/host/buf.c b/subsys/bluetooth/host/buf.c index 75bd15834ae..00d0f162693 100644 --- a/subsys/bluetooth/host/buf.c +++ b/subsys/bluetooth/host/buf.c @@ -5,16 +5,17 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include +#include "common/hci_common_internal.h" + #include "buf_view.h" #include "hci_core.h" #include "conn_internal.h" #include "iso_internal.h" -#include - #include LOG_MODULE_REGISTER(bt_buf, CONFIG_BT_LOG_LEVEL); @@ -72,8 +73,9 @@ static void evt_pool_destroy(struct net_buf *buf) buf_rx_freed_notify(BT_BUF_EVT); } -NET_BUF_POOL_DEFINE(acl_in_pool, BT_BUF_ACL_RX_COUNT, BT_BUF_ACL_SIZE(CONFIG_BT_BUF_ACL_RX_SIZE), - sizeof(struct acl_data), acl_in_pool_destroy); +NET_BUF_POOL_DEFINE(acl_in_pool, (BT_BUF_ACL_RX_COUNT_EXTRA + BT_BUF_HCI_ACL_RX_COUNT), + BT_BUF_ACL_SIZE(CONFIG_BT_BUF_ACL_RX_SIZE), sizeof(struct acl_data), + acl_in_pool_destroy); NET_BUF_POOL_FIXED_DEFINE(evt_pool, CONFIG_BT_BUF_EVT_RX_COUNT, BT_BUF_EVT_RX_SIZE, sizeof(struct bt_buf_data), evt_pool_destroy); diff --git a/subsys/bluetooth/host/hci_common.c b/subsys/bluetooth/host/hci_common.c index 1f382075d05..bae131e759d 100644 --- a/subsys/bluetooth/host/hci_common.c +++ b/subsys/bluetooth/host/hci_common.c @@ -33,7 +33,17 @@ struct net_buf *bt_hci_cmd_complete_create(uint16_t op, uint8_t plen) buf = bt_hci_evt_create(BT_HCI_EVT_CMD_COMPLETE, sizeof(*cc) + plen); cc = net_buf_add(buf, sizeof(*cc)); + + /* The Num_HCI_Command_Packets parameter allows the Controller to + * indicate the number of HCI command packets the Host can send to the + * Controller. If the Controller requires the Host to stop sending + * commands, Num_HCI_Command_Packets will be set to zero. + * + * NOTE: Zephyr Controller (and may be other Controllers) do not support + * higher Number of HCI Command packets than 1. + */ cc->ncmd = 1U; + cc->opcode = sys_cpu_to_le16(op); return buf; @@ -48,7 +58,17 @@ struct net_buf *bt_hci_cmd_status_create(uint16_t op, uint8_t status) cs = net_buf_add(buf, sizeof(*cs)); cs->status = status; + + /* The Num_HCI_Command_Packets parameter allows the Controller to + * indicate the number of HCI command packets the Host can send to the + * Controller. If the Controller requires the Host to stop sending + * commands, Num_HCI_Command_Packets will be set to zero. + * + * NOTE: Zephyr Controller (and may be other Controllers) do not support + * higher Number of HCI Command packets than 1. + */ cs->ncmd = 1U; + cs->opcode = sys_cpu_to_le16(op); return buf; diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index b01c49d3243..c91f867bf87 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -33,10 +33,11 @@ #include #include +#include "common/hci_common_internal.h" #include "common/bt_str.h" +#include "common/rpa.h" #include "common/assert.h" -#include "common/rpa.h" #include "keys.h" #include "monitor.h" #include "hci_core.h" @@ -126,7 +127,7 @@ struct cmd_data { struct k_sem *sync; }; -static struct cmd_data cmd_data[CONFIG_BT_BUF_CMD_TX_COUNT]; +static struct cmd_data cmd_data[BT_BUF_CMD_TX_COUNT]; #define cmd(buf) (&cmd_data[net_buf_id(buf)]) #define acl(buf) ((struct acl_data *)net_buf_user_data(buf)) @@ -156,7 +157,7 @@ void bt_hci_cmd_state_set_init(struct net_buf *buf, * command complete or command status. */ #define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE) -NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT, +NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, BT_BUF_CMD_TX_COUNT, CMD_BUF_SIZE, sizeof(struct bt_buf_data), NULL); struct event_handler { @@ -2001,7 +2002,7 @@ static int set_flow_control(void) hbs = net_buf_add(buf, sizeof(*hbs)); (void)memset(hbs, 0, sizeof(*hbs)); hbs->acl_mtu = sys_cpu_to_le16(CONFIG_BT_BUF_ACL_RX_SIZE); - hbs->acl_pkts = sys_cpu_to_le16(BT_BUF_ACL_RX_COUNT); + hbs->acl_pkts = sys_cpu_to_le16(BT_BUF_HCI_ACL_RX_COUNT); err = bt_hci_cmd_send_sync(BT_HCI_OP_HOST_BUFFER_SIZE, buf, NULL); if (err) { diff --git a/subsys/bluetooth/host/hci_raw.c b/subsys/bluetooth/host/hci_raw.c index 3e913151156..aa885e1ac8b 100644 --- a/subsys/bluetooth/host/hci_raw.c +++ b/subsys/bluetooth/host/hci_raw.c @@ -19,6 +19,8 @@ #include +#include "common/hci_common_internal.h" + #include "monitor.h" #include "hci_raw_internal.h" @@ -48,7 +50,7 @@ static void hci_rx_buf_destroy(struct net_buf *buf) NET_BUF_POOL_FIXED_DEFINE(hci_rx_pool, BT_BUF_RX_COUNT, BT_BUF_RX_SIZE, sizeof(struct bt_buf_data), hci_rx_buf_destroy); -NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT, +NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, BT_BUF_CMD_TX_COUNT, BT_BUF_CMD_SIZE(CONFIG_BT_BUF_CMD_TX_SIZE), sizeof(struct bt_buf_data), NULL); NET_BUF_POOL_FIXED_DEFINE(hci_acl_pool, CONFIG_BT_BUF_ACL_TX_COUNT, diff --git a/tests/bluetooth/hci_codecs_info/src/main.c b/tests/bluetooth/hci_codecs_info/src/main.c index 8f63e3782a8..1d2937a21e7 100644 --- a/tests/bluetooth/hci_codecs_info/src/main.c +++ b/tests/bluetooth/hci_codecs_info/src/main.c @@ -208,6 +208,8 @@ ZTEST(test_hci_codecs_info, test_read_codec_capabilities) ptr = &rp->capabilities[0]; zassert_mem_equal(ptr, codec_capabilities, sizeof(codec_capabilities), 0, "Reading codec capabilities content failed"); + + net_buf_unref(rsp); } #define READ_DELAY_CODING_FMT 0xff @@ -290,4 +292,6 @@ ZTEST(test_hci_codecs_info, test_read_ctlr_delay) "Reading controller min delay failed"); zassert_equal(sys_get_le24(rp->max_ctlr_delay), MAX_CTLR_DELAY, "Reading controller max delay failed"); + + net_buf_unref(rsp); } diff --git a/tests/bsim/bluetooth/host/att/pipeline/tester/prj.conf b/tests/bsim/bluetooth/host/att/pipeline/tester/prj.conf index a5ca6cf0f62..16c2caa091c 100644 --- a/tests/bsim/bluetooth/host/att/pipeline/tester/prj.conf +++ b/tests/bsim/bluetooth/host/att/pipeline/tester/prj.conf @@ -5,11 +5,9 @@ CONFIG_BT=y CONFIG_BT_HCI_RAW=y CONFIG_BT_MAX_CONN=1 -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_ACL_TX_COUNT=20 +CONFIG_BT_BUF_EVT_RX_COUNT=21 -CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_CMD_TX_SIZE=255 CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 diff --git a/tests/bsim/bluetooth/host/att/pipeline/tester/src/main.c b/tests/bsim/bluetooth/host/att/pipeline/tester/src/main.c index 3f49e7e43cd..ad2cfee2f46 100644 --- a/tests/bsim/bluetooth/host/att/pipeline/tester/src/main.c +++ b/tests/bsim/bluetooth/host/att/pipeline/tester/src/main.c @@ -16,6 +16,7 @@ #include #include +#include "common/hci_common_internal.h" #include "common/bt_str.h" #include "host/conn_internal.h" @@ -55,7 +56,7 @@ static att_handler_t att_handlers[LAST_SUPPORTED_ATT_OPCODE]; static K_FIFO_DEFINE(rx_queue); #define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE) -NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT, +NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, BT_BUF_CMD_TX_COUNT, CMD_BUF_SIZE, 8, NULL); static K_SEM_DEFINE(cmd_sem, 1, 1); diff --git a/tests/bsim/bluetooth/host/att/sequential/tester/prj.conf b/tests/bsim/bluetooth/host/att/sequential/tester/prj.conf index 5217040a117..e8ba462aeea 100644 --- a/tests/bsim/bluetooth/host/att/sequential/tester/prj.conf +++ b/tests/bsim/bluetooth/host/att/sequential/tester/prj.conf @@ -5,8 +5,6 @@ CONFIG_BT=y CONFIG_BT_HCI_RAW=y CONFIG_BT_MAX_CONN=1 -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_CMD_TX_SIZE=255 CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 diff --git a/tests/bsim/bluetooth/host/att/sequential/tester/src/main.c b/tests/bsim/bluetooth/host/att/sequential/tester/src/main.c index 4cd981d615b..fc3477072c1 100644 --- a/tests/bsim/bluetooth/host/att/sequential/tester/src/main.c +++ b/tests/bsim/bluetooth/host/att/sequential/tester/src/main.c @@ -16,6 +16,7 @@ #include #include +#include "common/hci_common_internal.h" #include "common/bt_str.h" #include "host/conn_internal.h" @@ -50,7 +51,7 @@ static uint16_t server_write_handle; static K_FIFO_DEFINE(rx_queue); #define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE) -NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT, +NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, BT_BUF_CMD_TX_COUNT, CMD_BUF_SIZE, 8, NULL); static K_SEM_DEFINE(cmd_sem, 1, 1); diff --git a/tests/bsim/bluetooth/host/central/src/main.c b/tests/bsim/bluetooth/host/central/src/main.c index 4969a9bb437..dd12fd91a5b 100644 --- a/tests/bsim/bluetooth/host/central/src/main.c +++ b/tests/bsim/bluetooth/host/central/src/main.c @@ -9,6 +9,9 @@ #include #include +/* Include hci_common_internal for the purpose of checking HCI Command counts. */ +#include "common/hci_common_internal.h" + /* Include conn_internal for the purpose of checking reference counts. */ #include "host/conn_internal.h" @@ -63,7 +66,7 @@ static void test_central_connect_timeout_with_timeout(uint32_t timeout_ms, bool .window_coded = 0, .timeout = timeout_ms / 10, }; - struct net_buf *bufs[CONFIG_BT_BUF_CMD_TX_COUNT]; + struct net_buf *bufs[BT_BUF_CMD_TX_COUNT]; k_sem_reset(&sem_failed_to_connect); @@ -74,7 +77,7 @@ static void test_central_connect_timeout_with_timeout(uint32_t timeout_ms, bool if (stack_load) { /* Claim all the buffers so that the stack cannot handle the timeout */ - for (int i = 0; i < CONFIG_BT_BUF_CMD_TX_COUNT; i++) { + for (int i = 0; i < BT_BUF_CMD_TX_COUNT; i++) { bufs[i] = bt_hci_cmd_create(BT_HCI_LE_ADV_ENABLE, 0); TEST_ASSERT(bufs[i] != NULL, "Failed to claim all command buffers"); } @@ -82,7 +85,7 @@ static void test_central_connect_timeout_with_timeout(uint32_t timeout_ms, bool err = k_sem_take(&sem_failed_to_connect, K_MSEC(expected_conn_timeout_ms + 50)); TEST_ASSERT(err == -EAGAIN, "Callback ran with no buffers available", err); /* Release all the buffers back to the stack */ - for (int i = 0; i < CONFIG_BT_BUF_CMD_TX_COUNT; i++) { + for (int i = 0; i < BT_BUF_CMD_TX_COUNT; i++) { net_buf_unref(bufs[i]); } } diff --git a/tests/bsim/bluetooth/host/l2cap/reassembly/dut/prj.conf b/tests/bsim/bluetooth/host/l2cap/reassembly/dut/prj.conf index d913264f700..0ec3db7fd21 100644 --- a/tests/bsim/bluetooth/host/l2cap/reassembly/dut/prj.conf +++ b/tests/bsim/bluetooth/host/l2cap/reassembly/dut/prj.conf @@ -24,9 +24,28 @@ CONFIG_BT_AUTO_PHY_UPDATE=n CONFIG_BT_AUTO_DATA_LEN_UPDATE=n CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n +# HCI Controller to Host data flow control across active connections +CONFIG_BT_MAX_CONN=1 + # Since the test's purpose is to test for leaks in the ACL # RX buffer pool, it is a good idea to constrain said buffer # pool. -CONFIG_BT_MAX_CONN=1 -CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA=4 -CONFIG_BT_BUF_EVT_RX_COUNT=6 + +# Simultaneous connection receiving one Rx buffer each plus one additional for +# L2CAP recombination, if any, across these active connections. +CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA=1 + +# Minimum EVT Rx buffers permitting reception of events (Number of Completed Packets or +# disconnection complete etc.) while ACL RX buffers are busy +CONFIG_BT_BUF_EVT_RX_COUNT=4 + +# Minimum ACL TX buffers to ensure continuous transmission without skipping connection intervals +CONFIG_BT_BUF_ACL_TX_COUNT=3 + +# Minimum HCI Command TX buffers +CONFIG_BT_BUF_CMD_TX_COUNT=1 + +# If we don't define this, it will inherit +# CONFIG_BT_BUF_ACL_TX_COUNT and fail a build assert that +# expects >= 3. +CONFIG_BT_L2CAP_TX_BUF_COUNT=3 diff --git a/tests/bsim/bluetooth/host/l2cap/reassembly/peer/prj.conf b/tests/bsim/bluetooth/host/l2cap/reassembly/peer/prj.conf index b9f5e34727b..f3493edb4ef 100644 --- a/tests/bsim/bluetooth/host/l2cap/reassembly/peer/prj.conf +++ b/tests/bsim/bluetooth/host/l2cap/reassembly/peer/prj.conf @@ -3,17 +3,18 @@ CONFIG_ASSERT=y CONFIG_BT=y CONFIG_BT_HCI_RAW=y + CONFIG_BT_MAX_CONN=1 -CONFIG_BT_BUF_CMD_TX_COUNT=10 CONFIG_BT_BUF_ACL_TX_COUNT=20 +CONFIG_BT_BUF_EVT_RX_COUNT=21 -CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_CMD_TX_SIZE=255 CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 # Allow whole L2CAP PDUs to fit on-air CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_BUF_ACL_RX_SIZE=251 + CONFIG_BT_DATA_LEN_UPDATE=y CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 diff --git a/tests/bsim/bluetooth/host/l2cap/reassembly/peer/src/peer.c b/tests/bsim/bluetooth/host/l2cap/reassembly/peer/src/peer.c index dd9d0e77fb8..9311802658c 100644 --- a/tests/bsim/bluetooth/host/l2cap/reassembly/peer/src/peer.c +++ b/tests/bsim/bluetooth/host/l2cap/reassembly/peer/src/peer.c @@ -16,6 +16,7 @@ #include #include +#include "common/hci_common_internal.h" #include "common/bt_str.h" #include "host/conn_internal.h" @@ -45,7 +46,7 @@ DEFINE_FLAG(is_connected); static K_FIFO_DEFINE(rx_queue); #define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE) -NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT, +NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, BT_BUF_CMD_TX_COUNT, CMD_BUF_SIZE, 8, NULL); #define MAX_CMD_COUNT 1 diff --git a/tests/bsim/bluetooth/host/l2cap/split/tester/prj.conf b/tests/bsim/bluetooth/host/l2cap/split/tester/prj.conf index be8487976cc..068f8c0c064 100644 --- a/tests/bsim/bluetooth/host/l2cap/split/tester/prj.conf +++ b/tests/bsim/bluetooth/host/l2cap/split/tester/prj.conf @@ -5,8 +5,6 @@ CONFIG_BT=y CONFIG_BT_HCI_RAW=y CONFIG_BT_MAX_CONN=1 -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_CMD_TX_SIZE=255 CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 diff --git a/tests/bsim/bluetooth/host/l2cap/split/tester/src/main.c b/tests/bsim/bluetooth/host/l2cap/split/tester/src/main.c index af3467948bc..1f53f254adf 100644 --- a/tests/bsim/bluetooth/host/l2cap/split/tester/src/main.c +++ b/tests/bsim/bluetooth/host/l2cap/split/tester/src/main.c @@ -16,6 +16,7 @@ #include #include +#include "common/hci_common_internal.h" #include "common/bt_str.h" #include "host/conn_internal.h" @@ -36,7 +37,7 @@ DEFINE_FLAG_STATIC(flag_data_length_updated); static K_FIFO_DEFINE(rx_queue); #define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE) -NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT, +NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, BT_BUF_CMD_TX_COUNT, CMD_BUF_SIZE, 8, NULL); static K_SEM_DEFINE(cmd_sem, 1, 1); diff --git a/tests/bsim/bluetooth/host/misc/disconnect/tester/prj.conf b/tests/bsim/bluetooth/host/misc/disconnect/tester/prj.conf index 5217040a117..e8ba462aeea 100644 --- a/tests/bsim/bluetooth/host/misc/disconnect/tester/prj.conf +++ b/tests/bsim/bluetooth/host/misc/disconnect/tester/prj.conf @@ -5,8 +5,6 @@ CONFIG_BT=y CONFIG_BT_HCI_RAW=y CONFIG_BT_MAX_CONN=1 -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_CMD_TX_SIZE=255 CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 diff --git a/tests/bsim/bluetooth/host/misc/disconnect/tester/src/main.c b/tests/bsim/bluetooth/host/misc/disconnect/tester/src/main.c index 48923faa980..f21a0b1ad9b 100644 --- a/tests/bsim/bluetooth/host/misc/disconnect/tester/src/main.c +++ b/tests/bsim/bluetooth/host/misc/disconnect/tester/src/main.c @@ -16,6 +16,7 @@ #include #include +#include "common/hci_common_internal.h" #include "common/bt_str.h" #include "host/conn_internal.h" @@ -47,7 +48,7 @@ DEFINE_FLAG_STATIC(flag_data_length_updated); static K_FIFO_DEFINE(rx_queue); #define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE) -NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT, +NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, BT_BUF_CMD_TX_COUNT, CMD_BUF_SIZE, 8, NULL); static K_SEM_DEFINE(cmd_sem, 1, 1); diff --git a/tests/bsim/bluetooth/host/misc/hfc/prj.conf b/tests/bsim/bluetooth/host/misc/hfc/prj.conf index ee754878191..d8854bb3c69 100644 --- a/tests/bsim/bluetooth/host/misc/hfc/prj.conf +++ b/tests/bsim/bluetooth/host/misc/hfc/prj.conf @@ -16,7 +16,23 @@ CONFIG_ASSERT=y CONFIG_BT_TESTING=y CONFIG_LOG=y -CONFIG_BT_MAX_CONN=3 +# HCI Controller to Host data flow control across active connections +CONFIG_BT_MAX_CONN=1 + +# Simultaneous connection receiving one Rx buffer each plus one additional for +# L2CAP recombination, if any, across these active connections. +CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA=1 + +# Minimum EVT Rx buffers permitting reception of events (Number of Completed Packets or +# disconnection complete etc.) while ACL RX buffers are busy +CONFIG_BT_BUF_EVT_RX_COUNT=4 + +# Minimum ACL TX buffers to ensure continuous transmission without skipping connection intervals +CONFIG_BT_BUF_ACL_TX_COUNT=3 + +# Minimum HCI Command TX buffers +CONFIG_BT_BUF_CMD_TX_COUNT=1 + CONFIG_ARCH_POSIX_TRAP_ON_FATAL=y # CONFIG_BT_CONN_LOG_LEVEL_DBG=y diff --git a/tests/bsim/bluetooth/host/misc/hfc/src/main.c b/tests/bsim/bluetooth/host/misc/hfc/src/main.c index 1cb5f32091b..47ce23dbcf4 100644 --- a/tests/bsim/bluetooth/host/misc/hfc/src/main.c +++ b/tests/bsim/bluetooth/host/misc/hfc/src/main.c @@ -376,10 +376,11 @@ static void entrypoint_peer(void) tx = 0; while (true) { + UNSET_FLAG(is_subscribed); + conn = connect_as_peripheral(); LOG_INF("wait until DUT subscribes"); - UNSET_FLAG(is_subscribed); WAIT_FOR_FLAG(is_subscribed); LOG_INF("send notifications"); diff --git a/tests/bsim/bluetooth/host/misc/hfc_multilink/tester/prj.conf b/tests/bsim/bluetooth/host/misc/hfc_multilink/tester/prj.conf index a4d8875e92c..44e2b46cb1d 100644 --- a/tests/bsim/bluetooth/host/misc/hfc_multilink/tester/prj.conf +++ b/tests/bsim/bluetooth/host/misc/hfc_multilink/tester/prj.conf @@ -5,8 +5,6 @@ CONFIG_BT=y CONFIG_BT_HCI_RAW=y CONFIG_BT_MAX_CONN=1 -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_CMD_TX_SIZE=255 CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 diff --git a/tests/bsim/bluetooth/host/misc/hfc_multilink/tester/src/tester.c b/tests/bsim/bluetooth/host/misc/hfc_multilink/tester/src/tester.c index b5054cfdc3f..9e7f4c19d00 100644 --- a/tests/bsim/bluetooth/host/misc/hfc_multilink/tester/src/tester.c +++ b/tests/bsim/bluetooth/host/misc/hfc_multilink/tester/src/tester.c @@ -17,6 +17,7 @@ #include #include +#include "common/hci_common_internal.h" #include "common/bt_str.h" #include "host/conn_internal.h" @@ -38,7 +39,7 @@ DEFINE_FLAG(flag_l2cap_connected); static K_FIFO_DEFINE(rx_queue); #define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE) -NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT, CMD_BUF_SIZE, 8, NULL); +NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, BT_BUF_CMD_TX_COUNT, CMD_BUF_SIZE, 8, NULL); static K_SEM_DEFINE(cmd_sem, 1, 1); static struct k_sem acl_pkts; diff --git a/tests/bsim/bluetooth/ll/cis/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf b/tests/bsim/bluetooth/ll/cis/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf index c43da5523ff..7ccec95bcee 100644 --- a/tests/bsim/bluetooth/ll/cis/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf +++ b/tests/bsim/bluetooth/ll/cis/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf @@ -15,12 +15,7 @@ CONFIG_BT_CENTRAL=y CONFIG_BT_HCI_RAW=y CONFIG_BT_MAX_CONN=4 -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 - CONFIG_BT_BUF_EVT_RX_COUNT=16 - CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 diff --git a/tests/bsim/bluetooth/ll/throughput/prj.conf b/tests/bsim/bluetooth/ll/throughput/prj.conf index d0356a37234..e8848bbf25d 100644 --- a/tests/bsim/bluetooth/ll/throughput/prj.conf +++ b/tests/bsim/bluetooth/ll/throughput/prj.conf @@ -36,7 +36,7 @@ CONFIG_BT_BUF_ACL_TX_COUNT=3 CONFIG_BT_BUF_ACL_TX_SIZE=251 # BT HCI ACL RX Data Buffers -CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA=0 +CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA=1 CONFIG_BT_BUF_ACL_RX_SIZE=255 # Maximum LL ACL PDU length