/** @file  uapevent.h
 *
 *  @brief Header file for uapevent application
 * 
 * Copyright (C) 2008-2009, Marvell International Ltd. 
 *
 * This software file (the "File") is distributed by Marvell International 
 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
 * (the "License").  You may use, redistribute and/or modify this File in 
 * accordance with the terms and conditions of the License, a copy of which 
 * is available along with the File in the gpl.txt file or by writing to 
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
 * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
 *
 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
 * this warranty disclaimer.
 *
 */
/************************************************************************
Change log:
    03/18/08: Initial creation
************************************************************************/

#ifndef _UAP_H
#define _UAP_H

#if (BYTE_ORDER == LITTLE_ENDIAN)
#undef BIG_ENDIAN
#endif

/** 16 bits byte swap */
#define swap_byte_16(x) \
  ((u16)((((u16)(x) & 0x00ffU) << 8) | \
         (((u16)(x) & 0xff00U) >> 8)))

/** 32 bits byte swap */
#define swap_byte_32(x) \
  ((u32)((((u32)(x) & 0x000000ffUL) << 24) | \
         (((u32)(x) & 0x0000ff00UL) <<  8) | \
         (((u32)(x) & 0x00ff0000UL) >>  8) | \
         (((u32)(x) & 0xff000000UL) >> 24)))

/** 64 bits byte swap */
#define swap_byte_64(x) \
  ((u64)((u64)(((u64)(x) & 0x00000000000000ffULL) << 56) | \
         (u64)(((u64)(x) & 0x000000000000ff00ULL) << 40) | \
         (u64)(((u64)(x) & 0x0000000000ff0000ULL) << 24) | \
         (u64)(((u64)(x) & 0x00000000ff000000ULL) <<  8) | \
         (u64)(((u64)(x) & 0x000000ff00000000ULL) >>  8) | \
         (u64)(((u64)(x) & 0x0000ff0000000000ULL) >> 24) | \
         (u64)(((u64)(x) & 0x00ff000000000000ULL) >> 40) | \
         (u64)(((u64)(x) & 0xff00000000000000ULL) >> 56) ))

#ifdef BIG_ENDIAN
/** Convert from 16 bit little endian format to CPU format */
#define uap_le16_to_cpu(x) swap_byte_16(x)
/** Convert from 32 bit little endian format to CPU format */
#define uap_le32_to_cpu(x) swap_byte_32(x)
/** Convert from 64 bit little endian format to CPU format */
#define uap_le64_to_cpu(x) swap_byte_64(x)
/** Convert to 16 bit little endian format from CPU format */
#define uap_cpu_to_le16(x) swap_byte_16(x)
/** Convert to 32 bit little endian format from CPU format */
#define uap_cpu_to_le32(x) swap_byte_32(x)
/** Convert to 64 bit little endian format from CPU format */
#define uap_cpu_to_le64(x) swap_byte_64(x)
#else /* BIG_ENDIAN */
/** Do nothing */
#define uap_le16_to_cpu(x) x
/** Do nothing */
#define uap_le32_to_cpu(x) x
/** Do nothing */
#define uap_le64_to_cpu(x) x
/** Do nothing */
#define uap_cpu_to_le16(x) x
/** Do nothing */
#define uap_cpu_to_le32(x) x
/** Do nothing */
#define uap_cpu_to_le64(x) x
#endif /* BIG_ENDIAN */

/** uAP application version string */
#define UAP_VERSION         "uAP 1.4"

/** Success */
#define UAP_SUCCESS     1
/** Failure */
#define UAP_FAILURE     -1

#ifdef __GNUC__
/** Structure packing begins */
#define PACK_START
/** Structure packeing end */
#define PACK_END  __attribute__ ((packed))
#else
/** Structure packing begins */
#define PACK_START   __packed
/** Structure packeing end */
#define PACK_END
#endif

#ifndef ETH_ALEN
/** MAC address length */
#define ETH_ALEN    6
#endif

/** Netlink protocol number */
#define NETLINK_MARVELL         (MAX_LINKS - 1)
/** Netlink maximum payload size */
#define NL_MAX_PAYLOAD          1024
/** Netlink multicast group number */
#define NL_MULTICAST_GROUP      1
/** Default wait time in seconds for events */
#define UAP_RECV_WAIT_DEFAULT   10

