//
// Embedded 802.11b wireless network interface
// MAC layer internal defines
// Copyright 2003 Digi International
//

#ifndef _MAC_H
#define _MAC_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef NET_OS_SPECIFIC
#include <bsp_net.h>
#else
#include <bsp.h>
#endif

#if (BSP_ENABLE_WIWAVE == TRUE)
#define USB_WIFI_ENABLED 1
#endif

#include "fwtypes.h"
#include "trace.h"
#include "mac_api.h"
#include "tx_api.h"
#include "NA_ISR.h"

#if !defined BIG_ENDIAN && !defined NETOS_ARM_TOOLS
#define	BIG_ENDIAN
#endif


//#define DEBUG

#ifdef NET_OS_SPECIFIC
#include <trsocket.h>
#include <trmacro.h>
#include <trtype.h>
#include <trproto.h>
#define wln_rand    tfGetRandom
#else
#define wln_rand    rand
#endif

extern uint8 global_chan;	/* last channel programmed */

#ifdef NETOS_ARM_TOOLS
/* Allow anonymous unions and structures in C and anonymous classes and
   structures in C++*/
#pragma anon_unions
#endif

#define WLN_MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"

#define WLN_MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]

//
// Implementation constants
//
#define NA_WIFI_MAX_CHANNEL_INDEX       (52)        /* maximum number of channels */

#define NA_TX_POWER_CONTRAINT_NONE      (0)

#define	BUF_SIZE			512*3+128	// Max IP size (1500) + LLC/SNAP size (8)

// For the WiWave we need more MAC buffers, we need to constantly poll
// the WiWave and need buffers available to do this, otherwise
// the WiWave will lock up.
#if (USB_WIFI_ENABLED == 1)
#define	BUF_NUM				64		// Buffer pool size
#else
#define	BUF_NUM				32		// Buffer pool size
#endif

#define	BUF_RESV			8		// Buffers reserved for transmit or receive

#define	SCAN_NUM			16		// Number of scan results to allocate
#define	RXCACHE_NUM			10		// Receive cache size

#define	TIMER_PERIOD		50		// MAC timer period (in msecs)

#define	MGMT_PERIOD			500		// Management timer period (in msecs)
#define	MGMT_RETRY_LIMIT	4		// Management frame retry limit

#define	SCAN_PERIOD			10		// Active scan timer period (in msecs)
#define AFTER_PROBE_SCAN_LIMIT  15   // Scan ticks to wait after a probe has been sent
#define BEFORE_PROBE_SCAN_LIMIT 15  // Scan ticks to wait before a probe has been sent

#define	SCAN_MIN_TIME		5000	// Min time between scans (in msecs)
#define	SCAN_MAX_TIME		90000	// Max scan data lifetime (in msecs)

#define	IR_TIMEOUT			500		// Trasmitter idle timeout (in msecs)
#define	MICFAIL_TIMEOUT		60000	// MIC failure timer (in msecs)

#define	BEACON_INT			100		// IBSS Beacon interval (in TU)
#ifdef NET_OS_SPECIFIC
#define	BEACON_MISS			6		// Missed beacons to start new scan
#else
#define	BEACON_MISS			6		// Missed beacons to start new scan
#endif
#define	RSSI_SCALE			32		// RSSI samples to average

#ifndef AES_ENABLED
#define	AES_ENABLED					// Enable AES/CCMP encryption
#endif
#define	AES_encrypt			AES_encrypt_asm

// Preferred SSID if searching for any SSID
#define	PREF_SSID			"Connect"
#define	PREF_SSID_LEN		((sizeof PREF_SSID)-1)

//
// 802.11 MIB constants
//
#define	SHORT_RETRY_LIMIT	7			// Small frame transmit retry limit
#define	LONG_RETRY_LIMIT	4			// Large frame transmit retry limit

#define	CW_MIN				31			// Min contention window size
#define	CW_MAX				1023		// Max contention window size

#define TU					1024L/1000	// Time unit (in msecs)
#define	MAX_TX_LIFETIME		(512*TU)	// Transmit lifetime limit (in msecs)
#define	MAX_RX_LIFETIME		(512*TU)	// Receive lifetime limit (in msecs)

//
// 802.11 MAC frame formats
//
#define	IV_SIZE				4		// Initialization vector size
#define	EXTIV_SIZE			8		// IV and extended IV size
#define	SNAP_SIZE			8		// LLC/SNAP header size
#define	ICV_SIZE			4		// Integrity check value size
#define	MIC_SIZE			8		// Message integrity check size
#define	FCS_SIZE			4		// FCS (CRC-32) size

#define	WEP_SIZE			(IV_SIZE+ICV_SIZE)		// Total WEP size
#define	TKIP_SIZE			(EXTIV_SIZE+ICV_SIZE)	// Total TKIP size
#define	CCMP_SIZE			(EXTIV_SIZE+MIC_SIZE)	// Total CCMP size

#define TKIP_KEY_SIZE		32		// TKIP/MIC key size
#define CCMP_KEY_SIZE		16		// CCMP key size

#define	CHAL_SIZE			128		// Authentication challenge size

#define	RTS_SIZE			20		// RTS frame size
#define	CTS_SIZE			14		// CTS frame size
#define	DATA_SIZE			28		// Data frame header+FCS size
#define	ACK_SIZE			14		// ACK frame size

