From 44e0f5fee338121391a54e099e24cee9cb1a8bc8 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sun, 5 May 2024 18:12:49 +0300 Subject: [PATCH] Bluetooth: controller: Update to new HCI driver API Update the native controller to the new HCI driver API. The devicetree node is placed under existing `radio` nodes, which seemed like the most intuitive option. Signed-off-by: Johan Hedberg --- .../rv32m1_vega_openisa_rv32m1_ri5cy.dts | 5 ++ drivers/bluetooth/Kconfig | 2 +- dts/arm/nordic/nrf51822.dtsi | 6 ++ dts/arm/nordic/nrf52805.dtsi | 6 ++ dts/arm/nordic/nrf52810.dtsi | 6 ++ dts/arm/nordic/nrf52811.dtsi | 6 ++ dts/arm/nordic/nrf52820.dtsi | 6 ++ dts/arm/nordic/nrf52832.dtsi | 6 ++ dts/arm/nordic/nrf52833.dtsi | 6 ++ dts/arm/nordic/nrf52840.dtsi | 6 ++ dts/arm/nordic/nrf5340_cpunet.dtsi | 6 ++ dts/arm/nordic/nrf54l15_cpuapp.dtsi | 8 ++ .../bluetooth/zephyr,bt-hci-ll-sw-split.yaml | 13 +++ dts/common/nordic/nrf54l15.dtsi | 5 ++ dts/riscv/openisa/rv32m1.dtsi | 5 ++ subsys/bluetooth/controller/Kconfig | 1 + subsys/bluetooth/controller/hci/hci_driver.c | 88 +++++++++++-------- 17 files changed, 145 insertions(+), 36 deletions(-) create mode 100644 dts/bindings/bluetooth/zephyr,bt-hci-ll-sw-split.yaml diff --git a/boards/openisa/rv32m1_vega/rv32m1_vega_openisa_rv32m1_ri5cy.dts b/boards/openisa/rv32m1_vega/rv32m1_vega_openisa_rv32m1_ri5cy.dts index c98531845536..ceba94b4794a 100644 --- a/boards/openisa/rv32m1_vega/rv32m1_vega_openisa_rv32m1_ri5cy.dts +++ b/boards/openisa/rv32m1_vega/rv32m1_vega_openisa_rv32m1_ri5cy.dts @@ -19,9 +19,14 @@ zephyr,shell-uart = &lpuart0; zephyr,uart-pipe = &lpuart0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_controller; }; }; +&bt_hci_controller { + status = "okay"; +}; + &m4_flash { /* * For more information, see: diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 46bf62bb1a7f..a1680af6583d 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -12,7 +12,7 @@ menuconfig BT_DRIVERS bool "Bluetooth drivers" default y - depends on BT && !BT_CTLR + depends on BT if BT_DRIVERS diff --git a/dts/arm/nordic/nrf51822.dtsi b/dts/arm/nordic/nrf51822.dtsi index b64de1d4985c..11cc9eff2f9e 100644 --- a/dts/arm/nordic/nrf51822.dtsi +++ b/dts/arm/nordic/nrf51822.dtsi @@ -5,6 +5,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -73,6 +74,11 @@ reg = <0x40001000 0x1000>; interrupts = <1 NRF_DEFAULT_IRQ_PRIORITY>; status = "okay"; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52805.dtsi b/dts/arm/nordic/nrf52805.dtsi index c5a184d5e288..b375ef170697 100644 --- a/dts/arm/nordic/nrf52805.dtsi +++ b/dts/arm/nordic/nrf52805.dtsi @@ -9,6 +9,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -86,6 +87,11 @@ interrupts = <1 NRF_DEFAULT_IRQ_PRIORITY>; status = "okay"; ble-2mbps-supported; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52810.dtsi b/dts/arm/nordic/nrf52810.dtsi index 1ca4a9ea378a..0c95fe96e70d 100644 --- a/dts/arm/nordic/nrf52810.dtsi +++ b/dts/arm/nordic/nrf52810.dtsi @@ -5,6 +5,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -90,6 +91,11 @@ interrupts = <1 NRF_DEFAULT_IRQ_PRIORITY>; status = "okay"; ble-2mbps-supported; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52811.dtsi b/dts/arm/nordic/nrf52811.dtsi index 63b856765877..2176bfa93c74 100644 --- a/dts/arm/nordic/nrf52811.dtsi +++ b/dts/arm/nordic/nrf52811.dtsi @@ -9,6 +9,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -102,6 +103,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52820.dtsi b/dts/arm/nordic/nrf52820.dtsi index f93e449b0b2c..d6bd6e65f66c 100644 --- a/dts/arm/nordic/nrf52820.dtsi +++ b/dts/arm/nordic/nrf52820.dtsi @@ -10,6 +10,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -98,6 +99,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52832.dtsi b/dts/arm/nordic/nrf52832.dtsi index 13ee05226b76..bdb76a05d5b5 100644 --- a/dts/arm/nordic/nrf52832.dtsi +++ b/dts/arm/nordic/nrf52832.dtsi @@ -5,6 +5,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -90,6 +91,11 @@ interrupts = <1 NRF_DEFAULT_IRQ_PRIORITY>; status = "okay"; ble-2mbps-supported; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52833.dtsi b/dts/arm/nordic/nrf52833.dtsi index f22cb36bc14a..40c3f1efcad4 100644 --- a/dts/arm/nordic/nrf52833.dtsi +++ b/dts/arm/nordic/nrf52833.dtsi @@ -9,6 +9,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -97,6 +98,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52840.dtsi b/dts/arm/nordic/nrf52840.dtsi index 4cfb7abc511e..120a5a87b135 100644 --- a/dts/arm/nordic/nrf52840.dtsi +++ b/dts/arm/nordic/nrf52840.dtsi @@ -5,6 +5,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -92,6 +93,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf5340_cpunet.dtsi b/dts/arm/nordic/nrf5340_cpunet.dtsi index 8a95b3e99850..4e05f4a1df02 100644 --- a/dts/arm/nordic/nrf5340_cpunet.dtsi +++ b/dts/arm/nordic/nrf5340_cpunet.dtsi @@ -9,6 +9,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -100,6 +101,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; rng: random@41009000 { diff --git a/dts/arm/nordic/nrf54l15_cpuapp.dtsi b/dts/arm/nordic/nrf54l15_cpuapp.dtsi index 6a4f5fcae239..f2264079e8d6 100644 --- a/dts/arm/nordic/nrf54l15_cpuapp.dtsi +++ b/dts/arm/nordic/nrf54l15_cpuapp.dtsi @@ -17,6 +17,10 @@ cpuflpr_vevif: &cpuflpr_vevif_remote {}; /delete-node/ &cpuflpr_clic; / { + chosen { + zephyr,bt-hci = &bt_hci_controller; + }; + soc { compatible = "simple-bus"; interrupt-parent = <&cpuapp_nvic>; @@ -29,6 +33,10 @@ cpuflpr_vevif: &cpuflpr_vevif_remote {}; }; }; +&bt_hci_controller { + status = "okay"; +}; + &cpuapp_ppb { compatible = "simple-bus"; ranges; diff --git a/dts/bindings/bluetooth/zephyr,bt-hci-ll-sw-split.yaml b/dts/bindings/bluetooth/zephyr,bt-hci-ll-sw-split.yaml new file mode 100644 index 000000000000..f53cf49e90e0 --- /dev/null +++ b/dts/bindings/bluetooth/zephyr,bt-hci-ll-sw-split.yaml @@ -0,0 +1,13 @@ +description: Bluetooth HCI provided by the native Zephyr Bluetooth Controller + +compatible: "zephyr,bt-hci-ll-sw-split" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "Controller" + bt-hci-bus: + default: "BT_HCI_BUS_VIRTUAL" + bt-hci-quirks: + default: ["BT_HCI_QUIRK_NO_AUTO_DLE"] diff --git a/dts/common/nordic/nrf54l15.dtsi b/dts/common/nordic/nrf54l15.dtsi index 0b8eb1c549a8..8896b94f8748 100644 --- a/dts/common/nordic/nrf54l15.dtsi +++ b/dts/common/nordic/nrf54l15.dtsi @@ -264,6 +264,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "disabled"; + }; }; dppic20: dppic@c2000 { diff --git a/dts/riscv/openisa/rv32m1.dtsi b/dts/riscv/openisa/rv32m1.dtsi index afbc7c41c23a..cb234eba9982 100644 --- a/dts/riscv/openisa/rv32m1.dtsi +++ b/dts/riscv/openisa/rv32m1.dtsi @@ -524,5 +524,10 @@ write-block-size = <8>; }; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "disabled"; + }; }; }; diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index a401502dbfe5..9c21740b813c 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -133,6 +133,7 @@ endchoice config BT_CTLR_HCI bool "Host Controller Interface (HCI)" default y + depends on DT_HAS_ZEPHYR_BT_HCI_LL_SW_SPLIT_ENABLED help Enable the Host Controller interface (HCI) in the Controller. This should almost always be enabled, except in a few special diff --git a/subsys/bluetooth/controller/hci/hci_driver.c b/subsys/bluetooth/controller/hci/hci_driver.c index f174ca02c728..d5826c9dc592 100644 --- a/subsys/bluetooth/controller/hci/hci_driver.c +++ b/subsys/bluetooth/controller/hci/hci_driver.c @@ -21,7 +21,7 @@ #include #include -#include +#include #ifdef CONFIG_CLOCK_CONTROL_NRF #include @@ -66,6 +66,12 @@ #include LOG_MODULE_REGISTER(bt_ctlr_hci_driver); +#define DT_DRV_COMPAT zephyr_bt_hci_ll_sw_split + +struct hci_driver_data { + bt_hci_recv_t recv; +}; + static struct k_sem sem_prio_recv; static struct k_fifo recv_fifo; @@ -120,8 +126,10 @@ static inline uint8_t bt_hci_evt_get_flags(uint8_t evt) * tree) 'recv blocking' API to the normal single-receiver * `bt_recv` API. */ -static int bt_recv_prio(struct net_buf *buf) +static int bt_recv_prio(const struct device *dev, struct net_buf *buf) { + struct hci_driver_data *data = dev->data; + 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); @@ -133,7 +141,7 @@ static int bt_recv_prio(struct net_buf *buf) } } - return bt_recv(buf); + return data->recv(dev, buf); } #if defined(CONFIG_BT_CTLR_ISO) @@ -167,6 +175,8 @@ isoal_status_t sink_sdu_emit_hci(const struct isoal_sink *sink_ctx, const struct isoal_emitted_sdu_frag *sdu_frag, const struct isoal_emitted_sdu *sdu) { + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct hci_driver_data *data = dev->data; struct bt_hci_iso_sdu_ts_hdr *sdu_hdr; uint16_t packet_status_flag; struct bt_hci_iso_hdr *hdr; @@ -249,7 +259,7 @@ isoal_status_t sink_sdu_emit_hci(const struct isoal_sink *sink_ctx, hdr->len = sys_cpu_to_le16(len); /* send fragment up the chain */ - bt_recv(buf); + data->recv(dev, buf); } return ISOAL_STATUS_OK; @@ -322,6 +332,8 @@ static struct net_buf *process_prio_evt(struct node_rx_pdu *node_rx, */ static void prio_recv_thread(void *p1, void *p2, void *p3) { + const struct device *dev = p1; + while (1) { struct node_rx_pdu *node_rx; struct net_buf *buf; @@ -358,7 +370,7 @@ static void prio_recv_thread(void *p1, void *p2, void *p3) false, K_FOREVER); hci_num_cmplt_encode(buf, handle, num_cmplt); LOG_DBG("Num Complete: 0x%04x:%u", handle, num_cmplt); - bt_recv_prio(buf); + bt_recv_prio(dev, buf); k_yield(); #endif /* CONFIG_BT_CONN || CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */ } @@ -382,7 +394,7 @@ static void prio_recv_thread(void *p1, void *p2, void *p3) ll_rx_mem_release((void **)&node_rx); } - bt_recv_prio(buf); + bt_recv_prio(dev, buf); /* bt_recv_prio would not release normal evt * buf. */ @@ -661,6 +673,9 @@ static inline struct net_buf *process_hbuf(struct node_rx_pdu *n) */ static void recv_thread(void *p1, void *p2, void *p3) { + const struct device *dev = p1; + struct hci_driver_data *data = dev->data; + #if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) /* @todo: check if the events structure really needs to be static */ static struct k_poll_event events[2] = { @@ -719,7 +734,7 @@ static void recv_thread(void *p1, void *p2, void *p3) LOG_DBG("Packet in: type:%u len:%u", bt_buf_get_type(frag), frag->len); - bt_recv(frag); + data->recv(dev, frag); } else { net_buf_unref(frag); } @@ -729,7 +744,7 @@ static void recv_thread(void *p1, void *p2, void *p3) } } -static int cmd_handle(struct net_buf *buf) +static int cmd_handle(const struct device *dev, struct net_buf *buf) { struct node_rx_pdu *node_rx = NULL; struct net_buf *evt; @@ -737,7 +752,7 @@ static int cmd_handle(struct net_buf *buf) evt = hci_cmd_handle(buf, (void **) &node_rx); if (evt) { LOG_DBG("Replying with event of %u bytes", evt->len); - bt_recv_prio(evt); + bt_recv_prio(dev, evt); if (node_rx) { LOG_DBG("RX node enqueue"); @@ -750,7 +765,7 @@ static int cmd_handle(struct net_buf *buf) } #if defined(CONFIG_BT_CONN) -static int acl_handle(struct net_buf *buf) +static int acl_handle(const struct device *dev, struct net_buf *buf) { struct net_buf *evt; int err; @@ -758,7 +773,7 @@ static int acl_handle(struct net_buf *buf) err = hci_acl_handle(buf, &evt); if (evt) { LOG_DBG("Replying with event of %u bytes", evt->len); - bt_recv_prio(evt); + bt_recv_prio(dev, evt); } return err; @@ -766,7 +781,7 @@ static int acl_handle(struct net_buf *buf) #endif /* CONFIG_BT_CONN */ #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO) -static int iso_handle(struct net_buf *buf) +static int iso_handle(const struct device *dev, struct net_buf *buf) { struct net_buf *evt; int err; @@ -774,14 +789,14 @@ static int iso_handle(struct net_buf *buf) err = hci_iso_handle(buf, &evt); if (evt) { LOG_DBG("Replying with event of %u bytes", evt->len); - bt_recv_prio(evt); + bt_recv_prio(dev, evt); } return err; } #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */ -static int hci_driver_send(struct net_buf *buf) +static int hci_driver_send(const struct device *dev, struct net_buf *buf) { uint8_t type; int err; @@ -797,15 +812,15 @@ static int hci_driver_send(struct net_buf *buf) switch (type) { #if defined(CONFIG_BT_CONN) case BT_BUF_ACL_OUT: - err = acl_handle(buf); + err = acl_handle(dev, buf); break; #endif /* CONFIG_BT_CONN */ case BT_BUF_CMD: - err = cmd_handle(buf); + err = cmd_handle(dev, buf); break; #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO) case BT_BUF_ISO_OUT: - err = iso_handle(buf); + err = iso_handle(dev, buf); break; #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */ default: @@ -822,8 +837,9 @@ static int hci_driver_send(struct net_buf *buf) return err; } -static int hci_driver_open(void) +static int hci_driver_open(const struct device *dev, bt_hci_recv_t recv) { + struct hci_driver_data *data = dev->data; uint32_t err; DEBUG_INIT(); @@ -837,6 +853,8 @@ static int hci_driver_open(void) return err; } + data->recv = recv; + #if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) k_poll_signal_init(&hbuf_signal); hci_init(&hbuf_signal); @@ -846,13 +864,13 @@ static int hci_driver_open(void) k_thread_create(&prio_recv_thread_data, prio_recv_thread_stack, K_KERNEL_STACK_SIZEOF(prio_recv_thread_stack), - prio_recv_thread, NULL, NULL, NULL, + prio_recv_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT); k_thread_name_set(&prio_recv_thread_data, "BT RX pri"); k_thread_create(&recv_thread_data, recv_thread_stack, K_KERNEL_STACK_SIZEOF(recv_thread_stack), - recv_thread, NULL, NULL, NULL, + recv_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_BT_RX_PRIO), 0, K_NO_WAIT); k_thread_name_set(&recv_thread_data, "BT RX"); @@ -861,8 +879,10 @@ static int hci_driver_open(void) return 0; } -static int hci_driver_close(void) +static int hci_driver_close(const struct device *dev) { + struct hci_driver_data *data = dev->data; + /* Resetting the LL stops all roles */ ll_deinit(); @@ -872,24 +892,22 @@ static int hci_driver_close(void) /* Abort RX thread */ k_thread_abort(&recv_thread_data); + /* Clear the (host) receive callback */ + data->recv = NULL; + return 0; } -static const struct bt_hci_driver drv = { - .name = "Controller", - .bus = BT_HCI_DRIVER_BUS_VIRTUAL, - .quirks = BT_QUIRK_NO_AUTO_DLE, - .open = hci_driver_open, +static const struct bt_hci_driver_api hci_driver_api = { + .open = hci_driver_open, .close = hci_driver_close, - .send = hci_driver_send, + .send = hci_driver_send, }; -static int hci_driver_init(void) -{ - - bt_hci_driver_register(&drv); - - return 0; -} +#define BT_HCI_CONTROLLER_INIT(inst) \ + static struct hci_driver_data data_##inst; \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &data_##inst, NULL, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &hci_driver_api) -SYS_INIT(hci_driver_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +/* Only a single instance is supported */ +BT_HCI_CONTROLLER_INIT(0)