2008-10-28 21:48:09 +00:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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 "rt_config.h"
ULONG RTDebugLevel = RT_DEBUG_ERROR ;
BUILD_TIMER_FUNCTION ( MlmePeriodicExec ) ;
BUILD_TIMER_FUNCTION ( AsicRxAntEvalTimeout ) ;
BUILD_TIMER_FUNCTION ( APSDPeriodicExec ) ;
BUILD_TIMER_FUNCTION ( AsicRfTuningExec ) ;
2009-04-26 14:06:25 +00:00
# ifdef RT2870
BUILD_TIMER_FUNCTION ( BeaconUpdateExec ) ;
# endif // RT2870 //
2008-10-28 21:48:09 +00:00
BUILD_TIMER_FUNCTION ( BeaconTimeout ) ;
BUILD_TIMER_FUNCTION ( ScanTimeout ) ;
BUILD_TIMER_FUNCTION ( AuthTimeout ) ;
BUILD_TIMER_FUNCTION ( AssocTimeout ) ;
BUILD_TIMER_FUNCTION ( ReassocTimeout ) ;
BUILD_TIMER_FUNCTION ( DisassocTimeout ) ;
BUILD_TIMER_FUNCTION ( LinkDownExec ) ;
BUILD_TIMER_FUNCTION ( StaQuickResponeForRateUpExec ) ;
BUILD_TIMER_FUNCTION ( WpaDisassocApAndBlockAssoc ) ;
2009-04-26 14:06:25 +00:00
# ifdef RT2860
2008-10-28 21:48:09 +00:00
BUILD_TIMER_FUNCTION ( PsPollWakeExec ) ;
BUILD_TIMER_FUNCTION ( RadioOnExec ) ;
2009-04-26 14:06:25 +00:00
# endif
2008-10-28 21:48:09 +00:00
// 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 (
IN NDIS_MINIPORT_TIMER * pTimer ,
IN unsigned long timeout )
{
timeout = ( ( timeout * HZ ) / 1000 ) ;
pTimer - > expires = jiffies + timeout ;
add_timer ( pTimer ) ;
}
/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
VOID RTMP_OS_Init_Timer (
IN PRTMP_ADAPTER pAd ,
IN NDIS_MINIPORT_TIMER * pTimer ,
IN TIMER_FUNCTION function ,
IN PVOID data )
{
init_timer ( pTimer ) ;
pTimer - > data = ( unsigned long ) data ;
pTimer - > function = function ;
}
VOID RTMP_OS_Add_Timer (
IN NDIS_MINIPORT_TIMER * pTimer ,
IN unsigned long timeout )
{
if ( timer_pending ( pTimer ) )
return ;
timeout = ( ( timeout * HZ ) / 1000 ) ;
pTimer - > expires = jiffies + timeout ;
add_timer ( pTimer ) ;
}
VOID RTMP_OS_Mod_Timer (
IN NDIS_MINIPORT_TIMER * pTimer ,
IN unsigned long timeout )
{
timeout = ( ( timeout * HZ ) / 1000 ) ;
mod_timer ( pTimer , jiffies + timeout ) ;
}
VOID RTMP_OS_Del_Timer (
IN NDIS_MINIPORT_TIMER * pTimer ,
OUT BOOLEAN * pCancelled )
{
if ( timer_pending ( pTimer ) )
{
* pCancelled = del_timer_sync ( pTimer ) ;
}
else
{
* pCancelled = TRUE ;
}
}
VOID RTMP_OS_Release_Packet (
IN PRTMP_ADAPTER pAd ,
IN PQUEUE_ENTRY pEntry )
{
//RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
}
// Unify all delay routine by using udelay
VOID RTMPusecDelay (
IN ULONG usec )
{
ULONG 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
NDIS_STATUS os_alloc_mem (
IN PRTMP_ADAPTER pAd ,
OUT PUCHAR * mem ,
IN ULONG size )
{
* mem = ( PUCHAR ) kmalloc ( size , GFP_ATOMIC ) ;
if ( * mem )
return ( NDIS_STATUS_SUCCESS ) ;
else
return ( NDIS_STATUS_FAILURE ) ;
}
// pAd MUST allow to be NULL
NDIS_STATUS os_free_mem (
IN PRTMP_ADAPTER pAd ,
IN PUCHAR mem )
{
ASSERT ( mem ) ;
kfree ( mem ) ;
return ( NDIS_STATUS_SUCCESS ) ;
}
PNDIS_PACKET RTMP_AllocateFragPacketBuffer (
IN PRTMP_ADAPTER pAd ,
IN ULONG 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 ( PNDIS_PACKET ) pkt ;
}
PNDIS_PACKET RTMP_AllocateTxPacketBuffer (
IN PRTMP_ADAPTER pAd ,
IN ULONG Length ,
IN BOOLEAN Cached ,
OUT PVOID * 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 = ( PVOID ) pkt - > data ;
}
else
{
* VirtualAddress = ( PVOID ) NULL ;
}
return ( PNDIS_PACKET ) pkt ;
}
VOID build_tx_packet (
IN PRTMP_ADAPTER pAd ,
IN PNDIS_PACKET pPacket ,
IN PUCHAR pFrame ,
IN ULONG FrameLen )
{
struct sk_buff * pTxPkt ;
ASSERT ( pPacket ) ;
pTxPkt = RTPKT_TO_OSPKT ( pPacket ) ;
NdisMoveMemory ( skb_put ( pTxPkt , FrameLen ) , pFrame , FrameLen ) ;
}
VOID RTMPFreeAdapter (
IN PRTMP_ADAPTER pAd )
{
POS_COOKIE os_cookie ;
int index ;
os_cookie = ( POS_COOKIE ) pAd - > OS_Cookie ;
kfree ( pAd - > BeaconBuf ) ;
NdisFreeSpinLock ( & pAd - > MgmtRingLock ) ;
2009-04-26 14:06:25 +00:00
# ifdef RT2860
2008-10-28 21:48:09 +00:00
NdisFreeSpinLock ( & pAd - > RxRingLock ) ;
2009-04-26 14:06:25 +00:00
# endif
2008-10-28 21:48:09 +00:00
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 ) ;
vfree ( pAd ) ; // pci_free_consistent(os_cookie->pci_dev,sizeof(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 NDIS_PACKET 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 lenght is calculated with 802.3 format packet .
Return Value :
NDIS_STATUS_SUCCESS
NDIS_STATUS_FAILURE
Note :
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
NDIS_STATUS RTMPCloneNdisPacket (
IN PRTMP_ADAPTER pAd ,
IN BOOLEAN pInsAMSDUHdr ,
IN PNDIS_PACKET pInPacket ,
OUT PNDIS_PACKET * 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 ( " ###Clone### \n " ) ;
return NDIS_STATUS_SUCCESS ;
}
// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
NDIS_STATUS RTMPAllocateNdisPacket (
IN PRTMP_ADAPTER pAd ,
OUT PNDIS_PACKET * ppPacket ,
IN PUCHAR pHeader ,
IN UINT HeaderLen ,
IN PUCHAR pData ,
IN UINT DataLen )
{
PNDIS_PACKET pPacket ;
ASSERT ( pData ) ;
ASSERT ( DataLen ) ;
// 1. Allocate a packet
pPacket = ( PNDIS_PACKET * ) dev_alloc_skb ( HeaderLen + DataLen + TXPADDING_SIZE ) ;
if ( pPacket = = NULL )
{
* ppPacket = NULL ;
# ifdef DEBUG
printk ( " RTMPAllocateNdisPacket Fail \n \n " ) ;
# endif
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 ) ;
2009-01-07 22:31:57 +00:00
// printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
2008-10-28 21:48:09 +00:00
* ppPacket = pPacket ;
return NDIS_STATUS_SUCCESS ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Description :
This routine frees a miniport internally allocated NDIS_PACKET and its
corresponding NDIS_BUFFER and allocated memory .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
VOID RTMPFreeNdisPacket (
IN PRTMP_ADAPTER pAd ,
IN PNDIS_PACKET 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
NDIS_STATUS Sniff2BytesFromNdisBuffer (
IN PNDIS_BUFFER pFirstBuffer ,
IN UCHAR DesiredOffset ,
OUT PUCHAR pByte0 ,
OUT PUCHAR pByte1 )
{
* pByte0 = * ( PUCHAR ) ( pFirstBuffer + DesiredOffset ) ;
* pByte1 = * ( PUCHAR ) ( pFirstBuffer + DesiredOffset + 1 ) ;
return NDIS_STATUS_SUCCESS ;
}
void RTMP_QueryPacketInfo (
IN PNDIS_PACKET pPacket ,
OUT PACKET_INFO * pPacketInfo ,
OUT PUCHAR * pSrcBufVA ,
OUT UINT * pSrcBufLen )
{
pPacketInfo - > BufferCount = 1 ;
pPacketInfo - > pFirstBuffer = 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 (
IN PNDIS_PACKET * ppPacket ,
OUT PACKET_INFO * pPacketInfo ,
OUT PUCHAR * pSrcBufVA ,
OUT UINT * pSrcBufLen )
{
PNDIS_PACKET pPacket = NULL ;
if ( * ppPacket )
pPacket = GET_OS_PKT_NEXT ( * ppPacket ) ;
if ( pPacket )
{
pPacketInfo - > BufferCount = 1 ;
pPacketInfo - > pFirstBuffer = 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 ;
}
}
// not yet support MBSS
PNET_DEV get_netdev_from_bssid (
IN PRTMP_ADAPTER pAd ,
IN UCHAR FromWhichBSSID )
{
PNET_DEV dev_p = NULL ;
2009-04-26 14:06:04 +00:00
dev_p = pAd - > net_dev ;
2008-10-28 21:48:09 +00:00
ASSERT ( dev_p ) ;
return dev_p ; /* return one of MBSS */
}
PNDIS_PACKET DuplicatePacket (
IN PRTMP_ADAPTER pAd ,
IN PNDIS_PACKET pPacket ,
IN UCHAR FromWhichBSSID )
{
struct sk_buff * skb ;
PNDIS_PACKET pRetPacket = NULL ;
USHORT DataSize ;
UCHAR * pData ;
DataSize = ( USHORT ) GET_OS_PKT_LEN ( pPacket ) ;
pData = ( PUCHAR ) 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 ;
}
PNDIS_PACKET duplicate_pkt (
IN PRTMP_ADAPTER pAd ,
IN PUCHAR pHeader802_3 ,
IN UINT HdrLen ,
IN PUCHAR pData ,
IN ULONG DataSize ,
IN UCHAR FromWhichBSSID )
{
struct sk_buff * skb ;
PNDIS_PACKET pPacket = NULL ;
if ( ( skb = __dev_alloc_skb ( HdrLen + DataSize + 2 , MEM_ALLOC_FLAG ) ) ! = NULL )
{
skb_reserve ( skb , 2 ) ;
NdisMoveMemory ( skb - > tail , pHeader802_3 , HdrLen ) ;
skb_put ( skb , HdrLen ) ;
NdisMoveMemory ( skb - > tail , 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
PNDIS_PACKET duplicate_pkt_with_TKIP_MIC (
IN PRTMP_ADAPTER pAd ,
IN PNDIS_PACKET 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 ) ;
}
PNDIS_PACKET ClonePacket (
IN PRTMP_ADAPTER pAd ,
IN PNDIS_PACKET pPacket ,
IN PUCHAR pData ,
IN ULONG 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 ;
pClonedPkt - > tail = pClonedPkt - > data + pClonedPkt - > len ;
ASSERT ( DataSize < 1530 ) ;
}
return pClonedPkt ;
}
//
// change OS packet DataPtr and DataLen
//
void update_os_packet_info (
IN PRTMP_ADAPTER pAd ,
IN RX_BLK * pRxBlk ,
IN UCHAR 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 ;
pOSPkt - > tail = pOSPkt - > data + pOSPkt - > len ;
}
void wlan_802_11_to_802_3_packet (
IN PRTMP_ADAPTER pAd ,
IN RX_BLK * pRxBlk ,
IN PUCHAR pHeader802_3 ,
IN UCHAR 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 ;
pOSPkt - > tail = pOSPkt - > data + pOSPkt - > len ;
//
// copy 802.3 header
//
//
2009-04-26 14:06:04 +00:00
NdisMoveMemory ( skb_push ( pOSPkt , LENGTH_802_3 ) , pHeader802_3 , LENGTH_802_3 ) ;
}
2008-10-28 21:48:09 +00:00
void announce_802_3_packet (
IN PRTMP_ADAPTER pAd ,
IN PNDIS_PACKET pPacket )
{
struct sk_buff * pRxPkt ;
ASSERT ( pPacket ) ;
pRxPkt = RTPKT_TO_OSPKT ( pPacket ) ;
/* Push up the protocol stack */
# ifdef IKANOS_VX_1X0
IKANOS_DataFrameRx ( pAd , pRxPkt - > dev , pRxPkt , pRxPkt - > len ) ;
# else
pRxPkt - > protocol = eth_type_trans ( pRxPkt , pRxPkt - > dev ) ;
netif_rx ( pRxPkt ) ;
# endif // IKANOS_VX_1X0 //
}
PRTMP_SCATTER_GATHER_LIST
rt_get_sg_list_from_packet ( PNDIS_PACKET pPacket , RTMP_SCATTER_GATHER_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 ( " %s: %p, len = %d \n " , str , pSrcBufVA , SrcBufLen ) ;
for ( x = 0 ; x < SrcBufLen ; x + + )
{
if ( x % 16 = = 0 )
printk ( " 0x%04x : " , x ) ;
printk ( " %02x " , ( ( unsigned char ) pt [ x ] ) ) ;
if ( x % 16 = = 15 ) printk ( " \n " ) ;
}
printk ( " \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 (
IN PRTMP_ADAPTER pAd ,
IN USHORT Event_flag ,
IN PUCHAR pAddr ,
IN UCHAR BssIdx ,
IN CHAR Rssi )
{
# if WIRELESS_EXT >= 15
union iwreq_data wrqu ;
PUCHAR pBuf = NULL , pBufPtr = NULL ;
USHORT event , type , BufLen ;
UCHAR 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 )
{
2009-01-07 22:31:57 +00:00
DBGPRINT ( RT_DEBUG_ERROR , ( " %s : The type(%0x02x) is not valid. \n " , __func__ , type ) ) ;
2008-10-28 21:48:09 +00:00
return ;
}
if ( event > = event_table_len )
{
2009-01-07 22:31:57 +00:00
DBGPRINT ( RT_DEBUG_ERROR , ( " %s : The event(%0x02x) is not valid. \n " , __func__ , event ) ) ;
2008-10-28 21:48:09 +00:00
return ;
}
//Allocate memory and copy the msg.
if ( ( pBuf = kmalloc ( IW_CUSTOM_MAX_LEN , GFP_ATOMIC ) ) ! = NULL )
{
//Prepare the payload
memset ( pBuf , 0 , IW_CUSTOM_MAX_LEN ) ;
pBufPtr = pBuf ;
if ( pAddr )
pBufPtr + = sprintf ( pBufPtr , " (RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) " , PRINT_MAC ( pAddr ) ) ;
else if ( BssIdx < MAX_MBSSID_NUM )
pBufPtr + = sprintf ( pBufPtr , " (RT2860) BSS(ra%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 ;
memset ( & wrqu , 0 , sizeof ( wrqu ) ) ;
wrqu . data . flags = Event_flag ;
wrqu . data . length = BufLen ;
//send wireless event
wireless_send_event ( pAd - > net_dev , IWEVCUSTOM , & wrqu , pBuf ) ;
2009-01-07 22:31:57 +00:00
//DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
2008-10-28 21:48:09 +00:00
kfree ( pBuf ) ;
}
else
2009-01-07 22:31:57 +00:00
DBGPRINT ( RT_DEBUG_ERROR , ( " %s : Can't allocate memory for wireless event. \n " , __func__ ) ) ;
2008-10-28 21:48:09 +00:00
# else
2009-01-07 22:31:57 +00:00
DBGPRINT ( RT_DEBUG_ERROR , ( " %s : The Wireless Extension MUST be v15 or newer. \n " , __func__ ) ) ;
2008-10-28 21:48:09 +00:00
# endif /* WIRELESS_EXT >= 15 */
}
void send_monitor_packets (
IN PRTMP_ADAPTER pAd ,
IN RX_BLK * pRxBlk )
{
struct sk_buff * pOSPkt ;
wlan_ng_prism2_header * ph ;
int rate_index = 0 ;
USHORT header_len = 0 ;
UCHAR 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 )
{
2009-01-07 22:31:57 +00:00
DBGPRINT ( RT_DEBUG_ERROR , ( " %s : Size is too small! (%d) \n " , __func__ , pRxBlk - > DataSize ) ) ;
2008-10-28 21:48:09 +00:00
goto err_free_sk_buff ;
}
if ( pRxBlk - > DataSize + sizeof ( wlan_ng_prism2_header ) > RX_BUFFER_AGGRESIZE )
{
2009-04-26 14:06:25 +00:00
# ifndef RT30xx
2009-02-11 21:18:22 +00:00
DBGPRINT ( RT_DEBUG_ERROR , ( " %s : Size is too large! (%zu) \n " , __func__ , pRxBlk - > DataSize + sizeof ( wlan_ng_prism2_header ) ) ) ;
2009-04-26 14:06:25 +00:00
# endif
# ifdef RT30xx
DBGPRINT ( RT_DEBUG_ERROR , ( " %s : Size is too large! (%d) \n " , __func__ , pRxBlk - > DataSize + sizeof ( wlan_ng_prism2_header ) ) ) ;
# endif
2008-10-28 21:48:09 +00:00
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 contorl field
pRxBlk - > DataSize - = 2 ;
}
// Order bit: A-Ralink or HTC+
if ( pRxBlk - > pHeader - > FC . Order )
{
header_len + = 4 ;
// Data skip HTC contorl 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 ( wlan_ng_prism2_header ) + header_len ) ) {
if ( pskb_expand_head ( pOSPkt , ( sizeof ( wlan_ng_prism2_header ) + header_len ) , 0 , GFP_ATOMIC ) ) {
2009-01-07 22:31:57 +00:00
DBGPRINT ( RT_DEBUG_ERROR , ( " %s : Reallocate header size of sk_buff fail! \n " , __func__ ) ) ;
2008-10-28 21:48:09 +00:00
goto err_free_sk_buff ;
} //end if
} //end if
if ( header_len > 0 )
NdisMoveMemory ( skb_push ( pOSPkt , header_len ) , temp_header , header_len ) ;
ph = ( wlan_ng_prism2_header * ) skb_push ( pOSPkt , sizeof ( wlan_ng_prism2_header ) ) ;
NdisZeroMemory ( ph , sizeof ( wlan_ng_prism2_header ) ) ;
ph - > msgcode = DIDmsg_lnxind_wlansniffrm ;
ph - > msglen = sizeof ( wlan_ng_prism2_header ) ;
strcpy ( ph - > devname , 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 + ( ( UCHAR ) pRxBlk - > pRxWI - > BW * 16 ) + ( ( UCHAR ) pRxBlk - > pRxWI - > ShortGI * 32 ) + ( ( UCHAR ) pRxBlk - > pRxWI - > MCS ) ;
}
else
if ( pRxBlk - > pRxWI - > PHYMODE = = MODE_OFDM )
rate_index = ( UCHAR ) ( pRxBlk - > pRxWI - > MCS ) + 4 ;
else
rate_index = ( UCHAR ) ( 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 ;
}
void rtmp_os_thread_init ( PUCHAR pThreadName , PVOID pNotify )
{
daemonize ( pThreadName /*"%s",pAd->net_dev->name*/ ) ;
allow_signal ( SIGTERM ) ;
allow_signal ( SIGKILL ) ;
current - > flags | = PF_NOFREEZE ;
2009-01-13 18:51:11 +00:00
/* signal that we've started the thread */
2008-10-28 21:48:09 +00:00
complete ( pNotify ) ;
}
void RTMP_IndicateMediaState (
IN PRTMP_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 ) ;
}
}
}