// Max total MAC frame size
#define	MAX_FRAME_SIZE		(DATA_SIZE+BUF_SIZE+TKIP_SIZE+MIC_SIZE)

// Max number of fragments
#define	MAX_FRAGS			16

// Frame header modulation type field
#define	MOD_PSKCCK			0x00	// PSK/CCK modulation
#define	MOD_OFDM			0xee	// OFDM modulation

// PSK/CCK PLCP service field bits
#define	SERVICE_LOCKED		0x04	// Locked clocks
#define	SERVICE_MODSEL		0x08	// Modulation selection
#define	SERVICE_LENEXT		0x80	// Length extension

// MAC type field values
#define	TYPE_ASSOC_REQ		0x00	// Association request
#define	TYPE_ASSOC_RESP		0x10	// Association response
#define	TYPE_REASSOC_REQ	0x20	// Reassociation request
#define	TYPE_REASSOC_RESP	0x30	// Reassociation response
#define	TYPE_PROBE_REQ		0x40	// Probe request
#define	TYPE_PROBE_RESP		0x50	// Probe response

#define	TYPE_BEACON			0x80	// Beacon
#define	TYPE_ATIM			0x90	// Annoucement traffice indication
#define	TYPE_DISASSOC		0xa0	// Disassociation
#define	TYPE_AUTH			0xb0	// Authentication
#define	TYPE_DEAUTH			0xc0	// Deauthentication
#define TYPE_ACTION         0xd0    // Action

#define TYPE_RTS			0xb4	// Request to send
#define TYPE_CTS			0xc4	// Clear to send
#define TYPE_ACK			0xd4	// Acknowledgement
#define TYPE_PSPOLL			0xa4	// Power Save(PS)-Poll

#define TYPE_DATA			0x08	// Data
#define TYPE_NULL_DATA      0x48    // Null Data

// TRUE if buf is data or management frame
#define	IS_DATA(buf)		(((buf)->macHdr.fc.type & 0xcf) == TYPE_DATA)
#define	IS_MGMT(buf)		(((buf)->macHdr.fc.type & 0x0f) == 0)

// Use short preamble if allowed in BSS and params and rate > 1 mbps.
#define	USE_SHORTPRE(rate)	((rate) > 0 && \
							 !(erpInfo & ERP_BARKER) && \
							 (macParams.options & WLN_OPT_SHORTPRE))

// MAC address macros
#define	MAC_GROUP			0x01	// Broadcast or multicast address
#define	MAC_LOCAL			0x02	// Locally administered address

#define	IS_GROUP_ADDR(addr)	(addr[0] & MAC_GROUP)
#define	EQUAL_ADDR(a1, a2)	(memcmp (a1, a2, WLN_ADDR_SIZE) == 0)
#define	SET_ADDR(a1, a2)	(memcpy (a1, a2, WLN_ADDR_SIZE))

// Authentication algorithm number field values
#define	AUTH_OPEN			0x00	// Open system
#define	AUTH_SHAREDKEY		0x01	// Shared key
#define	AUTH_LEAP			0x80	// LEAP

// Capability information field bits
#define	CAP_ESS				0x0001	// Extended service set (infrastructure)
#define	CAP_IBSS			0x0002	// Independent BSS (ad hoc)
#define	CAP_POLLABLE		0x0004	// Contention free pollable
#define	CAP_POLLREQ			0x0008	// Contention free poll request
#define	CAP_PRIVACY			0x0010	// Privacy (WEP) required
#define	CAP_SHORTPRE		0x0020	// Short preambles allowed
#define	CAP_PBCC			0x0040	// PBCC modulation allowed
#define	CAP_AGILITY			0x0080	// Channel agility in use
#define CAP_SPECTRUM_MGMT   0x0100  // 802.11h spectrum management is required
#define	CAP_SHORTSLOT		0x0400	// Short slot time in use
#define	CAP_DSSSOFDM		0x2000	// DSSS-OFDM in use

// Status code field values
#define	STAT_SUCCESS		0

// Reason code field values
#define	REAS_NOLONGERVALID	                    2
#define	REAS_DEAUTH_LEAVING	                    3
#define	REAS_INACTIVITY		                    4
#define REAS_INCORRECT_FRAME_UNAUTH             6
#define REAS_INCORRECT_FRAME_UNASSO             7
#define REAS_POWER_CAP_UNACCEPTABLE             10
#define REAS_SUPPORTED_CHANNELS_UNACCEPTABLE    11

// Information element IDs
#define	ELEM_SSID			        0		// Service set ID
#define	ELEM_SUPRATES		        1		// Supported rates
#define	ELEM_DSPARAM		        3		// DS parameter set
#define	ELEM_IBSSPARAM		        6		// IBSS parameter set
#define ELEM_COUNTRY                7       // Country information
#define	ELEM_CHALLENGE		        16		// Challenge text
#define ELEM_POWER_CONTRAINT        32      // Power Contraint
#define ELEM_POWER_CAPABILITY       33      // Power Capability
#define ELEM_TPC_REQUEST            34      // TPC request
#define ELEM_TPC_REPORT             35      // TPC report
#define ELEM_TPC_SUPPORTED_CHANNELS 36      // TPC list of supported channels
#define ELEM_CHANNEL_SWITCH         37      // Channel Switch Announcement
#define ELEM_MEASURE_REQUEST        38      // Measure request
#define ELEM_MEASURE_REPORT         39      // Measure report
#define ELEM_QUIET                  40      // Quiet period announcement
#define ELEM_ERPINFO		        42		// Extended rate PHY info
#define ELEM_RSN			        48		// Robust security network (WPA2)
#define	ELEM_EXTSUPRATES	        50		// Extended supported rates
#define ELEM_VENDOR			        221		// Vendor extension (WPA)

