kernel: import series to support Renesas Bluetooth HCI
[openwrt/staging/dangole.git] / target / linux / generic / pending-5.15 / 900-0001-Support-for-Renesas-Bluetooth-Low-Energy-HCI-over-UA.patch
1 From e7eaf003090c6b2e56ce1d39b30b221ed7283de3 Mon Sep 17 00:00:00 2001
2 From: Alvin Park <alvin.park.pv@renesas.com>
3 Date: Thu, 17 Mar 2022 19:39:57 +0900
4 Subject: [PATCH] Support for Renesas Bluetooth Low Energy HCI over UART
5
6 ---
7 drivers/bluetooth/Kconfig | 13 +
8 drivers/bluetooth/Makefile | 1 +
9 drivers/bluetooth/hci_ldisc.c | 6 +
10 drivers/bluetooth/hci_renesas.c | 474 ++++++++++++++++++++++++++++++++
11 drivers/bluetooth/hci_uart.h | 8 +-
12 5 files changed, 501 insertions(+), 1 deletion(-)
13 create mode 100644 drivers/bluetooth/hci_renesas.c
14
15 --- a/drivers/bluetooth/Kconfig
16 +++ b/drivers/bluetooth/Kconfig
17 @@ -257,6 +257,19 @@ config BT_HCIUART_MRVL
18
19 Say Y here to compile support for HCI MRVL protocol.
20
21 +config BT_HCIUART_RENESAS
22 + bool "Renesas protocol support"
23 + depends on BT_HCIUART
24 + depends on BT_HCIUART_SERDEV
25 + select BT_HCIUART_H4
26 + help
27 + The Renesas protocol support enables Bluetooth Low Energy HCI
28 + over serial.
29 + This protocol is required for the Renesas Bluetooth Low Energy
30 + devices with UART interface.
31 +
32 + Say Y here to compile support for HCI Renesas protocol.
33 +
34 config BT_HCIBCM203X
35 tristate "HCI BCM203x USB driver"
36 depends on USB
37 --- a/drivers/bluetooth/Makefile
38 +++ b/drivers/bluetooth/Makefile
39 @@ -47,4 +47,5 @@ hci_uart-$(CONFIG_BT_HCIUART_BCM) += hci
40 hci_uart-$(CONFIG_BT_HCIUART_QCA) += hci_qca.o
41 hci_uart-$(CONFIG_BT_HCIUART_AG6XX) += hci_ag6xx.o
42 hci_uart-$(CONFIG_BT_HCIUART_MRVL) += hci_mrvl.o
43 +hci_uart-$(CONFIG_BT_HCIUART_RENESAS) += hci_renesas.o
44 hci_uart-objs := $(hci_uart-y)
45 --- a/drivers/bluetooth/hci_ldisc.c
46 +++ b/drivers/bluetooth/hci_ldisc.c
47 @@ -880,6 +880,9 @@ static int __init hci_uart_init(void)
48 #ifdef CONFIG_BT_HCIUART_MRVL
49 mrvl_init();
50 #endif
51 +#ifdef CONFIG_BT_HCIUART_RENESAS
52 + renesas_init();
53 +#endif
54
55 return 0;
56 }
57 @@ -916,6 +919,9 @@ static void __exit hci_uart_exit(void)
58 #ifdef CONFIG_BT_HCIUART_MRVL
59 mrvl_deinit();
60 #endif
61 +#ifdef CONFIG_BT_HCIUART_RENESAS
62 + renesas_deinit();
63 +#endif
64
65 tty_unregister_ldisc(&hci_uart_ldisc);
66 }
67 --- /dev/null
68 +++ b/drivers/bluetooth/hci_renesas.c
69 @@ -0,0 +1,474 @@
70 +// SPDX-License-Identifier: GPL-2.0-or-later
71 +/*
72 + * Renesas Bluetooth Low Energy HCI UART driver
73 + *
74 + * Copyright (C) 2022 Renesas Electroics Corp.
75 + *
76 + * Alvin Park <alvin.park.pv@renesas.com>
77 + *
78 + * This file is subject to the terms and conditions of the GNU General Public
79 + * License. See the file "COPYING" in the main directory of this archive
80 + * for more details.
81 +*/
82 +
83 +#include <linux/kernel.h>
84 +#include <linux/errno.h>
85 +#include <linux/skbuff.h>
86 +#include <linux/firmware.h>
87 +#include <linux/module.h>
88 +#include <linux/of.h>
89 +#include <linux/serdev.h>
90 +#include <net/bluetooth/bluetooth.h>
91 +#include <net/bluetooth/hci_core.h>
92 +
93 +#include "hci_uart.h"
94 +
95 +enum {
96 + STATE_FW_STX_PENDING,
97 + STATE_FW_ACK_PENDING,
98 + STATE_FW_CRC_PENDING
99 +};
100 +
101 +enum {
102 + STATE_FW_INIT,
103 + STATE_FW_SIZE,
104 + STATE_FW_PROG,
105 + STATE_FW_DONE,
106 + STATE_FW_BOOTED
107 +};
108 +
109 +#define STX 0x02
110 +#define SOH 0x01
111 +#define ACK 0x06
112 +#define NACK 0x15
113 +#define CRC_INIT 0x00
114 +
115 +struct renesas_serdev {
116 + struct hci_uart hu;
117 +};
118 +
119 +struct renesas_data {
120 + struct sk_buff *rx_skb;
121 + struct sk_buff_head txq;
122 + struct sk_buff_head rawq;
123 + unsigned long flags;
124 + unsigned int state;
125 + u8 id, rev, fw_crc;
126 +};
127 +
128 +static const struct h4_recv_pkt renesas_recv_pkts[] = {
129 + { H4_RECV_ACL, .recv = hci_recv_frame },
130 + { H4_RECV_SCO, .recv = hci_recv_frame },
131 + { H4_RECV_EVENT, .recv = hci_recv_frame },
132 +};
133 +
134 +static int renesas_open(struct hci_uart *hu)
135 +{
136 + struct renesas_data *rdata;
137 + int ret;
138 +
139 + BT_DBG("hu %p", hu);
140 +
141 + if (!hci_uart_has_flow_control(hu))
142 + return -EOPNOTSUPP;
143 +
144 + rdata = kzalloc(sizeof(*rdata), GFP_KERNEL);
145 + if (!rdata)
146 + return -ENOMEM;
147 +
148 + skb_queue_head_init(&rdata->txq);
149 + skb_queue_head_init(&rdata->rawq);
150 +
151 + hu->priv = rdata;
152 +
153 + if (hu->serdev) {
154 + ret = serdev_device_open(hu->serdev);
155 + if (ret) {
156 + kfree(rdata);
157 + return ret;
158 + }
159 + }
160 +
161 + return 0;
162 +}
163 +
164 +static int renesas_close(struct hci_uart *hu)
165 +{
166 + struct renesas_data *rdata = hu->priv;
167 +
168 + BT_DBG("hu %p", hu);
169 +
170 + if (hu->serdev)
171 + serdev_device_close(hu->serdev);
172 +
173 + skb_queue_purge(&rdata->txq);
174 + skb_queue_purge(&rdata->rawq);
175 + kfree_skb(rdata->rx_skb);
176 + kfree(rdata);
177 +
178 + hu->priv = NULL;
179 + return 0;
180 +}
181 +
182 +static int renesas_flush(struct hci_uart *hu)
183 +{
184 + struct renesas_data *rdata = hu->priv;
185 +
186 + BT_DBG("hu %p", hu);
187 +
188 + skb_queue_purge(&rdata->txq);
189 + skb_queue_purge(&rdata->rawq);
190 +
191 + return 0;
192 +}
193 +
194 +static int renesas_send_ack(struct hci_uart *hu, unsigned char type)
195 +{
196 + struct renesas_data *rdata = hu->priv;
197 + struct sk_buff *skb;
198 +
199 + skb = alloc_skb(1, GFP_ATOMIC);
200 + if (!skb) {
201 + bt_dev_err(hu->hdev, "Unable to alloc ack/nak packet");
202 + return -ENOMEM;
203 + }
204 + skb_put_u8(skb, type);
205 +
206 + skb_queue_tail(&rdata->rawq, skb);
207 + hci_uart_tx_wakeup(hu);
208 +
209 + return 0;
210 +}
211 +
212 +static int renesas_send_fw_size(struct hci_uart *hu, u16 length)
213 +{
214 + struct renesas_data *rdata = hu->priv;
215 + struct sk_buff *skb;
216 +
217 + skb = alloc_skb(3, GFP_ATOMIC);
218 + if (!skb) {
219 + bt_dev_err(hu->hdev, "Failed to alloc mem for FW size packet");
220 + return -ENOMEM;
221 + }
222 +
223 + skb_put_u8(skb, SOH);
224 + skb_put_u8(skb, length);
225 + skb_put_u8(skb, length>>8);
226 +
227 + skb_queue_tail(&rdata->rawq, skb);
228 + hci_uart_tx_wakeup(hu);
229 +
230 + return 0;
231 +}
232 +
233 +static int renesas_load_firmware(struct hci_dev *hdev, const char *name)
234 +{
235 + struct hci_uart *hu = hci_get_drvdata(hdev);
236 + struct renesas_data *rdata = hu->priv;
237 + const struct firmware *fw = NULL;
238 + const u8 *fw_ptr, *fw_max;
239 + u16 fw_size = 0;
240 + int err, i;
241 +
242 + err = request_firmware(&fw, name, &hdev->dev);
243 + if (err < 0) {
244 + bt_dev_err(hdev, "Failed to load firmware file %s", name);
245 + return err;
246 + }
247 +
248 + fw_ptr = fw->data;
249 + fw_max = fw->data + fw->size;
250 + fw_size = fw->size;
251 +
252 + bt_dev_info(hdev, "Loading %s", name);
253 +
254 + /* update crc */
255 + for (i = 0; i < fw->size; i++)
256 + rdata->fw_crc ^= fw_ptr[i];
257 +
258 + rdata->state = STATE_FW_INIT;
259 + set_bit(STATE_FW_STX_PENDING, &rdata->flags);
260 +
261 + while (rdata->state != STATE_FW_DONE) {
262 + struct sk_buff *skb;
263 +
264 + /* Controller drives the firmware load by sending firmware
265 + * request packets containing the expected fragment size.
266 + */
267 + err = wait_on_bit_timeout(&rdata->flags, STATE_FW_STX_PENDING,
268 + TASK_INTERRUPTIBLE,
269 + msecs_to_jiffies(5000));
270 + if (err == 1) {
271 + bt_dev_err(hdev, "Firmware load interrupted");
272 + err = -EINTR;
273 + break;
274 + } else if (err) {
275 + bt_dev_err(hdev, "Firmware request timeout");
276 + err = -ETIMEDOUT;
277 + break;
278 + }
279 +
280 + switch(rdata->state) {
281 + case STATE_FW_INIT:
282 + bt_dev_dbg(hdev, "Firmware request, expecting %d bytes",
283 + fw->size);
284 +
285 + set_bit(STATE_FW_ACK_PENDING, &rdata->flags);
286 + err = renesas_send_fw_size(hu, fw_size);
287 + if (err) {
288 + break;
289 + }
290 +
291 + rdata->state = STATE_FW_SIZE;
292 + break;
293 +
294 + case STATE_FW_SIZE:
295 + err = wait_on_bit_timeout(&rdata->flags, STATE_FW_ACK_PENDING,
296 + TASK_INTERRUPTIBLE,
297 + msecs_to_jiffies(2000));
298 + if (err == 1) {
299 + bt_dev_err(hdev, "Firmware load interrupted");
300 + err = -EINTR;
301 + break;
302 + } else if (err) {
303 + bt_dev_err(hdev, "Firmware request timeout");
304 + err = -ETIMEDOUT;
305 + break;
306 + }
307 +
308 + set_bit(STATE_FW_CRC_PENDING, &rdata->flags);
309 +
310 + skb = alloc_skb(fw_size, GFP_KERNEL);
311 + if (!skb) {
312 + bt_dev_err(hdev, "Failed to alloc mem for FW packet");
313 + err = -ENOMEM;
314 + break;
315 + }
316 + skb_put_data(skb, fw_ptr, fw_size);
317 + skb_queue_tail(&rdata->rawq, skb);
318 + hci_uart_tx_wakeup(hu);
319 +
320 + rdata->state = STATE_FW_PROG;
321 + break;
322 +
323 + case STATE_FW_PROG:
324 + err = wait_on_bit_timeout(&rdata->flags, STATE_FW_CRC_PENDING,
325 + TASK_INTERRUPTIBLE,
326 + msecs_to_jiffies(2000));
327 + if (err == 1) {
328 + bt_dev_err(hdev, "Firmware load interrupted");
329 + err = -EINTR;
330 + break;
331 + } else if (err) {
332 + bt_dev_err(hdev, "Firmware request timeout");
333 + err = -ETIMEDOUT;
334 + break;
335 + }
336 +
337 + err = renesas_send_ack(hu, ACK);
338 + if (err) {
339 + break;
340 + }
341 +
342 + bt_dev_dbg(hdev, "Firmware has been loaded");
343 +
344 + set_bit(STATE_FW_STX_PENDING, &rdata->flags);
345 + rdata->state = STATE_FW_DONE;
346 + break;
347 +
348 + default:
349 + break;
350 + }
351 +
352 + if (err) {
353 + break;
354 + }
355 + }
356 +
357 + release_firmware(fw);
358 + return err;
359 +}
360 +
361 +static int renesas_setup(struct hci_uart *hu)
362 +{
363 + struct renesas_data *rdata = hu->priv;
364 + int err;
365 +
366 + hci_uart_set_flow_control(hu, true);
367 +
368 + err = renesas_load_firmware(hu->hdev, "renesas/hci_531.bin");
369 + if (err)
370 + return err;
371 +
372 + /* wait for HCI application to start */
373 + usleep_range(8000, 10000);
374 +
375 + rdata->state = STATE_FW_BOOTED;
376 +
377 + hci_uart_set_flow_control(hu, false);
378 +
379 + return 0;
380 +}
381 +
382 +static int renesas_recv(struct hci_uart *hu, const void *data, int count)
383 +{
384 + struct renesas_data *rdata = hu->priv;
385 + u8 *data_ptr = (u8 *)data;
386 +
387 + switch(rdata->state) {
388 + case STATE_FW_INIT:
389 + if (*data_ptr == STX) {
390 + if (!test_bit(STATE_FW_STX_PENDING, &rdata->flags)) {
391 + bt_dev_err(hu->hdev, "Received unexpected STX");
392 + return -EINVAL;
393 + }
394 + clear_bit(STATE_FW_STX_PENDING, &rdata->flags);
395 + wake_up_bit(&rdata->flags, STATE_FW_STX_PENDING);
396 + }
397 + break;
398 +
399 + case STATE_FW_SIZE:
400 + if (*data_ptr == ACK) {
401 + if (!test_bit(STATE_FW_ACK_PENDING, &rdata->flags)) {
402 + bt_dev_err(hu->hdev, "Received unexpected ACK");
403 + return -EINVAL;
404 + }
405 + clear_bit(STATE_FW_ACK_PENDING, &rdata->flags);
406 + wake_up_bit(&rdata->flags, STATE_FW_ACK_PENDING);
407 + } else {
408 + bt_dev_err(hu->hdev, "Received unexpected data (%x)", *data_ptr);
409 + return -EINVAL;
410 + }
411 + break;
412 +
413 + case STATE_FW_PROG:
414 + if (!test_bit(STATE_FW_CRC_PENDING, &rdata->flags)) {
415 + bt_dev_err(hu->hdev, "Received unexpected CRC");
416 + return -EINVAL;
417 + }
418 +
419 + if (rdata->fw_crc != *data_ptr) {
420 + bt_dev_err(hu->hdev, "Received CRC %02x, "
421 + "which does not match "
422 + "computed CRC %02x.\n",
423 + *data_ptr, rdata->fw_crc);
424 + return -EINVAL;
425 + }
426 +
427 + clear_bit(STATE_FW_CRC_PENDING, &rdata->flags);
428 + wake_up_bit(&rdata->flags, STATE_FW_CRC_PENDING);
429 + break;
430 +
431 + case STATE_FW_DONE:
432 + /* Do nothing */
433 + break;
434 +
435 + case STATE_FW_BOOTED:
436 + rdata->rx_skb = h4_recv_buf(hu->hdev, rdata->rx_skb, data, count,
437 + renesas_recv_pkts,
438 + ARRAY_SIZE(renesas_recv_pkts));
439 + if (IS_ERR(rdata->rx_skb)) {
440 + int err = PTR_ERR(rdata->rx_skb);
441 + bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
442 + rdata->rx_skb = NULL;
443 + return err;
444 + }
445 + break;
446 +
447 + default:
448 + bt_dev_err(hu->hdev, "Unknown state (%d)", rdata->state);
449 + break;
450 + }
451 +
452 + return count;
453 +}
454 +
455 +static int renesas_enqueue(struct hci_uart *hu, struct sk_buff *skb)
456 +{
457 + struct renesas_data *rdata = hu->priv;
458 +
459 + skb_queue_tail(&rdata->txq, skb);
460 + return 0;
461 +}
462 +
463 +static struct sk_buff *renesas_dequeue(struct hci_uart *hu)
464 +{
465 + struct renesas_data *rdata = hu->priv;
466 + struct sk_buff *skb;
467 +
468 + skb = skb_dequeue(&rdata->txq);
469 + if (!skb) {
470 + /* Any raw data ? */
471 + skb = skb_dequeue(&rdata->rawq);
472 + } else {
473 + /* Prepend skb with frame type */
474 + memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
475 + }
476 +
477 + return skb;
478 +}
479 +
480 +static const struct hci_uart_proto renesas_proto = {
481 + .id = HCI_UART_RENESAS,
482 + .name = "Renesas",
483 + .init_speed = 115200,
484 + .open = renesas_open,
485 + .close = renesas_close,
486 + .flush = renesas_flush,
487 + .setup = renesas_setup,
488 + .recv = renesas_recv,
489 + .enqueue = renesas_enqueue,
490 + .dequeue = renesas_dequeue,
491 +};
492 +
493 +static int renesas_serdev_probe(struct serdev_device *serdev)
494 +{
495 + struct renesas_serdev *rdatadev;
496 +
497 + rdatadev = devm_kzalloc(&serdev->dev, sizeof(*rdatadev), GFP_KERNEL);
498 + if (!rdatadev)
499 + return -ENOMEM;
500 +
501 + rdatadev->hu.serdev = serdev;
502 + serdev_device_set_drvdata(serdev, rdatadev);
503 +
504 + return hci_uart_register_device(&rdatadev->hu, &renesas_proto);
505 +}
506 +
507 +static void renesas_serdev_remove(struct serdev_device *serdev)
508 +{
509 + struct renesas_serdev *rdatadev = serdev_device_get_drvdata(serdev);
510 +
511 + hci_uart_unregister_device(&rdatadev->hu);
512 +}
513 +
514 +#ifdef CONFIG_OF
515 +static const struct of_device_id renesas_bluetooth_of_match[] = {
516 + { .compatible = "renesas,DA14531" },
517 + { },
518 +};
519 +MODULE_DEVICE_TABLE(of, renesas_bluetooth_of_match);
520 +#endif
521 +
522 +static struct serdev_device_driver renesas_serdev_driver = {
523 + .probe = renesas_serdev_probe,
524 + .remove = renesas_serdev_remove,
525 + .driver = {
526 + .name = "hci_uart_renesas",
527 + .of_match_table = of_match_ptr(renesas_bluetooth_of_match),
528 + },
529 +};
530 +
531 +int __init renesas_init(void)
532 +{
533 + serdev_device_driver_register(&renesas_serdev_driver);
534 +
535 + return hci_uart_register_proto(&renesas_proto);
536 +}
537 +
538 +int __exit renesas_deinit(void)
539 +{
540 + serdev_device_driver_unregister(&renesas_serdev_driver);
541 +
542 + return hci_uart_unregister_proto(&renesas_proto);
543 +}
544 --- a/drivers/bluetooth/hci_uart.h
545 +++ b/drivers/bluetooth/hci_uart.h
546 @@ -20,7 +20,7 @@
547 #define HCIUARTGETFLAGS _IOR('U', 204, int)
548
549 /* UART protocols */
550 -#define HCI_UART_MAX_PROTO 12
551 +#define HCI_UART_MAX_PROTO 13
552
553 #define HCI_UART_H4 0
554 #define HCI_UART_BCSP 1
555 @@ -34,6 +34,7 @@
556 #define HCI_UART_AG6XX 9
557 #define HCI_UART_NOKIA 10
558 #define HCI_UART_MRVL 11
559 +#define HCI_UART_RENESAS 12
560
561 #define HCI_UART_RAW_DEVICE 0
562 #define HCI_UART_RESET_ON_INIT 1
563 @@ -200,3 +201,8 @@ int ag6xx_deinit(void);
564 int mrvl_init(void);
565 int mrvl_deinit(void);
566 #endif
567 +
568 +#ifdef CONFIG_BT_HCIUART_RENESAS
569 +int renesas_init(void);
570 +int renesas_deinit(void);
571 +#endif