/****************************************************************************
 * Ralink Tech Inc.
 * Taiwan, R.O.C.
 *
 * (c) Copyright 2002, Ralink Technology, Inc.
 *
 * All rights reserved. Ralink's source code is an unpublished work and the
 * use of a copyright notice does not imply otherwise. This source code
 * contains confidential trade secret material of Ralink Tech. Any attemp
 * or participation in deciphering, decoding, reverse engineering or in any
 * way altering the source code is stricitly prohibited, unless the prior
 * written consent of Ralink Technology, Inc. is obtained.
 ***************************************************************************

    Module Name:
	rt_ecos.h

    Abstract:

    Revision History:
    Who          When          What
    ---------    ----------    ----------------------------------------------
*/

#ifndef __RT_ECOS_H__
#define __RT_ECOS_H__

#define LLTD_SUPPORT 1

#include <stdio.h>
#include <stdlib.h>

#include <cyg/infra/diag.h>     /* For dial_printf */
#include <cyg/hal/hal_if.h>     /* For CYGACC_CALL_IF_DELAY_US */
#include <cyg/hal/hal_cache.h>  /* For HAL_DCACHE_INVALIDATE */
#include <cyg/kernel/kapi.h>
#include <cyg/io/eth/netdev.h>  /* For struct eth_drv_sc */
#include <cyg/io/eth/eth_drv.h> /* For eth_drv_netdev */
#include <cyg/io/flash.h>       /* For SPI Flash */
#include <sys/mbuf.h>           /* Memory Pool */
#include <sys/param.h>          /* For tsleep */
#include <stdarg.h>

#include <pkgconf/system.h>
#ifdef BRANCH_ADV
#undef CONFIG_BRIDGE
#include <autoconf.h>
#endif

#include "rtmp_type.h"
/*#include "rtmp_def.h" */

#undef AP_WSC_INCLUDED
#undef STA_WSC_INCLUDED
#undef WSC_INCLUDED

#ifdef CONFIG_AP_SUPPORT
#ifdef WSC_AP_SUPPORT
#define AP_WSC_INCLUDED
#endif /* WSC_AP_SUPPORT */
#endif /* CONFIG_AP_SUPPORT */

#ifdef CONFIG_STA_SUPPORT
#ifdef WSC_STA_SUPPORT
#define STA_WSC_INCLUDED
#endif /* WSC_STA_SUPPORT */
#endif /* CONFIG_STA_SUPPORT */

#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
#define WSC_INCLUDED
#endif

#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif

#define RTMP_TIMER_TASK_SUPPORT

/***********************************************************************************
 *	Profile related sections
 ***********************************************************************************/
#ifdef CONFIG_AP_SUPPORT
#ifdef RTMP_MAC_PCI
#define AP_PROFILE_PATH			"/etc/Wireless/RT2860AP/RT2860AP.dat"
#define AP_RTMP_FIRMWARE_FILE_NAME "/etc/Wireless/RT2860AP/RT2860AP.bin"
#define AP_NIC_DEVICE_NAME			"RT2860AP"
#define AP_DRIVER_VERSION			"2.6.0.0"
#ifdef MULTIPLE_CARD_SUPPORT
#define CARD_INFO_PATH			"/etc/Wireless/RT2860AP/RT2860APCard.dat"
#endif /* MULTIPLE_CARD_SUPPORT */
#endif /* RTMP_MAC_PCI */

#ifdef RTMP_MAC_USB
#define AP_PROFILE_PATH			"/etc/Wireless/RT2870AP/RT2870AP.dat"
#define AP_RTMP_FIRMWARE_FILE_NAME "/etc/Wireless/RT2870AP/RT2870AP.bin"
#define AP_NIC_DEVICE_NAME			"RT2870AP"
#define AP_DRIVER_VERSION			"2.1.0.0"
#ifdef MULTIPLE_CARD_SUPPORT
#define CARD_INFO_PATH			"/etc/Wireless/RT2870AP/RT2870APCard.dat"
#endif /* MULTIPLE_CARD_SUPPORT */
#endif /* RTMP_MAC_USB */

#ifdef RTMP_RBUS_SUPPORT
/* This used for rbus-based chip, maybe we can integrate it together. */
#define RTMP_FIRMWARE_FILE_NAME		"/etc_ro/Wireless/RT2860AP/RT2860AP.bin"
#define PROFILE_PATH			"/etc/Wireless/RT2860i.dat"
#define AP_PROFILE_PATH_RBUS		"/etc/Wireless/RT2860/RT2860.dat"
#define RT2880_AP_DRIVER_VERSION	"2.6.0.0"
#endif /* RTMP_RBUS_SUPPORT */
#endif /* CONFIG_AP_SUPPORT */


#ifdef CONFIG_STA_SUPPORT
#ifdef RTMP_MAC_PCI
#define STA_PROFILE_PATH			"/etc/Wireless/RT2860STA/RT2860STA.dat"
#define STA_DRIVER_VERSION			"2.2.0.0"
#ifdef MULTIPLE_CARD_SUPPORT
#define CARD_INFO_PATH			"/etc/Wireless/RT2860STA/RT2860STACard.dat"
#endif /* MULTIPLE_CARD_SUPPORT */
#endif /* RTMP_MAC_PCI */

#ifdef RTMP_MAC_USB
#define STA_PROFILE_PATH			"/etc/Wireless/RT2870STA/RT2870STA.dat"
#define STA_DRIVER_VERSION			"2.3.0.0"
#ifdef MULTIPLE_CARD_SUPPORT
#define CARD_INFO_PATH			"/etc/Wireless/RT2870STA/RT2870STACard.dat"
#endif /* MULTIPLE_CARD_SUPPORT */
#endif /* RTMP_MAC_USB */

#ifdef RTMP_RBUS_SUPPORT
#define RTMP_FIRMWARE_FILE_NAME		"/etc_ro/Wireless/RT2860STA/RT2860STA.bin"
#define PROFILE_PATH			"/etc/Wireless/RT2860i.dat"
#define STA_PROFILE_PATH_RBUS	"/etc/Wireless/RT2860/RT2860.dat"
#define RT2880_STA_DRIVER_VERSION		"1.0.0.0"
#endif /* RTMP_RBUS_SUPPORT */

extern	const struct iw_handler_def rt28xx_iw_handler_def;
#endif /* CONFIG_STA_SUPPORT */

#ifdef CONFIG_APSTA_MIXED_SUPPORT
extern	const struct iw_handler_def rt28xx_ap_iw_handler_def;
#endif /* CONFIG_APSTA_MIXED_SUPPORT */

/***********************************************************************************
 *	Compiler related definitions
 ***********************************************************************************/
#undef __inline
#define __inline		static inline
#define IN
#define OUT
#define INOUT
#define NDIS_STATUS		INT


/***********************************************************************************
 *	OS Specific definitions and data structures
 ***********************************************************************************/
#define RTMP_INTERRUPT_INIC  CYGNUM_HAL_INTERRUPT_IP5
typedef unsigned int		ra_dma_addr_t;
typedef struct eth_drv_sc	*PNET_DEV;
typedef void				*PNDIS_PACKET;
typedef char				NDIS_PACKET;
typedef PNDIS_PACKET		*PPNDIS_PACKET;
typedef	ra_dma_addr_t			NDIS_PHYSICAL_ADDRESS;
typedef	ra_dma_addr_t			*PNDIS_PHYSICAL_ADDRESS;
typedef void				*NDIS_HANDLE;
typedef char 				*PNDIS_BUFFER;

