1 /* ipm_stm32wb.c - HCI driver for stm32wb shared ram */
2 
3 /*
4  * Copyright (c) 2019 Linaro Ltd.
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 
10 #include <init.h>
11 #include <sys/util.h>
12 #include <bluetooth/hci.h>
13 #include <drivers/bluetooth/hci_driver.h>
14 #include "bluetooth/addr.h"
15 #include <drivers/clock_control/stm32_clock_control.h>
16 
17 #include "app_conf.h"
18 #include "stm32_wpan_common.h"
19 #include "shci.h"
20 #include "shci_tl.h"
21 
22 #define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH * 4 * \
23 		DIVC((sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE), 4))
24 
25 /* Private variables ---------------------------------------------------------*/
26 PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer;
27 PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t EvtPool[POOL_SIZE];
28 PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t SystemCmdBuffer;
29 PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t
30 	SystemSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
31 PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t
32 	BleSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
33 PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t
34 	HciAclDataBuffer[sizeof(TL_PacketHeader_t) + 5 + 251];
35 
36 static void syscmd_status_not(SHCI_TL_CmdStatus_t status);
37 static void sysevt_received(void *pdata);
38 
39 #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
40 #define LOG_MODULE_NAME hci_ipm
41 #include "common/log.h"
42 
43 #define HCI_CMD                 0x01
44 #define HCI_ACL                 0x02
45 #define HCI_SCO                 0x03
46 #define HCI_EVT                 0x04
47 
48 #define STM32WB_C2_LOCK_TIMEOUT K_MSEC(500)
49 
50 static K_SEM_DEFINE(c2_started, 0, 1);
51 static K_SEM_DEFINE(ble_sys_wait_cmd_rsp, 0, 1);
52 static K_SEM_DEFINE(acl_data_ack, 1, 1);
53 static K_SEM_DEFINE(ipm_busy, 1, 1);
54 
55 struct aci_set_tx_power {
56 	uint8_t cmd;
57 	uint8_t value[2];
58 };
59 
60 struct aci_set_ble_addr {
61 	uint8_t config_offset;
62 	uint8_t length;
63 	uint8_t value[6];
64 } __packed;
65 
66 #define ACI_WRITE_SET_TX_POWER_LEVEL       BT_OP(BT_OGF_VS, 0xFC0F)
67 #define ACI_HAL_WRITE_CONFIG_DATA	   BT_OP(BT_OGF_VS, 0xFC0C)
68 
69 #define HCI_CONFIG_DATA_PUBADDR_OFFSET		0
70 #define HCI_CONFIG_DATA_RANDOM_ADDRESS_OFFSET	0x2E
71 
72 static bt_addr_t bd_addr_udn;
73 
74 /* Rx thread definitions */
75 K_FIFO_DEFINE(ipm_rx_events_fifo);
76 static K_KERNEL_STACK_DEFINE(ipm_rx_stack, CONFIG_BT_STM32_IPM_RX_STACK_SIZE);
77 static struct k_thread ipm_rx_thread_data;
78 
stm32wb_start_ble(void)79 static void stm32wb_start_ble(void)
80 {
81 	SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = {
82 	  { { 0, 0, 0 } },                     /**< Header unused */
83 	  { 0,                                 /** pBleBufferAddress not used */
84 	    0,                                 /** BleBufferSize not used */
85 	    CFG_BLE_NUM_GATT_ATTRIBUTES,
86 	    CFG_BLE_NUM_GATT_SERVICES,
87 	    CFG_BLE_ATT_VALUE_ARRAY_SIZE,
88 	    CFG_BLE_NUM_LINK,
89 	    CFG_BLE_DATA_LENGTH_EXTENSION,
90 	    CFG_BLE_PREPARE_WRITE_LIST_SIZE,
91 	    CFG_BLE_MBLOCK_COUNT,
92 	    CFG_BLE_MAX_ATT_MTU,
93 	    CFG_BLE_SLAVE_SCA,
94 	    CFG_BLE_MASTER_SCA,
95 	    CFG_BLE_LSE_SOURCE,
96 	    CFG_BLE_MAX_CONN_EVENT_LENGTH,
97 	    CFG_BLE_HSE_STARTUP_TIME,
98 	    CFG_BLE_VITERBI_MODE,
99 	    CFG_BLE_OPTIONS,
100 	    0 }
101 	};
102 
103 	/**
104 	 * Starts the BLE Stack on CPU2
105 	 */
106 	SHCI_C2_BLE_Init(&ble_init_cmd_packet);
107 }
108 
sysevt_received(void * pdata)109 static void sysevt_received(void *pdata)
110 {
111 	k_sem_give(&c2_started);
112 }
113 
syscmd_status_not(SHCI_TL_CmdStatus_t status)114 static void syscmd_status_not(SHCI_TL_CmdStatus_t status)
115 {
116 	BT_DBG("status:%d", status);
117 }
118 
119 /*
120  * https://github.com/zephyrproject-rtos/zephyr/issues/19509
121  * Tested on nucleo_wb55rg (stm32wb55rg) BLE stack (v1.2.0)
122  * Unresolved Resolvable Private Addresses (RPA)
123  * is reported in the peer_rpa field, and not in the peer address,
124  * as it should, when this happens the peer address is set to all FFs
125  * 0A 00 01 08 01 01 FF FF FF FF FF FF 00 00 00 00 00 00 0C AA C5 B3 3D 6B ...
126  * If such message is passed to HCI core than pairing will essentially fail.
127  * Solution: Rewrite the event with the RPA in the PEER address field
128  */
tryfix_event(TL_Evt_t * tev)129 static void tryfix_event(TL_Evt_t *tev)
130 {
131 	struct bt_hci_evt_le_meta_event *mev = (void *)&tev->payload;
132 
133 	if (tev->evtcode != BT_HCI_EVT_LE_META_EVENT ||
134 	    mev->subevent != BT_HCI_EVT_LE_ENH_CONN_COMPLETE) {
135 		return;
136 	}
137 
138 	struct bt_hci_evt_le_enh_conn_complete *evt =
139 			(void *)((uint8_t *)mev + (sizeof(*mev)));
140 
141 	if (!bt_addr_cmp(&evt->peer_addr.a, BT_ADDR_NONE)) {
142 		BT_WARN("Invalid peer addr %s", bt_addr_le_str(&evt->peer_addr));
143 		bt_addr_copy(&evt->peer_addr.a, &evt->peer_rpa);
144 		evt->peer_addr.type = BT_ADDR_LE_RANDOM;
145 	}
146 }
147 
TM_EvtReceivedCb(TL_EvtPacket_t * hcievt)148 void TM_EvtReceivedCb(TL_EvtPacket_t *hcievt)
149 {
150 	k_fifo_put(&ipm_rx_events_fifo, hcievt);
151 }
152 
bt_ipm_rx_thread(void)153 static void bt_ipm_rx_thread(void)
154 {
155 	while (true) {
156 		bool discardable = false;
157 		k_timeout_t timeout = K_FOREVER;
158 		static TL_EvtPacket_t *hcievt;
159 		struct net_buf *buf = NULL;
160 		struct bt_hci_acl_hdr acl_hdr;
161 		TL_AclDataSerial_t *acl;
162 		struct bt_hci_evt_le_meta_event *mev;
163 
164 		hcievt = k_fifo_get(&ipm_rx_events_fifo, K_FOREVER);
165 
166 		k_sem_take(&ipm_busy, K_FOREVER);
167 
168 		switch (hcievt->evtserial.type) {
169 		case HCI_EVT:
170 			BT_DBG("EVT: hcievt->evtserial.evt.evtcode: 0x%02x",
171 			       hcievt->evtserial.evt.evtcode);
172 			switch (hcievt->evtserial.evt.evtcode) {
173 			case BT_HCI_EVT_VENDOR:
174 				/* Vendor events are currently unsupported */
175 				BT_ERR("Unknown evtcode type 0x%02x",
176 				       hcievt->evtserial.evt.evtcode);
177 				TL_MM_EvtDone(hcievt);
178 				goto end_loop;
179 			default:
180 				mev = (void *)&hcievt->evtserial.evt.payload;
181 				if (hcievt->evtserial.evt.evtcode == BT_HCI_EVT_LE_META_EVENT &&
182 				    (mev->subevent == BT_HCI_EVT_LE_ADVERTISING_REPORT ||
183 				     mev->subevent == BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT)) {
184 					discardable = true;
185 					timeout = K_NO_WAIT;
186 				}
187 
188 				buf = bt_buf_get_evt(
189 					hcievt->evtserial.evt.evtcode,
190 					discardable, timeout);
191 				if (!buf) {
192 					BT_DBG("Discard adv report due to insufficient buf");
193 					goto end_loop;
194 				}
195 			}
196 
197 			tryfix_event(&hcievt->evtserial.evt);
198 			net_buf_add_mem(buf, &hcievt->evtserial.evt,
199 					hcievt->evtserial.evt.plen + 2);
200 			break;
201 		case HCI_ACL:
202 			acl = &(((TL_AclDataPacket_t *)hcievt)->AclDataSerial);
203 			buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
204 			acl_hdr.handle = acl->handle;
205 			acl_hdr.len = acl->length;
206 			BT_DBG("ACL: handle %x, len %x",
207 			       acl_hdr.handle, acl_hdr.len);
208 			net_buf_add_mem(buf, &acl_hdr, sizeof(acl_hdr));
209 			net_buf_add_mem(buf, (uint8_t *)&acl->acl_data,
210 					acl_hdr.len);
211 			break;
212 		default:
213 			BT_ERR("Unknown BT buf type %d",
214 			       hcievt->evtserial.type);
215 			TL_MM_EvtDone(hcievt);
216 			goto end_loop;
217 		}
218 
219 		TL_MM_EvtDone(hcievt);
220 
221 		bt_recv(buf);
222 end_loop:
223 		k_sem_give(&ipm_busy);
224 	}
225 
226 }
227 
TM_AclDataAck(void)228 static void TM_AclDataAck(void)
229 {
230 	k_sem_give(&acl_data_ack);
231 }
232 
shci_notify_asynch_evt(void * pdata)233 void shci_notify_asynch_evt(void *pdata)
234 {
235 	shci_user_evt_proc();
236 }
237 
shci_cmd_resp_release(uint32_t flag)238 void shci_cmd_resp_release(uint32_t flag)
239 {
240 	k_sem_give(&ble_sys_wait_cmd_rsp);
241 }
242 
shci_cmd_resp_wait(uint32_t timeout)243 void shci_cmd_resp_wait(uint32_t timeout)
244 {
245 	k_sem_take(&ble_sys_wait_cmd_rsp, K_MSEC(timeout));
246 }
247 
ipcc_reset(void)248 void ipcc_reset(void)
249 {
250 	/* Reset IPCC */
251 	LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_IPCC);
252 
253 	LL_C1_IPCC_ClearFlag_CHx(
254 		IPCC,
255 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
256 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
257 
258 	LL_C2_IPCC_ClearFlag_CHx(
259 		IPCC,
260 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
261 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
262 
263 	LL_C1_IPCC_DisableTransmitChannel(
264 		IPCC,
265 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
266 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
267 
268 	LL_C2_IPCC_DisableTransmitChannel(
269 		IPCC,
270 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
271 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
272 
273 	LL_C1_IPCC_DisableReceiveChannel(
274 		IPCC,
275 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
276 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
277 
278 	LL_C2_IPCC_DisableReceiveChannel(
279 		IPCC,
280 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
281 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
282 
283 	/* Set IPCC default IRQ handlers */
284 	IRQ_CONNECT(IPCC_C1_RX_IRQn, 0, HW_IPCC_Rx_Handler, NULL, 0);
285 	IRQ_CONNECT(IPCC_C1_TX_IRQn, 0, HW_IPCC_Tx_Handler, NULL, 0);
286 }
287 
transport_init(void)288 void transport_init(void)
289 {
290 	TL_MM_Config_t tl_mm_config;
291 	TL_BLE_InitConf_t tl_ble_config;
292 	SHCI_TL_HciInitConf_t shci_init_config;
293 
294 	BT_DBG("BleCmdBuffer: %p", (void *)&BleCmdBuffer);
295 	BT_DBG("HciAclDataBuffer: %p", (void *)&HciAclDataBuffer);
296 	BT_DBG("SystemCmdBuffer: %p", (void *)&SystemCmdBuffer);
297 	BT_DBG("EvtPool: %p", (void *)&EvtPool);
298 	BT_DBG("SystemSpareEvtBuffer: %p", (void *)&SystemSpareEvtBuffer);
299 	BT_DBG("BleSpareEvtBuffer: %p", (void *)&BleSpareEvtBuffer);
300 
301 	/**< Reference table initialization */
302 	TL_Init();
303 
304 	/**< System channel initialization */
305 	shci_init_config.p_cmdbuffer = (uint8_t *)&SystemCmdBuffer;
306 	shci_init_config.StatusNotCallBack = syscmd_status_not;
307 	shci_init(sysevt_received, (void *) &shci_init_config);
308 
309 	/**< Memory Manager channel initialization */
310 	tl_mm_config.p_BleSpareEvtBuffer = BleSpareEvtBuffer;
311 	tl_mm_config.p_SystemSpareEvtBuffer = SystemSpareEvtBuffer;
312 	tl_mm_config.p_AsynchEvtPool = EvtPool;
313 	tl_mm_config.AsynchEvtPoolSize = POOL_SIZE;
314 	TL_MM_Init(&tl_mm_config);
315 
316 	/**< BLE channel initialization */
317 	tl_ble_config.p_cmdbuffer = (uint8_t *)&BleCmdBuffer;
318 	tl_ble_config.p_AclDataBuffer = HciAclDataBuffer;
319 	tl_ble_config.IoBusEvtCallBack = TM_EvtReceivedCb;
320 	tl_ble_config.IoBusAclDataTxAck = TM_AclDataAck;
321 	TL_BLE_Init((void *)&tl_ble_config);
322 
323 	TL_Enable();
324 }
325 
bt_ipm_send(struct net_buf * buf)326 static int bt_ipm_send(struct net_buf *buf)
327 {
328 	TL_CmdPacket_t *ble_cmd_buff = &BleCmdBuffer;
329 
330 	k_sem_take(&ipm_busy, K_FOREVER);
331 
332 	switch (bt_buf_get_type(buf)) {
333 	case BT_BUF_ACL_OUT:
334 		BT_DBG("ACL: buf %p type %u len %u", buf, bt_buf_get_type(buf),
335 		       buf->len);
336 		k_sem_take(&acl_data_ack, K_FOREVER);
337 		net_buf_push_u8(buf, HCI_ACL);
338 		memcpy((void *)
339 		       &((TL_AclDataPacket_t *)HciAclDataBuffer)->AclDataSerial,
340 		       buf->data, buf->len);
341 		TL_BLE_SendAclData(NULL, 0);
342 		break;
343 	case BT_BUF_CMD:
344 		BT_DBG("CMD: buf %p type %u len %u", buf, bt_buf_get_type(buf),
345 		       buf->len);
346 		ble_cmd_buff->cmdserial.type = HCI_CMD;
347 		ble_cmd_buff->cmdserial.cmd.plen = buf->len;
348 		memcpy((void *)&ble_cmd_buff->cmdserial.cmd, buf->data,
349 		       buf->len);
350 		TL_BLE_SendCmd(NULL, 0);
351 		break;
352 	default:
353 		k_sem_give(&ipm_busy);
354 		BT_ERR("Unsupported type");
355 		return -EINVAL;
356 	}
357 
358 	k_sem_give(&ipm_busy);
359 
360 	net_buf_unref(buf);
361 
362 	return 0;
363 }
364 
start_ble_rf(void)365 static void start_ble_rf(void)
366 {
367 	if ((LL_RCC_IsActiveFlag_PINRST()) && (!LL_RCC_IsActiveFlag_SFTRST())) {
368 		/* Simulate power off reset */
369 		LL_PWR_EnableBkUpAccess();
370 		LL_PWR_EnableBkUpAccess();
371 		LL_RCC_ForceBackupDomainReset();
372 		LL_RCC_ReleaseBackupDomainReset();
373 	}
374 
375 #if STM32_LSE_CLOCK
376 	/* Select LSE clock */
377 	LL_RCC_LSE_Enable();
378 	while (!LL_RCC_LSE_IsReady()) {
379 	}
380 
381 	/* Select wakeup source of BLE RF */
382 	LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE);
383 	LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
384 
385 	/* Switch OFF LSI */
386 	LL_RCC_LSI2_Disable();
387 #else
388 	LL_RCC_LSI2_Enable();
389 	while (!LL_RCC_LSI2_IsReady()) {
390 	}
391 
392 	/* Select wakeup source of BLE RF */
393 	LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSI);
394 	LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSI);
395 #endif
396 
397 	/* Set RNG on HSI48 */
398 	LL_RCC_HSI48_Enable();
399 	while (!LL_RCC_HSI48_IsReady()) {
400 	}
401 
402 	LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_HSI48);
403 }
404 
bt_get_ble_addr(void)405 bt_addr_t *bt_get_ble_addr(void)
406 {
407 	bt_addr_t *bd_addr;
408 	uint32_t udn;
409 	uint32_t company_id;
410 	uint32_t device_id;
411 
412 	/* Get the 64 bit Unique Device Number UID */
413 	/* The UID is used by firmware to derive   */
414 	/* 48-bit Device Address EUI-48 */
415 	udn = LL_FLASH_GetUDN();
416 
417 	if (udn != 0xFFFFFFFF) {
418 		/* Get the ST Company ID */
419 		company_id = LL_FLASH_GetSTCompanyID();
420 		/* Get the STM32 Device ID */
421 		device_id = LL_FLASH_GetDeviceID();
422 		bd_addr_udn.val[0] = (uint8_t)(udn & 0x000000FF);
423 		bd_addr_udn.val[1] = (uint8_t)((udn & 0x0000FF00) >> 8);
424 		bd_addr_udn.val[2] = (uint8_t)((udn & 0x00FF0000) >> 16);
425 		bd_addr_udn.val[3] = (uint8_t)device_id;
426 		bd_addr_udn.val[4] = (uint8_t)(company_id & 0x000000FF);
427 		bd_addr_udn.val[5] = (uint8_t)((company_id & 0x0000FF00) >> 8);
428 		bd_addr = &bd_addr_udn;
429 	} else {
430 		bd_addr = NULL;
431 	}
432 
433 	return bd_addr;
434 }
435 
bt_ipm_set_addr(void)436 static int bt_ipm_set_addr(void)
437 {
438 	bt_addr_t *uid_addr;
439 	struct aci_set_ble_addr *param;
440 	struct net_buf *buf, *rsp;
441 	int err;
442 
443 	uid_addr = bt_get_ble_addr();
444 	if (!uid_addr) {
445 		return -ENOMSG;
446 	}
447 
448 	buf = bt_hci_cmd_create(ACI_HAL_WRITE_CONFIG_DATA, sizeof(*param));
449 
450 	if (!buf) {
451 		return -ENOBUFS;
452 	}
453 
454 	param = net_buf_add(buf, sizeof(*param));
455 	param->config_offset = HCI_CONFIG_DATA_PUBADDR_OFFSET;
456 	param->length = 6;
457 	param->value[0] = uid_addr->val[0];
458 	param->value[1] = uid_addr->val[1];
459 	param->value[2] = uid_addr->val[2];
460 	param->value[3] = uid_addr->val[3];
461 	param->value[4] = uid_addr->val[4];
462 	param->value[5] = uid_addr->val[5];
463 
464 	err = bt_hci_cmd_send_sync(ACI_HAL_WRITE_CONFIG_DATA, buf, &rsp);
465 	if (err) {
466 		return err;
467 	}
468 	net_buf_unref(rsp);
469 	return 0;
470 }
471 
bt_ipm_ble_init(void)472 static int bt_ipm_ble_init(void)
473 {
474 	struct aci_set_tx_power *param;
475 	struct net_buf *buf, *rsp;
476 	int err;
477 
478 	/* Send HCI_RESET */
479 	err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, &rsp);
480 	if (err) {
481 		return err;
482 	}
483 	/* TDB: Something to do on reset complete? */
484 	net_buf_unref(rsp);
485 	err = bt_ipm_set_addr();
486 	if (err) {
487 		BT_ERR("Can't set BLE UID addr");
488 	}
489 	/* Send ACI_WRITE_SET_TX_POWER_LEVEL */
490 	buf = bt_hci_cmd_create(ACI_WRITE_SET_TX_POWER_LEVEL, 3);
491 	if (!buf) {
492 		return -ENOBUFS;
493 	}
494 	param = net_buf_add(buf, sizeof(*param));
495 	param->cmd = 0x0F;
496 	param->value[0] = 0x18;
497 	param->value[1] = 0x01;
498 
499 	err = bt_hci_cmd_send_sync(ACI_WRITE_SET_TX_POWER_LEVEL, buf, &rsp);
500 	if (err) {
501 		return err;
502 	}
503 	net_buf_unref(rsp);
504 
505 	return 0;
506 }
507 
bt_ipm_open(void)508 static int bt_ipm_open(void)
509 {
510 	int err;
511 
512 	err = bt_ipm_ble_init();
513 	if (err) {
514 		return err;
515 	}
516 
517 	BT_DBG("IPM Channel Open Completed");
518 
519 	return 0;
520 }
521 
522 static const struct bt_hci_driver drv = {
523 	.name           = "BT IPM",
524 	.bus            = BT_HCI_DRIVER_BUS_IPM,
525 	.quirks         = BT_QUIRK_NO_RESET,
526 	.open           = bt_ipm_open,
527 	.send           = bt_ipm_send,
528 };
529 
_bt_ipm_init(const struct device * unused)530 static int _bt_ipm_init(const struct device *unused)
531 {
532 	ARG_UNUSED(unused);
533 
534 	bt_hci_driver_register(&drv);
535 
536 	start_ble_rf();
537 
538 	/* Start RX thread */
539 	k_thread_create(&ipm_rx_thread_data, ipm_rx_stack,
540 			K_KERNEL_STACK_SIZEOF(ipm_rx_stack),
541 			(k_thread_entry_t)bt_ipm_rx_thread, NULL, NULL, NULL,
542 			K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO),
543 			0, K_NO_WAIT);
544 
545 	/* Take BLE out of reset */
546 	ipcc_reset();
547 
548 	transport_init();
549 
550 	/* Device will let us know when it's ready */
551 	if (k_sem_take(&c2_started, STM32WB_C2_LOCK_TIMEOUT)) {
552 		return -ETIMEDOUT;
553 	}
554 	BT_DBG("C2 unlocked");
555 
556 	stm32wb_start_ble();
557 
558 	return 0;
559 }
560 
561 SYS_INIT(_bt_ipm_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
562