xref: /linux/drivers/bluetooth/hci_h4.c (revision 70c29b35fd87f87a7b8dad6eb8d55ce54a0d549a)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *
4  *  Bluetooth HCI UART driver
5  *
6  *  Copyright (C) 2000-2001  Qualcomm Incorporated
7  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
8  *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
9  */
10 
11 #include <linux/module.h>
12 
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/types.h>
16 #include <linux/fcntl.h>
17 #include <linux/interrupt.h>
18 #include <linux/ptrace.h>
19 #include <linux/poll.h>
20 
21 #include <linux/slab.h>
22 #include <linux/tty.h>
23 #include <linux/errno.h>
24 #include <linux/string.h>
25 #include <linux/signal.h>
26 #include <linux/ioctl.h>
27 #include <linux/skbuff.h>
28 #include <linux/unaligned.h>
29 
30 #include <net/bluetooth/bluetooth.h>
31 #include <net/bluetooth/hci_core.h>
32 #include <net/bluetooth/hci_h4.h>
33 
34 #include "hci_uart.h"
35 
36 struct h4_struct {
37 	struct sk_buff *rx_skb;
38 	struct sk_buff_head txq;
39 };
40 
41 /* Initialize protocol */
42 static int h4_open(struct hci_uart *hu)
43 {
44 	struct h4_struct *h4;
45 
46 	BT_DBG("hu %p", hu);
47 
48 	h4 = kzalloc_obj(*h4);
49 	if (!h4)
50 		return -ENOMEM;
51 
52 	skb_queue_head_init(&h4->txq);
53 
54 	hu->priv = h4;
55 	return 0;
56 }
57 
58 /* Flush protocol data */
59 static int h4_flush(struct hci_uart *hu)
60 {
61 	struct h4_struct *h4 = hu->priv;
62 
63 	BT_DBG("hu %p", hu);
64 
65 	skb_queue_purge(&h4->txq);
66 
67 	return 0;
68 }
69 
70 /* Close protocol */
71 static int h4_close(struct hci_uart *hu)
72 {
73 	struct h4_struct *h4 = hu->priv;
74 
75 	BT_DBG("hu %p", hu);
76 
77 	skb_queue_purge(&h4->txq);
78 
79 	kfree_skb(h4->rx_skb);
80 
81 	hu->priv = NULL;
82 	kfree(h4);
83 
84 	return 0;
85 }
86 
87 /* Enqueue frame for transmission (padding, crc, etc) */
88 static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
89 {
90 	struct h4_struct *h4 = hu->priv;
91 
92 	BT_DBG("hu %p skb %p", hu, skb);
93 
94 	/* Prepend skb with frame type */
95 	memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
96 	skb_queue_tail(&h4->txq, skb);
97 
98 	return 0;
99 }
100 
101 static const struct h4_recv_pkt h4_recv_pkts[] = {
102 	{ H4_RECV_ACL,   .recv = hci_recv_frame },
103 	{ H4_RECV_SCO,   .recv = hci_recv_frame },
104 	{ H4_RECV_EVENT, .recv = hci_recv_frame },
105 	{ H4_RECV_ISO,   .recv = hci_recv_frame },
106 };
107 
108 /* Recv data */
109 static int h4_recv(struct hci_uart *hu, const void *data, int count)
110 {
111 	struct h4_struct *h4 = hu->priv;
112 
113 	if (!h4)
114 		return -ENODEV;
115 
116 	h4->rx_skb = h4_recv_skb(hu->hdev, &hu->alignment, &hu->padding,
117 				 h4->rx_skb, data, count, h4_recv_pkts,
118 				 ARRAY_SIZE(h4_recv_pkts));
119 	if (IS_ERR(h4->rx_skb)) {
120 		int err = PTR_ERR(h4->rx_skb);
121 		bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
122 		h4->rx_skb = NULL;
123 		return err;
124 	}
125 
126 	return count;
127 }
128 
129 static struct sk_buff *h4_dequeue(struct hci_uart *hu)
130 {
131 	struct h4_struct *h4 = hu->priv;
132 	return skb_dequeue(&h4->txq);
133 }
134 
135 static const struct hci_uart_proto h4p = {
136 	.id		= HCI_UART_H4,
137 	.name		= "H4",
138 	.open		= h4_open,
139 	.close		= h4_close,
140 	.recv		= h4_recv,
141 	.enqueue	= h4_enqueue,
142 	.dequeue	= h4_dequeue,
143 	.flush		= h4_flush,
144 };
145 
146 int __init h4_init(void)
147 {
148 	return hci_uart_register_proto(&h4p);
149 }
150 
151 int __exit h4_deinit(void)
152 {
153 	return hci_uart_unregister_proto(&h4p);
154 }
155 
156 struct sk_buff *h4_recv_buf(struct hci_uart *hu, struct sk_buff *skb,
157 			    const unsigned char *buffer, int count,
158 			    const struct h4_recv_pkt *pkts, int pkts_count)
159 {
160 	return h4_recv_skb(hu->hdev, &hu->alignment, &hu->padding, skb, buffer,
161 			   count, pkts, pkts_count);
162 }
163 EXPORT_SYMBOL_GPL(h4_recv_buf);
164