Skip to content

Commit

Permalink
Bluetooth: drivers: Convert IPC driver to new API
Browse files Browse the repository at this point in the history
Convert the ipc.c HCI driver to the new HCI driver API.

Signed-off-by: Johan Hedberg <[email protected]>
  • Loading branch information
jhedberg authored and nashif committed Jun 11, 2024
1 parent af750cd commit 6e584a4
Show file tree
Hide file tree
Showing 18 changed files with 117 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
zephyr,bt-mon-uart = &uart0;
zephyr,bt-c2h-uart = &uart0;
zephyr,display = &ili9340;
zephyr,bt-hci-ipc = &ipc0;
zephyr,bt-hci = &bt_hci_ipc0;
};

/* Main LEDs and buttons are on an I2C TCA9538 GPIO port expander */
Expand Down
2 changes: 1 addition & 1 deletion boards/native/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
chosen {
zephyr,entropy = &rng_hci;
zephyr,flash = &flash0;
zephyr,bt-hci-ipc = &ipc0;
zephyr,bt-hci = &bt_hci_ipc0;
nordic,802154-spinel-ipc = &ipc0;
zephyr,ieee802154 = &ieee802154;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
zephyr,uart-mcumgr = &uart0;
zephyr,bt-mon-uart = &uart0;
zephyr,bt-c2h-uart = &uart0;
zephyr,bt-hci-ipc = &ipc0;
zephyr,bt-hci = &bt_hci_ipc0;
watchdog0 = &wdt0;
};

Expand Down
2 changes: 1 addition & 1 deletion boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
zephyr,uart-mcumgr = &uart0;
zephyr,bt-mon-uart = &uart0;
zephyr,bt-c2h-uart = &uart0;
zephyr,bt-hci-ipc = &ipc0;
zephyr,bt-hci = &bt_hci_ipc0;
nordic,802154-spinel-ipc = &ipc0;
zephyr,ieee802154 = &ieee802154;
};
Expand Down
7 changes: 6 additions & 1 deletion boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
zephyr,sram = &cpuapp_data;
zephyr,shell-uart = &uart136;
zephyr,ieee802154 = &cpuapp_ieee802154;
zephyr,bt-hci-ipc = &ipc0;
zephyr,bt-hci = &bt_hci_ipc0;
nordic,802154-spinel-ipc = &ipc0;
zephyr,canbus = &can120;
};
Expand Down Expand Up @@ -155,6 +155,11 @@ ipc0: &cpuapp_cpurad_ipc {
rx-region = <&cpurad_cpuapp_ipc_shm>;
tx-blocks = <32>;
rx-blocks = <32>;

bt_hci_ipc0: bt_hci_ipc0 {
compatible = "zephyr,bt-hci-ipc";
status = "okay";
};
};

&cpuapp_cpusys_ipc {
Expand Down
1 change: 1 addition & 0 deletions boards/nordic/thingy53/thingy53_nrf5340_common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
zephyr,bt-mon-uart = &cdc_acm_uart;
zephyr,bt-c2h-uart = &cdc_acm_uart;
zephyr,bt-hci-ipc = &ipc0;
zephyr,bt-hci = &bt_hci_ipc0;
nordic,802154-spinel-ipc = &ipc0;
zephyr,ieee802154 = &ieee802154;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
zephyr,uart-mcumgr = &uart0;
zephyr,bt-mon-uart = &uart0;
zephyr,bt-c2h-uart = &uart0;
zephyr,bt-hci-ipc = &ipc0;
zephyr,bt-hci = &bt_hci_ipc0;
nordic,802154-spinel-ipc = &ipc0;
zephyr,ieee802154 = &ieee802154;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
zephyr,uart-mcumgr = &uart0;
zephyr,bt-mon-uart = &uart0;
zephyr,bt-c2h-uart = &uart0;
zephyr,bt-hci-ipc = &ipc0;
zephyr,bt-hci = &bt_hci_ipc0;
nordic,802154-spinel-ipc = &ipc0;
zephyr,ieee802154 = &ieee802154;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
zephyr,uart-mcumgr = &uart0;
zephyr,bt-mon-uart = &uart0;
zephyr,bt-c2h-uart = &uart0;
zephyr,bt-hci-ipc = &ipc0;
zephyr,bt-hci = &bt_hci_ipc0;
nordic,802154-spinel-ipc = &ipc0;
zephyr,ieee802154 = &ieee802154;
};
Expand Down
2 changes: 2 additions & 0 deletions drivers/bluetooth/hci/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ config BT_RPMSG

