Commit 433833d9 authored by Aleksander Wasaznik's avatar Aleksander Wasaznik Committed by Fabio Baltieri
Browse files

Bluetooth: Support `BT_RECV_WORKQ_BT` with Zephyr LL



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: default avatarAleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
parent a4ea4e29
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -3899,6 +3899,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);
@@ -3909,6 +3910,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)
{