typedef int 				RTMP_OS_PID;
typedef cyg_sem_t	        RTMP_OS_SEM;

#ifdef RTMP_MAC_PCI
#ifndef PCI_DEVICE
#define PCI_DEVICE(vend,dev) \
	.vendor = (vend), .device = (dev), \
	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
#endif /* PCI_DEVICE */
#endif /* RTMP_MAC_PCI */

#define RT_MOD_DEC_USE_COUNT()	do{}while(0)
#define RT_MOD_INC_USE_COUNT()	do{}while(0)

#define RTMP_INC_REF(_A)		0
#define RTMP_DEC_REF(_A)		0
#define RTMP_GET_REF(_A)		0

#define isxdigit(_char)  \
	(('0' <= (_char) && (_char) <= '9') ||\
	 ('a' <= (_char) && (_char) <= 'f') || \
	 ('A' <= (_char) && (_char) <= 'F') \
	)

#define isdigit(ch) \
	((ch >= '0') && (ch <= '9'))


#define tolower(ch) ((ch >= 'A' && (ch) <= 'Z') ? (ch) - ('A' - 'a') : (ch))

#define toupper(ch) ((ch >= 'a' && (ch) <= 'z') ? (ch) + ('A' - 'a') : (ch))

#define IWEVCUSTOM	0x8C02		/* Driver specific ascii string */
#define IW_PRIV_SIZE_MASK       0x07FF  /* Max number of those args */

/* Define Linux ioctl relative structure, keep only necessary things */
struct iw_point
{
	PVOID		pointer;
	USHORT		length;
	USHORT		flags;
};
	
union iwreq_data
{
	struct iw_point data;
};

struct iwreq 
{
	union
	{
		char    ifrn_name[IFNAMSIZ];    /* if name, e.g. "eth0" */
	} ifr_ifrn;
	
	union   iwreq_data      u;
};

/* Maximum size of returned data, sync with wireless.h in Linux */
#define IW_SCAN_MAX_DATA        4096    /* In bytes */

/*
 *	Data unalignment handling related definitions and data structure
 */
extern void bad_unaligned_access_length(void) __attribute__((noreturn));

struct UINT64 { UINT64 x __attribute__((packed)); };
struct UINT32 { UINT32 x __attribute__((packed)); };
struct UINT16 { UINT16 x __attribute__((packed)); };

/*
 * Elemental unaligned loads 
 */
static inline UINT64 __uldq(const UINT64 *addr)
{
	const struct UINT64 *ptr = (const struct UINT64 *) addr;
	return ptr->x;
}

static inline UINT32 __uldl(const UINT32 *addr)
{
	const struct UINT32 *ptr = (const struct UINT32 *) addr;
	return ptr->x;
}



/*
 * Elemental unaligned stores 
 */
static inline void __ustq(UINT64 val, UINT64 *addr)
{
	struct UINT64 *ptr = (struct UINT64 *) addr;
	ptr->x = val;
}

static inline void __ustl(UINT32 val, UINT32 *addr)
{
	struct UINT32 *ptr = (struct UINT32 *) addr;
	ptr->x = val;
}

static inline void __ustw(UINT16 val, UINT16 *addr)
{
	struct UINT16 *ptr = (struct UINT16 *) addr;
	ptr->x = val;
}

static inline USHORT __uldw(const UINT16 *addr)
{
	const struct UINT16 *ptr = (const struct UINT16 *) addr;
	return ptr->x;
}

#define __get_unaligned(ptr, size) ({		\
	const void *__gu_p = ptr;		\
	__typeof__(*(ptr)) val;			\
	switch (size) {				\
	case 1:					\
		val = *(const UINT8 *)__gu_p;	\
		break;				\
	case 2:					\
		val = __uldw(__gu_p);		\
		break;				\
	case 4:					\
		val = __uldl(__gu_p);		\
		break;				\
	case 8:					\
		val = __uldq(__gu_p);		\
		break;				\
	default:				\
		bad_unaligned_access_length();	\
	};					\
	val;					\
})

#define __put_unaligned(val, ptr, size)		\
do {						\
	void *__gu_p = ptr;			\
	switch (size) {				\
	case 1:					\
		*(UINT8 *)__gu_p = val;		\
	        break;				\
	case 2:					\
		__ustw(val, __gu_p);		\
		break;				\
	case 4:					\
		__ustl(val, __gu_p);		\
		break;				\
	case 8:					\
		__ustq(val, __gu_p);		\
		break;				\
	default:				\
	    	bad_unaligned_access_length();	\
	};					\
} while(0)

#define get_unaligned(ptr) \
	__get_unaligned((ptr), sizeof(*(ptr)))
#define put_unaligned(x,ptr) \
	__put_unaligned((UINT64)(x), (ptr), sizeof(*(ptr)))


/***********************************************************************************
 *	Network related constant definitions
 ***********************************************************************************/
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif

#define ETH_P_IPV6	0x86DD
#define ETH_P_IP		0x0800

#define ETH_LENGTH_OF_ADDRESS		6

#define NDIS_STATUS_SUCCESS			0x00
#define NDIS_STATUS_FAILURE			0x01
#define NDIS_STATUS_INVALID_DATA		0x02
#define NDIS_STATUS_RESOURCES			0x03

#define NDIS_SET_PACKET_STATUS(_p, _status)		do{} while(0)
#define NdisWriteErrorLogEntry(_a, _b, _c, _d)		do{} while(0)

/* statistics counter */
#define STATS_INC_RX_PACKETS(_pAd, _dev)
#define STATS_INC_TX_PACKETS(_pAd, _dev)

#define STATS_INC_RX_BYTESS(_pAd, _dev, len)
#define STATS_INC_TX_BYTESS(_pAd, _dev, len)

#define STATS_INC_RX_ERRORS(_pAd, _dev)
#define STATS_INC_TX_ERRORS(_pAd, _dev)

#define STATS_INC_RX_DROPPED(_pAd, _dev)
#define STATS_INC_TX_DROPPED(_pAd, _dev)


/***********************************************************************************
 *	Ralink Specific network related constant definitions
 ***********************************************************************************/
#define MIN_NET_DEVICE_FOR_MBSSID		0x00		/*0x00,0x10,0x20,0x30 */
#define MIN_NET_DEVICE_FOR_WDS			0x10		/*0x40,0x50,0x60,0x70 */
#define MIN_NET_DEVICE_FOR_APCLI		0x20
#define MIN_NET_DEVICE_FOR_MESH			0x30
#ifdef CONFIG_STA_SUPPORT
#define MIN_NET_DEVICE_FOR_DLS			0x40
#define MIN_NET_DEVICE_FOR_TDLS			0x80
#ifdef MESH_SUPPORT
#undef MIN_NET_DEVICE_FOR_DLS
#undef MIN_NET_DEVICE_FOR_TDLS
#define MIN_NET_DEVICE_FOR_DLS			(MIN_NET_DEVICE_FOR_MESH + 0x20)
#define MIN_NET_DEVICE_FOR_TDLS			(MIN_NET_DEVICE_FOR_MESH + 0x50)
#endif /* MESH_SUPPORT */
#endif /* CONFIG_STA_SUPPORT */
#define NET_DEVICE_REAL_IDX_MASK		0x0f		/* for each operation mode, we maximum support 15 entities. */