// Action category codes
#define ACTION_CAT_SPECTRUM_MGMT    (0)   // action frame category code for spectrum management

// Action Spectrum Management action value field codes
#define ACTION_SPECTRUM_MGMT_MEASURE_REQUEST                (0)
#define ACTION_SPECTRUM_MGMT_MEASURE_REPORT                 (1)
#define ACTION_SPECTRUM_MGMT_TPC_REQUEST                    (2)
#define ACTION_SPECTRUM_MGMT_TPC_REPORT                     (3)
#define ACTION_SPECTRUM_MGMT_CHANNEL_SWITCH_ANNOUNCEMENT    (4)

#define MEASURE_REQUEST_TYPE_BASIC          (0)
#define MEASURE_REQUEST_TYPE_CAA            (1)
#define MEASURE_REQUEST_TYPE_RPI_HISTOGRAM  (2)


#define MEASURE_REPORT_MODE_SUCCESS         (0)
#define MEASURE_REPORT_MODE_LATE            (1)
#define MEASURE_REPORT_MODE_INCAPABLE       (2)
#define MEASURE_REPORT_MODE_REFUSED         (4)

#define NA_BASIC_MEASURE_IDLE               (0)
#define NA_BASIC_MEASURE_WAITING            (1)

#define CHANNEL_SWITCH_MODE_VERBOSE         (0)
#define CHANNEL_SWITCH_MODE_QUIET           (1)

// Used in measure requests, # of usecs in a millisecond
#define NA_WIFI_ONE_MILLISECOND                     (1000)

void naWifiWaitUS (uint32 usec);

// 802.11d related defines
// minimum length field value in country information elelment
#define COUNTRY_INFO_MIN_LEN   6

// Supported rates bits
#define	RATE_BASIC			0x80	// Bit set if basic rate

// TRUE if channel number in 5 GHz band
#define	CHAN_5G(chan)		((chan) > 16)

// ERP info bits
#define	ERP_NONERP			0x01	// Non-ERP present
#define	ERP_USEPROTECT		0x02	// Use protection
#define	ERP_BARKER			0x04	// Barker (long) preamble mode

// WPA/RSN info length field
#define	wpa_info_len		wpa_info[1]
#define rsn_info_len        rsn_info[1]

// Key ID byte in data frame body
#define	EXT_IV				0x20	// Extended IV is present

// Correct CRC-32 check value
#define	GOOD_CRC32			0x2144df1c

//
// 802.11 MAC frame structures.
// These structures lay out a complete PLCP/MAC frame in a single memory region.
// They are compiler dependent.
//
#pragma pack(1)

#ifdef NETOS_ARM_TOOLS
#define	PACKED_H	__packed
#define	PACKED_F
#else
#define	PACKED_H
#define	PACKED_F	__attribute__ ((packed))
#endif

// Receive frame header
typedef PACKED_H struct {
	unsigned modType	:8;		// Modulation type
#ifdef BIG_ENDIAN
	unsigned ant		:1;		// Receive antenna indicator
	unsigned rssiLNA	:2;		// RSSI LNA setting
	unsigned rssiVGA	:5;		// RSSI VGA setting
#else
	unsigned rssiVGA	:5;		// RSSI VGA setting
	unsigned rssiLNA	:2;		// RSSI LNA setting
	unsigned ant		:1;		// Receive antenna indicator
#endif
	unsigned freqOff	:16;	// Frequency offset (needs byte swap)
} PACKED_F RxFrameHeader;

// Transmit frame header
// Need to swap bytes on BIG_ENDIAN
typedef PACKED_H struct {
#ifdef BIG_ENDIAN
	unsigned _pad		:15;
	unsigned length		:9;		// Length in words
	unsigned modType	:8;		// Modulation type
#else
	unsigned modType	:8;		// Modulation type
	unsigned length		:9;		// Length in words
	unsigned _pad		:15;
#endif
} PACKED_F TxFrameHeader;

// Union of frame header types
typedef union {
	RxFrameHeader rx;			// Receive frame header
	TxFrameHeader tx;			// Transmit frame header (needs byte swap)
	uint32 hdr32;				// Frame header as 32-bit int
} FrameHeader;


// PSK/CCK PLCP header
typedef PACKED_H struct {
	uint8	signal;				// Signal (rate in 100 kbps)
	uint8	service;			// Service: OR of SERVICE_xxx
	uint16	length;				// Length in usecs (needs byte swap)
} PACKED_F PskCckHeader;

