/*
 *************************************************************************
 * Ralink Tech Inc.
 * 5F., No.36, Taiyuan St., Jhubei City,
 * Hsinchu County 302,
 * Taiwan, R.O.C.
 *
 * (c) Copyright 2002-2007, Ralink Technology, Inc.
 *
 * This program is free software; you can redistribute it and/or modify  *
 * it under the terms of the GNU General Public License as published by  *
 * the Free Software Foundation; either version 2 of the License, or     *
 * (at your option) any later version.                                   *
 *                                                                       *
 * This program is distributed in the hope that it will be useful,       *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 * GNU General Public License for more details.                          *
 *                                                                       *
 * You should have received a copy of the GNU General Public License     *
 * along with this program; if not, write to the                         *
 * Free Software Foundation, Inc.,                                       *
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 *                                                                       *
 *************************************************************************
 */

#include <linux/firmware.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include "rt_config.h"

unsigned long RTDebugLevel = RT_DEBUG_ERROR;

/* for wireless system event message */
char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
	/* system status event */
	"had associated successfully",	/* IW_ASSOC_EVENT_FLAG */
	"had disassociated",	/* IW_DISASSOC_EVENT_FLAG */
	"had deauthenticated",	/* IW_DEAUTH_EVENT_FLAG */
	"had been aged-out and disassociated",	/* IW_AGEOUT_EVENT_FLAG */
	"occurred CounterMeasures attack",	/* IW_COUNTER_MEASURES_EVENT_FLAG */
	"occurred replay counter different in Key Handshaking",	/* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
	"occurred RSNIE different in Key Handshaking",	/* IW_RSNIE_DIFF_EVENT_FLAG */
	"occurred MIC different in Key Handshaking",	/* IW_MIC_DIFF_EVENT_FLAG */
	"occurred ICV error in RX",	/* IW_ICV_ERROR_EVENT_FLAG */
	"occurred MIC error in RX",	/* IW_MIC_ERROR_EVENT_FLAG */
	"Group Key Handshaking timeout",	/* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
	"Pairwise Key Handshaking timeout",	/* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
	"RSN IE sanity check failure",	/* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
	"set key done in WPA/WPAPSK",	/* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
	"set key done in WPA2/WPA2PSK",	/* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
	"connects with our wireless client",	/* IW_STA_LINKUP_EVENT_FLAG */
	"disconnects with our wireless client",	/* IW_STA_LINKDOWN_EVENT_FLAG */
	"scan completed"	/* IW_SCAN_COMPLETED_EVENT_FLAG */
	    "scan terminate! Busy! Enqueue fail!"	/* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
};

/* for wireless IDS_spoof_attack event message */
char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
	"detected conflict SSID",	/* IW_CONFLICT_SSID_EVENT_FLAG */
	"detected spoofed association response",	/* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
	"detected spoofed reassociation responses",	/* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
	"detected spoofed probe response",	/* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
	"detected spoofed beacon",	/* IW_SPOOF_BEACON_EVENT_FLAG */
	"detected spoofed disassociation",	/* IW_SPOOF_DISASSOC_EVENT_FLAG */
	"detected spoofed authentication",	/* IW_SPOOF_AUTH_EVENT_FLAG */
	"detected spoofed deauthentication",	/* IW_SPOOF_DEAUTH_EVENT_FLAG */
	"detected spoofed unknown management frame",	/* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
	"detected replay attack"	/* IW_REPLAY_ATTACK_EVENT_FLAG */
};

/* for wireless IDS_flooding_attack event message */
char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
	"detected authentication flooding",	/* IW_FLOOD_AUTH_EVENT_FLAG */
	"detected association request flooding",	/* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
	"detected reassociation request flooding",	/* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
	"detected probe request flooding",	/* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
	"detected disassociation flooding",	/* IW_FLOOD_DISASSOC_EVENT_FLAG */
	"detected deauthentication flooding",	/* IW_FLOOD_DEAUTH_EVENT_FLAG */
	"detected 802.1x eap-request flooding"	/* IW_FLOOD_EAP_REQ_EVENT_FLAG */
};

/* timeout -- ms */
void RTMP_SetPeriodicTimer(struct timer_list *pTimer,
			   IN unsigned long timeout)
{
	timeout = ((timeout * OS_HZ) / 1000);
	pTimer->expires = jiffies + timeout;
	add_timer(pTimer);
}

/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd,
			struct timer_list *pTimer,
			IN TIMER_FUNCTION function, void *data)
{
	init_timer(pTimer);
	pTimer->data = (unsigned long)data;
	pTimer->function = function;
}

void RTMP_OS_Add_Timer(struct timer_list *pTimer,
		       IN unsigned long timeout)
{
	if (timer_pending(pTimer))
		return;

	timeout = ((timeout * OS_HZ) / 1000);
	pTimer->expires = jiffies + timeout;
	add_timer(pTimer);
}