#define RT_DEV_PRIV_FLAGS_GET(__pDev)									\
	((PNET_DEV)pDev)->priv_flags

#define RT_DEV_PRIV_FLAGS_SET(__pDev, __PrivFlags)						\
	((PNET_DEV)pDev)->priv_flags = __PrivFlags

#ifdef CONFIG_STA_SUPPORT
#define NDIS_PACKET_TYPE_DIRECTED		0
#define NDIS_PACKET_TYPE_MULTICAST		1
#define NDIS_PACKET_TYPE_BROADCAST		2
#define NDIS_PACKET_TYPE_ALL_MULTICAST	3
#define NDIS_PACKET_TYPE_PROMISCUOUS	4
#endif /* CONFIG_STA_SUPPORT */


/***********************************************************************************
 *	OS signaling related constant definitions
 ***********************************************************************************/
/*EddyTODO */
#ifdef CONFIG_AP_SUPPORT
#ifdef IAPP_SUPPORT
typedef struct _RT_SIGNAL_STRUC {
	unsigned short					Sequence;
	unsigned char					MacAddr[ETH_LENGTH_OF_ADDRESS];
	unsigned char					CurrAPAddr[ETH_LENGTH_OF_ADDRESS];
	unsigned char					Sig;
} RT_SIGNAL_STRUC, *PRT_SIGNAL_STRUC;

/* definition of signal */
#define	SIG_NONE					0
#define SIG_ASSOCIATION				1
#define SIG_REASSOCIATION			2
#endif /* IAPP_SUPPORT */
#endif /* CONFIG_AP_SUPPORT */

/***********************************************************************************
 *	OS file operation related data structure definitions
 ***********************************************************************************/
/*EddyTODO */
typedef int RTMP_OS_FD;

typedef struct _RTMP_OS_FS_INFO_
{
	int	fsinfo; /* Dummy structure, for cross-platform compatibility */
}RTMP_OS_FS_INFO;

#define IS_FILE_OPEN_ERR(_fd) 	((_fd) < 0)

/***********************************************************************************
 *	OS semaphore related data structure and definitions
 ***********************************************************************************/
typedef cyg_sem_t           NDIS_SPIN_LOCK;

/* */
/*  spin_lock enhanced for Nested spin lock */
/* */
#define NdisAllocateSpinLock(__pReserve, __lock)	\
        cyg_semaphore_init(__lock, 1);

#define NdisFreeSpinLock(__lock)		\
		cyg_semaphore_destroy(__lock)

#define RTMP_Spinlock_LOCK(__lock)	\
		cyg_semaphore_wait(__lock)
		
#define RTMP_Spinlock_UNLOCK(__lock)	\
		cyg_semaphore_post(__lock)


/* sample, use semaphore lock to replace IRQ lock, 2007/11/15 */
#define RTMP_IRQ_LOCK(__lock, __irqflags)	\
{											\
	__irqflags = 0;							\
	cyg_scheduler_lock();				\
}

#define RTMP_IRQ_UNLOCK(__lock, __irqflag)	\
{											\
	cyg_scheduler_unlock();				\
}

#define RTMP_INT_LOCK(__lock, __irqflags)	\
{											\
    HAL_DISABLE_INTERRUPTS(__irqflags);     \
}

#define RTMP_INT_UNLOCK(__lock, __irqflag)	\
{											\
    HAL_RESTORE_INTERRUPTS(__irqflag);      \
}

#define RTMP_SEM_LOCK 			RTMP_Spinlock_LOCK
#define RTMP_SEM_UNLOCK 		RTMP_Spinlock_UNLOCK
#define NdisAcquireSpinLock		RTMP_Spinlock_LOCK
#define NdisReleaseSpinLock		RTMP_Spinlock_UNLOCK

typedef int		wait_queue_head_t;

struct completion
{
	unsigned int done;
	cyg_sem_t    wait;
};

#ifndef wait_event_interruptible_timeout
#define __wait_event_interruptible_timeout(wq, condition, ret) \
do { \
        wait_queue_t __wait; \
        init_waitqueue_entry(&__wait, current); \
        add_wait_queue(&wq, &__wait); \
        for (;;) { \
                set_current_state(TASK_INTERRUPTIBLE); \
                if (condition) \
                        break; \
                if (!signal_pending(current)) { \
                        ret = schedule_timeout(ret); \
                        if (!ret) \
                                break; \
                        continue; \
                } \
                ret = -ERESTARTSYS; \
                break; \
        } \
        current->state = TASK_RUNNING; \
        remove_wait_queue(&wq, &__wait); \
} while (0)

#define wait_event_interruptible_timeout(wq, condition, timeout) \
({ \
        long __ret = timeout; \
        if (!(condition)) \
                __wait_event_interruptible_timeout(wq, condition, __ret); \
        __ret; \
})
#endif

#define RTMP_SEM_EVENT_INIT_LOCKED(_pSema, __pSemaList)	\
	cyg_semaphore_init(_pSema, 1);      \
    cyg_semaphore_wait(_pSema);
	 	
#define RTMP_SEM_EVENT_INIT(_pSema)			\
	cyg_semaphore_init(_pSema, 1);
	
#define RTMP_SEM_EVENT_WAIT(_pSema, _status)	\
	(_status) = ((~cyg_semaphore_wait(_pSema)) & 0x01);

#define RTMP_SEM_EVENT_UP(_pSema)			\
	cyg_semaphore_post(_pSema)

#define RTMP_OS_TASK_WAKE_UP(__pTask)						\
	RTMP_SEM_EVENT_UP(&(pTask)->taskSema);

#define RTMP_OS_TASK_GET(__pTask)							\
	(__pTask)

#define RTCMDUp					OS_RTCMDUp

/***********************************************************************************
 *	OS Memory Access related data structure and definitions
 ***********************************************************************************/
#define GFP_ATOMIC          (0)
#define GFP_DMA             (0)
#define GFP_KERNEL          (0)

#define kmalloc(_size, _flags)	malloc((_size), M_TEMP, M_NOWAIT)
#define kfree(_ptr)             free((_ptr), M_TEMP)

#define vmalloc(_size)          malloc((_size), M_TEMP, M_NOWAIT)
#define vfree(_ptr)             free((_ptr), M_TEMP)

#define MEM_ALLOC_FLAG          (GFP_ATOMIC) /*(GFP_DMA | GFP_ATOMIC) */
#define copy_to_user(x,y,z)     (memcpy(x,y,z) == NULL)
#define copy_from_user(x,y,z)   (memcpy(x,y,z) == NULL)

#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
#define NdisCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length)
#define NdisZeroMemory(Destination, Length)         memset(Destination, 0, Length)
#define NdisFillMemory(Destination, Length, Fill)   memset(Destination, Fill, Length)
#define NdisCmpMemory(Destination, Source, Length)  memcmp(Destination, Source, Length)
#define NdisEqualMemory(Source1, Source2, Length)   (!memcmp(Source1, Source2, Length))
#define RTMPEqualMemory(Source1, Source2, Length)	(!memcmp(Source1, Source2, Length))
#define COPY_MAC_ADDR(Addr1, Addr2)                 memcpy((Addr1), (Addr2), MAC_ADDR_LEN)