// OFDM PLCP header
// Need to swap bytes on BIG_ENDIAN
typedef PACKED_H struct {
#ifdef BIG_ENDIAN
	unsigned _pad    	:14;	// Service field
	unsigned parity		:1;		// Even parity bit
	unsigned length		:12;	// Length in bytes
	unsigned reserved	:1;
	unsigned rate		:4;		// Data rate
#else
	unsigned rate		:4;		// Data rate
	unsigned reserved	:1;
	unsigned length		:12;	// Length in bytes
	unsigned parity		:1;		// Even parity bit
	unsigned _pad   	:14;	// Service field
#endif
} PACKED_F OfdmHeader;

// Union of PLCP header types
typedef union {
	PskCckHeader pskcck;		// PLCP header for PSK/CCK
	OfdmHeader ofdm;			// PLCP header for OFDM (needs byte swap)
	uint32 plcp32;				// PLCP header as 32-bit int
} PlcpHeader;

// Frame control field
typedef PACKED_H struct {
	unsigned type		:8;		// Type, subtype, version
#ifdef BIG_ENDIAN
	unsigned order		:1;		// Strictly ordered
	unsigned protected	:1;		// Encrypted
	unsigned moreData	:1;		// More data buffered
	unsigned pwrMgt		:1;		// Power management state
	unsigned retry		:1;		// Retransmission
	unsigned moreFrag	:1;		// More fragments
	unsigned fromDS		:1;		// From distribution service (AP)
	unsigned toDS		:1;		// To distribution service (AP)
#else
	unsigned toDS		:1;		// To distribution service (AP)
	unsigned fromDS		:1;		// From distribution service (AP)
	unsigned moreFrag	:1;		// More fragments
	unsigned retry		:1;		// Retransmission
	unsigned pwrMgt		:1;		// Power management state
	unsigned moreData	:1;		// More data buffered
	unsigned protected	:1;		// Encrypted
	unsigned order		:1;		// Strictly ordered
#endif
} PACKED_F FrameControl;

// MAC address
typedef uint8 MacAddr[WLN_ADDR_SIZE];

// Sequence control field
// Need to swap bytes on BIG_ENDIAN
typedef PACKED_H struct {
#ifdef BIG_ENDIAN
	unsigned seq		:12;	// Sequence number
	unsigned frag		:4;		// Fragment number
#else
	unsigned frag		:4;		// Fragment number
	unsigned seq		:12;	// Sequence number
#endif
} PACKED_F SeqControl;

// Union of sequence control types
typedef PACKED_H union {
	SeqControl sq;				// Sequence control fields
	uint16 sq16;				// Sequence control as 16-bit int (needs byte swap)
} PACKED_F SeqControlU;

// MAC header
typedef PACKED_H struct {
	FrameControl fc;			// Frame control
	uint16	duration;			// Duration/ID (needs byte swap)
	MacAddr	addr1;				// Address 1
	MacAddr	addr2;				// Address 2
	MacAddr	addr3;				// Address 3
	SeqControlU squ;			// Sequence control fields
} PACKED_F MacHeader;

#pragma pack()

// MAC buffer, including complete MAC frame
//!!!!!!!!!! When add a field to this structure, be sure every field's address to be at 4- byte boundary !!!!!
typedef struct MacBuffer {
	struct MacBuffer *next;		// Next buffer in list
	uint16	length;				// Length including MAC header, body, FCS
	int8_t	rx_signal;		    // Received signal strength
	uint8	tx_rate;			// Transmit rate index
	uint32	rssi;		        // Received signal strength:(rxFrame.frameHdr.rx.rssiLNA << 5) | rxFrame.frameHdr.rx.rssiVGA
#if (USB_WIFI_ENABLED == 1)
	uint32  usb_encoded_length;	// Encoded length for wifi-usb header
	uint32  usb_status[3];		// Array of wifi-usb status words
#endif
	FrameHeader	frameHdr;		// Frame header
	PlcpHeader	plcpHdr;		// PLCP header
	MacHeader	macHdr;			// MAC header

	// IV, body, MIC, ICV, FCS
	uint8 	body[TKIP_SIZE+MIC_SIZE+FCS_SIZE];
	// Additional BUF_SIZE bytes of body follow
} MacBuffer;

// LLC/SNAP (802.2) header on data frames
typedef struct
{
    uint8	dsap;
    uint8	ssap;
    uint8	control;
    uint8	oui[3];
    uint16	eptype;
} LLC_SNAP;

#define	SAP_SNAP	0xaa		// Subnetwork address protocol
#define XDLC_U		0x03		// Unnumbered frame

#define	EP_8021X	SWAP16(0x8e88)	// 802.1x (EAPOL) protocol type

// Ethernet (802.3) MAC header
typedef PACKED_H struct
{
    MacAddr	dst;
    MacAddr	src;
    uint16	eptype;
    uint8	data[]; /* was 0 */
} PACKED_F ether_hdr;

//
// Internal defines
//

// Transmitter state
typedef enum {
	ST_IDLE,	// Transmitter idle
	ST_CTS,		// Sent RTS, waiting for CTS
	ST_ACK,		// Sent data, waiting for ACK
	ST_BC,		// Sent BC data, waiting for txEnd
	ST_BUSY,	// Sent frame, waiting for txEnd
} TxState;

// IBSS beacon/ATIM state
typedef enum {
	SB_DATA,	// Data frames allowed
	SB_TBTT,	// Time to transmit beacon
	SB_BEACON,	// Transmitting beacon
	SB_ATIM,	// ATIM window
} BcnState;

