/*
 * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/* #ifndef _NET_IF_ETHERSUBR_H_ */
/* #define _NET_IF_ETHERSUBR_H_ */
#ifndef _NET_IF_UPPERPROTO_H_
#define _NET_IF_UPPERPROTO_H_

#define ETHER_ADDR_LEN    6     /* length of an Ethernet address */
#define ETHER_TYPE_LEN    2     /* length of the Ethernet type field */
#define ETHER_CRC_LEN     4     /* length of the Ethernet CRC */
#define ETHER_HDR_LEN     (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN)
#define ETHER_MAX_LEN     1518

#define ETHERMTU          (ETHER_MAX_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)

/*
 * Structure of a 10Mb/s Ethernet header.
 */
#ifndef _NET_ETHERNET_H_
struct ether_header {
	uint8_t ether_dhost[ETHER_ADDR_LEN];
	uint8_t ether_shost[ETHER_ADDR_LEN];
	uint16_t ether_type;
} __packed;
#endif

#ifndef ETHERTYPE_PAE
#define ETHERTYPE_PAE    0x888e /* EAPOL PAE/802.1x */
#endif
#ifndef ETHERTYPE_IP
#define ETHERTYPE_IP     0x0800 /* IP protocol */
#endif
#ifndef ETHERTYPE_AARP
#define ETHERTYPE_AARP  0x80f3  /* Appletalk AARP protocol */
#endif
#ifndef ETHERTYPE_IPX
#define ETHERTYPE_IPX    0x8137 /* IPX over DIX protocol */
#endif
#ifndef ETHERTYPE_ARP
#define ETHERTYPE_ARP    0x0806 /* ARP protocol */
#endif
#ifndef ETHERTYPE_IPV6
#define ETHERTYPE_IPV6   0x86dd /* IPv6 */
#endif
#ifndef ETHERTYPE_8021Q
#define ETHERTYPE_8021Q 0x8100  /* 802.1Q vlan protocol */
#endif
#ifndef ETHERTYPE_VLAN
#define ETHERTYPE_VLAN  0x8100  /* VLAN TAG protocol */
#endif
#ifndef TX_QUEUE_FOR_EAPOL_FRAME
#define TX_QUEUE_FOR_EAPOL_FRAME  0x7   /* queue eapol frame to queue 7 to avoid aggregation disorder */
#endif

/*
 * define WAI ethertype
 */
#ifndef ETHERTYPE_WAI
#define ETHERTYPE_WAI    0x88b4 /* WAI/WAPI */
#endif

#define ETHERTYPE_OCB_TX   0x8151
#define ETHERTYPE_OCB_RX   0x8152

/*
 * Structure of a 48-bit Ethernet address.
 */
#if 0
#ifndef _NET_ETHERNET_H_
struct ether_addr {
	uint8_t octet[ETHER_ADDR_LEN];
} __packed;
#endif
#endif

#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01)       /* is address mcast/bcast? */

#define VLAN_PRI_SHIFT  13      /* Shift to find VLAN user priority */
#define VLAN_PRI_MASK    7      /* Mask for user priority bits in VLAN */

/*
 * Structure of the IP frame
 */
struct ip_header {
	uint8_t version_ihl;
	uint8_t tos;
	uint16_t tot_len;
	uint16_t id;
	uint16_t frag_off;
	uint8_t ttl;
	uint8_t protocol;
	uint16_t check;
	uint32_t saddr;
	uint32_t daddr;
	/*The options start here. */
};
#ifndef IP_PROTO_TCP
#define IP_PROTO_TCP    0x6     /* TCP protocol */
#endif
#ifndef IP_PROTO_UDP
#define IP_PROTO_UDP 17
#endif

/*
 *   IGMP protocol structures
 */

/* IGMP record type */
#define IGMP_QUERY_TYPE       0x11
#define IGMPV1_REPORT_TYPE    0x12
#define IGMPV2_REPORT_TYPE    0x16
#define IGMPV2_LEAVE_TYPE     0x17
#define IGMPV3_REPORT_TYPE    0x22

/* Is packet type is either leave or report */
#define IS_IGMP_REPORT_LEAVE_PACKET(type) ( \
		(IGMPV1_REPORT_TYPE == type) \
		|| (IGMPV2_REPORT_TYPE == type)	\
		|| (IGMPV2_LEAVE_TYPE  == type)	\
		|| (IGMPV3_REPORT_TYPE == type)	\
		)
/*
 *    Header in on cable format
 */

struct igmp_header {
	uint8_t type;
	uint8_t code;           /* For newer IGMP */
	uint16_t csum;
	uint32_t group;
};

/* V3 group record types [grec_type] */
#define IGMPV3_MODE_IS_INCLUDE        1
#define IGMPV3_MODE_IS_EXCLUDE        2
#define IGMPV3_CHANGE_TO_INCLUDE      3
#define IGMPV3_CHANGE_TO_EXCLUDE      4
#define IGMPV3_ALLOW_NEW_SOURCES      5
#define IGMPV3_BLOCK_OLD_SOURCES      6

/*  Group record format
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |  Record Type  |  Aux Data Len |     Number of Sources (N)     |
 ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                       Multicast Address                       |
 ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                       Source Address [1]                      |
 ||+-                                                             -+
 |                       Source Address [2]                      |
 ||+-                                                             -+
      .                               .                               .
      .                               .                               .
      .                               .                               .
 ||+-                                                             -+
 |                       Source Address [N]                      |
 ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
      .                                                               .
      .                         Auxiliary Data                        .
      .                                                               .
 |                                                               |
 ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */
struct igmp_v3_grec {
	uint8_t grec_type;
	uint8_t grec_auxwords;
	uint16_t grec_nsrcs;
	uint32_t grec_mca;
};

/* IGMPv3 report format
       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |  Type = 0x22  |    Reserved   |           Checksum            |
 ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |           Reserved            |  Number of Group Records (M)  |
 ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
      .                                                               .
      .                        Group Record [1]                       .
      .                                                               .
 |                                                               |
 ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
      .                                                               .
      .                        Group Record [2]                       .
      .                                                               .
 |                                                               |
 ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                               .                               |
      .                               .                               .
 |                               .                               |
 ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
      .                                                               .
      .                        Group Record [M]                       .
      .                                                               .
 |                                                               |
 ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */
struct igmp_v3_report {
	uint8_t type;
	uint8_t resv1;
	uint16_t csum;
	uint16_t resv2;
	uint16_t ngrec;
};

/* Calculate the group record length*/
#define IGMPV3_GRP_REC_LEN(x) (8 + (4 * x->grec_nsrcs) + (4 * x->grec_auxwords) )

#endif /* _NET_IF_ETHERSUBR_H_ */