#define MlmeAllocateMemory(_pAd, _ppVA)		os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
#define MlmeFreeMemory(_pAd, _pVA)			os_free_mem(_pAd, _pVA)

/***********************************************************************************
 *	OS task related data structure and definitions
 ***********************************************************************************/
/*EddyTODO */
typedef	int	THREAD_PID;
#define RTMP_OS_MGMT_TASK_FLAGS	    0
#define	THREAD_PID_INIT_VALUE	    -1
#define RTMP_GET_OS_PID(_x, _pid)   _x = _pid
#define	GET_PID_NUMBER(_v)	        (_v)
#define CHECK_PID_LEGALITY(_pid)	if ((_pid) >= 0)
#define KILL_THREAD_PID(_A, _B, _C)	kill_proc((_A), (_B), (_C))


typedef void (*PNETFUNC)(ULONG arg1);
typedef INT (*RTMP_OS_TASK_CALLBACK)(IN ULONG Context);

typedef enum _RTMP_NET_TASK_STATUS_
{
	RTMP_NET_TASK_UNKNOWN = 0,
	RTMP_NET_TASK_INITED = 1,
	RTMP_NET_TASK_RUNNING = 2,
	RTMP_NET_TASK_PENDING = 4,
	RTMP_NET_TASK_STOP = 8,
}RTMP_NET_TASK_STATUS;

typedef struct _RTMP_NET_TASK_STRUCT_
{
	PNETFUNC 				funcPtr;
	unsigned long           data;
	RTMP_NET_TASK_STATUS	taskStatus;
	char                    taskName[8];
}RTMP_NET_TASK_STRUCT, *PRTMP_NET_TASK_STRUCT;

#define RTMP_NET_TASK_INIT(_pNetTask, _pFuncPtr, _pData)	\
    do{														\
		(_pNetTask)->funcPtr = (_pFuncPtr);					\
		(_pNetTask)->data = (unsigned int)(_pData);			\
		(_pNetTask)->taskStatus = RTMP_NET_TASK_INITED;		\
	}while(0)

#define tasklet_hi_schedule(_pTask)					                        						\
	do{																		                        \
		cyg_bool_t _retVal = 0;											                        \
		POS_COOKIE pOSCookie = (POS_COOKIE) ((PRTMP_ADAPTER) ((_pTask)->data))->OS_Cookie;             \
        if (pOSCookie->nettask_handle != 0)                                                      \
    		_retVal = cyg_mbox_tryput(pOSCookie->nettask_handle, (void*) (_pTask));                    \
		else 																                        \
        	DBGPRINT_ERR(("NetTask(%s) nettask_handle is null!\n", (char *)((_pTask)->taskName)));	\
		if (_retVal == 1)												                        \
			(_pTask)->taskStatus = RTMP_NET_TASK_PENDING;					                        \
		else																                        \
        	DBGPRINT_ERR(("NetTask(%s) add failed!\n", (char *)((_pTask)->taskName)));	\
	}while(0)

#define RTMP_OS_TASKLET_SCHE(__pTasklet)							\
		tasklet_hi_schedule(__pTasklet)


/***********************************************************************************
 * Timer related definitions and data structures.
 **********************************************************************************/
#define HZ				100
#define OS_HZ			HZ

typedef void (*FUNCPTR)(void *);

struct RtmpEcosTimer
{
	cyg_handle_t	sys_clk;
	cyg_handle_t 	counter_hdl;
	cyg_handle_t	alarm_hdl;
	cyg_alarm	alarm_obj;
	PVOID		data;
};

typedef struct RtmpEcosTimer	NDIS_MINIPORT_TIMER;
typedef struct RtmpEcosTimer	RTMP_OS_TIMER;
typedef void (*TIMER_FUNCTION) (cyg_handle_t alarm, cyg_addrword_t data);

/* The unit of _time is ticks instead of ms. */
#define OS_WAIT(_time) {int value; tsleep((caddr_t)&value, PWAIT, "os_wait", (_time*HZ/1000));}

#define typecheck(type,x) \
({      type __dummy; \
        typeof(x) __dummy2; \
        (void)(&__dummy == &__dummy2); \
        1; \
})
#define time_after(a,b)         \
        (typecheck(unsigned long, a) && \
         typecheck(unsigned long, b) && \
         ((long)(b) - (long)(a) < 0))
#define time_before(a,b)        time_after(b,a)

#define RTMP_TIME_BEFORE(a,b)	time_before(b,a)
#define RTMP_TIME_AFTER(a,b) 	time_after(a, b)
#define mdelay(_us)		        RTMPusecDelay((_us)*1000)

#define ONE_TICK 1

static inline void NdisGetSystemUpTime(ULONG *time)
{
	*time = cyg_current_time();
}

/***********************************************************************************
 * Memory pool & Network packet Structure
 **********************************************************************************/
typedef struct _ECOS_DESC_BUFFER
{
    struct mbuf             *pMBuf;
    PNDIS_PHYSICAL_ADDRESS  PhysicalAddress;
} ECOS_DESC_BUFFER, *PECOS_DESC_BUFFER;

typedef struct _ECOS_PKT_BUFFER
{
	struct _ECOS_PKT_BUFFER *Next;  /* Don't move, for InsertTailQueueAC use */

	/* Internal information */
	INT             MemPoolType;        /* Record from which mempool */
    struct mbuf     *pHeaderMBuf;       /* Pointer to header mbuf */
    struct mbuf     *pDataMBuf;         /* Pointer to data mbuf */

	/* packet information */
	PNET_DEV        net_dev;
	UCHAR           cb[48];

	PUCHAR          pDataPtr;
	LONG            pktLen;
	LONG            ref_cnt;
} ECOS_PKT_BUFFER, *PECOS_PKT_BUFFER;

/***********************************************************************************
 *	OS specific cookie data structure binding to RTMP_ADAPTER
 ***********************************************************************************/
typedef INT (*pWscMsgCallBack)(PUCHAR pData, UINT32	dataLen);

struct os_cookie {
#ifdef RTMP_MAC_PCI
	struct pci_dev          *pci_dev;
	struct pci_dev          *parent_pci_dev;
	USHORT                  DeviceID;
	ra_dma_addr_t              pAd_pa;
#endif /* RTMP_MAC_PCI */

	RTMP_NET_TASK_STRUCT    rx_done_task;
	RTMP_NET_TASK_STRUCT    mgmt_dma_done_task;
	RTMP_NET_TASK_STRUCT    ac0_dma_done_task;
	RTMP_NET_TASK_STRUCT    ac1_dma_done_task;
	RTMP_NET_TASK_STRUCT    ac2_dma_done_task;
	RTMP_NET_TASK_STRUCT    ac3_dma_done_task;
	RTMP_NET_TASK_STRUCT    hcca_dma_done_task;
	RTMP_NET_TASK_STRUCT    tbtt_task;
#ifdef RTMP_MAC_PCI
	RTMP_NET_TASK_STRUCT    fifo_statistic_full_task;
#endif /* RTMP_MAC_PCI */

#ifdef CONFIG_AP_SUPPORT
#ifdef UAPSD_SUPPORT
	RTMP_NET_TASK_STRUCT    uapsd_eosp_sent_task;
#endif /* UAPSD_SUPPORT */

#ifdef DFS_SUPPORT
	RTMP_NET_TASK_STRUCT    pulse_radar_detect_task;
	RTMP_NET_TASK_STRUCT    width_radar_detect_task;
#endif /* DFS_SUPPORT */

#ifdef CARRIER_DETECTION_SUPPORT
	RTMP_NET_TASK_STRUCT    carrier_sense_task;
#endif /* CARRIER_DETECTION_SUPPORT */

#ifdef NEW_DFS
	RTMP_NET_TASK_STRUCT    dfs_task;
#endif /* NEW_DFS */
#endif /* CONFIG_AP_SUPPORT */

