^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Generic Bluetooth HCI UART driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2015-2018 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) struct h4_recv_pkt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) u8 type; /* Packet type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) u8 hlen; /* Header length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) u8 loff; /* Data length offset in header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) u8 lsize; /* Data length field size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) u16 maxlen; /* Max overall packet length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) int (*recv)(struct hci_dev *hdev, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define H4_RECV_ACL \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) .type = HCI_ACLDATA_PKT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) .hlen = HCI_ACL_HDR_SIZE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) .loff = 2, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) .lsize = 2, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) .maxlen = HCI_MAX_FRAME_SIZE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define H4_RECV_SCO \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .type = HCI_SCODATA_PKT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .hlen = HCI_SCO_HDR_SIZE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .loff = 2, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .lsize = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) .maxlen = HCI_MAX_SCO_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define H4_RECV_EVENT \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .type = HCI_EVENT_PKT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .hlen = HCI_EVENT_HDR_SIZE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .loff = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .lsize = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .maxlen = HCI_MAX_EVENT_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static inline struct sk_buff *h4_recv_buf(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) const unsigned char *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) const struct h4_recv_pkt *pkts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int pkts_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* Check for error from previous call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (IS_ERR(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) while (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) for (i = 0; i < pkts_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (buffer[0] != (&pkts[i])->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) skb = bt_skb_alloc((&pkts[i])->maxlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) hci_skb_pkt_type(skb) = (&pkts[i])->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) hci_skb_expect(skb) = (&pkts[i])->hlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Check for invalid packet type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return ERR_PTR(-EILSEQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) count -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) buffer += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) len = min_t(uint, hci_skb_expect(skb) - skb->len, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) skb_put_data(skb, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) count -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) buffer += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Check for partial packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (skb->len < hci_skb_expect(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) for (i = 0; i < pkts_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (hci_skb_pkt_type(skb) == (&pkts[i])->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (i >= pkts_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return ERR_PTR(-EILSEQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (skb->len == (&pkts[i])->hlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) u16 dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) switch ((&pkts[i])->lsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* No variable data length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) dlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Single octet variable length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) dlen = skb->data[(&pkts[i])->loff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) hci_skb_expect(skb) += dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (skb_tailroom(skb) < dlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return ERR_PTR(-EMSGSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* Double octet variable length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) dlen = get_unaligned_le16(skb->data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) (&pkts[i])->loff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) hci_skb_expect(skb) += dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (skb_tailroom(skb) < dlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return ERR_PTR(-EMSGSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* Unsupported variable length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return ERR_PTR(-EILSEQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (!dlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* No more data, complete frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) (&pkts[i])->recv(hdev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* Complete frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) (&pkts[i])->recv(hdev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }