Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 *
  4 *  Bluetooth HCI UART driver for marvell devices
  5 *
  6 *  Copyright (C) 2016  Marvell International Ltd.
  7 *  Copyright (C) 2016  Intel Corporation
  8 */
  9
 10#include <linux/kernel.h>
 11#include <linux/errno.h>
 12#include <linux/skbuff.h>
 13#include <linux/firmware.h>
 14#include <linux/module.h>
 15#include <linux/tty.h>
 16#include <linux/of.h>
 17#include <linux/serdev.h>
 18
 19#include <net/bluetooth/bluetooth.h>
 20#include <net/bluetooth/hci_core.h>
 21
 22#include "hci_uart.h"
 23
 24#define HCI_FW_REQ_PKT 0xA5
 25#define HCI_CHIP_VER_PKT 0xAA
 26
 27#define MRVL_ACK 0x5A
 28#define MRVL_NAK 0xBF
 29#define MRVL_RAW_DATA 0x1F
 30
 31enum {
 32	STATE_CHIP_VER_PENDING,
 33	STATE_FW_REQ_PENDING,
 34};
 35
 36struct mrvl_data {
 37	struct sk_buff *rx_skb;
 38	struct sk_buff_head txq;
 39	struct sk_buff_head rawq;
 40	unsigned long flags;
 41	unsigned int tx_len;
 42	u8 id, rev;
 43};
 44
 45struct mrvl_serdev {
 46	struct hci_uart hu;
 47};
 48
 49struct hci_mrvl_pkt {
 50	__le16 lhs;
 51	__le16 rhs;
 52} __packed;
 53#define HCI_MRVL_PKT_SIZE 4
 54
 55static int mrvl_open(struct hci_uart *hu)
 56{
 57	struct mrvl_data *mrvl;
 58	int ret;
 59
 60	BT_DBG("hu %p", hu);
 61
 62	if (!hci_uart_has_flow_control(hu))
 63		return -EOPNOTSUPP;
 64
 65	mrvl = kzalloc(sizeof(*mrvl), GFP_KERNEL);
 66	if (!mrvl)
 67		return -ENOMEM;
 68
 69	skb_queue_head_init(&mrvl->txq);
 70	skb_queue_head_init(&mrvl->rawq);
 71
 72	set_bit(STATE_CHIP_VER_PENDING, &mrvl->flags);
 73
 74	hu->priv = mrvl;
 75
 76	if (hu->serdev) {
 77		ret = serdev_device_open(hu->serdev);
 78		if (ret)
 79			goto err;
 80	}
 81
 82	return 0;
 83err:
 84	kfree(mrvl);
 85
 86	return ret;
 87}
 88
 89static int mrvl_close(struct hci_uart *hu)
 90{
 91	struct mrvl_data *mrvl = hu->priv;
 92
 93	BT_DBG("hu %p", hu);
 94
 95	if (hu->serdev)
 96		serdev_device_close(hu->serdev);
 97
 98	skb_queue_purge(&mrvl->txq);
 99	skb_queue_purge(&mrvl->rawq);
100	kfree_skb(mrvl->rx_skb);
101	kfree(mrvl);
102
103	hu->priv = NULL;
104	return 0;
105}
106
107static int mrvl_flush(struct hci_uart *hu)
108{
109	struct mrvl_data *mrvl = hu->priv;
110
111	BT_DBG("hu %p", hu);
112
113	skb_queue_purge(&mrvl->txq);
114	skb_queue_purge(&mrvl->rawq);
115
116	return 0;
117}
118
119static struct sk_buff *mrvl_dequeue(struct hci_uart *hu)
120{
121	struct mrvl_data *mrvl = hu->priv;
122	struct sk_buff *skb;
123
124	skb = skb_dequeue(&mrvl->txq);
125	if (!skb) {
126		/* Any raw data ? */
127		skb = skb_dequeue(&mrvl->rawq);
128	} else {
129		/* Prepend skb with frame type */
130		memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
131	}
132
133	return skb;
134}
135
136static int mrvl_enqueue(struct hci_uart *hu, struct sk_buff *skb)
137{
138	struct mrvl_data *mrvl = hu->priv;
139
140	skb_queue_tail(&mrvl->txq, skb);
141	return 0;
142}
143
144static void mrvl_send_ack(struct hci_uart *hu, unsigned char type)
145{
146	struct mrvl_data *mrvl = hu->priv;
147	struct sk_buff *skb;
148
149	/* No H4 payload, only 1 byte header */
150	skb = bt_skb_alloc(0, GFP_ATOMIC);
151	if (!skb) {
152		bt_dev_err(hu->hdev, "Unable to alloc ack/nak packet");
153		return;
154	}
155	hci_skb_pkt_type(skb) = type;
156
157	skb_queue_tail(&mrvl->txq, skb);
158	hci_uart_tx_wakeup(hu);
159}
160
161static int mrvl_recv_fw_req(struct hci_dev *hdev, struct sk_buff *skb)
162{
163	struct hci_mrvl_pkt *pkt = (void *)skb->data;
164	struct hci_uart *hu = hci_get_drvdata(hdev);
165	struct mrvl_data *mrvl = hu->priv;
166	int ret = 0;
167
168	if ((pkt->lhs ^ pkt->rhs) != 0xffff) {
169		bt_dev_err(hdev, "Corrupted mrvl header");
170		mrvl_send_ack(hu, MRVL_NAK);
171		ret = -EINVAL;
172		goto done;
173	}
174	mrvl_send_ack(hu, MRVL_ACK);
175
176	if (!test_bit(STATE_FW_REQ_PENDING, &mrvl->flags)) {
177		bt_dev_err(hdev, "Received unexpected firmware request");
178		ret = -EINVAL;
179		goto done;
180	}
181
182	mrvl->tx_len = le16_to_cpu(pkt->lhs);
183
184	clear_bit(STATE_FW_REQ_PENDING, &mrvl->flags);
185	smp_mb__after_atomic();
186	wake_up_bit(&mrvl->flags, STATE_FW_REQ_PENDING);
187
188done:
189	kfree_skb(skb);
190	return ret;
191}
192
193static int mrvl_recv_chip_ver(struct hci_dev *hdev, struct sk_buff *skb)
194{
195	struct hci_mrvl_pkt *pkt = (void *)skb->data;
196	struct hci_uart *hu = hci_get_drvdata(hdev);
197	struct mrvl_data *mrvl = hu->priv;
198	u16 version = le16_to_cpu(pkt->lhs);
199	int ret = 0;
200
201	if ((pkt->lhs ^ pkt->rhs) != 0xffff) {
202		bt_dev_err(hdev, "Corrupted mrvl header");
203		mrvl_send_ack(hu, MRVL_NAK);
204		ret = -EINVAL;
205		goto done;
206	}
207	mrvl_send_ack(hu, MRVL_ACK);
208
209	if (!test_bit(STATE_CHIP_VER_PENDING, &mrvl->flags)) {
210		bt_dev_err(hdev, "Received unexpected chip version");
211		goto done;
212	}
213
214	mrvl->id = version;
215	mrvl->rev = version >> 8;
216
217	bt_dev_info(hdev, "Controller id = %x, rev = %x", mrvl->id, mrvl->rev);
218
219	clear_bit(STATE_CHIP_VER_PENDING, &mrvl->flags);
220	smp_mb__after_atomic();
221	wake_up_bit(&mrvl->flags, STATE_CHIP_VER_PENDING);
222
223done:
224	kfree_skb(skb);
225	return ret;
226}
227
228#define HCI_RECV_CHIP_VER \
229	.type = HCI_CHIP_VER_PKT, \
230	.hlen = HCI_MRVL_PKT_SIZE, \
231	.loff = 0, \
232	.lsize = 0, \
233	.maxlen = HCI_MRVL_PKT_SIZE
234
235#define HCI_RECV_FW_REQ \
236	.type = HCI_FW_REQ_PKT, \
237	.hlen = HCI_MRVL_PKT_SIZE, \
238	.loff = 0, \
239	.lsize = 0, \
240	.maxlen = HCI_MRVL_PKT_SIZE
241
242static const struct h4_recv_pkt mrvl_recv_pkts[] = {
243	{ H4_RECV_ACL,       .recv = hci_recv_frame     },
244	{ H4_RECV_SCO,       .recv = hci_recv_frame     },
245	{ H4_RECV_EVENT,     .recv = hci_recv_frame     },
246	{ HCI_RECV_FW_REQ,   .recv = mrvl_recv_fw_req   },
247	{ HCI_RECV_CHIP_VER, .recv = mrvl_recv_chip_ver },
248};
249
250static int mrvl_recv(struct hci_uart *hu, const void *data, int count)
251{
252	struct mrvl_data *mrvl = hu->priv;
253
254	if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
255		return -EUNATCH;
256
257	mrvl->rx_skb = h4_recv_buf(hu->hdev, mrvl->rx_skb, data, count,
258				    mrvl_recv_pkts,
259				    ARRAY_SIZE(mrvl_recv_pkts));
260	if (IS_ERR(mrvl->rx_skb)) {
261		int err = PTR_ERR(mrvl->rx_skb);
262		bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
263		mrvl->rx_skb = NULL;
264		return err;
265	}
266
267	return count;
268}
269
270static int mrvl_load_firmware(struct hci_dev *hdev, const char *name)
271{
272	struct hci_uart *hu = hci_get_drvdata(hdev);
273	struct mrvl_data *mrvl = hu->priv;
274	const struct firmware *fw = NULL;
275	const u8 *fw_ptr, *fw_max;
276	int err;
277
278	err = request_firmware(&fw, name, &hdev->dev);
279	if (err < 0) {
280		bt_dev_err(hdev, "Failed to load firmware file %s", name);
281		return err;
282	}
283
284	fw_ptr = fw->data;
285	fw_max = fw->data + fw->size;
286
287	bt_dev_info(hdev, "Loading %s", name);
288
289	set_bit(STATE_FW_REQ_PENDING, &mrvl->flags);
290
291	while (fw_ptr <= fw_max) {
292		struct sk_buff *skb;
293
294		/* Controller drives the firmware load by sending firmware
295		 * request packets containing the expected fragment size.
296		 */
297		err = wait_on_bit_timeout(&mrvl->flags, STATE_FW_REQ_PENDING,
298					  TASK_INTERRUPTIBLE,
299					  msecs_to_jiffies(2000));
300		if (err == 1) {
301			bt_dev_err(hdev, "Firmware load interrupted");
302			err = -EINTR;
303			break;
304		} else if (err) {
305			bt_dev_err(hdev, "Firmware request timeout");
306			err = -ETIMEDOUT;
307			break;
308		}
309
310		bt_dev_dbg(hdev, "Firmware request, expecting %d bytes",
311			   mrvl->tx_len);
312
313		if (fw_ptr == fw_max) {
314			/* Controller requests a null size once firmware is
315			 * fully loaded. If controller expects more data, there
316			 * is an issue.
317			 */
318			if (!mrvl->tx_len) {
319				bt_dev_info(hdev, "Firmware loading complete");
320			} else {
321				bt_dev_err(hdev, "Firmware loading failure");
322				err = -EINVAL;
323			}
324			break;
325		}
326
327		if (fw_ptr + mrvl->tx_len > fw_max) {
328			mrvl->tx_len = fw_max - fw_ptr;
329			bt_dev_dbg(hdev, "Adjusting tx_len to %d",
330				   mrvl->tx_len);
331		}
332
333		skb = bt_skb_alloc(mrvl->tx_len, GFP_KERNEL);
334		if (!skb) {
335			bt_dev_err(hdev, "Failed to alloc mem for FW packet");
336			err = -ENOMEM;
337			break;
338		}
339		bt_cb(skb)->pkt_type = MRVL_RAW_DATA;
340
341		skb_put_data(skb, fw_ptr, mrvl->tx_len);
342		fw_ptr += mrvl->tx_len;
343
344		set_bit(STATE_FW_REQ_PENDING, &mrvl->flags);
345
346		skb_queue_tail(&mrvl->rawq, skb);
347		hci_uart_tx_wakeup(hu);
348	}
349
350	release_firmware(fw);
351	return err;
352}
353
354static int mrvl_setup(struct hci_uart *hu)
355{
356	int err;
357
358	hci_uart_set_flow_control(hu, true);
359
360	err = mrvl_load_firmware(hu->hdev, "mrvl/helper_uart_3000000.bin");
361	if (err) {
362		bt_dev_err(hu->hdev, "Unable to download firmware helper");
363		return -EINVAL;
364	}
365
366	/* Let the final ack go out before switching the baudrate */
367	hci_uart_wait_until_sent(hu);
368
369	if (hu->serdev)
370		serdev_device_set_baudrate(hu->serdev, 3000000);
371	else
372		hci_uart_set_baudrate(hu, 3000000);
373
374	hci_uart_set_flow_control(hu, false);
375
376	err = mrvl_load_firmware(hu->hdev, "mrvl/uart8897_bt.bin");
377	if (err)
378		return err;
379
380	return 0;
381}
382
383static const struct hci_uart_proto mrvl_proto = {
384	.id		= HCI_UART_MRVL,
385	.name		= "Marvell",
386	.init_speed	= 115200,
387	.open		= mrvl_open,
388	.close		= mrvl_close,
389	.flush		= mrvl_flush,
390	.setup		= mrvl_setup,
391	.recv		= mrvl_recv,
392	.enqueue	= mrvl_enqueue,
393	.dequeue	= mrvl_dequeue,
394};
395
396static int mrvl_serdev_probe(struct serdev_device *serdev)
397{
398	struct mrvl_serdev *mrvldev;
399
400	mrvldev = devm_kzalloc(&serdev->dev, sizeof(*mrvldev), GFP_KERNEL);
401	if (!mrvldev)
402		return -ENOMEM;
403
404	mrvldev->hu.serdev = serdev;
405	serdev_device_set_drvdata(serdev, mrvldev);
406
407	return hci_uart_register_device(&mrvldev->hu, &mrvl_proto);
408}
409
410static void mrvl_serdev_remove(struct serdev_device *serdev)
411{
412	struct mrvl_serdev *mrvldev = serdev_device_get_drvdata(serdev);
413
414	hci_uart_unregister_device(&mrvldev->hu);
415}
416
417#ifdef CONFIG_OF
418static const struct of_device_id mrvl_bluetooth_of_match[] = {
419	{ .compatible = "mrvl,88w8897" },
420	{ },
421};
422MODULE_DEVICE_TABLE(of, mrvl_bluetooth_of_match);
423#endif
424
425static struct serdev_device_driver mrvl_serdev_driver = {
426	.probe = mrvl_serdev_probe,
427	.remove = mrvl_serdev_remove,
428	.driver = {
429		.name = "hci_uart_mrvl",
430		.of_match_table = of_match_ptr(mrvl_bluetooth_of_match),
431	},
432};
433
434int __init mrvl_init(void)
435{
436	serdev_device_driver_register(&mrvl_serdev_driver);
437
438	return hci_uart_register_proto(&mrvl_proto);
439}
440
441int __exit mrvl_deinit(void)
442{
443	serdev_device_driver_unregister(&mrvl_serdev_driver);
444
445	return hci_uart_unregister_proto(&mrvl_proto);
446}