2009-06-13 11:38:31 +00:00
/*
* Copyright ( c ) 1996 , 2003 VIA Networking Technologies , Inc .
* All rights reserved .
*
* 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 . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* File : rxtx . c
*
* Purpose : handle WMAC / 802.3 / 802.11 rx & tx functions
*
* Author : Lyndon Chen
*
* Date : May 20 , 2003
*
* Functions :
* s_vGenerateTxParameter - Generate tx dma requried parameter .
* s_vGenerateMACHeader - Translate 802.3 to 802.11 header
* csBeacon_xmit - beacon tx function
* csMgmt_xmit - management tx function
* s_uGetDataDuration - get tx data required duration
* s_uFillDataHead - fulfill tx data duration header
* s_uGetRTSCTSDuration - get rtx / cts requried duration
* s_uGetRTSCTSRsvTime - get rts / cts reserved time
* s_uGetTxRsvTime - get frame reserved time
* s_vFillCTSHead - fulfill CTS ctl header
* s_vFillFragParameter - Set fragement ctl parameter .
* s_vFillRTSHead - fulfill RTS ctl header
* s_vFillTxKey - fulfill tx encrypt key
* s_vSWencryption - Software encrypt header
* vDMA0_tx_80211 - tx 802.11 frame via dma0
* vGenerateFIFOHeader - Generate tx FIFO ctl header
*
* Revision History :
*
*/
# include "device.h"
# include "rxtx.h"
# include "tether.h"
# include "card.h"
# include "bssdb.h"
# include "mac.h"
# include "baseband.h"
# include "michael.h"
# include "tkip.h"
# include "tcrc.h"
# include "wctl.h"
# include "hostap.h"
# include "rf.h"
# include "datarate.h"
# include "usbpipe.h"
# ifdef WPA_SM_Transtatus
# include "iocmd.h"
# endif
2009-08-12 21:54:08 +00:00
2009-06-13 11:38:31 +00:00
/*--------------------- Static Definitions -------------------------*/
/*--------------------- Static Classes ----------------------------*/
/*--------------------- Static Variables --------------------------*/
//static int msglevel =MSG_LEVEL_DEBUG;
static int msglevel = MSG_LEVEL_INFO ;
/*--------------------- Static Functions --------------------------*/
/*--------------------- Static Definitions -------------------------*/
# define CRITICAL_PACKET_LEN 256 // if packet size < 256 -> in-direct send
// packet size >= 256 -> direct send
const WORD wTimeStampOff [ 2 ] [ MAX_RATE ] = {
{ 384 , 288 , 226 , 209 , 54 , 43 , 37 , 31 , 28 , 25 , 24 , 23 } , // Long Preamble
{ 384 , 192 , 130 , 113 , 54 , 43 , 37 , 31 , 28 , 25 , 24 , 23 } , // Short Preamble
} ;
const WORD wFB_Opt0 [ 2 ] [ 5 ] = {
{ RATE_12M , RATE_18M , RATE_24M , RATE_36M , RATE_48M } , // fallback_rate0
{ RATE_12M , RATE_12M , RATE_18M , RATE_24M , RATE_36M } , // fallback_rate1
} ;
const WORD wFB_Opt1 [ 2 ] [ 5 ] = {
{ RATE_12M , RATE_18M , RATE_24M , RATE_24M , RATE_36M } , // fallback_rate0
{ RATE_6M , RATE_6M , RATE_12M , RATE_12M , RATE_18M } , // fallback_rate1
} ;
# define RTSDUR_BB 0
# define RTSDUR_BA 1
# define RTSDUR_AA 2
# define CTSDUR_BA 3
# define RTSDUR_BA_F0 4
# define RTSDUR_AA_F0 5
# define RTSDUR_BA_F1 6
# define RTSDUR_AA_F1 7
# define CTSDUR_BA_F0 8
# define CTSDUR_BA_F1 9
# define DATADUR_B 10
# define DATADUR_A 11
# define DATADUR_A_F0 12
# define DATADUR_A_F1 13
/*--------------------- Static Functions --------------------------*/
static
VOID
s_vSaveTxPktInfo (
IN PSDevice pDevice ,
IN BYTE byPktNum ,
IN PBYTE pbyDestAddr ,
IN WORD wPktLength ,
IN WORD wFIFOCtl
) ;
static
PVOID
s_vGetFreeContext (
PSDevice pDevice
) ;
static
VOID
s_vGenerateTxParameter (
IN PSDevice pDevice ,
IN BYTE byPktType ,
IN WORD wCurrentRate ,
IN PVOID pTxBufHead ,
IN PVOID pvRrvTime ,
IN PVOID pvRTS ,
IN PVOID pvCTS ,
IN UINT cbFrameSize ,
IN BOOL bNeedACK ,
IN UINT uDMAIdx ,
IN PSEthernetHeader psEthHeader
) ;
static
UINT
s_uFillDataHead (
IN PSDevice pDevice ,
IN BYTE byPktType ,
IN WORD wCurrentRate ,
IN PVOID pTxDataHead ,
IN UINT cbFrameLength ,
IN UINT uDMAIdx ,
IN BOOL bNeedAck ,
IN UINT uFragIdx ,
IN UINT cbLastFragmentSize ,
IN UINT uMACfragNum ,
IN BYTE byFBOption
) ;
static
VOID
s_vGenerateMACHeader (
IN PSDevice pDevice ,
IN PBYTE pbyBufferAddr ,
IN WORD wDuration ,
IN PSEthernetHeader psEthHeader ,
IN BOOL bNeedEncrypt ,
IN WORD wFragType ,
IN UINT uDMAIdx ,
IN UINT uFragIdx
) ;
static
VOID
s_vFillTxKey (
IN PSDevice pDevice ,
IN PBYTE pbyBuf ,
IN PBYTE pbyIVHead ,
IN PSKeyItem pTransmitKey ,
IN PBYTE pbyHdrBuf ,
IN WORD wPayloadLen ,
OUT PBYTE pMICHDR
) ;
static
VOID
s_vSWencryption (
IN PSDevice pDevice ,
IN PSKeyItem pTransmitKey ,
IN PBYTE pbyPayloadHead ,
IN WORD wPayloadSize
) ;
static
UINT
s_uGetTxRsvTime (
IN PSDevice pDevice ,
IN BYTE byPktType ,
IN UINT cbFrameLength ,
IN WORD wRate ,
IN BOOL bNeedAck
) ;
static
UINT
s_uGetRTSCTSRsvTime (
IN PSDevice pDevice ,
IN BYTE byRTSRsvType ,
IN BYTE byPktType ,
IN UINT cbFrameLength ,
IN WORD wCurrentRate
) ;
static
VOID
s_vFillCTSHead (
IN PSDevice pDevice ,
IN UINT uDMAIdx ,
IN BYTE byPktType ,
IN PVOID pvCTS ,
IN UINT cbFrameLength ,
IN BOOL bNeedAck ,
IN BOOL bDisCRC ,
IN WORD wCurrentRate ,
IN BYTE byFBOption
) ;
static
VOID
s_vFillRTSHead (
IN PSDevice pDevice ,
IN BYTE byPktType ,
IN PVOID pvRTS ,
IN UINT cbFrameLength ,
IN BOOL bNeedAck ,
IN BOOL bDisCRC ,
IN PSEthernetHeader psEthHeader ,
IN WORD wCurrentRate ,
IN BYTE byFBOption
) ;
static
UINT
s_uGetDataDuration (
IN PSDevice pDevice ,
IN BYTE byDurType ,
IN UINT cbFrameLength ,
IN BYTE byPktType ,
IN WORD wRate ,
IN BOOL bNeedAck ,
IN UINT uFragIdx ,
IN UINT cbLastFragmentSize ,
IN UINT uMACfragNum ,
IN BYTE byFBOption
) ;
static
UINT
s_uGetRTSCTSDuration (
IN PSDevice pDevice ,
IN BYTE byDurType ,
IN UINT cbFrameLength ,
IN BYTE byPktType ,
IN WORD wRate ,
IN BOOL bNeedAck ,
IN BYTE byFBOption
) ;
/*--------------------- Export Variables --------------------------*/
static
PVOID
s_vGetFreeContext (
PSDevice pDevice
)
{
PUSB_SEND_CONTEXT pContext = NULL ;
PUSB_SEND_CONTEXT pReturnContext = NULL ;
UINT ii ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " GetFreeContext() \n " ) ;
for ( ii = 0 ; ii < pDevice - > cbTD ; ii + + ) {
pContext = pDevice - > apTD [ ii ] ;
if ( pContext - > bBoolInUse = = FALSE ) {
pContext - > bBoolInUse = TRUE ;
pReturnContext = pContext ;
break ;
}
}
if ( ii = = pDevice - > cbTD ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " No Free Tx Context \n " ) ;
}
return ( ( PVOID ) pReturnContext ) ;
}
static
VOID
s_vSaveTxPktInfo ( PSDevice pDevice , BYTE byPktNum , PBYTE pbyDestAddr , WORD wPktLength , WORD wFIFOCtl )
{
PSStatCounter pStatistic = & ( pDevice - > scStatistic ) ;
if ( IS_BROADCAST_ADDRESS ( pbyDestAddr ) )
pStatistic - > abyTxPktInfo [ byPktNum ] . byBroadMultiUni = TX_PKT_BROAD ;
else if ( IS_MULTICAST_ADDRESS ( pbyDestAddr ) )
pStatistic - > abyTxPktInfo [ byPktNum ] . byBroadMultiUni = TX_PKT_MULTI ;
else
pStatistic - > abyTxPktInfo [ byPktNum ] . byBroadMultiUni = TX_PKT_UNI ;
pStatistic - > abyTxPktInfo [ byPktNum ] . wLength = wPktLength ;
pStatistic - > abyTxPktInfo [ byPktNum ] . wFIFOCtl = wFIFOCtl ;
2009-08-12 21:54:11 +00:00
memcpy ( pStatistic - > abyTxPktInfo [ byPktNum ] . abyDestAddr , pbyDestAddr , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
static
VOID
s_vFillTxKey (
IN PSDevice pDevice ,
IN PBYTE pbyBuf ,
IN PBYTE pbyIVHead ,
IN PSKeyItem pTransmitKey ,
IN PBYTE pbyHdrBuf ,
IN WORD wPayloadLen ,
OUT PBYTE pMICHDR
)
{
PDWORD pdwIV = ( PDWORD ) pbyIVHead ;
PDWORD pdwExtIV = ( PDWORD ) ( ( PBYTE ) pbyIVHead + 4 ) ;
WORD wValue ;
PS802_11Header pMACHeader = ( PS802_11Header ) pbyHdrBuf ;
DWORD dwRevIVCounter ;
//Fill TXKEY
if ( pTransmitKey = = NULL )
return ;
dwRevIVCounter = cpu_to_le32 ( pDevice - > dwIVCounter ) ;
* pdwIV = pDevice - > dwIVCounter ;
pDevice - > byKeyIndex = pTransmitKey - > dwKeyIndex & 0xf ;
if ( pTransmitKey - > byCipherSuite = = KEY_CTL_WEP ) {
if ( pTransmitKey - > uKeyLength = = WLAN_WEP232_KEYLEN ) {
2009-08-12 21:54:11 +00:00
memcpy ( pDevice - > abyPRNG , ( PBYTE ) & ( dwRevIVCounter ) , 3 ) ;
memcpy ( pDevice - > abyPRNG + 3 , pTransmitKey - > abyKey , pTransmitKey - > uKeyLength ) ;
2009-06-13 11:38:31 +00:00
} else {
2009-08-12 21:54:11 +00:00
memcpy ( pbyBuf , ( PBYTE ) & ( dwRevIVCounter ) , 3 ) ;
memcpy ( pbyBuf + 3 , pTransmitKey - > abyKey , pTransmitKey - > uKeyLength ) ;
2009-06-13 11:38:31 +00:00
if ( pTransmitKey - > uKeyLength = = WLAN_WEP40_KEYLEN ) {
2009-08-12 21:54:11 +00:00
memcpy ( pbyBuf + 8 , ( PBYTE ) & ( dwRevIVCounter ) , 3 ) ;
memcpy ( pbyBuf + 11 , pTransmitKey - > abyKey , pTransmitKey - > uKeyLength ) ;
2009-06-13 11:38:31 +00:00
}
2009-08-12 21:54:11 +00:00
memcpy ( pDevice - > abyPRNG , pbyBuf , 16 ) ;
2009-06-13 11:38:31 +00:00
}
// Append IV after Mac Header
* pdwIV & = WEP_IV_MASK ; //00000000 11111111 11111111 11111111
* pdwIV | = ( pDevice - > byKeyIndex < < 30 ) ;
* pdwIV = cpu_to_le32 ( * pdwIV ) ;
pDevice - > dwIVCounter + + ;
if ( pDevice - > dwIVCounter > WEP_IV_MASK ) {
pDevice - > dwIVCounter = 0 ;
}
} else if ( pTransmitKey - > byCipherSuite = = KEY_CTL_TKIP ) {
pTransmitKey - > wTSC15_0 + + ;
if ( pTransmitKey - > wTSC15_0 = = 0 ) {
pTransmitKey - > dwTSC47_16 + + ;
}
TKIPvMixKey ( pTransmitKey - > abyKey , pDevice - > abyCurrentNetAddr ,
pTransmitKey - > wTSC15_0 , pTransmitKey - > dwTSC47_16 , pDevice - > abyPRNG ) ;
2009-08-12 21:54:11 +00:00
memcpy ( pbyBuf , pDevice - > abyPRNG , 16 ) ;
2009-06-13 11:38:31 +00:00
// Make IV
2009-08-12 21:54:11 +00:00
memcpy ( pdwIV , pDevice - > abyPRNG , 3 ) ;
2009-06-13 11:38:31 +00:00
* ( pbyIVHead + 3 ) = ( BYTE ) ( ( ( pDevice - > byKeyIndex < < 6 ) & 0xc0 ) | 0x20 ) ; // 0x20 is ExtIV
// Append IV&ExtIV after Mac Header
* pdwExtIV = cpu_to_le32 ( pTransmitKey - > dwTSC47_16 ) ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " vFillTxKey()---- pdwExtIV: %lx \n " , * pdwExtIV ) ;
} else if ( pTransmitKey - > byCipherSuite = = KEY_CTL_CCMP ) {
pTransmitKey - > wTSC15_0 + + ;
if ( pTransmitKey - > wTSC15_0 = = 0 ) {
pTransmitKey - > dwTSC47_16 + + ;
}
2009-08-12 21:54:11 +00:00
memcpy ( pbyBuf , pTransmitKey - > abyKey , 16 ) ;
2009-06-13 11:38:31 +00:00
// Make IV
* pdwIV = 0 ;
* ( pbyIVHead + 3 ) = ( BYTE ) ( ( ( pDevice - > byKeyIndex < < 6 ) & 0xc0 ) | 0x20 ) ; // 0x20 is ExtIV
* pdwIV | = cpu_to_le16 ( ( WORD ) ( pTransmitKey - > wTSC15_0 ) ) ;
//Append IV&ExtIV after Mac Header
* pdwExtIV = cpu_to_le32 ( pTransmitKey - > dwTSC47_16 ) ;
//Fill MICHDR0
* pMICHDR = 0x59 ;
* ( ( PBYTE ) ( pMICHDR + 1 ) ) = 0 ; // TxPriority
2009-08-12 21:54:11 +00:00
memcpy ( pMICHDR + 2 , & ( pMACHeader - > abyAddr2 [ 0 ] ) , 6 ) ;
2009-06-13 11:38:31 +00:00
* ( ( PBYTE ) ( pMICHDR + 8 ) ) = HIBYTE ( HIWORD ( pTransmitKey - > dwTSC47_16 ) ) ;
* ( ( PBYTE ) ( pMICHDR + 9 ) ) = LOBYTE ( HIWORD ( pTransmitKey - > dwTSC47_16 ) ) ;
* ( ( PBYTE ) ( pMICHDR + 10 ) ) = HIBYTE ( LOWORD ( pTransmitKey - > dwTSC47_16 ) ) ;
* ( ( PBYTE ) ( pMICHDR + 11 ) ) = LOBYTE ( LOWORD ( pTransmitKey - > dwTSC47_16 ) ) ;
* ( ( PBYTE ) ( pMICHDR + 12 ) ) = HIBYTE ( pTransmitKey - > wTSC15_0 ) ;
* ( ( PBYTE ) ( pMICHDR + 13 ) ) = LOBYTE ( pTransmitKey - > wTSC15_0 ) ;
* ( ( PBYTE ) ( pMICHDR + 14 ) ) = HIBYTE ( wPayloadLen ) ;
* ( ( PBYTE ) ( pMICHDR + 15 ) ) = LOBYTE ( wPayloadLen ) ;
//Fill MICHDR1
* ( ( PBYTE ) ( pMICHDR + 16 ) ) = 0 ; // HLEN[15:8]
if ( pDevice - > bLongHeader ) {
* ( ( PBYTE ) ( pMICHDR + 17 ) ) = 28 ; // HLEN[7:0]
} else {
* ( ( PBYTE ) ( pMICHDR + 17 ) ) = 22 ; // HLEN[7:0]
}
wValue = cpu_to_le16 ( pMACHeader - > wFrameCtl & 0xC78F ) ;
2009-08-12 21:54:11 +00:00
memcpy ( pMICHDR + 18 , ( PBYTE ) & wValue , 2 ) ; // MSKFRACTL
memcpy ( pMICHDR + 20 , & ( pMACHeader - > abyAddr1 [ 0 ] ) , 6 ) ;
memcpy ( pMICHDR + 26 , & ( pMACHeader - > abyAddr2 [ 0 ] ) , 6 ) ;
2009-06-13 11:38:31 +00:00
//Fill MICHDR2
2009-08-12 21:54:11 +00:00
memcpy ( pMICHDR + 32 , & ( pMACHeader - > abyAddr3 [ 0 ] ) , 6 ) ;
2009-06-13 11:38:31 +00:00
wValue = pMACHeader - > wSeqCtl ;
wValue & = 0x000F ;
wValue = cpu_to_le16 ( wValue ) ;
2009-08-12 21:54:11 +00:00
memcpy ( pMICHDR + 38 , ( PBYTE ) & wValue , 2 ) ; // MSKSEQCTL
2009-06-13 11:38:31 +00:00
if ( pDevice - > bLongHeader ) {
2009-08-12 21:54:11 +00:00
memcpy ( pMICHDR + 40 , & ( pMACHeader - > abyAddr4 [ 0 ] ) , 6 ) ;
2009-06-13 11:38:31 +00:00
}
}
}
static
VOID
s_vSWencryption (
IN PSDevice pDevice ,
IN PSKeyItem pTransmitKey ,
IN PBYTE pbyPayloadHead ,
IN WORD wPayloadSize
)
{
UINT cbICVlen = 4 ;
DWORD dwICV = 0xFFFFFFFFL ;
PDWORD pdwICV ;
if ( pTransmitKey = = NULL )
return ;
if ( pTransmitKey - > byCipherSuite = = KEY_CTL_WEP ) {
//=======================================================================
// Append ICV after payload
dwICV = CRCdwGetCrc32Ex ( pbyPayloadHead , wPayloadSize , dwICV ) ; //ICV(Payload)
pdwICV = ( PDWORD ) ( pbyPayloadHead + wPayloadSize ) ;
// finally, we must invert dwCRC to get the correct answer
* pdwICV = cpu_to_le32 ( ~ dwICV ) ;
// RC4 encryption
rc4_init ( & pDevice - > SBox , pDevice - > abyPRNG , pTransmitKey - > uKeyLength + 3 ) ;
rc4_encrypt ( & pDevice - > SBox , pbyPayloadHead , pbyPayloadHead , wPayloadSize + cbICVlen ) ;
//=======================================================================
} else if ( pTransmitKey - > byCipherSuite = = KEY_CTL_TKIP ) {
//=======================================================================
//Append ICV after payload
dwICV = CRCdwGetCrc32Ex ( pbyPayloadHead , wPayloadSize , dwICV ) ; //ICV(Payload)
pdwICV = ( PDWORD ) ( pbyPayloadHead + wPayloadSize ) ;
// finally, we must invert dwCRC to get the correct answer
* pdwICV = cpu_to_le32 ( ~ dwICV ) ;
// RC4 encryption
rc4_init ( & pDevice - > SBox , pDevice - > abyPRNG , TKIP_KEY_LEN ) ;
rc4_encrypt ( & pDevice - > SBox , pbyPayloadHead , pbyPayloadHead , wPayloadSize + cbICVlen ) ;
//=======================================================================
}
}
/*byPktType : PK_TYPE_11A 0
PK_TYPE_11B 1
PK_TYPE_11GB 2
PK_TYPE_11GA 3
*/
static
UINT
s_uGetTxRsvTime (
IN PSDevice pDevice ,
IN BYTE byPktType ,
IN UINT cbFrameLength ,
IN WORD wRate ,
IN BOOL bNeedAck
)
{
UINT uDataTime , uAckTime ;
uDataTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , cbFrameLength , wRate ) ;
if ( byPktType = = PK_TYPE_11B ) { //llb,CCK mode
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , ( WORD ) pDevice - > byTopCCKBasicRate ) ;
} else { //11g 2.4G OFDM mode & 11a 5G OFDM mode
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , ( WORD ) pDevice - > byTopOFDMBasicRate ) ;
}
if ( bNeedAck ) {
return ( uDataTime + pDevice - > uSIFS + uAckTime ) ;
}
else {
return uDataTime ;
}
}
//byFreqType: 0=>5GHZ 1=>2.4GHZ
static
UINT
s_uGetRTSCTSRsvTime (
IN PSDevice pDevice ,
IN BYTE byRTSRsvType ,
IN BYTE byPktType ,
IN UINT cbFrameLength ,
IN WORD wCurrentRate
)
{
UINT uRrvTime , uRTSTime , uCTSTime , uAckTime , uDataTime ;
uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0 ;
uDataTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , cbFrameLength , wCurrentRate ) ;
if ( byRTSRsvType = = 0 ) { //RTSTxRrvTime_bb
uRTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 20 , pDevice - > byTopCCKBasicRate ) ;
uCTSTime = uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopCCKBasicRate ) ;
}
else if ( byRTSRsvType = = 1 ) { //RTSTxRrvTime_ba, only in 2.4GHZ
uRTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 20 , pDevice - > byTopCCKBasicRate ) ;
uCTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopCCKBasicRate ) ;
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
}
else if ( byRTSRsvType = = 2 ) { //RTSTxRrvTime_aa
uRTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 20 , pDevice - > byTopOFDMBasicRate ) ;
uCTSTime = uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
}
else if ( byRTSRsvType = = 3 ) { //CTSTxRrvTime_ba, only in 2.4GHZ
uCTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopCCKBasicRate ) ;
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
uRrvTime = uCTSTime + uAckTime + uDataTime + 2 * pDevice - > uSIFS ;
return uRrvTime ;
}
//RTSRrvTime
uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3 * pDevice - > uSIFS ;
return uRrvTime ;
}
//byFreqType 0: 5GHz, 1:2.4Ghz
static
UINT
s_uGetDataDuration (
IN PSDevice pDevice ,
IN BYTE byDurType ,
IN UINT cbFrameLength ,
IN BYTE byPktType ,
IN WORD wRate ,
IN BOOL bNeedAck ,
IN UINT uFragIdx ,
IN UINT cbLastFragmentSize ,
IN UINT uMACfragNum ,
IN BYTE byFBOption
)
{
BOOL bLastFrag = 0 ;
UINT uAckTime = 0 , uNextPktTime = 0 ;
if ( uFragIdx = = ( uMACfragNum - 1 ) ) {
bLastFrag = 1 ;
}
switch ( byDurType ) {
case DATADUR_B : //DATADUR_B
if ( ( ( uMACfragNum = = 1 ) ) | | ( bLastFrag = = 1 ) ) { //Non Frag or Last Frag
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopCCKBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime ) ;
} else {
return 0 ;
}
}
else { //First Frag or Mid Frag
if ( uFragIdx = = ( uMACfragNum - 2 ) ) {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbLastFragmentSize , wRate , bNeedAck ) ;
} else {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wRate , bNeedAck ) ;
}
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopCCKBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime + uNextPktTime ) ;
} else {
return ( pDevice - > uSIFS + uNextPktTime ) ;
}
}
break ;
case DATADUR_A : //DATADUR_A
if ( ( ( uMACfragNum = = 1 ) ) | | ( bLastFrag = = 1 ) ) { //Non Frag or Last Frag
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime ) ;
} else {
return 0 ;
}
}
else { //First Frag or Mid Frag
if ( uFragIdx = = ( uMACfragNum - 2 ) ) {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbLastFragmentSize , wRate , bNeedAck ) ;
} else {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wRate , bNeedAck ) ;
}
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime + uNextPktTime ) ;
} else {
return ( pDevice - > uSIFS + uNextPktTime ) ;
}
}
break ;
case DATADUR_A_F0 : //DATADUR_A_F0
if ( ( ( uMACfragNum = = 1 ) ) | | ( bLastFrag = = 1 ) ) { //Non Frag or Last Frag
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime ) ;
} else {
return 0 ;
}
}
else { //First Frag or Mid Frag
if ( byFBOption = = AUTO_FB_0 ) {
if ( wRate < RATE_18M )
wRate = RATE_18M ;
else if ( wRate > RATE_54M )
wRate = RATE_54M ;
if ( uFragIdx = = ( uMACfragNum - 2 ) ) {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbLastFragmentSize , wFB_Opt0 [ FB_RATE0 ] [ wRate - RATE_18M ] , bNeedAck ) ;
} else {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt0 [ FB_RATE0 ] [ wRate - RATE_18M ] , bNeedAck ) ;
}
} else { // (byFBOption == AUTO_FB_1)
if ( wRate < RATE_18M )
wRate = RATE_18M ;
else if ( wRate > RATE_54M )
wRate = RATE_54M ;
if ( uFragIdx = = ( uMACfragNum - 2 ) ) {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbLastFragmentSize , wFB_Opt1 [ FB_RATE0 ] [ wRate - RATE_18M ] , bNeedAck ) ;
} else {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt1 [ FB_RATE0 ] [ wRate - RATE_18M ] , bNeedAck ) ;
}
}
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime + uNextPktTime ) ;
} else {
return ( pDevice - > uSIFS + uNextPktTime ) ;
}
}
break ;
case DATADUR_A_F1 : //DATADUR_A_F1
if ( ( ( uMACfragNum = = 1 ) ) | | ( bLastFrag = = 1 ) ) { //Non Frag or Last Frag
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime ) ;
} else {
return 0 ;
}
}
else { //First Frag or Mid Frag
if ( byFBOption = = AUTO_FB_0 ) {
if ( wRate < RATE_18M )
wRate = RATE_18M ;
else if ( wRate > RATE_54M )
wRate = RATE_54M ;
if ( uFragIdx = = ( uMACfragNum - 2 ) ) {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbLastFragmentSize , wFB_Opt0 [ FB_RATE1 ] [ wRate - RATE_18M ] , bNeedAck ) ;
} else {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt0 [ FB_RATE1 ] [ wRate - RATE_18M ] , bNeedAck ) ;
}
} else { // (byFBOption == AUTO_FB_1)
if ( wRate < RATE_18M )
wRate = RATE_18M ;
else if ( wRate > RATE_54M )
wRate = RATE_54M ;
if ( uFragIdx = = ( uMACfragNum - 2 ) ) {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbLastFragmentSize , wFB_Opt1 [ FB_RATE1 ] [ wRate - RATE_18M ] , bNeedAck ) ;
} else {
uNextPktTime = s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt1 [ FB_RATE1 ] [ wRate - RATE_18M ] , bNeedAck ) ;
}
}
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime + uNextPktTime ) ;
} else {
return ( pDevice - > uSIFS + uNextPktTime ) ;
}
}
break ;
default :
break ;
}
ASSERT ( FALSE ) ;
return 0 ;
}
//byFreqType: 0=>5GHZ 1=>2.4GHZ
static
UINT
s_uGetRTSCTSDuration (
IN PSDevice pDevice ,
IN BYTE byDurType ,
IN UINT cbFrameLength ,
IN BYTE byPktType ,
IN WORD wRate ,
IN BOOL bNeedAck ,
IN BYTE byFBOption
)
{
UINT uCTSTime = 0 , uDurTime = 0 ;
switch ( byDurType ) {
case RTSDUR_BB : //RTSDuration_bb
uCTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopCCKBasicRate ) ;
uDurTime = uCTSTime + 2 * pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wRate , bNeedAck ) ;
break ;
case RTSDUR_BA : //RTSDuration_ba
uCTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopCCKBasicRate ) ;
uDurTime = uCTSTime + 2 * pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wRate , bNeedAck ) ;
break ;
case RTSDUR_AA : //RTSDuration_aa
uCTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
uDurTime = uCTSTime + 2 * pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wRate , bNeedAck ) ;
break ;
case CTSDUR_BA : //CTSDuration_ba
uDurTime = pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wRate , bNeedAck ) ;
break ;
case RTSDUR_BA_F0 : //RTSDuration_ba_f0
uCTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopCCKBasicRate ) ;
if ( ( byFBOption = = AUTO_FB_0 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = uCTSTime + 2 * pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt0 [ FB_RATE0 ] [ wRate - RATE_18M ] , bNeedAck ) ;
} else if ( ( byFBOption = = AUTO_FB_1 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = uCTSTime + 2 * pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt1 [ FB_RATE0 ] [ wRate - RATE_18M ] , bNeedAck ) ;
}
break ;
case RTSDUR_AA_F0 : //RTSDuration_aa_f0
uCTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
if ( ( byFBOption = = AUTO_FB_0 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = uCTSTime + 2 * pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt0 [ FB_RATE0 ] [ wRate - RATE_18M ] , bNeedAck ) ;
} else if ( ( byFBOption = = AUTO_FB_1 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = uCTSTime + 2 * pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt1 [ FB_RATE0 ] [ wRate - RATE_18M ] , bNeedAck ) ;
}
break ;
case RTSDUR_BA_F1 : //RTSDuration_ba_f1
uCTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopCCKBasicRate ) ;
if ( ( byFBOption = = AUTO_FB_0 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = uCTSTime + 2 * pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt0 [ FB_RATE1 ] [ wRate - RATE_18M ] , bNeedAck ) ;
} else if ( ( byFBOption = = AUTO_FB_1 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = uCTSTime + 2 * pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt1 [ FB_RATE1 ] [ wRate - RATE_18M ] , bNeedAck ) ;
}
break ;
case RTSDUR_AA_F1 : //RTSDuration_aa_f1
uCTSTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
if ( ( byFBOption = = AUTO_FB_0 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = uCTSTime + 2 * pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt0 [ FB_RATE1 ] [ wRate - RATE_18M ] , bNeedAck ) ;
} else if ( ( byFBOption = = AUTO_FB_1 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = uCTSTime + 2 * pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt1 [ FB_RATE1 ] [ wRate - RATE_18M ] , bNeedAck ) ;
}
break ;
case CTSDUR_BA_F0 : //CTSDuration_ba_f0
if ( ( byFBOption = = AUTO_FB_0 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt0 [ FB_RATE0 ] [ wRate - RATE_18M ] , bNeedAck ) ;
} else if ( ( byFBOption = = AUTO_FB_1 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt1 [ FB_RATE0 ] [ wRate - RATE_18M ] , bNeedAck ) ;
}
break ;
case CTSDUR_BA_F1 : //CTSDuration_ba_f1
if ( ( byFBOption = = AUTO_FB_0 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt0 [ FB_RATE1 ] [ wRate - RATE_18M ] , bNeedAck ) ;
} else if ( ( byFBOption = = AUTO_FB_1 ) & & ( wRate > = RATE_18M ) & & ( wRate < = RATE_54M ) ) {
uDurTime = pDevice - > uSIFS + s_uGetTxRsvTime ( pDevice , byPktType , cbFrameLength , wFB_Opt1 [ FB_RATE1 ] [ wRate - RATE_18M ] , bNeedAck ) ;
}
break ;
default :
break ;
}
return uDurTime ;
}
static
UINT
s_uFillDataHead (
IN PSDevice pDevice ,
IN BYTE byPktType ,
IN WORD wCurrentRate ,
IN PVOID pTxDataHead ,
IN UINT cbFrameLength ,
IN UINT uDMAIdx ,
IN BOOL bNeedAck ,
IN UINT uFragIdx ,
IN UINT cbLastFragmentSize ,
IN UINT uMACfragNum ,
IN BYTE byFBOption
)
{
if ( pTxDataHead = = NULL ) {
return 0 ;
}
if ( byPktType = = PK_TYPE_11GB | | byPktType = = PK_TYPE_11GA ) {
if ( ( uDMAIdx = = TYPE_ATIMDMA ) | | ( uDMAIdx = = TYPE_BEACONDMA ) ) {
PSTxDataHead_ab pBuf = ( PSTxDataHead_ab ) pTxDataHead ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
( PWORD ) & ( pBuf - > wTransmitLength ) , ( PBYTE ) & ( pBuf - > byServiceField ) , ( PBYTE ) & ( pBuf - > bySignalField )
) ;
//Get Duration and TimeStampOff
pBuf - > wDuration = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_A , cbFrameLength , byPktType ,
wCurrentRate , bNeedAck , uFragIdx ,
cbLastFragmentSize , uMACfragNum ,
byFBOption ) ; //1: 2.4GHz
if ( uDMAIdx ! = TYPE_ATIMDMA ) {
pBuf - > wTimeStampOff = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ wCurrentRate % MAX_RATE ] ;
}
return ( pBuf - > wDuration ) ;
}
else { // DATA & MANAGE Frame
if ( byFBOption = = AUTO_FB_NONE ) {
PSTxDataHead_g pBuf = ( PSTxDataHead_g ) pTxDataHead ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
( PWORD ) & ( pBuf - > wTransmitLength_a ) , ( PBYTE ) & ( pBuf - > byServiceField_a ) , ( PBYTE ) & ( pBuf - > bySignalField_a )
) ;
BBvCaculateParameter ( pDevice , cbFrameLength , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
( PWORD ) & ( pBuf - > wTransmitLength_b ) , ( PBYTE ) & ( pBuf - > byServiceField_b ) , ( PBYTE ) & ( pBuf - > bySignalField_b )
) ;
//Get Duration and TimeStamp
pBuf - > wDuration_a = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_A , cbFrameLength ,
byPktType , wCurrentRate , bNeedAck , uFragIdx ,
cbLastFragmentSize , uMACfragNum ,
byFBOption ) ; //1: 2.4GHz
pBuf - > wDuration_b = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_B , cbFrameLength ,
PK_TYPE_11B , pDevice - > byTopCCKBasicRate ,
bNeedAck , uFragIdx , cbLastFragmentSize ,
uMACfragNum , byFBOption ) ; //1: 2.4GHz
pBuf - > wTimeStampOff_a = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ wCurrentRate % MAX_RATE ] ;
pBuf - > wTimeStampOff_b = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ pDevice - > byTopCCKBasicRate % MAX_RATE ] ;
return ( pBuf - > wDuration_a ) ;
} else {
// Auto Fallback
PSTxDataHead_g_FB pBuf = ( PSTxDataHead_g_FB ) pTxDataHead ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
( PWORD ) & ( pBuf - > wTransmitLength_a ) , ( PBYTE ) & ( pBuf - > byServiceField_a ) , ( PBYTE ) & ( pBuf - > bySignalField_a )
) ;
BBvCaculateParameter ( pDevice , cbFrameLength , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
( PWORD ) & ( pBuf - > wTransmitLength_b ) , ( PBYTE ) & ( pBuf - > byServiceField_b ) , ( PBYTE ) & ( pBuf - > bySignalField_b )
) ;
//Get Duration and TimeStamp
pBuf - > wDuration_a = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_A , cbFrameLength , byPktType ,
wCurrentRate , bNeedAck , uFragIdx , cbLastFragmentSize , uMACfragNum , byFBOption ) ; //1: 2.4GHz
pBuf - > wDuration_b = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_B , cbFrameLength , PK_TYPE_11B ,
pDevice - > byTopCCKBasicRate , bNeedAck , uFragIdx , cbLastFragmentSize , uMACfragNum , byFBOption ) ; //1: 2.4GHz
pBuf - > wDuration_a_f0 = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_A_F0 , cbFrameLength , byPktType ,
wCurrentRate , bNeedAck , uFragIdx , cbLastFragmentSize , uMACfragNum , byFBOption ) ; //1: 2.4GHz
pBuf - > wDuration_a_f1 = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_A_F1 , cbFrameLength , byPktType ,
wCurrentRate , bNeedAck , uFragIdx , cbLastFragmentSize , uMACfragNum , byFBOption ) ; //1: 2.4GHz
pBuf - > wTimeStampOff_a = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ wCurrentRate % MAX_RATE ] ;
pBuf - > wTimeStampOff_b = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ pDevice - > byTopCCKBasicRate % MAX_RATE ] ;
return ( pBuf - > wDuration_a ) ;
} //if (byFBOption == AUTO_FB_NONE)
}
}
else if ( byPktType = = PK_TYPE_11A ) {
if ( ( byFBOption ! = AUTO_FB_NONE ) & & ( uDMAIdx ! = TYPE_ATIMDMA ) & & ( uDMAIdx ! = TYPE_BEACONDMA ) ) {
// Auto Fallback
PSTxDataHead_a_FB pBuf = ( PSTxDataHead_a_FB ) pTxDataHead ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
( PWORD ) & ( pBuf - > wTransmitLength ) , ( PBYTE ) & ( pBuf - > byServiceField ) , ( PBYTE ) & ( pBuf - > bySignalField )
) ;
//Get Duration and TimeStampOff
pBuf - > wDuration = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_A , cbFrameLength , byPktType ,
wCurrentRate , bNeedAck , uFragIdx , cbLastFragmentSize , uMACfragNum , byFBOption ) ; //0: 5GHz
pBuf - > wDuration_f0 = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_A_F0 , cbFrameLength , byPktType ,
wCurrentRate , bNeedAck , uFragIdx , cbLastFragmentSize , uMACfragNum , byFBOption ) ; //0: 5GHz
pBuf - > wDuration_f1 = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_A_F1 , cbFrameLength , byPktType ,
wCurrentRate , bNeedAck , uFragIdx , cbLastFragmentSize , uMACfragNum , byFBOption ) ; //0: 5GHz
if ( uDMAIdx ! = TYPE_ATIMDMA ) {
pBuf - > wTimeStampOff = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ wCurrentRate % MAX_RATE ] ;
}
return ( pBuf - > wDuration ) ;
} else {
PSTxDataHead_ab pBuf = ( PSTxDataHead_ab ) pTxDataHead ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
( PWORD ) & ( pBuf - > wTransmitLength ) , ( PBYTE ) & ( pBuf - > byServiceField ) , ( PBYTE ) & ( pBuf - > bySignalField )
) ;
//Get Duration and TimeStampOff
pBuf - > wDuration = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_A , cbFrameLength , byPktType ,
wCurrentRate , bNeedAck , uFragIdx ,
cbLastFragmentSize , uMACfragNum ,
byFBOption ) ;
if ( uDMAIdx ! = TYPE_ATIMDMA ) {
pBuf - > wTimeStampOff = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ wCurrentRate % MAX_RATE ] ;
}
return ( pBuf - > wDuration ) ;
}
}
else if ( byPktType = = PK_TYPE_11B ) {
PSTxDataHead_ab pBuf = ( PSTxDataHead_ab ) pTxDataHead ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
( PWORD ) & ( pBuf - > wTransmitLength ) , ( PBYTE ) & ( pBuf - > byServiceField ) , ( PBYTE ) & ( pBuf - > bySignalField )
) ;
//Get Duration and TimeStampOff
pBuf - > wDuration = ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_B , cbFrameLength , byPktType ,
wCurrentRate , bNeedAck , uFragIdx ,
cbLastFragmentSize , uMACfragNum ,
byFBOption ) ;
if ( uDMAIdx ! = TYPE_ATIMDMA ) {
pBuf - > wTimeStampOff = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ wCurrentRate % MAX_RATE ] ;
}
return ( pBuf - > wDuration ) ;
}
return 0 ;
}
static
VOID
s_vFillRTSHead (
IN PSDevice pDevice ,
IN BYTE byPktType ,
IN PVOID pvRTS ,
IN UINT cbFrameLength ,
IN BOOL bNeedAck ,
IN BOOL bDisCRC ,
IN PSEthernetHeader psEthHeader ,
IN WORD wCurrentRate ,
IN BYTE byFBOption
)
{
UINT uRTSFrameLen = 20 ;
WORD wLen = 0x0000 ;
if ( pvRTS = = NULL )
return ;
if ( bDisCRC ) {
// When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
// in this case we need to decrease its length by 4.
uRTSFrameLen - = 4 ;
}
// Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account.
// Otherwise, we need to modified codes for them.
if ( byPktType = = PK_TYPE_11GB | | byPktType = = PK_TYPE_11GA ) {
if ( byFBOption = = AUTO_FB_NONE ) {
PSRTS_g pBuf = ( PSRTS_g ) pvRTS ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
( PWORD ) & ( wLen ) , ( PBYTE ) & ( pBuf - > byServiceField_b ) , ( PBYTE ) & ( pBuf - > bySignalField_b )
) ;
pBuf - > wTransmitLength_b = cpu_to_le16 ( wLen ) ;
BBvCaculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopOFDMBasicRate , byPktType ,
( PWORD ) & ( wLen ) , ( PBYTE ) & ( pBuf - > byServiceField_a ) , ( PBYTE ) & ( pBuf - > bySignalField_a )
) ;
pBuf - > wTransmitLength_a = cpu_to_le16 ( wLen ) ;
//Get Duration
pBuf - > wDuration_bb = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_BB , cbFrameLength , PK_TYPE_11B , pDevice - > byTopCCKBasicRate , bNeedAck , byFBOption ) ) ; //0:RTSDuration_bb, 1:2.4G, 1:CCKData
pBuf - > wDuration_aa = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData
pBuf - > wDuration_ba = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_BA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
pBuf - > Data . wDurationID = pBuf - > wDuration_aa ;
//Get RTS Frame body
pBuf - > Data . wFrameControl = TYPE_CTL_RTS ; //0x00B4
if ( ( pDevice - > eOPMode = = OP_MODE_ADHOC ) | |
( pDevice - > eOPMode = = OP_MODE_AP ) ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( psEthHeader - > abyDstAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
if ( pDevice - > eOPMode = = OP_MODE_AP ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyTA [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyTA [ 0 ] ) , & ( psEthHeader - > abySrcAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
}
else {
PSRTS_g_FB pBuf = ( PSRTS_g_FB ) pvRTS ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
( PWORD ) & ( wLen ) , ( PBYTE ) & ( pBuf - > byServiceField_b ) , ( PBYTE ) & ( pBuf - > bySignalField_b )
) ;
pBuf - > wTransmitLength_b = cpu_to_le16 ( wLen ) ;
BBvCaculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopOFDMBasicRate , byPktType ,
( PWORD ) & ( wLen ) , ( PBYTE ) & ( pBuf - > byServiceField_a ) , ( PBYTE ) & ( pBuf - > bySignalField_a )
) ;
pBuf - > wTransmitLength_a = cpu_to_le16 ( wLen ) ;
//Get Duration
pBuf - > wDuration_bb = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_BB , cbFrameLength , PK_TYPE_11B , pDevice - > byTopCCKBasicRate , bNeedAck , byFBOption ) ) ; //0:RTSDuration_bb, 1:2.4G, 1:CCKData
pBuf - > wDuration_aa = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData
pBuf - > wDuration_ba = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_BA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData
pBuf - > wRTSDuration_ba_f0 = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_BA_F0 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData
pBuf - > wRTSDuration_aa_f0 = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA_F0 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData
pBuf - > wRTSDuration_ba_f1 = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_BA_F1 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData
pBuf - > wRTSDuration_aa_f1 = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA_F1 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
pBuf - > Data . wDurationID = pBuf - > wDuration_aa ;
//Get RTS Frame body
pBuf - > Data . wFrameControl = TYPE_CTL_RTS ; //0x00B4
if ( ( pDevice - > eOPMode = = OP_MODE_ADHOC ) | |
( pDevice - > eOPMode = = OP_MODE_AP ) ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( psEthHeader - > abyDstAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
if ( pDevice - > eOPMode = = OP_MODE_AP ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyTA [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyTA [ 0 ] ) , & ( psEthHeader - > abySrcAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
} // if (byFBOption == AUTO_FB_NONE)
}
else if ( byPktType = = PK_TYPE_11A ) {
if ( byFBOption = = AUTO_FB_NONE ) {
PSRTS_ab pBuf = ( PSRTS_ab ) pvRTS ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopOFDMBasicRate , byPktType ,
( PWORD ) & ( wLen ) , ( PBYTE ) & ( pBuf - > byServiceField ) , ( PBYTE ) & ( pBuf - > bySignalField )
) ;
pBuf - > wTransmitLength = cpu_to_le16 ( wLen ) ;
//Get Duration
pBuf - > wDuration = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
pBuf - > Data . wDurationID = pBuf - > wDuration ;
//Get RTS Frame body
pBuf - > Data . wFrameControl = TYPE_CTL_RTS ; //0x00B4
if ( ( pDevice - > eOPMode = = OP_MODE_ADHOC ) | |
( pDevice - > eOPMode = = OP_MODE_AP ) ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( psEthHeader - > abyDstAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
if ( pDevice - > eOPMode = = OP_MODE_AP ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyTA [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyTA [ 0 ] ) , & ( psEthHeader - > abySrcAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
}
else {
PSRTS_a_FB pBuf = ( PSRTS_a_FB ) pvRTS ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopOFDMBasicRate , byPktType ,
( PWORD ) & ( wLen ) , ( PBYTE ) & ( pBuf - > byServiceField ) , ( PBYTE ) & ( pBuf - > bySignalField )
) ;
pBuf - > wTransmitLength = cpu_to_le16 ( wLen ) ;
//Get Duration
pBuf - > wDuration = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
pBuf - > wRTSDuration_f0 = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA_F0 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData
pBuf - > wRTSDuration_f1 = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA_F1 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //7:RTSDuration_aa_f1, 0:5G, 0:
pBuf - > Data . wDurationID = pBuf - > wDuration ;
//Get RTS Frame body
pBuf - > Data . wFrameControl = TYPE_CTL_RTS ; //0x00B4
if ( ( pDevice - > eOPMode = = OP_MODE_ADHOC ) | |
( pDevice - > eOPMode = = OP_MODE_AP ) ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( psEthHeader - > abyDstAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
if ( pDevice - > eOPMode = = OP_MODE_AP ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyTA [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyTA [ 0 ] ) , & ( psEthHeader - > abySrcAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
}
}
else if ( byPktType = = PK_TYPE_11B ) {
PSRTS_ab pBuf = ( PSRTS_ab ) pvRTS ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
( PWORD ) & ( wLen ) , ( PBYTE ) & ( pBuf - > byServiceField ) , ( PBYTE ) & ( pBuf - > bySignalField )
) ;
pBuf - > wTransmitLength = cpu_to_le16 ( wLen ) ;
//Get Duration
pBuf - > wDuration = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_BB , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //0:RTSDuration_bb, 1:2.4G, 1:CCKData
pBuf - > Data . wDurationID = pBuf - > wDuration ;
//Get RTS Frame body
pBuf - > Data . wFrameControl = TYPE_CTL_RTS ; //0x00B4
if ( ( pDevice - > eOPMode = = OP_MODE_ADHOC ) | |
( pDevice - > eOPMode = = OP_MODE_AP ) ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( psEthHeader - > abyDstAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
if ( pDevice - > eOPMode = = OP_MODE_AP ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyTA [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyTA [ 0 ] ) , & ( psEthHeader - > abySrcAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
}
}
static
VOID
s_vFillCTSHead (
IN PSDevice pDevice ,
IN UINT uDMAIdx ,
IN BYTE byPktType ,
IN PVOID pvCTS ,
IN UINT cbFrameLength ,
IN BOOL bNeedAck ,
IN BOOL bDisCRC ,
IN WORD wCurrentRate ,
IN BYTE byFBOption
)
{
UINT uCTSFrameLen = 14 ;
WORD wLen = 0x0000 ;
if ( pvCTS = = NULL ) {
return ;
}
if ( bDisCRC ) {
// When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
// in this case we need to decrease its length by 4.
uCTSFrameLen - = 4 ;
}
if ( byPktType = = PK_TYPE_11GB | | byPktType = = PK_TYPE_11GA ) {
if ( byFBOption ! = AUTO_FB_NONE & & uDMAIdx ! = TYPE_ATIMDMA & & uDMAIdx ! = TYPE_BEACONDMA ) {
// Auto Fall back
PSCTS_FB pBuf = ( PSCTS_FB ) pvCTS ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , uCTSFrameLen , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
( PWORD ) & ( wLen ) , ( PBYTE ) & ( pBuf - > byServiceField_b ) , ( PBYTE ) & ( pBuf - > bySignalField_b )
) ;
pBuf - > wTransmitLength_b = cpu_to_le16 ( wLen ) ;
pBuf - > wDuration_ba = ( WORD ) s_uGetRTSCTSDuration ( pDevice , CTSDUR_BA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ; //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
pBuf - > wDuration_ba + = pDevice - > wCTSDuration ;
pBuf - > wDuration_ba = cpu_to_le16 ( pBuf - > wDuration_ba ) ;
//Get CTSDuration_ba_f0
pBuf - > wCTSDuration_ba_f0 = ( WORD ) s_uGetRTSCTSDuration ( pDevice , CTSDUR_BA_F0 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ; //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data
pBuf - > wCTSDuration_ba_f0 + = pDevice - > wCTSDuration ;
pBuf - > wCTSDuration_ba_f0 = cpu_to_le16 ( pBuf - > wCTSDuration_ba_f0 ) ;
//Get CTSDuration_ba_f1
pBuf - > wCTSDuration_ba_f1 = ( WORD ) s_uGetRTSCTSDuration ( pDevice , CTSDUR_BA_F1 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ; //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data
pBuf - > wCTSDuration_ba_f1 + = pDevice - > wCTSDuration ;
pBuf - > wCTSDuration_ba_f1 = cpu_to_le16 ( pBuf - > wCTSDuration_ba_f1 ) ;
//Get CTS Frame body
pBuf - > Data . wDurationID = pBuf - > wDuration_ba ;
pBuf - > Data . wFrameControl = TYPE_CTL_CTS ; //0x00C4
pBuf - > Data . wReserved = 0x0000 ;
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( pDevice - > abyCurrentNetAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
} else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
PSCTS pBuf = ( PSCTS ) pvCTS ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , uCTSFrameLen , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
( PWORD ) & ( wLen ) , ( PBYTE ) & ( pBuf - > byServiceField_b ) , ( PBYTE ) & ( pBuf - > bySignalField_b )
) ;
pBuf - > wTransmitLength_b = cpu_to_le16 ( wLen ) ;
//Get CTSDuration_ba
pBuf - > wDuration_ba = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSDuration ( pDevice , CTSDUR_BA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
pBuf - > wDuration_ba + = pDevice - > wCTSDuration ;
pBuf - > wDuration_ba = cpu_to_le16 ( pBuf - > wDuration_ba ) ;
//Get CTS Frame body
pBuf - > Data . wDurationID = pBuf - > wDuration_ba ;
pBuf - > Data . wFrameControl = TYPE_CTL_CTS ; //0x00C4
pBuf - > Data . wReserved = 0x0000 ;
2009-08-12 21:54:11 +00:00
memcpy ( & ( pBuf - > Data . abyRA [ 0 ] ) , & ( pDevice - > abyCurrentNetAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
}
}
/*+
*
* Description :
* Generate FIFO control for MAC & Baseband controller
*
* Parameters :
* In :
* pDevice - Pointer to adpater
* pTxDataHead - Transmit Data Buffer
* pTxBufHead - pTxBufHead
* pvRrvTime - pvRrvTime
* pvRTS - RTS Buffer
* pCTS - CTS Buffer
* cbFrameSize - Transmit Data Length ( Hdr + Payload + FCS )
* bNeedACK - If need ACK
* uDMAIdx - DMA Index
* Out :
* none
*
* Return Value : none
*
- */
// UINT cbFrameSize,//Hdr+Payload+FCS
static
VOID
s_vGenerateTxParameter (
IN PSDevice pDevice ,
IN BYTE byPktType ,
IN WORD wCurrentRate ,
IN PVOID pTxBufHead ,
IN PVOID pvRrvTime ,
IN PVOID pvRTS ,
IN PVOID pvCTS ,
IN UINT cbFrameSize ,
IN BOOL bNeedACK ,
IN UINT uDMAIdx ,
IN PSEthernetHeader psEthHeader
)
{
UINT cbMACHdLen = WLAN_HDR_ADDR3_LEN ; //24
WORD wFifoCtl ;
BOOL bDisCRC = FALSE ;
BYTE byFBOption = AUTO_FB_NONE ;
// WORD wCurrentRate = pDevice->wCurrentRate;
//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
PSTxBufHead pFifoHead = ( PSTxBufHead ) pTxBufHead ;
pFifoHead - > wReserved = wCurrentRate ;
wFifoCtl = pFifoHead - > wFIFOCtl ;
if ( wFifoCtl & FIFOCTL_CRCDIS ) {
bDisCRC = TRUE ;
}
if ( wFifoCtl & FIFOCTL_AUTO_FB_0 ) {
byFBOption = AUTO_FB_0 ;
}
else if ( wFifoCtl & FIFOCTL_AUTO_FB_1 ) {
byFBOption = AUTO_FB_1 ;
}
if ( pDevice - > bLongHeader )
cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6 ;
if ( byPktType = = PK_TYPE_11GB | | byPktType = = PK_TYPE_11GA ) {
if ( pvRTS ! = NULL ) { //RTS_need
//Fill RsvTime
if ( pvRrvTime ) {
PSRrvTime_gRTS pBuf = ( PSRrvTime_gRTS ) pvRrvTime ;
pBuf - > wRTSTxRrvTime_aa = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSRsvTime ( pDevice , 2 , byPktType , cbFrameSize , wCurrentRate ) ) ; //2:RTSTxRrvTime_aa, 1:2.4GHz
pBuf - > wRTSTxRrvTime_ba = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSRsvTime ( pDevice , 1 , byPktType , cbFrameSize , wCurrentRate ) ) ; //1:RTSTxRrvTime_ba, 1:2.4GHz
pBuf - > wRTSTxRrvTime_bb = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSRsvTime ( pDevice , 0 , byPktType , cbFrameSize , wCurrentRate ) ) ; //0:RTSTxRrvTime_bb, 1:2.4GHz
pBuf - > wTxRrvTime_a = cpu_to_le16 ( ( WORD ) s_uGetTxRsvTime ( pDevice , byPktType , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //2.4G OFDM
pBuf - > wTxRrvTime_b = cpu_to_le16 ( ( WORD ) s_uGetTxRsvTime ( pDevice , PK_TYPE_11B , cbFrameSize , pDevice - > byTopCCKBasicRate , bNeedACK ) ) ; //1:CCK
}
//Fill RTS
s_vFillRTSHead ( pDevice , byPktType , pvRTS , cbFrameSize , bNeedACK , bDisCRC , psEthHeader , wCurrentRate , byFBOption ) ;
}
else { //RTS_needless, PCF mode
//Fill RsvTime
if ( pvRrvTime ) {
PSRrvTime_gCTS pBuf = ( PSRrvTime_gCTS ) pvRrvTime ;
pBuf - > wTxRrvTime_a = cpu_to_le16 ( ( WORD ) s_uGetTxRsvTime ( pDevice , byPktType , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //2.4G OFDM
pBuf - > wTxRrvTime_b = cpu_to_le16 ( ( WORD ) s_uGetTxRsvTime ( pDevice , PK_TYPE_11B , cbFrameSize , pDevice - > byTopCCKBasicRate , bNeedACK ) ) ; //1:CCK
pBuf - > wCTSTxRrvTime_ba = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSRsvTime ( pDevice , 3 , byPktType , cbFrameSize , wCurrentRate ) ) ; //3:CTSTxRrvTime_Ba, 1:2.4GHz
}
//Fill CTS
s_vFillCTSHead ( pDevice , uDMAIdx , byPktType , pvCTS , cbFrameSize , bNeedACK , bDisCRC , wCurrentRate , byFBOption ) ;
}
}
else if ( byPktType = = PK_TYPE_11A ) {
if ( pvRTS ! = NULL ) { //RTS_need, non PCF mode
//Fill RsvTime
if ( pvRrvTime ) {
PSRrvTime_ab pBuf = ( PSRrvTime_ab ) pvRrvTime ;
pBuf - > wRTSTxRrvTime = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSRsvTime ( pDevice , 2 , byPktType , cbFrameSize , wCurrentRate ) ) ; //2:RTSTxRrvTime_aa, 0:5GHz
pBuf - > wTxRrvTime = cpu_to_le16 ( ( WORD ) s_uGetTxRsvTime ( pDevice , byPktType , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //0:OFDM
}
//Fill RTS
s_vFillRTSHead ( pDevice , byPktType , pvRTS , cbFrameSize , bNeedACK , bDisCRC , psEthHeader , wCurrentRate , byFBOption ) ;
}
else if ( pvRTS = = NULL ) { //RTS_needless, non PCF mode
//Fill RsvTime
if ( pvRrvTime ) {
PSRrvTime_ab pBuf = ( PSRrvTime_ab ) pvRrvTime ;
pBuf - > wTxRrvTime = cpu_to_le16 ( ( WORD ) s_uGetTxRsvTime ( pDevice , PK_TYPE_11A , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //0:OFDM
}
}
}
else if ( byPktType = = PK_TYPE_11B ) {
if ( ( pvRTS ! = NULL ) ) { //RTS_need, non PCF mode
//Fill RsvTime
if ( pvRrvTime ) {
PSRrvTime_ab pBuf = ( PSRrvTime_ab ) pvRrvTime ;
pBuf - > wRTSTxRrvTime = cpu_to_le16 ( ( WORD ) s_uGetRTSCTSRsvTime ( pDevice , 0 , byPktType , cbFrameSize , wCurrentRate ) ) ; //0:RTSTxRrvTime_bb, 1:2.4GHz
pBuf - > wTxRrvTime = cpu_to_le16 ( ( WORD ) s_uGetTxRsvTime ( pDevice , PK_TYPE_11B , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //1:CCK
}
//Fill RTS
s_vFillRTSHead ( pDevice , byPktType , pvRTS , cbFrameSize , bNeedACK , bDisCRC , psEthHeader , wCurrentRate , byFBOption ) ;
}
else { //RTS_needless, non PCF mode
//Fill RsvTime
if ( pvRrvTime ) {
PSRrvTime_ab pBuf = ( PSRrvTime_ab ) pvRrvTime ;
pBuf - > wTxRrvTime = cpu_to_le16 ( ( WORD ) s_uGetTxRsvTime ( pDevice , PK_TYPE_11B , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //1:CCK
}
}
}
//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
}
/*
PBYTE pbyBuffer , //point to pTxBufHead
WORD wFragType , //00:Non-Frag, 01:Start, 02:Mid, 03:Last
UINT cbFragmentSize , //Hdr+payoad+FCS
*/
BOOL
s_bPacketToWirelessUsb (
IN PSDevice pDevice ,
IN BYTE byPktType ,
IN PBYTE usbPacketBuf ,
IN BOOL bNeedEncryption ,
IN UINT uSkbPacketLen ,
IN UINT uDMAIdx ,
IN PSEthernetHeader psEthHeader ,
IN PBYTE pPacket ,
IN PSKeyItem pTransmitKey ,
IN UINT uNodeIndex ,
IN WORD wCurrentRate ,
OUT UINT * pcbHeaderLen ,
OUT UINT * pcbTotalLen
)
{
PSMgmtObject pMgmt = & ( pDevice - > sMgmtObj ) ;
UINT cbFrameSize , cbFrameBodySize ;
PTX_BUFFER pTxBufHead ;
UINT cb802_1_H_len ;
UINT cbIVlen = 0 , cbICVlen = 0 , cbMIClen = 0 , cbMACHdLen = 0 , cbFCSlen = 4 ;
UINT cbMICHDR = 0 ;
BOOL bNeedACK , bRTS ;
PBYTE pbyType , pbyMacHdr , pbyIVHead , pbyPayloadHead , pbyTxBufferAddr ;
BYTE abySNAP_RFC1042 [ 6 ] = { 0xAA , 0xAA , 0x03 , 0x00 , 0x00 , 0x00 } ;
BYTE abySNAP_Bridgetunnel [ 6 ] = { 0xAA , 0xAA , 0x03 , 0x00 , 0x00 , 0xF8 } ;
UINT uDuration ;
UINT cbHeaderLength = 0 , uPadding = 0 ;
PVOID pvRrvTime ;
PSMICHDRHead pMICHDR ;
PVOID pvRTS ;
PVOID pvCTS ;
PVOID pvTxDataHd ;
BYTE byFBOption = AUTO_FB_NONE , byFragType ;
WORD wTxBufSize ;
DWORD dwMICKey0 , dwMICKey1 , dwMIC_Priority , dwCRC ;
PDWORD pdwMIC_L , pdwMIC_R ;
BOOL bSoftWEP = FALSE ;
pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL ;
if ( ( bNeedEncryption ) & & ( pTransmitKey ! = NULL ) ) {
if ( ( ( PSKeyTable ) ( pTransmitKey - > pvKeyTable ) ) - > bSoftWEP = = TRUE ) {
// WEP 256
bSoftWEP = TRUE ;
}
}
pTxBufHead = ( PTX_BUFFER ) usbPacketBuf ;
2009-08-12 21:54:11 +00:00
memset ( pTxBufHead , 0 , sizeof ( TX_BUFFER ) ) ;
2009-06-13 11:38:31 +00:00
// Get pkt type
if ( ntohs ( psEthHeader - > wType ) > MAX_DATA_LEN ) {
if ( pDevice - > dwDiagRefCount = = 0 ) {
cb802_1_H_len = 8 ;
} else {
cb802_1_H_len = 2 ;
}
} else {
cb802_1_H_len = 0 ;
}
cbFrameBodySize = uSkbPacketLen - U_HEADER_LEN + cb802_1_H_len ;
//Set packet type
pTxBufHead - > wFIFOCtl | = ( WORD ) ( byPktType < < 8 ) ;
if ( pDevice - > dwDiagRefCount ! = 0 ) {
bNeedACK = FALSE ;
pTxBufHead - > wFIFOCtl = pTxBufHead - > wFIFOCtl & ( ~ FIFOCTL_NEEDACK ) ;
} else { //if (pDevice->dwDiagRefCount != 0) {
if ( ( pDevice - > eOPMode = = OP_MODE_ADHOC ) | |
( pDevice - > eOPMode = = OP_MODE_AP ) ) {
if ( IS_MULTICAST_ADDRESS ( & ( psEthHeader - > abyDstAddr [ 0 ] ) ) | |
IS_BROADCAST_ADDRESS ( & ( psEthHeader - > abyDstAddr [ 0 ] ) ) ) {
bNeedACK = FALSE ;
pTxBufHead - > wFIFOCtl = pTxBufHead - > wFIFOCtl & ( ~ FIFOCTL_NEEDACK ) ;
}
else {
bNeedACK = TRUE ;
pTxBufHead - > wFIFOCtl | = FIFOCTL_NEEDACK ;
}
}
else {
// MSDUs in Infra mode always need ACK
bNeedACK = TRUE ;
pTxBufHead - > wFIFOCtl | = FIFOCTL_NEEDACK ;
}
} //if (pDevice->dwDiagRefCount != 0) {
pTxBufHead - > wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us ;
//Set FIFOCTL_LHEAD
if ( pDevice - > bLongHeader )
pTxBufHead - > wFIFOCtl | = FIFOCTL_LHEAD ;
if ( pDevice - > bSoftwareGenCrcErr ) {
pTxBufHead - > wFIFOCtl | = FIFOCTL_CRCDIS ; // set tx descriptors to NO hardware CRC
}
//Set FRAGCTL_MACHDCNT
if ( pDevice - > bLongHeader ) {
cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6 ;
} else {
cbMACHdLen = WLAN_HDR_ADDR3_LEN ;
}
pTxBufHead - > wFragCtl | = ( WORD ) ( cbMACHdLen < < 10 ) ;
//Set FIFOCTL_GrpAckPolicy
if ( pDevice - > bGrpAckPolicy = = TRUE ) { //0000 0100 0000 0000
pTxBufHead - > wFIFOCtl | = FIFOCTL_GRPACK ;
}
//Set Auto Fallback Ctl
if ( wCurrentRate > = RATE_18M ) {
if ( pDevice - > byAutoFBCtrl = = AUTO_FB_0 ) {
pTxBufHead - > wFIFOCtl | = FIFOCTL_AUTO_FB_0 ;
byFBOption = AUTO_FB_0 ;
} else if ( pDevice - > byAutoFBCtrl = = AUTO_FB_1 ) {
pTxBufHead - > wFIFOCtl | = FIFOCTL_AUTO_FB_1 ;
byFBOption = AUTO_FB_1 ;
}
}
if ( bSoftWEP ! = TRUE ) {
if ( ( bNeedEncryption ) & & ( pTransmitKey ! = NULL ) ) { //WEP enabled
if ( pTransmitKey - > byCipherSuite = = KEY_CTL_WEP ) { //WEP40 or WEP104
pTxBufHead - > wFragCtl | = FRAGCTL_LEGACY ;
}
if ( pTransmitKey - > byCipherSuite = = KEY_CTL_TKIP ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Tx Set wFragCtl == FRAGCTL_TKIP \n " ) ;
pTxBufHead - > wFragCtl | = FRAGCTL_TKIP ;
}
else if ( pTransmitKey - > byCipherSuite = = KEY_CTL_CCMP ) { //CCMP
pTxBufHead - > wFragCtl | = FRAGCTL_AES ;
}
}
}
if ( ( bNeedEncryption ) & & ( pTransmitKey ! = NULL ) ) {
if ( pTransmitKey - > byCipherSuite = = KEY_CTL_WEP ) {
cbIVlen = 4 ;
cbICVlen = 4 ;
}
else if ( pTransmitKey - > byCipherSuite = = KEY_CTL_TKIP ) {
cbIVlen = 8 ; //IV+ExtIV
cbMIClen = 8 ;
cbICVlen = 4 ;
}
if ( pTransmitKey - > byCipherSuite = = KEY_CTL_CCMP ) {
cbIVlen = 8 ; //RSN Header
cbICVlen = 8 ; //MIC
cbMICHDR = sizeof ( SMICHDRHead ) ;
}
if ( bSoftWEP = = FALSE ) {
//MAC Header should be padding 0 to DW alignment.
uPadding = 4 - ( cbMACHdLen % 4 ) ;
uPadding % = 4 ;
}
}
cbFrameSize = cbMACHdLen + cbIVlen + ( cbFrameBodySize + cbMIClen ) + cbICVlen + cbFCSlen ;
if ( ( bNeedACK = = FALSE ) | | ( cbFrameSize < pDevice - > wRTSThreshold ) ) {
bRTS = FALSE ;
} else {
bRTS = TRUE ;
pTxBufHead - > wFIFOCtl | = ( FIFOCTL_RTS | FIFOCTL_LRETRY ) ;
}
pbyTxBufferAddr = ( PBYTE ) & ( pTxBufHead - > adwTxKey [ 0 ] ) ;
wTxBufSize = sizeof ( STxBufHead ) ;
if ( byPktType = = PK_TYPE_11GB | | byPktType = = PK_TYPE_11GA ) { //802.11g packet
if ( byFBOption = = AUTO_FB_NONE ) {
if ( bRTS = = TRUE ) { //RTS_need
pvRrvTime = ( PSRrvTime_gRTS ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = ( PSMICHDRHead ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gRTS ) ) ;
pvRTS = ( PSRTS_g ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gRTS ) + cbMICHDR ) ;
pvCTS = NULL ;
pvTxDataHd = ( PSTxDataHead_g ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gRTS ) + cbMICHDR + sizeof ( SRTS_g ) ) ;
cbHeaderLength = wTxBufSize + sizeof ( SRrvTime_gRTS ) + cbMICHDR + sizeof ( SRTS_g ) + sizeof ( STxDataHead_g ) ;
}
else { //RTS_needless
pvRrvTime = ( PSRrvTime_gCTS ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = ( PSMICHDRHead ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gCTS ) ) ;
pvRTS = NULL ;
pvCTS = ( PSCTS ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gCTS ) + cbMICHDR ) ;
pvTxDataHd = ( PSTxDataHead_g ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gCTS ) + cbMICHDR + sizeof ( SCTS ) ) ;
cbHeaderLength = wTxBufSize + sizeof ( SRrvTime_gCTS ) + cbMICHDR + sizeof ( SCTS ) + sizeof ( STxDataHead_g ) ;
}
} else {
// Auto Fall Back
if ( bRTS = = TRUE ) { //RTS_need
pvRrvTime = ( PSRrvTime_gRTS ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = ( PSMICHDRHead ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gRTS ) ) ;
pvRTS = ( PSRTS_g_FB ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gRTS ) + cbMICHDR ) ;
pvCTS = NULL ;
pvTxDataHd = ( PSTxDataHead_g_FB ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gRTS ) + cbMICHDR + sizeof ( SRTS_g_FB ) ) ;
cbHeaderLength = wTxBufSize + sizeof ( SRrvTime_gRTS ) + cbMICHDR + sizeof ( SRTS_g_FB ) + sizeof ( STxDataHead_g_FB ) ;
}
else if ( bRTS = = FALSE ) { //RTS_needless
pvRrvTime = ( PSRrvTime_gCTS ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = ( PSMICHDRHead ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gCTS ) ) ;
pvRTS = NULL ;
pvCTS = ( PSCTS_FB ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gCTS ) + cbMICHDR ) ;
pvTxDataHd = ( PSTxDataHead_g_FB ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gCTS ) + cbMICHDR + sizeof ( SCTS_FB ) ) ;
cbHeaderLength = wTxBufSize + sizeof ( SRrvTime_gCTS ) + cbMICHDR + sizeof ( SCTS_FB ) + sizeof ( STxDataHead_g_FB ) ;
}
} // Auto Fall Back
}
else { //802.11a/b packet
if ( byFBOption = = AUTO_FB_NONE ) {
if ( bRTS = = TRUE ) { //RTS_need
pvRrvTime = ( PSRrvTime_ab ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = ( PSMICHDRHead ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) ) ;
pvRTS = ( PSRTS_ab ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) + cbMICHDR ) ;
pvCTS = NULL ;
pvTxDataHd = ( PSTxDataHead_ab ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) + cbMICHDR + sizeof ( SRTS_ab ) ) ;
cbHeaderLength = wTxBufSize + sizeof ( PSRrvTime_ab ) + cbMICHDR + sizeof ( SRTS_ab ) + sizeof ( STxDataHead_ab ) ;
}
else if ( bRTS = = FALSE ) { //RTS_needless, no MICHDR
pvRrvTime = ( PSRrvTime_ab ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = ( PSMICHDRHead ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) ) ;
pvRTS = NULL ;
pvCTS = NULL ;
pvTxDataHd = ( PSTxDataHead_ab ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) + cbMICHDR ) ;
cbHeaderLength = wTxBufSize + sizeof ( SRrvTime_ab ) + cbMICHDR + sizeof ( STxDataHead_ab ) ;
}
} else {
// Auto Fall Back
if ( bRTS = = TRUE ) { //RTS_need
pvRrvTime = ( PSRrvTime_ab ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = ( PSMICHDRHead ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) ) ;
pvRTS = ( PSRTS_a_FB ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) + cbMICHDR ) ;
pvCTS = NULL ;
pvTxDataHd = ( PSTxDataHead_a_FB ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) + cbMICHDR + sizeof ( SRTS_a_FB ) ) ;
cbHeaderLength = wTxBufSize + sizeof ( PSRrvTime_ab ) + cbMICHDR + sizeof ( SRTS_a_FB ) + sizeof ( STxDataHead_a_FB ) ;
}
else if ( bRTS = = FALSE ) { //RTS_needless
pvRrvTime = ( PSRrvTime_ab ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = ( PSMICHDRHead ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) ) ;
pvRTS = NULL ;
pvCTS = NULL ;
pvTxDataHd = ( PSTxDataHead_a_FB ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) + cbMICHDR ) ;
cbHeaderLength = wTxBufSize + sizeof ( SRrvTime_ab ) + cbMICHDR + sizeof ( STxDataHead_a_FB ) ;
}
} // Auto Fall Back
}
pbyMacHdr = ( PBYTE ) ( pbyTxBufferAddr + cbHeaderLength ) ;
pbyIVHead = ( PBYTE ) ( pbyMacHdr + cbMACHdLen + uPadding ) ;
pbyPayloadHead = ( PBYTE ) ( pbyMacHdr + cbMACHdLen + uPadding + cbIVlen ) ;
//=========================
// No Fragmentation
//=========================
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " No Fragmentation... \n " ) ;
byFragType = FRAGCTL_NONFRAG ;
//uDMAIdx = TYPE_AC0DMA;
//pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
//Fill FIFO,RrvTime,RTS,and CTS
s_vGenerateTxParameter ( pDevice , byPktType , wCurrentRate , ( PVOID ) pbyTxBufferAddr , pvRrvTime , pvRTS , pvCTS ,
cbFrameSize , bNeedACK , uDMAIdx , psEthHeader ) ;
//Fill DataHead
uDuration = s_uFillDataHead ( pDevice , byPktType , wCurrentRate , pvTxDataHd , cbFrameSize , uDMAIdx , bNeedACK ,
0 , 0 , 1 /*uMACfragNum*/ , byFBOption ) ;
// Generate TX MAC Header
s_vGenerateMACHeader ( pDevice , pbyMacHdr , ( WORD ) uDuration , psEthHeader , bNeedEncryption ,
byFragType , uDMAIdx , 0 ) ;
if ( bNeedEncryption = = TRUE ) {
//Fill TXKEY
s_vFillTxKey ( pDevice , ( PBYTE ) ( pTxBufHead - > adwTxKey ) , pbyIVHead , pTransmitKey ,
pbyMacHdr , ( WORD ) cbFrameBodySize , ( PBYTE ) pMICHDR ) ;
if ( pDevice - > bEnableHostWEP ) {
pMgmt - > sNodeDBTable [ uNodeIndex ] . dwTSC47_16 = pTransmitKey - > dwTSC47_16 ;
pMgmt - > sNodeDBTable [ uNodeIndex ] . wTSC15_0 = pTransmitKey - > wTSC15_0 ;
}
}
// 802.1H
if ( ntohs ( psEthHeader - > wType ) > MAX_DATA_LEN ) {
if ( pDevice - > dwDiagRefCount = = 0 ) {
if ( ( psEthHeader - > wType = = TYPE_PKT_IPX ) | |
( psEthHeader - > wType = = cpu_to_le16 ( 0xF380 ) ) ) {
2009-08-12 21:54:11 +00:00
memcpy ( ( PBYTE ) ( pbyPayloadHead ) , & abySNAP_Bridgetunnel [ 0 ] , 6 ) ;
2009-06-13 11:38:31 +00:00
} else {
2009-08-12 21:54:11 +00:00
memcpy ( ( PBYTE ) ( pbyPayloadHead ) , & abySNAP_RFC1042 [ 0 ] , 6 ) ;
2009-06-13 11:38:31 +00:00
}
pbyType = ( PBYTE ) ( pbyPayloadHead + 6 ) ;
2009-08-12 21:54:11 +00:00
memcpy ( pbyType , & ( psEthHeader - > wType ) , sizeof ( WORD ) ) ;
2009-06-13 11:38:31 +00:00
} else {
2009-08-12 21:54:11 +00:00
memcpy ( ( PBYTE ) ( pbyPayloadHead ) , & ( psEthHeader - > wType ) , sizeof ( WORD ) ) ;
2009-06-13 11:38:31 +00:00
}
}
if ( pPacket ! = NULL ) {
// Copy the Packet into a tx Buffer
2009-08-12 21:54:11 +00:00
memcpy ( ( pbyPayloadHead + cb802_1_H_len ) ,
2009-06-13 11:38:31 +00:00
( pPacket + U_HEADER_LEN ) ,
uSkbPacketLen - U_HEADER_LEN
) ;
} else {
// while bRelayPacketSend psEthHeader is point to header+payload
2009-08-12 21:54:11 +00:00
memcpy ( ( pbyPayloadHead + cb802_1_H_len ) , ( ( PBYTE ) psEthHeader ) + U_HEADER_LEN , uSkbPacketLen - U_HEADER_LEN ) ;
2009-06-13 11:38:31 +00:00
}
ASSERT ( uLength = = cbNdisBodySize ) ;
if ( ( bNeedEncryption = = TRUE ) & & ( pTransmitKey ! = NULL ) & & ( pTransmitKey - > byCipherSuite = = KEY_CTL_TKIP ) ) {
///////////////////////////////////////////////////////////////////
if ( pDevice - > sMgmtObj . eAuthenMode = = WMAC_AUTH_WPANONE ) {
dwMICKey0 = * ( PDWORD ) ( & pTransmitKey - > abyKey [ 16 ] ) ;
dwMICKey1 = * ( PDWORD ) ( & pTransmitKey - > abyKey [ 20 ] ) ;
}
else if ( ( pTransmitKey - > dwKeyIndex & AUTHENTICATOR_KEY ) ! = 0 ) {
dwMICKey0 = * ( PDWORD ) ( & pTransmitKey - > abyKey [ 16 ] ) ;
dwMICKey1 = * ( PDWORD ) ( & pTransmitKey - > abyKey [ 20 ] ) ;
}
else {
dwMICKey0 = * ( PDWORD ) ( & pTransmitKey - > abyKey [ 24 ] ) ;
dwMICKey1 = * ( PDWORD ) ( & pTransmitKey - > abyKey [ 28 ] ) ;
}
// DO Software Michael
MIC_vInit ( dwMICKey0 , dwMICKey1 ) ;
MIC_vAppend ( ( PBYTE ) & ( psEthHeader - > abyDstAddr [ 0 ] ) , 12 ) ;
dwMIC_Priority = 0 ;
MIC_vAppend ( ( PBYTE ) & dwMIC_Priority , 4 ) ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " MIC KEY: %lX, %lX \n " , dwMICKey0 , dwMICKey1 ) ;
///////////////////////////////////////////////////////////////////
//DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength));
//for (ii = 0; ii < cbFrameBodySize; ii++) {
// DBG_PRN_GRP12(("%02x ", *((PBYTE)((pbyPayloadHead + cb802_1_H_len) + ii))));
//}
//DBG_PRN_GRP12(("\n\n\n"));
MIC_vAppend ( pbyPayloadHead , cbFrameBodySize ) ;
pdwMIC_L = ( PDWORD ) ( pbyPayloadHead + cbFrameBodySize ) ;
pdwMIC_R = ( PDWORD ) ( pbyPayloadHead + cbFrameBodySize + 4 ) ;
MIC_vGetMIC ( pdwMIC_L , pdwMIC_R ) ;
MIC_vUnInit ( ) ;
if ( pDevice - > bTxMICFail = = TRUE ) {
* pdwMIC_L = 0 ;
* pdwMIC_R = 0 ;
pDevice - > bTxMICFail = FALSE ;
}
//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
}
if ( bSoftWEP = = TRUE ) {
s_vSWencryption ( pDevice , pTransmitKey , ( pbyPayloadHead ) , ( WORD ) ( cbFrameBodySize + cbMIClen ) ) ;
} else if ( ( ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption1Enabled ) & & ( bNeedEncryption = = TRUE ) ) | |
( ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption2Enabled ) & & ( bNeedEncryption = = TRUE ) ) | |
( ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption3Enabled ) & & ( bNeedEncryption = = TRUE ) ) ) {
cbFrameSize - = cbICVlen ;
}
if ( pDevice - > bSoftwareGenCrcErr = = TRUE ) {
UINT cbLen ;
PDWORD pdwCRC ;
dwCRC = 0xFFFFFFFFL ;
cbLen = cbFrameSize - cbFCSlen ;
// calculate CRC, and wrtie CRC value to end of TD
dwCRC = CRCdwGetCrc32Ex ( pbyMacHdr , cbLen , dwCRC ) ;
pdwCRC = ( PDWORD ) ( pbyMacHdr + cbLen ) ;
// finally, we must invert dwCRC to get the correct answer
* pdwCRC = ~ dwCRC ;
// Force Error
* pdwCRC - = 1 ;
} else {
cbFrameSize - = cbFCSlen ;
}
* pcbHeaderLen = cbHeaderLength ;
* pcbTotalLen = cbHeaderLength + cbFrameSize ;
//Set FragCtl in TxBufferHead
pTxBufHead - > wFragCtl | = ( WORD ) byFragType ;
return TRUE ;
}
/*+
*
* Description :
* Translate 802.3 to 802.11 header
*
* Parameters :
* In :
* pDevice - Pointer to adpater
* dwTxBufferAddr - Transmit Buffer
* pPacket - Packet from upper layer
* cbPacketSize - Transmit Data Length
* Out :
* pcbHeadSize - Header size of MAC & Baseband control and 802.11 Header
* pcbAppendPayload - size of append payload for 802.1 H translation
*
* Return Value : none
*
- */
VOID
s_vGenerateMACHeader (
IN PSDevice pDevice ,
IN PBYTE pbyBufferAddr ,
IN WORD wDuration ,
IN PSEthernetHeader psEthHeader ,
IN BOOL bNeedEncrypt ,
IN WORD wFragType ,
IN UINT uDMAIdx ,
IN UINT uFragIdx
)
{
PS802_11Header pMACHeader = ( PS802_11Header ) pbyBufferAddr ;
2009-08-12 21:54:11 +00:00
memset ( pMACHeader , 0 , ( sizeof ( S802_11Header ) ) ) ; //- sizeof(pMACHeader->dwIV)));
2009-06-13 11:38:31 +00:00
if ( uDMAIdx = = TYPE_ATIMDMA ) {
pMACHeader - > wFrameCtl = TYPE_802_11_ATIM ;
} else {
pMACHeader - > wFrameCtl = TYPE_802_11_DATA ;
}
if ( pDevice - > eOPMode = = OP_MODE_AP ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pMACHeader - > abyAddr1 [ 0 ] ) , & ( psEthHeader - > abyDstAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
memcpy ( & ( pMACHeader - > abyAddr2 [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
memcpy ( & ( pMACHeader - > abyAddr3 [ 0 ] ) , & ( psEthHeader - > abySrcAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
pMACHeader - > wFrameCtl | = FC_FROMDS ;
}
else {
if ( pDevice - > eOPMode = = OP_MODE_ADHOC ) {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pMACHeader - > abyAddr1 [ 0 ] ) , & ( psEthHeader - > abyDstAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
memcpy ( & ( pMACHeader - > abyAddr2 [ 0 ] ) , & ( psEthHeader - > abySrcAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
memcpy ( & ( pMACHeader - > abyAddr3 [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
2009-08-12 21:54:11 +00:00
memcpy ( & ( pMACHeader - > abyAddr3 [ 0 ] ) , & ( psEthHeader - > abyDstAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
memcpy ( & ( pMACHeader - > abyAddr2 [ 0 ] ) , & ( psEthHeader - > abySrcAddr [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
memcpy ( & ( pMACHeader - > abyAddr1 [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
pMACHeader - > wFrameCtl | = FC_TODS ;
}
}
if ( bNeedEncrypt )
pMACHeader - > wFrameCtl | = cpu_to_le16 ( ( WORD ) WLAN_SET_FC_ISWEP ( 1 ) ) ;
pMACHeader - > wDurationID = cpu_to_le16 ( wDuration ) ;
if ( pDevice - > bLongHeader ) {
PWLAN_80211HDR_A4 pMACA4Header = ( PWLAN_80211HDR_A4 ) pbyBufferAddr ;
pMACHeader - > wFrameCtl | = ( FC_TODS | FC_FROMDS ) ;
2009-08-12 21:54:11 +00:00
memcpy ( pMACA4Header - > abyAddr4 , pDevice - > abyBSSID , WLAN_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
}
pMACHeader - > wSeqCtl = cpu_to_le16 ( pDevice - > wSeqCounter < < 4 ) ;
//Set FragNumber in Sequence Control
pMACHeader - > wSeqCtl | = cpu_to_le16 ( ( WORD ) uFragIdx ) ;
if ( ( wFragType = = FRAGCTL_ENDFRAG ) | | ( wFragType = = FRAGCTL_NONFRAG ) ) {
pDevice - > wSeqCounter + + ;
if ( pDevice - > wSeqCounter > 0x0fff )
pDevice - > wSeqCounter = 0 ;
}
if ( ( wFragType = = FRAGCTL_STAFRAG ) | | ( wFragType = = FRAGCTL_MIDFRAG ) ) { //StartFrag or MidFrag
pMACHeader - > wFrameCtl | = FC_MOREFRAG ;
}
}
/*+
*
* Description :
* Request instructs a MAC to transmit a 802.11 management packet through
* the adapter onto the medium .
*
* Parameters :
* In :
* hDeviceContext - Pointer to the adapter
* pPacket - A pointer to a descriptor for the packet to transmit
* Out :
* none
*
* Return Value : CMD_STATUS_PENDING if MAC Tx resource avaliable ; otherwise FALSE
*
- */
CMD_STATUS csMgmt_xmit (
IN PSDevice pDevice ,
IN PSTxMgmtPacket pPacket
)
{
BYTE byPktType ;
PBYTE pbyTxBufferAddr ;
PVOID pvRTS ;
PSCTS pCTS ;
PVOID pvTxDataHd ;
UINT uDuration ;
UINT cbReqCount ;
PS802_11Header pMACHeader ;
UINT cbHeaderSize ;
UINT cbFrameBodySize ;
BOOL bNeedACK ;
BOOL bIsPSPOLL = FALSE ;
PSTxBufHead pTxBufHead ;
UINT cbFrameSize ;
UINT cbIVlen = 0 ;
UINT cbICVlen = 0 ;
UINT cbMIClen = 0 ;
UINT cbFCSlen = 4 ;
UINT uPadding = 0 ;
WORD wTxBufSize ;
UINT cbMacHdLen ;
SEthernetHeader sEthHeader ;
PVOID pvRrvTime ;
PVOID pMICHDR ;
PSMgmtObject pMgmt = & ( pDevice - > sMgmtObj ) ;
WORD wCurrentRate = RATE_1M ;
PTX_BUFFER pTX_Buffer ;
PUSB_SEND_CONTEXT pContext ;
pContext = ( PUSB_SEND_CONTEXT ) s_vGetFreeContext ( pDevice ) ;
if ( NULL = = pContext ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " ManagementSend TX...NO CONTEXT! \n " ) ;
return CMD_STATUS_RESOURCES ;
}
pTX_Buffer = ( PTX_BUFFER ) ( & pContext - > Data [ 0 ] ) ;
pbyTxBufferAddr = ( PBYTE ) & ( pTX_Buffer - > adwTxKey [ 0 ] ) ;
cbFrameBodySize = pPacket - > cbPayloadLen ;
pTxBufHead = ( PSTxBufHead ) pbyTxBufferAddr ;
wTxBufSize = sizeof ( STxBufHead ) ;
memset ( pTxBufHead , 0 , wTxBufSize ) ;
if ( pDevice - > byBBType = = BB_TYPE_11A ) {
wCurrentRate = RATE_6M ;
byPktType = PK_TYPE_11A ;
} else {
wCurrentRate = RATE_1M ;
byPktType = PK_TYPE_11B ;
}
// SetPower will cause error power TX state for OFDM Date packet in TX buffer.
// 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
// And cmd timer will wait data pkt TX finish before scanning so it's OK
// to set power here.
if ( pMgmt - > eScanState ! = WMAC_NO_SCANNING ) {
RFbSetPower ( pDevice , wCurrentRate , pDevice - > byCurrentCh ) ;
} else {
RFbSetPower ( pDevice , wCurrentRate , pMgmt - > uCurrChannel ) ;
}
pDevice - > wCurrentRate = wCurrentRate ;
//Set packet type
if ( byPktType = = PK_TYPE_11A ) { //0000 0000 0000 0000
pTxBufHead - > wFIFOCtl = 0 ;
}
else if ( byPktType = = PK_TYPE_11B ) { //0000 0001 0000 0000
pTxBufHead - > wFIFOCtl | = FIFOCTL_11B ;
}
else if ( byPktType = = PK_TYPE_11GB ) { //0000 0010 0000 0000
pTxBufHead - > wFIFOCtl | = FIFOCTL_11GB ;
}
else if ( byPktType = = PK_TYPE_11GA ) { //0000 0011 0000 0000
pTxBufHead - > wFIFOCtl | = FIFOCTL_11GA ;
}
pTxBufHead - > wFIFOCtl | = FIFOCTL_TMOEN ;
pTxBufHead - > wTimeStamp = cpu_to_le16 ( DEFAULT_MGN_LIFETIME_RES_64us ) ;
if ( IS_MULTICAST_ADDRESS ( & ( pPacket - > p80211Header - > sA3 . abyAddr1 [ 0 ] ) ) | |
IS_BROADCAST_ADDRESS ( & ( pPacket - > p80211Header - > sA3 . abyAddr1 [ 0 ] ) ) ) {
bNeedACK = FALSE ;
}
else {
bNeedACK = TRUE ;
pTxBufHead - > wFIFOCtl | = FIFOCTL_NEEDACK ;
} ;
if ( ( pMgmt - > eCurrMode = = WMAC_MODE_ESS_AP ) | |
( pMgmt - > eCurrMode = = WMAC_MODE_IBSS_STA ) ) {
pTxBufHead - > wFIFOCtl | = FIFOCTL_LRETRY ;
//Set Preamble type always long
//pDevice->byPreambleType = PREAMBLE_LONG;
// probe-response don't retry
//if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
// bNeedACK = FALSE;
// pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
//}
}
pTxBufHead - > wFIFOCtl | = ( FIFOCTL_GENINT | FIFOCTL_ISDMA0 ) ;
if ( ( pPacket - > p80211Header - > sA4 . wFrameCtl & TYPE_SUBTYPE_MASK ) = = TYPE_CTL_PSPOLL ) {
bIsPSPOLL = TRUE ;
cbMacHdLen = WLAN_HDR_ADDR2_LEN ;
} else {
cbMacHdLen = WLAN_HDR_ADDR3_LEN ;
}
//Set FRAGCTL_MACHDCNT
pTxBufHead - > wFragCtl | = cpu_to_le16 ( ( WORD ) ( cbMacHdLen < < 10 ) ) ;
// Notes:
// Although spec says MMPDU can be fragmented; In most case,
// no one will send a MMPDU under fragmentation. With RTS may occur.
pDevice - > bAES = FALSE ; //Set FRAGCTL_WEPTYP
if ( WLAN_GET_FC_ISWEP ( pPacket - > p80211Header - > sA4 . wFrameCtl ) ! = 0 ) {
if ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption1Enabled ) {
cbIVlen = 4 ;
cbICVlen = 4 ;
pTxBufHead - > wFragCtl | = FRAGCTL_LEGACY ;
}
else if ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption2Enabled ) {
cbIVlen = 8 ; //IV+ExtIV
cbMIClen = 8 ;
cbICVlen = 4 ;
pTxBufHead - > wFragCtl | = FRAGCTL_TKIP ;
//We need to get seed here for filling TxKey entry.
//TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
// pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
}
else if ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption3Enabled ) {
cbIVlen = 8 ; //RSN Header
cbICVlen = 8 ; //MIC
pTxBufHead - > wFragCtl | = FRAGCTL_AES ;
pDevice - > bAES = TRUE ;
}
//MAC Header should be padding 0 to DW alignment.
uPadding = 4 - ( cbMacHdLen % 4 ) ;
uPadding % = 4 ;
}
cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen ;
//Set FIFOCTL_GrpAckPolicy
if ( pDevice - > bGrpAckPolicy = = TRUE ) { //0000 0100 0000 0000
pTxBufHead - > wFIFOCtl | = FIFOCTL_GRPACK ;
}
//the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
//Set RrvTime/RTS/CTS Buffer
if ( byPktType = = PK_TYPE_11GB | | byPktType = = PK_TYPE_11GA ) { //802.11g packet
pvRrvTime = ( PSRrvTime_gCTS ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = NULL ;
pvRTS = NULL ;
pCTS = ( PSCTS ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gCTS ) ) ;
pvTxDataHd = ( PSTxDataHead_g ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gCTS ) + sizeof ( SCTS ) ) ;
cbHeaderSize = wTxBufSize + sizeof ( SRrvTime_gCTS ) + sizeof ( SCTS ) + sizeof ( STxDataHead_g ) ;
}
else { // 802.11a/b packet
pvRrvTime = ( PSRrvTime_ab ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = NULL ;
pvRTS = NULL ;
pCTS = NULL ;
pvTxDataHd = ( PSTxDataHead_ab ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) ) ;
cbHeaderSize = wTxBufSize + sizeof ( SRrvTime_ab ) + sizeof ( STxDataHead_ab ) ;
}
2009-08-12 21:54:11 +00:00
memset ( ( PVOID ) ( pbyTxBufferAddr + wTxBufSize ) , 0 , ( cbHeaderSize - wTxBufSize ) ) ;
2009-06-13 11:38:31 +00:00
2009-08-12 21:54:11 +00:00
memcpy ( & ( sEthHeader . abyDstAddr [ 0 ] ) , & ( pPacket - > p80211Header - > sA3 . abyAddr1 [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
memcpy ( & ( sEthHeader . abySrcAddr [ 0 ] ) , & ( pPacket - > p80211Header - > sA3 . abyAddr2 [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
//=========================
// No Fragmentation
//=========================
pTxBufHead - > wFragCtl | = ( WORD ) FRAGCTL_NONFRAG ;
//Fill FIFO,RrvTime,RTS,and CTS
s_vGenerateTxParameter ( pDevice , byPktType , wCurrentRate , pbyTxBufferAddr , pvRrvTime , pvRTS , pCTS ,
cbFrameSize , bNeedACK , TYPE_TXDMA0 , & sEthHeader ) ;
//Fill DataHead
uDuration = s_uFillDataHead ( pDevice , byPktType , wCurrentRate , pvTxDataHd , cbFrameSize , TYPE_TXDMA0 , bNeedACK ,
0 , 0 , 1 , AUTO_FB_NONE ) ;
pMACHeader = ( PS802_11Header ) ( pbyTxBufferAddr + cbHeaderSize ) ;
cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize ;
if ( WLAN_GET_FC_ISWEP ( pPacket - > p80211Header - > sA4 . wFrameCtl ) ! = 0 ) {
PBYTE pbyIVHead ;
PBYTE pbyPayloadHead ;
PBYTE pbyBSSID ;
PSKeyItem pTransmitKey = NULL ;
pbyIVHead = ( PBYTE ) ( pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding ) ;
pbyPayloadHead = ( PBYTE ) ( pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen ) ;
do {
if ( ( pDevice - > eOPMode = = OP_MODE_INFRASTRUCTURE ) & &
( pDevice - > bLinkPass = = TRUE ) ) {
pbyBSSID = pDevice - > abyBSSID ;
// get pairwise key
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , PAIRWISE_KEY , & pTransmitKey ) = = FALSE ) {
// get group key
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , GROUP_KEY , & pTransmitKey ) = = TRUE ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Get GTK. \n " ) ;
break ;
}
} else {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Get PTK. \n " ) ;
break ;
}
}
// get group key
pbyBSSID = pDevice - > abyBroadcastAddr ;
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , GROUP_KEY , & pTransmitKey ) = = FALSE ) {
pTransmitKey = NULL ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " KEY is NULL. OP Mode[%d] \n " , pDevice - > eOPMode ) ;
} else {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Get GTK. \n " ) ;
}
} while ( FALSE ) ;
//Fill TXKEY
s_vFillTxKey ( pDevice , ( PBYTE ) ( pTxBufHead - > adwTxKey ) , pbyIVHead , pTransmitKey ,
( PBYTE ) pMACHeader , ( WORD ) cbFrameBodySize , NULL ) ;
2009-08-12 21:54:11 +00:00
memcpy ( pMACHeader , pPacket - > p80211Header , cbMacHdLen ) ;
memcpy ( pbyPayloadHead , ( ( PBYTE ) ( pPacket - > p80211Header ) + cbMacHdLen ) ,
2009-06-13 11:38:31 +00:00
cbFrameBodySize ) ;
}
else {
// Copy the Packet into a tx Buffer
2009-08-12 21:54:11 +00:00
memcpy ( pMACHeader , pPacket - > p80211Header , pPacket - > cbMPDULen ) ;
2009-06-13 11:38:31 +00:00
}
pMACHeader - > wSeqCtl = cpu_to_le16 ( pDevice - > wSeqCounter < < 4 ) ;
pDevice - > wSeqCounter + + ;
if ( pDevice - > wSeqCounter > 0x0fff )
pDevice - > wSeqCounter = 0 ;
if ( bIsPSPOLL ) {
// The MAC will automatically replace the Duration-field of MAC header by Duration-field
// of FIFO control header.
// This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
// in the same place of other packet's Duration-field).
// And it will cause Cisco-AP to issue Disassociation-packet
if ( byPktType = = PK_TYPE_11GB | | byPktType = = PK_TYPE_11GA ) {
( ( PSTxDataHead_g ) pvTxDataHd ) - > wDuration_a = cpu_to_le16 ( pPacket - > p80211Header - > sA2 . wDurationID ) ;
( ( PSTxDataHead_g ) pvTxDataHd ) - > wDuration_b = cpu_to_le16 ( pPacket - > p80211Header - > sA2 . wDurationID ) ;
} else {
( ( PSTxDataHead_ab ) pvTxDataHd ) - > wDuration = cpu_to_le16 ( pPacket - > p80211Header - > sA2 . wDurationID ) ;
}
}
pTX_Buffer - > wTxByteCount = cpu_to_le16 ( ( WORD ) ( cbReqCount ) ) ;
pTX_Buffer - > byPKTNO = ( BYTE ) ( ( ( wCurrentRate < < 4 ) & 0x00F0 ) | ( ( pDevice - > wSeqCounter - 1 ) & 0x000F ) ) ;
pTX_Buffer - > byType = 0x00 ;
pContext - > pPacket = NULL ;
pContext - > Type = CONTEXT_MGMT_PACKET ;
pContext - > uBufLen = ( WORD ) cbReqCount + 4 ; //USB header
if ( WLAN_GET_FC_TODS ( pMACHeader - > wFrameCtl ) = = 0 ) {
s_vSaveTxPktInfo ( pDevice , ( BYTE ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pMACHeader - > abyAddr1 [ 0 ] ) , ( WORD ) cbFrameSize , pTX_Buffer - > wFIFOCtl ) ;
}
else {
s_vSaveTxPktInfo ( pDevice , ( BYTE ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pMACHeader - > abyAddr3 [ 0 ] ) , ( WORD ) cbFrameSize , pTX_Buffer - > wFIFOCtl ) ;
}
PIPEnsSendBulkOut ( pDevice , pContext ) ;
return CMD_STATUS_PENDING ;
}
CMD_STATUS
csBeacon_xmit (
IN PSDevice pDevice ,
IN PSTxMgmtPacket pPacket
)
{
UINT cbFrameSize = pPacket - > cbMPDULen + WLAN_FCS_LEN ;
UINT cbHeaderSize = 0 ;
WORD wTxBufSize = sizeof ( STxShortBufHead ) ;
PSTxShortBufHead pTxBufHead ;
PS802_11Header pMACHeader ;
PSTxDataHead_ab pTxDataHead ;
WORD wCurrentRate ;
UINT cbFrameBodySize ;
UINT cbReqCount ;
PBEACON_BUFFER pTX_Buffer ;
PBYTE pbyTxBufferAddr ;
PUSB_SEND_CONTEXT pContext ;
CMD_STATUS status ;
pContext = ( PUSB_SEND_CONTEXT ) s_vGetFreeContext ( pDevice ) ;
if ( NULL = = pContext ) {
status = CMD_STATUS_RESOURCES ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " ManagementSend TX...NO CONTEXT! \n " ) ;
return status ;
}
pTX_Buffer = ( PBEACON_BUFFER ) ( & pContext - > Data [ 0 ] ) ;
pbyTxBufferAddr = ( PBYTE ) & ( pTX_Buffer - > wFIFOCtl ) ;
cbFrameBodySize = pPacket - > cbPayloadLen ;
pTxBufHead = ( PSTxShortBufHead ) pbyTxBufferAddr ;
wTxBufSize = sizeof ( STxShortBufHead ) ;
memset ( pTxBufHead , 0 , wTxBufSize ) ;
if ( pDevice - > byBBType = = BB_TYPE_11A ) {
wCurrentRate = RATE_6M ;
pTxDataHead = ( PSTxDataHead_ab ) ( pbyTxBufferAddr + wTxBufSize ) ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , cbFrameSize , wCurrentRate , PK_TYPE_11A ,
( PWORD ) & ( pTxDataHead - > wTransmitLength ) , ( PBYTE ) & ( pTxDataHead - > byServiceField ) , ( PBYTE ) & ( pTxDataHead - > bySignalField )
) ;
//Get Duration and TimeStampOff
pTxDataHead - > wDuration = cpu_to_le16 ( ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_A , cbFrameSize , PK_TYPE_11A ,
wCurrentRate , FALSE , 0 , 0 , 1 , AUTO_FB_NONE ) ) ;
pTxDataHead - > wTimeStampOff = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ wCurrentRate % MAX_RATE ] ;
cbHeaderSize = wTxBufSize + sizeof ( STxDataHead_ab ) ;
} else {
wCurrentRate = RATE_1M ;
pTxBufHead - > wFIFOCtl | = FIFOCTL_11B ;
pTxDataHead = ( PSTxDataHead_ab ) ( pbyTxBufferAddr + wTxBufSize ) ;
//Get SignalField,ServiceField,Length
BBvCaculateParameter ( pDevice , cbFrameSize , wCurrentRate , PK_TYPE_11B ,
( PWORD ) & ( pTxDataHead - > wTransmitLength ) , ( PBYTE ) & ( pTxDataHead - > byServiceField ) , ( PBYTE ) & ( pTxDataHead - > bySignalField )
) ;
//Get Duration and TimeStampOff
pTxDataHead - > wDuration = cpu_to_le16 ( ( WORD ) s_uGetDataDuration ( pDevice , DATADUR_B , cbFrameSize , PK_TYPE_11B ,
wCurrentRate , FALSE , 0 , 0 , 1 , AUTO_FB_NONE ) ) ;
pTxDataHead - > wTimeStampOff = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ wCurrentRate % MAX_RATE ] ;
cbHeaderSize = wTxBufSize + sizeof ( STxDataHead_ab ) ;
}
//Generate Beacon Header
pMACHeader = ( PS802_11Header ) ( pbyTxBufferAddr + cbHeaderSize ) ;
2009-08-12 21:54:11 +00:00
memcpy ( pMACHeader , pPacket - > p80211Header , pPacket - > cbMPDULen ) ;
2009-06-13 11:38:31 +00:00
pMACHeader - > wDurationID = 0 ;
pMACHeader - > wSeqCtl = cpu_to_le16 ( pDevice - > wSeqCounter < < 4 ) ;
pDevice - > wSeqCounter + + ;
if ( pDevice - > wSeqCounter > 0x0fff )
pDevice - > wSeqCounter = 0 ;
cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize ;
pTX_Buffer - > wTxByteCount = ( WORD ) cbReqCount ;
pTX_Buffer - > byPKTNO = ( BYTE ) ( ( ( wCurrentRate < < 4 ) & 0x00F0 ) | ( ( pDevice - > wSeqCounter - 1 ) & 0x000F ) ) ;
pTX_Buffer - > byType = 0x01 ;
pContext - > pPacket = NULL ;
pContext - > Type = CONTEXT_MGMT_PACKET ;
pContext - > uBufLen = ( WORD ) cbReqCount + 4 ; //USB header
PIPEnsSendBulkOut ( pDevice , pContext ) ;
return CMD_STATUS_PENDING ;
}
VOID
vDMA0_tx_80211 ( PSDevice pDevice , struct sk_buff * skb ) {
PSMgmtObject pMgmt = & ( pDevice - > sMgmtObj ) ;
BYTE byPktType ;
PBYTE pbyTxBufferAddr ;
PVOID pvRTS ;
PVOID pvCTS ;
PVOID pvTxDataHd ;
UINT uDuration ;
UINT cbReqCount ;
PS802_11Header pMACHeader ;
UINT cbHeaderSize ;
UINT cbFrameBodySize ;
BOOL bNeedACK ;
BOOL bIsPSPOLL = FALSE ;
PSTxBufHead pTxBufHead ;
UINT cbFrameSize ;
UINT cbIVlen = 0 ;
UINT cbICVlen = 0 ;
UINT cbMIClen = 0 ;
UINT cbFCSlen = 4 ;
UINT uPadding = 0 ;
UINT cbMICHDR = 0 ;
UINT uLength = 0 ;
DWORD dwMICKey0 , dwMICKey1 ;
DWORD dwMIC_Priority ;
PDWORD pdwMIC_L ;
PDWORD pdwMIC_R ;
WORD wTxBufSize ;
UINT cbMacHdLen ;
SEthernetHeader sEthHeader ;
PVOID pvRrvTime ;
PVOID pMICHDR ;
WORD wCurrentRate = RATE_1M ;
PUWLAN_80211HDR p80211Header ;
UINT uNodeIndex = 0 ;
BOOL bNodeExist = FALSE ;
SKeyItem STempKey ;
PSKeyItem pTransmitKey = NULL ;
PBYTE pbyIVHead ;
PBYTE pbyPayloadHead ;
PBYTE pbyMacHdr ;
UINT cbExtSuppRate = 0 ;
PTX_BUFFER pTX_Buffer ;
PUSB_SEND_CONTEXT pContext ;
// PWLAN_IE pItem;
pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL ;
if ( skb - > len < = WLAN_HDR_ADDR3_LEN ) {
cbFrameBodySize = 0 ;
}
else {
cbFrameBodySize = skb - > len - WLAN_HDR_ADDR3_LEN ;
}
p80211Header = ( PUWLAN_80211HDR ) skb - > data ;
pContext = ( PUSB_SEND_CONTEXT ) s_vGetFreeContext ( pDevice ) ;
if ( NULL = = pContext ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " DMA0 TX...NO CONTEXT! \n " ) ;
dev_kfree_skb_irq ( skb ) ;
return ;
}
pTX_Buffer = ( PTX_BUFFER ) ( & pContext - > Data [ 0 ] ) ;
pbyTxBufferAddr = ( PBYTE ) ( & pTX_Buffer - > adwTxKey [ 0 ] ) ;
pTxBufHead = ( PSTxBufHead ) pbyTxBufferAddr ;
wTxBufSize = sizeof ( STxBufHead ) ;
memset ( pTxBufHead , 0 , wTxBufSize ) ;
if ( pDevice - > byBBType = = BB_TYPE_11A ) {
wCurrentRate = RATE_6M ;
byPktType = PK_TYPE_11A ;
} else {
wCurrentRate = RATE_1M ;
byPktType = PK_TYPE_11B ;
}
// SetPower will cause error power TX state for OFDM Date packet in TX buffer.
// 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
// And cmd timer will wait data pkt TX finish before scanning so it's OK
// to set power here.
if ( pMgmt - > eScanState ! = WMAC_NO_SCANNING ) {
RFbSetPower ( pDevice , wCurrentRate , pDevice - > byCurrentCh ) ;
} else {
RFbSetPower ( pDevice , wCurrentRate , pMgmt - > uCurrChannel ) ;
}
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n " , p80211Header - > sA3 . wFrameCtl ) ;
//Set packet type
if ( byPktType = = PK_TYPE_11A ) { //0000 0000 0000 0000
pTxBufHead - > wFIFOCtl = 0 ;
}
else if ( byPktType = = PK_TYPE_11B ) { //0000 0001 0000 0000
pTxBufHead - > wFIFOCtl | = FIFOCTL_11B ;
}
else if ( byPktType = = PK_TYPE_11GB ) { //0000 0010 0000 0000
pTxBufHead - > wFIFOCtl | = FIFOCTL_11GB ;
}
else if ( byPktType = = PK_TYPE_11GA ) { //0000 0011 0000 0000
pTxBufHead - > wFIFOCtl | = FIFOCTL_11GA ;
}
pTxBufHead - > wFIFOCtl | = FIFOCTL_TMOEN ;
pTxBufHead - > wTimeStamp = cpu_to_le16 ( DEFAULT_MGN_LIFETIME_RES_64us ) ;
if ( IS_MULTICAST_ADDRESS ( & ( p80211Header - > sA3 . abyAddr1 [ 0 ] ) ) | |
IS_BROADCAST_ADDRESS ( & ( p80211Header - > sA3 . abyAddr1 [ 0 ] ) ) ) {
bNeedACK = FALSE ;
if ( pDevice - > bEnableHostWEP ) {
uNodeIndex = 0 ;
bNodeExist = TRUE ;
} ;
}
else {
if ( pDevice - > bEnableHostWEP ) {
if ( BSSbIsSTAInNodeDB ( pDevice , ( PBYTE ) ( p80211Header - > sA3 . abyAddr1 ) , & uNodeIndex ) )
bNodeExist = TRUE ;
} ;
bNeedACK = TRUE ;
pTxBufHead - > wFIFOCtl | = FIFOCTL_NEEDACK ;
} ;
if ( ( pMgmt - > eCurrMode = = WMAC_MODE_ESS_AP ) | |
( pMgmt - > eCurrMode = = WMAC_MODE_IBSS_STA ) ) {
pTxBufHead - > wFIFOCtl | = FIFOCTL_LRETRY ;
//Set Preamble type always long
//pDevice->byPreambleType = PREAMBLE_LONG;
// probe-response don't retry
//if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
// bNeedACK = FALSE;
// pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
//}
}
pTxBufHead - > wFIFOCtl | = ( FIFOCTL_GENINT | FIFOCTL_ISDMA0 ) ;
if ( ( p80211Header - > sA4 . wFrameCtl & TYPE_SUBTYPE_MASK ) = = TYPE_CTL_PSPOLL ) {
bIsPSPOLL = TRUE ;
cbMacHdLen = WLAN_HDR_ADDR2_LEN ;
} else {
cbMacHdLen = WLAN_HDR_ADDR3_LEN ;
}
// hostapd deamon ext support rate patch
if ( WLAN_GET_FC_FSTYPE ( p80211Header - > sA4 . wFrameCtl ) = = WLAN_FSTYPE_ASSOCRESP ) {
if ( ( ( PWLAN_IE_SUPP_RATES ) pMgmt - > abyCurrSuppRates ) - > len ! = 0 ) {
cbExtSuppRate + = ( ( PWLAN_IE_SUPP_RATES ) pMgmt - > abyCurrSuppRates ) - > len + WLAN_IEHDR_LEN ;
}
if ( ( ( PWLAN_IE_SUPP_RATES ) pMgmt - > abyCurrExtSuppRates ) - > len ! = 0 ) {
cbExtSuppRate + = ( ( PWLAN_IE_SUPP_RATES ) pMgmt - > abyCurrExtSuppRates ) - > len + WLAN_IEHDR_LEN ;
}
if ( cbExtSuppRate > 0 ) {
cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES ;
}
}
//Set FRAGCTL_MACHDCNT
pTxBufHead - > wFragCtl | = cpu_to_le16 ( ( WORD ) cbMacHdLen < < 10 ) ;
// Notes:
// Although spec says MMPDU can be fragmented; In most case,
// no one will send a MMPDU under fragmentation. With RTS may occur.
pDevice - > bAES = FALSE ; //Set FRAGCTL_WEPTYP
if ( WLAN_GET_FC_ISWEP ( p80211Header - > sA4 . wFrameCtl ) ! = 0 ) {
if ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption1Enabled ) {
cbIVlen = 4 ;
cbICVlen = 4 ;
pTxBufHead - > wFragCtl | = FRAGCTL_LEGACY ;
}
else if ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption2Enabled ) {
cbIVlen = 8 ; //IV+ExtIV
cbMIClen = 8 ;
cbICVlen = 4 ;
pTxBufHead - > wFragCtl | = FRAGCTL_TKIP ;
//We need to get seed here for filling TxKey entry.
//TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
// pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
}
else if ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption3Enabled ) {
cbIVlen = 8 ; //RSN Header
cbICVlen = 8 ; //MIC
cbMICHDR = sizeof ( SMICHDRHead ) ;
pTxBufHead - > wFragCtl | = FRAGCTL_AES ;
pDevice - > bAES = TRUE ;
}
//MAC Header should be padding 0 to DW alignment.
uPadding = 4 - ( cbMacHdLen % 4 ) ;
uPadding % = 4 ;
}
cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate ;
//Set FIFOCTL_GrpAckPolicy
if ( pDevice - > bGrpAckPolicy = = TRUE ) { //0000 0100 0000 0000
pTxBufHead - > wFIFOCtl | = FIFOCTL_GRPACK ;
}
//the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
if ( byPktType = = PK_TYPE_11GB | | byPktType = = PK_TYPE_11GA ) { //802.11g packet
pvRrvTime = ( PSRrvTime_gCTS ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = ( PSMICHDRHead ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gCTS ) ) ;
pvRTS = NULL ;
pvCTS = ( PSCTS ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gCTS ) + cbMICHDR ) ;
pvTxDataHd = ( PSTxDataHead_g ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_gCTS ) + cbMICHDR + sizeof ( SCTS ) ) ;
cbHeaderSize = wTxBufSize + sizeof ( SRrvTime_gCTS ) + cbMICHDR + sizeof ( SCTS ) + sizeof ( STxDataHead_g ) ;
}
else { //802.11a/b packet
pvRrvTime = ( PSRrvTime_ab ) ( pbyTxBufferAddr + wTxBufSize ) ;
pMICHDR = ( PSMICHDRHead ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) ) ;
pvRTS = NULL ;
pvCTS = NULL ;
pvTxDataHd = ( PSTxDataHead_ab ) ( pbyTxBufferAddr + wTxBufSize + sizeof ( SRrvTime_ab ) + cbMICHDR ) ;
cbHeaderSize = wTxBufSize + sizeof ( SRrvTime_ab ) + cbMICHDR + sizeof ( STxDataHead_ab ) ;
}
2009-08-12 21:54:11 +00:00
memset ( ( PVOID ) ( pbyTxBufferAddr + wTxBufSize ) , 0 , ( cbHeaderSize - wTxBufSize ) ) ;
memcpy ( & ( sEthHeader . abyDstAddr [ 0 ] ) , & ( p80211Header - > sA3 . abyAddr1 [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
memcpy ( & ( sEthHeader . abySrcAddr [ 0 ] ) , & ( p80211Header - > sA3 . abyAddr2 [ 0 ] ) , U_ETHER_ADDR_LEN ) ;
2009-06-13 11:38:31 +00:00
//=========================
// No Fragmentation
//=========================
pTxBufHead - > wFragCtl | = ( WORD ) FRAGCTL_NONFRAG ;
//Fill FIFO,RrvTime,RTS,and CTS
s_vGenerateTxParameter ( pDevice , byPktType , wCurrentRate , pbyTxBufferAddr , pvRrvTime , pvRTS , pvCTS ,
cbFrameSize , bNeedACK , TYPE_TXDMA0 , & sEthHeader ) ;
//Fill DataHead
uDuration = s_uFillDataHead ( pDevice , byPktType , wCurrentRate , pvTxDataHd , cbFrameSize , TYPE_TXDMA0 , bNeedACK ,
0 , 0 , 1 , AUTO_FB_NONE ) ;
pMACHeader = ( PS802_11Header ) ( pbyTxBufferAddr + cbHeaderSize ) ;
cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + ( cbFrameBodySize + cbMIClen ) + cbExtSuppRate ;
pbyMacHdr = ( PBYTE ) ( pbyTxBufferAddr + cbHeaderSize ) ;
pbyPayloadHead = ( PBYTE ) ( pbyMacHdr + cbMacHdLen + uPadding + cbIVlen ) ;
pbyIVHead = ( PBYTE ) ( pbyMacHdr + cbMacHdLen + uPadding ) ;
// Copy the Packet into a tx Buffer
memcpy ( pbyMacHdr , skb - > data , cbMacHdLen ) ;
// version set to 0, patch for hostapd deamon
pMACHeader - > wFrameCtl & = cpu_to_le16 ( 0xfffc ) ;
memcpy ( pbyPayloadHead , ( skb - > data + cbMacHdLen ) , cbFrameBodySize ) ;
// replace support rate, patch for hostapd deamon( only support 11M)
if ( WLAN_GET_FC_FSTYPE ( p80211Header - > sA4 . wFrameCtl ) = = WLAN_FSTYPE_ASSOCRESP ) {
if ( cbExtSuppRate ! = 0 ) {
if ( ( ( PWLAN_IE_SUPP_RATES ) pMgmt - > abyCurrSuppRates ) - > len ! = 0 )
memcpy ( ( pbyPayloadHead + cbFrameBodySize ) ,
pMgmt - > abyCurrSuppRates ,
( ( PWLAN_IE_SUPP_RATES ) pMgmt - > abyCurrSuppRates ) - > len + WLAN_IEHDR_LEN
) ;
if ( ( ( PWLAN_IE_SUPP_RATES ) pMgmt - > abyCurrExtSuppRates ) - > len ! = 0 )
memcpy ( ( pbyPayloadHead + cbFrameBodySize ) + ( ( PWLAN_IE_SUPP_RATES ) pMgmt - > abyCurrSuppRates ) - > len + WLAN_IEHDR_LEN ,
pMgmt - > abyCurrExtSuppRates ,
( ( PWLAN_IE_SUPP_RATES ) pMgmt - > abyCurrExtSuppRates ) - > len + WLAN_IEHDR_LEN
) ;
}
}
// Set wep
if ( WLAN_GET_FC_ISWEP ( p80211Header - > sA4 . wFrameCtl ) ! = 0 ) {
if ( pDevice - > bEnableHostWEP ) {
pTransmitKey = & STempKey ;
pTransmitKey - > byCipherSuite = pMgmt - > sNodeDBTable [ uNodeIndex ] . byCipherSuite ;
pTransmitKey - > dwKeyIndex = pMgmt - > sNodeDBTable [ uNodeIndex ] . dwKeyIndex ;
pTransmitKey - > uKeyLength = pMgmt - > sNodeDBTable [ uNodeIndex ] . uWepKeyLength ;
pTransmitKey - > dwTSC47_16 = pMgmt - > sNodeDBTable [ uNodeIndex ] . dwTSC47_16 ;
pTransmitKey - > wTSC15_0 = pMgmt - > sNodeDBTable [ uNodeIndex ] . wTSC15_0 ;
memcpy ( pTransmitKey - > abyKey ,
& pMgmt - > sNodeDBTable [ uNodeIndex ] . abyWepKey [ 0 ] ,
pTransmitKey - > uKeyLength
) ;
}
if ( ( pTransmitKey ! = NULL ) & & ( pTransmitKey - > byCipherSuite = = KEY_CTL_TKIP ) ) {
dwMICKey0 = * ( PDWORD ) ( & pTransmitKey - > abyKey [ 16 ] ) ;
dwMICKey1 = * ( PDWORD ) ( & pTransmitKey - > abyKey [ 20 ] ) ;
// DO Software Michael
MIC_vInit ( dwMICKey0 , dwMICKey1 ) ;
MIC_vAppend ( ( PBYTE ) & ( sEthHeader . abyDstAddr [ 0 ] ) , 12 ) ;
dwMIC_Priority = 0 ;
MIC_vAppend ( ( PBYTE ) & dwMIC_Priority , 4 ) ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " DMA0_tx_8021:MIC KEY: %lX, %lX \n " , dwMICKey0 , dwMICKey1 ) ;
uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen ;
MIC_vAppend ( ( pbyTxBufferAddr + uLength ) , cbFrameBodySize ) ;
pdwMIC_L = ( PDWORD ) ( pbyTxBufferAddr + uLength + cbFrameBodySize ) ;
pdwMIC_R = ( PDWORD ) ( pbyTxBufferAddr + uLength + cbFrameBodySize + 4 ) ;
MIC_vGetMIC ( pdwMIC_L , pdwMIC_R ) ;
MIC_vUnInit ( ) ;
if ( pDevice - > bTxMICFail = = TRUE ) {
* pdwMIC_L = 0 ;
* pdwMIC_R = 0 ;
pDevice - > bTxMICFail = FALSE ;
}
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " uLength: %d, %d \n " , uLength , cbFrameBodySize ) ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " cbReqCount:%d, %d, %d, %d \n " , cbReqCount , cbHeaderSize , uPadding , cbIVlen ) ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " MIC:%lx, %lx \n " , * pdwMIC_L , * pdwMIC_R ) ;
}
s_vFillTxKey ( pDevice , ( PBYTE ) ( pTxBufHead - > adwTxKey ) , pbyIVHead , pTransmitKey ,
pbyMacHdr , ( WORD ) cbFrameBodySize , ( PBYTE ) pMICHDR ) ;
if ( pDevice - > bEnableHostWEP ) {
pMgmt - > sNodeDBTable [ uNodeIndex ] . dwTSC47_16 = pTransmitKey - > dwTSC47_16 ;
pMgmt - > sNodeDBTable [ uNodeIndex ] . wTSC15_0 = pTransmitKey - > wTSC15_0 ;
}
if ( ( pDevice - > byLocalID < = REV_ID_VT3253_A1 ) ) {
s_vSWencryption ( pDevice , pTransmitKey , pbyPayloadHead , ( WORD ) ( cbFrameBodySize + cbMIClen ) ) ;
}
}
pMACHeader - > wSeqCtl = cpu_to_le16 ( pDevice - > wSeqCounter < < 4 ) ;
pDevice - > wSeqCounter + + ;
if ( pDevice - > wSeqCounter > 0x0fff )
pDevice - > wSeqCounter = 0 ;
if ( bIsPSPOLL ) {
// The MAC will automatically replace the Duration-field of MAC header by Duration-field
// of FIFO control header.
// This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
// in the same place of other packet's Duration-field).
// And it will cause Cisco-AP to issue Disassociation-packet
if ( byPktType = = PK_TYPE_11GB | | byPktType = = PK_TYPE_11GA ) {
( ( PSTxDataHead_g ) pvTxDataHd ) - > wDuration_a = cpu_to_le16 ( p80211Header - > sA2 . wDurationID ) ;
( ( PSTxDataHead_g ) pvTxDataHd ) - > wDuration_b = cpu_to_le16 ( p80211Header - > sA2 . wDurationID ) ;
} else {
( ( PSTxDataHead_ab ) pvTxDataHd ) - > wDuration = cpu_to_le16 ( p80211Header - > sA2 . wDurationID ) ;
}
}
pTX_Buffer - > wTxByteCount = cpu_to_le16 ( ( WORD ) ( cbReqCount ) ) ;
pTX_Buffer - > byPKTNO = ( BYTE ) ( ( ( wCurrentRate < < 4 ) & 0x00F0 ) | ( ( pDevice - > wSeqCounter - 1 ) & 0x000F ) ) ;
pTX_Buffer - > byType = 0x00 ;
pContext - > pPacket = skb ;
pContext - > Type = CONTEXT_MGMT_PACKET ;
pContext - > uBufLen = ( WORD ) cbReqCount + 4 ; //USB header
if ( WLAN_GET_FC_TODS ( pMACHeader - > wFrameCtl ) = = 0 ) {
s_vSaveTxPktInfo ( pDevice , ( BYTE ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pMACHeader - > abyAddr1 [ 0 ] ) , ( WORD ) cbFrameSize , pTX_Buffer - > wFIFOCtl ) ;
}
else {
s_vSaveTxPktInfo ( pDevice , ( BYTE ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pMACHeader - > abyAddr3 [ 0 ] ) , ( WORD ) cbFrameSize , pTX_Buffer - > wFIFOCtl ) ;
}
PIPEnsSendBulkOut ( pDevice , pContext ) ;
return ;
}
//TYPE_AC0DMA data tx
/*
* Description :
* Tx packet via AC0DMA ( DMA1 )
*
* Parameters :
* In :
* pDevice - Pointer to the adapter
* skb - Pointer to tx skb packet
* Out :
* void
*
* Return Value : NULL
*/
NTSTATUS
nsDMA_tx_packet (
IN PSDevice pDevice ,
IN UINT uDMAIdx ,
IN struct sk_buff * skb
)
{
PSMgmtObject pMgmt = & ( pDevice - > sMgmtObj ) ;
UINT BytesToWrite = 0 , uHeaderLen = 0 ;
UINT uNodeIndex = 0 ;
BYTE byMask [ 8 ] = { 1 , 2 , 4 , 8 , 0x10 , 0x20 , 0x40 , 0x80 } ;
WORD wAID ;
BYTE byPktType ;
BOOL bNeedEncryption = FALSE ;
PSKeyItem pTransmitKey = NULL ;
SKeyItem STempKey ;
UINT ii ;
BOOL bTKIP_UseGTK = FALSE ;
BOOL bNeedDeAuth = FALSE ;
PBYTE pbyBSSID ;
BOOL bNodeExist = FALSE ;
PUSB_SEND_CONTEXT pContext ;
BOOL fConvertedPacket ;
PTX_BUFFER pTX_Buffer ;
UINT status ;
WORD wKeepRate = pDevice - > wCurrentRate ;
struct net_device_stats * pStats = & pDevice - > stats ;
//#ifdef WPA_SM_Transtatus
// extern SWPAResult wpa_Result;
//#endif
BOOL bTxeapol_key = FALSE ;
if ( pMgmt - > eCurrMode = = WMAC_MODE_ESS_AP ) {
if ( pDevice - > uAssocCount = = 0 ) {
dev_kfree_skb_irq ( skb ) ;
return 0 ;
}
if ( IS_MULTICAST_ADDRESS ( ( PBYTE ) ( skb - > data ) ) ) {
uNodeIndex = 0 ;
bNodeExist = TRUE ;
if ( pMgmt - > sNodeDBTable [ 0 ] . bPSEnable ) {
skb_queue_tail ( & ( pMgmt - > sNodeDBTable [ 0 ] . sTxPSQueue ) , skb ) ;
pMgmt - > sNodeDBTable [ 0 ] . wEnQueueCnt + + ;
// set tx map
pMgmt - > abyPSTxMap [ 0 ] | = byMask [ 0 ] ;
return 0 ;
}
// muticast/broadcast data rate
if ( pDevice - > byBBType ! = BB_TYPE_11A )
pDevice - > wCurrentRate = RATE_2M ;
else
pDevice - > wCurrentRate = RATE_24M ;
// long preamble type
pDevice - > byPreambleType = PREAMBLE_SHORT ;
} else {
if ( BSSbIsSTAInNodeDB ( pDevice , ( PBYTE ) ( skb - > data ) , & uNodeIndex ) ) {
if ( pMgmt - > sNodeDBTable [ uNodeIndex ] . bPSEnable ) {
skb_queue_tail ( & pMgmt - > sNodeDBTable [ uNodeIndex ] . sTxPSQueue , skb ) ;
pMgmt - > sNodeDBTable [ uNodeIndex ] . wEnQueueCnt + + ;
// set tx map
wAID = pMgmt - > sNodeDBTable [ uNodeIndex ] . wAID ;
pMgmt - > abyPSTxMap [ wAID > > 3 ] | = byMask [ wAID & 7 ] ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Set:pMgmt->abyPSTxMap[%d]= %d \n " ,
( wAID > > 3 ) , pMgmt - > abyPSTxMap [ wAID > > 3 ] ) ;
return 0 ;
}
// AP rate decided from node
pDevice - > wCurrentRate = pMgmt - > sNodeDBTable [ uNodeIndex ] . wTxDataRate ;
// tx preamble decided from node
if ( pMgmt - > sNodeDBTable [ uNodeIndex ] . bShortPreamble ) {
pDevice - > byPreambleType = pDevice - > byShortPreamble ;
} else {
pDevice - > byPreambleType = PREAMBLE_LONG ;
}
bNodeExist = TRUE ;
}
}
if ( bNodeExist = = FALSE ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " Unknown STA not found in node DB \n " ) ;
dev_kfree_skb_irq ( skb ) ;
return 0 ;
}
}
pContext = ( PUSB_SEND_CONTEXT ) s_vGetFreeContext ( pDevice ) ;
if ( pContext = = NULL ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " pContext == NULL \n " ) ;
dev_kfree_skb_irq ( skb ) ;
return STATUS_RESOURCES ;
}
memcpy ( pDevice - > sTxEthHeader . abyDstAddr , ( PBYTE ) ( skb - > data ) , U_HEADER_LEN ) ;
//mike add:station mode check eapol-key challenge--->
{
BYTE Protocol_Version ; //802.1x Authentication
BYTE Packet_Type ; //802.1x Authentication
BYTE Descriptor_type ;
WORD Key_info ;
Protocol_Version = skb - > data [ U_HEADER_LEN ] ;
Packet_Type = skb - > data [ U_HEADER_LEN + 1 ] ;
Descriptor_type = skb - > data [ U_HEADER_LEN + 1 + 1 + 2 ] ;
Key_info = ( skb - > data [ U_HEADER_LEN + 1 + 1 + 2 + 1 ] < < 8 ) | ( skb - > data [ U_HEADER_LEN + 1 + 1 + 2 + 2 ] ) ;
if ( pDevice - > sTxEthHeader . wType = = TYPE_PKT_802_1x ) {
if ( ( ( Protocol_Version = = 1 ) | | ( Protocol_Version = = 2 ) ) & &
( Packet_Type = = 3 ) ) { //802.1x OR eapol-key challenge frame transfer
bTxeapol_key = TRUE ;
if ( ! ( Key_info & BIT3 ) & & //WPA or RSN group-key challenge
( Key_info & BIT8 ) & & ( Key_info & BIT9 ) ) { //send 2/2 key
if ( Descriptor_type = = 254 ) {
pDevice - > fWPA_Authened = TRUE ;
PRINT_K ( " WPA " ) ;
}
else {
pDevice - > fWPA_Authened = TRUE ;
PRINT_K ( " WPA2(re-keying) " ) ;
}
PRINT_K ( " Authentication completed!! \n " ) ;
}
else if ( ( Key_info & BIT3 ) & & ( Descriptor_type = = 2 ) & & //RSN pairse-key challenge
( Key_info & BIT8 ) & & ( Key_info & BIT9 ) ) {
pDevice - > fWPA_Authened = TRUE ;
PRINT_K ( " WPA2 Authentication completed!! \n " ) ;
}
}
}
}
//mike add:station mode check eapol-key challenge<---
if ( pDevice - > bEncryptionEnable = = TRUE ) {
bNeedEncryption = TRUE ;
// get Transmit key
do {
if ( ( pMgmt - > eCurrMode = = WMAC_MODE_ESS_STA ) & &
( pMgmt - > eCurrState = = WMAC_STATE_ASSOC ) ) {
pbyBSSID = pDevice - > abyBSSID ;
// get pairwise key
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , PAIRWISE_KEY , & pTransmitKey ) = = FALSE ) {
// get group key
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , GROUP_KEY , & pTransmitKey ) = = TRUE ) {
bTKIP_UseGTK = TRUE ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " Get GTK. \n " ) ;
break ;
}
} else {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " Get PTK. \n " ) ;
break ;
}
} else if ( pMgmt - > eCurrMode = = WMAC_MODE_IBSS_STA ) {
pbyBSSID = pDevice - > sTxEthHeader . abyDstAddr ; //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " IBSS Serach Key: \n " ) ;
for ( ii = 0 ; ii < 6 ; ii + + )
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " %x \n " , * ( pbyBSSID + ii ) ) ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " \n " ) ;
// get pairwise key
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , PAIRWISE_KEY , & pTransmitKey ) = = TRUE )
break ;
}
// get group key
pbyBSSID = pDevice - > abyBroadcastAddr ;
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , GROUP_KEY , & pTransmitKey ) = = FALSE ) {
pTransmitKey = NULL ;
if ( pMgmt - > eCurrMode = = WMAC_MODE_IBSS_STA ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " IBSS and KEY is NULL. [%d] \n " , pMgmt - > eCurrMode ) ;
}
else
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " NOT IBSS and KEY is NULL. [%d] \n " , pMgmt - > eCurrMode ) ;
} else {
bTKIP_UseGTK = TRUE ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " Get GTK. \n " ) ;
}
} while ( FALSE ) ;
}
if ( pDevice - > bEnableHostWEP ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " acdma0: STA index %d \n " , uNodeIndex ) ;
if ( pDevice - > bEncryptionEnable = = TRUE ) {
pTransmitKey = & STempKey ;
pTransmitKey - > byCipherSuite = pMgmt - > sNodeDBTable [ uNodeIndex ] . byCipherSuite ;
pTransmitKey - > dwKeyIndex = pMgmt - > sNodeDBTable [ uNodeIndex ] . dwKeyIndex ;
pTransmitKey - > uKeyLength = pMgmt - > sNodeDBTable [ uNodeIndex ] . uWepKeyLength ;
pTransmitKey - > dwTSC47_16 = pMgmt - > sNodeDBTable [ uNodeIndex ] . dwTSC47_16 ;
pTransmitKey - > wTSC15_0 = pMgmt - > sNodeDBTable [ uNodeIndex ] . wTSC15_0 ;
memcpy ( pTransmitKey - > abyKey ,
& pMgmt - > sNodeDBTable [ uNodeIndex ] . abyWepKey [ 0 ] ,
pTransmitKey - > uKeyLength
) ;
}
}
byPktType = ( BYTE ) pDevice - > byPacketType ;
if ( pDevice - > bFixRate ) {
if ( pDevice - > byBBType = = BB_TYPE_11B ) {
if ( pDevice - > uConnectionRate > = RATE_11M ) {
pDevice - > wCurrentRate = RATE_11M ;
} else {
pDevice - > wCurrentRate = ( WORD ) pDevice - > uConnectionRate ;
}
} else {
if ( ( pDevice - > byBBType = = BB_TYPE_11A ) & &
( pDevice - > uConnectionRate < = RATE_6M ) ) {
pDevice - > wCurrentRate = RATE_6M ;
} else {
if ( pDevice - > uConnectionRate > = RATE_54M )
pDevice - > wCurrentRate = RATE_54M ;
else
pDevice - > wCurrentRate = ( WORD ) pDevice - > uConnectionRate ;
}
}
}
else {
if ( pDevice - > eOPMode = = OP_MODE_ADHOC ) {
// Adhoc Tx rate decided from node DB
if ( IS_MULTICAST_ADDRESS ( & ( pDevice - > sTxEthHeader . abyDstAddr [ 0 ] ) ) ) {
// Multicast use highest data rate
pDevice - > wCurrentRate = pMgmt - > sNodeDBTable [ 0 ] . wTxDataRate ;
// preamble type
pDevice - > byPreambleType = pDevice - > byShortPreamble ;
}
else {
if ( BSSbIsSTAInNodeDB ( pDevice , & ( pDevice - > sTxEthHeader . abyDstAddr [ 0 ] ) , & uNodeIndex ) ) {
pDevice - > wCurrentRate = pMgmt - > sNodeDBTable [ uNodeIndex ] . wTxDataRate ;
if ( pMgmt - > sNodeDBTable [ uNodeIndex ] . bShortPreamble ) {
pDevice - > byPreambleType = pDevice - > byShortPreamble ;
}
else {
pDevice - > byPreambleType = PREAMBLE_LONG ;
}
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Found Node Index is [%d] Tx Data Rate:[%d] \n " , uNodeIndex , pDevice - > wCurrentRate ) ;
}
else {
if ( pDevice - > byBBType ! = BB_TYPE_11A )
pDevice - > wCurrentRate = RATE_2M ;
else
pDevice - > wCurrentRate = RATE_24M ; // refer to vMgrCreateOwnIBSS()'s
// abyCurrExtSuppRates[]
pDevice - > byPreambleType = PREAMBLE_SHORT ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Not Found Node use highest basic Rate..... \n " ) ;
}
}
}
if ( pDevice - > eOPMode = = OP_MODE_INFRASTRUCTURE ) {
// Infra STA rate decided from AP Node, index = 0
pDevice - > wCurrentRate = pMgmt - > sNodeDBTable [ 0 ] . wTxDataRate ;
}
}
if ( pDevice - > sTxEthHeader . wType = = TYPE_PKT_802_1x ) {
if ( pDevice - > byBBType ! = BB_TYPE_11A ) {
pDevice - > wCurrentRate = RATE_1M ;
pDevice - > byACKRate = RATE_1M ;
pDevice - > byTopCCKBasicRate = RATE_1M ;
pDevice - > byTopOFDMBasicRate = RATE_6M ;
} else {
pDevice - > wCurrentRate = RATE_6M ;
pDevice - > byACKRate = RATE_6M ;
pDevice - > byTopCCKBasicRate = RATE_1M ;
pDevice - > byTopOFDMBasicRate = RATE_6M ;
}
}
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " dma_tx: pDevice->wCurrentRate = %d \n " , pDevice - > wCurrentRate ) ;
if ( wKeepRate ! = pDevice - > wCurrentRate ) {
bScheduleCommand ( ( HANDLE ) pDevice , WLAN_CMD_SETPOWER , NULL ) ;
}
if ( pDevice - > wCurrentRate < = RATE_11M ) {
byPktType = PK_TYPE_11B ;
}
if ( bNeedEncryption = = TRUE ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " ntohs Pkt Type=%04x \n " , ntohs ( pDevice - > sTxEthHeader . wType ) ) ;
if ( ( pDevice - > sTxEthHeader . wType ) = = TYPE_PKT_802_1x ) {
bNeedEncryption = FALSE ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Pkt Type=%04x \n " , ( pDevice - > sTxEthHeader . wType ) ) ;
if ( ( pMgmt - > eCurrMode = = WMAC_MODE_ESS_STA ) & & ( pMgmt - > eCurrState = = WMAC_STATE_ASSOC ) ) {
if ( pTransmitKey = = NULL ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Don't Find TX KEY \n " ) ;
}
else {
if ( bTKIP_UseGTK = = TRUE ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " error: KEY is GTK!!~~ \n " ) ;
}
else {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Find PTK [%lX] \n " , pTransmitKey - > dwKeyIndex ) ;
bNeedEncryption = TRUE ;
}
}
}
if ( pDevice - > byCntMeasure = = 2 ) {
bNeedDeAuth = TRUE ;
pDevice - > s802_11Counter . TKIPCounterMeasuresInvoked + + ;
}
if ( pDevice - > bEnableHostWEP ) {
if ( ( uNodeIndex ! = 0 ) & &
( pMgmt - > sNodeDBTable [ uNodeIndex ] . dwKeyIndex & PAIRWISE_KEY ) ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Find PTK [%lX] \n " , pTransmitKey - > dwKeyIndex ) ;
bNeedEncryption = TRUE ;
}
}
}
else {
#if 0
if ( ( pDevice - > fWPA_Authened = = FALSE ) & &
( ( pMgmt - > eAuthenMode = = WMAC_AUTH_WPAPSK ) | | ( pMgmt - > eAuthenMode = WMAC_AUTH_WPA2PSK ) ) ) {
dev_kfree_skb_irq ( skb ) ;
pStats - > tx_dropped + + ;
return STATUS_FAILURE ;
}
else if ( pTransmitKey = = NULL ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " return no tx key \n " ) ;
dev_kfree_skb_irq ( skb ) ;
pStats - > tx_dropped + + ;
return STATUS_FAILURE ;
}
# else
if ( pTransmitKey = = NULL ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " return no tx key \n " ) ;
dev_kfree_skb_irq ( skb ) ;
pStats - > tx_dropped + + ;
return STATUS_FAILURE ;
}
# endif
}
}
fConvertedPacket = s_bPacketToWirelessUsb ( pDevice , byPktType ,
( PBYTE ) ( & pContext - > Data [ 0 ] ) , bNeedEncryption ,
skb - > len , uDMAIdx , & pDevice - > sTxEthHeader ,
( PBYTE ) skb - > data , pTransmitKey , uNodeIndex ,
pDevice - > wCurrentRate ,
& uHeaderLen , & BytesToWrite
) ;
if ( fConvertedPacket = = FALSE ) {
pContext - > bBoolInUse = FALSE ;
dev_kfree_skb_irq ( skb ) ;
return STATUS_FAILURE ;
}
if ( pDevice - > bEnablePSMode = = TRUE ) {
if ( ! pDevice - > bPSModeTxBurst ) {
bScheduleCommand ( ( HANDLE ) pDevice , WLAN_CMD_MAC_DISPOWERSAVING , NULL ) ;
pDevice - > bPSModeTxBurst = TRUE ;
}
}
pTX_Buffer = ( PTX_BUFFER ) & ( pContext - > Data [ 0 ] ) ;
pTX_Buffer - > byPKTNO = ( BYTE ) ( ( ( pDevice - > wCurrentRate < < 4 ) & 0x00F0 ) | ( ( pDevice - > wSeqCounter - 1 ) & 0x000F ) ) ;
pTX_Buffer - > wTxByteCount = ( WORD ) BytesToWrite ;
pContext - > pPacket = skb ;
pContext - > Type = CONTEXT_DATA_PACKET ;
pContext - > uBufLen = ( WORD ) BytesToWrite + 4 ; //USB header
s_vSaveTxPktInfo ( pDevice , ( BYTE ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pContext - > sEthHeader . abyDstAddr [ 0 ] ) , ( WORD ) ( BytesToWrite - uHeaderLen ) , pTX_Buffer - > wFIFOCtl ) ;
status = PIPEnsSendBulkOut ( pDevice , pContext ) ;
if ( bNeedDeAuth = = TRUE ) {
WORD wReason = WLAN_MGMT_REASON_MIC_FAILURE ;
bScheduleCommand ( ( HANDLE ) pDevice , WLAN_CMD_DEAUTH , ( PBYTE ) & wReason ) ;
}
if ( status ! = STATUS_PENDING ) {
pContext - > bBoolInUse = FALSE ;
dev_kfree_skb_irq ( skb ) ;
return STATUS_FAILURE ;
}
else
return 0 ;
}
/*
* Description :
* Relay packet send ( AC1DMA ) from rx dpc .
*
* Parameters :
* In :
* pDevice - Pointer to the adapter
* pPacket - Pointer to rx packet
* cbPacketSize - rx ethernet frame size
* Out :
* TURE , FALSE
*
* Return Value : Return TRUE if packet is copy to dma1 ; otherwise FALSE
*/
BOOL
bRelayPacketSend (
IN PSDevice pDevice ,
IN PBYTE pbySkbData ,
IN UINT uDataLen ,
IN UINT uNodeIndex
)
{
PSMgmtObject pMgmt = & ( pDevice - > sMgmtObj ) ;
UINT BytesToWrite = 0 , uHeaderLen = 0 ;
BYTE byPktType = PK_TYPE_11B ;
BOOL bNeedEncryption = FALSE ;
SKeyItem STempKey ;
PSKeyItem pTransmitKey = NULL ;
PBYTE pbyBSSID ;
PUSB_SEND_CONTEXT pContext ;
BYTE byPktTyp ;
BOOL fConvertedPacket ;
PTX_BUFFER pTX_Buffer ;
UINT status ;
WORD wKeepRate = pDevice - > wCurrentRate ;
pContext = ( PUSB_SEND_CONTEXT ) s_vGetFreeContext ( pDevice ) ;
if ( NULL = = pContext ) {
return FALSE ;
}
memcpy ( pDevice - > sTxEthHeader . abyDstAddr , ( PBYTE ) pbySkbData , U_HEADER_LEN ) ;
if ( pDevice - > bEncryptionEnable = = TRUE ) {
bNeedEncryption = TRUE ;
// get group key
pbyBSSID = pDevice - > abyBroadcastAddr ;
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , GROUP_KEY , & pTransmitKey ) = = FALSE ) {
pTransmitKey = NULL ;
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " KEY is NULL. [%d] \n " , pMgmt - > eCurrMode ) ;
} else {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " Get GTK. \n " ) ;
}
}
if ( pDevice - > bEnableHostWEP ) {
2009-10-16 18:17:57 +00:00
if ( uNodeIndex < MAX_NODE_NUM + 1 ) {
2009-06-13 11:38:31 +00:00
pTransmitKey = & STempKey ;
pTransmitKey - > byCipherSuite = pMgmt - > sNodeDBTable [ uNodeIndex ] . byCipherSuite ;
pTransmitKey - > dwKeyIndex = pMgmt - > sNodeDBTable [ uNodeIndex ] . dwKeyIndex ;
pTransmitKey - > uKeyLength = pMgmt - > sNodeDBTable [ uNodeIndex ] . uWepKeyLength ;
pTransmitKey - > dwTSC47_16 = pMgmt - > sNodeDBTable [ uNodeIndex ] . dwTSC47_16 ;
pTransmitKey - > wTSC15_0 = pMgmt - > sNodeDBTable [ uNodeIndex ] . wTSC15_0 ;
memcpy ( pTransmitKey - > abyKey ,
& pMgmt - > sNodeDBTable [ uNodeIndex ] . abyWepKey [ 0 ] ,
pTransmitKey - > uKeyLength
) ;
}
}
if ( bNeedEncryption & & ( pTransmitKey = = NULL ) ) {
pContext - > bBoolInUse = FALSE ;
return FALSE ;
}
byPktTyp = ( BYTE ) pDevice - > byPacketType ;
if ( pDevice - > bFixRate ) {
if ( pDevice - > byBBType = = BB_TYPE_11B ) {
if ( pDevice - > uConnectionRate > = RATE_11M ) {
pDevice - > wCurrentRate = RATE_11M ;
} else {
pDevice - > wCurrentRate = ( WORD ) pDevice - > uConnectionRate ;
}
} else {
if ( ( pDevice - > byBBType = = BB_TYPE_11A ) & &
( pDevice - > uConnectionRate < = RATE_6M ) ) {
pDevice - > wCurrentRate = RATE_6M ;
} else {
if ( pDevice - > uConnectionRate > = RATE_54M )
pDevice - > wCurrentRate = RATE_54M ;
else
pDevice - > wCurrentRate = ( WORD ) pDevice - > uConnectionRate ;
}
}
}
else {
pDevice - > wCurrentRate = pMgmt - > sNodeDBTable [ uNodeIndex ] . wTxDataRate ;
}
if ( wKeepRate ! = pDevice - > wCurrentRate ) {
bScheduleCommand ( ( HANDLE ) pDevice , WLAN_CMD_SETPOWER , NULL ) ;
}
if ( pDevice - > wCurrentRate < = RATE_11M )
byPktType = PK_TYPE_11B ;
BytesToWrite = uDataLen + U_CRC_LEN ;
// Convert the packet to an usb frame and copy into our buffer
// and send the irp.
fConvertedPacket = s_bPacketToWirelessUsb ( pDevice , byPktType ,
( PBYTE ) ( & pContext - > Data [ 0 ] ) , bNeedEncryption ,
uDataLen , TYPE_AC0DMA , & pDevice - > sTxEthHeader ,
pbySkbData , pTransmitKey , uNodeIndex ,
pDevice - > wCurrentRate ,
& uHeaderLen , & BytesToWrite
) ;
if ( fConvertedPacket = = FALSE ) {
pContext - > bBoolInUse = FALSE ;
return FALSE ;
}
pTX_Buffer = ( PTX_BUFFER ) & ( pContext - > Data [ 0 ] ) ;
pTX_Buffer - > byPKTNO = ( BYTE ) ( ( ( pDevice - > wCurrentRate < < 4 ) & 0x00F0 ) | ( ( pDevice - > wSeqCounter - 1 ) & 0x000F ) ) ;
pTX_Buffer - > wTxByteCount = ( WORD ) BytesToWrite ;
pContext - > pPacket = NULL ;
pContext - > Type = CONTEXT_DATA_PACKET ;
pContext - > uBufLen = ( WORD ) BytesToWrite + 4 ; //USB header
s_vSaveTxPktInfo ( pDevice , ( BYTE ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pContext - > sEthHeader . abyDstAddr [ 0 ] ) , ( WORD ) ( BytesToWrite - uHeaderLen ) , pTX_Buffer - > wFIFOCtl ) ;
status = PIPEnsSendBulkOut ( pDevice , pContext ) ;
return TRUE ;
}