// Station management state
typedef enum {
	SS_WAIT,	// Waiting to restart
	SS_SCAN,	// Scanning
	SS_BEACON,	// Waiting to receive beacon
	SS_JOIN,	// Joined a BSS
	SS_AUTH,	// Authenticated
	SS_ASSOC,	// Associated with AP or joined IBSS
} StaState;

// 802.11 authentication state, in order of method attempted
typedef enum {
	SA_INIT,			// Initial state
	SA_LEAP = SA_INIT,	// LEAP
	SA_SHARED,			// Shared key
	SA_OPEN,			// Open System
	SA_FAIL,			// Above attempts failed
	SA_SHARED2,			// Shared key response
	SA_FAIL2,			// Shared key response failed
} AuthState;

// Expected event after sending a frame
enum {
	SF_NONE,	// No event
	SF_TXEND, 	// Interrupt on txEnd
	SF_RX,		// Receive a frame
	SF_RX_TX,	// Receive a frame, then transmit another
};

// Encryption cipher operations
typedef struct {
	int ivSize;				// Initialization vector size
	BOOL (*SetKey)  (struct endptStatus *pSta, int keyidx, BOOL tx, uint8 *key, int len, uint8 *seq);
	BOOL (*Encrypt) (struct endptStatus *pSta, MacBuffer *buf);
	BOOL (*Decrypt) (struct endptStatus *pSta, MacBuffer *buf);
	BOOL (*AddMIC)  (struct endptStatus *pSta, MacBuffer *buf, MacAddr dst);
	BOOL (*VerifyMIC) (struct endptStatus *pSta, MacBuffer *buf);
} MacCipher;

#ifdef	AES_ENABLED
#include "aes.h"

// CCMP encryption data
typedef struct {
	AES_KEY		*key;
	uint8		init[AES_BLOCK_SIZE];
	uint8		header[2*AES_BLOCK_SIZE];
} CcmpData;
#endif

// Rate values
#define	RATE_MASK_A		0x0ff0
#define	RATE_MASK_B		0x000f
#define	RATE_MASK_G		0x0fff

#define	RATE_MASK_PSK		0x0003
#define	RATE_MASK_CCK		0x000c
#define	RATE_MASK_OFDM		0x0ff0

#define	RATE_MASK_BASIC		0x0153	// Ad hoc basic rates

#define	RATE_MIN_A		4
#define	RATE_MIN_B		0

// Buffer queue
typedef struct {
	MacBuffer *head;		// Head of queue, NULL if empty
	MacBuffer *tail;		// Tail of queue if not empty
    int count;				// Number of buffers queued

} MacQueue;

// Queue macros
#define	TXQ_GET(buf)		((buf) = GetQueue (&txQueue))
#define	TXQ_PUT(buf)		(PutQueue (&txQueue, buf))

#define	RXQ_GET(buf)		((buf) = GetQueue (&rxQueue))
#define	RXQ_PUT(buf)		(PutQueue (&rxQueue, buf))

// Utility macros
#define	TRUE				1
#define	FALSE				0

#define	GET_TIME()			getTimeMS()		// Get system time (in msecs)

#define	GET_MUTEX()			tx_mutex_get (&wln_mutex, TX_WAIT_FOREVER)
#define	PUT_MUTEX()			tx_mutex_put (&wln_mutex)
#define	GET_MUTEX2()			tx_mutex_get (&wln_mutex2, TX_WAIT_FOREVER)
#define	PUT_MUTEX2()			tx_mutex_put (&wln_mutex2)
#define	GET_MUTEX3()			tx_mutex_get (&wln_mutex3, TX_WAIT_FOREVER)
#define	PUT_MUTEX3()			tx_mutex_put (&wln_mutex3)
extern TX_MUTEX wln_mutex3;

// Power save macros

// power save states
typedef enum
{
    WLN_PSMODE_DISABLED,
    WLN_PSMODE_AWAKE,
    WLN_PSMODE_NF_SET,
    WLN_PSMODE_NF_SET_ACK,
    WLN_PSMODE_SLEEP,
    WLN_PSMODE_NF_CLR,
    WLN_PSMODE_NF_CLR_ACK
}wln_psmode_state_t;

// power save event flags
#define WLN_PSEVENT_TIMER    0x0001  /* timer expired */
#define WLN_PSEVENT_BEACON   0x0002  /* Received beacon */
#define WLN_PSEVENT_ACK      0x0004  /* ACK from NULL frame  */
#define WLN_PSEVENT_MORE     0x0008  /* more data from PS poll */
#define WLN_PSEVENT_ALL      (WLN_PSEVENT_TIMER | WLN_PSEVENT_BEACON | \
                              WLN_PSEVENT_ACK | WLN_PSEVENT_MORE)


#define A_SUBBAND1    	1
#define A_SUBBAND2	2
#define A_SUBBAND3	3
#define A_SUBBAND4	4
#define A_SUBBAND5	5
#define A_SUBBAND_NO_EXIST	0xff

// #define WLN_PS_BEACON_BASED

#ifdef NET_OS_SPECIFIC
/* turning this flag on here turns off the definition in mac_hw_wiwave.c */
#define	WLAN_TRACE_ENABLED

