1 /* ipm_stm32wb.c - HCI driver for stm32wb shared ram */
2 
3 /*
4  * Copyright (c) 2019-2022 Linaro Ltd.
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #define DT_DRV_COMPAT st_stm32wb_rf
10 
11 #include <zephyr/init.h>
12 #include <zephyr/sys/util.h>
13 #include <zephyr/bluetooth/hci.h>
14 #include <zephyr/drivers/bluetooth.h>
15 #include <zephyr/bluetooth/addr.h>
16 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
17 #include <zephyr/irq.h>
18 
19 #include "app_conf.h"
20 #include "stm32_wpan_common.h"
21 #include "shci.h"
22 #include "shci_tl.h"
23 
24 struct hci_data {
25 	bt_hci_recv_t recv;
26 };
27 
28 static const struct stm32_pclken clk_cfg[] = STM32_DT_CLOCKS(DT_DRV_INST(0));
29 
30 #define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH * 4 * \
31 		DIVC((sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE), 4))
32 
33 /* Private variables ---------------------------------------------------------*/
34 PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer;
35 PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t EvtPool[POOL_SIZE];
36 PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t SystemCmdBuffer;
37 PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t
38 	SystemSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
39 PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t
40 	BleSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
41 PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t
42 	HciAclDataBuffer[sizeof(TL_PacketHeader_t) + 5 + 251];
43 
44 static void syscmd_status_not(SHCI_TL_CmdStatus_t status);
45 static void sysevt_received(void *pdata);
46 
47 #include "common/bt_str.h"
48 
49 #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
50 #include <zephyr/logging/log.h>
51 LOG_MODULE_REGISTER(hci_ipm);
52 
53 #define STM32WB_C2_LOCK_TIMEOUT K_MSEC(500)
54 
55 static K_SEM_DEFINE(c2_started, 0, 1);
56 static K_SEM_DEFINE(ble_sys_wait_cmd_rsp, 0, 1);
57 static K_SEM_DEFINE(acl_data_ack, 1, 1);
58 static K_SEM_DEFINE(ipm_busy, 1, 1);
59 
60 struct aci_set_tx_power {
61 	uint8_t cmd;
62 	uint8_t value[2];
63 };
64 
65 struct aci_set_ble_addr {
66 	uint8_t config_offset;
67 	uint8_t length;
68 	uint8_t value[6];
69 } __packed;
70 
71 #ifdef CONFIG_BT_HCI_HOST
72 #define ACI_WRITE_SET_TX_POWER_LEVEL       BT_OP(BT_OGF_VS, 0xFC0F)
73 #define ACI_HAL_WRITE_CONFIG_DATA	   BT_OP(BT_OGF_VS, 0xFC0C)
74 #define ACI_HAL_STACK_RESET		   BT_OP(BT_OGF_VS, 0xFC3B)
75 
76 #define HCI_CONFIG_DATA_PUBADDR_OFFSET		0
77 static bt_addr_t bd_addr_udn;
78 #endif /* CONFIG_BT_HCI_HOST */
79 
80 /* Rx thread definitions */
81 K_FIFO_DEFINE(ipm_rx_events_fifo);
82 static K_KERNEL_STACK_DEFINE(ipm_rx_stack, CONFIG_BT_DRV_RX_STACK_SIZE);
83 static struct k_thread ipm_rx_thread_data;
84 
85 static bool c2_started_flag;
86 
stm32wb_start_ble(uint32_t rf_clock)87 static void stm32wb_start_ble(uint32_t rf_clock)
88 {
89 	SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = {
90 	  { { 0, 0, 0 } },                     /**< Header unused */
91 	  { 0,                                 /** pBleBufferAddress not used */
92 	    0,                                 /** BleBufferSize not used */
93 	    CFG_BLE_NUM_GATT_ATTRIBUTES,
94 	    CFG_BLE_NUM_GATT_SERVICES,
95 	    CFG_BLE_ATT_VALUE_ARRAY_SIZE,
96 	    CFG_BLE_NUM_LINK,
97 	    CFG_BLE_DATA_LENGTH_EXTENSION,
98 	    CFG_BLE_PREPARE_WRITE_LIST_SIZE,
99 	    CFG_BLE_MBLOCK_COUNT,
100 	    CFG_BLE_MAX_ATT_MTU,
101 	    CFG_BLE_PERIPHERAL_SCA,
102 	    CFG_BLE_CENTRAL_SCA,
103 	    (rf_clock == STM32_SRC_LSE) ? CFG_BLE_LS_SOURCE : 0,
104 	    CFG_BLE_MAX_CONN_EVENT_LENGTH,
105 	    CFG_BLE_HSE_STARTUP_TIME,
106 	    CFG_BLE_VITERBI_MODE,
107 	    CFG_BLE_OPTIONS,
108 	    0 }
109 	};
110 
111 	/**
112 	 * Starts the BLE Stack on CPU2
113 	 */
114 	SHCI_C2_BLE_Init(&ble_init_cmd_packet);
115 }
116 
sysevt_received(void * pdata)117 static void sysevt_received(void *pdata)
118 {
119 	k_sem_give(&c2_started);
120 }
121 
syscmd_status_not(SHCI_TL_CmdStatus_t status)122 static void syscmd_status_not(SHCI_TL_CmdStatus_t status)
123 {
124 	LOG_DBG("status:%d", status);
125 }
126 
127 /*
128  * https://github.com/zephyrproject-rtos/zephyr/issues/19509
129  * Tested on nucleo_wb55rg (stm32wb55rg) BLE stack (v1.2.0)
130  * Unresolved Resolvable Private Addresses (RPA)
131  * is reported in the peer_rpa field, and not in the peer address,
132  * as it should, when this happens the peer address is set to all FFs
133  * 0A 00 01 08 01 01 FF FF FF FF FF FF 00 00 00 00 00 00 0C AA C5 B3 3D 6B ...
134  * If such message is passed to HCI core than pairing will essentially fail.
135  * Solution: Rewrite the event with the RPA in the PEER address field
136  */
tryfix_event(TL_Evt_t * tev)137 static void tryfix_event(TL_Evt_t *tev)
138 {
139 	struct bt_hci_evt_le_meta_event *mev = (void *)&tev->payload;
140 
141 	if (tev->evtcode != BT_HCI_EVT_LE_META_EVENT ||
142 	    mev->subevent != BT_HCI_EVT_LE_ENH_CONN_COMPLETE) {
143 		return;
144 	}
145 
146 	struct bt_hci_evt_le_enh_conn_complete *evt =
147 			(void *)((uint8_t *)mev + (sizeof(*mev)));
148 
149 	if (bt_addr_eq(&evt->peer_addr.a, BT_ADDR_NONE)) {
150 		LOG_WRN("Invalid peer addr %s", bt_addr_le_str(&evt->peer_addr));
151 		bt_addr_copy(&evt->peer_addr.a, &evt->peer_rpa);
152 		evt->peer_addr.type = BT_ADDR_LE_RANDOM;
153 	}
154 }
155 
TM_EvtReceivedCb(TL_EvtPacket_t * hcievt)156 void TM_EvtReceivedCb(TL_EvtPacket_t *hcievt)
157 {
158 	k_fifo_put(&ipm_rx_events_fifo, hcievt);
159 }
160 
bt_ipm_rx_thread(void * p1,void * p2,void * p3)161 static void bt_ipm_rx_thread(void *p1, void *p2, void *p3)
162 {
163 	const struct device *dev = p1;
164 	struct hci_data *hci = dev->data;
165 
166 	ARG_UNUSED(p2);
167 	ARG_UNUSED(p3);
168 
169 	while (true) {
170 		bool discardable = false;
171 		k_timeout_t timeout = K_FOREVER;
172 		static TL_EvtPacket_t *hcievt;
173 		struct net_buf *buf = NULL;
174 		struct bt_hci_acl_hdr acl_hdr;
175 		TL_AclDataSerial_t *acl;
176 		struct bt_hci_evt_le_meta_event *mev;
177 		size_t buf_tailroom;
178 		size_t buf_add_len;
179 
180 		hcievt = k_fifo_get(&ipm_rx_events_fifo, K_FOREVER);
181 
182 		k_sem_take(&ipm_busy, K_FOREVER);
183 
184 		switch (hcievt->evtserial.type) {
185 		case BT_HCI_H4_EVT:
186 			LOG_DBG("EVT: hcievt->evtserial.evt.evtcode: 0x%02x",
187 				hcievt->evtserial.evt.evtcode);
188 			switch (hcievt->evtserial.evt.evtcode) {
189 			case BT_HCI_EVT_VENDOR:
190 				/* Vendor events are currently unsupported */
191 				LOG_ERR("Unknown evtcode type 0x%02x",
192 					hcievt->evtserial.evt.evtcode);
193 				TL_MM_EvtDone(hcievt);
194 				goto end_loop;
195 			default:
196 				mev = (void *)&hcievt->evtserial.evt.payload;
197 				if (hcievt->evtserial.evt.evtcode == BT_HCI_EVT_LE_META_EVENT &&
198 				    (mev->subevent == BT_HCI_EVT_LE_ADVERTISING_REPORT)) {
199 					discardable = true;
200 					timeout = K_NO_WAIT;
201 				}
202 
203 				buf = bt_buf_get_evt(
204 					hcievt->evtserial.evt.evtcode,
205 					discardable, timeout);
206 				if (!buf) {
207 					LOG_DBG("Discard adv report due to insufficient buf");
208 					goto end_loop;
209 				}
210 			}
211 
212 			tryfix_event(&hcievt->evtserial.evt);
213 
214 			buf_tailroom = net_buf_tailroom(buf);
215 			buf_add_len = hcievt->evtserial.evt.plen + 2;
216 			if (buf_tailroom < buf_add_len) {
217 				LOG_ERR("Not enough space in buffer %zu/%zu", buf_add_len,
218 					buf_tailroom);
219 				net_buf_unref(buf);
220 				goto end_loop;
221 			}
222 
223 			net_buf_add_mem(buf, &hcievt->evtserial.evt,
224 					buf_add_len);
225 			break;
226 		case BT_HCI_H4_ACL:
227 			acl = &(((TL_AclDataPacket_t *)hcievt)->AclDataSerial);
228 			buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
229 			acl_hdr.handle = acl->handle;
230 			acl_hdr.len = acl->length;
231 			LOG_DBG("ACL: handle %x, len %x", acl_hdr.handle, acl_hdr.len);
232 			net_buf_add_mem(buf, &acl_hdr, sizeof(acl_hdr));
233 
234 			buf_tailroom = net_buf_tailroom(buf);
235 			buf_add_len = acl_hdr.len;
236 			if (buf_tailroom < buf_add_len) {
237 				LOG_ERR("Not enough space in buffer %zu/%zu", buf_add_len,
238 					buf_tailroom);
239 				net_buf_unref(buf);
240 				goto end_loop;
241 			}
242 
243 			net_buf_add_mem(buf, (uint8_t *)&acl->acl_data,
244 					buf_add_len);
245 			break;
246 		default:
247 			LOG_ERR("Unknown BT buf type %d", hcievt->evtserial.type);
248 			TL_MM_EvtDone(hcievt);
249 			goto end_loop;
250 		}
251 
252 		TL_MM_EvtDone(hcievt);
253 
254 		hci->recv(dev, buf);
255 end_loop:
256 		k_sem_give(&ipm_busy);
257 	}
258 
259 }
260 
TM_AclDataAck(void)261 static void TM_AclDataAck(void)
262 {
263 	k_sem_give(&acl_data_ack);
264 }
265 
shci_notify_asynch_evt(void * pdata)266 void shci_notify_asynch_evt(void *pdata)
267 {
268 	shci_user_evt_proc();
269 }
270 
shci_cmd_resp_release(uint32_t flag)271 void shci_cmd_resp_release(uint32_t flag)
272 {
273 	k_sem_give(&ble_sys_wait_cmd_rsp);
274 }
275 
shci_cmd_resp_wait(uint32_t timeout)276 void shci_cmd_resp_wait(uint32_t timeout)
277 {
278 	k_sem_take(&ble_sys_wait_cmd_rsp, K_MSEC(timeout));
279 }
280 
ipcc_reset(void)281 void ipcc_reset(void)
282 {
283 	LL_C1_IPCC_ClearFlag_CHx(
284 		IPCC,
285 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
286 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
287 
288 	LL_C2_IPCC_ClearFlag_CHx(
289 		IPCC,
290 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
291 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
292 
293 	LL_C1_IPCC_DisableTransmitChannel(
294 		IPCC,
295 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
296 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
297 
298 	LL_C2_IPCC_DisableTransmitChannel(
299 		IPCC,
300 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
301 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
302 
303 	LL_C1_IPCC_DisableReceiveChannel(
304 		IPCC,
305 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
306 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
307 
308 	LL_C2_IPCC_DisableReceiveChannel(
309 		IPCC,
310 		LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 |
311 		LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
312 
313 	/* Set IPCC default IRQ handlers */
314 	IRQ_CONNECT(IPCC_C1_RX_IRQn, 0, HW_IPCC_Rx_Handler, NULL, 0);
315 	IRQ_CONNECT(IPCC_C1_TX_IRQn, 0, HW_IPCC_Tx_Handler, NULL, 0);
316 }
317 
transport_init(void)318 void transport_init(void)
319 {
320 	TL_MM_Config_t tl_mm_config;
321 	TL_BLE_InitConf_t tl_ble_config;
322 	SHCI_TL_HciInitConf_t shci_init_config;
323 
324 	LOG_DBG("BleCmdBuffer: %p", (void *)&BleCmdBuffer);
325 	LOG_DBG("HciAclDataBuffer: %p", (void *)&HciAclDataBuffer);
326 	LOG_DBG("SystemCmdBuffer: %p", (void *)&SystemCmdBuffer);
327 	LOG_DBG("EvtPool: %p", (void *)&EvtPool);
328 	LOG_DBG("SystemSpareEvtBuffer: %p", (void *)&SystemSpareEvtBuffer);
329 	LOG_DBG("BleSpareEvtBuffer: %p", (void *)&BleSpareEvtBuffer);
330 
331 	/**< Reference table initialization */
332 	TL_Init();
333 
334 	/**< System channel initialization */
335 	shci_init_config.p_cmdbuffer = (uint8_t *)&SystemCmdBuffer;
336 	shci_init_config.StatusNotCallBack = syscmd_status_not;
337 	shci_init(sysevt_received, (void *) &shci_init_config);
338 
339 	/**< Memory Manager channel initialization */
340 	tl_mm_config.p_BleSpareEvtBuffer = BleSpareEvtBuffer;
341 	tl_mm_config.p_SystemSpareEvtBuffer = SystemSpareEvtBuffer;
342 	tl_mm_config.p_AsynchEvtPool = EvtPool;
343 	tl_mm_config.AsynchEvtPoolSize = POOL_SIZE;
344 	TL_MM_Init(&tl_mm_config);
345 
346 	/**< BLE channel initialization */
347 	tl_ble_config.p_cmdbuffer = (uint8_t *)&BleCmdBuffer;
348 	tl_ble_config.p_AclDataBuffer = HciAclDataBuffer;
349 	tl_ble_config.IoBusEvtCallBack = TM_EvtReceivedCb;
350 	tl_ble_config.IoBusAclDataTxAck = TM_AclDataAck;
351 	TL_BLE_Init((void *)&tl_ble_config);
352 
353 	TL_Enable();
354 }
355 
bt_ipm_send(const struct device * dev,struct net_buf * buf)356 static int bt_ipm_send(const struct device *dev, struct net_buf *buf)
357 {
358 	TL_CmdPacket_t *ble_cmd_buff = &BleCmdBuffer;
359 
360 	ARG_UNUSED(dev);
361 
362 	k_sem_take(&ipm_busy, K_FOREVER);
363 
364 	switch (bt_buf_get_type(buf)) {
365 	case BT_BUF_ACL_OUT:
366 		LOG_DBG("ACL: buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);
367 		k_sem_take(&acl_data_ack, K_FOREVER);
368 		net_buf_push_u8(buf, BT_HCI_H4_ACL);
369 		memcpy((void *)
370 		       &((TL_AclDataPacket_t *)HciAclDataBuffer)->AclDataSerial,
371 		       buf->data, buf->len);
372 		TL_BLE_SendAclData(NULL, 0);
373 		break;
374 	case BT_BUF_CMD:
375 		LOG_DBG("CMD: buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);
376 		ble_cmd_buff->cmdserial.type = BT_HCI_H4_CMD;
377 		ble_cmd_buff->cmdserial.cmd.plen = buf->len;
378 		memcpy((void *)&ble_cmd_buff->cmdserial.cmd, buf->data,
379 		       buf->len);
380 		TL_BLE_SendCmd(NULL, 0);
381 		break;
382 	default:
383 		k_sem_give(&ipm_busy);
384 		LOG_ERR("Unsupported type");
385 		return -EINVAL;
386 	}
387 
388 	k_sem_give(&ipm_busy);
389 
390 	net_buf_unref(buf);
391 
392 	return 0;
393 }
394 
395 #ifdef CONFIG_BT_HCI_HOST
bt_get_ble_addr(void)396 bt_addr_t *bt_get_ble_addr(void)
397 {
398 	bt_addr_t *bd_addr;
399 	uint32_t udn;
400 	uint32_t company_id;
401 	uint32_t device_id;
402 
403 	/* Get the 64 bit Unique Device Number UID */
404 	/* The UID is used by firmware to derive   */
405 	/* 48-bit Device Address EUI-48 */
406 	udn = LL_FLASH_GetUDN();
407 
408 	if (udn != 0xFFFFFFFF) {
409 		/* Get the ST Company ID */
410 		company_id = LL_FLASH_GetSTCompanyID();
411 		/* Get the STM32 Device ID */
412 		device_id = LL_FLASH_GetDeviceID();
413 		bd_addr_udn.val[0] = (uint8_t)(udn & 0x000000FF);
414 		bd_addr_udn.val[1] = (uint8_t)((udn & 0x0000FF00) >> 8);
415 		bd_addr_udn.val[2] = (uint8_t)((udn & 0x00FF0000) >> 16);
416 		bd_addr_udn.val[3] = (uint8_t)device_id;
417 		bd_addr_udn.val[4] = (uint8_t)(company_id & 0x000000FF);
418 		bd_addr_udn.val[5] = (uint8_t)((company_id & 0x0000FF00) >> 8);
419 		bd_addr = &bd_addr_udn;
420 	} else {
421 		bd_addr = NULL;
422 	}
423 
424 	return bd_addr;
425 }
426 
bt_ipm_set_addr(void)427 static int bt_ipm_set_addr(void)
428 {
429 	bt_addr_t *uid_addr;
430 	struct aci_set_ble_addr *param;
431 	struct net_buf *buf;
432 	int err;
433 
434 	uid_addr = bt_get_ble_addr();
435 	if (!uid_addr) {
436 		return -ENOMSG;
437 	}
438 
439 	buf = bt_hci_cmd_create(ACI_HAL_WRITE_CONFIG_DATA, sizeof(*param));
440 
441 	if (!buf) {
442 		return -ENOBUFS;
443 	}
444 
445 	param = net_buf_add(buf, sizeof(*param));
446 	param->config_offset = HCI_CONFIG_DATA_PUBADDR_OFFSET;
447 	param->length = 6;
448 	param->value[0] = uid_addr->val[0];
449 	param->value[1] = uid_addr->val[1];
450 	param->value[2] = uid_addr->val[2];
451 	param->value[3] = uid_addr->val[3];
452 	param->value[4] = uid_addr->val[4];
453 	param->value[5] = uid_addr->val[5];
454 
455 	err = bt_hci_cmd_send_sync(ACI_HAL_WRITE_CONFIG_DATA, buf, NULL);
456 	if (err) {
457 		return err;
458 	}
459 
460 	return 0;
461 }
462 
bt_ipm_ble_init(void)463 static int bt_ipm_ble_init(void)
464 {
465 	struct aci_set_tx_power *param;
466 	struct net_buf *buf;
467 	int err;
468 
469 	err = bt_ipm_set_addr();
470 	if (err) {
471 		LOG_ERR("Can't set BLE UID addr");
472 	}
473 	/* Send ACI_WRITE_SET_TX_POWER_LEVEL */
474 	buf = bt_hci_cmd_create(ACI_WRITE_SET_TX_POWER_LEVEL, 3);
475 	if (!buf) {
476 		return -ENOBUFS;
477 	}
478 	param = net_buf_add(buf, sizeof(*param));
479 	param->cmd = 0x0F;
480 	param->value[0] = 0x18;
481 	param->value[1] = 0x01;
482 
483 	err = bt_hci_cmd_send_sync(ACI_WRITE_SET_TX_POWER_LEVEL, buf, NULL);
484 	if (err) {
485 		return err;
486 	}
487 
488 	return 0;
489 }
490 #endif /* CONFIG_BT_HCI_HOST */
491 
c2_reset(void)492 static int c2_reset(void)
493 {
494 	const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
495 	int err;
496 
497 	if (!device_is_ready(clk)) {
498 		LOG_ERR("clock control device not ready");
499 		return -ENODEV;
500 	}
501 
502 	err = clock_control_configure(clk, (clock_control_subsys_t) &clk_cfg[1],
503 					NULL);
504 	if (err < 0) {
505 		LOG_ERR("Could not configure RF Wake up clock");
506 		return err;
507 	}
508 
509 	/* HSI48 clock and CLK48 clock source are enabled using the device tree */
510 #if !STM32_HSI48_ENABLED
511 	/* Deprecated: enable HSI48 using device tree */
512 #warning Bluetooth IPM requires HSI48 clock to be enabled using device tree
513 	/* Keeping this sequence for legacy: */
514 	LL_RCC_HSI48_Enable();
515 	while (!LL_RCC_HSI48_IsReady()) {
516 	}
517 
518 #endif /* !STM32_HSI48_ENABLED */
519 
520 	err = clock_control_on(clk, (clock_control_subsys_t) &clk_cfg[0]);
521 	if (err < 0) {
522 		LOG_ERR("Could not enable IPCC clock");
523 		return err;
524 	}
525 
526 	/* Take BLE out of reset */
527 	ipcc_reset();
528 
529 	transport_init();
530 
531 	/* Device will let us know when it's ready */
532 	if (k_sem_take(&c2_started, STM32WB_C2_LOCK_TIMEOUT)) {
533 		return -ETIMEDOUT;
534 	}
535 	LOG_DBG("C2 unlocked");
536 
537 	stm32wb_start_ble(clk_cfg[1].bus);
538 
539 	c2_started_flag = true;
540 
541 	return 0;
542 }
543 
bt_ipm_open(const struct device * dev,bt_hci_recv_t recv)544 static int bt_ipm_open(const struct device *dev, bt_hci_recv_t recv)
545 {
546 	struct hci_data *hci = dev->data;
547 	int err;
548 
549 	if (!c2_started_flag) {
550 		/* C2 has been teared down. Reinit required */
551 		SHCI_C2_Reinit();
552 		while (LL_PWR_IsActiveFlag_C2DS() == 0) {
553 		};
554 
555 		err = c2_reset();
556 		if (err) {
557 			return err;
558 		}
559 	}
560 
561 	/* Start RX thread */
562 	k_thread_create(&ipm_rx_thread_data, ipm_rx_stack,
563 			K_KERNEL_STACK_SIZEOF(ipm_rx_stack),
564 			bt_ipm_rx_thread, (void *)dev, NULL, NULL,
565 			K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO),
566 			0, K_NO_WAIT);
567 
568 	hci->recv = recv;
569 
570 	LOG_DBG("IPM Channel Open Completed");
571 
572 	return 0;
573 }
574 
bt_ipm_setup(const struct device * dev,const struct bt_hci_setup_params * params)575 static int bt_ipm_setup(const struct device *dev, const struct bt_hci_setup_params *params)
576 {
577 	ARG_UNUSED(params);
578 	ARG_UNUSED(dev);
579 	int err;
580 
581 #ifdef CONFIG_BT_HCI_HOST
582 	err = bt_ipm_ble_init();
583 	if (err) {
584 		return err;
585 	}
586 #endif /* CONFIG_BT_HCI_HOST */
587 
588 	LOG_DBG("IPM Channel Setup Completed");
589 
590 	return 0;
591 }
592 
593 #ifdef CONFIG_BT_HCI_HOST
bt_ipm_close(const struct device * dev)594 static int bt_ipm_close(const struct device *dev)
595 {
596 	struct hci_data *hci = dev->data;
597 	int err;
598 
599 	err = bt_hci_cmd_send_sync(ACI_HAL_STACK_RESET, NULL, NULL);
600 	if (err) {
601 		LOG_ERR("IPM Channel Close Issue");
602 		return err;
603 	}
604 
605 	/* Wait till C2DS set */
606 	while (LL_PWR_IsActiveFlag_C2DS() == 0) {
607 	};
608 
609 	c2_started_flag = false;
610 
611 	k_thread_abort(&ipm_rx_thread_data);
612 
613 	hci->recv = NULL;
614 
615 	LOG_DBG("IPM Channel Close Completed");
616 
617 	return err;
618 }
619 #endif /* CONFIG_BT_HCI_HOST */
620 
621 static DEVICE_API(bt_hci, drv) = {
622 	.open           = bt_ipm_open,
623 #ifdef CONFIG_BT_HCI_HOST
624 	.close          = bt_ipm_close,
625 #endif
626 	.send           = bt_ipm_send,
627 	.setup          = bt_ipm_setup,
628 };
629 
_bt_ipm_init(const struct device * dev)630 static int _bt_ipm_init(const struct device *dev)
631 {
632 	int err;
633 
634 	ARG_UNUSED(dev);
635 
636 	err = c2_reset();
637 	if (err) {
638 		return err;
639 	}
640 
641 	return 0;
642 }
643 
644 #define HCI_DEVICE_INIT(inst) \
645 	static struct hci_data hci_data_##inst = { \
646 	}; \
647 	DEVICE_DT_INST_DEFINE(inst, _bt_ipm_init, NULL, &hci_data_##inst, NULL, \
648 			      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv)
649 
650 /* Only one instance supported right now */
651 HCI_DEVICE_INIT(0)
652