	RTMP_OS_PID             apd_pid; /*802.1x daemon pid */
	unsigned long			apd_pid_nr;
#ifdef CONFIG_AP_SUPPORT
#ifdef IAPP_SUPPORT
	RT_SIGNAL_STRUC			RTSignal;
	RTMP_OS_PID             IappPid; /*IAPP daemon pid */
	unsigned long			IappPid_nr;
#endif /* IAPP_SUPPORT */
#endif /* CONFIG_AP_SUPPORT */
#ifdef WAPI_SUPPORT
	RTMP_OS_PID             wapi_pid; /*wapi daemon pid */
	unsigned long			wapi_pid_nr;
#endif /* WAPI_SUPPORT */
	INT						ioctl_if_type;
	INT 					ioctl_if;

    /* message queue handle & box */
    cyg_handle_t            nettask_handle;
    cyg_mbox                nettask_mbox;    

#ifdef WSC_AP_SUPPORT
#ifdef WSC_INCLUDED
	pWscMsgCallBack WscMsgCallBack;
#endif /* WSC_INCLUDED */	
#endif /* WSC_AP_SUPPORT */   
};

typedef struct os_cookie	* POS_COOKIE;



/***********************************************************************************
 *	OS debugging and printing related definitions and data structure
 ***********************************************************************************/
#define printk      diag_printf
#define printf      diag_printf
#define sprintf     diag_sprintf
#define snprintf    diag_snprintf
#define PRINT_MAC(addr)	\
	addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]

#ifdef DBG
extern ULONG RTDebugLevel;
extern ULONG RTDebugFunc;

#ifdef BRANCH_ADV    
extern UCHAR    DbgBuffer[2048];
int printUI(const char *fmt, ...);

#define DBGPRINT_RAW(Level, Fmt)    \
do{                                 \
    if (Level <= RTDebugLevel)      \
    {                               \
        printUI Fmt;                 \
    }                               \
}while(0)
#else /* !BRANCH_ADV */
#define DBGPRINT_RAW(Level, Fmt)    \
do{                                 \
    if (Level <= RTDebugLevel)      \
    {                               \
        printk Fmt;                 \
    }                               \
}while(0)
#endif /* BRANCH_ADV */

#define DBGPRINT(Level, Fmt)    DBGPRINT_RAW(Level, Fmt)

#define DBGPRINT_ERR(Fmt)           \
{                                   \
    printk("ERROR!!! ");            \
    printk Fmt;                     \
}

#define DBGPRINT_S(Status, Fmt)     \
{                                   \
	printk Fmt;                     \
}
#else
#define DBGPRINT(Level, Fmt)
#define DBGPRINT_RAW(Level, Fmt)
#define DBGPRINT_S(Status, Fmt)
#define DBGPRINT_ERR(Fmt)
#endif

#undef  ASSERT
#ifdef VENDOR_FEATURE3_SUPPORT
#define ASSERT(x)
#else
#define ASSERT(x)                                   \
{                                                   \
    if (!(x))                                       \
    {                                               \
	printk("%s", __FILE__);   		                \
	printk(":%d assert " #x "failed\n", __LINE__);  \
    }                                               \
}
#endif /* VENDOR_FEATURE3_SUPPORT */

void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen);

/***********************************************************************************
 * Device DMA Access related definitions and data structures.
 **********************************************************************************/
/* This defines the direction arg to the DMA mapping routines. */
#define PCI_DMA_BIDIRECTIONAL	0
#define PCI_DMA_TODEVICE	    1
#define PCI_DMA_FROMDEVICE	    2
#define PCI_DMA_NONE		    3

ra_dma_addr_t ecos_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction);
#ifdef RTMP_MAC_PCI
#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \
    ecos_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir)

#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) {}
#endif /* RTMP_MAC_PCI */

/*
 * Input: NDIS_PHYSICAL_ADDRESS  PhysicalAddress
 * Input: ULONG  Value
 */
#define RTMP_GetPhysicalAddressLow(PhysicalAddress)         (PhysicalAddress)
#define RTMP_GetPhysicalAddressHigh(PhysicalAddress)        (0)
#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value)  PhysicalAddress = Value;
#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value)


/***********************************************************************************
 * Device Register I/O Access related definitions and data structures.
 **********************************************************************************/
#ifdef RTMP_MAC_PCI
#define RTMP_IO_READ32(_A, _R, _pV)								    \
{																    \
    if ((_A)->bPCIclkOff == FALSE)                                  \
    {                                                               \
		(*_pV = HAL_REG32(((_A)->CSRBaseAddress + (_R))));			\
    }                                                               \
    else															\
		*_pV = 0;													\
}

#define RTMP_IO_FORCE_READ32(_A, _R, _pV)							\
{																	\
	(*_pV = HAL_REG32(((_A)->CSRBaseAddress + (_R))));			    \
}

#define RTMP_IO_READ8(_A, _R, _pV)								    \
{																    \
	(*_pV = HAL_REG8(((_A)->CSRBaseAddress + (_R))));				\
}

#ifndef VENDOR_FEATURE3_SUPPORT
#define RTMP_IO_WRITE32(_A, _R, _V)									\
{																	\
    if ((_A)->bPCIclkOff == FALSE)                                  \
    {                                                               \
	HAL_REG32(((_A)->CSRBaseAddress + (_R))) = (_V);		        \
    }                                                               \
}
#endif /* VENDOR_FEATURE3_SUPPORT */

#define RTMP_IO_FORCE_WRITE32(_A, _R, _V)							\
{																	\
	HAL_REG32(((_A)->CSRBaseAddress + (_R))) = (_V);		        \
}

#ifdef RTMP_RBUS_SUPPORT
#ifdef NEW_DFS
#define RTMP_DFS_IO_READ32(_R, _pV)		\
{										\
	(*_pV = HAL_REG32((_R)));			\
}
#endif /* NEW_DFS */

#define RTMP_DFS_IO_WRITE32(_R, _V)		\
{										\
    HAL_REG32((_R)) = (_V);             \
}
#endif /* RTMP_RBUS_SUPPORT */