#ifdef	WLAN_TRACE_ENABLED
#define DPRINTF(...) trace(WIRELESS_TRACE, TRACE_DEBUG, __VA_ARGS__)
#define XPRINTF(level, ...) trace(WIRELESS_TRACE, level, __VA_ARGS__)
#define SMPRINTF(level, ...) trace(ESM_TRACE, level, __VA_ARGS__)

//#define DPRINTF(...)         printf(__VA_ARGS__)
//#define XPRINTF(level, ...)  printf(__VA_ARGS__)
//#define SMPRINTF(level, ...) printf(__VA_ARGS__)
#define	ASSERT(x)
#else

#define DEBUG
#ifdef DEBUG
#define	DPRINTF				printf
#define XPRINTF(level, ...) printf(__VA_ARGS__)
#define SMPRINTF(level, ...) printf(__VA_ARGS__)
#define	ASSERT(x)			{ if (!(x)) assert_fail (#x, __FILE__, __LINE__); }
#else
#define	DPRINTF(...)
#define	XPRINTF(level, ...)
#define	ASSERT(x)
#endif	/* not DEBUG */
#endif	/* not WLAN_TRACE_ENABLED */
#endif	/* NET_OS_SPECIFIC */

#ifdef NDS_SPECIFIC

#define	DPRINTF(format, args...) \
	trace_printf (WIRELESS_TRACE, TRACE_DEBUG, format, ##args)

#define NA_UNUSED_PARAM(p)    ((void)(p))
#define	ASSERT(x)

#endif /* NDS_SPECIFIC */

#define	DISABLE()			NASetIRQ(IRQ_DISABLED)	// Disable interrupts
#define	ENABLE(x)			NASetIRQ(x)				// Enable interrupts

// Host to network byte order macros.
// MAC layer is little endian, so big endian CPUs must swap.
#ifdef BIG_ENDIAN
#define	SWAP16(x)			((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
#define	SWAP32(x)			((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | \
							 (((x) >> 8) & 0xff00) | (((x) >> 24) & 0xff))

#define GET_TSF(high, low, p)   low = ((BYTE *)p)[0] | (((BYTE *)p)[1] << 8) | (((BYTE *)p)[2] << 16) | (((BYTE *)p)[3] << 24); \
                                high = ((BYTE *)p)[4] | (((BYTE *)p)[5] << 8) | (((BYTE *)p)[6] << 16) | (((BYTE *)p)[7] << 24)
#define SET_TSF(high, low, p)   ((BYTE *)p)[0] = low & 0xff;          \
                                ((BYTE *)p)[1] = (low >> 8) & 0xff;   \
                                ((BYTE *)p)[2] = (low >> 16) & 0xff;  \
                                ((BYTE *)p)[3] = (low >> 24) & 0xff;  \
                                ((BYTE *)p)[4] = high & 0xff;         \
                                ((BYTE *)p)[5] = (high >> 8) & 0xff;  \
                                ((BYTE *)p)[6] = (high >> 16) & 0xff; \
                                ((BYTE *)p)[7] = (high >> 24) & 0xff

#else
#define	SWAP16(x)			(x)
#define	SWAP32(x)			(x)

#define GET_TSF(high, low, p)   low = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); \
                                high = p[4] | (p[5] << 8) | (p[6] << 16) | (p[7] << 24)

#endif

#define	HTON16(x)			SWAP16(x)
#define	NTOH16(x)			SWAP16(x)

// Get 16 bits at byte pointer
#define	GET16(bp)			((bp)[0] | ((bp)[1] << 8))

// Store 16 bits at byte pointer
#define	SET16(bp, data)		{ (bp)[0] = (data); \
							  (bp)[1] = (data) >> 8; }

// Get 32 bits at byte pointer
#define	GET32(bp)			((bp)[0] | ((bp)[1] << 8) | ((bp)[2] << 16) | ((bp)[3] << 24))

// Store 32 bits at byte pointer
#define	SET32(bp, data)		{ (bp)[0] = (data); \
							  (bp)[1] = (data) >> 8;  \
							  (bp)[2] = (data) >> 16; \
							  (bp)[3] = (data) >> 24; }

//
// Internal data and functions
//

// mac_buf.c
extern MacQueue txQueue;
extern MacQueue rxQueue;

MacReturn InitBuffers (void);
void ReleaseBuffers (void);
MacBuffer *GetQueue (MacQueue *q);
void PutQueue (MacQueue *q, MacBuffer *buf);

#ifdef AES_ENABLED
// mac_ccmp.c
extern MacCipher ccmpCipher;
extern BOOL hwAES;

BOOL CcmpGetData (MacAddr ourAddress, MacBuffer *buf, CcmpData *data);

#if (USB_WIFI_ENABLED == 1)
#include "aes.h"
void SetAESKey(int id, AES_KEY *key);
#endif
#endif

// mac_data.c
extern MacCipher openCipher;
extern MacStats macStats;
extern int maxFragSize;


typedef struct NABasicMeasureRequest_t
{
    uint32 timerHigh;
    uint32 timerLow;
    uint32 startHigh;
    uint32 startLow;
    uint8 dialogToken;
    uint8 measureToken;
    uint16 duration;
    void *pSta;
    uint8 channel;
    MacAddr destAddress;
} NABasicMeasureRequest_t;

typedef struct NAQuietPeriod_t
{
    uint32 periodEnd;
    uint32 overflowCorrection;
    BOOL transmitterStopped;
} NAQuietPeriod_t;

