1 /*
2 * Copyright (c) 2023 Antmicro <www.antmicro.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/drivers/bluetooth/hci_driver.h>
8
9 #include <sl_btctrl_linklayer.h>
10 #include <sl_hci_common_transport.h>
11 #include <pa_conversions_efr32.h>
12 #include <sl_bt_ll_zephyr.h>
13 #include <rail.h>
14
15 #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
16 #include <zephyr/logging/log.h>
17 LOG_MODULE_REGISTER(bt_hci_driver_slz);
18
19 #define SL_BT_CONFIG_ACCEPT_LIST_SIZE 1
20 #define SL_BT_CONFIG_MAX_CONNECTIONS 1
21 #define SL_BT_CONFIG_USER_ADVERTISERS 1
22 #define SL_BT_CONTROLLER_BUFFER_MEMORY CONFIG_BT_SILABS_HCI_BUFFER_MEMORY
23 #define SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX CONFIG_BT_BUF_ACL_TX_COUNT
24 #define SL_BT_CONTROLLER_COMPLETED_PACKETS_THRESHOLD 1
25 #define SL_BT_CONTROLLER_COMPLETED_PACKETS_EVENTS_TIMEOUT 3
26 #define SL_BT_SILABS_LL_STACK_SIZE 1024
27
28 static K_KERNEL_STACK_DEFINE(slz_ll_stack, SL_BT_SILABS_LL_STACK_SIZE);
29 static struct k_thread slz_ll_thread;
30
rail_isr_installer(void)31 void rail_isr_installer(void)
32 {
33 #ifdef CONFIG_SOC_SERIES_EFR32MG24
34 IRQ_CONNECT(SYNTH_IRQn, 0, SYNTH_IRQHandler, NULL, 0);
35 #else
36 IRQ_CONNECT(RDMAILBOX_IRQn, 0, RDMAILBOX_IRQHandler, NULL, 0);
37 #endif
38 IRQ_CONNECT(RAC_SEQ_IRQn, 0, RAC_SEQ_IRQHandler, NULL, 0);
39 IRQ_CONNECT(RAC_RSM_IRQn, 0, RAC_RSM_IRQHandler, NULL, 0);
40 IRQ_CONNECT(PROTIMER_IRQn, 0, PROTIMER_IRQHandler, NULL, 0);
41 IRQ_CONNECT(MODEM_IRQn, 0, MODEM_IRQHandler, NULL, 0);
42 IRQ_CONNECT(FRC_IRQn, 0, FRC_IRQHandler, NULL, 0);
43 IRQ_CONNECT(BUFC_IRQn, 0, BUFC_IRQHandler, NULL, 0);
44 IRQ_CONNECT(AGC_IRQn, 0, AGC_IRQHandler, NULL, 0);
45 }
46
47 /**
48 * @brief Transmit HCI message using the currently used transport layer.
49 * The HCI calls this function to transmit a full HCI message.
50 * @param[in] data Packet type followed by HCI packet data.
51 * @param[in] len Length of the `data` parameter
52 * @return 0 - on success, or non-zero on failure.
53 */
hci_common_transport_transmit(uint8_t * data,int16_t len)54 uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len)
55 {
56 struct net_buf *buf;
57 uint8_t packet_type = data[0];
58 uint8_t flags;
59 uint8_t event_code;
60
61 LOG_HEXDUMP_DBG(data, len, "host packet data:");
62
63 /* drop packet type from the frame buffer - it is no longer needed */
64 data = &data[1];
65 len -= 1;
66
67 switch (packet_type) {
68 case h4_event:
69 event_code = data[0];
70 flags = bt_hci_evt_get_flags(event_code);
71 buf = bt_buf_get_evt(event_code, false, K_FOREVER);
72 break;
73 case h4_acl:
74 buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
75 break;
76 default:
77 LOG_ERR("Unknown HCI type: %d", packet_type);
78 return -EINVAL;
79 }
80
81 net_buf_add_mem(buf, data, len);
82 if (IS_ENABLED(CONFIG_BT_RECV_BLOCKING) &&
83 (packet_type == h4_event) && (flags & BT_HCI_EVT_FLAG_RECV_PRIO)) {
84 bt_recv_prio(buf);
85 } else {
86 bt_recv(buf);
87 }
88
89 sl_btctrl_hci_transmit_complete(0);
90
91 return 0;
92 }
93
slz_bt_send(struct net_buf * buf)94 static int slz_bt_send(struct net_buf *buf)
95 {
96 int rv = 0;
97
98 switch (bt_buf_get_type(buf)) {
99 case BT_BUF_ACL_OUT:
100 net_buf_push_u8(buf, h4_acl);
101 break;
102 case BT_BUF_CMD:
103 net_buf_push_u8(buf, h4_command);
104 break;
105 default:
106 rv = -EINVAL;
107 goto done;
108 }
109
110 rv = hci_common_transport_receive(buf->data, buf->len, true);
111 if (!rv) {
112 goto done;
113 }
114
115 done:
116 net_buf_unref(buf);
117 return rv;
118 }
119
slz_bt_open(void)120 static int slz_bt_open(void)
121 {
122 int ret;
123
124 /* Start RX thread */
125 k_thread_create(&slz_ll_thread, slz_ll_stack,
126 K_KERNEL_STACK_SIZEOF(slz_ll_stack),
127 (k_thread_entry_t)slz_ll_thread_func, NULL, NULL, NULL,
128 K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0,
129 K_NO_WAIT);
130
131 rail_isr_installer();
132 sl_rail_util_pa_init();
133
134 /* sl_btctrl_init_mem returns the number of memory buffers allocated */
135 ret = sl_btctrl_init_mem(SL_BT_CONTROLLER_BUFFER_MEMORY);
136 if (!ret) {
137 LOG_ERR("Failed to allocate memory %d", ret);
138 return -ENOMEM;
139 }
140
141 sl_btctrl_configure_le_buffer_size(SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX);
142
143 ret = sl_btctrl_init_ll();
144 if (ret) {
145 LOG_ERR("Bluetooth link layer init failed %d", ret);
146 goto deinit;
147 }
148
149 sl_btctrl_init_adv();
150 sl_btctrl_init_scan();
151 sl_btctrl_init_conn();
152 sl_btctrl_init_adv_ext();
153 sl_btctrl_init_scan_ext();
154
155 ret = sl_btctrl_init_basic(SL_BT_CONFIG_MAX_CONNECTIONS,
156 SL_BT_CONFIG_USER_ADVERTISERS,
157 SL_BT_CONFIG_ACCEPT_LIST_SIZE);
158 if (ret) {
159 LOG_ERR("Failed to initialize the controller %d", ret);
160 goto deinit;
161 }
162
163 sl_btctrl_configure_completed_packets_reporting(
164 SL_BT_CONTROLLER_COMPLETED_PACKETS_THRESHOLD,
165 SL_BT_CONTROLLER_COMPLETED_PACKETS_EVENTS_TIMEOUT);
166
167 sl_bthci_init_upper();
168 sl_btctrl_hci_parser_init_default();
169 sl_btctrl_hci_parser_init_conn();
170 sl_btctrl_hci_parser_init_adv();
171 sl_btctrl_hci_parser_init_phy();
172
173 #ifdef CONFIG_PM
174 {
175 RAIL_Status_t status = RAIL_InitPowerManager();
176
177 if (status != RAIL_STATUS_NO_ERROR) {
178 LOG_ERR("RAIL: failed to initialize power management, status=%d",
179 status);
180 ret = -EIO;
181 goto deinit;
182 }
183 }
184 #endif
185
186 LOG_DBG("SiLabs BT HCI started");
187
188 return 0;
189 deinit:
190 sli_btctrl_deinit_mem();
191 return ret;
192 }
193
194 static const struct bt_hci_driver drv = {
195 .name = "sl:bt",
196 .bus = BT_HCI_DRIVER_BUS_UART,
197 .open = slz_bt_open,
198 .send = slz_bt_send,
199 .quirks = BT_QUIRK_NO_RESET
200 };
201
slz_bt_init(void)202 static int slz_bt_init(void)
203 {
204 int ret;
205
206 ret = bt_hci_driver_register(&drv);
207 if (ret) {
208 LOG_ERR("Failed to register SiLabs BT HCI %d", ret);
209 }
210
211 return ret;
212 }
213
214 SYS_INIT(slz_bt_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
215