1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Bluetooth HCI serdev driver lib |
4 | * |
5 | * Copyright (C) 2017 Linaro, Ltd., Rob Herring <robh@kernel.org> |
6 | * |
7 | * Based on hci_ldisc.c: |
8 | * |
9 | * Copyright (C) 2000-2001 Qualcomm Incorporated |
10 | * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> |
11 | * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org> |
12 | */ |
13 | |
14 | #include <linux/kernel.h> |
15 | #include <linux/types.h> |
16 | #include <linux/serdev.h> |
17 | #include <linux/skbuff.h> |
18 | |
19 | #include <net/bluetooth/bluetooth.h> |
20 | #include <net/bluetooth/hci_core.h> |
21 | |
22 | #include "hci_uart.h" |
23 | |
24 | static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type) |
25 | { |
26 | struct hci_dev *hdev = hu->hdev; |
27 | |
28 | /* Update HCI stat counters */ |
29 | switch (pkt_type) { |
30 | case HCI_COMMAND_PKT: |
31 | hdev->stat.cmd_tx++; |
32 | break; |
33 | |
34 | case HCI_ACLDATA_PKT: |
35 | hdev->stat.acl_tx++; |
36 | break; |
37 | |
38 | case HCI_SCODATA_PKT: |
39 | hdev->stat.sco_tx++; |
40 | break; |
41 | } |
42 | } |
43 | |
44 | static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu) |
45 | { |
46 | struct sk_buff *skb = hu->tx_skb; |
47 | |
48 | if (!skb) { |
49 | if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) |
50 | skb = hu->proto->dequeue(hu); |
51 | } else |
52 | hu->tx_skb = NULL; |
53 | |
54 | return skb; |
55 | } |
56 | |
57 | static void hci_uart_write_work(struct work_struct *work) |
58 | { |
59 | struct hci_uart *hu = container_of(work, struct hci_uart, write_work); |
60 | struct serdev_device *serdev = hu->serdev; |
61 | struct hci_dev *hdev = hu->hdev; |
62 | struct sk_buff *skb; |
63 | |
64 | /* REVISIT: |
65 | * should we cope with bad skbs or ->write() returning an error value? |
66 | */ |
67 | do { |
68 | clear_bit(HCI_UART_TX_WAKEUP, addr: &hu->tx_state); |
69 | |
70 | while ((skb = hci_uart_dequeue(hu))) { |
71 | int len; |
72 | |
73 | len = serdev_device_write_buf(serdev, |
74 | skb->data, skb->len); |
75 | hdev->stat.byte_tx += len; |
76 | |
77 | skb_pull(skb, len); |
78 | if (skb->len) { |
79 | hu->tx_skb = skb; |
80 | break; |
81 | } |
82 | |
83 | hci_uart_tx_complete(hu, hci_skb_pkt_type(skb)); |
84 | kfree_skb(skb); |
85 | } |
86 | |
87 | clear_bit(HCI_UART_SENDING, addr: &hu->tx_state); |
88 | } while (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state)); |
89 | } |
90 | |
91 | /* ------- Interface to HCI layer ------ */ |
92 | |
93 | /* Reset device */ |
94 | static int hci_uart_flush(struct hci_dev *hdev) |
95 | { |
96 | struct hci_uart *hu = hci_get_drvdata(hdev); |
97 | |
98 | BT_DBG("hdev %p serdev %p" , hdev, hu->serdev); |
99 | |
100 | if (hu->tx_skb) { |
101 | kfree_skb(skb: hu->tx_skb); hu->tx_skb = NULL; |
102 | } |
103 | |
104 | /* Flush any pending characters in the driver and discipline. */ |
105 | serdev_device_write_flush(hu->serdev); |
106 | |
107 | if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) |
108 | hu->proto->flush(hu); |
109 | |
110 | return 0; |
111 | } |
112 | |
113 | /* Initialize device */ |
114 | static int hci_uart_open(struct hci_dev *hdev) |
115 | { |
116 | struct hci_uart *hu = hci_get_drvdata(hdev); |
117 | int err; |
118 | |
119 | BT_DBG("%s %p" , hdev->name, hdev); |
120 | |
121 | /* When Quirk HCI_QUIRK_NON_PERSISTENT_SETUP is set by |
122 | * driver, BT SoC is completely turned OFF during |
123 | * BT OFF. Upon next BT ON UART port should be opened. |
124 | */ |
125 | if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) { |
126 | err = serdev_device_open(hu->serdev); |
127 | if (err) |
128 | return err; |
129 | set_bit(HCI_UART_PROTO_READY, addr: &hu->flags); |
130 | } |
131 | |
132 | /* Undo clearing this from hci_uart_close() */ |
133 | hdev->flush = hci_uart_flush; |
134 | |
135 | return 0; |
136 | } |
137 | |
138 | /* Close device */ |
139 | static int hci_uart_close(struct hci_dev *hdev) |
140 | { |
141 | struct hci_uart *hu = hci_get_drvdata(hdev); |
142 | |
143 | BT_DBG("hdev %p" , hdev); |
144 | |
145 | if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) |
146 | return 0; |
147 | |
148 | hci_uart_flush(hdev); |
149 | hdev->flush = NULL; |
150 | |
151 | /* When QUIRK HCI_QUIRK_NON_PERSISTENT_SETUP is set by driver, |
152 | * BT SOC is completely powered OFF during BT OFF, holding port |
153 | * open may drain the battery. |
154 | */ |
155 | if (test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) { |
156 | clear_bit(HCI_UART_PROTO_READY, addr: &hu->flags); |
157 | serdev_device_close(hu->serdev); |
158 | } |
159 | |
160 | return 0; |
161 | } |
162 | |
163 | /* Send frames from HCI layer */ |
164 | static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb) |
165 | { |
166 | struct hci_uart *hu = hci_get_drvdata(hdev); |
167 | |
168 | BT_DBG("%s: type %d len %d" , hdev->name, hci_skb_pkt_type(skb), |
169 | skb->len); |
170 | |
171 | hu->proto->enqueue(hu, skb); |
172 | |
173 | hci_uart_tx_wakeup(hu); |
174 | |
175 | return 0; |
176 | } |
177 | |
178 | static int hci_uart_setup(struct hci_dev *hdev) |
179 | { |
180 | struct hci_uart *hu = hci_get_drvdata(hdev); |
181 | struct hci_rp_read_local_version *ver; |
182 | struct sk_buff *skb; |
183 | unsigned int speed; |
184 | int err; |
185 | |
186 | /* Init speed if any */ |
187 | if (hu->init_speed) |
188 | speed = hu->init_speed; |
189 | else if (hu->proto->init_speed) |
190 | speed = hu->proto->init_speed; |
191 | else |
192 | speed = 0; |
193 | |
194 | if (speed) |
195 | serdev_device_set_baudrate(hu->serdev, speed); |
196 | |
197 | /* Operational speed if any */ |
198 | if (hu->oper_speed) |
199 | speed = hu->oper_speed; |
200 | else if (hu->proto->oper_speed) |
201 | speed = hu->proto->oper_speed; |
202 | else |
203 | speed = 0; |
204 | |
205 | if (hu->proto->set_baudrate && speed) { |
206 | err = hu->proto->set_baudrate(hu, speed); |
207 | if (err) |
208 | bt_dev_err(hdev, "Failed to set baudrate" ); |
209 | else |
210 | serdev_device_set_baudrate(hu->serdev, speed); |
211 | } |
212 | |
213 | if (hu->proto->setup) |
214 | return hu->proto->setup(hu); |
215 | |
216 | if (!test_bit(HCI_UART_VND_DETECT, &hu->hdev_flags)) |
217 | return 0; |
218 | |
219 | skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, plen: 0, NULL, |
220 | HCI_INIT_TIMEOUT); |
221 | if (IS_ERR(ptr: skb)) { |
222 | bt_dev_err(hdev, "Reading local version info failed (%ld)" , |
223 | PTR_ERR(skb)); |
224 | return 0; |
225 | } |
226 | |
227 | if (skb->len != sizeof(*ver)) |
228 | bt_dev_err(hdev, "Event length mismatch for version info" ); |
229 | |
230 | kfree_skb(skb); |
231 | return 0; |
232 | } |
233 | |
234 | /* Check if the device is wakeable */ |
235 | static bool hci_uart_wakeup(struct hci_dev *hdev) |
236 | { |
237 | /* HCI UART devices are assumed to be wakeable by default. |
238 | * Implement wakeup callback to override this behavior. |
239 | */ |
240 | return true; |
241 | } |
242 | |
243 | /** hci_uart_write_wakeup - transmit buffer wakeup |
244 | * @serdev: serial device |
245 | * |
246 | * This function is called by the serdev framework when it accepts |
247 | * more data being sent. |
248 | */ |
249 | static void hci_uart_write_wakeup(struct serdev_device *serdev) |
250 | { |
251 | struct hci_uart *hu = serdev_device_get_drvdata(serdev); |
252 | |
253 | BT_DBG("" ); |
254 | |
255 | if (!hu || serdev != hu->serdev) { |
256 | WARN_ON(1); |
257 | return; |
258 | } |
259 | |
260 | if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) |
261 | hci_uart_tx_wakeup(hu); |
262 | } |
263 | |
264 | /** hci_uart_receive_buf - receive buffer wakeup |
265 | * @serdev: serial device |
266 | * @data: pointer to received data |
267 | * @count: count of received data in bytes |
268 | * |
269 | * This function is called by the serdev framework when it received data |
270 | * in the RX buffer. |
271 | * |
272 | * Return: number of processed bytes |
273 | */ |
274 | static int hci_uart_receive_buf(struct serdev_device *serdev, const u8 *data, |
275 | size_t count) |
276 | { |
277 | struct hci_uart *hu = serdev_device_get_drvdata(serdev); |
278 | |
279 | if (!hu || serdev != hu->serdev) { |
280 | WARN_ON(1); |
281 | return 0; |
282 | } |
283 | |
284 | if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) |
285 | return 0; |
286 | |
287 | /* It does not need a lock here as it is already protected by a mutex in |
288 | * tty caller |
289 | */ |
290 | hu->proto->recv(hu, data, count); |
291 | |
292 | if (hu->hdev) |
293 | hu->hdev->stat.byte_rx += count; |
294 | |
295 | return count; |
296 | } |
297 | |
298 | static const struct serdev_device_ops hci_serdev_client_ops = { |
299 | .receive_buf = hci_uart_receive_buf, |
300 | .write_wakeup = hci_uart_write_wakeup, |
301 | }; |
302 | |
303 | int hci_uart_register_device(struct hci_uart *hu, |
304 | const struct hci_uart_proto *p) |
305 | { |
306 | int err; |
307 | struct hci_dev *hdev; |
308 | |
309 | BT_DBG("" ); |
310 | |
311 | serdev_device_set_client_ops(serdev: hu->serdev, ops: &hci_serdev_client_ops); |
312 | |
313 | if (percpu_init_rwsem(&hu->proto_lock)) |
314 | return -ENOMEM; |
315 | |
316 | err = serdev_device_open(hu->serdev); |
317 | if (err) |
318 | goto err_rwsem; |
319 | |
320 | err = p->open(hu); |
321 | if (err) |
322 | goto err_open; |
323 | |
324 | hu->proto = p; |
325 | set_bit(HCI_UART_PROTO_READY, addr: &hu->flags); |
326 | |
327 | /* Initialize and register HCI device */ |
328 | hdev = hci_alloc_dev(); |
329 | if (!hdev) { |
330 | BT_ERR("Can't allocate HCI device" ); |
331 | err = -ENOMEM; |
332 | goto err_alloc; |
333 | } |
334 | |
335 | hu->hdev = hdev; |
336 | |
337 | hdev->bus = HCI_UART; |
338 | hci_set_drvdata(hdev, data: hu); |
339 | |
340 | INIT_WORK(&hu->init_ready, hci_uart_init_work); |
341 | INIT_WORK(&hu->write_work, hci_uart_write_work); |
342 | |
343 | /* Only when vendor specific setup callback is provided, consider |
344 | * the manufacturer information valid. This avoids filling in the |
345 | * value for Ericsson when nothing is specified. |
346 | */ |
347 | if (hu->proto->setup) |
348 | hdev->manufacturer = hu->proto->manufacturer; |
349 | |
350 | hdev->open = hci_uart_open; |
351 | hdev->close = hci_uart_close; |
352 | hdev->flush = hci_uart_flush; |
353 | hdev->send = hci_uart_send_frame; |
354 | hdev->setup = hci_uart_setup; |
355 | if (!hdev->wakeup) |
356 | hdev->wakeup = hci_uart_wakeup; |
357 | SET_HCIDEV_DEV(hdev, &hu->serdev->dev); |
358 | |
359 | if (test_bit(HCI_UART_NO_SUSPEND_NOTIFIER, &hu->flags)) |
360 | set_bit(nr: HCI_QUIRK_NO_SUSPEND_NOTIFIER, addr: &hdev->quirks); |
361 | |
362 | if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags)) |
363 | set_bit(nr: HCI_QUIRK_RAW_DEVICE, addr: &hdev->quirks); |
364 | |
365 | if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags)) |
366 | set_bit(nr: HCI_QUIRK_EXTERNAL_CONFIG, addr: &hdev->quirks); |
367 | |
368 | if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags)) |
369 | hdev->dev_type = HCI_AMP; |
370 | else |
371 | hdev->dev_type = HCI_PRIMARY; |
372 | |
373 | if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags)) |
374 | return 0; |
375 | |
376 | if (hci_register_dev(hdev) < 0) { |
377 | BT_ERR("Can't register HCI device" ); |
378 | err = -ENODEV; |
379 | goto err_register; |
380 | } |
381 | |
382 | set_bit(HCI_UART_REGISTERED, addr: &hu->flags); |
383 | |
384 | return 0; |
385 | |
386 | err_register: |
387 | hci_free_dev(hdev); |
388 | err_alloc: |
389 | clear_bit(HCI_UART_PROTO_READY, addr: &hu->flags); |
390 | p->close(hu); |
391 | err_open: |
392 | serdev_device_close(hu->serdev); |
393 | err_rwsem: |
394 | percpu_free_rwsem(&hu->proto_lock); |
395 | return err; |
396 | } |
397 | EXPORT_SYMBOL_GPL(hci_uart_register_device); |
398 | |
399 | void hci_uart_unregister_device(struct hci_uart *hu) |
400 | { |
401 | struct hci_dev *hdev = hu->hdev; |
402 | |
403 | cancel_work_sync(work: &hu->init_ready); |
404 | if (test_bit(HCI_UART_REGISTERED, &hu->flags)) |
405 | hci_unregister_dev(hdev); |
406 | hci_free_dev(hdev); |
407 | |
408 | cancel_work_sync(work: &hu->write_work); |
409 | |
410 | hu->proto->close(hu); |
411 | |
412 | if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) { |
413 | clear_bit(HCI_UART_PROTO_READY, addr: &hu->flags); |
414 | serdev_device_close(hu->serdev); |
415 | } |
416 | percpu_free_rwsem(&hu->proto_lock); |
417 | } |
418 | EXPORT_SYMBOL_GPL(hci_uart_unregister_device); |
419 | |