//
// 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

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

//
// Implementation constants
//
#define	BUF_SIZE			512*3+128	// Max IP size (1500) + LLC/SNAP size (8)
#define	BUF_NUM				32		// Buffer pool size
#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	SCAN_LIMIT			3		// Scan ticks per channel
#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_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

// 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_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

// 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_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)

// 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) > 14)

// 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
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)  (int keyidx, BOOL tx, uint8 *key, int len, uint8 *seq);
	BOOL (*Encrypt) (MacBuffer *buf);
	BOOL (*Decrypt) (MacBuffer *buf);
	BOOL (*AddMIC)  (MacBuffer *buf, MacAddr dst);
	BOOL (*VerifyMIC) (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)

#ifdef NET_OS_SPECIFIC
#ifdef DEBUG
#define	DPRINTF				printf
#define	ASSERT(x)			{ if (!(x)) assert_fail (#x, __FILE__, __LINE__); }
#else
#define	DPRINTF(...)
#define	ASSERT(x)
#endif
#endif

#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))
#else
#define	SWAP16(x)			(x)
#define	SWAP32(x)			(x)
#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 fuctions
//

// 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 (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;

void InitData (void);
void SetDefaultKeys (void);
void SendFrames (MacBuffer *sbuf, MacAddr dst);
void RecvFrame (MacBuffer *buf);
void AgeRecvCache (void);
BOOL OpenAddMIC (MacBuffer *buf, MacAddr dst);
BOOL OpenVerifyMIC (MacBuffer *buf);

// mac_drv.c
extern BOOL wln_params_set;
extern TX_MUTEX wln_mutex;

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 RecvMgmtFrame (MacBuffer *buf);
void NextBSS (void);
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 (void);

// 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);

// wln_api.c
BOOL wln_receive (uint8 *data, int len);
BOOL wln_send_event (wln_event event, void *param);
void assert_fail (char *expr, char *file, int line);

// 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

// Monitor mode flags and functions
extern void SetPromiscuousMode(BOOLEAN enable);
extern int monitorMode;
extern void adjustMaxAgc_wi9c(MacBuffer *buf);
extern void adjustMaxAgc_wiwave(MacBuffer *buf);

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

#endif // _MAC_H