#if defined(RALINK_2880) || defined(RALINK_3052) || defined(RALINK_2883) || defined(RTMP_RBUS_SUPPORT)
#define RTMP_IO_WRITE8(_A, _R, _V)                                  \
{                                                                   \
	ULONG Val;                                                      \
	UCHAR _i;                                                       \
	_i = ((_R) & 0x3);                                              \
	Val = HAL_REG32(((_A)->CSRBaseAddress + ((_R) - _i)));          \
	Val = Val & (~(0x000000ff << ((_i)*8)));                        \
	Val = Val | ((ULONG)(_V) << ((_i)*8));                          \
	HAL_REG32(((_A)->CSRBaseAddress + ((_R) - _i))) = (Val);	    \
}
#else
#define RTMP_IO_WRITE8(_A, _R, _V)							        \
{															        \
	HAL_REG8(((_A)->CSRBaseAddress + (_R))) = (_V);	                \
}
#endif /* defined(RT2880) || defined(RT3052) || defined(RT2883)  */

#define RTMP_IO_WRITE16(_A, _R, _V)							        \
{															        \
	HAL_REG16(((_A)->CSRBaseAddress + (_R))) = (_V);                \
}
#endif /* RTMP_MAC_PCI */

#define RTMP_SYS_IO_READ32(_R, _pV)		\
{										\
	(*_pV = HAL_REG32(_R));				\
}

#define RTMP_SYS_IO_WRITE32(_R, _V)		\
{										\
	HAL_REG32((_R)) = (_V);			\
}

/*EddyTODO */
#define EFAULT  -1
#define SIOCIWFIRSTPRIV 0x00


/***********************************************************************************
 *	Network Related data structure and marco definitions
 ***********************************************************************************/
typedef struct _RTMP_VX_INIT_STRING_{
	int phyNum;
	int devNum;
	int infType;
	int irqNum;
	int devType;
	int privSize;
	unsigned int csrAddr;
	unsigned char devName[IFNAMSIZ];
}RTMP_VX_INIT_STRING;

#define PKTSRC_NDIS             0x7f
#define PKTSRC_DRIVER           0x0f

#define RTMP_OS_NETDEV_STATE_RUNNING(_pNetDev)	((_pNetDev)->sc_arpcom.ac_if.if_flags & IFF_UP)
#define RTMP_OS_NETDEV_GET_PRIV(_pNetDev)		((_pNetDev)->driver_private)
#define RTMP_OS_NETDEV_SET_PRIV(_pNetDev, _pPriv)	((_pNetDev)->driver_private = (_pPriv))
#define RTMP_OS_NETDEV_GET_DEVNAME(_pNetDev)	((_pNetDev)->dev_name)
#define RTMP_OS_NETDEV_GET_PHYADDR(_pNetDev)	((_pNetDev)->sc_arpcom.ac_enaddr)
#define RTMP_OS_NETDEV_PHYADDR_LEN(_pNetDev)	(MAC_ADDR_LENGTH)

#define RTMP_OS_NETDEV_START_QUEUE(_pNetDev)	do{}while(0)
#define RTMP_OS_NETDEV_STOP_QUEUE(_pNetDev)		do{}while(0)
#define RTMP_OS_NETDEV_WAKE_QUEUE(_pNetDev)		do{}while(0)
#define RTMP_OS_NETDEV_CARRIER_OFF(_pNetDev)	do{}while(0)


#define QUEUE_ENTRY_TO_PACKET(pEntry)   (PNDIS_PACKET)(pEntry)

#define PACKET_TO_QUEUE_ENTRY(pPacket)  (PQUEUE_ENTRY)(pPacket)


#define GET_SG_LIST_FROM_PACKET(_p, _sc)    rt_get_sg_list_from_packet(_p, _sc)

#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status)    \
    RTMPFreeNdisPacket(_pAd, _pPacket);

/*
 * packet helper
 * 	- convert internal rt packet to os packet or
 *             os packet to rt packet
 */
#define RTPKT_TO_OSPKT(_p)		((PECOS_PKT_BUFFER)(_p))
#define OSPKT_TO_RTPKT(_p)		((PNDIS_PACKET)(_p))

#define GET_OS_PKT_DATAPTR(_pkt)    (RTPKT_TO_OSPKT(_pkt)->pDataPtr)
#define SET_OS_PKT_DATAPTR(_pkt, _dataPtr)	\
		(RTPKT_TO_OSPKT(_pkt)->pDataPtr) = (_dataPtr)
		
#define GET_OS_PKT_LEN(_pkt)        (RTPKT_TO_OSPKT(_pkt)->pktLen)
#define SET_OS_PKT_LEN(_pkt, _len)	\
		(RTPKT_TO_OSPKT(_pkt)->pktLen) = (_len)
		
#define GET_OS_PKT_DATATAIL(_pkt) \
		((RTPKT_TO_OSPKT(_pkt)->pDataPtr) + (RTPKT_TO_OSPKT(_pkt)->pktLen))
#define SET_OS_PKT_DATATAIL(_pkt, _start, _len)	do {}while(0)

#define GET_OS_PKT_NETDEV(_pkt) \
		(RTPKT_TO_OSPKT(_pkt)->net_dev)
#define SET_OS_PKT_NETDEV(_pkt, _pNetDev)	\
		(RTPKT_TO_OSPKT(_pkt)->net_dev) = (PNET_DEV)(_pNetDev)
		
#define GET_OS_PKT_TYPE(_pkt)   (RTPKT_TO_OSPKT(_pkt))

#define GET_OS_PKT_NEXT(_pkt)   do {}while(0)

#define OS_PKT_CLONE(_pAd, _pkt, _src, _flag)		\
	_src = skb_clone(RTPKT_TO_OSPKT(_pkt), _flag);

#define OS_PKT_CLONED(_pkt)		(((RTPKT_TO_OSPKT(_pkt))->ref_cnt) > 1)
#define OS_PKT_COPY(_pkt)		skb_copy(RTPKT_TO_OSPKT(_pkt), GFP_ATOMIC)

#define OS_PKT_TAIL_ADJUST(_pkt, _removedTagLen)								\
	SET_OS_PKT_DATATAIL(_pkt, GET_OS_PKT_DATATAIL(_pkt), (-_removedTagLen));	\
	GET_OS_PKT_LEN(_pkt) -= _removedTagLen;

#define OS_PKT_HEAD_BUF_EXTEND(_pkt, _offset)								\
	skb_push(RTPKT_TO_OSPKT(_pkt), _offset)

#define OS_PKT_TAIL_BUF_EXTEND(_pkt, _Len)									\
	skb_put(RTPKT_TO_OSPKT(_pkt), _Len)

#define OS_PKT_RESERVE(_pkt, _Len)											\
	skb_reserve(RTPKT_TO_OSPKT(_pkt), _Len)

#define GET_OS_PKT_TOTAL_LEN(_pkt)  (RTPKT_TO_OSPKT(_pkt)->pktLen)

#define OS_NTOHS(_Val)  (ntohs(_Val))
#define OS_HTONS(_Val)  (htons(_Val))
#define OS_NTOHL(_Val)  (ntohl(_Val))
#define OS_HTONL(_Val)  (htonl(_Val))

#define CB_OFF  10

#define GET_OS_PKT_CB(_p)						(RTPKT_TO_OSPKT(_p)->cb)

/* User Priority */
#define RTMP_SET_PACKET_UP(_p, _prio)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio)
#define RTMP_GET_PACKET_UP(_p)				(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0])

/* Fragment # */
#define RTMP_SET_PACKET_FRAGMENTS(_p, _num)	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num)
#define RTMP_GET_PACKET_FRAGMENTS(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1])

