1 /* hci_stm32wb0.c - HCI driver for stm32wb0x */
2 
3 /*
4  * Copyright (c) 2024 STMicroelectronics
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/init.h>
10 #include <zephyr/sys/byteorder.h>
11 #include <zephyr/bluetooth/hci_types.h>
12 #include <zephyr/drivers/bluetooth.h>
13 #include "bleplat_cntr.h"
14 #include "ble_stack.h"
15 #include "stm32wb0x_hal_radio_timer.h"
16 #include "miscutil.h"
17 #include "pka_manager.h"
18 #include "app_conf.h"
19 #include "dtm_cmd_db.h"
20 #include "dm_alloc.h"
21 #include "aci_adv_nwk.h"
22 #include "app_common.h"
23 #include "hw_rng.h"
24 #include "hw_aes.h"
25 #include "hw_pka.h"
26 
27 #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
28 #include <zephyr/logging/log.h>
29 LOG_MODULE_REGISTER(bt_driver);
30 
31 #define DT_DRV_COMPAT st_hci_stm32wb0
32 
33 /* Max HS startup time expressed in system time (1953 us / 2.4414 us) */
34 #define MAX_HS_STARTUP_TIME 320
35 #define BLE_WKUP_PRIO       0
36 #define BLE_WKUP_FLAGS      0
37 #define BLE_TX_RX_PRIO      0
38 #define BLE_TX_RX_FLAGS     0
39 #define CPU_WKUP_PRIO       1
40 #define CPU_WKUP_FLAGS      0
41 #define BLE_ERROR_PRIO      3
42 #define BLE_ERROR_FLAGS     0
43 #define BLE_RXTX_SEQ_PRIO   3
44 #define BLE_RXTX_SEQ_FLAGS  0
45 #define PKA_PRIO	    2
46 #define PKA_FLAGS	    0
47 
48 #define MAX_EVENT_SIZE		 259
49 #define MAX_ISO_DATA_LOAD_LENGTH 512
50 
51 #define PACKET_TYPE	     0
52 #define EVT_HEADER_TYPE      0
53 #define EVT_HEADER_EVENT     1
54 #define EVT_HEADER_SIZE      2
55 #define EVT_LE_META_SUBEVENT 3
56 #define EVT_VENDOR_CODE_LSB  3
57 #define EVT_VENDOR_CODE_MSB  4
58 
59 static uint32_t __noinit dyn_alloc_a[BLE_DYN_ALLOC_SIZE >> 2];
60 static uint8_t buffer_out_mem[MAX_EVENT_SIZE];
61 static struct k_work_delayable hal_radio_timer_work, ble_stack_work;
62 
63 static struct net_buf *get_rx(uint8_t *msg);
64 static PKA_HandleTypeDef hpka;
65 
66 #if CONFIG_BT_EXT_ADV
67 static uint32_t __noinit aci_adv_nwk_buffer[CFG_BLE_ADV_NWK_BUFFER_SIZE >> 2];
68 #endif /* CONFIG_BT_EXT_ADV */
69 
70 struct hci_data {
71 	bt_hci_recv_t recv;
72 };
73 
74 /* Dummy implementation */
BLEPLAT_NvmGet(void)75 int BLEPLAT_NvmGet(void)
76 {
77 	return 0;
78 }
79 
blestack_process(struct k_work * work)80 static void blestack_process(struct k_work *work)
81 {
82 	BLE_STACK_Tick();
83 	if (BLE_STACK_SleepCheck() == 0) {
84 		k_work_reschedule(&ble_stack_work, K_NO_WAIT);
85 	}
86 }
87 
vtimer_process(struct k_work * work)88 static void vtimer_process(struct k_work *work)
89 {
90 	HAL_RADIO_TIMER_Tick();
91 }
92 
93 /* "If, since the last power-on or reset, the Host has ever issued a legacy
94  * advertising command and then issues an extended advertising command, or
95  * has ever issued an extended advertising command and then issues a legacy
96  * advertising command, the Controller shall return the error code Command
97  * Disallowed (0x0C)."
98  * This function returns 1 if an error has to be given.
99  */
check_legacy_extended_call(uint16_t opcode,uint8_t * buffer_out)100 static uint8_t check_legacy_extended_call(uint16_t opcode, uint8_t *buffer_out)
101 {
102 	static bool legacy_cmd_issued, extended_cmd_issued;
103 	bool allowed = true;
104 
105 	if (IN_RANGE(opcode, BT_HCI_OP_LE_SET_ADV_PARAM, BT_HCI_OP_LE_CREATE_CONN)) {
106 		if (extended_cmd_issued) {
107 			allowed = false; /* Error */
108 			LOG_ERR("Extended not allowed");
109 		} else {
110 			legacy_cmd_issued = true;
111 			allowed = true; /* OK */
112 		}
113 	} else if ((opcode >= BT_HCI_OP_LE_SET_EXT_ADV_PARAM) &&
114 		   (opcode <= BT_HCI_OP_LE_READ_PER_ADV_LIST_SIZE)) {
115 		if (legacy_cmd_issued) {
116 			allowed = false; /* Error */
117 			LOG_ERR("Legacy not allowed");
118 		} else {
119 			extended_cmd_issued = true;
120 			allowed = true; /* OK */
121 		}
122 	}
123 
124 	if (!allowed) {
125 		struct bt_hci_evt_hdr *evt_header = (struct bt_hci_evt_hdr *)(buffer_out + 1);
126 
127 		*buffer_out = BT_HCI_H4_EVT;
128 		if (opcode == BT_HCI_OP_LE_CREATE_CONN || opcode == BT_HCI_OP_LE_EXT_CREATE_CONN ||
129 		    opcode == BT_HCI_OP_LE_PER_ADV_CREATE_SYNC) {
130 			struct bt_hci_evt_cmd_status *params =
131 				(struct bt_hci_evt_cmd_status *)(buffer_out + 3);
132 
133 			evt_header->evt = BT_HCI_EVT_CMD_STATUS;
134 			evt_header->len = 4;
135 			params->status = BT_HCI_ERR_CMD_DISALLOWED;
136 			params->ncmd = 1;
137 			params->opcode = sys_cpu_to_le16(opcode);
138 		} else {
139 			struct bt_hci_evt_cmd_complete *params =
140 				(struct bt_hci_evt_cmd_complete *)(buffer_out + 3);
141 
142 			evt_header->evt = BT_HCI_EVT_CMD_COMPLETE;
143 			evt_header->len = 4;
144 			params->ncmd = 1;
145 			params->opcode = sys_cpu_to_le16(opcode);
146 			buffer_out[6] = BT_HCI_ERR_CMD_DISALLOWED;
147 		}
148 		return 7;
149 	}
150 	return 0;
151 }
152 
153 /* Process Commands */
process_command(uint8_t * buffer,uint16_t buffer_in_length,uint8_t * buffer_out,uint16_t buffer_out_max_length)154 static uint16_t process_command(uint8_t *buffer, uint16_t buffer_in_length, uint8_t *buffer_out,
155 				uint16_t buffer_out_max_length)
156 {
157 	uint32_t i;
158 	uint16_t ret_val;
159 	uint16_t op_code;
160 	uint8_t *buffer_in = buffer + sizeof(struct bt_hci_cmd_hdr);
161 	struct bt_hci_cmd_hdr *hdr = (struct bt_hci_cmd_hdr *)buffer;
162 
163 	buffer_in_length -= sizeof(struct bt_hci_cmd_hdr);
164 	op_code = hdr->opcode;
165 	ret_val = check_legacy_extended_call(op_code, buffer_out);
166 	if (ret_val != 0) {
167 		LOG_ERR("ret_val: %d", ret_val);
168 		return ret_val;
169 	}
170 
171 	for (i = 0; hci_command_table[i].opcode != 0; i++) {
172 		if (op_code == hci_command_table[i].opcode) {
173 			ret_val = hci_command_table[i].execute(buffer_in, buffer_in_length,
174 							       buffer_out, buffer_out_max_length);
175 			/* add get crash handler */
176 			return ret_val;
177 		}
178 	}
179 
180 	struct bt_hci_evt_hdr *evt_header = (struct bt_hci_evt_hdr *)(buffer_out + 1);
181 	struct bt_hci_evt_cmd_status *params = (struct bt_hci_evt_cmd_status *)(buffer_out + 3);
182 
183 	*buffer_out = BT_HCI_H4_EVT;
184 	evt_header->evt = BT_HCI_EVT_CMD_STATUS;
185 	evt_header->len = 4;
186 	params->status = BT_HCI_ERR_UNKNOWN_CMD;
187 	params->ncmd = 1;
188 	params->opcode = sys_cpu_to_le16(op_code);
189 	return 7;
190 }
191 
send_event(uint8_t * buffer_out,uint16_t buffer_out_length,int8_t overflow_index)192 void send_event(uint8_t *buffer_out, uint16_t buffer_out_length, int8_t overflow_index)
193 {
194 	ARG_UNUSED(buffer_out_length);
195 	ARG_UNUSED(overflow_index);
196 
197 	const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0));
198 	struct hci_data *hci = dev->data;
199 	/* Construct net_buf from event data */
200 	struct net_buf *buf = get_rx(buffer_out);
201 
202 	if (buf) {
203 		/* Handle the received HCI data */
204 		LOG_DBG("New event %p len %u type %u", buf, buf->len, bt_buf_get_type(buf));
205 		hci->recv(dev, buf);
206 	} else {
207 		LOG_ERR("Buf is null");
208 	}
209 }
210 
HAL_RADIO_TIMER_TxRxWakeUpCallback(void)211 void HAL_RADIO_TIMER_TxRxWakeUpCallback(void)
212 {
213 	k_work_schedule(&hal_radio_timer_work, K_NO_WAIT);
214 	k_work_schedule(&ble_stack_work, K_NO_WAIT);
215 }
216 
HAL_RADIO_TIMER_CpuWakeUpCallback(void)217 void HAL_RADIO_TIMER_CpuWakeUpCallback(void)
218 {
219 	k_work_schedule(&hal_radio_timer_work, K_NO_WAIT);
220 	k_work_schedule(&ble_stack_work, K_NO_WAIT);
221 }
222 
HAL_RADIO_TxRxCallback(uint32_t flags)223 void HAL_RADIO_TxRxCallback(uint32_t flags)
224 {
225 	BLE_STACK_RadioHandler(flags);
226 	k_work_schedule(&ble_stack_work, K_NO_WAIT);
227 	k_work_schedule(&hal_radio_timer_work, K_NO_WAIT);
228 }
229 
ISR_DIRECT_DECLARE(RADIO_TIMER_TXRX_WKUP_IRQHandler)230 ISR_DIRECT_DECLARE(RADIO_TIMER_TXRX_WKUP_IRQHandler)
231 {
232 	HAL_RADIO_TIMER_TXRX_WKUP_IRQHandler();
233 	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency */
234 	return 1;
235 }
236 
ISR_DIRECT_DECLARE(RADIO_TXRX_IRQHandler)237 ISR_DIRECT_DECLARE(RADIO_TXRX_IRQHandler)
238 {
239 	HAL_RADIO_TXRX_IRQHandler();
240 	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency */
241 	return 1;
242 }
243 
ISR_DIRECT_DECLARE(RADIO_TXRX_SEQ_IRQHandler)244 ISR_DIRECT_DECLARE(RADIO_TXRX_SEQ_IRQHandler)
245 {
246 	HAL_RADIO_TXRX_SEQ_IRQHandler();
247 	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency */
248 	return 1;
249 }
250 
ISR_DIRECT_DECLARE(RADIO_TIMER_CPU_WKUP_IRQHandler)251 ISR_DIRECT_DECLARE(RADIO_TIMER_CPU_WKUP_IRQHandler)
252 {
253 	HAL_RADIO_TIMER_TimeoutCallback();
254 	HAL_RADIO_TIMER_CpuWakeUpCallback();
255 	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency */
256 	return 1;
257 }
258 
ISR_DIRECT_DECLARE(RADIO_TIMER_ERROR_IRQHandler)259 ISR_DIRECT_DECLARE(RADIO_TIMER_ERROR_IRQHandler)
260 {
261 	volatile uint32_t debug_cmd;
262 
263 	BLUE->DEBUGCMDREG |= 1;
264 	/* If the device is configured with CLK_SYS = 64MHz
265 	 * and BLE clock = 16MHz, a register read is necessary
266 	 * to ensure interrupt register is properly cleared
267 	 * due to AHB down converter latency
268 	 */
269 	debug_cmd = BLUE->DEBUGCMDREG;
270 	LOG_ERR("Timer error");
271 	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency */
272 	return 1;
273 }
274 
275 /* Function called from PKA_IRQHandler() context. */
PKAMGR_IRQCallback(void)276 void PKAMGR_IRQCallback(void)
277 {
278 	k_work_schedule(&ble_stack_work, K_NO_WAIT);
279 }
280 
_PKA_IRQHandler(void * args)281 static int _PKA_IRQHandler(void *args)
282 {
283 	ARG_UNUSED(args);
284 
285 	HAL_PKA_IRQHandler(&hpka);
286 	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency */
287 	return 1;
288 }
289 
ble_isr_installer(void)290 static void ble_isr_installer(void)
291 {
292 	IRQ_DIRECT_CONNECT(RADIO_TIMER_TXRX_WKUP_IRQn, BLE_WKUP_PRIO,
293 			   RADIO_TIMER_TXRX_WKUP_IRQHandler, BLE_WKUP_FLAGS);
294 	IRQ_DIRECT_CONNECT(RADIO_TXRX_IRQn, BLE_TX_RX_PRIO, RADIO_TXRX_IRQHandler, BLE_TX_RX_FLAGS);
295 	IRQ_DIRECT_CONNECT(RADIO_TIMER_CPU_WKUP_IRQn, CPU_WKUP_PRIO,
296 			   RADIO_TIMER_CPU_WKUP_IRQHandler, CPU_WKUP_FLAGS);
297 	IRQ_DIRECT_CONNECT(RADIO_TXRX_SEQ_IRQn, BLE_RXTX_SEQ_PRIO, RADIO_TXRX_SEQ_IRQHandler,
298 			   BLE_RXTX_SEQ_FLAGS);
299 	IRQ_DIRECT_CONNECT(RADIO_TIMER_ERROR_IRQn, BLE_ERROR_PRIO, RADIO_TIMER_ERROR_IRQHandler,
300 			   BLE_ERROR_FLAGS);
301 	IRQ_CONNECT(PKA_IRQn, PKA_PRIO, _PKA_IRQHandler, NULL, PKA_FLAGS);
302 }
303 
get_rx(uint8_t * msg)304 static struct net_buf *get_rx(uint8_t *msg)
305 {
306 	bool discardable = false;
307 	k_timeout_t timeout = K_FOREVER;
308 	struct net_buf *buf;
309 	int len;
310 
311 	switch (msg[PACKET_TYPE]) {
312 	case BT_HCI_H4_EVT:
313 		if (msg[EVT_HEADER_EVENT] == BT_HCI_EVT_LE_META_EVENT &&
314 		   (msg[EVT_LE_META_SUBEVENT] == BT_HCI_EVT_LE_ADVERTISING_REPORT)) {
315 			discardable = true;
316 			timeout = K_NO_WAIT;
317 		}
318 		buf = bt_buf_get_evt(msg[EVT_HEADER_EVENT], discardable, timeout);
319 		if (!buf) {
320 			LOG_DBG("Discard adv report due to insufficient buf");
321 			return NULL;
322 		}
323 
324 		len = sizeof(struct bt_hci_evt_hdr) + msg[EVT_HEADER_SIZE];
325 		if (len > net_buf_tailroom(buf)) {
326 			LOG_ERR("Event too long: %d", len);
327 			net_buf_unref(buf);
328 			return NULL;
329 		}
330 		net_buf_add_mem(buf, &msg[1], len);
331 		break;
332 	case BT_HCI_H4_ACL:
333 		struct bt_hci_acl_hdr acl_hdr;
334 
335 		buf = bt_buf_get_rx(BT_BUF_ACL_IN, timeout);
336 		memcpy(&acl_hdr, &msg[1], sizeof(acl_hdr));
337 		len = sizeof(acl_hdr) + sys_le16_to_cpu(acl_hdr.len);
338 		if (len > net_buf_tailroom(buf)) {
339 			LOG_ERR("ACL too long: %d", len);
340 			net_buf_unref(buf);
341 			return NULL;
342 		}
343 		net_buf_add_mem(buf, &msg[1], len);
344 		break;
345 	case BT_HCI_H4_ISO:
346 		struct bt_hci_iso_hdr iso_hdr;
347 
348 		buf = bt_buf_get_rx(BT_BUF_ISO_IN, timeout);
349 		if (buf) {
350 			memcpy(&iso_hdr, &msg[1], sizeof(iso_hdr));
351 			len = sizeof(iso_hdr) + sys_le16_to_cpu(iso_hdr.len);
352 		} else {
353 			LOG_ERR("No available ISO buffers!");
354 			return NULL;
355 		}
356 		if (len > net_buf_tailroom(buf)) {
357 			LOG_ERR("ISO too long: %d", len);
358 			net_buf_unref(buf);
359 			return NULL;
360 		}
361 		net_buf_add_mem(buf, &msg[1], len);
362 		break;
363 	default:
364 		LOG_ERR("Unknown BT buf type %d", msg[0]);
365 		return NULL;
366 	}
367 
368 	return buf;
369 }
370 
bt_hci_stm32wb0_send(const struct device * dev,struct net_buf * buf)371 static int bt_hci_stm32wb0_send(const struct device *dev, struct net_buf *buf)
372 {
373 	int ret = 0;
374 	uint8_t *hci_buffer = buf->data;
375 
376 	ARG_UNUSED(dev);
377 
378 	switch (bt_buf_get_type(buf)) {
379 	case BT_BUF_ACL_OUT: {
380 		uint16_t connection_handle;
381 		uint16_t data_len;
382 		uint8_t *pdu;
383 		uint8_t	pb_flag;
384 		uint8_t	bc_flag;
385 
386 		connection_handle = ((hci_buffer[1] & 0x0F) << 8) + hci_buffer[0];
387 		data_len = (hci_buffer[3] << 8) + hci_buffer[2];
388 		pdu = hci_buffer + 4;
389 		pb_flag = (hci_buffer[1] >> 4) & 0x3;
390 		bc_flag = (hci_buffer[1] >> 6) & 0x3;
391 		hci_tx_acl_data(connection_handle, pb_flag, bc_flag, data_len, pdu);
392 		break;
393 	}
394 #if defined(CONFIG_BT_ISO)
395 	case BT_BUF_ISO_OUT: {
396 		uint16_t connection_handle;
397 		uint16_t iso_data_load_len;
398 		uint8_t *iso_data_load;
399 		uint8_t	pb_flag;
400 		uint8_t	ts_flag;
401 
402 		connection_handle = sys_get_le16(hci_buffer) & 0x0FFF;
403 		iso_data_load_len = sys_get_le16(hci_buffer + 2) & 0x3FFF;
404 		pb_flag = (hci_buffer[1] >> 4) & 0x3;
405 		ts_flag = (hci_buffer[1] >> 6) & 0x1;
406 		iso_data_load = &hci_buffer[4];
407 		hci_tx_iso_data(connection_handle, pb_flag, ts_flag, iso_data_load_len,
408 			       iso_data_load);
409 		break;
410 	}
411 #endif /* CONFIG_BT_ISO */
412 	case BT_BUF_CMD:
413 		process_command(hci_buffer, buf->len, buffer_out_mem, sizeof(buffer_out_mem));
414 		send_event(buffer_out_mem, 0, 0);
415 		break;
416 	default:
417 		LOG_ERR("Unsupported type");
418 		return -EINVAL;
419 	}
420 	net_buf_unref(buf);
421 
422 	return ret;
423 }
424 
bt_hci_stm32wb0_open(const struct device * dev,bt_hci_recv_t recv)425 static int bt_hci_stm32wb0_open(const struct device *dev, bt_hci_recv_t recv)
426 {
427 	struct hci_data *data = dev->data;
428 	RADIO_TIMER_InitTypeDef VTIMER_InitStruct = {MAX_HS_STARTUP_TIME, 0, 0};
429 	RADIO_HandleTypeDef hradio = {0};
430 	BLE_STACK_InitTypeDef BLE_STACK_InitParams = {
431 		.BLEStartRamAddress = (uint8_t *)dyn_alloc_a,
432 		.TotalBufferSize = BLE_DYN_ALLOC_SIZE,
433 		.NumAttrRecords = CFG_BLE_NUM_GATT_ATTRIBUTES,
434 		.MaxNumOfClientProcs = CFG_BLE_NUM_OF_CONCURRENT_GATT_CLIENT_PROC,
435 		.NumOfRadioTasks = CFG_BLE_NUM_RADIO_TASKS,
436 		.NumOfEATTChannels = CFG_BLE_NUM_EATT_CHANNELS,
437 		.NumBlockCount = CFG_BLE_MBLOCKS_COUNT,
438 		.ATT_MTU = CFG_BLE_ATT_MTU_MAX,
439 		.MaxConnEventLength = CFG_BLE_CONN_EVENT_LENGTH_MAX,
440 		.SleepClockAccuracy = CFG_BLE_SLEEP_CLOCK_ACCURACY,
441 		.NumOfAdvDataSet = CFG_BLE_NUM_ADV_SETS,
442 		.NumOfSubeventsPAwR = CFG_BLE_NUM_PAWR_SUBEVENTS,
443 		.MaxPAwRSubeventDataCount = CFG_BLE_PAWR_SUBEVENT_DATA_COUNT_MAX,
444 		.NumOfAuxScanSlots = CFG_BLE_NUM_AUX_SCAN_SLOTS,
445 		.FilterAcceptListSizeLog2 = CFG_BLE_FILTER_ACCEPT_LIST_SIZE_LOG2,
446 		.L2CAP_MPS = CFG_BLE_COC_MPS_MAX,
447 		.L2CAP_NumChannels = CFG_BLE_COC_NBR_MAX,
448 		.NumOfSyncSlots = CFG_BLE_NUM_SYNC_SLOTS,
449 		.CTE_MaxNumAntennaIDs = CFG_BLE_NUM_CTE_ANTENNA_IDS_MAX,
450 		.CTE_MaxNumIQSamples = CFG_BLE_NUM_CTE_IQ_SAMPLES_MAX,
451 		.NumOfSyncBIG = CFG_BLE_NUM_SYNC_BIG_MAX,
452 		.NumOfBrcBIG = CFG_BLE_NUM_BRC_BIG_MAX,
453 		.NumOfSyncBIS = CFG_BLE_NUM_SYNC_BIS_MAX,
454 		.NumOfBrcBIS = CFG_BLE_NUM_BRC_BIS_MAX,
455 		.NumOfCIG = CFG_BLE_NUM_CIG_MAX,
456 		.NumOfCIS = CFG_BLE_NUM_CIS_MAX,
457 		.isr0_fifo_size = CFG_BLE_ISR0_FIFO_SIZE,
458 		.isr1_fifo_size = CFG_BLE_ISR1_FIFO_SIZE,
459 		.user_fifo_size = CFG_BLE_USER_FIFO_SIZE
460 	};
461 
462 	ble_isr_installer();
463 	hradio.Instance = RADIO;
464 	HAL_RADIO_Init(&hradio);
465 	HAL_RADIO_TIMER_Init(&VTIMER_InitStruct);
466 
467 	HW_RNG_Init();
468 	HW_AES_Init();
469 	hpka.Instance = PKA;
470 	HAL_PKA_Init(&hpka);
471 	HW_PKA_Init();
472 	if (BLE_STACK_Init(&BLE_STACK_InitParams)) {
473 		LOG_ERR("BLE Init Failed....");
474 		return -EIO;
475 	}
476 
477 #if CONFIG_BT_EXT_ADV
478 	dm_init(CFG_BLE_ADV_NWK_BUFFER_SIZE, aci_adv_nwk_buffer);
479 #endif /* CONFIG_BT_EXT_ADV */
480 
481 	aci_adv_nwk_init();
482 
483 	data->recv = recv;
484 	k_work_init_delayable(&hal_radio_timer_work, vtimer_process);
485 	k_work_init_delayable(&ble_stack_work, blestack_process);
486 	k_work_schedule(&ble_stack_work, K_NO_WAIT);
487 
488 	return 0;
489 }
490 
491 static DEVICE_API(bt_hci, drv) = {
492 	.open = bt_hci_stm32wb0_open,
493 	.send = bt_hci_stm32wb0_send,
494 };
495 
496 #define HCI_DEVICE_INIT(inst) \
497 	static struct hci_data hci_data_##inst = { \
498 	}; \
499 	DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &hci_data_##inst, NULL, \
500 				POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv)
501 
502 /* Only one instance supported */
503 HCI_DEVICE_INIT(0)
504