void RTMP_OS_Mod_Timer(struct timer_list *pTimer,
		       IN unsigned long timeout)
{
	timeout = ((timeout * OS_HZ) / 1000);
	mod_timer(pTimer, jiffies + timeout);
}

void RTMP_OS_Del_Timer(struct timer_list *pTimer, OUT BOOLEAN *pCancelled)
{
	if (timer_pending(pTimer)) {
		*pCancelled = del_timer_sync(pTimer);
	} else {
		*pCancelled = TRUE;
	}

}

void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry)
{
	/*RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); */
}

/* Unify all delay routine by using udelay */
void RTMPusecDelay(unsigned long usec)
{
	unsigned long i;

	for (i = 0; i < (usec / 50); i++)
		udelay(50);

	if (usec % 50)
		udelay(usec % 50);
}

void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
{
	time->u.LowPart = jiffies;
}

/* pAd MUST allow to be NULL */
int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size)
{
	*mem = kmalloc(size, GFP_ATOMIC);
	if (*mem)
		return NDIS_STATUS_SUCCESS;
	else
		return NDIS_STATUS_FAILURE;
}

/* pAd MUST allow to be NULL */
int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem)
{

	ASSERT(mem);
	kfree(mem);
	return NDIS_STATUS_SUCCESS;
}

void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size)
{
	struct sk_buff *skb;
	/* Add 2 more bytes for ip header alignment */
	skb = dev_alloc_skb(size + 2);

	return (void *)skb;
}

void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd,
					   unsigned long Length)
{
	struct sk_buff *pkt;

	pkt = dev_alloc_skb(Length);

	if (pkt == NULL) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("can't allocate frag rx %ld size packet\n", Length));
	}

	if (pkt) {
		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
	}

	return (void *)pkt;
}

void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd,
					 unsigned long Length,
					 IN BOOLEAN Cached,
					 void **VirtualAddress)
{
	struct sk_buff *pkt;

	pkt = dev_alloc_skb(Length);

	if (pkt == NULL) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("can't allocate tx %ld size packet\n", Length));
	}

	if (pkt) {
		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
		*VirtualAddress = (void *)pkt->data;
	} else {
		*VirtualAddress = (void *)NULL;
	}

	return (void *)pkt;
}

void build_tx_packet(struct rt_rtmp_adapter *pAd,
		     void *pPacket,
		     u8 *pFrame, unsigned long FrameLen)
{

	struct sk_buff *pTxPkt;

	ASSERT(pPacket);
	pTxPkt = RTPKT_TO_OSPKT(pPacket);

	NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
}

void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)
{
	struct os_cookie *os_cookie;
	int index;

	os_cookie = (struct os_cookie *)pAd->OS_Cookie;

	kfree(pAd->BeaconBuf);

	NdisFreeSpinLock(&pAd->MgmtRingLock);

#ifdef RTMP_MAC_PCI
	NdisFreeSpinLock(&pAd->RxRingLock);
#ifdef RT3090
	NdisFreeSpinLock(&pAd->McuCmdLock);
#endif /* RT3090 // */
#endif /* RTMP_MAC_PCI // */

	for (index = 0; index < NUM_OF_TX_RING; index++) {
		NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
		NdisFreeSpinLock(&pAd->DeQueueLock[index]);
		pAd->DeQueueRunning[index] = FALSE;
	}

	NdisFreeSpinLock(&pAd->irq_lock);

	release_firmware(pAd->firmware);

	vfree(pAd);		/* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
	kfree(os_cookie);
}

BOOLEAN OS_Need_Clone_Packet(void)
{
	return FALSE;
}

/*
	========================================================================

	Routine Description:
		clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
		must have only one NDIS BUFFER
		return - byte copied. 0 means can't create NDIS PACKET
		NOTE: internally created char should be destroyed by RTMPFreeNdisPacket

	Arguments:
		pAd 	Pointer to our adapter
		pInsAMSDUHdr	EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
		*pSrcTotalLen			return total packet length. This length is calculated with 802.3 format packet.

	Return Value:
		NDIS_STATUS_SUCCESS
		NDIS_STATUS_FAILURE

	Note:

	========================================================================
*/
int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
				IN BOOLEAN pInsAMSDUHdr,
				void *pInPacket,
				void **ppOutPacket)
{

	struct sk_buff *pkt;

	ASSERT(pInPacket);
	ASSERT(ppOutPacket);

	/* 1. Allocate a packet */
	pkt = dev_alloc_skb(2048);

	if (pkt == NULL) {
		return NDIS_STATUS_FAILURE;
	}

	skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
	NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket),
		       GET_OS_PKT_LEN(pInPacket));
	*ppOutPacket = OSPKT_TO_RTPKT(pkt);

	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);

	printk(KERN_DEBUG "###Clone###\n");

	return NDIS_STATUS_SUCCESS;
}

/* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */
int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
				   void **ppPacket,
				   u8 *pHeader,
				   u32 HeaderLen,
				   u8 *pData, u32 DataLen)
{
	void *pPacket;
	ASSERT(pData);
	ASSERT(DataLen);

	/* 1. Allocate a packet */
	pPacket =
	    (void **) dev_alloc_skb(HeaderLen + DataLen +
					   RTMP_PKT_TAIL_PADDING);
	if (pPacket == NULL) {
		*ppPacket = NULL;
		pr_devel("RTMPAllocateNdisPacket Fail\n");

		return NDIS_STATUS_FAILURE;
	}
	/* 2. clone the frame content */
	if (HeaderLen > 0)
		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
	if (DataLen > 0)
		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData,
			       DataLen);

	/* 3. update length of packet */
	skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen + DataLen);

	RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
/*      printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); */
	*ppPacket = pPacket;
	return NDIS_STATUS_SUCCESS;
}

/*
  ========================================================================
  Description:
	This routine frees a miniport internally allocated char and its
	corresponding NDIS_BUFFER and allocated memory.
  ========================================================================
*/
void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
{
	dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
}

/* IRQL = DISPATCH_LEVEL */
/* NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same */
/*                       scatter gather buffer */
int Sniff2BytesFromNdisBuffer(char *pFirstBuffer,
				      u8 DesiredOffset,
				      u8 *pByte0, u8 *pByte1)
{
	*pByte0 = *(u8 *)(pFirstBuffer + DesiredOffset);
	*pByte1 = *(u8 *)(pFirstBuffer + DesiredOffset + 1);

	return NDIS_STATUS_SUCCESS;
}

void RTMP_QueryPacketInfo(void *pPacket,
			  struct rt_packet_info *pPacketInfo,
			  u8 **pSrcBufVA, u32 * pSrcBufLen)
{
	pPacketInfo->BufferCount = 1;
	pPacketInfo->pFirstBuffer = (char *)GET_OS_PKT_DATAPTR(pPacket);
	pPacketInfo->PhysicalBufferCount = 1;
	pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);

	*pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
	*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
}

void RTMP_QueryNextPacketInfo(void **ppPacket,
			      struct rt_packet_info *pPacketInfo,
			      u8 **pSrcBufVA, u32 * pSrcBufLen)
{
	void *pPacket = NULL;

	if (*ppPacket)
		pPacket = GET_OS_PKT_NEXT(*ppPacket);

	if (pPacket) {
		pPacketInfo->BufferCount = 1;
		pPacketInfo->pFirstBuffer =
		    (char *)GET_OS_PKT_DATAPTR(pPacket);
		pPacketInfo->PhysicalBufferCount = 1;
		pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);

		*pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
		*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
		*ppPacket = GET_OS_PKT_NEXT(pPacket);
	} else {
		pPacketInfo->BufferCount = 0;
		pPacketInfo->pFirstBuffer = NULL;
		pPacketInfo->PhysicalBufferCount = 0;
		pPacketInfo->TotalPacketLength = 0;

		*pSrcBufVA = NULL;
		*pSrcBufLen = 0;
		*ppPacket = NULL;
	}
}

void *DuplicatePacket(struct rt_rtmp_adapter *pAd,
			     void *pPacket, u8 FromWhichBSSID)
{
	struct sk_buff *skb;
	void *pRetPacket = NULL;
	u16 DataSize;
	u8 *pData;

	DataSize = (u16)GET_OS_PKT_LEN(pPacket);
	pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);

	skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
	if (skb) {
		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
		pRetPacket = OSPKT_TO_RTPKT(skb);
	}

	return pRetPacket;

}

void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
			   u8 *pHeader802_3,
			   u32 HdrLen,
			   u8 *pData,
			   unsigned long DataSize, u8 FromWhichBSSID)
{
	struct sk_buff *skb;
	void *pPacket = NULL;

	skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG);
	if (skb != NULL) {
		skb_reserve(skb, 2);
		NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
		skb_put(skb, HdrLen);
		NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
		skb_put(skb, DataSize);
		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
		pPacket = OSPKT_TO_RTPKT(skb);
	}

	return pPacket;
}

#define TKIP_TX_MIC_SIZE		8
void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd,
					 void *pPacket)
{
	struct sk_buff *skb, *newskb;

	skb = RTPKT_TO_OSPKT(pPacket);
	if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) {
		/* alloc a new skb and copy the packet */
		newskb =
		    skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE,
				    GFP_ATOMIC);
		dev_kfree_skb_any(skb);
		if (newskb == NULL) {
			DBGPRINT(RT_DEBUG_ERROR,
				 ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
			return NULL;
		}
		skb = newskb;
	}

	return OSPKT_TO_RTPKT(skb);
}