/*
 * Contains variables used for Dynamic Frequency Selection, which
 * is part of 802.11h.
 */
typedef struct NA802dot11_t
{
    /*
     * This field indicates if spectrum management is required.  It is set to the NVRAM
     * value (macParams.options & WLN_OPT_SPECTRUM_MGMT) before we associate.  If it is set
     * TRUE, then we will only associate with an AP that advertises it.  When we associate,
     * it will be forced TRUE if the AP advertises it as TRUE.
     */
    BOOL spectrumManagementRequired;

     /*
     * This field indicates if regulatory classes is required.  It is set to TRUE
     * when the station received beacon and the first channel number fiield has a positive
     * integer value greater than 200.
     */
    BOOL regulatoryClassesRequired;

    /*
     * This field is used to keep track of whether we have received any frames on the
     * channel we are currently scanning for APs.  If dot11SpectrumManagementRequired is
     * TRUE, then we will not transmit on that channel until we receive a packet.
     */
    BOOL receivedFrameOnCurrentChannel;
    uint32 tsfHigh;
    uint32 tsfLow;
    ULONG ticksAtLastBeacon;
    NABasicMeasureRequest_t basicMeasureRequest;
    NAQuietPeriod_t quiet;
    int currentTxPower;
} NA802dot11_t;

extern NA802dot11_t naDot11;

void InitData (void);
void naWlnmacInitializeCiphers(struct endptStatus *pSta);
void SetDefaultKeys (struct endptStatus *pSta);
void SendFrames (struct endptStatus *pSta, MacBuffer *sbuf, MacAddr dst);
void RecvFrame (MacBuffer *buf);
void AgeRecvCache (void);
BOOL OpenAddMIC (struct endptStatus *pSta, MacBuffer *buf, MacAddr dst);
BOOL OpenVerifyMIC (struct endptStatus *pSta, MacBuffer *buf);
void naWifiStartHWBasicMeasure(void);
uint8 naWifiStartHWGetBasicMeasureMap(void);
int32 naWifiMicrosecondsLeft(uint32 timerHigh, uint32 timerLow);
void naStartBasicMeasure(ULONG notUsed);


// mac_drv.c
extern BOOL wln_params_set;
extern TX_MUTEX wln_mutex;
#if (USB_WIFI_ENABLED == 1)
extern TX_MUTEX wln_tx_mutex;
#endif

uint32 getTimeMS (void);

// mac_hw.c
MacReturn InitHW (void);
void ShutdownHW (void);
void SetChannel (int channel);
void SetBSS (int bssCaps, MacAddr bssid, uint8 *ssid, int ssid_len, uint16 basic, int atim);
void SetLED (BOOL on);
void SetActivityLED (BOOL on);
void MacSendFrame (MacBuffer *buf, int cw, int next);
BOOL GetFrame (MacBuffer *buf);
void DropFrame (int length);

// mac_ir.c
extern TxState txState;
extern BcnState bcnState;
extern uint32 bcnTime;
extern MacBuffer ctsFrame;

void InitIR (void);
void IRTimer (void);
void HandleRxEnd (MacBuffer *rxBuf);
void HandleTxEnd (void);
void HandleMacError (int error);
void HandleBeacon (BOOL tbtt);
void SendQueue (void);

// mac_mgmt.c
extern wln_params macParams;
extern wln_status macStatus;
extern MacBuffer *bcnFrame;
extern MacBuffer *respFrame;
extern StaState staState;
extern uint16 bcnInt;
extern uint16 atimWindow;
extern uint8 erpInfo;
extern uint32 macRandom;

void UpdateActivityLED (BOOL on);

// mac_rate.c
extern int rateTx;
extern int rateBC;
extern int rateMin;
extern uint8 ratesBasic[];
extern int rateTxCount;
extern int rateErrorCount;

int GetDuration (MacBuffer *buf);
int GetAckDuration (int rate);
void SetPLCP (MacBuffer *buf, int rate);
BOOL CheckRates (uint8 *bssRates, int len, wln_scan_bss *info);
uint8 *SetRates (uint8 *bp, int elem, int channel);
BOOL InitRates (wln_scan_bss *sp, BOOL init);
void ReduceRate (MacBuffer *buf, int steps);
void UpdateRate (struct endptStatus *pSta);

// mac_tkip.c
extern MacCipher tkipCipher;

// mac_wep.c
extern MacCipher wepCipher;

void InitCRC32 (void);
uint32 CalcCRC32 (uint8 *buf, int length);
void RC4Process (uint8 *key, int keyLen, uint8 *data, int dataLen);

void assert_fail (char *expr, char *file, int line);

// mac_ps.c
#ifdef MAC_PS_ENABLED
extern MacBuffer * wln_make_null_frame (BOOL psave);
extern TX_EVENT_FLAGS_GROUP wln_ps_event_flags;
extern wln_psmode_state_t wln_ps_mode;
extern MacBuffer *wlnNullFramePtr;
extern BOOL wlnClearTxFrame;
#endif

// Receive callback table entry
typedef struct {
	int ep_type;			// Ethernet protocol type
	wln_receive_cb func;	// Callback function
	void *context;			// Parameter to callback function
} ep_types;