config BT_HCI_IPC
bool "HCI using the IPC subsystem"
default y
depends on DT_HAS_ZEPHYR_BT_HCI_IPC_ENABLED
select BT_HAS_HCI_VS
select IPC_SERVICE
select MBOX
Expand Down
104 changes: 54 additions & 50 deletions drivers/bluetooth/hci/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/drivers/bluetooth/hci_driver.h>
#include <zephyr/drivers/bluetooth.h>

#include <zephyr/device.h>
#include <zephyr/ipc/ipc_service.h>
Expand All @@ -18,10 +18,17 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_hci_driver);

#define DT_DRV_COMPAT zephyr_bt_hci_ipc

#define IPC_BOUND_TIMEOUT_IN_MS K_MSEC(1000)

static struct ipc_ept hci_ept;
static K_SEM_DEFINE(ipc_bound_sem, 0, 1);
struct ipc_data {
bt_hci_recv_t recv;
struct ipc_ept hci_ept;
struct ipc_ept_cfg hci_ept_cfg;
struct k_sem bound_sem;
const struct device *ipc;
};

static bool is_hci_event_discardable(const uint8_t *evt_data)
{
Expand Down Expand Up @@ -200,8 +207,9 @@ static struct net_buf *bt_ipc_iso_recv(const uint8_t *data, size_t remaining)
return buf;
}

static void bt_ipc_rx(const uint8_t *data, size_t len)
static void bt_ipc_rx(const struct device *dev, const uint8_t *data, size_t len)
{
struct ipc_data *ipc = dev->data;
uint8_t pkt_indicator;
struct net_buf *buf = NULL;
size_t remaining = len;
Expand Down Expand Up @@ -231,14 +239,15 @@ static void bt_ipc_rx(const uint8_t *data, size_t len)

if (buf) {
LOG_DBG("Calling bt_recv(%p)", buf);
bt_recv(buf);
ipc->recv(dev, buf);

LOG_HEXDUMP_DBG(buf->data, buf->len, "RX buf payload:");
}
}

static int bt_ipc_send(struct net_buf *buf)
static int bt_ipc_send(const struct device *dev, struct net_buf *buf)
{
struct ipc_data *data = dev->data;
int err;
uint8_t pkt_indicator;

Expand All @@ -261,7 +270,7 @@ static int bt_ipc_send(struct net_buf *buf)
net_buf_push_u8(buf, pkt_indicator);

LOG_HEXDUMP_DBG(buf->data, buf->len, "Final HCI buffer:");
err = ipc_service_send(&hci_ept, buf->data, buf->len);
err = ipc_service_send(&data->hci_ept, buf->data, buf->len);
if (err < 0) {
LOG_ERR("Failed to send (err %d)", err);
}
Expand All @@ -273,21 +282,18 @@ static int bt_ipc_send(struct net_buf *buf)

static void hci_ept_bound(void *priv)
{
k_sem_give(&ipc_bound_sem);
const struct device *dev = priv;
struct ipc_data *ipc = dev->data;

k_sem_give(&ipc->bound_sem);
}

static void hci_ept_recv(const void *data, size_t len, void *priv)
{
bt_ipc_rx(data, len);
}
const struct device *dev = priv;

static struct ipc_ept_cfg hci_ept_cfg = {
.name = "nrf_bt_hci",
.cb = {
.bound = hci_ept_bound,
.received = hci_ept_recv,
},
};
bt_ipc_rx(dev, data, len);
}

int __weak bt_hci_transport_setup(const struct device *dev)
{
Expand All @@ -301,13 +307,11 @@ int __weak bt_hci_transport_teardown(const struct device *dev)
return 0;
}

static int bt_ipc_open(void)
static int bt_ipc_open(const struct device *dev, bt_hci_recv_t recv)
{
struct ipc_data *ipc = dev->data;
int err;

const struct device *hci_ipc_instance =
DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_ipc));

err = bt_hci_transport_setup(NULL);
if (err) {
LOG_ERR("HCI transport setup failed with: %d\n", err);
Expand All @@ -316,29 +320,32 @@ static int bt_ipc_open(void)

LOG_DBG("");

err = ipc_service_open_instance(hci_ipc_instance);
err = ipc_service_open_instance(ipc->ipc);
if (err && (err != -EALREADY)) {
LOG_ERR("IPC service instance initialization failed: %d\n", err);
return err;
}

err = ipc_service_register_endpoint(hci_ipc_instance, &hci_ept, &hci_ept_cfg);
err = ipc_service_register_endpoint(ipc->ipc, &ipc->hci_ept, &ipc->hci_ept_cfg);
if (err) {
LOG_ERR("Registering endpoint failed with %d", err);
return err;
}

err = k_sem_take(&ipc_bound_sem, IPC_BOUND_TIMEOUT_IN_MS);
err = k_sem_take(&ipc->bound_sem, IPC_BOUND_TIMEOUT_IN_MS);
if (err) {
LOG_ERR("Endpoint binding failed with %d", err);
return err;
}

ipc->recv = recv;

return 0;
}