/** Character, 1 byte */
typedef char s8;
/** Unsigned character, 1 byte */
typedef unsigned char u8;

/** Short integer */
typedef signed short s16;
/** Unsigned short integer */
typedef unsigned short u16;

/** Long integer */
typedef signed long s32;
/** Unsigned long integer */
typedef unsigned long u32;

/** event ID mask */
#define EVENT_ID_MASK                   0x0fff

/** Event header */
typedef PACK_START struct _EVENTHEADER
{
    /** Event ID */
    u32 EventId;
    /** Event data */
    u8 EventData[0];
} PACK_END EVENTHEADER;

/** Event ID length */
#define EVENT_ID_LEN    4

/** Event ID: STA deauth */
#define MICRO_AP_EV_ID_STA_DEAUTH   44

/** Event ID: STA associated */
#define MICRO_AP_EV_ID_STA_ASSOC    45

/** Event ID: BSS started */
#define MICRO_AP_EV_ID_BSS_START    46

/** Event ID: Debug event */
#define MICRO_AP_EV_ID_DEBUG	     54

/** Event ID: BSS idle event */
#define MICRO_AP_EV_BSS_IDLE	     67

/** Event ID: BSS active event */
#define MICRO_AP_EV_BSS_ACTIVE	     68

/** TLV buffer header*/
typedef PACK_START struct _tlvbuf_header
{
    /** Header type */
    u16 type;
    /** Header length */
    u16 len;
} PACK_END tlvbuf_header;

/** TLV ID : WAPI Information */
#define MRVL_WAPI_INFO_TLV_ID        0x0167

/** TLV ID : Management Frame */
#define MRVL_MGMT_FRAME_TLV_ID       0x0168
/** Assoc Request */
#define SUBTYPE_ASSOC_REQUEST		0
/** Assoc Response */
#define SUBTYPE_ASSOC_RESPONSE		1
/** ReAssoc Request */
#define SUBTYPE_REASSOC_REQUEST		2
/** ReAssoc Response */
#define SUBTYPE_REASSOC_RESPONSE	3

/** Event body : STA deauth */
typedef PACK_START struct _EVENTBUF_STA_DEAUTH
{
    /** Deauthentication reason */
    u16 ReasonCode;
    /** MAC address of deauthenticated STA */
    u8 StaMacAddress[ETH_ALEN];
} PACK_END EVENTBUF_STA_DEAUTH;

/** Event body : STA associated */
typedef PACK_START struct _EVENTBUF_STA_ASSOC
{
    /** Reserved */
    u8 Reserved[2];
    /** MAC address of associated STA */
    u8 StaMacAddress[ETH_ALEN];
    /** Assoc request/response buffer */
    u8 AssocPayload[0];
} PACK_END EVENTBUF_STA_ASSOC;

/** Event body : BSS started */
typedef PACK_START struct _EVENTBUF_BSS_START
{
    /** Reserved */
    u8 Reserved[2];
    /** MAC address of BSS */
    u8 apMacAddress[ETH_ALEN];
} PACK_END EVENTBUF_BSS_START;

/**
 *                 IEEE 802.11 MAC Message Data Structures                   
 *                                                                           
 * Each IEEE 802.11 MAC message includes a MAC header, a frame body (which   
 * can be empty), and a frame check sequence field. This section gives the   
 * structures that used for the MAC message headers and frame bodies that    
 * can exist in the three types of MAC messages - 1) Control messages,       
 * 2) Data messages, and 3) Management messages.                             
 */
