Skip to content

Commit

Permalink
Bluetooth: Support BT_RECV_WORKQ_BT with Zephyr LL
Browse files Browse the repository at this point in the history
This patch allows selecting the combination of `CONFIG_BT_RECV_WORKQ_BT`
and `BT_LL_SW_SPLIT`. The implementation of `bt_recv_prio` is copied
from `hci_raw.c`. This ensures the order of packets is the same as when
the controller's `hci_driver.c` is off-chip and sends HCI over UART.

Without this patch, the Zephyr LL driver will duplicate some events on
behalf of `hci_core`. This duplication is not wanted when
`CONFIG_BT_RECV_WORKQ_BT=y`.

The above mentioned duplication is not sound and is evidenced in logged
warnings, e.g. in `tests/bsim/bluetooth/host/l2cap/stress` with
`CONFIG_BT_RECV_WORKQ_BT=y` logging "no transition".

This patch is a step towards the deprecation of
`CONFIG_BT_RECV_BLOCKING`. `CONFIG_BT_RECV_BLOCKING` is complicated and
tightly coupled to `hci_core`. In the future, removing
`CONFIG_BT_RECV_BLOCKING` will give a cleaner separation between
`hci_core` and the drivers and allow `hci_core` to evolve without
changes spilling out into the drivers.

Signed-off-by: Aleksander Wasaznik <[email protected]>
  • Loading branch information
alwa-nordic committed Feb 5, 2024
1 parent f6adaf5 commit 92ef586
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
24 changes: 24 additions & 0 deletions subsys/bluetooth/controller/hci/hci_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,30 @@ static sys_slist_t hbuf_pend;
static int32_t hbuf_count;
#endif

#if !defined(CONFIG_BT_RECV_BLOCKING)
/* Copied here from `hci_raw.c`, which would be used in
* conjunction with this driver when serializing HCI over wire.
* This serves as a converter from the more complicated
* `CONFIG_BT_RECV_BLOCKING` API to the normal single-receiver
* `bt_recv` API.
*/
int bt_recv_prio(struct net_buf *buf)
{
if (bt_buf_get_type(buf) == BT_BUF_EVT) {
struct bt_hci_evt_hdr *hdr = (void *)buf->data;
uint8_t evt_flags = bt_hci_evt_get_flags(hdr->evt);

if ((evt_flags & BT_HCI_EVT_FLAG_RECV_PRIO) &&
(evt_flags & BT_HCI_EVT_FLAG_RECV)) {
/* Avoid queuing the event twice */
return 0;
}
}

return bt_recv(buf);
}
#endif /* CONFIG_BT_RECV_BLOCKING */

#if defined(CONFIG_BT_CTLR_ISO)

#define SDU_HCI_HDR_SIZE (BT_HCI_ISO_HDR_SIZE + BT_HCI_ISO_TS_DATA_HDR_SIZE)
Expand Down
2 changes: 2 additions & 0 deletions subsys/bluetooth/host/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3881,6 +3881,7 @@ int bt_recv(struct net_buf *buf)
}
}

#if defined(CONFIG_BT_RECV_BLOCKING)
int bt_recv_prio(struct net_buf *buf)
{
bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
Expand All @@ -3891,6 +3892,7 @@ int bt_recv_prio(struct net_buf *buf)

return 0;
}
#endif /* CONFIG_BT_RECV_BLOCKING */

int bt_hci_driver_register(const struct bt_hci_driver *drv)
{
Expand Down

0 comments on commit 92ef586

Please sign in to comment.