void *ClonePacket(struct rt_rtmp_adapter *pAd,
			 void *pPacket,
			 u8 *pData, unsigned long DataSize)
{
	struct sk_buff *pRxPkt;
	struct sk_buff *pClonedPkt;

	ASSERT(pPacket);
	pRxPkt = RTPKT_TO_OSPKT(pPacket);

	/* clone the packet */
	pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);

	if (pClonedPkt) {
		/* set the correct dataptr and data len */
		pClonedPkt->dev = pRxPkt->dev;
		pClonedPkt->data = pData;
		pClonedPkt->len = DataSize;
		skb_set_tail_pointer(pClonedPkt, DataSize)
		ASSERT(DataSize < 1530);
	}
	return pClonedPkt;
}

/* */
/* change OS packet DataPtr and DataLen */
/* */
void update_os_packet_info(struct rt_rtmp_adapter *pAd,
			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
{
	struct sk_buff *pOSPkt;

	ASSERT(pRxBlk->pRxPacket);
	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);

	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
	pOSPkt->data = pRxBlk->pData;
	pOSPkt->len = pRxBlk->DataSize;
	skb_set_tail_pointer(pOSPkt, pOSPkt->len);
}

void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
				 struct rt_rx_blk *pRxBlk,
				 u8 *pHeader802_3,
				 u8 FromWhichBSSID)
{
	struct sk_buff *pOSPkt;

	ASSERT(pRxBlk->pRxPacket);
	ASSERT(pHeader802_3);

	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);

	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
	pOSPkt->data = pRxBlk->pData;
	pOSPkt->len = pRxBlk->DataSize;
	skb_set_tail_pointer(pOSPkt, pOSPkt->len);

	/* */
	/* copy 802.3 header */
	/* */
	/* */

	NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3,
		       LENGTH_802_3);
}

void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket)
{

	struct sk_buff *pRxPkt;

	ASSERT(pPacket);

	pRxPkt = RTPKT_TO_OSPKT(pPacket);

	/* Push up the protocol stack */
	pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);

	netif_rx(pRxPkt);
}

struct rt_rtmp_sg_list *
rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg)
{
	sg->NumberOfElements = 1;
	sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
	sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
	return sg;
}

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

	if (RTDebugLevel < RT_DEBUG_TRACE)
		return;

	pt = pSrcBufVA;
	printk(KERN_DEBUG "%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen);
	for (x = 0; x < SrcBufLen; x++) {
		if (x % 16 == 0)
			printk(KERN_DEBUG "0x%04x : ", x);
		printk(KERN_DEBUG "%02x ", ((unsigned char)pt[x]));
		if (x % 16 == 15)
			printk(KERN_DEBUG "\n");
	}
	printk(KERN_DEBUG "\n");
}

/*
	========================================================================

	Routine Description:
		Send log message through wireless event

		Support standard iw_event with IWEVCUSTOM. It is used below.

		iwreq_data.data.flags is used to store event_flag that is defined by user.
		iwreq_data.data.length is the length of the event log.

		The format of the event log is composed of the entry's MAC address and
		the desired log message (refer to pWirelessEventText).

			ex: 11:22:33:44:55:66 has associated successfully

		p.s. The requirement of Wireless Extension is v15 or newer.

	========================================================================
*/
void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd,
			   u16 Event_flag,
			   u8 *pAddr, u8 BssIdx, char Rssi)
{

	/*union         iwreq_data      wrqu; */
	char *pBuf = NULL, *pBufPtr = NULL;
	u16 event, type, BufLen;
	u8 event_table_len = 0;

	type = Event_flag & 0xFF00;
	event = Event_flag & 0x00FF;

	switch (type) {
	case IW_SYS_EVENT_FLAG_START:
		event_table_len = IW_SYS_EVENT_TYPE_NUM;
		break;

	case IW_SPOOF_EVENT_FLAG_START:
		event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
		break;

	case IW_FLOOD_EVENT_FLAG_START:
		event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
		break;
	}

	if (event_table_len == 0) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("%s : The type(%0x02x) is not valid.\n", __func__,
			  type));
		return;
	}

	if (event >= event_table_len) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("%s : The event(%0x02x) is not valid.\n", __func__,
			  event));
		return;
	}
	/*Allocate memory and copy the msg. */
	pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC);
	if (pBuf != NULL) {
		/*Prepare the payload */
		memset(pBuf, 0, IW_CUSTOM_MAX_LEN);

		pBufPtr = pBuf;

		if (pAddr)
			pBufPtr +=
			    sprintf(pBufPtr, "(RT2860) STA(%pM) ", pAddr);
		else if (BssIdx < MAX_MBSSID_NUM)
			pBufPtr +=
			    sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
		else
			pBufPtr += sprintf(pBufPtr, "(RT2860) ");

		if (type == IW_SYS_EVENT_FLAG_START)
			pBufPtr +=
			    sprintf(pBufPtr, "%s",
				    pWirelessSysEventText[event]);
		else if (type == IW_SPOOF_EVENT_FLAG_START)
			pBufPtr +=
			    sprintf(pBufPtr, "%s (RSSI=%d)",
				    pWirelessSpoofEventText[event], Rssi);
		else if (type == IW_FLOOD_EVENT_FLAG_START)
			pBufPtr +=
			    sprintf(pBufPtr, "%s",
				    pWirelessFloodEventText[event]);
		else
			pBufPtr += sprintf(pBufPtr, "%s", "unknown event");

		pBufPtr[pBufPtr - pBuf] = '\0';
		BufLen = pBufPtr - pBuf;

		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL,
					(u8 *)pBuf, BufLen);
		/*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */

		kfree(pBuf);
	} else
		DBGPRINT(RT_DEBUG_ERROR,
			 ("%s : Can't allocate memory for wireless event.\n",
			  __func__));
}