#ifdef BIG_ENDIAN
typedef PACK_START struct _IEEEtypes_FrameCtl_t
{
        /** Order */
    u8 Order:1;
        /** Wep */
    u8 Wep:1;
        /** MoreData */
    u8 MoreData:1;
        /** PwrMgmt */
    u8 PwrMgmt:1;
        /** Retry */
    u8 Retry:1;
        /** MoreFrag */
    u8 MoreFrag:1;
        /** FromDs */
    u8 FromDs:1;
        /** ToDs */
    u8 ToDs:1;
        /** Subtype */
    u8 Subtype:4;
        /** Type */
    u8 Type:2;
    /** Protocol Version */
    u8 ProtocolVersion:2;
} PACK_END IEEEtypes_FrameCtl_t;
#else
typedef PACK_START struct _IEEEtypes_FrameCtl_t
{
        /** Protocol Version */
    u8 ProtocolVersion:2;
        /** Type */
    u8 Type:2;
        /** Subtype */
    u8 Subtype:4;
        /** ToDs */
    u8 ToDs:1;
        /** FromDs */
    u8 FromDs:1;
        /** MoreFrag */
    u8 MoreFrag:1;
        /** Retry */
    u8 Retry:1;
        /** PwrMgmt */
    u8 PwrMgmt:1;
        /** MoreData */
    u8 MoreData:1;
        /** Wep */
    u8 Wep:1;
        /** Order */
    u8 Order:1;
} PACK_END IEEEtypes_FrameCtl_t;
#endif

/** IEEEtypes_AssocRqst_t */
typedef PACK_START struct _IEEEtypes_AssocRqst_t
{
        /** CapInfo */
    u16 CapInfo;
        /** ListenInterval */
    u16 ListenInterval;
        /** IE Buffer */
    u8 IEBuffer[0];
} PACK_END IEEEtypes_AssocRqst_t;

/** IEEEtypes_AssocRsp_t */
typedef PACK_START struct _IEEEtypes_AssocRsp_t
{
        /** CapInfo */
    u16 CapInfo;
        /** StatusCode */
    u16 StatusCode;
        /** AID */
    u16 AId;
} PACK_END IEEEtypes_AssocRsp_t;

/** IEEEtypes_ReAssocRqst_t */
typedef PACK_START struct _IEEEtypes_ReAssocRqst_t
{
        /** CapInfo */
    u16 CapInfo;
        /** ListenInterval */
    u16 ListenInterval;
        /** Current APAddr */
    u8 CurrentApAddr[ETH_ALEN];
        /** IE Buffer */
    u8 IEBuffer[0];
} PACK_END IEEEtypes_ReAssocRqst_t;

/** MrvlIEtypes_WapiInfoSet_t */
typedef PACK_START struct _MrvlIEtypes_WapiInfoSet_t
{
        /** Type */
    u16 Type;
        /** Length */
    u16 Len;
        /** Multicast PN */
    u8 MulticastPN[16];
} PACK_END MrvlIEtypes_WapiInfoSet_t;

/** MrvlIETypes_MgmtFrameSet_t */
typedef PACK_START struct _MrvlIETypes_MgmtFrameSet_t
{
        /** Type */
    u16 Type;
        /** Length */
    u16 Len;
        /** Frame Control */
    IEEEtypes_FrameCtl_t FrameControl;
        /** Frame Contents */
    u8 FrameContents[0];
} PACK_END MrvlIETypes_MgmtFrameSet_t;

/**Debug Type : Event */
#define DEBUG_TYPE_EVENT 	0
/**Debug Type : Info */
#define DEBUG_TYPE_INFO		1

/** Major debug id: Authenticator */
#define DEBUG_ID_MAJ_AUTHENTICATOR	1
/** Minor debug id: PWK1 */
#define DEBUG_MAJ_AUTH_MIN_PWK1		0
/** Minor debug id: PWK2 */
#define DEBUG_MAJ_AUTH_MIN_PWK2		1
/** Minor debug id: PWK3 */
#define DEBUG_MAJ_AUTH_MIN_PWK3		2
/** Minor debug id: PWK4 */
#define DEBUG_MAJ_AUTH_MIN_PWK4		3
/** Minor debug id: GWK1 */
#define DEBUG_MAJ_AUTH_MIN_GWK1		4
/** Minor debug id: GWK2 */
#define DEBUG_MAJ_AUTH_MIN_GWK2		5
/** Minor debug id: station reject */
#define DEBUG_MAJ_AUTH_MIN_STA_REJ	6
/** Minor debug id: EAPOL_TR */
#define DEBUG_MAJ_AUTH_MIN_EAPOL_TR	7

/** Major debug id: Assoicate agent */
#define DEBUG_ID_MAJ_ASSOC_AGENT	2
/** Minor debug id: WPA IE*/
#define DEBUG_ID_MAJ_ASSOC_MIN_WPA_IE	0
/** Minor debug id: station reject */
#define DEBUG_ID_MAJ_ASSOC_MIN_STA_REJ 	1