static int bt_ipc_close(void)
static int bt_ipc_close(const struct device *dev)
{
struct ipc_data *ipc = dev->data;
int err;

if (IS_ENABLED(CONFIG_BT_HCI_HOST)) {
Expand All @@ -349,16 +356,13 @@ static int bt_ipc_close(void)
}
}

err = ipc_service_deregister_endpoint(&hci_ept);
err = ipc_service_deregister_endpoint(&ipc->hci_ept);
if (err) {
LOG_ERR("Deregistering HCI endpoint failed with: %d", err);
return err;
}

const struct device *hci_ipc_instance =
DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_ipc));

err = ipc_service_close_instance(hci_ipc_instance);
err = ipc_service_close_instance(ipc->ipc);
if (err) {
LOG_ERR("Closing IPC service failed with: %d", err);
return err;
Expand All @@ -370,31 +374,31 @@ static int bt_ipc_close(void)
return err;
}

ipc->recv = NULL;

return 0;
}

static const struct bt_hci_driver drv = {
.name = "IPC",
static const struct bt_hci_driver_api drv = {
.open = bt_ipc_open,
.close = bt_ipc_close,
.send = bt_ipc_send,
.bus = BT_HCI_DRIVER_BUS_IPM,
#if defined(CONFIG_BT_DRIVER_QUIRK_NO_AUTO_DLE)
.quirks = BT_QUIRK_NO_AUTO_DLE,
#endif
};

static int bt_ipc_init(void)
{

int err;

err = bt_hci_driver_register(&drv);
if (err < 0) {
LOG_ERR("Failed to register BT HIC driver (err %d)", err);
}

return err;
}

SYS_INIT(bt_ipc_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
#define IPC_DEVICE_INIT(inst) \
static struct ipc_data ipc_data_##inst = { \
.bound_sem = Z_SEM_INITIALIZER(ipc_data_##inst.bound_sem, 0, 1), \
.hci_ept_cfg = { \
.name = DT_INST_PROP(inst, bt_hci_ipc_name), \
.cb = { \
.bound = hci_ept_bound, \
.received = hci_ept_recv, \
}, \
.priv = (void *)DEVICE_DT_INST_GET(inst), \
}, \
.ipc = DEVICE_DT_GET(DT_INST_PARENT(inst)), \
}; \
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &ipc_data_##inst, NULL, \
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv)

DT_INST_FOREACH_STATUS_OKAY(IPC_DEVICE_INIT)
5 changes: 5 additions & 0 deletions dts/arm/nordic/nrf5340_cpuapp_ipc.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ ipc0: ipc0 {
mbox-names = "tx", "rx";
role = "host";
status = "okay";

bt_hci_ipc0: bt_hci_ipc0 {
compatible = "zephyr,bt-hci-ipc";
status = "okay";
};
};
17 changes: 17 additions & 0 deletions dts/bindings/bluetooth/zephyr,bt-hci-ipc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
description: Bluetooth HCI using the IPC subsystem

compatible: "zephyr,bt-hci-ipc"

include: bt-hci.yaml

properties:
bt-hci-name:
default: "IPC"
bt-hci-bus:
default: "BT_HCI_BUS_IPM"
bt-hci-quirks:
default: ["BT_HCI_QUIRK_NO_AUTO_DLE"]
bt-hci-ipc-name:
type: string
default: "nrf_bt_hci"
description: IPC endpoint name
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
mboxes = <&mbox 0>, <&mbox 1>;
mbox-names = "tx", "rx";
status = "okay";

bt_hci_ipc0: bt_hci_ipc0 {
compatible = "zephyr,bt-hci-ipc";
status = "okay";
};
};
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
mboxes = <&mbox 0>, <&mbox 1>;
mbox-names = "tx", "rx";
status = "okay";

bt_hci_ipc0: bt_hci_ipc0 {
compatible = "zephyr,bt-hci-ipc";
status = "okay";
};
};

ipc1: ipc1 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
mboxes = <&mbox 0>, <&mbox 1>;
mbox-names = "tx", "rx";
status = "okay";

bt_hci_ipc0: bt_hci_ipc0 {
compatible = "zephyr,bt-hci-ipc";
status = "okay";
};
};

ipc1: ipc1 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
mbox-names = "tx", "rx";
role = "host";
status = "okay";

bt_hci_ipc0: bt_hci_ipc0 {
compatible = "zephyr,bt-hci-ipc";
status = "okay";
};
};

ipc1: ipc1 {
Expand Down
Loading

0 comments on commit 6e584a4

Please sign in to comment.