// Table of callback functions for each protocol type
#define	MAX_TYPES	8

// Event callback table entry
typedef struct {
	wln_event_cb func;		// Callback function
	void *context;			// Parameter to callback function
} event_cb;

typedef struct {
	BOOL valid;			// TRUE if key is valid
	uint16 	txPN0;		// Transmit packet number (low 16 bits)
	uint32 	txPN1;		// Transmit packet number (high 32 bits)
	uint16 	rxPN0;		// Next receive packet number
	uint32 	rxPN1;
	AES_KEY	rk;			// AES key schedule
} CcmpKey;

typedef struct
{
    CcmpKey keys[WLN_KEY_NUM];
    int txKeyId;
} NaCcmpInfo_t;


// Table of event callback functions
#define	MAX_EVENTS	8


typedef struct {
	int		length;					// Length: 0, 5, or 13
	uint8	key[WLN_WEP104_SIZE];	// Key bytes
} WepKey;

typedef struct
{
    WepKey keys[WLN_KEY_NUM];
    int txKeyID;					// Key index used to transmit
} NaWepInfo_t;


typedef struct {
	BOOL valid;					// TRUE if key is valid
	uint8  key[TKIP_KEY_SIZE];	// Key data
	uint16 txTTAK[5];			// Transmit phase 1 key mixing output
	uint16 rxTTAK[5];			// Receive phase 1 key mixing output

	uint16 txTSC0;				// Transmit sequence counter (low 16 bits)
	uint32 txTSC1;				// Transmit sequence counter (high 32 bits)

	uint16 rxTSC0;				// Receive sequence counter
	uint32 rxTSC1;
	uint16 micTSC0;				// Next receive sequence counter after MIC verified
	uint32 micTSC1;
} TkipKey;

typedef struct
{
    TkipKey keys[WLN_KEY_NUM];
    int txKeyID;				// Key index used to transmit
    uint32 micFailureTime;	// Time MIC failure occurred
    BOOL blocking;			// TRUE if blocking due to MIC failure
} NaTkipInfo_t;


/* number of addresses supported in the mac assist code, including the
 * primary address */
#define	WLN_MAX_ADDRS	(3)

typedef struct endptStatus
{
	struct	endptStatus	*next;
	struct	endptStatus	*root;
	int		entryNdx;
	unsigned int mgmtTime;
	int	retry;
	mac_addr	staAddr;
	StaState	staState;         // Station state: one of SS_xxx
	StaState	scan_state;       // Station state before scan
	AuthState	authState;        // Authentication state
	uint8	challenge[CHAL_SIZE]; // Authentication challenge
	wln_status	macStatus;       // Operating status
	event_cb	event_cbs[MAX_EVENTS];
	ep_types	types[MAX_TYPES];
    MacCipher *pairCipher;		// Pairwise (station to station) cipher
    MacCipher *newPairCipher;	// Pairsize cipher after next frame
    MacCipher *groupCipher;	// Group (broadcast) cipher
    NaCcmpInfo_t ccmpInfo;
    NaTkipInfo_t tkipInfo;
    NaWepInfo_t wepInfo;
    int     waitingForRoot;     // waiting for root to complete authentication before starting association/authentication process on secondary endpoint
    int     secondaryEndpointDelayTimer;
    uint16  tbttMilliseconds;  // number of milliseconds in a TBTT
    char    * ifname;
} epStatus;

extern epStatus *rootEndPoint[WLN_MAX_ADDRS];

// Monitor mode flags and functions
extern void SetPromiscuousMode(BOOLEAN enable);
extern int monitorMode;


//function added to fix UNH test vantives
extern int force_disassociate (epStatus *pSta, MacBuffer *rxBuf, int reson, int deauth);

extern epStatus * MacGetStationPtr(char *macAddr);
extern void resetTxFifo(void);

void LogRecvStats(FrameControl fc);

// wln_api.c
#if	BSP_WIFI_MULTIPLE_MAC
BOOL wln_receive (epStatus * pSta, uint8 *data, int len);
#else
BOOL wln_receive (uint8 *data, int len);
#endif
void RecvMgmtFrame (epStatus *pSta, MacBuffer *buf);
void SendMgmtFrame (epStatus *pSta);

void NextBSS (epStatus * pSta);

BOOL wln_send_event (epStatus * pSta, wln_event event, void *param);


//added for 802.11j
#define MAX_CHAN_NUM_IN_ONE_REG_CLASS            11
typedef struct {
        uint8 chanNum;                //how many channels in reg class
        uint8 channel_set[MAX_CHAN_NUM_IN_ONE_REG_CLASS];   //which channels in reg class, index in the frequence table
} regulatoryClass_T;

#define MAX_COVERAGE_CLASS_VALUE    31

extern int ParseRegulatoryInfo(uint8 * country_info, regulatoryClass_T ** regulatoryClass, int * maxRegClass);
extern void SetCoverageclass( uint coverageClass );


int wlnMacGetTxCurrentTxRateX2(void);
void adjustMaxAgc_wi9c(epStatus *pSta, MacBuffer *buf);

int wlnMacGetTxCurrentOfdmCode(void);

int wlnApplyTxPowerConstraint(int value, unsigned channelIndex);
extern void adjustMaxAgc(epStatus * pSta, MacBuffer * rxBuf);

#endif // _MAC_H