/** ether_hdr */
typedef PACK_START struct
{
        /** dest address */
    u8 da[ETH_ALEN];
        /** src address */
    u8 sa[ETH_ALEN];
        /** header type */
    u16 type;
} PACK_END ether_hdr_t;

/** 8021x header */
typedef PACK_START struct
{
        /** protocol version*/
    u8 protocol_ver;
        /** packet type*/
    u8 pckt_type;
        /** packet len */
    u8 pckt_body_len;
} PACK_END Hdr_8021x_t;

/** nonce size */
#define NONCE_SIZE	32
/** max wpa ie len */
#define MAX_WPA_IE_LEN	     64
/** EAPOL mic size */
#define EAPOL_MIC_SIZE        16

/** EAPOL key message */
typedef PACK_START struct
{
        /** Ether header */
    ether_hdr_t Ether_Hdr;
        /** 8021x header */
    Hdr_8021x_t hdr_8021x;
        /** desc_type */
    u8 desc_type;
        /** key info */
    u16 k;
        /** key length */
    u16 key_length;
        /** replay count */
    u32 replay_cnt[2];
        /** key nonce */
    u8 key_nonce[NONCE_SIZE];
        /** key IV */
    u8 EAPOL_key_IV[16];
        /** key RSC */
    u8 key_RSC[8];
        /** key ID */
    u8 key_ID[8];
        /** key MIC */
    u8 key_MIC[EAPOL_MIC_SIZE];
        /** key len */
    u16 key_material_len;
        /** key data */
    u8 key_data[MAX_WPA_IE_LEN];
} PACK_END EAPOL_KeyMsg_Debug_t;

/** failure after receive EAPOL MSG2 PMK */
#define REJECT_STATE_FAIL_EAPOL_2	1
/** failure after receive EAPOL MSG4 PMK*/
#define REJECT_STATE_FAIL_EAPOL_4	2
/** failure after receive EAPOL Group MSG2 GWK */
#define REJECT_STATE_FAIL_EAPOL_GROUP_2  3

/** Fail reason: Invalid ie */
#define IEEEtypes_REASON_INVALID_IE	13
/** Fail reason: Mic failure */
#define IEEEtypes_REASON_MIC_FAILURE	14

/** station reject */
typedef PACK_START struct
{
        /** reject state */
    u8 reject_state;
        /** reject reason */
    u16 reject_reason;
        /** station mac address */
    u8 staMacAddr[ETH_ALEN];
} PACK_END sta_reject_t;

/** wpa_ie */
typedef PACK_START struct
{
        /** station mac address */
    u8 staMacAddr[ETH_ALEN];
        /** wpa ie */
    u8 wpa_ie[MAX_WPA_IE_LEN];
} PACK_END wpaIe_t;

/** initial state of the state machine */
#define EAPOL_START 		1
/** sent eapol msg1, wait for msg2 from the client */
#define EAPOL_WAIT_PWK2		2
/** sent eapol msg3, wait for msg4 from the client */
#define EAPOL_WAIT_PWK4		3
/** sent eapol group key msg1, wait for group msg2 from the client */
#define EAPOL_WAIT_GTK2		4
/** eapol handshake complete */
#define EAPOL_END 		5

/** eapol state */
typedef PACK_START struct
{
        /** eapol state*/
    u8 eapolState;
        /** station address*/
    u8 staMacAddr[ETH_ALEN];
} PACK_END eapolState_t;

/**debug Info */
typedef PACK_START union
{
        /** eapol key message */
    EAPOL_KeyMsg_Debug_t eapol_pwkMsg;
        /** station reject*/
    sta_reject_t sta_reject;
        /** wpa ie */
    wpaIe_t wpaIe;
        /** eapol state */
    eapolState_t eapol_state;
} PACK_END dInfo;

/** Event body : Debug */
typedef PACK_START struct _EVENTBUF_DEBUG
{
        /** debug type */
    u8 debugtype;
        /** Major debug id */
    u32 debugIdMajor;
        /** Minor debug id */
    u32 debugIdMinor;
        /** debug Info */
    dInfo info;
} PACK_END EVENTBUF_DEBUG;
#endif /* _UAP_H */
