Bluetooth: hci_uart: add support for word alignment
authorSebastian Reichel <sre@kernel.org>
Tue, 28 Mar 2017 15:59:34 +0000 (17:59 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 12 Apr 2017 20:12:17 +0000 (22:12 +0200)
This will be used by Nokia's H4+ protocol, which
uses 2-byte aligned packets.

Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
drivers/bluetooth/hci_h4.c
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_uart.h

index 635597b6e1681f25e8ed6004c6960369dcae3e1b..82e5a32b87a43646cf49721e0f39a1671d498897 100644 (file)
@@ -171,9 +171,20 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
                            const unsigned char *buffer, int count,
                            const struct h4_recv_pkt *pkts, int pkts_count)
 {
+       struct hci_uart *hu = hci_get_drvdata(hdev);
+       u8 alignment = hu->alignment;
+
        while (count) {
                int i, len;
 
+               /* remove padding bytes from buffer */
+               for (; hu->padding && count > 0; hu->padding--) {
+                       count--;
+                       buffer++;
+               }
+               if (!count)
+                       break;
+
                if (!skb) {
                        for (i = 0; i < pkts_count; i++) {
                                if (buffer[0] != (&pkts[i])->type)
@@ -253,11 +264,17 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
                        }
 
                        if (!dlen) {
+                               hu->padding = (skb->len - 1) % alignment;
+                               hu->padding = (alignment - hu->padding) % alignment;
+
                                /* No more data, complete frame */
                                (&pkts[i])->recv(hdev, skb);
                                skb = NULL;
                        }
                } else {
+                       hu->padding = (skb->len - 1) % alignment;
+                       hu->padding = (alignment - hu->padding) % alignment;
+
                        /* Complete frame */
                        (&pkts[i])->recv(hdev, skb);
                        skb = NULL;
index 9497c469efd225cddd8cb53214d18c7310a14539..0ec8a94bd712f2444a9ee82224a40c6e639228de 100644 (file)
@@ -459,6 +459,10 @@ static int hci_uart_tty_open(struct tty_struct *tty)
        hu->tty = tty;
        tty->receive_room = 65536;
 
+       /* disable alignment support by default */
+       hu->alignment = 1;
+       hu->padding = 0;
+
        INIT_WORK(&hu->init_ready, hci_uart_init_work);
        INIT_WORK(&hu->write_work, hci_uart_write_work);
 
index 070139513e651792c8058f5665227cf1b54bd499..4aff50960cac1111d0722e689843472a84c399b9 100644 (file)
@@ -92,6 +92,9 @@ struct hci_uart {
 
        unsigned int init_speed;
        unsigned int oper_speed;
+
+       u8                      alignment;
+       u8                      padding;
 };
 
 /* HCI_UART proto flag bits */