void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
{
	struct sk_buff *pOSPkt;
	struct rt_wlan_ng_prism2_header *ph;
	int rate_index = 0;
	u16 header_len = 0;
	u8 temp_header[40] = { 0 };

	u_int32_t ralinkrate[256] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 109, 110, 111, 112, 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, 27, 54, 81, 108, 162, 216, 243, 270,	/* Last 38 */
		54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115,
		    130, 144, 29, 59, 87, 115, 173, 230, 260, 288, 30, 60, 90,
		    120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
		    600, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
		11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
		    27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
		    42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
		    57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
		    72, 73, 74, 75, 76, 77, 78, 79, 80
	};

	ASSERT(pRxBlk->pRxPacket);
	if (pRxBlk->DataSize < 10) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("%s : Size is too small! (%d)\n", __func__,
			  pRxBlk->DataSize));
		goto err_free_sk_buff;
	}

	if (pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header) >
	    RX_BUFFER_AGGRESIZE) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("%s : Size is too large! (%zu)\n", __func__,
			  pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header)));
		goto err_free_sk_buff;
	}

	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
	pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
	if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) {
		pRxBlk->DataSize -= LENGTH_802_11;
		if ((pRxBlk->pHeader->FC.ToDs == 1) &&
		    (pRxBlk->pHeader->FC.FrDs == 1))
			header_len = LENGTH_802_11_WITH_ADDR4;
		else
			header_len = LENGTH_802_11;

		/* QOS */
		if (pRxBlk->pHeader->FC.SubType & 0x08) {
			header_len += 2;
			/* Data skip QOS control field */
			pRxBlk->DataSize -= 2;
		}
		/* Order bit: A-Ralink or HTC+ */
		if (pRxBlk->pHeader->FC.Order) {
			header_len += 4;
			/* Data skip HTC control field */
			pRxBlk->DataSize -= 4;
		}
		/* Copy Header */
		if (header_len <= 40)
			NdisMoveMemory(temp_header, pRxBlk->pData, header_len);

		/* skip HW padding */
		if (pRxBlk->RxD.L2PAD)
			pRxBlk->pData += (header_len + 2);
		else
			pRxBlk->pData += header_len;
	}			/*end if */

	if (pRxBlk->DataSize < pOSPkt->len) {
		skb_trim(pOSPkt, pRxBlk->DataSize);
	} else {
		skb_put(pOSPkt, (pRxBlk->DataSize - pOSPkt->len));
	}			/*end if */

	if ((pRxBlk->pData - pOSPkt->data) > 0) {
		skb_put(pOSPkt, (pRxBlk->pData - pOSPkt->data));
		skb_pull(pOSPkt, (pRxBlk->pData - pOSPkt->data));
	}			/*end if */

	if (skb_headroom(pOSPkt) < (sizeof(struct rt_wlan_ng_prism2_header) + header_len)) {
		if (pskb_expand_head
		    (pOSPkt, (sizeof(struct rt_wlan_ng_prism2_header) + header_len), 0,
		     GFP_ATOMIC)) {
			DBGPRINT(RT_DEBUG_ERROR,
				 ("%s : Reallocate header size of sk_buff fail!\n",
				  __func__));
			goto err_free_sk_buff;
		}		/*end if */
	}			/*end if */

	if (header_len > 0)
		NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header,
			       header_len);

	ph = (struct rt_wlan_ng_prism2_header *)skb_push(pOSPkt,
						sizeof(struct rt_wlan_ng_prism2_header));
	NdisZeroMemory(ph, sizeof(struct rt_wlan_ng_prism2_header));

	ph->msgcode = DIDmsg_lnxind_wlansniffrm;
	ph->msglen = sizeof(struct rt_wlan_ng_prism2_header);
	strcpy((char *)ph->devname, (char *)pAd->net_dev->name);

	ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
	ph->hosttime.status = 0;
	ph->hosttime.len = 4;
	ph->hosttime.data = jiffies;

	ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
	ph->mactime.status = 0;
	ph->mactime.len = 0;
	ph->mactime.data = 0;

	ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
	ph->istx.status = 0;
	ph->istx.len = 0;
	ph->istx.data = 0;

	ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
	ph->channel.status = 0;
	ph->channel.len = 4;

	ph->channel.data = (u_int32_t) pAd->CommonCfg.Channel;

	ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
	ph->rssi.status = 0;
	ph->rssi.len = 4;
	ph->rssi.data =
	    (u_int32_t) RTMPMaxRssi(pAd,
				    ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0,
						  RSSI_0), ConvertToRssi(pAd,
									 pRxBlk->
									 pRxWI->
									 RSSI1,
									 RSSI_1),
				    ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2,
						  RSSI_2));

	ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
	ph->signal.status = 0;
	ph->signal.len = 4;
	ph->signal.data = 0;	/*rssi + noise; */

	ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
	ph->noise.status = 0;
	ph->noise.len = 4;
	ph->noise.data = 0;

	if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) {
		rate_index =
		    16 + ((u8)pRxBlk->pRxWI->BW * 16) +
		    ((u8)pRxBlk->pRxWI->ShortGI * 32) +
		    ((u8)pRxBlk->pRxWI->MCS);
	} else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
		rate_index = (u8)(pRxBlk->pRxWI->MCS) + 4;
	else
		rate_index = (u8)(pRxBlk->pRxWI->MCS);
	if (rate_index < 0)
		rate_index = 0;
	if (rate_index > 255)
		rate_index = 255;

	ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
	ph->rate.status = 0;
	ph->rate.len = 4;
	ph->rate.data = ralinkrate[rate_index];

	ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
	ph->frmlen.status = 0;
	ph->frmlen.len = 4;
	ph->frmlen.data = (u_int32_t) pRxBlk->DataSize;

	pOSPkt->pkt_type = PACKET_OTHERHOST;
	pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
	pOSPkt->ip_summed = CHECKSUM_NONE;
	netif_rx(pOSPkt);

	return;

