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 
9 #include <sl_btctrl_linklayer.h>
10 #include <sl_hci_common_transport.h>
11 #include <pa_conversions_efr32.h>
12 #include <rail.h>
13 
14 #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
15 #include <zephyr/logging/log.h>
16 LOG_MODULE_REGISTER(bt_hci_driver_efr32);
17 
18 #define DT_DRV_COMPAT silabs_bt_hci_efr32
19 
20 struct hci_data {
21 	bt_hci_recv_t recv;
22 };
23 
24 #define SL_BT_CONFIG_ACCEPT_LIST_SIZE				1
25 #define SL_BT_CONFIG_MAX_CONNECTIONS				1
26 #define SL_BT_CONFIG_USER_ADVERTISERS				1
27 #define SL_BT_CONTROLLER_BUFFER_MEMORY				CONFIG_BT_SILABS_EFR32_BUFFER_MEMORY
28 #define SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX			CONFIG_BT_BUF_ACL_TX_COUNT
29 #define SL_BT_CONTROLLER_COMPLETED_PACKETS_THRESHOLD		1
30 #define SL_BT_CONTROLLER_COMPLETED_PACKETS_EVENTS_TIMEOUT	3
31 #define SL_BT_SILABS_LL_STACK_SIZE				1024
32 
33 static K_KERNEL_STACK_DEFINE(slz_ll_stack, SL_BT_SILABS_LL_STACK_SIZE);
34 static struct k_thread slz_ll_thread;
35 
36 /* Semaphore for Link Layer */
37 K_SEM_DEFINE(slz_ll_sem, 0, 1);
38 
39 /* Events mask for Link Layer */
40 static atomic_t sli_btctrl_events;
41 
42 /* FIXME: these functions should come from the SiSDK headers! */
43 void BTLE_LL_EventRaise(uint32_t events);
44 void BTLE_LL_Process(uint32_t events);
45 bool sli_pending_btctrl_events(void);
46 RAIL_Handle_t BTLE_LL_GetRadioHandle(void);
47 
rail_isr_installer(void)48 void rail_isr_installer(void)
49 {
50 #ifdef CONFIG_SOC_SERIES_EFR32MG24
51 	IRQ_CONNECT(SYNTH_IRQn, 0, SYNTH_IRQHandler, NULL, 0);
52 #else
53 	IRQ_CONNECT(RDMAILBOX_IRQn, 0, RDMAILBOX_IRQHandler, NULL, 0);
54 #endif
55 	IRQ_CONNECT(RAC_SEQ_IRQn, 0, RAC_SEQ_IRQHandler, NULL, 0);
56 	IRQ_CONNECT(RAC_RSM_IRQn, 0, RAC_RSM_IRQHandler, NULL, 0);
57 	IRQ_CONNECT(PROTIMER_IRQn, 0, PROTIMER_IRQHandler, NULL, 0);
58 	IRQ_CONNECT(MODEM_IRQn, 0, MODEM_IRQHandler, NULL, 0);
59 	IRQ_CONNECT(FRC_IRQn, 0, FRC_IRQHandler, NULL, 0);
60 	IRQ_CONNECT(BUFC_IRQn, 0, BUFC_IRQHandler, NULL, 0);
61 	IRQ_CONNECT(AGC_IRQn, 0, AGC_IRQHandler, NULL, 0);
62 }
63 
64 /**
65  * @brief Transmit HCI message using the currently used transport layer.
66  * The HCI calls this function to transmit a full HCI message.
67  * @param[in] data Packet type followed by HCI packet data.
68  * @param[in] len Length of the `data` parameter
69  * @return 0 - on success, or non-zero on failure.
70  */
hci_common_transport_transmit(uint8_t * data,int16_t len)71 uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len)
72 {
73 	const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0));
74 	struct hci_data *hci = dev->data;
75 	struct net_buf *buf;
76 	uint8_t packet_type = data[0];
77 	uint8_t event_code;
78 
79 	LOG_HEXDUMP_DBG(data, len, "host packet data:");
80 
81 	/* drop packet type from the frame buffer - it is no longer needed */
82 	data = &data[1];
83 	len -= 1;
84 
85 	switch (packet_type) {
86 	case BT_HCI_H4_EVT:
87 		event_code = data[0];
88 		buf = bt_buf_get_evt(event_code, false, K_FOREVER);
89 		break;
90 	case BT_HCI_H4_ACL:
91 		buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
92 		break;
93 	default:
94 		LOG_ERR("Unknown HCI type: %d", packet_type);
95 		return -EINVAL;
96 	}
97 
98 	net_buf_add_mem(buf, data, len);
99 	hci->recv(dev, buf);
100 
101 	sl_btctrl_hci_transmit_complete(0);
102 
103 	return 0;
104 }
105 
slz_bt_send(const struct device * dev,struct net_buf * buf)106 static int slz_bt_send(const struct device *dev, struct net_buf *buf)
107 {
108 	int rv = 0;
109 
110 	ARG_UNUSED(dev);
111 
112 	switch (bt_buf_get_type(buf)) {
113 	case BT_BUF_ACL_OUT:
114 		net_buf_push_u8(buf, BT_HCI_H4_ACL);
115 		break;
116 	case BT_BUF_CMD:
117 		net_buf_push_u8(buf, BT_HCI_H4_CMD);
118 		break;
119 	default:
120 		rv = -EINVAL;
121 		goto done;
122 	}
123 
124 	rv = hci_common_transport_receive(buf->data, buf->len, true);
125 	if (!rv) {
126 		goto done;
127 	}
128 
129 done:
130 	net_buf_unref(buf);
131 	return rv;
132 }
133 
134 /**
135  * The HCI driver thread simply waits for the LL semaphore to signal that
136  * it has an event to handle, whether it's from the radio, its own scheduler,
137  * or an HCI event to pass upstairs. The BTLE_LL_Process function call will
138  * take care of all of them, and add HCI events to the HCI queue when applicable.
139  */
slz_thread_func(void * p1,void * p2,void * p3)140 static void slz_thread_func(void *p1, void *p2, void *p3)
141 {
142 	ARG_UNUSED(p1);
143 	ARG_UNUSED(p2);
144 	ARG_UNUSED(p3);
145 
146 	while (true) {
147 		uint32_t events;
148 
149 		k_sem_take(&slz_ll_sem, K_FOREVER);
150 		events = atomic_clear(&sli_btctrl_events);
151 		BTLE_LL_Process(events);
152 	}
153 }
154 
slz_bt_open(const struct device * dev,bt_hci_recv_t recv)155 static int slz_bt_open(const struct device *dev, bt_hci_recv_t recv)
156 {
157 	struct hci_data *hci = dev->data;
158 	int ret;
159 
160 	/* Start RX thread */
161 	k_thread_create(&slz_ll_thread, slz_ll_stack,
162 			K_KERNEL_STACK_SIZEOF(slz_ll_stack),
163 			slz_thread_func, NULL, NULL, NULL,
164 			K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0,
165 			K_NO_WAIT);
166 
167 	rail_isr_installer();
168 	sl_rail_util_pa_init();
169 
170 	/* Disable 2M and coded PHYs, they do not work with the current configuration */
171 	sl_btctrl_disable_2m_phy();
172 	sl_btctrl_disable_coded_phy();
173 
174 	/* sl_btctrl_init_mem returns the number of memory buffers allocated */
175 	ret = sl_btctrl_init_mem(SL_BT_CONTROLLER_BUFFER_MEMORY);
176 	if (!ret) {
177 		LOG_ERR("Failed to allocate memory %d", ret);
178 		return -ENOMEM;
179 	}
180 
181 	sl_btctrl_configure_le_buffer_size(SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX);
182 
183 	ret = sl_btctrl_init_ll();
184 	if (ret) {
185 		LOG_ERR("Bluetooth link layer init failed %d", ret);
186 		goto deinit;
187 	}
188 
189 	if (IS_ENABLED(CONFIG_BT_BROADCASTER) || IS_ENABLED(CONFIG_BT_PERIPHERAL)) {
190 		sl_btctrl_init_adv();
191 	}
192 	if (IS_ENABLED(CONFIG_BT_CENTRAL) || IS_ENABLED(CONFIG_BT_OBSERVER)) {
193 		sl_btctrl_init_scan();
194 	}
195 	if (IS_ENABLED(CONFIG_BT_CONN)) {
196 		sl_btctrl_init_conn();
197 	}
198 	sl_btctrl_init_phy();
199 
200 	if (IS_ENABLED(CONFIG_BT_EXT_ADV)) {
201 		if (IS_ENABLED(CONFIG_BT_BROADCASTER) || IS_ENABLED(CONFIG_BT_PERIPHERAL)) {
202 			sl_btctrl_init_adv_ext();
203 		}
204 		if (IS_ENABLED(CONFIG_BT_CENTRAL) || IS_ENABLED(CONFIG_BT_OBSERVER)) {
205 			sl_btctrl_init_scan_ext();
206 		}
207 	}
208 
209 	ret = sl_btctrl_init_basic(SL_BT_CONFIG_MAX_CONNECTIONS,
210 			SL_BT_CONFIG_USER_ADVERTISERS,
211 			SL_BT_CONFIG_ACCEPT_LIST_SIZE);
212 	if (ret) {
213 		LOG_ERR("Failed to initialize the controller %d", ret);
214 		goto deinit;
215 	}
216 
217 	sl_btctrl_configure_completed_packets_reporting(
218 		SL_BT_CONTROLLER_COMPLETED_PACKETS_THRESHOLD,
219 		SL_BT_CONTROLLER_COMPLETED_PACKETS_EVENTS_TIMEOUT);
220 
221 	sl_bthci_init_upper();
222 	sl_btctrl_hci_parser_init_default();
223 	if (IS_ENABLED(CONFIG_BT_CONN)) {
224 		sl_btctrl_hci_parser_init_conn();
225 	}
226 	if (IS_ENABLED(CONFIG_BT_BROADCASTER) || IS_ENABLED(CONFIG_BT_PERIPHERAL)) {
227 		sl_btctrl_hci_parser_init_adv();
228 	}
229 	sl_btctrl_hci_parser_init_phy();
230 
231 #ifdef CONFIG_PM
232 	{
233 		RAIL_ConfigSleep(BTLE_LL_GetRadioHandle(), RAIL_SLEEP_CONFIG_TIMERSYNC_ENABLED);
234 		RAIL_Status_t status = RAIL_InitPowerManager();
235 
236 		if (status != RAIL_STATUS_NO_ERROR) {
237 			LOG_ERR("RAIL: failed to initialize power management, status=%d",
238 					status);
239 			ret = -EIO;
240 			goto deinit;
241 		}
242 	}
243 #endif
244 
245 	hci->recv = recv;
246 
247 	LOG_DBG("SiLabs BT HCI started");
248 
249 	return 0;
250 deinit:
251 	sli_btctrl_deinit_mem();
252 	return ret;
253 }
254 
sli_pending_btctrl_events(void)255 bool sli_pending_btctrl_events(void)
256 {
257 	return false; /* TODO: check if this should really return false! */
258 }
259 
260 /* Store event flags and increment the LL semaphore */
BTLE_LL_EventRaise(uint32_t events)261 void BTLE_LL_EventRaise(uint32_t events)
262 {
263 	atomic_or(&sli_btctrl_events, events);
264 	k_sem_give(&slz_ll_sem);
265 }
266 
sl_bt_controller_init(void)267 void sl_bt_controller_init(void)
268 {
269 	/* No extra initialization procedure required */
270 }
271 
272 static DEVICE_API(bt_hci, drv) = {
273 	.open           = slz_bt_open,
274 	.send           = slz_bt_send,
275 };
276 
277 #define HCI_DEVICE_INIT(inst) \
278 	static struct hci_data hci_data_##inst = { \
279 	}; \
280 	DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &hci_data_##inst, NULL, \
281 			      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv)
282 
283 /* Only one instance supported right now */
284 HCI_DEVICE_INIT(0)
285