Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }