Commit | Line | Data |
---|---|---|
c942fddf | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
82f5169b RH |
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> | |
82f5169b RH |
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 | ||
82f5169b RH |
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 | ||
5a637751 BG |
48 | if (!skb) { |
49 | if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) | |
50 | skb = hu->proto->dequeue(hu); | |
51 | } else | |
82f5169b RH |
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, &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 | } | |
82f5169b | 86 | |
afe0b1c8 CC |
87 | clear_bit(HCI_UART_SENDING, &hu->tx_state); |
88 | } while (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state)); | |
82f5169b RH |
89 | } |
90 | ||
91 | /* ------- Interface to HCI layer ------ */ | |
92 | ||
82f5169b RH |
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(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 | ||
412fe29f HG |
113 | /* Initialize device */ |
114 | static int hci_uart_open(struct hci_dev *hdev) | |
115 | { | |
de8892df VLNG |
116 | struct hci_uart *hu = hci_get_drvdata(hdev); |
117 | int err; | |
118 | ||
412fe29f HG |
119 | BT_DBG("%s %p", hdev->name, hdev); |
120 | ||
de8892df VLNG |
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, &hu->flags); | |
130 | } | |
131 | ||
412fe29f HG |
132 | /* Undo clearing this from hci_uart_close() */ |
133 | hdev->flush = hci_uart_flush; | |
134 | ||
135 | return 0; | |
136 | } | |
137 | ||
82f5169b RH |
138 | /* Close device */ |
139 | static int hci_uart_close(struct hci_dev *hdev) | |
140 | { | |
de8892df VLNG |
141 | struct hci_uart *hu = hci_get_drvdata(hdev); |
142 | ||
82f5169b RH |
143 | BT_DBG("hdev %p", hdev); |
144 | ||
de8892df VLNG |
145 | if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) |
146 | return 0; | |
147 | ||
82f5169b RH |
148 | hci_uart_flush(hdev); |
149 | hdev->flush = NULL; | |
150 | ||
de8892df VLNG |
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, &hu->flags); | |
157 | serdev_device_close(hu->serdev); | |
158 | } | |
159 | ||
82f5169b RH |
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) | |
2064ee33 | 208 | bt_dev_err(hdev, "Failed to set baudrate"); |
82f5169b RH |
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, 0, NULL, | |
220 | HCI_INIT_TIMEOUT); | |
221 | if (IS_ERR(skb)) { | |
2064ee33 MH |
222 | bt_dev_err(hdev, "Reading local version info failed (%ld)", |
223 | PTR_ERR(skb)); | |
82f5169b RH |
224 | return 0; |
225 | } | |
226 | ||
0c0c09ff | 227 | if (skb->len != sizeof(*ver)) |
2064ee33 | 228 | bt_dev_err(hdev, "Event length mismatch for version info"); |
82f5169b RH |
229 | |
230 | kfree_skb(skb); | |
231 | return 0; | |
232 | } | |
233 | ||
bee5395c YH |
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 | ||
82f5169b RH |
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 | ||
608c39f4 | 298 | static const struct serdev_device_ops hci_serdev_client_ops = { |
82f5169b RH |
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 | ||
52b318e6 SR |
311 | serdev_device_set_client_ops(hu->serdev, &hci_serdev_client_ops); |
312 | ||
3124d320 TH |
313 | if (percpu_init_rwsem(&hu->proto_lock)) |
314 | return -ENOMEM; | |
315 | ||
e9ca0807 | 316 | err = serdev_device_open(hu->serdev); |
82f5169b | 317 | if (err) |
3124d320 | 318 | goto err_rwsem; |
9d7cbe2b | 319 | |
e9ca0807 HG |
320 | err = p->open(hu); |
321 | if (err) | |
322 | goto err_open; | |
323 | ||
82f5169b RH |
324 | hu->proto = p; |
325 | set_bit(HCI_UART_PROTO_READY, &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, hu); | |
339 | ||
fdee6d8f | 340 | INIT_WORK(&hu->init_ready, hci_uart_init_work); |
82f5169b RH |
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; | |
bee5395c YH |
355 | if (!hdev->wakeup) |
356 | hdev->wakeup = hci_uart_wakeup; | |
82f5169b RH |
357 | SET_HCIDEV_DEV(hdev, &hu->serdev->dev); |
358 | ||
b4a46996 HG |
359 | if (test_bit(HCI_UART_NO_SUSPEND_NOTIFIER, &hu->flags)) |
360 | set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks); | |
361 | ||
82f5169b RH |
362 | if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags)) |
363 | set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); | |
364 | ||
365 | if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags)) | |
366 | set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks); | |
367 | ||
82f5169b RH |
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, &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, &hu->flags); | |
390 | p->close(hu); | |
e9ca0807 HG |
391 | err_open: |
392 | serdev_device_close(hu->serdev); | |
3124d320 TH |
393 | err_rwsem: |
394 | percpu_free_rwsem(&hu->proto_lock); | |
82f5169b RH |
395 | return err; |
396 | } | |
081f36a8 | 397 | EXPORT_SYMBOL_GPL(hci_uart_register_device); |
c34dc3bf IM |
398 | |
399 | void hci_uart_unregister_device(struct hci_uart *hu) | |
400 | { | |
401 | struct hci_dev *hdev = hu->hdev; | |
402 | ||
3b799254 | 403 | cancel_work_sync(&hu->init_ready); |
202798db NB |
404 | if (test_bit(HCI_UART_REGISTERED, &hu->flags)) |
405 | hci_unregister_dev(hdev); | |
c34dc3bf IM |
406 | hci_free_dev(hdev); |
407 | ||
408 | cancel_work_sync(&hu->write_work); | |
409 | ||
410 | hu->proto->close(hu); | |
de8892df VLNG |
411 | |
412 | if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) { | |
413 | clear_bit(HCI_UART_PROTO_READY, &hu->flags); | |
414 | serdev_device_close(hu->serdev); | |
415 | } | |
3124d320 | 416 | percpu_free_rwsem(&hu->proto_lock); |
c34dc3bf IM |
417 | } |
418 | EXPORT_SYMBOL_GPL(hci_uart_unregister_device); |