err_free_sk_buff:
	RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
	return;

}

/*******************************************************************************

	Device IRQ related functions.

 *******************************************************************************/
int RtmpOSIRQRequest(struct net_device *pNetDev)
{
#ifdef RTMP_PCI_SUPPORT
	struct net_device *net_dev = pNetDev;
	struct rt_rtmp_adapter *pAd = NULL;
	int retval = 0;

	GET_PAD_FROM_NET_DEV(pAd, pNetDev);

	ASSERT(pAd);

	if (pAd->infType == RTMP_DEV_INF_PCI) {
		struct os_cookie *_pObj = (struct os_cookie *)(pAd->OS_Cookie);
		RTMP_MSI_ENABLE(pAd);
		retval =
		    request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ,
				(net_dev)->name, (net_dev));
		if (retval != 0)
			printk(KERN_ERR "rt2860: request_irq  ERROR(%d)\n", retval);
	}

	return retval;
#else
	return 0;
#endif
}

int RtmpOSIRQRelease(struct net_device *pNetDev)
{
	struct net_device *net_dev = pNetDev;
	struct rt_rtmp_adapter *pAd = NULL;

	GET_PAD_FROM_NET_DEV(pAd, net_dev);

	ASSERT(pAd);

#ifdef RTMP_PCI_SUPPORT
	if (pAd->infType == RTMP_DEV_INF_PCI) {
		struct os_cookie *pObj = (struct os_cookie *)(pAd->OS_Cookie);
		synchronize_irq(pObj->pci_dev->irq);
		free_irq(pObj->pci_dev->irq, (net_dev));
		RTMP_MSI_DISABLE(pAd);
	}
#endif /* RTMP_PCI_SUPPORT // */

	return 0;
}

/*******************************************************************************

	File open/close related functions.

 *******************************************************************************/
struct file *RtmpOSFileOpen(char *pPath, int flag, int mode)
{
	struct file *filePtr;

	filePtr = filp_open(pPath, flag, 0);
	if (IS_ERR(filePtr)) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("%s(): Error %ld opening %s\n", __func__,
			  -PTR_ERR(filePtr), pPath));
	}

	return (struct file *)filePtr;
}

int RtmpOSFileClose(struct file *osfd)
{
	filp_close(osfd, NULL);
	return 0;
}

void RtmpOSFileSeek(struct file *osfd, int offset)
{
	osfd->f_pos = offset;
}

int RtmpOSFileRead(struct file *osfd, char *pDataPtr, int readLen)
{
	/* The object must have a read method */
	if (osfd->f_op && osfd->f_op->read) {
		return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
	} else {
		DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
		return -1;
	}
}

