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