wifi: update bcm driver to 101.10.240 to support android r [1/2]
[GitHub/LineageOS/G12/android_hardware_amlogic_kernel-modules_dhd-driver.git] / bcmdhd.101.10.240.x / include / bcmproto.h
diff --git a/bcmdhd.101.10.240.x/include/bcmproto.h b/bcmdhd.101.10.240.x/include/bcmproto.h
new file mode 100644 (file)
index 0000000..c1a33ba
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Fundamental constants relating to IP Protocol
+ *
+ * Copyright (C) 2020, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+#ifndef _bcmproto_h_
+#define _bcmproto_h_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+#include "eapol.h"
+#include "802.3.h"
+#include "vlan.h"
+#include "bcmtcp.h"
+/* copy from igsc.h */
+#define IGMP_HLEN                      8
+
+enum frame_l2_hdr {
+FRAME_L2_SNAP_H = 1,
+FRAME_L2_SNAPVLAN_H,
+FRAME_L2_ETH_H,
+FRAME_L2_ETHVLAN_H,
+FRAME_L2_ERROR,
+};
+
+enum frame_l3_hdr {
+FRAME_L3_IP_H = 4,
+FRAME_L3_IP6_H = 6,
+FRAME_L3_ARP_H,
+FRAME_L3_8021X_EAPOLKEY_H,
+FRAME_L3_ERROR,
+};
+
+enum frame_l4_hdr {
+FRAME_L4_ICMP_H = 1,
+FRAME_L4_IGMP_H = 2,
+FRAME_L4_TCP_H = 6,
+FRAME_L4_UDP_H = 17,
+FRAME_L4_ICMP6_H = 58,
+FRAME_L4_ERROR,
+};
+
+typedef struct {
+       uint8 *l2;
+       uint8 l2_t;
+       uint16 l2_len;
+       uint8 *l3;
+       uint8 l3_t;
+       uint16 l3_len;
+       uint8 *l4;
+       uint8 l4_t;
+       uint16 l4_len;
+} frame_proto_t;
+
+static const uint8 llc_snap_hdr[SNAP_HDR_LEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+
+/* Generic header parser function */
+static INLINE int
+hnd_frame_proto(uint8 *p, int plen, frame_proto_t *fp)
+{
+       struct dot3_mac_llc_snap_header *sh = (struct dot3_mac_llc_snap_header *)p;
+       struct dot3_mac_llc_snapvlan_header *svh = (struct dot3_mac_llc_snapvlan_header *)p;
+       struct ether_header *eh = (struct ether_header *)p;
+       struct ethervlan_header *evh = (struct ethervlan_header *)p;
+       uint16 type;
+       uint16 len;
+
+       if (p == NULL || plen <= 0)
+               return BCME_ERROR;
+
+       type  = ntoh16(eh->ether_type);
+
+       bzero(fp, sizeof(frame_proto_t));
+
+       /* L2 header/pointer check */
+       fp->l2 = p;
+       fp->l2_len = (uint16)plen;
+       if (type < ETHER_TYPE_MIN) {
+               if (bcmp(&sh->dsap, llc_snap_hdr, SNAP_HDR_LEN) == 0) {
+                       type = ntoh16(sh->type);
+                       if (type == ETHER_TYPE_8021Q) {
+                               fp->l2_t = FRAME_L2_SNAPVLAN_H;
+                               p += sizeof(struct dot3_mac_llc_snap_header);
+                               if ((plen -= sizeof(struct dot3_mac_llc_snap_header)) <= 0)
+                                       return BCME_ERROR;
+                       }
+                       else {
+                               fp->l2_t = FRAME_L2_SNAP_H;
+                               type = ntoh16(svh->ether_type);
+                               p += sizeof(struct dot3_mac_llc_snapvlan_header);
+                               if ((plen -= sizeof(struct dot3_mac_llc_snapvlan_header)) <= 0)
+                                       return BCME_ERROR;
+                       }
+               }
+               else
+                       return BCME_ERROR;
+       }
+       else {
+               if (type == ETHER_TYPE_8021Q) {
+                       fp->l2_t = FRAME_L2_ETHVLAN_H;
+                       type = ntoh16(evh->ether_type);
+                       p += ETHERVLAN_HDR_LEN;
+                       if ((plen -= ETHERVLAN_HDR_LEN) <= 0)
+                               return BCME_ERROR;
+               }
+               else {
+                       fp->l2_t = FRAME_L2_ETH_H;
+                       p += ETHER_HDR_LEN;
+                       if ((plen -= ETHER_HDR_LEN) <= 0)
+                               return BCME_ERROR;
+               }
+       }
+       /* L3 header/pointer check */
+       fp->l3 = p;
+       fp->l3_len = (uint16)plen;
+       switch (type) {
+       case ETHER_TYPE_ARP: {
+               if ((plen -= ARP_DATA_LEN) < 0)
+                       return BCME_ERROR;
+
+               fp->l3_t = FRAME_L3_ARP_H;
+               /* no layer 4 protocol, return */
+               return BCME_OK;
+               break;
+       }
+       case ETHER_TYPE_IP: {
+               struct ipv4_hdr *iph = (struct ipv4_hdr *)p;
+               len = IPV4_HLEN(iph);
+
+               if ((plen -= len) <= 0)
+                       return BCME_ERROR;
+
+               if (IP_VER(iph) == IP_VER_4 && len >= IPV4_MIN_HEADER_LEN) {
+                       fp->l3_t = FRAME_L3_IP_H;
+                       type = IPV4_PROT(iph);
+                       p += len;
+               }
+               else /* not a valid ipv4 packet */
+                       return BCME_ERROR;
+               break;
+       }
+       case ETHER_TYPE_IPV6: {
+               struct ipv6_hdr *ip6h = (struct ipv6_hdr *)p;
+
+               if ((plen -= IPV6_MIN_HLEN) <= 0)
+                       return BCME_ERROR;
+
+               if (IP_VER(ip6h) == IP_VER_6) {
+                       fp->l3_t = FRAME_L3_IP6_H;
+                       type = IPV6_PROT(ip6h);
+                       p += IPV6_MIN_HLEN;
+                       if (IPV6_EXTHDR(type)) {
+                               uint8 proto = 0;
+                               int32 exth_len = ipv6_exthdr_len(p, &proto);
+                               if (exth_len < 0 || ((plen -= exth_len) <= 0))
+                                       return BCME_ERROR;
+                               type = proto;
+                               p += exth_len;
+                       }
+               }
+               else /* not a valid ipv6 packet */
+                       return BCME_ERROR;
+               break;
+       }
+       case ETHER_TYPE_802_1X: {
+               eapol_hdr_t *eapolh = (eapol_hdr_t *)p;
+
+               if ((plen -= EAPOL_HDR_LEN) <= 0)
+                       return BCME_ERROR;
+
+               if (eapolh->type == EAPOL_KEY) {
+                       fp->l3_t = FRAME_L3_8021X_EAPOLKEY_H;
+                       return BCME_OK;
+               }
+               else /* not a valid ipv6 packet */
+                       return BCME_ERROR;
+
+               break;
+       }
+       default:
+               /* not interesting case */
+               return BCME_ERROR;
+               break;
+       }
+
+       /* L4 header/pointer check */
+       fp->l4 = p;
+       fp->l4_len = (uint16)plen;
+       switch (type) {
+       case IP_PROT_ICMP:
+               fp->l4_t = FRAME_L4_ICMP_H;
+               if ((plen -= sizeof(struct bcmicmp_hdr)) < 0)
+                       return BCME_ERROR;
+               break;
+       case IP_PROT_IGMP:
+               fp->l4_t = FRAME_L4_IGMP_H;
+               if ((plen -= IGMP_HLEN) < 0)
+                       return BCME_ERROR;
+               break;
+       case IP_PROT_TCP:
+               fp->l4_t = FRAME_L4_TCP_H;
+               if ((plen -= sizeof(struct bcmtcp_hdr)) < 0)
+                       return BCME_ERROR;
+               break;
+       case IP_PROT_UDP:
+               fp->l4_t = FRAME_L4_UDP_H;
+               if ((plen -= sizeof(struct bcmudp_hdr)) < 0)
+                       return BCME_ERROR;
+               break;
+       case IP_PROT_ICMP6:
+               fp->l4_t = FRAME_L4_ICMP6_H;
+               if ((plen -= sizeof(struct icmp6_hdr)) < 0)
+                       return BCME_ERROR;
+               break;
+       default:
+               break;
+       }
+
+       return BCME_OK;
+}
+
+#define SNAP_HDR_LEN   6       /* 802.3 LLC/SNAP header length */
+
+#define FRAME_DROP 0
+#define FRAME_NOP 1
+#define FRAME_TAKEN 2
+
+#endif /* _bcmproto_h_ */