Commit | Line | Data |
---|---|---|
162f812f LP |
1 | /* |
2 | * | |
3 | * Bluetooth HCI UART driver for marvell devices | |
4 | * | |
5 | * Copyright (C) 2016 Marvell International Ltd. | |
6 | * Copyright (C) 2016 Intel Corporation | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation; either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | * | |
22 | */ | |
23 | ||
24 | #include <linux/kernel.h> | |
25 | #include <linux/errno.h> | |
26 | #include <linux/skbuff.h> | |
27 | #include <linux/firmware.h> | |
28 | #include <linux/module.h> | |
29 | #include <linux/tty.h> | |
30 | ||
31 | #include <net/bluetooth/bluetooth.h> | |
32 | #include <net/bluetooth/hci_core.h> | |
33 | ||
34 | #include "hci_uart.h" | |
35 | ||
36 | #define HCI_FW_REQ_PKT 0xA5 | |
37 | #define HCI_CHIP_VER_PKT 0xAA | |
38 | ||
39 | #define MRVL_ACK 0x5A | |
40 | #define MRVL_NAK 0xBF | |
41 | #define MRVL_RAW_DATA 0x1F | |
42 | ||
43 | enum { | |
44 | STATE_CHIP_VER_PENDING, | |
45 | STATE_FW_REQ_PENDING, | |
46 | }; | |
47 | ||
48 | struct mrvl_data { | |
49 | struct sk_buff *rx_skb; | |
50 | struct sk_buff_head txq; | |
51 | struct sk_buff_head rawq; | |
52 | unsigned long flags; | |
53 | unsigned int tx_len; | |
54 | u8 id, rev; | |
55 | }; | |
56 | ||
57 | struct hci_mrvl_pkt { | |
58 | __le16 lhs; | |
59 | __le16 rhs; | |
60 | } __packed; | |
61 | #define HCI_MRVL_PKT_SIZE 4 | |
62 | ||
63 | static int mrvl_open(struct hci_uart *hu) | |
64 | { | |
65 | struct mrvl_data *mrvl; | |
66 | ||
67 | BT_DBG("hu %p", hu); | |
68 | ||
69 | mrvl = kzalloc(sizeof(*mrvl), GFP_KERNEL); | |
70 | if (!mrvl) | |
71 | return -ENOMEM; | |
72 | ||
73 | skb_queue_head_init(&mrvl->txq); | |
74 | skb_queue_head_init(&mrvl->rawq); | |
75 | ||
76 | set_bit(STATE_CHIP_VER_PENDING, &mrvl->flags); | |
77 | ||
78 | hu->priv = mrvl; | |
79 | return 0; | |
80 | } | |
81 | ||
82 | static int mrvl_close(struct hci_uart *hu) | |
83 | { | |
84 | struct mrvl_data *mrvl = hu->priv; | |
85 | ||
86 | BT_DBG("hu %p", hu); | |
87 | ||
88 | skb_queue_purge(&mrvl->txq); | |
89 | skb_queue_purge(&mrvl->rawq); | |
90 | kfree_skb(mrvl->rx_skb); | |
91 | kfree(mrvl); | |
92 | ||
93 | hu->priv = NULL; | |
94 | return 0; | |
95 | } | |
96 | ||
97 | static int mrvl_flush(struct hci_uart *hu) | |
98 | { | |
99 | struct mrvl_data *mrvl = hu->priv; | |
100 | ||
101 | BT_DBG("hu %p", hu); | |
102 | ||
103 | skb_queue_purge(&mrvl->txq); | |
104 | skb_queue_purge(&mrvl->rawq); | |
105 | ||
106 | return 0; | |
107 | } | |
108 | ||
109 | static struct sk_buff *mrvl_dequeue(struct hci_uart *hu) | |
110 | { | |
111 | struct mrvl_data *mrvl = hu->priv; | |
112 | struct sk_buff *skb; | |
113 | ||
114 | skb = skb_dequeue(&mrvl->txq); | |
115 | if (!skb) { | |
116 | /* Any raw data ? */ | |
117 | skb = skb_dequeue(&mrvl->rawq); | |
118 | } else { | |
119 | /* Prepend skb with frame type */ | |
120 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); | |
121 | } | |
122 | ||
123 | return skb; | |
124 | } | |
125 | ||
126 | static int mrvl_enqueue(struct hci_uart *hu, struct sk_buff *skb) | |
127 | { | |
128 | struct mrvl_data *mrvl = hu->priv; | |
129 | ||
130 | skb_queue_tail(&mrvl->txq, skb); | |
131 | return 0; | |
132 | } | |
133 | ||
134 | static void mrvl_send_ack(struct hci_uart *hu, unsigned char type) | |
135 | { | |
136 | struct mrvl_data *mrvl = hu->priv; | |
137 | struct sk_buff *skb; | |
138 | ||
139 | /* No H4 payload, only 1 byte header */ | |
140 | skb = bt_skb_alloc(0, GFP_ATOMIC); | |
141 | if (!skb) { | |
142 | bt_dev_err(hu->hdev, "Unable to alloc ack/nak packet"); | |
143 | return; | |
144 | } | |
145 | hci_skb_pkt_type(skb) = type; | |
146 | ||
147 | skb_queue_tail(&mrvl->txq, skb); | |
148 | hci_uart_tx_wakeup(hu); | |
149 | } | |
150 | ||
151 | static int mrvl_recv_fw_req(struct hci_dev *hdev, struct sk_buff *skb) | |
152 | { | |
153 | struct hci_mrvl_pkt *pkt = (void *)skb->data; | |
154 | struct hci_uart *hu = hci_get_drvdata(hdev); | |
155 | struct mrvl_data *mrvl = hu->priv; | |
156 | int ret = 0; | |
157 | ||
158 | if ((pkt->lhs ^ pkt->rhs) != 0xffff) { | |
159 | bt_dev_err(hdev, "Corrupted mrvl header"); | |
160 | mrvl_send_ack(hu, MRVL_NAK); | |
161 | ret = -EINVAL; | |
162 | goto done; | |
163 | } | |
164 | mrvl_send_ack(hu, MRVL_ACK); | |
165 | ||
166 | if (!test_bit(STATE_FW_REQ_PENDING, &mrvl->flags)) { | |
167 | bt_dev_err(hdev, "Received unexpected firmware request"); | |
168 | ret = -EINVAL; | |
169 | goto done; | |
170 | } | |
171 | ||
172 | mrvl->tx_len = le16_to_cpu(pkt->lhs); | |
173 | ||
174 | clear_bit(STATE_FW_REQ_PENDING, &mrvl->flags); | |
175 | smp_mb__after_atomic(); | |
176 | wake_up_bit(&mrvl->flags, STATE_FW_REQ_PENDING); | |
177 | ||
178 | done: | |
179 | kfree_skb(skb); | |
180 | return ret; | |
181 | } | |
182 | ||
183 | static int mrvl_recv_chip_ver(struct hci_dev *hdev, struct sk_buff *skb) | |
184 | { | |
185 | struct hci_mrvl_pkt *pkt = (void *)skb->data; | |
186 | struct hci_uart *hu = hci_get_drvdata(hdev); | |
187 | struct mrvl_data *mrvl = hu->priv; | |
188 | u16 version = le16_to_cpu(pkt->lhs); | |
189 | int ret = 0; | |
190 | ||
191 | if ((pkt->lhs ^ pkt->rhs) != 0xffff) { | |
192 | bt_dev_err(hdev, "Corrupted mrvl header"); | |
193 | mrvl_send_ack(hu, MRVL_NAK); | |
194 | ret = -EINVAL; | |
195 | goto done; | |
196 | } | |
197 | mrvl_send_ack(hu, MRVL_ACK); | |
198 | ||
199 | if (!test_bit(STATE_CHIP_VER_PENDING, &mrvl->flags)) { | |
200 | bt_dev_err(hdev, "Received unexpected chip version"); | |
201 | goto done; | |
202 | } | |
203 | ||
204 | mrvl->id = version; | |
205 | mrvl->rev = version >> 8; | |
206 | ||
207 | bt_dev_info(hdev, "Controller id = %x, rev = %x", mrvl->id, mrvl->rev); | |
208 | ||
209 | clear_bit(STATE_CHIP_VER_PENDING, &mrvl->flags); | |
210 | smp_mb__after_atomic(); | |
211 | wake_up_bit(&mrvl->flags, STATE_CHIP_VER_PENDING); | |
212 | ||
213 | done: | |
214 | kfree_skb(skb); | |
215 | return ret; | |
216 | } | |
217 | ||
218 | #define HCI_RECV_CHIP_VER \ | |
219 | .type = HCI_CHIP_VER_PKT, \ | |
220 | .hlen = HCI_MRVL_PKT_SIZE, \ | |
221 | .loff = 0, \ | |
222 | .lsize = 0, \ | |
223 | .maxlen = HCI_MRVL_PKT_SIZE | |
224 | ||
225 | #define HCI_RECV_FW_REQ \ | |
226 | .type = HCI_FW_REQ_PKT, \ | |
227 | .hlen = HCI_MRVL_PKT_SIZE, \ | |
228 | .loff = 0, \ | |
229 | .lsize = 0, \ | |
230 | .maxlen = HCI_MRVL_PKT_SIZE | |
231 | ||
232 | static const struct h4_recv_pkt mrvl_recv_pkts[] = { | |
233 | { H4_RECV_ACL, .recv = hci_recv_frame }, | |
234 | { H4_RECV_SCO, .recv = hci_recv_frame }, | |
235 | { H4_RECV_EVENT, .recv = hci_recv_frame }, | |
236 | { HCI_RECV_FW_REQ, .recv = mrvl_recv_fw_req }, | |
237 | { HCI_RECV_CHIP_VER, .recv = mrvl_recv_chip_ver }, | |
238 | }; | |
239 | ||
240 | static int mrvl_recv(struct hci_uart *hu, const void *data, int count) | |
241 | { | |
242 | struct mrvl_data *mrvl = hu->priv; | |
243 | ||
244 | if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) | |
245 | return -EUNATCH; | |
246 | ||
247 | mrvl->rx_skb = h4_recv_buf(hu->hdev, mrvl->rx_skb, data, count, | |
248 | mrvl_recv_pkts, | |
249 | ARRAY_SIZE(mrvl_recv_pkts)); | |
250 | if (IS_ERR(mrvl->rx_skb)) { | |
251 | int err = PTR_ERR(mrvl->rx_skb); | |
252 | bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err); | |
253 | mrvl->rx_skb = NULL; | |
254 | return err; | |
255 | } | |
256 | ||
257 | return count; | |
258 | } | |
259 | ||
260 | static int mrvl_load_firmware(struct hci_dev *hdev, const char *name) | |
261 | { | |
262 | struct hci_uart *hu = hci_get_drvdata(hdev); | |
263 | struct mrvl_data *mrvl = hu->priv; | |
264 | const struct firmware *fw = NULL; | |
265 | const u8 *fw_ptr, *fw_max; | |
266 | int err; | |
267 | ||
268 | err = request_firmware(&fw, name, &hdev->dev); | |
269 | if (err < 0) { | |
270 | bt_dev_err(hdev, "Failed to load firmware file %s", name); | |
271 | return err; | |
272 | } | |
273 | ||
274 | fw_ptr = fw->data; | |
275 | fw_max = fw->data + fw->size; | |
276 | ||
277 | bt_dev_info(hdev, "Loading %s", name); | |
278 | ||
279 | set_bit(STATE_FW_REQ_PENDING, &mrvl->flags); | |
280 | ||
281 | while (fw_ptr <= fw_max) { | |
282 | struct sk_buff *skb; | |
283 | ||
284 | /* Controller drives the firmware load by sending firmware | |
285 | * request packets containing the expected fragment size. | |
286 | */ | |
287 | err = wait_on_bit_timeout(&mrvl->flags, STATE_FW_REQ_PENDING, | |
288 | TASK_INTERRUPTIBLE, | |
289 | msecs_to_jiffies(2000)); | |
290 | if (err == 1) { | |
291 | bt_dev_err(hdev, "Firmware load interrupted"); | |
292 | err = -EINTR; | |
293 | break; | |
294 | } else if (err) { | |
295 | bt_dev_err(hdev, "Firmware request timeout"); | |
296 | err = -ETIMEDOUT; | |
297 | break; | |
298 | } | |
299 | ||
300 | bt_dev_dbg(hdev, "Firmware request, expecting %d bytes", | |
301 | mrvl->tx_len); | |
302 | ||
303 | if (fw_ptr == fw_max) { | |
304 | /* Controller requests a null size once firmware is | |
305 | * fully loaded. If controller expects more data, there | |
306 | * is an issue. | |
307 | */ | |
308 | if (!mrvl->tx_len) { | |
309 | bt_dev_info(hdev, "Firmware loading complete"); | |
310 | } else { | |
311 | bt_dev_err(hdev, "Firmware loading failure"); | |
312 | err = -EINVAL; | |
313 | } | |
314 | break; | |
315 | } | |
316 | ||
317 | if (fw_ptr + mrvl->tx_len > fw_max) { | |
318 | mrvl->tx_len = fw_max - fw_ptr; | |
319 | bt_dev_dbg(hdev, "Adjusting tx_len to %d", | |
320 | mrvl->tx_len); | |
321 | } | |
322 | ||
323 | skb = bt_skb_alloc(mrvl->tx_len, GFP_KERNEL); | |
324 | if (!skb) { | |
325 | bt_dev_err(hdev, "Failed to alloc mem for FW packet"); | |
326 | err = -ENOMEM; | |
327 | break; | |
328 | } | |
329 | bt_cb(skb)->pkt_type = MRVL_RAW_DATA; | |
330 | ||
331 | memcpy(skb_put(skb, mrvl->tx_len), fw_ptr, mrvl->tx_len); | |
332 | fw_ptr += mrvl->tx_len; | |
333 | ||
334 | set_bit(STATE_FW_REQ_PENDING, &mrvl->flags); | |
335 | ||
336 | skb_queue_tail(&mrvl->rawq, skb); | |
337 | hci_uart_tx_wakeup(hu); | |
338 | } | |
339 | ||
340 | release_firmware(fw); | |
341 | return err; | |
342 | } | |
343 | ||
344 | static int mrvl_setup(struct hci_uart *hu) | |
345 | { | |
346 | int err; | |
347 | ||
348 | hci_uart_set_flow_control(hu, true); | |
349 | ||
350 | err = mrvl_load_firmware(hu->hdev, "mrvl/helper_uart_3000000.bin"); | |
351 | if (err) { | |
352 | bt_dev_err(hu->hdev, "Unable to download firmware helper"); | |
353 | return -EINVAL; | |
354 | } | |
355 | ||
356 | hci_uart_set_baudrate(hu, 3000000); | |
357 | hci_uart_set_flow_control(hu, false); | |
358 | ||
359 | err = mrvl_load_firmware(hu->hdev, "mrvl/uart8897_bt.bin"); | |
360 | if (err) | |
361 | return err; | |
362 | ||
363 | return 0; | |
364 | } | |
365 | ||
366 | static const struct hci_uart_proto mrvl_proto = { | |
367 | .id = HCI_UART_MRVL, | |
368 | .name = "Marvell", | |
369 | .init_speed = 115200, | |
370 | .open = mrvl_open, | |
371 | .close = mrvl_close, | |
372 | .flush = mrvl_flush, | |
373 | .setup = mrvl_setup, | |
374 | .recv = mrvl_recv, | |
375 | .enqueue = mrvl_enqueue, | |
376 | .dequeue = mrvl_dequeue, | |
377 | }; | |
378 | ||
379 | int __init mrvl_init(void) | |
380 | { | |
381 | return hci_uart_register_proto(&mrvl_proto); | |
382 | } | |
383 | ||
384 | int __exit mrvl_deinit(void) | |
385 | { | |
386 | return hci_uart_unregister_proto(&mrvl_proto); | |
387 | } |