/* 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too. */
/*(this value also as MAC(on-chip WCID) table index) */
/* 0x80~0xff: TX to a WDS link. b0~6: WDS index */
#define RTMP_SET_PACKET_WCID(_p, _wdsidx)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx)
#define RTMP_GET_PACKET_WCID(_p)          	((UCHAR)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2]))

/* 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet */
#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc)	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc)
#define RTMP_GET_PACKET_SOURCE(_p)       	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3])

/* RTS/CTS-to-self protection method */
#define RTMP_SET_PACKET_RTS(_p, _num)      	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num)
#define RTMP_GET_PACKET_RTS(_p)          	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4])
/* see RTMP_S(G)ET_PACKET_EMACTAB */

/* TX rate index */
#define RTMP_SET_PACKET_TXRATE(_p, _rate)	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate)
#define RTMP_GET_PACKET_TXRATE(_p)		  	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5])

/* From which Interface */
#define RTMP_SET_PACKET_IF(_p, _ifdx)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx)
#define RTMP_GET_PACKET_IF(_p)		  		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6])
#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss)		RTMP_SET_PACKET_IF((_p), (_bss))
#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss)		RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS))
#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx)   	RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI))
#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx)   	RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH))
#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p)			RTMP_GET_PACKET_IF((_p))
#define RTMP_GET_PACKET_NET_DEVICE(_p)					RTMP_GET_PACKET_IF((_p))

#define RTMP_SET_PACKET_MOREDATA(_p, _morebit)	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit)
#define RTMP_GET_PACKET_MOREDATA(_p)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7])
#define GET_PAD_FROM_NET_DEV(_pAd, _net_dev)	(_pAd) = (PRTMP_ADAPTER)(_net_dev)->driver_private;


#ifdef CONFIG_AP_SUPPORT
#ifdef UAPSD_SUPPORT
/* if we queue a U-APSD packet to any software queue, we will set the U-APSD
   flag and its physical queue ID for it */
#define RTMP_SET_PACKET_UAPSD(_p, _flg_uapsd, _que_id) \
                    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9] = ((_flg_uapsd<<7) | _que_id))

#define RTMP_SET_PACKET_QOS_NULL(_p)     (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9] = 0xff)
#define RTMP_GET_PACKET_QOS_NULL(_p)	 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9])
#define RTMP_SET_PACKET_NON_QOS_NULL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9] = 0x00)
#define RTMP_GET_PACKET_UAPSD_Flag(_p)   (((RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9]) & 0x80) >> 7)
#define RTMP_GET_PACKET_UAPSD_QUE_ID(_p) ((RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9]) & 0x7f)

#define RTMP_SET_PACKET_EOSP(_p, _flg)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+10] = _flg)
#define RTMP_GET_PACKET_EOSP(_p)         (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+10])
#endif /* UAPSD_SUPPORT */
#endif /* CONFIG_AP_SUPPORT */


/* */
/*	Sepcific Pakcet Type definition */
/* */
#define RTMP_PACKET_SPECIFIC_CB_OFFSET	11

#define RTMP_PACKET_SPECIFIC_DHCP		0x01
#define RTMP_PACKET_SPECIFIC_EAPOL		0x02
#define RTMP_PACKET_SPECIFIC_IPV4		0x04
#define RTMP_PACKET_SPECIFIC_WAI		0x08
#define RTMP_PACKET_SPECIFIC_VLAN		0x10
#define RTMP_PACKET_SPECIFIC_LLCSNAP	0x20

/*Specific */
#define RTMP_SET_PACKET_SPECIFIC(_p, _flg)  \
    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)

/*DHCP */
#define RTMP_SET_PACKET_DHCP(_p, _flg)   											\
    do{																				\
        if (_flg)																	\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_DHCP);		\
        else																		\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_DHCP);	\
    }while(0)
#define RTMP_GET_PACKET_DHCP(_p)    \
    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP)

/*EAPOL */
#define RTMP_SET_PACKET_EAPOL(_p, _flg)   											\
    do{																				\
        if (_flg)																	\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_EAPOL);	\
        else																		\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_EAPOL);	\
    }while(0)
#define RTMP_GET_PACKET_EAPOL(_p)   \
    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL)

/*WAI */
#define RTMP_SET_PACKET_WAI(_p, _flg)   											\
    do{																				\
        if (_flg)																	\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_WAI);		\
        else																		\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_WAI);	    \
    }while(0)
#define RTMP_GET_PACKET_WAI(_p) \
    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_WAI)

#define RTMP_GET_PACKET_LOWRATE(_p) \
    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & (RTMP_PACKET_SPECIFIC_EAPOL | RTMP_PACKET_SPECIFIC_DHCP | RTMP_PACKET_SPECIFIC_WAI))

/*VLAN */
#define RTMP_SET_PACKET_VLAN(_p, _flg)   											\
    do{																				\
        if (_flg)																	\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_VLAN);		\
        else																		\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_VLAN);	\
    }while(0)
#define RTMP_GET_PACKET_VLAN(_p)    \
    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN)

/*LLC/SNAP */
#define RTMP_SET_PACKET_LLCSNAP(_p, _flg)   										\
    do{																				\
        if (_flg)																	\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_LLCSNAP);	\
        else																		\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (~RTMP_PACKET_SPECIFIC_LLCSNAP);	\
    }while(0)
			
#define RTMP_GET_PACKET_LLCSNAP(_p) \
    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP)

/* IP */
#define RTMP_SET_PACKET_IPV4(_p, _flg)												\
    do{																				\
        if (_flg)																	\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_IPV4);		\
        else																		\
            (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_IPV4);	\
    }while(0)
			
#define RTMP_GET_PACKET_IPV4(_p)    \
    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4)


/* If this flag is set, it indicates that this EAPoL frame MUST be clear. */
#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg)   \
    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg)
#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p) \
    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12])

#ifdef MESH_SUPPORT
#define RTMP_SET_MESH_ROUTE_ID(_p, _flg)    (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+13] = _flg)
#define RTMP_GET_MESH_ROUTE_ID(_p)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+13])
#define RTMP_SET_MESH_SOURCE(_p, _flg)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+14] = _flg)
#define RTMP_GET_MESH_SOURCE(_p)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+14])
#endif /* MESH_SUPPORT */

#ifdef WMM_ACM_SUPPORT
/* total [CB_OFF+15] ~ [CB_OFF+19] 5B */

/* [CB_OFF+15], 1B (4bit vs 4bit, Packet Type vs UP), are reserved for ACM classification use */
/* reference to ACM_PACKET_INFO in acm_extr.h */
/* used in ACMP_DataPacketQueue() */
#define RTMP_GET_PACKET_ACM_PARAM_INFO(_p)		(&(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+15]))

/* [CB_OFF+16] (bit0~2, Phy Mode) ~ [CB_OFF+17] (bit0~7, MCS), 2B, are reserved for minimum tx rate use */
/* used in ACMP_PacketPhyModeMCSCheck() */
#define RTMP_SET_PACKET_ACM_MIN_PHY_MODE(_p, _mode) \
	RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] = (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] & 0xF8) | (_mode & 0x07);
#define RTMP_GET_PACKET_ACM_MIN_PHY_MODE(_p)    \
	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] & 0x07)

#define RTMP_SET_PACKET_ACM_MIN_PHY_MCS(_p, _mcs)	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+17] = _mcs)
#define RTMP_GET_PACKET_ACM_MIN_PHY_MCS(_p)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+17])

