1 /*
2  * Copyright (c) 2023 Antmicro <www.antmicro.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/bluetooth.h>
8 #include <zephyr/kernel.h>
9 
10 #include <sl_btctrl_linklayer.h>
11 #include <sl_hci_common_transport.h>
12 #include <pa_conversions_efr32.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_efr32);
18 
19 #define DT_DRV_COMPAT silabs_bt_hci_efr32
20 
21 struct hci_data {
22 	bt_hci_recv_t recv;
23 };
24 
25 #if defined(CONFIG_BT_MAX_CONN)
26 #define MAX_CONN CONFIG_BT_MAX_CONN
27 #else
28 #define MAX_CONN 0
29 #endif
30 
31 #if defined(CONFIG_BT_CTLR_RL_SIZE)
32 #define CTLR_RL_SIZE CONFIG_BT_CTLR_RL_SIZE
33 #else
34 #define CTLR_RL_SIZE 0
35 #endif
36 
37 static K_KERNEL_STACK_DEFINE(slz_ll_stack, CONFIG_BT_SILABS_EFR32_ACCEPT_LINK_LAYER_STACK_SIZE);
38 static struct k_thread slz_ll_thread;
39 
40 static K_KERNEL_STACK_DEFINE(slz_rx_stack, CONFIG_BT_DRV_RX_STACK_SIZE);
41 static struct k_thread slz_rx_thread;
42 
43 /* Semaphore for Link Layer */
44 K_SEM_DEFINE(slz_ll_sem, 0, 1);
45 
46 /* Events mask for Link Layer */
47 static atomic_t sli_btctrl_events;
48 
49 /* FIFO for received HCI packets */
50 static struct k_fifo slz_rx_fifo;
51 
52 /* FIXME: these functions should come from the SiSDK headers! */
53 void BTLE_LL_EventRaise(uint32_t events);
54 void BTLE_LL_Process(uint32_t events);
55 int16_t BTLE_LL_SetMaxPower(int16_t power);
56 bool sli_pending_btctrl_events(void);
57 RAIL_Handle_t BTLE_LL_GetRadioHandle(void);
58 
rail_isr_installer(void)59 void rail_isr_installer(void)
60 {
61 #ifdef CONFIG_SOC_SERIES_EFR32MG24
62 	IRQ_CONNECT(SYNTH_IRQn, 0, SYNTH_IRQHandler, NULL, 0);
63 #else
64 	IRQ_CONNECT(RDMAILBOX_IRQn, 0, RDMAILBOX_IRQHandler, NULL, 0);
65 #endif
66 	IRQ_CONNECT(RAC_SEQ_IRQn, 0, RAC_SEQ_IRQHandler, NULL, 0);
67 	IRQ_CONNECT(RAC_RSM_IRQn, 0, RAC_RSM_IRQHandler, NULL, 0);
68 	IRQ_CONNECT(PROTIMER_IRQn, 0, PROTIMER_IRQHandler, NULL, 0);
69 	IRQ_CONNECT(MODEM_IRQn, 0, MODEM_IRQHandler, NULL, 0);
70 	IRQ_CONNECT(FRC_IRQn, 0, FRC_IRQHandler, NULL, 0);
71 	IRQ_CONNECT(BUFC_IRQn, 0, BUFC_IRQHandler, NULL, 0);
72 	IRQ_CONNECT(AGC_IRQn, 0, AGC_IRQHandler, NULL, 0);
73 }
74 
slz_is_evt_discardable(const struct bt_hci_evt_hdr * hdr,const uint8_t * params,int16_t params_len)75 static bool slz_is_evt_discardable(const struct bt_hci_evt_hdr *hdr, const uint8_t *params,
76 				   int16_t params_len)
77 {
78 	switch (hdr->evt) {
79 	case BT_HCI_EVT_LE_META_EVENT: {
80 		struct bt_hci_evt_le_meta_event *meta_evt = (void *)params;
81 
82 		if (params_len < sizeof(*meta_evt)) {
83 			return false;
84 		}
85 		params += sizeof(*meta_evt);
86 		params_len -= sizeof(*meta_evt);
87 
88 		switch (meta_evt->subevent) {
89 		case BT_HCI_EVT_LE_ADVERTISING_REPORT:
90 			return true;
91 		case BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT: {
92 			struct bt_hci_evt_le_ext_advertising_report *evt = (void *)params;
93 
94 			if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) {
95 				return false;
96 			}
97 
98 			if (params_len < sizeof(*evt) + sizeof(*evt->adv_info)) {
99 				return false;
100 			}
101 
102 			/* Never discard if the event could be part of a multi-part report event,
103 			 * because the missing part could confuse the BT host.
104 			 */
105 			return (evt->num_reports == 1) &&
106 			       ((evt->adv_info[0].evt_type & BT_HCI_LE_ADV_EVT_TYPE_LEGACY) != 0);
107 		}
108 		default:
109 			return false;
110 		}
111 	}
112 	default:
113 		return false;
114 	}
115 }
116 
slz_bt_recv_evt(const uint8_t * data,const int16_t len)117 static struct net_buf *slz_bt_recv_evt(const uint8_t *data, const int16_t len)
118 {
119 	struct net_buf *buf;
120 	bool discardable;
121 	const struct bt_hci_evt_hdr *hdr = (void *)data;
122 	const uint8_t *params = &data[sizeof(*hdr)];
123 	const int16_t params_len = len - sizeof(*hdr);
124 
125 	if (len < sizeof(*hdr)) {
126 		LOG_ERR("Event header is missing");
127 		return NULL;
128 	}
129 
130 	discardable = slz_is_evt_discardable(hdr, params, params_len);
131 	buf = bt_buf_get_evt(hdr->evt, discardable, discardable ? K_NO_WAIT : K_FOREVER);
132 	if (!buf) {
133 		LOG_DBG("Discardable buffer pool full, ignoring event");
134 		return buf;
135 	}
136 
137 	net_buf_add_mem(buf, data, len);
138 
139 	return buf;
140 }
141 
slz_bt_recv_acl(const uint8_t * data,const int16_t len)142 static struct net_buf *slz_bt_recv_acl(const uint8_t *data, const int16_t len)
143 {
144 	struct net_buf *buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
145 
146 	net_buf_add_mem(buf, data, len);
147 
148 	return buf;
149 }
150 
151 /**
152  * @brief Transmit HCI message using the currently used transport layer.
153  * The HCI calls this function to transmit a full HCI message.
154  * @param[in] data Packet type followed by HCI packet data.
155  * @param[in] len Length of the `data` parameter
156  * @return 0 - on success, or non-zero on failure.
157  */
hci_common_transport_transmit(uint8_t * data,int16_t len)158 uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len)
159 {
160 	struct net_buf *buf;
161 	uint8_t packet_type;
162 
163 	LOG_HEXDUMP_DBG(data, len, "host packet data:");
164 
165 	if (len < 1) {
166 		LOG_ERR("HCI packet type is missing");
167 		return -EINVAL;
168 	}
169 
170 	packet_type = data[0];
171 	/* drop packet type from the frame buffer - it is no longer needed */
172 	data += 1;
173 	len -= 1;
174 
175 	switch (packet_type) {
176 	case BT_HCI_H4_EVT:
177 		buf = slz_bt_recv_evt(data, len);
178 		break;
179 	case BT_HCI_H4_ACL:
180 		buf = slz_bt_recv_acl(data, len);
181 		break;
182 	default:
183 		LOG_ERR("Unknown HCI type: %d", packet_type);
184 		return -EINVAL;
185 	}
186 
187 	if (buf) {
188 		k_fifo_put(&slz_rx_fifo, buf);
189 	}
190 
191 	sl_btctrl_hci_transmit_complete(0);
192 
193 	return 0;
194 }
195 
slz_bt_send(const struct device * dev,struct net_buf * buf)196 static int slz_bt_send(const struct device *dev, struct net_buf *buf)
197 {
198 	int rv = 0;
199 
200 	ARG_UNUSED(dev);
201 
202 	switch (bt_buf_get_type(buf)) {
203 	case BT_BUF_ACL_OUT:
204 		net_buf_push_u8(buf, BT_HCI_H4_ACL);
205 		break;
206 	case BT_BUF_CMD:
207 		net_buf_push_u8(buf, BT_HCI_H4_CMD);
208 		break;
209 	default:
210 		rv = -EINVAL;
211 		goto done;
212 	}
213 
214 	rv = hci_common_transport_receive(buf->data, buf->len, true);
215 	if (!rv) {
216 		goto done;
217 	}
218 
219 done:
220 	net_buf_unref(buf);
221 	return rv;
222 }
223 
224 /**
225  * The HCI driver thread simply waits for the LL semaphore to signal that
226  * it has an event to handle, whether it's from the radio, its own scheduler,
227  * or an HCI event to pass upstairs. The BTLE_LL_Process function call will
228  * take care of all of them, and add HCI events to the HCI queue when applicable.
229  */
slz_ll_thread_func(void * p1,void * p2,void * p3)230 static void slz_ll_thread_func(void *p1, void *p2, void *p3)
231 {
232 	ARG_UNUSED(p1);
233 	ARG_UNUSED(p2);
234 	ARG_UNUSED(p3);
235 
236 	while (true) {
237 		uint32_t events;
238 
239 		k_sem_take(&slz_ll_sem, K_FOREVER);
240 		events = atomic_clear(&sli_btctrl_events);
241 		BTLE_LL_Process(events);
242 	}
243 }
244 
slz_rx_thread_func(void * p1,void * p2,void * p3)245 static void slz_rx_thread_func(void *p1, void *p2, void *p3)
246 {
247 	const struct device *dev = p1;
248 	struct hci_data *hci = dev->data;
249 
250 	ARG_UNUSED(p2);
251 	ARG_UNUSED(p3);
252 
253 	while (true) {
254 		struct net_buf *buf = k_fifo_get(&slz_rx_fifo, K_FOREVER);
255 
256 		hci->recv(dev, buf);
257 	}
258 }
259 
slz_set_tx_power(int16_t max_power_dbm)260 static void slz_set_tx_power(int16_t max_power_dbm)
261 {
262 	const int16_t max_power_cbm = max_power_dbm * 10;
263 	const int16_t actual_max_power_cbm = BTLE_LL_SetMaxPower(max_power_cbm);
264 	const int16_t actual_max_power_dbm = DIV_ROUND_CLOSEST(actual_max_power_cbm, 10);
265 
266 	if (actual_max_power_dbm != max_power_dbm) {
267 		LOG_WRN("Unable to set max TX power to %d dBm, actual max is %d dBm", max_power_dbm,
268 			actual_max_power_dbm);
269 	}
270 }
271 
slz_bt_open(const struct device * dev,bt_hci_recv_t recv)272 static int slz_bt_open(const struct device *dev, bt_hci_recv_t recv)
273 {
274 	struct hci_data *hci = dev->data;
275 	int ret;
276 
277 	BUILD_ASSERT(CONFIG_NUM_METAIRQ_PRIORITIES > 0,
278 		     "Config NUM_METAIRQ_PRIORITIES must be greater than 0");
279 	BUILD_ASSERT(CONFIG_BT_SILABS_EFR32_LL_THREAD_PRIO < CONFIG_NUM_METAIRQ_PRIORITIES,
280 		     "Config BT_SILABS_EFR32_LL_THREAD_PRIO must be a meta-IRQ priority");
281 
282 	k_fifo_init(&slz_rx_fifo);
283 
284 	k_thread_create(&slz_ll_thread, slz_ll_stack, K_KERNEL_STACK_SIZEOF(slz_ll_stack),
285 			slz_ll_thread_func, NULL, NULL, NULL,
286 			K_PRIO_COOP(CONFIG_BT_SILABS_EFR32_LL_THREAD_PRIO), 0, K_NO_WAIT);
287 
288 	k_thread_create(&slz_rx_thread, slz_rx_stack, K_KERNEL_STACK_SIZEOF(slz_rx_stack),
289 			slz_rx_thread_func, (void *)dev, NULL, NULL,
290 			K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT);
291 
292 	rail_isr_installer();
293 	sl_rail_util_pa_init();
294 
295 	/* Disable 2M and coded PHYs, they do not work with the current configuration */
296 	sl_btctrl_disable_2m_phy();
297 	sl_btctrl_disable_coded_phy();
298 
299 	/* sl_btctrl_init_mem returns the number of memory buffers allocated */
300 	ret = sl_btctrl_init_mem(CONFIG_BT_SILABS_EFR32_BUFFER_MEMORY);
301 	if (!ret) {
302 		LOG_ERR("Failed to allocate memory %d", ret);
303 		return -ENOMEM;
304 	}
305 
306 	sl_btctrl_configure_le_buffer_size(CONFIG_BT_BUF_ACL_TX_COUNT);
307 
308 	if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {
309 		sl_btctrl_allocate_resolving_list_memory(CTLR_RL_SIZE);
310 		sl_btctrl_init_privacy();
311 	}
312 
313 	ret = sl_btctrl_init_ll();
314 	if (ret) {
315 		LOG_ERR("Bluetooth link layer init failed %d", ret);
316 		goto deinit;
317 	}
318 
319 	slz_set_tx_power(CONFIG_BT_CTLR_TX_PWR_ANTENNA);
320 
321 	sl_btctrl_init_adv();
322 	sl_btctrl_init_scan();
323 	sl_btctrl_init_conn();
324 	sl_btctrl_init_phy();
325 
326 	if (IS_ENABLED(CONFIG_BT_EXT_ADV)) {
327 		sl_btctrl_init_adv_ext();
328 		sl_btctrl_init_scan_ext();
329 	}
330 
331 	ret = sl_btctrl_init_basic(MAX_CONN, CONFIG_BT_SILABS_EFR32_USER_ADVERTISERS + MAX_CONN,
332 				   CONFIG_BT_SILABS_EFR32_ACCEPT_LIST_SIZE);
333 	if (ret) {
334 		LOG_ERR("Failed to initialize the controller %d", ret);
335 		goto deinit;
336 	}
337 
338 	sl_btctrl_configure_completed_packets_reporting(
339 		CONFIG_BT_SILABS_EFR32_COMPLETED_PACKETS_THRESHOLD,
340 		CONFIG_BT_SILABS_EFR32_COMPLETED_PACKETS_TIMEOUT);
341 
342 	sl_bthci_init_upper();
343 	sl_btctrl_hci_parser_init_default();
344 	sl_btctrl_hci_parser_init_conn();
345 	sl_btctrl_hci_parser_init_adv();
346 	sl_btctrl_hci_parser_init_phy();
347 
348 	if (IS_ENABLED(CONFIG_BT_SILABS_EFR32_HCI_VS)) {
349 		sl_bthci_init_vs();
350 	}
351 
352 	if (IS_ENABLED(CONFIG_PM)) {
353 		RAIL_ConfigSleep(BTLE_LL_GetRadioHandle(), RAIL_SLEEP_CONFIG_TIMERSYNC_ENABLED);
354 		RAIL_Status_t status = RAIL_InitPowerManager();
355 
356 		if (status != RAIL_STATUS_NO_ERROR) {
357 			LOG_ERR("RAIL: failed to initialize power management, status=%d",
358 					status);
359 			ret = -EIO;
360 			goto deinit;
361 		}
362 	}
363 
364 	if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {
365 		sl_btctrl_hci_parser_init_privacy();
366 	}
367 
368 	hci->recv = recv;
369 
370 	LOG_DBG("SiLabs BT HCI started");
371 
372 	return 0;
373 deinit:
374 	sli_btctrl_deinit_mem();
375 	return ret;
376 }
377 
sli_pending_btctrl_events(void)378 bool sli_pending_btctrl_events(void)
379 {
380 	return false; /* TODO: check if this should really return false! */
381 }
382 
383 /* Store event flags and increment the LL semaphore */
BTLE_LL_EventRaise(uint32_t events)384 void BTLE_LL_EventRaise(uint32_t events)
385 {
386 	atomic_or(&sli_btctrl_events, events);
387 	k_sem_give(&slz_ll_sem);
388 }
389 
sl_bt_controller_init(void)390 void sl_bt_controller_init(void)
391 {
392 	/* No extra initialization procedure required */
393 }
394 
395 static DEVICE_API(bt_hci, drv) = {
396 	.open           = slz_bt_open,
397 	.send           = slz_bt_send,
398 };
399 
400 #define HCI_DEVICE_INIT(inst) \
401 	static struct hci_data hci_data_##inst = { \
402 	}; \
403 	DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &hci_data_##inst, NULL, \
404 			      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv)
405 
406 /* Only one instance supported right now */
407 HCI_DEVICE_INIT(0)
408