Bluetooth: Kconfig: Introduce BLUETOOTH_COMBINED_RX_BUF option

If the controller doesn't need ACL host flow control it may want to
optimize and use a single pool for incoming data.

Change-Id: Iec2a69bd2d7a127c7329d0423ab5ce6b73cb9904
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2016-12-21 17:49:39 +02:00
commit 57de98daf6
4 changed files with 92 additions and 11 deletions

View file

@ -47,6 +47,12 @@ enum bt_buf_type {
/** Minimum amount of user data size for buffers passed to the stack. */ /** Minimum amount of user data size for buffers passed to the stack. */
#define BT_BUF_USER_DATA_MIN 4 #define BT_BUF_USER_DATA_MIN 4
#if defined(CONFIG_BLUETOOTH_COMBINED_RX_BUF)
/** Data size neeed for HCI RX buffers */
#define BT_BUF_RX_SIZE (CONFIG_BLUETOOTH_HCI_RECV_RESERVE + \
sizeof(struct bt_hci_acl_hdr) + \
CONFIG_BLUETOOTH_RX_BUF_LEN)
#else
/** Data size neeed for HCI event buffers */ /** Data size neeed for HCI event buffers */
#define BT_BUF_EVT_SIZE (CONFIG_BLUETOOTH_HCI_RECV_RESERVE + \ #define BT_BUF_EVT_SIZE (CONFIG_BLUETOOTH_HCI_RECV_RESERVE + \
sizeof(struct bt_hci_evt_hdr) + \ sizeof(struct bt_hci_evt_hdr) + \
@ -57,6 +63,7 @@ enum bt_buf_type {
sizeof(struct bt_hci_acl_hdr) + \ sizeof(struct bt_hci_acl_hdr) + \
4 /* L2CAP header size */ + \ 4 /* L2CAP header size */ + \
CONFIG_BLUETOOTH_L2CAP_IN_MTU) CONFIG_BLUETOOTH_L2CAP_IN_MTU)
#endif
/** Allocate a buffer for an HCI event /** Allocate a buffer for an HCI event
* *

View file

@ -44,6 +44,11 @@ config BLUETOOTH_HCI_HOST
select TINYCRYPT_SHA256_HMAC select TINYCRYPT_SHA256_HMAC
select TINYCRYPT_SHA256_HMAC_PRNG select TINYCRYPT_SHA256_HMAC_PRNG
config BLUETOOTH_COMBINED_RX_BUF
# Virtual option usually set by the controller to request a
# combined pool for incoming buffers.
bool
config BLUETOOTH_HCI_CMD_COUNT config BLUETOOTH_HCI_CMD_COUNT
int "Number of HCI command buffers" int "Number of HCI command buffers"
default 2 default 2
@ -60,6 +65,13 @@ config BLUETOOTH_MAX_CMD_LEN
help help
Maximum length of each HCI command. Maximum length of each HCI command.
if !BLUETOOTH_COMBINED_RX_BUF
config BLUETOOTH_HOST_FLOW_CONTROL
# Virtual option usually set by the HCI driver to state that ACL
# host flow control is needed.
bool
depends on BLUETOOTH_CONN
config BLUETOOTH_HCI_EVT_COUNT config BLUETOOTH_HCI_EVT_COUNT
int "Number of HCI event buffers" int "Number of HCI event buffers"
default 4 default 4
@ -81,6 +93,25 @@ config BLUETOOTH_MAX_EVT_LEN
for LE is the Command Complete for Read Local Supported for LE is the Command Complete for Read Local Supported
Commands. It is a 3 byte Command Complete header + 65 byte Commands. It is a 3 byte Command Complete header + 65 byte
return parameters = 68 bytes in total. return parameters = 68 bytes in total.
endif # !BLUETOOTH_COMBINED_RX_BUF
if BLUETOOTH_COMBINED_RX_BUF
config BLUETOOTH_RX_BUF_COUNT
int "Number of HCI RX buffers"
default 1
range 1 255
help
Number of buffers available for incoming ACL packets or HCI events
from the controller.
config BLUETOOTH_RX_BUF_LEN
int "Maximum supported HCI RX buffer length"
default 70
default 253 if BLUETOOTH_BREDR
range 70 2000
help
Maximum data size for each HCI RX buffer.
endif # BLUETOOTH_COMBINED_RX_BUF
config BLUETOOTH_UART_TO_HOST_DEV_NAME config BLUETOOTH_UART_TO_HOST_DEV_NAME
string "Device Name of UART Device to an external Bluetooth Host" string "Device Name of UART Device to an external Bluetooth Host"
@ -91,7 +122,7 @@ config BLUETOOTH_UART_TO_HOST_DEV_NAME
to connect to an external Bluetooth Host when Zephyr is to connect to an external Bluetooth Host when Zephyr is
acting as a Bluetooth Controller. acting as a Bluetooth Controller.
if BLUETOOTH_CONN || BLUETOOTH_HCI_RAW if !BLUETOOTH_COMBINED_RX_BUF && (BLUETOOTH_CONN || BLUETOOTH_HCI_RAW)
config BLUETOOTH_ACL_IN_COUNT config BLUETOOTH_ACL_IN_COUNT
int "Number of incoming ACL data buffers" int "Number of incoming ACL data buffers"
default 6 default 6
@ -109,7 +140,7 @@ config BLUETOOTH_L2CAP_IN_MTU
range 65 1300 if BLUETOOTH_SMP range 65 1300 if BLUETOOTH_SMP
help help
Maximum size of each incoming L2CAP PDU. Maximum size of each incoming L2CAP PDU.
endif # BLUETOOTH_CONN || BLUETOOTH_HCI_RAW endif # !BLUETOOTH_COMBINED_RX_BUF && (BLUETOOTH_CONN || BLUETOOTH_HCI_RAW)
if BLUETOOTH_HCI_HOST if BLUETOOTH_HCI_HOST
config BLUETOOTH_INTERNAL_STORAGE config BLUETOOTH_INTERNAL_STORAGE
@ -154,7 +185,8 @@ config BLUETOOTH_ATT_MTU
default 23 default 23
default 50 if BLUETOOTH_SMP # BLUETOOTH_L2CAP_IN_MTU is big enough default 50 if BLUETOOTH_SMP # BLUETOOTH_L2CAP_IN_MTU is big enough
# for two complete ACL packets # for two complete ACL packets
range 23 BLUETOOTH_L2CAP_IN_MTU range 23 BLUETOOTH_L2CAP_IN_MTU if !BLUETOOTH_COMBINED_RX_BUF
range 23 BLUETOOTH_RX_BUF_LEN if BLUETOOTH_COMBINED_RX_BUF
help help
The MTU for the ATT channel. The minimum and default is 23, The MTU for the ATT channel. The minimum and default is 23,
whereas the maximum is limited by CONFIG_BLUETOOTH_L2CAP_IN_MTU. whereas the maximum is limited by CONFIG_BLUETOOTH_L2CAP_IN_MTU.
@ -458,9 +490,11 @@ config BLUETOOTH_RFCOMM
config BLUETOOTH_RFCOMM_L2CAP_MTU config BLUETOOTH_RFCOMM_L2CAP_MTU
int "L2CAP MTU for RFCOMM frames" int "L2CAP MTU for RFCOMM frames"
default BLUETOOTH_L2CAP_IN_MTU default BLUETOOTH_L2CAP_IN_MTU if !BLUETOOTH_COMBINED_RX_BUF
default BLUETOOTH_RX_BUF_LEN if BLUETOOTH_COMBINED_RX_BUF
depends on BLUETOOTH_RFCOMM depends on BLUETOOTH_RFCOMM
range BLUETOOTH_L2CAP_IN_MTU 32767 range BLUETOOTH_L2CAP_IN_MTU 32767 if !BLUETOOTH_COMBINED_RX_BUF
range BLUETOOTH_RX_BUF_LEN 32767 if BLUETOOTH_COMBINED_RX_BUF
help help
Maximum size of L2CAP PDU for RFCOMM frames. Maximum size of L2CAP PDU for RFCOMM frames.

View file

@ -122,9 +122,15 @@ struct acl_data {
NET_BUF_POOL_DEFINE(hci_cmd_pool, CONFIG_BLUETOOTH_HCI_CMD_COUNT, NET_BUF_POOL_DEFINE(hci_cmd_pool, CONFIG_BLUETOOTH_HCI_CMD_COUNT,
CMD_BUF_SIZE, sizeof(struct cmd_data), NULL); CMD_BUF_SIZE, sizeof(struct cmd_data), NULL);
#if defined(CONFIG_BLUETOOTH_COMBINED_RX_BUF)
NET_BUF_POOL_DEFINE(hci_rx_pool, CONFIG_BLUETOOTH_RX_BUF_COUNT,
BT_BUF_RX_SIZE, BT_BUF_USER_DATA_MIN, NULL);
#else
/* HCI event buffers */ /* HCI event buffers */
NET_BUF_POOL_DEFINE(hci_evt_pool, CONFIG_BLUETOOTH_HCI_EVT_COUNT, NET_BUF_POOL_DEFINE(hci_evt_pool, CONFIG_BLUETOOTH_HCI_EVT_COUNT,
BT_BUF_EVT_SIZE, BT_BUF_USER_DATA_MIN, NULL); BT_BUF_EVT_SIZE, BT_BUF_USER_DATA_MIN, NULL);
#endif
/* /*
* This priority pool is to handle HCI events that must not be dropped * This priority pool is to handle HCI events that must not be dropped
* (currently this is Command Status, Command Complete and Number of * (currently this is Command Status, Command Complete and Number of
@ -133,17 +139,23 @@ NET_BUF_POOL_DEFINE(hci_evt_pool, CONFIG_BLUETOOTH_HCI_EVT_COUNT,
* the HCI ECC emulation is able to also allocate command status events * the HCI ECC emulation is able to also allocate command status events
* we need to reserve one extra buffer for it. * we need to reserve one extra buffer for it.
*/ */
/* The worst case event length, Read Local Supported Commands Complete:
* 2 (HCI evt hdr) + 3 (cmd complete hdr) + 65 (parameters) = 70.
*/
#define PRIO_EVT_SIZE (CONFIG_BLUETOOTH_HCI_RECV_RESERVE + 70)
#if defined(CONFIG_BLUETOOTH_TINYCRYPT_ECC) #if defined(CONFIG_BLUETOOTH_TINYCRYPT_ECC)
NET_BUF_POOL_DEFINE(hci_evt_prio_pool, 2, BT_BUF_EVT_SIZE, NET_BUF_POOL_DEFINE(hci_evt_prio_pool, 2, PRIO_EVT_SIZE,
BT_BUF_USER_DATA_MIN, NULL); BT_BUF_USER_DATA_MIN, NULL);
#else #else
NET_BUF_POOL_DEFINE(hci_evt_prio_pool, 1, BT_BUF_EVT_SIZE, NET_BUF_POOL_DEFINE(hci_evt_prio_pool, 1, PRIO_EVT_SIZE,
BT_BUF_USER_DATA_MIN, NULL); BT_BUF_USER_DATA_MIN, NULL);
#endif #endif
static struct tc_hmac_prng_struct prng; static struct tc_hmac_prng_struct prng;
#if defined(CONFIG_BLUETOOTH_CONN) #if defined(CONFIG_BLUETOOTH_HOST_FLOW_CONTROL)
static void report_completed_packet(struct net_buf *buf) static void report_completed_packet(struct net_buf *buf)
{ {
@ -180,7 +192,12 @@ static void report_completed_packet(struct net_buf *buf)
NET_BUF_POOL_DEFINE(acl_in_pool, CONFIG_BLUETOOTH_ACL_IN_COUNT, NET_BUF_POOL_DEFINE(acl_in_pool, CONFIG_BLUETOOTH_ACL_IN_COUNT,
BT_BUF_ACL_IN_SIZE, sizeof(struct acl_data), BT_BUF_ACL_IN_SIZE, sizeof(struct acl_data),
report_completed_packet); report_completed_packet);
#endif /* CONFIG_BLUETOOTH_CONN */ #elif !defined(CONFIG_BLUETOOTH_COMBINED_RX_BUF) && \
defined(CONFIG_BLUETOOTH_CONN)
NET_BUF_POOL_DEFINE(acl_in_pool, CONFIG_BLUETOOTH_ACL_IN_COUNT,
BT_BUF_ACL_IN_SIZE, sizeof(struct acl_data),
NULL);
#endif
#if defined(CONFIG_BLUETOOTH_DEBUG) #if defined(CONFIG_BLUETOOTH_DEBUG)
const char *bt_addr_str(const bt_addr_t *addr) const char *bt_addr_str(const bt_addr_t *addr)
@ -1009,7 +1026,9 @@ failed:
bt_conn_unref(conn); bt_conn_unref(conn);
bt_le_scan_update(false); bt_le_scan_update(false);
} }
#endif /* CONFIG_BLUETOOTH_CONN */
#if defined(CONFIG_BLUETOOTH_HOST_FLOW_CONTROL)
static int set_flow_control(void) static int set_flow_control(void)
{ {
struct bt_hci_cp_host_buffer_size *hbs; struct bt_hci_cp_host_buffer_size *hbs;
@ -1047,7 +1066,7 @@ static int set_flow_control(void)
net_buf_add_u8(buf, BT_HCI_CTL_TO_HOST_FLOW_ENABLE); net_buf_add_u8(buf, BT_HCI_CTL_TO_HOST_FLOW_ENABLE);
return bt_hci_cmd_send_sync(BT_HCI_OP_SET_CTL_TO_HOST_FLOW, buf, NULL); return bt_hci_cmd_send_sync(BT_HCI_OP_SET_CTL_TO_HOST_FLOW, buf, NULL);
} }
#endif /* CONFIG_BLUETOOTH_CONN */ #endif /* CONFIG_BLUETOOTH_HOST_FLOW_CONTROL */
#if defined(CONFIG_BLUETOOTH_BREDR) #if defined(CONFIG_BLUETOOTH_BREDR)
static void reset_pairing(struct bt_conn *conn) static void reset_pairing(struct bt_conn *conn)
@ -2991,7 +3010,7 @@ static int common_init(void)
read_supported_commands_complete(rsp); read_supported_commands_complete(rsp);
net_buf_unref(rsp); net_buf_unref(rsp);
#if defined(CONFIG_BLUETOOTH_CONN) #if defined(CONFIG_BLUETOOTH_HOST_FLOW_CONTROL)
err = set_flow_control(); err = set_flow_control();
if (err) { if (err) {
return err; return err;
@ -4029,7 +4048,11 @@ struct net_buf *bt_buf_get_evt(uint8_t opcode, int32_t timeout)
buf = net_buf_alloc(&hci_evt_prio_pool, timeout); buf = net_buf_alloc(&hci_evt_prio_pool, timeout);
break; break;
default: default:
#if defined(CONFIG_BLUETOOTH_COMBINED_RX_BUF)
buf = net_buf_alloc(&hci_rx_pool, K_NO_WAIT);
#else
buf = net_buf_alloc(&hci_evt_pool, K_NO_WAIT); buf = net_buf_alloc(&hci_evt_pool, K_NO_WAIT);
#endif
if (!buf && opcode == 0x00) { if (!buf && opcode == 0x00) {
buf = net_buf_alloc(&hci_evt_prio_pool, timeout); buf = net_buf_alloc(&hci_evt_prio_pool, timeout);
} }
@ -4049,7 +4072,11 @@ struct net_buf *bt_buf_get_acl(int32_t timeout)
#if defined(CONFIG_BLUETOOTH_CONN) #if defined(CONFIG_BLUETOOTH_CONN)
struct net_buf *buf; struct net_buf *buf;
#if defined(CONFIG_BLUETOOTH_COMBINED_RX_BUF)
buf = net_buf_alloc(&hci_rx_pool, timeout);
#else
buf = net_buf_alloc(&acl_in_pool, timeout); buf = net_buf_alloc(&acl_in_pool, timeout);
#endif
if (buf) { if (buf) {
net_buf_reserve(buf, CONFIG_BLUETOOTH_HCI_RECV_RESERVE); net_buf_reserve(buf, CONFIG_BLUETOOTH_HCI_RECV_RESERVE);
bt_buf_set_type(buf, BT_BUF_ACL_IN); bt_buf_set_type(buf, BT_BUF_ACL_IN);

View file

@ -29,6 +29,10 @@
static struct k_fifo *raw_rx; static struct k_fifo *raw_rx;
#if defined(CONFIG_BLUETOOTH_COMBINED_RX_BUF)
NET_BUF_POOL_DEFINE(hci_rx_pool, CONFIG_BLUETOOTH_RX_BUF_COUNT,
BT_BUF_RX_SIZE, BT_BUF_USER_DATA_MIN, NULL);
#else
/* ACL incoming buffers */ /* ACL incoming buffers */
NET_BUF_POOL_DEFINE(acl_in_pool, CONFIG_BLUETOOTH_ACL_IN_COUNT, NET_BUF_POOL_DEFINE(acl_in_pool, CONFIG_BLUETOOTH_ACL_IN_COUNT,
BT_BUF_ACL_IN_SIZE, sizeof(uint8_t), NULL); BT_BUF_ACL_IN_SIZE, sizeof(uint8_t), NULL);
@ -36,6 +40,7 @@ NET_BUF_POOL_DEFINE(acl_in_pool, CONFIG_BLUETOOTH_ACL_IN_COUNT,
/* HCI event buffers */ /* HCI event buffers */
NET_BUF_POOL_DEFINE(hci_evt_pool, CONFIG_BLUETOOTH_HCI_EVT_COUNT, NET_BUF_POOL_DEFINE(hci_evt_pool, CONFIG_BLUETOOTH_HCI_EVT_COUNT,
BT_BUF_EVT_SIZE, sizeof(uint8_t), NULL); BT_BUF_EVT_SIZE, sizeof(uint8_t), NULL);
#endif
struct bt_dev_raw bt_dev; struct bt_dev_raw bt_dev;
@ -68,7 +73,11 @@ struct net_buf *bt_buf_get_evt(uint8_t opcode, int timeout)
{ {
struct net_buf *buf; struct net_buf *buf;
#if defined(CONFIG_BLUETOOTH_COMBINED_RX_BUF)
buf = net_buf_alloc(&hci_rx_pool, timeout);
#else
buf = net_buf_alloc(&hci_evt_pool, timeout); buf = net_buf_alloc(&hci_evt_pool, timeout);
#endif
if (buf) { if (buf) {
bt_buf_set_type(buf, BT_BUF_EVT); bt_buf_set_type(buf, BT_BUF_EVT);
} }
@ -80,7 +89,11 @@ struct net_buf *bt_buf_get_acl(int32_t timeout)
{ {
struct net_buf *buf; struct net_buf *buf;
#if defined(CONFIG_BLUETOOTH_COMBINED_RX_BUF)
buf = net_buf_alloc(&hci_rx_pool, timeout);
#else
buf = net_buf_alloc(&acl_in_pool, timeout); buf = net_buf_alloc(&acl_in_pool, timeout);
#endif
if (buf) { if (buf) {
bt_buf_set_type(buf, BT_BUF_ACL_IN); bt_buf_set_type(buf, BT_BUF_ACL_IN);
} }