/* [CB_OFF+16] (bit4~7), are reserved for TSPEC TSID (0~15) use */
/* used in ACMP_MsduClassify() */
#define RTMP_SET_PACKET_STM_TSID(_p, _tsid) \
	RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] = (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] & 0x0F) | ((_tsid & 0x0F) << 4);
#define RTMP_GET_PACKET_STM_TSID(_p)    \
	((RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] & 0xF0) >> 4)

/* [CB_OFF+18] ~ [CB_OFF+19], 2B, are reserved for tx time use */
/* used in ACMP_DataPacketQueue() */
#define RTMP_SET_PACKET_TX_TIME(_p, _txtime)	(*(UINT16 *)&RTPKT_TO_OSPKT(_p)->cb[CB_OFF+18] = _txtime)
#define RTMP_GET_PACKET_TX_TIME(_p)				(*(UINT16 *)&RTPKT_TO_OSPKT(_p)->cb[CB_OFF+18])
#endif /* WMM_ACM_SUPPORT */

/* use bit3 of cb[CB_OFF+16] */
#ifdef CONFIG_AP_SUPPORT
#define RTMP_SET_PACKET_MGMT_PKT(_p, _flg)  \
        RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] = (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] & 0xF7) | ((_flg & 0x01) << 3);
#define RTMP_GET_PACKET_MGMT_PKT(_p)    \
		((RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] & 0x08) >> 3)

/* use bit0 of cb[CB_OFF+20] */
#define RTMP_SET_PACKET_MGMT_PKT_DATA_QUE(_p, _flg)	\
        RTPKT_TO_OSPKT(_p)->cb[CB_OFF+20] = (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+20] & 0xFE) | (_flg & 0x01);
#define RTMP_GET_PACKET_MGMT_PKT_DATA_QUE(_p)		\
		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+20] & 0x01)
#endif /* CONFIG_AP_SUPPORT */

#define RTMP_SET_PACKET_5VT(_p, _flg)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg)
#define RTMP_GET_PACKET_5VT(_p)         (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22])

#define RTMP_SET_PACKET_PROTOCOL(_p, _protocol) {   \
	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23] = (UINT8)((_protocol) & 0x00ff)); \
	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+24] = (UINT8)(((_protocol) & 0xff00) >> 8)); \
}

#define RTMP_GET_PACKET_PROTOCOL(_p)    \
	((((UINT16)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23])) << 8) \
	| ((UINT16)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+24])))


#ifdef DOT11V_WNM_SUPPORT
#define RTMP_SET_WNM_DMS(_p, _flg)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+29] = _flg)
#define RTMP_GET_WNM_DMS(_p)         (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+29])
#endif /* DOT11V_WNM_SUPPORT */


/***********************************************************************************
 *	Other function prototypes definitions
 ***********************************************************************************/
/*void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time); */
int rt28xx_packet_xmit(void *pPacket);

#ifdef RTMP_RBUS_SUPPORT
#ifndef CONFIG_RALINK_FLASH_API
void FlashWrite(UCHAR * p, ULONG a, ULONG b);
void FlashRead(UCHAR * p, ULONG a, ULONG b);
#endif /* CONFIG_RALINK_FLASH_API */
#endif /* RTMP_RBUS_SUPPORT */

#define RTMP_OS_PKT_INIT(__pRxPacket, __pNetDev, __pData, __DataSize)		\
{																			\
	PNDIS_PACKET __pRxPkt;													\
	__pRxPkt = RTPKT_TO_OSPKT(__pRxPacket);									\
	SET_OS_PKT_NETDEV(__pRxPkt, __pNetDev);									\
	SET_OS_PKT_DATAPTR(__pRxPkt, __pData);									\
	SET_OS_PKT_LEN(__pRxPkt, __DataSize);									\
	SET_OS_PKT_DATATAIL(__pRxPkt, __pData, __DataSize);						\
}

#define RTMP_OS_TASK							OS_TASK

#define RTMP_OS_TASK_DATA_GET(__pTask)						\
	((__pTask)->priv)

#define RTMP_OS_TASK_IS_KILLED(__pTask)						\
	((__pTask)->task_killed)

#define get_unaligned32							get_unaligned
#define get_unalignedlong						get_unaligned

typedef VOID									* PPCI_DEV;

#define KERN_EMERG
#define ate_print printf
#define ATEDBGPRINT DBGPRINT
#ifdef RTMP_MAC_PCI
#define EEPROM_SIZE								0x200
#ifdef CONFIG_AP_SUPPORT
#define EEPROM_BIN_FILE_NAME  "/tgtsvr/pci/e2p_ap.bin"
#endif /* CONFIG_AP_SUPPORT */
#ifdef CONFIG_STA_SUPPORT
#define EEPROM_BIN_FILE_NAME  "/tgtsvr/pci/e2p_sta.bin"
#endif /* CONFIG_STA_SUPPORT */
#endif /* RTMP_MAC_PCI */
#ifdef RTMP_MAC_USB
#define EEPROM_SIZE								0x400
#ifdef CONFIG_AP_SUPPORT
#define EEPROM_BIN_FILE_NAME  "/tgtsvr/usb/e2p_ap.bin"
#endif /* CONFIG_AP_SUPPORT */
#ifdef CONFIG_STA_SUPPORT
#define EEPROM_BIN_FILE_NAME  "/tgtsvr/usb/e2p_sta.bin"
#endif /* CONFIG_STA_SUPPORT */
#endif /* RTMP_MAC_USB */

#define MAX_PACKETS_IN_QUEUE				(128) /*(512)    // to pass WMM A5-WPAPSK */

INT rt28xx_ioctl(
	IN	PNET_DEV	endDev, 
	IN	caddr_t		data,
	IN	int			cmd);

long simple_strtol(const char *cp,char **endp,unsigned int base);
char *strsep(register char **stringp, register const char *delim);
VOID rt2860_interrupt(void *dev_instance);

#ifdef RTMP_MAC_PCI
#define TX_RING_SIZE            32 /*64 */
#define MGMT_RING_SIZE          128
#define RX_RING_SIZE            32 /*64 */
#define MAX_TX_PROCESS          TX_RING_SIZE /*8 */
#define MAX_DMA_DONE_PROCESS    TX_RING_SIZE
#define MAX_TX_DONE_PROCESS     TX_RING_SIZE /*8 */
#define LOCAL_TXBUF_SIZE        2
#endif /* RTMP_MAC_PCI */

typedef VOID					NET_DEV_STATS;

#define APCLI_IF_UP_CHECK(pAd, ifidx) ((pAd)->ApCfg.ApCliTab[(ifidx)].dev->state & ETH_DRV_STATE_ACTIVE)

#define RTMP_THREAD_PID_KILL(__PID)		KILL_THREAD_PID(__PID, SIGTERM, 1)

typedef int atomic_t;
#define RTMP_OS_ATOMIC							atomic_t
#define RTMP_OS_ATMOIC_INIT(__pAtomic, __pAtomicList)

#define OS_PKT_HEAD_BUF_EXTEND(_pkt, _offset)								\
	skb_push(RTPKT_TO_OSPKT(_pkt), _offset)

#include "os/rt_os.h"

#endif /* __RT_ECOS_H__ */
