162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *  Bluetooth HCI UART driver
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci *  Copyright (C) 2002-2003  Fabrizio Gennari <fabrizio.gennari@philips.com>
762306a36Sopenharmony_ci *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/module.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/kernel.h>
1362306a36Sopenharmony_ci#include <linux/init.h>
1462306a36Sopenharmony_ci#include <linux/types.h>
1562306a36Sopenharmony_ci#include <linux/fcntl.h>
1662306a36Sopenharmony_ci#include <linux/interrupt.h>
1762306a36Sopenharmony_ci#include <linux/ptrace.h>
1862306a36Sopenharmony_ci#include <linux/poll.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include <linux/slab.h>
2162306a36Sopenharmony_ci#include <linux/tty.h>
2262306a36Sopenharmony_ci#include <linux/errno.h>
2362306a36Sopenharmony_ci#include <linux/string.h>
2462306a36Sopenharmony_ci#include <linux/signal.h>
2562306a36Sopenharmony_ci#include <linux/ioctl.h>
2662306a36Sopenharmony_ci#include <linux/skbuff.h>
2762306a36Sopenharmony_ci#include <linux/bitrev.h>
2862306a36Sopenharmony_ci#include <asm/unaligned.h>
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#include <net/bluetooth/bluetooth.h>
3162306a36Sopenharmony_ci#include <net/bluetooth/hci_core.h>
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#include "hci_uart.h"
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic bool txcrc = true;
3662306a36Sopenharmony_cistatic bool hciextn = true;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define BCSP_TXWINSIZE	4
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#define BCSP_ACK_PKT	0x05
4162306a36Sopenharmony_ci#define BCSP_LE_PKT	0x06
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistruct bcsp_struct {
4462306a36Sopenharmony_ci	struct sk_buff_head unack;	/* Unack'ed packets queue */
4562306a36Sopenharmony_ci	struct sk_buff_head rel;	/* Reliable packets queue */
4662306a36Sopenharmony_ci	struct sk_buff_head unrel;	/* Unreliable packets queue */
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	unsigned long rx_count;
4962306a36Sopenharmony_ci	struct	sk_buff *rx_skb;
5062306a36Sopenharmony_ci	u8	rxseq_txack;		/* rxseq == txack. */
5162306a36Sopenharmony_ci	u8	rxack;			/* Last packet sent by us that the peer ack'ed */
5262306a36Sopenharmony_ci	struct	timer_list tbcsp;
5362306a36Sopenharmony_ci	struct	hci_uart *hu;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	enum {
5662306a36Sopenharmony_ci		BCSP_W4_PKT_DELIMITER,
5762306a36Sopenharmony_ci		BCSP_W4_PKT_START,
5862306a36Sopenharmony_ci		BCSP_W4_BCSP_HDR,
5962306a36Sopenharmony_ci		BCSP_W4_DATA,
6062306a36Sopenharmony_ci		BCSP_W4_CRC
6162306a36Sopenharmony_ci	} rx_state;
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	enum {
6462306a36Sopenharmony_ci		BCSP_ESCSTATE_NOESC,
6562306a36Sopenharmony_ci		BCSP_ESCSTATE_ESC
6662306a36Sopenharmony_ci	} rx_esc_state;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	u8	use_crc;
6962306a36Sopenharmony_ci	u16	message_crc;
7062306a36Sopenharmony_ci	u8	txack_req;		/* Do we need to send ack's to the peer? */
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	/* Reliable packet sequence number - used to assign seq to each rel pkt. */
7362306a36Sopenharmony_ci	u8	msgq_txseq;
7462306a36Sopenharmony_ci};
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci/* ---- BCSP CRC calculation ---- */
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
7962306a36Sopenharmony_ci * initial value 0xffff, bits shifted in reverse order.
8062306a36Sopenharmony_ci */
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistatic const u16 crc_table[] = {
8362306a36Sopenharmony_ci	0x0000, 0x1081, 0x2102, 0x3183,
8462306a36Sopenharmony_ci	0x4204, 0x5285, 0x6306, 0x7387,
8562306a36Sopenharmony_ci	0x8408, 0x9489, 0xa50a, 0xb58b,
8662306a36Sopenharmony_ci	0xc60c, 0xd68d, 0xe70e, 0xf78f
8762306a36Sopenharmony_ci};
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/* Initialise the crc calculator */
9062306a36Sopenharmony_ci#define BCSP_CRC_INIT(x) x = 0xffff
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci/* Update crc with next data byte
9362306a36Sopenharmony_ci *
9462306a36Sopenharmony_ci * Implementation note
9562306a36Sopenharmony_ci *     The data byte is treated as two nibbles.  The crc is generated
9662306a36Sopenharmony_ci *     in reverse, i.e., bits are fed into the register from the top.
9762306a36Sopenharmony_ci */
9862306a36Sopenharmony_cistatic void bcsp_crc_update(u16 *crc, u8 d)
9962306a36Sopenharmony_ci{
10062306a36Sopenharmony_ci	u16 reg = *crc;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
10362306a36Sopenharmony_ci	reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	*crc = reg;
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci/* ---- BCSP core ---- */
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_cistatic void bcsp_slip_msgdelim(struct sk_buff *skb)
11162306a36Sopenharmony_ci{
11262306a36Sopenharmony_ci	const char pkt_delim = 0xc0;
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	skb_put_data(skb, &pkt_delim, 1);
11562306a36Sopenharmony_ci}
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	const char esc_c0[2] = { 0xdb, 0xdc };
12062306a36Sopenharmony_ci	const char esc_db[2] = { 0xdb, 0xdd };
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	switch (c) {
12362306a36Sopenharmony_ci	case 0xc0:
12462306a36Sopenharmony_ci		skb_put_data(skb, &esc_c0, 2);
12562306a36Sopenharmony_ci		break;
12662306a36Sopenharmony_ci	case 0xdb:
12762306a36Sopenharmony_ci		skb_put_data(skb, &esc_db, 2);
12862306a36Sopenharmony_ci		break;
12962306a36Sopenharmony_ci	default:
13062306a36Sopenharmony_ci		skb_put_data(skb, &c, 1);
13162306a36Sopenharmony_ci	}
13262306a36Sopenharmony_ci}
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistatic int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	struct bcsp_struct *bcsp = hu->priv;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	if (skb->len > 0xFFF) {
13962306a36Sopenharmony_ci		BT_ERR("Packet too long");
14062306a36Sopenharmony_ci		kfree_skb(skb);
14162306a36Sopenharmony_ci		return 0;
14262306a36Sopenharmony_ci	}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	switch (hci_skb_pkt_type(skb)) {
14562306a36Sopenharmony_ci	case HCI_ACLDATA_PKT:
14662306a36Sopenharmony_ci	case HCI_COMMAND_PKT:
14762306a36Sopenharmony_ci		skb_queue_tail(&bcsp->rel, skb);
14862306a36Sopenharmony_ci		break;
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	case HCI_SCODATA_PKT:
15162306a36Sopenharmony_ci		skb_queue_tail(&bcsp->unrel, skb);
15262306a36Sopenharmony_ci		break;
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	default:
15562306a36Sopenharmony_ci		BT_ERR("Unknown packet type");
15662306a36Sopenharmony_ci		kfree_skb(skb);
15762306a36Sopenharmony_ci		break;
15862306a36Sopenharmony_ci	}
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	return 0;
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistatic struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
16462306a36Sopenharmony_ci					int len, int pkt_type)
16562306a36Sopenharmony_ci{
16662306a36Sopenharmony_ci	struct sk_buff *nskb;
16762306a36Sopenharmony_ci	u8 hdr[4], chan;
16862306a36Sopenharmony_ci	u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
16962306a36Sopenharmony_ci	int rel, i;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	switch (pkt_type) {
17262306a36Sopenharmony_ci	case HCI_ACLDATA_PKT:
17362306a36Sopenharmony_ci		chan = 6;	/* BCSP ACL channel */
17462306a36Sopenharmony_ci		rel = 1;	/* reliable channel */
17562306a36Sopenharmony_ci		break;
17662306a36Sopenharmony_ci	case HCI_COMMAND_PKT:
17762306a36Sopenharmony_ci		chan = 5;	/* BCSP cmd/evt channel */
17862306a36Sopenharmony_ci		rel = 1;	/* reliable channel */
17962306a36Sopenharmony_ci		break;
18062306a36Sopenharmony_ci	case HCI_SCODATA_PKT:
18162306a36Sopenharmony_ci		chan = 7;	/* BCSP SCO channel */
18262306a36Sopenharmony_ci		rel = 0;	/* unreliable channel */
18362306a36Sopenharmony_ci		break;
18462306a36Sopenharmony_ci	case BCSP_LE_PKT:
18562306a36Sopenharmony_ci		chan = 1;	/* BCSP LE channel */
18662306a36Sopenharmony_ci		rel = 0;	/* unreliable channel */
18762306a36Sopenharmony_ci		break;
18862306a36Sopenharmony_ci	case BCSP_ACK_PKT:
18962306a36Sopenharmony_ci		chan = 0;	/* BCSP internal channel */
19062306a36Sopenharmony_ci		rel = 0;	/* unreliable channel */
19162306a36Sopenharmony_ci		break;
19262306a36Sopenharmony_ci	default:
19362306a36Sopenharmony_ci		BT_ERR("Unknown packet type");
19462306a36Sopenharmony_ci		return NULL;
19562306a36Sopenharmony_ci	}
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	if (hciextn && chan == 5) {
19862306a36Sopenharmony_ci		__le16 opcode = ((struct hci_command_hdr *)data)->opcode;
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci		/* Vendor specific commands */
20162306a36Sopenharmony_ci		if (hci_opcode_ogf(__le16_to_cpu(opcode)) == 0x3f) {
20262306a36Sopenharmony_ci			u8 desc = *(data + HCI_COMMAND_HDR_SIZE);
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci			if ((desc & 0xf0) == 0xc0) {
20562306a36Sopenharmony_ci				data += HCI_COMMAND_HDR_SIZE + 1;
20662306a36Sopenharmony_ci				len  -= HCI_COMMAND_HDR_SIZE + 1;
20762306a36Sopenharmony_ci				chan = desc & 0x0f;
20862306a36Sopenharmony_ci			}
20962306a36Sopenharmony_ci		}
21062306a36Sopenharmony_ci	}
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	/* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
21362306a36Sopenharmony_ci	 * (because bytes 0xc0 and 0xdb are escaped, worst case is
21462306a36Sopenharmony_ci	 * when the packet is all made of 0xc0 and 0xdb :) )
21562306a36Sopenharmony_ci	 * + 2 (0xc0 delimiters at start and end).
21662306a36Sopenharmony_ci	 */
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
21962306a36Sopenharmony_ci	if (!nskb)
22062306a36Sopenharmony_ci		return NULL;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	hci_skb_pkt_type(nskb) = pkt_type;
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	bcsp_slip_msgdelim(nskb);
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	hdr[0] = bcsp->rxseq_txack << 3;
22762306a36Sopenharmony_ci	bcsp->txack_req = 0;
22862306a36Sopenharmony_ci	BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	if (rel) {
23162306a36Sopenharmony_ci		hdr[0] |= 0x80 + bcsp->msgq_txseq;
23262306a36Sopenharmony_ci		BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
23362306a36Sopenharmony_ci		bcsp->msgq_txseq = (bcsp->msgq_txseq + 1) & 0x07;
23462306a36Sopenharmony_ci	}
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	if (bcsp->use_crc)
23762306a36Sopenharmony_ci		hdr[0] |= 0x40;
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	hdr[1] = ((len << 4) & 0xff) | chan;
24062306a36Sopenharmony_ci	hdr[2] = len >> 4;
24162306a36Sopenharmony_ci	hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	/* Put BCSP header */
24462306a36Sopenharmony_ci	for (i = 0; i < 4; i++) {
24562306a36Sopenharmony_ci		bcsp_slip_one_byte(nskb, hdr[i]);
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci		if (bcsp->use_crc)
24862306a36Sopenharmony_ci			bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
24962306a36Sopenharmony_ci	}
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	/* Put payload */
25262306a36Sopenharmony_ci	for (i = 0; i < len; i++) {
25362306a36Sopenharmony_ci		bcsp_slip_one_byte(nskb, data[i]);
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci		if (bcsp->use_crc)
25662306a36Sopenharmony_ci			bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
25762306a36Sopenharmony_ci	}
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	/* Put CRC */
26062306a36Sopenharmony_ci	if (bcsp->use_crc) {
26162306a36Sopenharmony_ci		bcsp_txmsg_crc = bitrev16(bcsp_txmsg_crc);
26262306a36Sopenharmony_ci		bcsp_slip_one_byte(nskb, (u8)((bcsp_txmsg_crc >> 8) & 0x00ff));
26362306a36Sopenharmony_ci		bcsp_slip_one_byte(nskb, (u8)(bcsp_txmsg_crc & 0x00ff));
26462306a36Sopenharmony_ci	}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	bcsp_slip_msgdelim(nskb);
26762306a36Sopenharmony_ci	return nskb;
26862306a36Sopenharmony_ci}
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci/* This is a rewrite of pkt_avail in ABCSP */
27162306a36Sopenharmony_cistatic struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
27262306a36Sopenharmony_ci{
27362306a36Sopenharmony_ci	struct bcsp_struct *bcsp = hu->priv;
27462306a36Sopenharmony_ci	unsigned long flags;
27562306a36Sopenharmony_ci	struct sk_buff *skb;
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci	/* First of all, check for unreliable messages in the queue,
27862306a36Sopenharmony_ci	 * since they have priority
27962306a36Sopenharmony_ci	 */
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	skb = skb_dequeue(&bcsp->unrel);
28262306a36Sopenharmony_ci	if (skb != NULL) {
28362306a36Sopenharmony_ci		struct sk_buff *nskb;
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci		nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len,
28662306a36Sopenharmony_ci					hci_skb_pkt_type(skb));
28762306a36Sopenharmony_ci		if (nskb) {
28862306a36Sopenharmony_ci			kfree_skb(skb);
28962306a36Sopenharmony_ci			return nskb;
29062306a36Sopenharmony_ci		} else {
29162306a36Sopenharmony_ci			skb_queue_head(&bcsp->unrel, skb);
29262306a36Sopenharmony_ci			BT_ERR("Could not dequeue pkt because alloc_skb failed");
29362306a36Sopenharmony_ci		}
29462306a36Sopenharmony_ci	}
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	/* Now, try to send a reliable pkt. We can only send a
29762306a36Sopenharmony_ci	 * reliable packet if the number of packets sent but not yet ack'ed
29862306a36Sopenharmony_ci	 * is < than the winsize
29962306a36Sopenharmony_ci	 */
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING);
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	if (bcsp->unack.qlen < BCSP_TXWINSIZE) {
30462306a36Sopenharmony_ci		skb = skb_dequeue(&bcsp->rel);
30562306a36Sopenharmony_ci		if (skb != NULL) {
30662306a36Sopenharmony_ci			struct sk_buff *nskb;
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci			nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len,
30962306a36Sopenharmony_ci						hci_skb_pkt_type(skb));
31062306a36Sopenharmony_ci			if (nskb) {
31162306a36Sopenharmony_ci				__skb_queue_tail(&bcsp->unack, skb);
31262306a36Sopenharmony_ci				mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
31362306a36Sopenharmony_ci				spin_unlock_irqrestore(&bcsp->unack.lock, flags);
31462306a36Sopenharmony_ci				return nskb;
31562306a36Sopenharmony_ci			} else {
31662306a36Sopenharmony_ci				skb_queue_head(&bcsp->rel, skb);
31762306a36Sopenharmony_ci				BT_ERR("Could not dequeue pkt because alloc_skb failed");
31862306a36Sopenharmony_ci			}
31962306a36Sopenharmony_ci		}
32062306a36Sopenharmony_ci	}
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	spin_unlock_irqrestore(&bcsp->unack.lock, flags);
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	/* We could not send a reliable packet, either because there are
32562306a36Sopenharmony_ci	 * none or because there are too many unack'ed pkts. Did we receive
32662306a36Sopenharmony_ci	 * any packets we have not acknowledged yet ?
32762306a36Sopenharmony_ci	 */
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	if (bcsp->txack_req) {
33062306a36Sopenharmony_ci		/* if so, craft an empty ACK pkt and send it on BCSP unreliable
33162306a36Sopenharmony_ci		 * channel 0
33262306a36Sopenharmony_ci		 */
33362306a36Sopenharmony_ci		struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
33462306a36Sopenharmony_ci		return nskb;
33562306a36Sopenharmony_ci	}
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	/* We have nothing to send */
33862306a36Sopenharmony_ci	return NULL;
33962306a36Sopenharmony_ci}
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_cistatic int bcsp_flush(struct hci_uart *hu)
34262306a36Sopenharmony_ci{
34362306a36Sopenharmony_ci	BT_DBG("hu %p", hu);
34462306a36Sopenharmony_ci	return 0;
34562306a36Sopenharmony_ci}
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci/* Remove ack'ed packets */
34862306a36Sopenharmony_cistatic void bcsp_pkt_cull(struct bcsp_struct *bcsp)
34962306a36Sopenharmony_ci{
35062306a36Sopenharmony_ci	struct sk_buff *skb, *tmp;
35162306a36Sopenharmony_ci	unsigned long flags;
35262306a36Sopenharmony_ci	int i, pkts_to_be_removed;
35362306a36Sopenharmony_ci	u8 seqno;
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	spin_lock_irqsave(&bcsp->unack.lock, flags);
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci	pkts_to_be_removed = skb_queue_len(&bcsp->unack);
35862306a36Sopenharmony_ci	seqno = bcsp->msgq_txseq;
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	while (pkts_to_be_removed) {
36162306a36Sopenharmony_ci		if (bcsp->rxack == seqno)
36262306a36Sopenharmony_ci			break;
36362306a36Sopenharmony_ci		pkts_to_be_removed--;
36462306a36Sopenharmony_ci		seqno = (seqno - 1) & 0x07;
36562306a36Sopenharmony_ci	}
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	if (bcsp->rxack != seqno)
36862306a36Sopenharmony_ci		BT_ERR("Peer acked invalid packet");
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	BT_DBG("Removing %u pkts out of %u, up to seqno %u",
37162306a36Sopenharmony_ci	       pkts_to_be_removed, skb_queue_len(&bcsp->unack),
37262306a36Sopenharmony_ci	       (seqno - 1) & 0x07);
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	i = 0;
37562306a36Sopenharmony_ci	skb_queue_walk_safe(&bcsp->unack, skb, tmp) {
37662306a36Sopenharmony_ci		if (i >= pkts_to_be_removed)
37762306a36Sopenharmony_ci			break;
37862306a36Sopenharmony_ci		i++;
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci		__skb_unlink(skb, &bcsp->unack);
38162306a36Sopenharmony_ci		dev_kfree_skb_irq(skb);
38262306a36Sopenharmony_ci	}
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci	if (skb_queue_empty(&bcsp->unack))
38562306a36Sopenharmony_ci		del_timer(&bcsp->tbcsp);
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	spin_unlock_irqrestore(&bcsp->unack.lock, flags);
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	if (i != pkts_to_be_removed)
39062306a36Sopenharmony_ci		BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
39162306a36Sopenharmony_ci}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci/* Handle BCSP link-establishment packets. When we
39462306a36Sopenharmony_ci * detect a "sync" packet, symptom that the BT module has reset,
39562306a36Sopenharmony_ci * we do nothing :) (yet)
39662306a36Sopenharmony_ci */
39762306a36Sopenharmony_cistatic void bcsp_handle_le_pkt(struct hci_uart *hu)
39862306a36Sopenharmony_ci{
39962306a36Sopenharmony_ci	struct bcsp_struct *bcsp = hu->priv;
40062306a36Sopenharmony_ci	u8 conf_pkt[4]     = { 0xad, 0xef, 0xac, 0xed };
40162306a36Sopenharmony_ci	u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
40262306a36Sopenharmony_ci	u8 sync_pkt[4]     = { 0xda, 0xdc, 0xed, 0xed };
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	/* spot "conf" pkts and reply with a "conf rsp" pkt */
40562306a36Sopenharmony_ci	if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
40662306a36Sopenharmony_ci	    !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
40762306a36Sopenharmony_ci		struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci		BT_DBG("Found a LE conf pkt");
41062306a36Sopenharmony_ci		if (!nskb)
41162306a36Sopenharmony_ci			return;
41262306a36Sopenharmony_ci		skb_put_data(nskb, conf_rsp_pkt, 4);
41362306a36Sopenharmony_ci		hci_skb_pkt_type(nskb) = BCSP_LE_PKT;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci		skb_queue_head(&bcsp->unrel, nskb);
41662306a36Sopenharmony_ci		hci_uart_tx_wakeup(hu);
41762306a36Sopenharmony_ci	}
41862306a36Sopenharmony_ci	/* Spot "sync" pkts. If we find one...disaster! */
41962306a36Sopenharmony_ci	else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
42062306a36Sopenharmony_ci		 !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
42162306a36Sopenharmony_ci		BT_ERR("Found a LE sync pkt, card has reset");
42262306a36Sopenharmony_ci	}
42362306a36Sopenharmony_ci}
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_cistatic inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
42662306a36Sopenharmony_ci{
42762306a36Sopenharmony_ci	const u8 c0 = 0xc0, db = 0xdb;
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_ci	switch (bcsp->rx_esc_state) {
43062306a36Sopenharmony_ci	case BCSP_ESCSTATE_NOESC:
43162306a36Sopenharmony_ci		switch (byte) {
43262306a36Sopenharmony_ci		case 0xdb:
43362306a36Sopenharmony_ci			bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
43462306a36Sopenharmony_ci			break;
43562306a36Sopenharmony_ci		default:
43662306a36Sopenharmony_ci			skb_put_data(bcsp->rx_skb, &byte, 1);
43762306a36Sopenharmony_ci			if ((bcsp->rx_skb->data[0] & 0x40) != 0 &&
43862306a36Sopenharmony_ci			    bcsp->rx_state != BCSP_W4_CRC)
43962306a36Sopenharmony_ci				bcsp_crc_update(&bcsp->message_crc, byte);
44062306a36Sopenharmony_ci			bcsp->rx_count--;
44162306a36Sopenharmony_ci		}
44262306a36Sopenharmony_ci		break;
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci	case BCSP_ESCSTATE_ESC:
44562306a36Sopenharmony_ci		switch (byte) {
44662306a36Sopenharmony_ci		case 0xdc:
44762306a36Sopenharmony_ci			skb_put_data(bcsp->rx_skb, &c0, 1);
44862306a36Sopenharmony_ci			if ((bcsp->rx_skb->data[0] & 0x40) != 0 &&
44962306a36Sopenharmony_ci			    bcsp->rx_state != BCSP_W4_CRC)
45062306a36Sopenharmony_ci				bcsp_crc_update(&bcsp->message_crc, 0xc0);
45162306a36Sopenharmony_ci			bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
45262306a36Sopenharmony_ci			bcsp->rx_count--;
45362306a36Sopenharmony_ci			break;
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci		case 0xdd:
45662306a36Sopenharmony_ci			skb_put_data(bcsp->rx_skb, &db, 1);
45762306a36Sopenharmony_ci			if ((bcsp->rx_skb->data[0] & 0x40) != 0 &&
45862306a36Sopenharmony_ci			    bcsp->rx_state != BCSP_W4_CRC)
45962306a36Sopenharmony_ci				bcsp_crc_update(&bcsp->message_crc, 0xdb);
46062306a36Sopenharmony_ci			bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
46162306a36Sopenharmony_ci			bcsp->rx_count--;
46262306a36Sopenharmony_ci			break;
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci		default:
46562306a36Sopenharmony_ci			BT_ERR("Invalid byte %02x after esc byte", byte);
46662306a36Sopenharmony_ci			kfree_skb(bcsp->rx_skb);
46762306a36Sopenharmony_ci			bcsp->rx_skb = NULL;
46862306a36Sopenharmony_ci			bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
46962306a36Sopenharmony_ci			bcsp->rx_count = 0;
47062306a36Sopenharmony_ci		}
47162306a36Sopenharmony_ci	}
47262306a36Sopenharmony_ci}
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_cistatic void bcsp_complete_rx_pkt(struct hci_uart *hu)
47562306a36Sopenharmony_ci{
47662306a36Sopenharmony_ci	struct bcsp_struct *bcsp = hu->priv;
47762306a36Sopenharmony_ci	int pass_up = 0;
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	if (bcsp->rx_skb->data[0] & 0x80) {	/* reliable pkt */
48062306a36Sopenharmony_ci		BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci		/* check the rx sequence number is as expected */
48362306a36Sopenharmony_ci		if ((bcsp->rx_skb->data[0] & 0x07) == bcsp->rxseq_txack) {
48462306a36Sopenharmony_ci			bcsp->rxseq_txack++;
48562306a36Sopenharmony_ci			bcsp->rxseq_txack %= 0x8;
48662306a36Sopenharmony_ci		} else {
48762306a36Sopenharmony_ci			/* handle re-transmitted packet or
48862306a36Sopenharmony_ci			 * when packet was missed
48962306a36Sopenharmony_ci			 */
49062306a36Sopenharmony_ci			BT_ERR("Out-of-order packet arrived, got %u expected %u",
49162306a36Sopenharmony_ci			       bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci			/* do not process out-of-order packet payload */
49462306a36Sopenharmony_ci			pass_up = 2;
49562306a36Sopenharmony_ci		}
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci		/* send current txack value to all received reliable packets */
49862306a36Sopenharmony_ci		bcsp->txack_req = 1;
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci		/* If needed, transmit an ack pkt */
50162306a36Sopenharmony_ci		hci_uart_tx_wakeup(hu);
50262306a36Sopenharmony_ci	}
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_ci	bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
50562306a36Sopenharmony_ci	BT_DBG("Request for pkt %u from card", bcsp->rxack);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	/* handle received ACK indications,
50862306a36Sopenharmony_ci	 * including those from out-of-order packets
50962306a36Sopenharmony_ci	 */
51062306a36Sopenharmony_ci	bcsp_pkt_cull(bcsp);
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci	if (pass_up != 2) {
51362306a36Sopenharmony_ci		if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
51462306a36Sopenharmony_ci		    (bcsp->rx_skb->data[0] & 0x80)) {
51562306a36Sopenharmony_ci			hci_skb_pkt_type(bcsp->rx_skb) = HCI_ACLDATA_PKT;
51662306a36Sopenharmony_ci			pass_up = 1;
51762306a36Sopenharmony_ci		} else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
51862306a36Sopenharmony_ci			   (bcsp->rx_skb->data[0] & 0x80)) {
51962306a36Sopenharmony_ci			hci_skb_pkt_type(bcsp->rx_skb) = HCI_EVENT_PKT;
52062306a36Sopenharmony_ci			pass_up = 1;
52162306a36Sopenharmony_ci		} else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
52262306a36Sopenharmony_ci			hci_skb_pkt_type(bcsp->rx_skb) = HCI_SCODATA_PKT;
52362306a36Sopenharmony_ci			pass_up = 1;
52462306a36Sopenharmony_ci		} else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
52562306a36Sopenharmony_ci			   !(bcsp->rx_skb->data[0] & 0x80)) {
52662306a36Sopenharmony_ci			bcsp_handle_le_pkt(hu);
52762306a36Sopenharmony_ci			pass_up = 0;
52862306a36Sopenharmony_ci		} else {
52962306a36Sopenharmony_ci			pass_up = 0;
53062306a36Sopenharmony_ci		}
53162306a36Sopenharmony_ci	}
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	if (pass_up == 0) {
53462306a36Sopenharmony_ci		struct hci_event_hdr hdr;
53562306a36Sopenharmony_ci		u8 desc = (bcsp->rx_skb->data[1] & 0x0f);
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci		if (desc != 0 && desc != 1) {
53862306a36Sopenharmony_ci			if (hciextn) {
53962306a36Sopenharmony_ci				desc |= 0xc0;
54062306a36Sopenharmony_ci				skb_pull(bcsp->rx_skb, 4);
54162306a36Sopenharmony_ci				memcpy(skb_push(bcsp->rx_skb, 1), &desc, 1);
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_ci				hdr.evt = 0xff;
54462306a36Sopenharmony_ci				hdr.plen = bcsp->rx_skb->len;
54562306a36Sopenharmony_ci				memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE);
54662306a36Sopenharmony_ci				hci_skb_pkt_type(bcsp->rx_skb) = HCI_EVENT_PKT;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci				hci_recv_frame(hu->hdev, bcsp->rx_skb);
54962306a36Sopenharmony_ci			} else {
55062306a36Sopenharmony_ci				BT_ERR("Packet for unknown channel (%u %s)",
55162306a36Sopenharmony_ci				       bcsp->rx_skb->data[1] & 0x0f,
55262306a36Sopenharmony_ci				       bcsp->rx_skb->data[0] & 0x80 ?
55362306a36Sopenharmony_ci				       "reliable" : "unreliable");
55462306a36Sopenharmony_ci				kfree_skb(bcsp->rx_skb);
55562306a36Sopenharmony_ci			}
55662306a36Sopenharmony_ci		} else
55762306a36Sopenharmony_ci			kfree_skb(bcsp->rx_skb);
55862306a36Sopenharmony_ci	} else if (pass_up == 1) {
55962306a36Sopenharmony_ci		/* Pull out BCSP hdr */
56062306a36Sopenharmony_ci		skb_pull(bcsp->rx_skb, 4);
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci		hci_recv_frame(hu->hdev, bcsp->rx_skb);
56362306a36Sopenharmony_ci	} else {
56462306a36Sopenharmony_ci		/* ignore packet payload of already ACKed re-transmitted
56562306a36Sopenharmony_ci		 * packets or when a packet was missed in the BCSP window
56662306a36Sopenharmony_ci		 */
56762306a36Sopenharmony_ci		kfree_skb(bcsp->rx_skb);
56862306a36Sopenharmony_ci	}
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_ci	bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
57162306a36Sopenharmony_ci	bcsp->rx_skb = NULL;
57262306a36Sopenharmony_ci}
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_cistatic u16 bscp_get_crc(struct bcsp_struct *bcsp)
57562306a36Sopenharmony_ci{
57662306a36Sopenharmony_ci	return get_unaligned_be16(&bcsp->rx_skb->data[bcsp->rx_skb->len - 2]);
57762306a36Sopenharmony_ci}
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci/* Recv data */
58062306a36Sopenharmony_cistatic int bcsp_recv(struct hci_uart *hu, const void *data, int count)
58162306a36Sopenharmony_ci{
58262306a36Sopenharmony_ci	struct bcsp_struct *bcsp = hu->priv;
58362306a36Sopenharmony_ci	const unsigned char *ptr;
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	BT_DBG("hu %p count %d rx_state %d rx_count %ld",
58662306a36Sopenharmony_ci	       hu, count, bcsp->rx_state, bcsp->rx_count);
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	ptr = data;
58962306a36Sopenharmony_ci	while (count) {
59062306a36Sopenharmony_ci		if (bcsp->rx_count) {
59162306a36Sopenharmony_ci			if (*ptr == 0xc0) {
59262306a36Sopenharmony_ci				BT_ERR("Short BCSP packet");
59362306a36Sopenharmony_ci				kfree_skb(bcsp->rx_skb);
59462306a36Sopenharmony_ci				bcsp->rx_skb = NULL;
59562306a36Sopenharmony_ci				bcsp->rx_state = BCSP_W4_PKT_START;
59662306a36Sopenharmony_ci				bcsp->rx_count = 0;
59762306a36Sopenharmony_ci			} else
59862306a36Sopenharmony_ci				bcsp_unslip_one_byte(bcsp, *ptr);
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_ci			ptr++; count--;
60162306a36Sopenharmony_ci			continue;
60262306a36Sopenharmony_ci		}
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci		switch (bcsp->rx_state) {
60562306a36Sopenharmony_ci		case BCSP_W4_BCSP_HDR:
60662306a36Sopenharmony_ci			if ((0xff & (u8)~(bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
60762306a36Sopenharmony_ci			    bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
60862306a36Sopenharmony_ci				BT_ERR("Error in BCSP hdr checksum");
60962306a36Sopenharmony_ci				kfree_skb(bcsp->rx_skb);
61062306a36Sopenharmony_ci				bcsp->rx_skb = NULL;
61162306a36Sopenharmony_ci				bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
61262306a36Sopenharmony_ci				bcsp->rx_count = 0;
61362306a36Sopenharmony_ci				continue;
61462306a36Sopenharmony_ci			}
61562306a36Sopenharmony_ci			bcsp->rx_state = BCSP_W4_DATA;
61662306a36Sopenharmony_ci			bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
61762306a36Sopenharmony_ci					(bcsp->rx_skb->data[2] << 4);	/* May be 0 */
61862306a36Sopenharmony_ci			continue;
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci		case BCSP_W4_DATA:
62162306a36Sopenharmony_ci			if (bcsp->rx_skb->data[0] & 0x40) {	/* pkt with crc */
62262306a36Sopenharmony_ci				bcsp->rx_state = BCSP_W4_CRC;
62362306a36Sopenharmony_ci				bcsp->rx_count = 2;
62462306a36Sopenharmony_ci			} else
62562306a36Sopenharmony_ci				bcsp_complete_rx_pkt(hu);
62662306a36Sopenharmony_ci			continue;
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci		case BCSP_W4_CRC:
62962306a36Sopenharmony_ci			if (bitrev16(bcsp->message_crc) != bscp_get_crc(bcsp)) {
63062306a36Sopenharmony_ci				BT_ERR("Checksum failed: computed %04x received %04x",
63162306a36Sopenharmony_ci				       bitrev16(bcsp->message_crc),
63262306a36Sopenharmony_ci				       bscp_get_crc(bcsp));
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci				kfree_skb(bcsp->rx_skb);
63562306a36Sopenharmony_ci				bcsp->rx_skb = NULL;
63662306a36Sopenharmony_ci				bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
63762306a36Sopenharmony_ci				bcsp->rx_count = 0;
63862306a36Sopenharmony_ci				continue;
63962306a36Sopenharmony_ci			}
64062306a36Sopenharmony_ci			skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
64162306a36Sopenharmony_ci			bcsp_complete_rx_pkt(hu);
64262306a36Sopenharmony_ci			continue;
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci		case BCSP_W4_PKT_DELIMITER:
64562306a36Sopenharmony_ci			switch (*ptr) {
64662306a36Sopenharmony_ci			case 0xc0:
64762306a36Sopenharmony_ci				bcsp->rx_state = BCSP_W4_PKT_START;
64862306a36Sopenharmony_ci				break;
64962306a36Sopenharmony_ci			default:
65062306a36Sopenharmony_ci				/*BT_ERR("Ignoring byte %02x", *ptr);*/
65162306a36Sopenharmony_ci				break;
65262306a36Sopenharmony_ci			}
65362306a36Sopenharmony_ci			ptr++; count--;
65462306a36Sopenharmony_ci			break;
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci		case BCSP_W4_PKT_START:
65762306a36Sopenharmony_ci			switch (*ptr) {
65862306a36Sopenharmony_ci			case 0xc0:
65962306a36Sopenharmony_ci				ptr++; count--;
66062306a36Sopenharmony_ci				break;
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ci			default:
66362306a36Sopenharmony_ci				bcsp->rx_state = BCSP_W4_BCSP_HDR;
66462306a36Sopenharmony_ci				bcsp->rx_count = 4;
66562306a36Sopenharmony_ci				bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
66662306a36Sopenharmony_ci				BCSP_CRC_INIT(bcsp->message_crc);
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci				/* Do not increment ptr or decrement count
66962306a36Sopenharmony_ci				 * Allocate packet. Max len of a BCSP pkt=
67062306a36Sopenharmony_ci				 * 0xFFF (payload) +4 (header) +2 (crc)
67162306a36Sopenharmony_ci				 */
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ci				bcsp->rx_skb = bt_skb_alloc(0x1005, GFP_ATOMIC);
67462306a36Sopenharmony_ci				if (!bcsp->rx_skb) {
67562306a36Sopenharmony_ci					BT_ERR("Can't allocate mem for new packet");
67662306a36Sopenharmony_ci					bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
67762306a36Sopenharmony_ci					bcsp->rx_count = 0;
67862306a36Sopenharmony_ci					return 0;
67962306a36Sopenharmony_ci				}
68062306a36Sopenharmony_ci				break;
68162306a36Sopenharmony_ci			}
68262306a36Sopenharmony_ci			break;
68362306a36Sopenharmony_ci		}
68462306a36Sopenharmony_ci	}
68562306a36Sopenharmony_ci	return count;
68662306a36Sopenharmony_ci}
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci	/* Arrange to retransmit all messages in the relq. */
68962306a36Sopenharmony_cistatic void bcsp_timed_event(struct timer_list *t)
69062306a36Sopenharmony_ci{
69162306a36Sopenharmony_ci	struct bcsp_struct *bcsp = from_timer(bcsp, t, tbcsp);
69262306a36Sopenharmony_ci	struct hci_uart *hu = bcsp->hu;
69362306a36Sopenharmony_ci	struct sk_buff *skb;
69462306a36Sopenharmony_ci	unsigned long flags;
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci	BT_DBG("hu %p retransmitting %u pkts", hu, bcsp->unack.qlen);
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci	spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING);
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
70162306a36Sopenharmony_ci		bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
70262306a36Sopenharmony_ci		skb_queue_head(&bcsp->rel, skb);
70362306a36Sopenharmony_ci	}
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci	spin_unlock_irqrestore(&bcsp->unack.lock, flags);
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci	hci_uart_tx_wakeup(hu);
70862306a36Sopenharmony_ci}
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_cistatic int bcsp_open(struct hci_uart *hu)
71162306a36Sopenharmony_ci{
71262306a36Sopenharmony_ci	struct bcsp_struct *bcsp;
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci	BT_DBG("hu %p", hu);
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	bcsp = kzalloc(sizeof(*bcsp), GFP_KERNEL);
71762306a36Sopenharmony_ci	if (!bcsp)
71862306a36Sopenharmony_ci		return -ENOMEM;
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	hu->priv = bcsp;
72162306a36Sopenharmony_ci	bcsp->hu = hu;
72262306a36Sopenharmony_ci	skb_queue_head_init(&bcsp->unack);
72362306a36Sopenharmony_ci	skb_queue_head_init(&bcsp->rel);
72462306a36Sopenharmony_ci	skb_queue_head_init(&bcsp->unrel);
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_ci	timer_setup(&bcsp->tbcsp, bcsp_timed_event, 0);
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	if (txcrc)
73162306a36Sopenharmony_ci		bcsp->use_crc = 1;
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	return 0;
73462306a36Sopenharmony_ci}
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_cistatic int bcsp_close(struct hci_uart *hu)
73762306a36Sopenharmony_ci{
73862306a36Sopenharmony_ci	struct bcsp_struct *bcsp = hu->priv;
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci	timer_shutdown_sync(&bcsp->tbcsp);
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci	hu->priv = NULL;
74362306a36Sopenharmony_ci
74462306a36Sopenharmony_ci	BT_DBG("hu %p", hu);
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci	skb_queue_purge(&bcsp->unack);
74762306a36Sopenharmony_ci	skb_queue_purge(&bcsp->rel);
74862306a36Sopenharmony_ci	skb_queue_purge(&bcsp->unrel);
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci	if (bcsp->rx_skb) {
75162306a36Sopenharmony_ci		kfree_skb(bcsp->rx_skb);
75262306a36Sopenharmony_ci		bcsp->rx_skb = NULL;
75362306a36Sopenharmony_ci	}
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_ci	kfree(bcsp);
75662306a36Sopenharmony_ci	return 0;
75762306a36Sopenharmony_ci}
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_cistatic const struct hci_uart_proto bcsp = {
76062306a36Sopenharmony_ci	.id		= HCI_UART_BCSP,
76162306a36Sopenharmony_ci	.name		= "BCSP",
76262306a36Sopenharmony_ci	.open		= bcsp_open,
76362306a36Sopenharmony_ci	.close		= bcsp_close,
76462306a36Sopenharmony_ci	.enqueue	= bcsp_enqueue,
76562306a36Sopenharmony_ci	.dequeue	= bcsp_dequeue,
76662306a36Sopenharmony_ci	.recv		= bcsp_recv,
76762306a36Sopenharmony_ci	.flush		= bcsp_flush
76862306a36Sopenharmony_ci};
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ciint __init bcsp_init(void)
77162306a36Sopenharmony_ci{
77262306a36Sopenharmony_ci	return hci_uart_register_proto(&bcsp);
77362306a36Sopenharmony_ci}
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ciint __exit bcsp_deinit(void)
77662306a36Sopenharmony_ci{
77762306a36Sopenharmony_ci	return hci_uart_unregister_proto(&bcsp);
77862306a36Sopenharmony_ci}
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_cimodule_param(txcrc, bool, 0644);
78162306a36Sopenharmony_ciMODULE_PARM_DESC(txcrc, "Transmit CRC with every BCSP packet");
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_cimodule_param(hciextn, bool, 0644);
78462306a36Sopenharmony_ciMODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets");
785