int RtmpOSFileWrite(struct file *osfd, char *pDataPtr, int writeLen)
{
	return osfd->f_op->write(osfd, pDataPtr, (size_t) writeLen,
				 &osfd->f_pos);
}

/*******************************************************************************

	Task create/management/kill related functions.

 *******************************************************************************/
int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask)
{
	struct rt_rtmp_adapter *pAd;
	int ret = NDIS_STATUS_FAILURE;

	pAd = pTask->priv;

#ifdef KTHREAD_SUPPORT
	if (pTask->kthread_task) {
		kthread_stop(pTask->kthread_task);
		ret = NDIS_STATUS_SUCCESS;
	}
#else
	CHECK_PID_LEGALITY(pTask->taskPID) {
		printk(KERN_INFO "Terminate the task(%s) with pid(%d)!\n",
		       pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
		mb();
		pTask->task_killed = 1;
		mb();
		ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
		if (ret) {
			printk(KERN_WARNING
			       "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
			       pTask->taskName, GET_PID_NUMBER(pTask->taskPID),
			       ret);
		} else {
			wait_for_completion(&pTask->taskComplete);
			pTask->taskPID = THREAD_PID_INIT_VALUE;
			pTask->task_killed = 0;
			ret = NDIS_STATUS_SUCCESS;
		}
	}
#endif

	return ret;

}

int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask)
{

#ifndef KTHREAD_SUPPORT
	complete_and_exit(&pTask->taskComplete, 0);
#endif

	return 0;
}

void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask)
{

#ifndef KTHREAD_SUPPORT

	daemonize((char *)&pTask->taskName[0] /*"%s",pAd->net_dev->name */);

	allow_signal(SIGTERM);
	allow_signal(SIGKILL);
	current->flags |= PF_NOFREEZE;

	/* signal that we've started the thread */
	complete(&pTask->taskComplete);

#endif
}

int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
			     IN int (*fn) (void *), IN void *arg)
{
	int status = NDIS_STATUS_SUCCESS;

#ifdef KTHREAD_SUPPORT
	pTask->task_killed = 0;
	pTask->kthread_task = NULL;
	pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
	if (IS_ERR(pTask->kthread_task))
		status = NDIS_STATUS_FAILURE;
#else
	pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
	if (pid_number < 0) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("Attach task(%s) failed!\n", pTask->taskName));
		status = NDIS_STATUS_FAILURE;
	} else {
		pTask->taskPID = GET_PID(pid_number);

		/* Wait for the thread to start */
		wait_for_completion(&pTask->taskComplete);
		status = NDIS_STATUS_SUCCESS;
	}
#endif
	return status;
}

int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
			   char *pTaskName, void * pPriv)
{
	int len;

	ASSERT(pTask);

#ifndef KTHREAD_SUPPORT
	NdisZeroMemory((u8 *)(pTask), sizeof(struct rt_rtmp_os_task));
#endif

	len = strlen(pTaskName);
	len =
	    len >
	    (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len;
	NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
	pTask->priv = pPriv;

#ifndef KTHREAD_SUPPORT
	RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
	pTask->taskPID = THREAD_PID_INIT_VALUE;

	init_completion(&pTask->taskComplete);
#endif

	return NDIS_STATUS_SUCCESS;
}

void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd)
{
	if (pAd->CommonCfg.bWirelessEvent) {
		if (pAd->IndicateMediaState == NdisMediaStateConnected) {
			RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
					      pAd->MacTab.Content[BSSID_WCID].
					      Addr, BSS0, 0);
		} else {
			RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
					      pAd->MacTab.Content[BSSID_WCID].
					      Addr, BSS0, 0);
		}
	}
}

int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
			    u32 eventType,
			    int flags,
			    u8 *pSrcMac,
			    u8 *pData, u32 dataLen)
{
	union iwreq_data wrqu;

	memset(&wrqu, 0, sizeof(wrqu));

	if (flags > -1)
		wrqu.data.flags = flags;

	if (pSrcMac)
		memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);

	if ((pData != NULL) && (dataLen > 0))
		wrqu.data.length = dataLen;

	wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
	return 0;
}

int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr)
{
	struct net_device *net_dev;
	struct rt_rtmp_adapter *pAd;

	net_dev = pNetDev;
	GET_PAD_FROM_NET_DEV(pAd, net_dev);

	/* work-around for SuSE, due to them having their own interface name management system. */
	{
		NdisZeroMemory(pAd->StaCfg.dev_name, 16);
		NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name,
			       strlen(net_dev->name));
	}

	NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);

	return 0;
}

/*
  *	Assign the network dev name for created Ralink WiFi interface.
  */
static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter *pAd,
				   struct net_device *dev,
				   char *pPrefixStr, int devIdx)
{
	struct net_device *existNetDev;
	char suffixName[IFNAMSIZ];
	char desiredName[IFNAMSIZ];
	int ifNameIdx, prefixLen, slotNameLen;
	int Status;

	prefixLen = strlen(pPrefixStr);
	ASSERT((prefixLen < IFNAMSIZ));

	for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) {
		memset(suffixName, 0, IFNAMSIZ);
		memset(desiredName, 0, IFNAMSIZ);
		strncpy(&desiredName[0], pPrefixStr, prefixLen);

		sprintf(suffixName, "%d", ifNameIdx);

		slotNameLen = strlen(suffixName);
		ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
		strcat(desiredName, suffixName);

		existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
		if (existNetDev == NULL)
			break;
		else
			RtmpOSNetDeviceRefPut(existNetDev);
	}

	if (ifNameIdx < 32) {
		strcpy(&dev->name[0], &desiredName[0]);
		Status = NDIS_STATUS_SUCCESS;
	} else {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n",
			  pPrefixStr));
		Status = NDIS_STATUS_FAILURE;
	}

	return Status;
}

void RtmpOSNetDevClose(struct net_device *pNetDev)
{
	dev_close(pNetDev);
}

void RtmpOSNetDevFree(struct net_device *pNetDev)
{
	ASSERT(pNetDev);

	free_netdev(pNetDev);
}

int RtmpOSNetDevAlloc(struct net_device **new_dev_p, u32 privDataSize)
{
	/* assign it as null first. */
	*new_dev_p = NULL;

	DBGPRINT(RT_DEBUG_TRACE,
		 ("Allocate a net device with private data size=%d!\n",
		  privDataSize));
	*new_dev_p = alloc_etherdev(privDataSize);
	if (*new_dev_p)
		return NDIS_STATUS_SUCCESS;
	else
		return NDIS_STATUS_FAILURE;
}

struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName)
{
	struct net_device *pTargetNetDev = NULL;

	pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);

	return pTargetNetDev;
}

void RtmpOSNetDeviceRefPut(struct net_device *pNetDev)
{
	/*
	   every time dev_get_by_name is called, and it has returned a valid struct
	   net_device*, dev_put should be called afterwards, because otherwise the
	   machine hangs when the device is unregistered (since dev->refcnt > 1).
	 */
	if (pNetDev)
		dev_put(pNetDev);
}

int RtmpOSNetDevDestory(struct rt_rtmp_adapter *pAd, struct net_device *pNetDev)
{

	/* TODO: Need to fix this */
	printk("WARNING: This function(%s) not implement yet!\n", __func__);
	return 0;
}

void RtmpOSNetDevDetach(struct net_device *pNetDev)
{
	unregister_netdev(pNetDev);
}

int RtmpOSNetDevAttach(struct net_device *pNetDev,
		       struct rt_rtmp_os_netdev_op_hook *pDevOpHook)
{
	int ret, rtnl_locked = FALSE;

	DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
	/* If we need hook some callback function to the net device structure, now do it. */
	if (pDevOpHook) {
		struct rt_rtmp_adapter *pAd = NULL;

		GET_PAD_FROM_NET_DEV(pAd, pNetDev);

		pNetDev->netdev_ops = pDevOpHook->netdev_ops;

		/* OS specific flags, here we used to indicate if we are virtual interface */
		pNetDev->priv_flags = pDevOpHook->priv_flags;

		if (pAd->OpMode == OPMODE_STA)
			pNetDev->wireless_handlers = &rt28xx_iw_handler_def;

		/* copy the net device mac address to the net_device structure. */
		NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0],
			       MAC_ADDR_LEN);

		rtnl_locked = pDevOpHook->needProtcted;
	}

	if (rtnl_locked)
		ret = register_netdevice(pNetDev);
	else
		ret = register_netdev(pNetDev);

	DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
	if (ret == 0)
		return NDIS_STATUS_SUCCESS;
	else
		return NDIS_STATUS_FAILURE;
}

struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
			    int devType,
			    int devNum,
			    int privMemSize, char *pNamePrefix)
{
	struct net_device *pNetDev = NULL;
	int status;

	/* allocate a new network device */
	status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */);
	if (status != NDIS_STATUS_SUCCESS) {
		/* allocation fail, exit */
		DBGPRINT(RT_DEBUG_ERROR,
			 ("Allocate network device fail (%s)...\n",
			  pNamePrefix));
		return NULL;
	}

	/* find an available interface name, max 32 interfaces */
	status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
	if (status != NDIS_STATUS_SUCCESS) {
		/* error! no available ra name can be used! */
		DBGPRINT(RT_DEBUG_ERROR,
			 ("Assign interface name (%s with suffix 0~32) failed...\n",
			  pNamePrefix));
		RtmpOSNetDevFree(pNetDev);

		return NULL;
	} else {
		DBGPRINT(RT_DEBUG_TRACE,
			 ("The name of the new %s interface is %s...\n",
			  pNamePrefix, pNetDev->name));
	}

	return pNetDev;
}
