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 :
2010-03-29 13:41:47 +00:00
* s_vGenerateTxParameter - Generate tx dma required parameter .
2009-06-13 11:38:31 +00:00
* 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
2010-03-29 13:41:47 +00:00
* s_uGetRTSCTSDuration - get rtx / cts required duration
2009-06-13 11:38:31 +00:00
* s_uGetRTSCTSRsvTime - get rts / cts reserved time
* s_uGetTxRsvTime - get frame reserved time
* s_vFillCTSHead - fulfill CTS ctl header
2010-03-29 13:41:47 +00:00
* s_vFillFragParameter - Set fragment ctl parameter .
2009-06-13 11:38:31 +00:00
* 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"
# include "iocmd.h"
2009-08-12 21:54:08 +00:00
2010-10-29 22:15:26 +00:00
static int msglevel = MSG_LEVEL_INFO ;
2009-06-13 11:38:31 +00:00
2013-02-26 01:32:52 +00:00
const u16 wTimeStampOff [ 2 ] [ MAX_RATE ] = {
2009-06-13 11:38:31 +00:00
{ 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
} ;
2013-02-26 01:32:52 +00:00
const u16 wFB_Opt0 [ 2 ] [ 5 ] = {
2009-06-13 11:38:31 +00:00
{ RATE_12M , RATE_18M , RATE_24M , RATE_36M , RATE_48M } , // fallback_rate0
{ RATE_12M , RATE_12M , RATE_18M , RATE_24M , RATE_36M } , // fallback_rate1
} ;
2013-02-26 01:32:52 +00:00
const u16 wFB_Opt1 [ 2 ] [ 5 ] = {
2009-06-13 11:38:31 +00:00
{ 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
2013-01-17 23:15:22 +00:00
static void s_vSaveTxPktInfo ( struct vnt_private * pDevice , u8 byPktNum ,
u8 * pbyDestAddr , u16 wPktLength , u16 wFIFOCtl ) ;
static void * s_vGetFreeContext ( struct vnt_private * pDevice ) ;
static void s_vGenerateTxParameter ( struct vnt_private * pDevice ,
u8 byPktType , u16 wCurrentRate , void * pTxBufHead , void * pvRrvTime ,
void * pvRTS , void * pvCTS , u32 cbFrameSize , int bNeedACK , u32 uDMAIdx ,
2013-03-19 01:33:49 +00:00
struct ethhdr * psEthHeader ) ;
2013-01-17 23:15:22 +00:00
static u32 s_uFillDataHead ( struct vnt_private * pDevice ,
u8 byPktType , u16 wCurrentRate , void * pTxDataHead , u32 cbFrameLength ,
2013-08-07 20:31:48 +00:00
u32 uDMAIdx , int bNeedAck , u8 byFBOption ) ;
2013-01-17 23:15:22 +00:00
static void s_vGenerateMACHeader ( struct vnt_private * pDevice ,
2013-03-19 01:33:49 +00:00
u8 * pbyBufferAddr , u16 wDuration , struct ethhdr * psEthHeader ,
2013-01-17 23:15:22 +00:00
int bNeedEncrypt , u16 wFragType , u32 uDMAIdx , u32 uFragIdx ) ;
static void s_vFillTxKey ( struct vnt_private * pDevice , u8 * pbyBuf ,
u8 * pbyIVHead , PSKeyItem pTransmitKey , u8 * pbyHdrBuf , u16 wPayloadLen ,
u8 * pMICHDR ) ;
static void s_vSWencryption ( struct vnt_private * pDevice ,
PSKeyItem pTransmitKey , u8 * pbyPayloadHead , u16 wPayloadSize ) ;
static unsigned int s_uGetTxRsvTime ( struct vnt_private * pDevice , u8 byPktType ,
u32 cbFrameLength , u16 wRate , int bNeedAck ) ;
static u32 s_uGetRTSCTSRsvTime ( struct vnt_private * pDevice , u8 byRTSRsvType ,
u8 byPktType , u32 cbFrameLength , u16 wCurrentRate ) ;
static void s_vFillCTSHead ( struct vnt_private * pDevice , u32 uDMAIdx ,
u8 byPktType , void * pvCTS , u32 cbFrameLength , int bNeedAck ,
int bDisCRC , u16 wCurrentRate , u8 byFBOption ) ;
static void s_vFillRTSHead ( struct vnt_private * pDevice , u8 byPktType ,
void * pvRTS , u32 cbFrameLength , int bNeedAck , int bDisCRC ,
2013-03-19 01:33:49 +00:00
struct ethhdr * psEthHeader , u16 wCurrentRate , u8 byFBOption ) ;
2013-01-17 23:15:22 +00:00
static u32 s_uGetDataDuration ( struct vnt_private * pDevice , u8 byDurType ,
2013-08-07 20:28:45 +00:00
u8 byPktType , int bNeedAck ) ;
2013-01-17 23:15:22 +00:00
static unsigned int s_uGetRTSCTSDuration ( struct vnt_private * pDevice ,
u8 byDurType , u32 cbFrameLength , u8 byPktType , u16 wRate ,
int bNeedAck , u8 byFBOption ) ;
2009-06-13 11:38:31 +00:00
2013-01-17 23:15:22 +00:00
static void * s_vGetFreeContext ( struct vnt_private * pDevice )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
PUSB_SEND_CONTEXT pContext = NULL ;
PUSB_SEND_CONTEXT pReturnContext = NULL ;
int ii ;
2009-06-13 11:38:31 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " GetFreeContext() \n " ) ;
for ( ii = 0 ; ii < pDevice - > cbTD ; ii + + ) {
pContext = pDevice - > apTD [ ii ] ;
2013-02-13 01:36:29 +00:00
if ( pContext - > bBoolInUse = = false ) {
2013-02-13 01:36:30 +00:00
pContext - > bBoolInUse = true ;
2013-08-05 20:09:14 +00:00
memset ( pContext - > Data , 0 , MAX_TOTAL_SIZE_WITH_ALL_HEADERS ) ;
2009-06-13 11:38:31 +00:00
pReturnContext = pContext ;
break ;
}
}
if ( ii = = pDevice - > cbTD ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " No Free Tx Context \n " ) ;
}
2010-05-01 17:25:00 +00:00
return ( void * ) pReturnContext ;
2009-06-13 11:38:31 +00:00
}
2013-01-17 23:15:22 +00:00
static void s_vSaveTxPktInfo ( struct vnt_private * pDevice , u8 byPktNum ,
u8 * pbyDestAddr , u16 wPktLength , u16 wFIFOCtl )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
PSStatCounter pStatistic = & pDevice - > scStatistic ;
2009-06-13 11:38:31 +00:00
2010-06-23 00:57:42 +00:00
if ( is_broadcast_ether_addr ( pbyDestAddr ) )
2009-06-13 11:38:31 +00:00
pStatistic - > abyTxPktInfo [ byPktNum ] . byBroadMultiUni = TX_PKT_BROAD ;
2010-06-23 00:57:42 +00:00
else if ( is_multicast_ether_addr ( pbyDestAddr ) )
2009-06-13 11:38:31 +00:00
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 ;
2010-04-14 00:54:48 +00:00
memcpy ( pStatistic - > abyTxPktInfo [ byPktNum ] . abyDestAddr ,
pbyDestAddr ,
ETH_ALEN ) ;
2009-06-13 11:38:31 +00:00
}
2013-01-17 23:15:22 +00:00
static void s_vFillTxKey ( struct vnt_private * pDevice , u8 * pbyBuf ,
u8 * pbyIVHead , PSKeyItem pTransmitKey , u8 * pbyHdrBuf ,
u16 wPayloadLen , u8 * pMICHDR )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
u32 * pdwIV = ( u32 * ) pbyIVHead ;
u32 * pdwExtIV = ( u32 * ) ( ( u8 * ) pbyIVHead + 4 ) ;
u16 wValue ;
2013-03-19 01:33:50 +00:00
struct ieee80211_hdr * pMACHeader = ( struct ieee80211_hdr * ) pbyHdrBuf ;
2013-01-17 23:15:22 +00:00
u32 dwRevIVCounter ;
2009-06-13 11:38:31 +00:00
//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 ) {
2013-02-26 01:32:51 +00:00
memcpy ( pDevice - > abyPRNG , ( u8 * ) & ( dwRevIVCounter ) , 3 ) ;
2009-08-12 21:54:11 +00:00
memcpy ( pDevice - > abyPRNG + 3 , pTransmitKey - > abyKey , pTransmitKey - > uKeyLength ) ;
2009-06-13 11:38:31 +00:00
} else {
2013-02-26 01:32:51 +00:00
memcpy ( pbyBuf , ( u8 * ) & ( dwRevIVCounter ) , 3 ) ;
2009-08-12 21:54:11 +00:00
memcpy ( pbyBuf + 3 , pTransmitKey - > abyKey , pTransmitKey - > uKeyLength ) ;
2009-06-13 11:38:31 +00:00
if ( pTransmitKey - > uKeyLength = = WLAN_WEP40_KEYLEN ) {
2013-02-26 01:32:51 +00:00
memcpy ( pbyBuf + 8 , ( u8 * ) & ( dwRevIVCounter ) , 3 ) ;
2009-08-12 21:54:11 +00:00
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
2012-11-11 15:53:14 +00:00
* pdwIV | = ( u32 ) pDevice - > byKeyIndex < < 30 ;
2009-06-13 11:38:31 +00:00
* 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
2013-02-26 01:32:51 +00:00
* ( pbyIVHead + 3 ) = ( u8 ) ( ( ( pDevice - > byKeyIndex < < 6 ) & 0xc0 ) | 0x20 ) ; // 0x20 is ExtIV
2009-06-13 11:38:31 +00:00
// Append IV&ExtIV after Mac Header
* pdwExtIV = cpu_to_le32 ( pTransmitKey - > dwTSC47_16 ) ;
2012-11-11 15:45:52 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " vFillTxKey()---- pdwExtIV: %x \n " ,
* pdwExtIV ) ;
2009-06-13 11:38:31 +00:00
} 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 ;
2013-02-26 01:32:51 +00:00
* ( pbyIVHead + 3 ) = ( u8 ) ( ( ( pDevice - > byKeyIndex < < 6 ) & 0xc0 ) | 0x20 ) ; // 0x20 is ExtIV
2013-02-26 01:32:52 +00:00
* pdwIV | = cpu_to_le16 ( ( u16 ) ( pTransmitKey - > wTSC15_0 ) ) ;
2009-06-13 11:38:31 +00:00
//Append IV&ExtIV after Mac Header
* pdwExtIV = cpu_to_le32 ( pTransmitKey - > dwTSC47_16 ) ;
//Fill MICHDR0
* pMICHDR = 0x59 ;
2013-02-26 01:32:51 +00:00
* ( ( u8 * ) ( pMICHDR + 1 ) ) = 0 ; // TxPriority
2013-03-19 01:33:50 +00:00
memcpy ( pMICHDR + 2 , & ( pMACHeader - > addr2 [ 0 ] ) , 6 ) ;
2013-02-26 01:32:51 +00:00
* ( ( u8 * ) ( pMICHDR + 8 ) ) = HIBYTE ( HIWORD ( pTransmitKey - > dwTSC47_16 ) ) ;
* ( ( u8 * ) ( pMICHDR + 9 ) ) = LOBYTE ( HIWORD ( pTransmitKey - > dwTSC47_16 ) ) ;
* ( ( u8 * ) ( pMICHDR + 10 ) ) = HIBYTE ( LOWORD ( pTransmitKey - > dwTSC47_16 ) ) ;
* ( ( u8 * ) ( pMICHDR + 11 ) ) = LOBYTE ( LOWORD ( pTransmitKey - > dwTSC47_16 ) ) ;
* ( ( u8 * ) ( pMICHDR + 12 ) ) = HIBYTE ( pTransmitKey - > wTSC15_0 ) ;
* ( ( u8 * ) ( pMICHDR + 13 ) ) = LOBYTE ( pTransmitKey - > wTSC15_0 ) ;
* ( ( u8 * ) ( pMICHDR + 14 ) ) = HIBYTE ( wPayloadLen ) ;
* ( ( u8 * ) ( pMICHDR + 15 ) ) = LOBYTE ( wPayloadLen ) ;
2009-06-13 11:38:31 +00:00
//Fill MICHDR1
2013-02-26 01:32:51 +00:00
* ( ( u8 * ) ( pMICHDR + 16 ) ) = 0 ; // HLEN[15:8]
2009-06-13 11:38:31 +00:00
if ( pDevice - > bLongHeader ) {
2013-02-26 01:32:51 +00:00
* ( ( u8 * ) ( pMICHDR + 17 ) ) = 28 ; // HLEN[7:0]
2009-06-13 11:38:31 +00:00
} else {
2013-02-26 01:32:51 +00:00
* ( ( u8 * ) ( pMICHDR + 17 ) ) = 22 ; // HLEN[7:0]
2009-06-13 11:38:31 +00:00
}
2013-03-19 01:33:50 +00:00
wValue = cpu_to_le16 ( pMACHeader - > frame_control & 0xC78F ) ;
2013-02-26 01:32:51 +00:00
memcpy ( pMICHDR + 18 , ( u8 * ) & wValue , 2 ) ; // MSKFRACTL
2013-03-19 01:33:50 +00:00
memcpy ( pMICHDR + 20 , & ( pMACHeader - > addr1 [ 0 ] ) , 6 ) ;
memcpy ( pMICHDR + 26 , & ( pMACHeader - > addr2 [ 0 ] ) , 6 ) ;
2009-06-13 11:38:31 +00:00
//Fill MICHDR2
2013-03-19 01:33:50 +00:00
memcpy ( pMICHDR + 32 , & ( pMACHeader - > addr3 [ 0 ] ) , 6 ) ;
wValue = pMACHeader - > seq_ctrl ;
2009-06-13 11:38:31 +00:00
wValue & = 0x000F ;
wValue = cpu_to_le16 ( wValue ) ;
2013-02-26 01:32:51 +00:00
memcpy ( pMICHDR + 38 , ( u8 * ) & wValue , 2 ) ; // MSKSEQCTL
2009-06-13 11:38:31 +00:00
if ( pDevice - > bLongHeader ) {
2013-03-19 01:33:50 +00:00
memcpy ( pMICHDR + 40 , & ( pMACHeader - > addr4 [ 0 ] ) , 6 ) ;
2009-06-13 11:38:31 +00:00
}
}
}
2013-01-17 23:15:22 +00:00
static void s_vSWencryption ( struct vnt_private * pDevice ,
PSKeyItem pTransmitKey , u8 * pbyPayloadHead , u16 wPayloadSize )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
u32 cbICVlen = 4 ;
u32 dwICV = 0xffffffff ;
u32 * pdwICV ;
2009-06-13 11:38:31 +00:00
if ( pTransmitKey = = NULL )
return ;
if ( pTransmitKey - > byCipherSuite = = KEY_CTL_WEP ) {
//=======================================================================
// Append ICV after payload
dwICV = CRCdwGetCrc32Ex ( pbyPayloadHead , wPayloadSize , dwICV ) ; //ICV(Payload)
2013-02-26 01:32:53 +00:00
pdwICV = ( u32 * ) ( pbyPayloadHead + wPayloadSize ) ;
2009-06-13 11:38:31 +00:00
// 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)
2013-02-26 01:32:53 +00:00
pdwICV = ( u32 * ) ( pbyPayloadHead + wPayloadSize ) ;
2009-06-13 11:38:31 +00:00
// 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
*/
2013-01-17 23:15:22 +00:00
static u32 s_uGetTxRsvTime ( struct vnt_private * pDevice , u8 byPktType ,
u32 cbFrameLength , u16 wRate , int bNeedAck )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
u32 uDataTime , uAckTime ;
2009-06-13 11:38:31 +00:00
uDataTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , cbFrameLength , wRate ) ;
if ( byPktType = = PK_TYPE_11B ) { //llb,CCK mode
2013-02-26 01:32:52 +00:00
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , ( u16 ) pDevice - > byTopCCKBasicRate ) ;
2009-06-13 11:38:31 +00:00
} else { //11g 2.4G OFDM mode & 11a 5G OFDM mode
2013-02-26 01:32:52 +00:00
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , ( u16 ) pDevice - > byTopOFDMBasicRate ) ;
2009-06-13 11:38:31 +00:00
}
if ( bNeedAck ) {
return ( uDataTime + pDevice - > uSIFS + uAckTime ) ;
}
else {
return uDataTime ;
}
}
//byFreqType: 0=>5GHZ 1=>2.4GHZ
2013-01-17 23:15:22 +00:00
static u32 s_uGetRTSCTSRsvTime ( struct vnt_private * pDevice ,
u8 byRTSRsvType , u8 byPktType , u32 cbFrameLength , u16 wCurrentRate )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
u32 uRrvTime , uRTSTime , uCTSTime , uAckTime , uDataTime ;
2009-06-13 11:38:31 +00:00
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
2013-01-17 23:15:22 +00:00
static u32 s_uGetDataDuration ( struct vnt_private * pDevice , u8 byDurType ,
2013-08-07 20:28:45 +00:00
u8 byPktType , int bNeedAck )
2009-06-13 11:38:31 +00:00
{
2013-08-07 20:26:12 +00:00
u32 uAckTime = 0 ;
2009-06-13 11:38:31 +00:00
switch ( byDurType ) {
case DATADUR_B : //DATADUR_B
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopCCKBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime ) ;
} else {
return 0 ;
}
break ;
case DATADUR_A : //DATADUR_A
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime ) ;
} else {
return 0 ;
}
break ;
case DATADUR_A_F0 : //DATADUR_A_F0
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime ) ;
} else {
return 0 ;
}
break ;
case DATADUR_A_F1 : //DATADUR_A_F1
if ( bNeedAck ) {
uAckTime = BBuGetFrameTime ( pDevice - > byPreambleType , byPktType , 14 , pDevice - > byTopOFDMBasicRate ) ;
return ( pDevice - > uSIFS + uAckTime ) ;
} else {
return 0 ;
}
break ;
default :
break ;
}
return 0 ;
}
//byFreqType: 0=>5GHZ 1=>2.4GHZ
2013-01-17 23:15:22 +00:00
static u32 s_uGetRTSCTSDuration ( struct vnt_private * pDevice , u8 byDurType ,
u32 cbFrameLength , u8 byPktType , u16 wRate , int bNeedAck ,
u8 byFBOption )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
u32 uCTSTime = 0 , uDurTime = 0 ;
2009-06-13 11:38:31 +00:00
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 ;
}
2013-01-17 23:15:22 +00:00
static u32 s_uFillDataHead ( struct vnt_private * pDevice ,
u8 byPktType , u16 wCurrentRate , void * pTxDataHead , u32 cbFrameLength ,
2013-08-07 20:31:48 +00:00
u32 uDMAIdx , int bNeedAck , u8 byFBOption )
2009-06-13 11:38:31 +00:00
{
if ( pTxDataHead = = NULL ) {
return 0 ;
}
if ( byPktType = = PK_TYPE_11GB | | byPktType = = PK_TYPE_11GA ) {
2010-08-03 02:35:57 +00:00
if ( ( uDMAIdx = = TYPE_ATIMDMA ) | | ( uDMAIdx = = TYPE_BEACONDMA ) ) {
PSTxDataHead_ab pBuf = ( PSTxDataHead_ab ) pTxDataHead ;
2009-06-13 11:38:31 +00:00
//Get SignalField,ServiceField,Length
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( pBuf - > wTransmitLength ) , ( u8 * ) & ( pBuf - > byServiceField ) , ( u8 * ) & ( pBuf - > bySignalField )
2009-06-13 11:38:31 +00:00
) ;
//Get Duration and TimeStampOff
2013-08-07 20:28:45 +00:00
pBuf - > wDuration = ( u16 ) s_uGetDataDuration ( pDevice , DATADUR_A ,
byPktType , bNeedAck ) ;
2009-06-13 11:38:31 +00:00
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
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( pBuf - > wTransmitLength_a ) , ( u8 * ) & ( pBuf - > byServiceField_a ) , ( u8 * ) & ( pBuf - > bySignalField_a )
2009-06-13 11:38:31 +00:00
) ;
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , cbFrameLength , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( pBuf - > wTransmitLength_b ) , ( u8 * ) & ( pBuf - > byServiceField_b ) , ( u8 * ) & ( pBuf - > bySignalField_b )
2009-06-13 11:38:31 +00:00
) ;
//Get Duration and TimeStamp
2013-08-07 20:28:45 +00:00
pBuf - > wDuration_a = ( u16 ) s_uGetDataDuration ( pDevice , DATADUR_A ,
byPktType , bNeedAck ) ;
pBuf - > wDuration_b = ( u16 ) s_uGetDataDuration ( pDevice , DATADUR_B ,
PK_TYPE_11B , bNeedAck ) ;
2009-06-13 11:38:31 +00:00
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
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( pBuf - > wTransmitLength_a ) , ( u8 * ) & ( pBuf - > byServiceField_a ) , ( u8 * ) & ( pBuf - > bySignalField_a )
2009-06-13 11:38:31 +00:00
) ;
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , cbFrameLength , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( pBuf - > wTransmitLength_b ) , ( u8 * ) & ( pBuf - > byServiceField_b ) , ( u8 * ) & ( pBuf - > bySignalField_b )
2009-06-13 11:38:31 +00:00
) ;
//Get Duration and TimeStamp
2013-08-07 20:28:45 +00:00
pBuf - > wDuration_a = ( u16 ) s_uGetDataDuration ( pDevice , DATADUR_A ,
byPktType , bNeedAck ) ;
pBuf - > wDuration_b = ( u16 ) s_uGetDataDuration ( pDevice , DATADUR_B ,
PK_TYPE_11B , bNeedAck ) ;
pBuf - > wDuration_a_f0 = ( u16 ) s_uGetDataDuration ( pDevice ,
DATADUR_A_F0 , byPktType , bNeedAck ) ;
pBuf - > wDuration_a_f1 = ( u16 ) s_uGetDataDuration ( pDevice ,
DATADUR_A_F1 , byPktType , bNeedAck ) ;
2009-06-13 11:38:31 +00:00
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
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( pBuf - > wTransmitLength ) , ( u8 * ) & ( pBuf - > byServiceField ) , ( u8 * ) & ( pBuf - > bySignalField )
2009-06-13 11:38:31 +00:00
) ;
//Get Duration and TimeStampOff
2013-08-07 20:28:45 +00:00
pBuf - > wDuration = ( u16 ) s_uGetDataDuration ( pDevice , DATADUR_A ,
byPktType , bNeedAck ) ;
pBuf - > wDuration_f0 = ( u16 ) s_uGetDataDuration ( pDevice ,
DATADUR_A_F0 , byPktType , bNeedAck ) ;
pBuf - > wDuration_f1 = ( u16 ) s_uGetDataDuration ( pDevice ,
DATADUR_A_F1 , byPktType , bNeedAck ) ;
2009-06-13 11:38:31 +00:00
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
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( pBuf - > wTransmitLength ) , ( u8 * ) & ( pBuf - > byServiceField ) , ( u8 * ) & ( pBuf - > bySignalField )
2009-06-13 11:38:31 +00:00
) ;
//Get Duration and TimeStampOff
2013-08-07 20:28:45 +00:00
pBuf - > wDuration = ( u16 ) s_uGetDataDuration ( pDevice , DATADUR_A ,
byPktType , bNeedAck ) ;
2009-06-13 11:38:31 +00:00
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
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , cbFrameLength , wCurrentRate , byPktType ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( pBuf - > wTransmitLength ) , ( u8 * ) & ( pBuf - > byServiceField ) , ( u8 * ) & ( pBuf - > bySignalField )
2009-06-13 11:38:31 +00:00
) ;
//Get Duration and TimeStampOff
2013-08-07 20:28:45 +00:00
pBuf - > wDuration = ( u16 ) s_uGetDataDuration ( pDevice , DATADUR_B ,
byPktType , bNeedAck ) ;
2009-06-13 11:38:31 +00:00
if ( uDMAIdx ! = TYPE_ATIMDMA ) {
pBuf - > wTimeStampOff = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ wCurrentRate % MAX_RATE ] ;
}
return ( pBuf - > wDuration ) ;
}
return 0 ;
}
2013-01-17 23:15:22 +00:00
static void s_vFillRTSHead ( struct vnt_private * pDevice , u8 byPktType ,
void * pvRTS , u32 cbFrameLength , int bNeedAck , int bDisCRC ,
2013-03-19 01:33:49 +00:00
struct ethhdr * psEthHeader , u16 wCurrentRate , u8 byFBOption )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
u32 uRTSFrameLen = 20 ;
u16 wLen = 0 ;
2009-06-13 11:38:31 +00:00
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 ;
}
2012-08-13 12:21:50 +00:00
// Note: So far RTSHead doesn't appear in ATIM & Beacom DMA, so we don't need to take them into account.
2009-06-13 11:38:31 +00:00
// 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
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( wLen ) , ( u8 * ) & ( pBuf - > byServiceField_b ) , ( u8 * ) & ( pBuf - > bySignalField_b )
2009-06-13 11:38:31 +00:00
) ;
pBuf - > wTransmitLength_b = cpu_to_le16 ( wLen ) ;
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopOFDMBasicRate , byPktType ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( wLen ) , ( u8 * ) & ( pBuf - > byServiceField_a ) , ( u8 * ) & ( pBuf - > bySignalField_a )
2009-06-13 11:38:31 +00:00
) ;
pBuf - > wTransmitLength_a = cpu_to_le16 ( wLen ) ;
//Get Duration
2013-02-26 01:32:52 +00:00
pBuf - > wDuration_bb = cpu_to_le16 ( ( u16 ) 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 ( ( u16 ) 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 ( ( u16 ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_BA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
2013-08-05 21:08:05 +00:00
pBuf - > data . duration = pBuf - > wDuration_aa ;
/*Get RTS Frame body */
pBuf - > data . frame_control = TYPE_CTL_RTS ;
if ( pDevice - > eOPMode = = OP_MODE_ADHOC | |
pDevice - > eOPMode = = OP_MODE_AP )
memcpy ( pBuf - > data . ra , psEthHeader - > h_dest , ETH_ALEN ) ;
else
memcpy ( pBuf - > data . ra , pDevice - > abyBSSID , ETH_ALEN ) ;
if ( pDevice - > eOPMode = = OP_MODE_AP )
memcpy ( pBuf - > data . ta , pDevice - > abyBSSID , ETH_ALEN ) ;
else
memcpy ( pBuf - > data . ta , psEthHeader - > h_source , ETH_ALEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
PSRTS_g_FB pBuf = ( PSRTS_g_FB ) pvRTS ;
//Get SignalField,ServiceField,Length
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( wLen ) , ( u8 * ) & ( pBuf - > byServiceField_b ) , ( u8 * ) & ( pBuf - > bySignalField_b )
2009-06-13 11:38:31 +00:00
) ;
pBuf - > wTransmitLength_b = cpu_to_le16 ( wLen ) ;
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopOFDMBasicRate , byPktType ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( wLen ) , ( u8 * ) & ( pBuf - > byServiceField_a ) , ( u8 * ) & ( pBuf - > bySignalField_a )
2009-06-13 11:38:31 +00:00
) ;
pBuf - > wTransmitLength_a = cpu_to_le16 ( wLen ) ;
//Get Duration
2013-02-26 01:32:52 +00:00
pBuf - > wDuration_bb = cpu_to_le16 ( ( u16 ) 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 ( ( u16 ) 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 ( ( u16 ) 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 ( ( u16 ) 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 ( ( u16 ) 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 ( ( u16 ) 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 ( ( u16 ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA_F1 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
2013-08-05 21:08:05 +00:00
pBuf - > data . duration = pBuf - > wDuration_aa ;
/*Get RTS Frame body*/
pBuf - > data . frame_control = TYPE_CTL_RTS ;
if ( pDevice - > eOPMode = = OP_MODE_ADHOC | |
pDevice - > eOPMode = = OP_MODE_AP )
memcpy ( pBuf - > data . ra , psEthHeader - > h_dest , ETH_ALEN ) ;
else
memcpy ( pBuf - > data . ra , pDevice - > abyBSSID , ETH_ALEN ) ;
if ( pDevice - > eOPMode = = OP_MODE_AP )
memcpy ( pBuf - > data . ta , pDevice - > abyBSSID , ETH_ALEN ) ;
else
memcpy ( pBuf - > data . ta , psEthHeader - > h_source , ETH_ALEN ) ;
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
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopOFDMBasicRate , byPktType ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( wLen ) , ( u8 * ) & ( pBuf - > byServiceField ) , ( u8 * ) & ( pBuf - > bySignalField )
2009-06-13 11:38:31 +00:00
) ;
pBuf - > wTransmitLength = cpu_to_le16 ( wLen ) ;
//Get Duration
2013-02-26 01:32:52 +00:00
pBuf - > wDuration = cpu_to_le16 ( ( u16 ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
2013-08-05 21:08:05 +00:00
pBuf - > data . duration = pBuf - > wDuration ;
/* Get RTS Frame body */
pBuf - > data . frame_control = TYPE_CTL_RTS ;
if ( pDevice - > eOPMode = = OP_MODE_ADHOC | |
pDevice - > eOPMode = = OP_MODE_AP )
memcpy ( pBuf - > data . ra , psEthHeader - > h_dest , ETH_ALEN ) ;
else
memcpy ( pBuf - > data . ra , pDevice - > abyBSSID , ETH_ALEN ) ;
if ( pDevice - > eOPMode = = OP_MODE_AP )
memcpy ( pBuf - > data . ta , pDevice - > abyBSSID , ETH_ALEN ) ;
else
memcpy ( pBuf - > data . ta , psEthHeader - > h_source , ETH_ALEN ) ;
2009-06-13 11:38:31 +00:00
}
else {
PSRTS_a_FB pBuf = ( PSRTS_a_FB ) pvRTS ;
//Get SignalField,ServiceField,Length
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopOFDMBasicRate , byPktType ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( wLen ) , ( u8 * ) & ( pBuf - > byServiceField ) , ( u8 * ) & ( pBuf - > bySignalField )
2009-06-13 11:38:31 +00:00
) ;
pBuf - > wTransmitLength = cpu_to_le16 ( wLen ) ;
//Get Duration
2013-02-26 01:32:52 +00:00
pBuf - > wDuration = cpu_to_le16 ( ( u16 ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
pBuf - > wRTSDuration_f0 = cpu_to_le16 ( ( u16 ) 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 ( ( u16 ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_AA_F1 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //7:RTSDuration_aa_f1, 0:5G, 0:
2013-08-05 21:08:05 +00:00
pBuf - > data . duration = pBuf - > wDuration ;
/* Get RTS Frame body */
pBuf - > data . frame_control = TYPE_CTL_RTS ;
if ( pDevice - > eOPMode = = OP_MODE_ADHOC | |
pDevice - > eOPMode = = OP_MODE_AP )
memcpy ( pBuf - > data . ra , psEthHeader - > h_dest , ETH_ALEN ) ;
else
memcpy ( pBuf - > data . ra , pDevice - > abyBSSID , ETH_ALEN ) ;
if ( pDevice - > eOPMode = = OP_MODE_AP )
memcpy ( pBuf - > data . ta , pDevice - > abyBSSID , ETH_ALEN ) ;
else
memcpy ( pBuf - > data . ta , psEthHeader - > h_source , ETH_ALEN ) ;
2009-06-13 11:38:31 +00:00
}
}
else if ( byPktType = = PK_TYPE_11B ) {
PSRTS_ab pBuf = ( PSRTS_ab ) pvRTS ;
//Get SignalField,ServiceField,Length
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , uRTSFrameLen , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( wLen ) , ( u8 * ) & ( pBuf - > byServiceField ) , ( u8 * ) & ( pBuf - > bySignalField )
2009-06-13 11:38:31 +00:00
) ;
pBuf - > wTransmitLength = cpu_to_le16 ( wLen ) ;
//Get Duration
2013-02-26 01:32:52 +00:00
pBuf - > wDuration = cpu_to_le16 ( ( u16 ) s_uGetRTSCTSDuration ( pDevice , RTSDUR_BB , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //0:RTSDuration_bb, 1:2.4G, 1:CCKData
2009-06-13 11:38:31 +00:00
2013-08-05 21:08:05 +00:00
pBuf - > data . duration = pBuf - > wDuration ;
/* Get RTS Frame body */
pBuf - > data . frame_control = TYPE_CTL_RTS ;
if ( pDevice - > eOPMode = = OP_MODE_ADHOC | |
pDevice - > eOPMode = = OP_MODE_AP )
memcpy ( pBuf - > data . ra , psEthHeader - > h_dest , ETH_ALEN ) ;
else
memcpy ( pBuf - > data . ra , pDevice - > abyBSSID , ETH_ALEN ) ;
if ( pDevice - > eOPMode = = OP_MODE_AP )
memcpy ( pBuf - > data . ta , pDevice - > abyBSSID , ETH_ALEN ) ;
else
memcpy ( pBuf - > data . ta , psEthHeader - > h_source , ETH_ALEN ) ;
2009-06-13 11:38:31 +00:00
}
}
2013-01-17 23:15:22 +00:00
static void s_vFillCTSHead ( struct vnt_private * pDevice , u32 uDMAIdx ,
u8 byPktType , void * pvCTS , u32 cbFrameLength , int bNeedAck ,
int bDisCRC , u16 wCurrentRate , u8 byFBOption )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
u32 uCTSFrameLen = 14 ;
u16 wLen = 0 ;
2009-06-13 11:38:31 +00:00
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
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , uCTSFrameLen , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( wLen ) , ( u8 * ) & ( pBuf - > byServiceField_b ) , ( u8 * ) & ( pBuf - > bySignalField_b )
2009-06-13 11:38:31 +00:00
) ;
pBuf - > wTransmitLength_b = cpu_to_le16 ( wLen ) ;
2013-02-26 01:32:52 +00:00
pBuf - > wDuration_ba = ( u16 ) s_uGetRTSCTSDuration ( pDevice , CTSDUR_BA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ; //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
2009-06-13 11:38:31 +00:00
pBuf - > wDuration_ba = cpu_to_le16 ( pBuf - > wDuration_ba ) ;
//Get CTSDuration_ba_f0
2013-02-26 01:32:52 +00:00
pBuf - > wCTSDuration_ba_f0 = ( u16 ) s_uGetRTSCTSDuration ( pDevice , CTSDUR_BA_F0 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ; //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data
2009-06-13 11:38:31 +00:00
pBuf - > wCTSDuration_ba_f0 = cpu_to_le16 ( pBuf - > wCTSDuration_ba_f0 ) ;
//Get CTSDuration_ba_f1
2013-02-26 01:32:52 +00:00
pBuf - > wCTSDuration_ba_f1 = ( u16 ) s_uGetRTSCTSDuration ( pDevice , CTSDUR_BA_F1 , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ; //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data
2009-06-13 11:38:31 +00:00
pBuf - > wCTSDuration_ba_f1 = cpu_to_le16 ( pBuf - > wCTSDuration_ba_f1 ) ;
2013-08-05 21:12:42 +00:00
/* Get CTS Frame body */
pBuf - > data . duration = pBuf - > wDuration_ba ;
pBuf - > data . frame_control = TYPE_CTL_CTS ;
memcpy ( pBuf - > data . ra , pDevice - > abyCurrentNetAddr , ETH_ALEN ) ;
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
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , uCTSFrameLen , pDevice - > byTopCCKBasicRate , PK_TYPE_11B ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( wLen ) , ( u8 * ) & ( pBuf - > byServiceField_b ) , ( u8 * ) & ( pBuf - > bySignalField_b )
2009-06-13 11:38:31 +00:00
) ;
pBuf - > wTransmitLength_b = cpu_to_le16 ( wLen ) ;
//Get CTSDuration_ba
2013-02-26 01:32:52 +00:00
pBuf - > wDuration_ba = cpu_to_le16 ( ( u16 ) s_uGetRTSCTSDuration ( pDevice , CTSDUR_BA , cbFrameLength , byPktType , wCurrentRate , bNeedAck , byFBOption ) ) ; //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
2009-06-13 11:38:31 +00:00
pBuf - > wDuration_ba = cpu_to_le16 ( pBuf - > wDuration_ba ) ;
2013-08-05 21:12:42 +00:00
/*Get CTS Frame body*/
pBuf - > data . duration = pBuf - > wDuration_ba ;
pBuf - > data . frame_control = TYPE_CTL_CTS ;
memcpy ( pBuf - > data . ra , pDevice - > abyCurrentNetAddr , ETH_ALEN ) ;
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
*
- */
2010-05-18 00:34:01 +00:00
2013-01-17 23:15:22 +00:00
static void s_vGenerateTxParameter ( struct vnt_private * pDevice ,
u8 byPktType , u16 wCurrentRate , void * pTxBufHead , void * pvRrvTime ,
void * pvRTS , void * pvCTS , u32 cbFrameSize , int bNeedACK , u32 uDMAIdx ,
2013-03-19 01:33:49 +00:00
struct ethhdr * psEthHeader )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN ; /* 24 */
u16 wFifoCtl ;
2013-02-13 01:36:29 +00:00
int bDisCRC = false ;
2013-01-17 23:15:22 +00:00
u8 byFBOption = AUTO_FB_NONE ;
2009-06-13 11:38:31 +00:00
//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
PSTxBufHead pFifoHead = ( PSTxBufHead ) pTxBufHead ;
pFifoHead - > wReserved = wCurrentRate ;
wFifoCtl = pFifoHead - > wFIFOCtl ;
if ( wFifoCtl & FIFOCTL_CRCDIS ) {
2013-02-13 01:36:30 +00:00
bDisCRC = true ;
2009-06-13 11:38:31 +00:00
}
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 ;
2013-02-26 01:32:52 +00:00
pBuf - > wRTSTxRrvTime_aa = cpu_to_le16 ( ( u16 ) s_uGetRTSCTSRsvTime ( pDevice , 2 , byPktType , cbFrameSize , wCurrentRate ) ) ; //2:RTSTxRrvTime_aa, 1:2.4GHz
pBuf - > wRTSTxRrvTime_ba = cpu_to_le16 ( ( u16 ) s_uGetRTSCTSRsvTime ( pDevice , 1 , byPktType , cbFrameSize , wCurrentRate ) ) ; //1:RTSTxRrvTime_ba, 1:2.4GHz
pBuf - > wRTSTxRrvTime_bb = cpu_to_le16 ( ( u16 ) s_uGetRTSCTSRsvTime ( pDevice , 0 , byPktType , cbFrameSize , wCurrentRate ) ) ; //0:RTSTxRrvTime_bb, 1:2.4GHz
pBuf - > wTxRrvTime_a = cpu_to_le16 ( ( u16 ) s_uGetTxRsvTime ( pDevice , byPktType , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //2.4G OFDM
pBuf - > wTxRrvTime_b = cpu_to_le16 ( ( u16 ) s_uGetTxRsvTime ( pDevice , PK_TYPE_11B , cbFrameSize , pDevice - > byTopCCKBasicRate , bNeedACK ) ) ; //1:CCK
2009-06-13 11:38:31 +00:00
}
//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 ;
2013-02-26 01:32:52 +00:00
pBuf - > wTxRrvTime_a = cpu_to_le16 ( ( u16 ) s_uGetTxRsvTime ( pDevice , byPktType , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //2.4G OFDM
pBuf - > wTxRrvTime_b = cpu_to_le16 ( ( u16 ) s_uGetTxRsvTime ( pDevice , PK_TYPE_11B , cbFrameSize , pDevice - > byTopCCKBasicRate , bNeedACK ) ) ; //1:CCK
pBuf - > wCTSTxRrvTime_ba = cpu_to_le16 ( ( u16 ) s_uGetRTSCTSRsvTime ( pDevice , 3 , byPktType , cbFrameSize , wCurrentRate ) ) ; //3:CTSTxRrvTime_Ba, 1:2.4GHz
2009-06-13 11:38:31 +00:00
}
//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 ;
2013-02-26 01:32:52 +00:00
pBuf - > wRTSTxRrvTime = cpu_to_le16 ( ( u16 ) s_uGetRTSCTSRsvTime ( pDevice , 2 , byPktType , cbFrameSize , wCurrentRate ) ) ; //2:RTSTxRrvTime_aa, 0:5GHz
pBuf - > wTxRrvTime = cpu_to_le16 ( ( u16 ) s_uGetTxRsvTime ( pDevice , byPktType , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //0:OFDM
2009-06-13 11:38:31 +00:00
}
//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 ;
2013-02-26 01:32:52 +00:00
pBuf - > wTxRrvTime = cpu_to_le16 ( ( u16 ) s_uGetTxRsvTime ( pDevice , PK_TYPE_11A , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //0:OFDM
2009-06-13 11:38:31 +00:00
}
}
}
else if ( byPktType = = PK_TYPE_11B ) {
if ( ( pvRTS ! = NULL ) ) { //RTS_need, non PCF mode
//Fill RsvTime
if ( pvRrvTime ) {
PSRrvTime_ab pBuf = ( PSRrvTime_ab ) pvRrvTime ;
2013-02-26 01:32:52 +00:00
pBuf - > wRTSTxRrvTime = cpu_to_le16 ( ( u16 ) s_uGetRTSCTSRsvTime ( pDevice , 0 , byPktType , cbFrameSize , wCurrentRate ) ) ; //0:RTSTxRrvTime_bb, 1:2.4GHz
pBuf - > wTxRrvTime = cpu_to_le16 ( ( u16 ) s_uGetTxRsvTime ( pDevice , PK_TYPE_11B , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //1:CCK
2009-06-13 11:38:31 +00:00
}
//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 ;
2013-02-26 01:32:52 +00:00
pBuf - > wTxRrvTime = cpu_to_le16 ( ( u16 ) s_uGetTxRsvTime ( pDevice , PK_TYPE_11B , cbFrameSize , wCurrentRate , bNeedACK ) ) ; //1:CCK
2009-06-13 11:38:31 +00:00
}
}
}
//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
}
/*
2013-02-26 01:32:51 +00:00
u8 * pbyBuffer , //point to pTxBufHead
2013-02-26 01:32:52 +00:00
u16 wFragType , //00:Non-Frag, 01:Start, 02:Mid, 03:Last
2010-05-18 00:34:01 +00:00
unsigned int cbFragmentSize , //Hdr+payoad+FCS
2009-06-13 11:38:31 +00:00
*/
2013-01-17 23:15:22 +00:00
static int s_bPacketToWirelessUsb ( struct vnt_private * pDevice , u8 byPktType ,
u8 * usbPacketBuf , int bNeedEncryption , u32 uSkbPacketLen , u32 uDMAIdx ,
2013-03-19 01:33:49 +00:00
struct ethhdr * psEthHeader , u8 * pPacket , PSKeyItem pTransmitKey ,
2013-01-17 23:15:22 +00:00
u32 uNodeIndex , u16 wCurrentRate , u32 * pcbHeaderLen , u32 * pcbTotalLen )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
struct vnt_manager * pMgmt = & pDevice - > vnt_mgmt ;
u32 cbFrameSize , cbFrameBodySize ;
PTX_BUFFER pTxBufHead ;
u32 cb802_1_H_len ;
u32 cbIVlen = 0 , cbICVlen = 0 , cbMIClen = 0 , cbMACHdLen = 0 ;
u32 cbFCSlen = 4 , cbMICHDR = 0 ;
int bNeedACK , bRTS ;
u8 * pbyType , * pbyMacHdr , * pbyIVHead , * pbyPayloadHead , * pbyTxBufferAddr ;
u8 abySNAP_RFC1042 [ ETH_ALEN ] = { 0xAA , 0xAA , 0x03 , 0x00 , 0x00 , 0x00 } ;
u8 abySNAP_Bridgetunnel [ ETH_ALEN ]
= { 0xAA , 0xAA , 0x03 , 0x00 , 0x00 , 0xF8 } ;
u32 uDuration ;
u32 cbHeaderLength = 0 , uPadding = 0 ;
void * pvRrvTime ;
PSMICHDRHead pMICHDR ;
void * pvRTS ;
void * pvCTS ;
void * pvTxDataHd ;
u8 byFBOption = AUTO_FB_NONE , byFragType ;
u16 wTxBufSize ;
u32 dwMICKey0 , dwMICKey1 , dwMIC_Priority , dwCRC ;
u32 * pdwMIC_L , * pdwMIC_R ;
2013-02-13 01:36:29 +00:00
int bSoftWEP = false ;
2013-01-17 23:15:22 +00:00
pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL ;
2009-06-13 11:38:31 +00:00
2012-11-11 15:20:52 +00:00
if ( bNeedEncryption & & pTransmitKey - > pvKeyTable ) {
2013-02-13 01:36:30 +00:00
if ( ( ( PSKeyTable ) pTransmitKey - > pvKeyTable ) - > bSoftWEP = = true )
bSoftWEP = true ; /* WEP 256 */
2012-11-11 15:20:52 +00:00
}
2009-06-13 11:38:31 +00:00
pTxBufHead = ( PTX_BUFFER ) usbPacketBuf ;
// Get pkt type
2013-03-19 01:33:49 +00:00
if ( ntohs ( psEthHeader - > h_proto ) > ETH_DATA_LEN ) {
2009-06-13 11:38:31 +00:00
if ( pDevice - > dwDiagRefCount = = 0 ) {
cb802_1_H_len = 8 ;
} else {
cb802_1_H_len = 2 ;
}
} else {
cb802_1_H_len = 0 ;
}
2010-05-18 17:08:14 +00:00
cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len ;
2009-06-13 11:38:31 +00:00
//Set packet type
2013-02-26 01:32:52 +00:00
pTxBufHead - > wFIFOCtl | = ( u16 ) ( byPktType < < 8 ) ;
2009-06-13 11:38:31 +00:00
if ( pDevice - > dwDiagRefCount ! = 0 ) {
2013-02-13 01:36:29 +00:00
bNeedACK = false ;
2009-06-13 11:38:31 +00:00
pTxBufHead - > wFIFOCtl = pTxBufHead - > wFIFOCtl & ( ~ FIFOCTL_NEEDACK ) ;
} else { //if (pDevice->dwDiagRefCount != 0) {
2010-08-02 23:21:44 +00:00
if ( ( pDevice - > eOPMode = = OP_MODE_ADHOC ) | |
( pDevice - > eOPMode = = OP_MODE_AP ) ) {
2013-03-19 01:33:49 +00:00
if ( is_multicast_ether_addr ( psEthHeader - > h_dest ) ) {
2013-02-13 01:36:29 +00:00
bNeedACK = false ;
2010-08-02 23:21:44 +00:00
pTxBufHead - > wFIFOCtl =
pTxBufHead - > wFIFOCtl & ( ~ FIFOCTL_NEEDACK ) ;
} else {
2013-02-13 01:36:30 +00:00
bNeedACK = true ;
2010-08-02 23:21:44 +00:00
pTxBufHead - > wFIFOCtl | = FIFOCTL_NEEDACK ;
}
2009-06-13 11:38:31 +00:00
}
else {
// MSDUs in Infra mode always need ACK
2013-02-13 01:36:30 +00:00
bNeedACK = true ;
2009-06-13 11:38:31 +00:00
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 ;
}
2013-02-26 01:32:52 +00:00
pTxBufHead - > wFragCtl | = ( u16 ) ( cbMACHdLen < < 10 ) ;
2009-06-13 11:38:31 +00:00
//Set FIFOCTL_GrpAckPolicy
2013-02-13 01:36:30 +00:00
if ( pDevice - > bGrpAckPolicy = = true ) { //0000 0100 0000 0000
2009-06-13 11:38:31 +00:00
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 ;
}
}
2013-02-13 01:36:30 +00:00
if ( bSoftWEP ! = true ) {
2009-06-13 11:38:31 +00:00
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 ) ;
}
2013-02-13 01:36:29 +00:00
if ( bSoftWEP = = false ) {
2009-06-13 11:38:31 +00:00
//MAC Header should be padding 0 to DW alignment.
uPadding = 4 - ( cbMACHdLen % 4 ) ;
uPadding % = 4 ;
}
}
cbFrameSize = cbMACHdLen + cbIVlen + ( cbFrameBodySize + cbMIClen ) + cbICVlen + cbFCSlen ;
2013-02-13 01:36:29 +00:00
if ( ( bNeedACK = = false ) | | ( cbFrameSize < pDevice - > wRTSThreshold ) ) {
bRTS = false ;
2009-06-13 11:38:31 +00:00
} else {
2013-02-13 01:36:30 +00:00
bRTS = true ;
2009-06-13 11:38:31 +00:00
pTxBufHead - > wFIFOCtl | = ( FIFOCTL_RTS | FIFOCTL_LRETRY ) ;
}
2013-02-26 01:32:51 +00:00
pbyTxBufferAddr = ( u8 * ) & ( pTxBufHead - > adwTxKey [ 0 ] ) ;
2009-06-13 11:38:31 +00:00
wTxBufSize = sizeof ( STxBufHead ) ;
if ( byPktType = = PK_TYPE_11GB | | byPktType = = PK_TYPE_11GA ) { //802.11g packet
if ( byFBOption = = AUTO_FB_NONE ) {
2013-02-13 01:36:30 +00:00
if ( bRTS = = true ) { //RTS_need
2009-06-13 11:38:31 +00:00
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
2013-02-13 01:36:30 +00:00
if ( bRTS = = true ) { //RTS_need
2009-06-13 11:38:31 +00:00
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 ) ;
}
2013-02-13 01:36:29 +00:00
else if ( bRTS = = false ) { //RTS_needless
2009-06-13 11:38:31 +00:00
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 ) {
2013-02-13 01:36:30 +00:00
if ( bRTS = = true ) { //RTS_need
2009-06-13 11:38:31 +00:00
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 ) ;
}
2013-02-13 01:36:29 +00:00
else if ( bRTS = = false ) { //RTS_needless, no MICHDR
2009-06-13 11:38:31 +00:00
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
2013-02-13 01:36:30 +00:00
if ( bRTS = = true ) { //RTS_need
2009-06-13 11:38:31 +00:00
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 ) ;
}
2013-02-13 01:36:29 +00:00
else if ( bRTS = = false ) { //RTS_needless
2009-06-13 11:38:31 +00:00
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
}
2013-02-26 01:32:51 +00:00
pbyMacHdr = ( u8 * ) ( pbyTxBufferAddr + cbHeaderLength ) ;
pbyIVHead = ( u8 * ) ( pbyMacHdr + cbMACHdLen + uPadding ) ;
pbyPayloadHead = ( u8 * ) ( pbyMacHdr + cbMACHdLen + uPadding + cbIVlen ) ;
2009-06-13 11:38:31 +00:00
//=========================
// 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
2010-05-01 17:25:00 +00:00
s_vGenerateTxParameter ( pDevice , byPktType , wCurrentRate ,
( void * ) pbyTxBufferAddr , pvRrvTime , pvRTS , pvCTS ,
2009-06-13 11:38:31 +00:00
cbFrameSize , bNeedACK , uDMAIdx , psEthHeader ) ;
//Fill DataHead
uDuration = s_uFillDataHead ( pDevice , byPktType , wCurrentRate , pvTxDataHd , cbFrameSize , uDMAIdx , bNeedACK ,
2013-08-07 20:31:48 +00:00
byFBOption ) ;
2009-06-13 11:38:31 +00:00
// Generate TX MAC Header
2013-02-26 01:32:52 +00:00
s_vGenerateMACHeader ( pDevice , pbyMacHdr , ( u16 ) uDuration , psEthHeader , bNeedEncryption ,
2009-06-13 11:38:31 +00:00
byFragType , uDMAIdx , 0 ) ;
2013-02-13 01:36:30 +00:00
if ( bNeedEncryption = = true ) {
2009-06-13 11:38:31 +00:00
//Fill TXKEY
2013-02-26 01:32:51 +00:00
s_vFillTxKey ( pDevice , ( u8 * ) ( pTxBufHead - > adwTxKey ) , pbyIVHead , pTransmitKey ,
2013-02-26 01:32:52 +00:00
pbyMacHdr , ( u16 ) cbFrameBodySize , ( u8 * ) pMICHDR ) ;
2009-06-13 11:38:31 +00:00
if ( pDevice - > bEnableHostWEP ) {
pMgmt - > sNodeDBTable [ uNodeIndex ] . dwTSC47_16 = pTransmitKey - > dwTSC47_16 ;
pMgmt - > sNodeDBTable [ uNodeIndex ] . wTSC15_0 = pTransmitKey - > wTSC15_0 ;
}
}
// 802.1H
2013-03-19 01:33:49 +00:00
if ( ntohs ( psEthHeader - > h_proto ) > ETH_DATA_LEN ) {
2010-08-04 22:12:34 +00:00
if ( pDevice - > dwDiagRefCount = = 0 ) {
2013-03-19 01:33:49 +00:00
if ( ( psEthHeader - > h_proto = = cpu_to_be16 ( ETH_P_IPX ) ) | |
( psEthHeader - > h_proto = = cpu_to_le16 ( 0xF380 ) ) ) {
2013-02-26 01:32:51 +00:00
memcpy ( ( u8 * ) ( pbyPayloadHead ) ,
2010-08-04 22:12:34 +00:00
abySNAP_Bridgetunnel , 6 ) ;
2009-06-13 11:38:31 +00:00
} else {
2013-02-26 01:32:51 +00:00
memcpy ( ( u8 * ) ( pbyPayloadHead ) , & abySNAP_RFC1042 [ 0 ] , 6 ) ;
2009-06-13 11:38:31 +00:00
}
2013-02-26 01:32:51 +00:00
pbyType = ( u8 * ) ( pbyPayloadHead + 6 ) ;
2013-03-19 01:33:49 +00:00
memcpy ( pbyType , & ( psEthHeader - > h_proto ) , sizeof ( u16 ) ) ;
2009-06-13 11:38:31 +00:00
} else {
2013-03-19 01:33:49 +00:00
memcpy ( ( u8 * ) ( pbyPayloadHead ) , & ( psEthHeader - > h_proto ) , sizeof ( u16 ) ) ;
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 ) ,
2010-05-18 17:08:14 +00:00
( pPacket + ETH_HLEN ) ,
uSkbPacketLen - ETH_HLEN
2009-06-13 11:38:31 +00:00
) ;
} else {
// while bRelayPacketSend psEthHeader is point to header+payload
2013-02-26 01:32:51 +00:00
memcpy ( ( pbyPayloadHead + cb802_1_H_len ) , ( ( u8 * ) psEthHeader ) + ETH_HLEN , uSkbPacketLen - ETH_HLEN ) ;
2009-06-13 11:38:31 +00:00
}
2013-02-13 01:36:30 +00:00
if ( ( bNeedEncryption = = true ) & & ( pTransmitKey ! = NULL ) & & ( pTransmitKey - > byCipherSuite = = KEY_CTL_TKIP ) ) {
2009-06-13 11:38:31 +00:00
///////////////////////////////////////////////////////////////////
2013-01-17 23:19:37 +00:00
if ( pDevice - > vnt_mgmt . eAuthenMode = = WMAC_AUTH_WPANONE ) {
dwMICKey0 = * ( u32 * ) ( & pTransmitKey - > abyKey [ 16 ] ) ;
dwMICKey1 = * ( u32 * ) ( & pTransmitKey - > abyKey [ 20 ] ) ;
}
2009-06-13 11:38:31 +00:00
else if ( ( pTransmitKey - > dwKeyIndex & AUTHENTICATOR_KEY ) ! = 0 ) {
2013-02-26 01:32:53 +00:00
dwMICKey0 = * ( u32 * ) ( & pTransmitKey - > abyKey [ 16 ] ) ;
dwMICKey1 = * ( u32 * ) ( & pTransmitKey - > abyKey [ 20 ] ) ;
2009-06-13 11:38:31 +00:00
}
else {
2013-02-26 01:32:53 +00:00
dwMICKey0 = * ( u32 * ) ( & pTransmitKey - > abyKey [ 24 ] ) ;
dwMICKey1 = * ( u32 * ) ( & pTransmitKey - > abyKey [ 28 ] ) ;
2009-06-13 11:38:31 +00:00
}
// DO Software Michael
MIC_vInit ( dwMICKey0 , dwMICKey1 ) ;
2013-03-19 01:33:49 +00:00
MIC_vAppend ( ( u8 * ) & ( psEthHeader - > h_dest [ 0 ] ) , 12 ) ;
2009-06-13 11:38:31 +00:00
dwMIC_Priority = 0 ;
2013-02-26 01:32:51 +00:00
MIC_vAppend ( ( u8 * ) & dwMIC_Priority , 4 ) ;
2012-11-11 15:45:52 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " MIC KEY: %X, %X \n " ,
dwMICKey0 , dwMICKey1 ) ;
2009-06-13 11:38:31 +00:00
///////////////////////////////////////////////////////////////////
//DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength));
//for (ii = 0; ii < cbFrameBodySize; ii++) {
2013-02-26 01:32:51 +00:00
// DBG_PRN_GRP12(("%02x ", *((u8 *)((pbyPayloadHead + cb802_1_H_len) + ii))));
2009-06-13 11:38:31 +00:00
//}
//DBG_PRN_GRP12(("\n\n\n"));
MIC_vAppend ( pbyPayloadHead , cbFrameBodySize ) ;
2013-02-26 01:32:53 +00:00
pdwMIC_L = ( u32 * ) ( pbyPayloadHead + cbFrameBodySize ) ;
pdwMIC_R = ( u32 * ) ( pbyPayloadHead + cbFrameBodySize + 4 ) ;
2009-06-13 11:38:31 +00:00
MIC_vGetMIC ( pdwMIC_L , pdwMIC_R ) ;
MIC_vUnInit ( ) ;
2013-02-13 01:36:30 +00:00
if ( pDevice - > bTxMICFail = = true ) {
2009-06-13 11:38:31 +00:00
* pdwMIC_L = 0 ;
* pdwMIC_R = 0 ;
2013-02-13 01:36:29 +00:00
pDevice - > bTxMICFail = false ;
2009-06-13 11:38:31 +00:00
}
//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);
}
2013-02-13 01:36:30 +00:00
if ( bSoftWEP = = true ) {
2009-06-13 11:38:31 +00:00
2013-02-26 01:32:52 +00:00
s_vSWencryption ( pDevice , pTransmitKey , ( pbyPayloadHead ) , ( u16 ) ( cbFrameBodySize + cbMIClen ) ) ;
2009-06-13 11:38:31 +00:00
2013-02-13 01:36:30 +00:00
} else if ( ( ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption1Enabled ) & & ( bNeedEncryption = = true ) ) | |
( ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption2Enabled ) & & ( bNeedEncryption = = true ) ) | |
( ( pDevice - > eEncryptionStatus = = Ndis802_11Encryption3Enabled ) & & ( bNeedEncryption = = true ) ) ) {
2009-06-13 11:38:31 +00:00
cbFrameSize - = cbICVlen ;
}
2013-02-13 01:36:30 +00:00
if ( pDevice - > bSoftwareGenCrcErr = = true ) {
2010-05-18 00:34:01 +00:00
unsigned int cbLen ;
2013-02-26 01:32:53 +00:00
u32 * pdwCRC ;
2009-06-13 11:38:31 +00:00
dwCRC = 0xFFFFFFFFL ;
cbLen = cbFrameSize - cbFCSlen ;
// calculate CRC, and wrtie CRC value to end of TD
dwCRC = CRCdwGetCrc32Ex ( pbyMacHdr , cbLen , dwCRC ) ;
2013-02-26 01:32:53 +00:00
pdwCRC = ( u32 * ) ( pbyMacHdr + cbLen ) ;
2009-06-13 11:38:31 +00:00
// 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
2013-02-26 01:32:52 +00:00
pTxBufHead - > wFragCtl | = ( u16 ) byFragType ;
2009-06-13 11:38:31 +00:00
2013-02-13 01:36:30 +00:00
return true ;
2009-06-13 11:38:31 +00:00
}
/*+
*
* Description :
* Translate 802.3 to 802.11 header
*
* Parameters :
* In :
2012-08-26 15:16:43 +00:00
* pDevice - Pointer to adapter
2009-06-13 11:38:31 +00:00
* 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
*
- */
2013-01-17 23:15:22 +00:00
static void s_vGenerateMACHeader ( struct vnt_private * pDevice ,
2013-03-19 01:33:49 +00:00
u8 * pbyBufferAddr , u16 wDuration , struct ethhdr * psEthHeader ,
2013-01-17 23:15:22 +00:00
int bNeedEncrypt , u16 wFragType , u32 uDMAIdx , u32 uFragIdx )
2009-06-13 11:38:31 +00:00
{
2013-03-19 01:33:50 +00:00
struct ieee80211_hdr * pMACHeader = ( struct ieee80211_hdr * ) pbyBufferAddr ;
2009-06-13 11:38:31 +00:00
if ( uDMAIdx = = TYPE_ATIMDMA ) {
2013-03-19 01:33:50 +00:00
pMACHeader - > frame_control = TYPE_802_11_ATIM ;
2009-06-13 11:38:31 +00:00
} else {
2013-03-19 01:33:50 +00:00
pMACHeader - > frame_control = TYPE_802_11_DATA ;
2009-06-13 11:38:31 +00:00
}
if ( pDevice - > eOPMode = = OP_MODE_AP ) {
2013-03-19 01:33:50 +00:00
memcpy ( & ( pMACHeader - > addr1 [ 0 ] ) ,
2013-03-19 01:33:49 +00:00
& ( psEthHeader - > h_dest [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
ETH_ALEN ) ;
2013-03-19 01:33:50 +00:00
memcpy ( & ( pMACHeader - > addr2 [ 0 ] ) , & ( pDevice - > abyBSSID [ 0 ] ) , ETH_ALEN ) ;
memcpy ( & ( pMACHeader - > addr3 [ 0 ] ) ,
2013-03-19 01:33:49 +00:00
& ( psEthHeader - > h_source [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
ETH_ALEN ) ;
2013-03-19 01:33:50 +00:00
pMACHeader - > frame_control | = FC_FROMDS ;
2010-04-14 00:54:48 +00:00
} else {
if ( pDevice - > eOPMode = = OP_MODE_ADHOC ) {
2013-03-19 01:33:50 +00:00
memcpy ( & ( pMACHeader - > addr1 [ 0 ] ) ,
2013-03-19 01:33:49 +00:00
& ( psEthHeader - > h_dest [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
ETH_ALEN ) ;
2013-03-19 01:33:50 +00:00
memcpy ( & ( pMACHeader - > addr2 [ 0 ] ) ,
2013-03-19 01:33:49 +00:00
& ( psEthHeader - > h_source [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
ETH_ALEN ) ;
2013-03-19 01:33:50 +00:00
memcpy ( & ( pMACHeader - > addr3 [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
& ( pDevice - > abyBSSID [ 0 ] ) ,
ETH_ALEN ) ;
} else {
2013-03-19 01:33:50 +00:00
memcpy ( & ( pMACHeader - > addr3 [ 0 ] ) ,
2013-03-19 01:33:49 +00:00
& ( psEthHeader - > h_dest [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
ETH_ALEN ) ;
2013-03-19 01:33:50 +00:00
memcpy ( & ( pMACHeader - > addr2 [ 0 ] ) ,
2013-03-19 01:33:49 +00:00
& ( psEthHeader - > h_source [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
ETH_ALEN ) ;
2013-03-19 01:33:50 +00:00
memcpy ( & ( pMACHeader - > addr1 [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
& ( pDevice - > abyBSSID [ 0 ] ) ,
ETH_ALEN ) ;
2013-03-19 01:33:50 +00:00
pMACHeader - > frame_control | = FC_TODS ;
2009-06-13 11:38:31 +00:00
}
}
if ( bNeedEncrypt )
2013-03-19 01:33:50 +00:00
pMACHeader - > frame_control | = cpu_to_le16 ( ( u16 ) WLAN_SET_FC_ISWEP ( 1 ) ) ;
2009-06-13 11:38:31 +00:00
2013-03-19 01:33:50 +00:00
pMACHeader - > duration_id = cpu_to_le16 ( wDuration ) ;
2009-06-13 11:38:31 +00:00
if ( pDevice - > bLongHeader ) {
PWLAN_80211HDR_A4 pMACA4Header = ( PWLAN_80211HDR_A4 ) pbyBufferAddr ;
2013-03-19 01:33:50 +00:00
pMACHeader - > frame_control | = ( 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
}
2013-03-19 01:33:50 +00:00
pMACHeader - > seq_ctrl = cpu_to_le16 ( pDevice - > wSeqCounter < < 4 ) ;
2009-06-13 11:38:31 +00:00
//Set FragNumber in Sequence Control
2013-03-19 01:33:50 +00:00
pMACHeader - > seq_ctrl | = cpu_to_le16 ( ( u16 ) uFragIdx ) ;
2009-06-13 11:38:31 +00:00
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
2013-03-19 01:33:50 +00:00
pMACHeader - > frame_control | = FC_MOREFRAG ;
2009-06-13 11:38:31 +00:00
}
}
/*+
*
* 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
*
2013-02-13 01:36:29 +00:00
* Return Value : CMD_STATUS_PENDING if MAC Tx resource available ; otherwise false
2009-06-13 11:38:31 +00:00
*
- */
2013-01-17 23:15:22 +00:00
CMD_STATUS csMgmt_xmit ( struct vnt_private * pDevice ,
struct vnt_tx_mgmt * pPacket )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
struct vnt_manager * pMgmt = & pDevice - > vnt_mgmt ;
PTX_BUFFER pTX_Buffer ;
PSTxBufHead pTxBufHead ;
PUSB_SEND_CONTEXT pContext ;
2013-03-19 01:33:50 +00:00
struct ieee80211_hdr * pMACHeader ;
2013-01-17 23:15:22 +00:00
PSCTS pCTS ;
2013-03-19 01:33:49 +00:00
struct ethhdr sEthHeader ;
2013-01-17 23:15:22 +00:00
u8 byPktType , * pbyTxBufferAddr ;
void * pvRTS , * pvTxDataHd , * pvRrvTime , * pMICHDR ;
u32 uDuration , cbReqCount , cbHeaderSize , cbFrameBodySize , cbFrameSize ;
2013-02-13 01:36:29 +00:00
int bNeedACK , bIsPSPOLL = false ;
2013-01-17 23:15:22 +00:00
u32 cbIVlen = 0 , cbICVlen = 0 , cbMIClen = 0 , cbFCSlen = 4 ;
u32 uPadding = 0 ;
u16 wTxBufSize ;
u32 cbMacHdLen ;
u16 wCurrentRate = RATE_1M ;
2009-06-13 11:38:31 +00:00
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 ] ) ;
2013-02-26 01:32:51 +00:00
pbyTxBufferAddr = ( u8 * ) & ( pTX_Buffer - > adwTxKey [ 0 ] ) ;
2009-06-13 11:38:31 +00:00
cbFrameBodySize = pPacket - > cbPayloadLen ;
pTxBufHead = ( PSTxBufHead ) pbyTxBufferAddr ;
wTxBufSize = sizeof ( STxBufHead ) ;
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 ) ;
2010-08-02 23:21:44 +00:00
if ( is_multicast_ether_addr ( pPacket - > p80211Header - > sA3 . abyAddr1 ) ) {
2013-02-13 01:36:29 +00:00
bNeedACK = false ;
2009-06-13 11:38:31 +00:00
}
else {
2013-02-13 01:36:30 +00:00
bNeedACK = true ;
2009-06-13 11:38:31 +00:00
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) {
2013-02-13 01:36:29 +00:00
// bNeedACK = false;
2009-06-13 11:38:31 +00:00
// pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
//}
}
pTxBufHead - > wFIFOCtl | = ( FIFOCTL_GENINT | FIFOCTL_ISDMA0 ) ;
if ( ( pPacket - > p80211Header - > sA4 . wFrameCtl & TYPE_SUBTYPE_MASK ) = = TYPE_CTL_PSPOLL ) {
2013-02-13 01:36:30 +00:00
bIsPSPOLL = true ;
2009-06-13 11:38:31 +00:00
cbMacHdLen = WLAN_HDR_ADDR2_LEN ;
} else {
cbMacHdLen = WLAN_HDR_ADDR3_LEN ;
}
//Set FRAGCTL_MACHDCNT
2013-02-26 01:32:52 +00:00
pTxBufHead - > wFragCtl | = cpu_to_le16 ( ( u16 ) ( cbMacHdLen < < 10 ) ) ;
2009-06-13 11:38:31 +00:00
// Notes:
// Although spec says MMPDU can be fragmented; In most case,
// no one will send a MMPDU under fragmentation. With RTS may occur.
2013-02-13 01:36:29 +00:00
pDevice - > bAES = false ; //Set FRAGCTL_WEPTYP
2009-06-13 11:38:31 +00:00
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 ;
2013-02-13 01:36:30 +00:00
pDevice - > bAES = true ;
2009-06-13 11:38:31 +00:00
}
//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
2013-02-13 01:36:30 +00:00
if ( pDevice - > bGrpAckPolicy = = true ) { //0000 0100 0000 0000
2009-06-13 11:38:31 +00:00
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 ) ;
}
2013-03-19 01:33:49 +00:00
memcpy ( & ( sEthHeader . h_dest [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
& ( pPacket - > p80211Header - > sA3 . abyAddr1 [ 0 ] ) ,
ETH_ALEN ) ;
2013-03-19 01:33:49 +00:00
memcpy ( & ( sEthHeader . h_source [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
& ( pPacket - > p80211Header - > sA3 . abyAddr2 [ 0 ] ) ,
ETH_ALEN ) ;
2009-06-13 11:38:31 +00:00
//=========================
// No Fragmentation
//=========================
2013-02-26 01:32:52 +00:00
pTxBufHead - > wFragCtl | = ( u16 ) FRAGCTL_NONFRAG ;
2009-06-13 11:38:31 +00:00
//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 ,
2013-08-07 20:31:48 +00:00
AUTO_FB_NONE ) ;
2009-06-13 11:38:31 +00:00
2013-03-19 01:33:50 +00:00
pMACHeader = ( struct ieee80211_hdr * ) ( pbyTxBufferAddr + cbHeaderSize ) ;
2009-06-13 11:38:31 +00:00
cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize ;
if ( WLAN_GET_FC_ISWEP ( pPacket - > p80211Header - > sA4 . wFrameCtl ) ! = 0 ) {
2013-02-26 01:32:51 +00:00
u8 * pbyIVHead ;
u8 * pbyPayloadHead ;
u8 * pbyBSSID ;
2009-06-13 11:38:31 +00:00
PSKeyItem pTransmitKey = NULL ;
2013-02-26 01:32:51 +00:00
pbyIVHead = ( u8 * ) ( pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding ) ;
pbyPayloadHead = ( u8 * ) ( pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen ) ;
2009-06-13 11:38:31 +00:00
do {
if ( ( pDevice - > eOPMode = = OP_MODE_INFRASTRUCTURE ) & &
2013-02-13 01:36:30 +00:00
( pDevice - > bLinkPass = = true ) ) {
2009-06-13 11:38:31 +00:00
pbyBSSID = pDevice - > abyBSSID ;
// get pairwise key
2013-02-13 01:36:29 +00:00
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , PAIRWISE_KEY , & pTransmitKey ) = = false ) {
2009-06-13 11:38:31 +00:00
// get group key
2013-02-13 01:36:30 +00:00
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , GROUP_KEY , & pTransmitKey ) = = true ) {
2009-06-13 11:38:31 +00:00
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 ;
2013-02-13 01:36:29 +00:00
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , GROUP_KEY , & pTransmitKey ) = = false ) {
2009-06-13 11:38:31 +00:00
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 " ) ;
}
2013-02-13 01:36:29 +00:00
} while ( false ) ;
2009-06-13 11:38:31 +00:00
//Fill TXKEY
2013-02-26 01:32:51 +00:00
s_vFillTxKey ( pDevice , ( u8 * ) ( pTxBufHead - > adwTxKey ) , pbyIVHead , pTransmitKey ,
2013-02-26 01:32:52 +00:00
( u8 * ) pMACHeader , ( u16 ) cbFrameBodySize , NULL ) ;
2009-06-13 11:38:31 +00:00
2009-08-12 21:54:11 +00:00
memcpy ( pMACHeader , pPacket - > p80211Header , cbMacHdLen ) ;
2013-02-26 01:32:51 +00:00
memcpy ( pbyPayloadHead , ( ( u8 * ) ( 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
}
2013-03-19 01:33:50 +00:00
pMACHeader - > seq_ctrl = cpu_to_le16 ( pDevice - > wSeqCounter < < 4 ) ;
2009-06-13 11:38:31 +00:00
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
2012-08-26 15:16:43 +00:00
// of FIFO control header.
2009-06-13 11:38:31 +00:00
// 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 ) ;
}
}
2013-02-26 01:32:52 +00:00
pTX_Buffer - > wTxByteCount = cpu_to_le16 ( ( u16 ) ( cbReqCount ) ) ;
2013-02-26 01:32:51 +00:00
pTX_Buffer - > byPKTNO = ( u8 ) ( ( ( wCurrentRate < < 4 ) & 0x00F0 ) | ( ( pDevice - > wSeqCounter - 1 ) & 0x000F ) ) ;
2009-06-13 11:38:31 +00:00
pTX_Buffer - > byType = 0x00 ;
pContext - > pPacket = NULL ;
pContext - > Type = CONTEXT_MGMT_PACKET ;
2013-02-26 01:32:52 +00:00
pContext - > uBufLen = ( u16 ) cbReqCount + 4 ; //USB header
2009-06-13 11:38:31 +00:00
2013-03-19 01:33:50 +00:00
if ( WLAN_GET_FC_TODS ( pMACHeader - > frame_control ) = = 0 ) {
s_vSaveTxPktInfo ( pDevice , ( u8 ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pMACHeader - > addr1 [ 0 ] ) , ( u16 ) cbFrameSize , pTX_Buffer - > wFIFOCtl ) ;
2009-06-13 11:38:31 +00:00
}
else {
2013-03-19 01:33:50 +00:00
s_vSaveTxPktInfo ( pDevice , ( u8 ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pMACHeader - > addr3 [ 0 ] ) , ( u16 ) cbFrameSize , pTX_Buffer - > wFIFOCtl ) ;
2009-06-13 11:38:31 +00:00
}
PIPEnsSendBulkOut ( pDevice , pContext ) ;
return CMD_STATUS_PENDING ;
}
2013-01-17 23:15:22 +00:00
CMD_STATUS csBeacon_xmit ( struct vnt_private * pDevice ,
struct vnt_tx_mgmt * pPacket )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
u32 cbFrameSize = pPacket - > cbMPDULen + WLAN_FCS_LEN ;
u32 cbHeaderSize = 0 ;
u16 wTxBufSize = sizeof ( STxShortBufHead ) ;
PSTxShortBufHead pTxBufHead ;
2013-03-19 01:33:50 +00:00
struct ieee80211_hdr * pMACHeader ;
2013-01-17 23:15:22 +00:00
PSTxDataHead_ab pTxDataHead ;
u16 wCurrentRate ;
u32 cbFrameBodySize ;
u32 cbReqCount ;
PBEACON_BUFFER pTX_Buffer ;
u8 * pbyTxBufferAddr ;
PUSB_SEND_CONTEXT pContext ;
CMD_STATUS status ;
2009-06-13 11:38:31 +00:00
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 ] ) ;
2013-02-26 01:32:51 +00:00
pbyTxBufferAddr = ( u8 * ) & ( pTX_Buffer - > wFIFOCtl ) ;
2009-06-13 11:38:31 +00:00
cbFrameBodySize = pPacket - > cbPayloadLen ;
pTxBufHead = ( PSTxShortBufHead ) pbyTxBufferAddr ;
wTxBufSize = sizeof ( STxShortBufHead ) ;
if ( pDevice - > byBBType = = BB_TYPE_11A ) {
wCurrentRate = RATE_6M ;
pTxDataHead = ( PSTxDataHead_ab ) ( pbyTxBufferAddr + wTxBufSize ) ;
//Get SignalField,ServiceField,Length
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , cbFrameSize , wCurrentRate , PK_TYPE_11A ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( pTxDataHead - > wTransmitLength ) , ( u8 * ) & ( pTxDataHead - > byServiceField ) , ( u8 * ) & ( pTxDataHead - > bySignalField )
2009-06-13 11:38:31 +00:00
) ;
//Get Duration and TimeStampOff
2013-08-07 20:28:45 +00:00
pTxDataHead - > wDuration = cpu_to_le16 ( ( u16 ) s_uGetDataDuration ( pDevice ,
DATADUR_A , PK_TYPE_11A , false ) ) ;
2009-06-13 11:38:31 +00:00
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
2012-08-26 15:16:44 +00:00
BBvCalculateParameter ( pDevice , cbFrameSize , wCurrentRate , PK_TYPE_11B ,
2013-02-26 01:32:52 +00:00
( u16 * ) & ( pTxDataHead - > wTransmitLength ) , ( u8 * ) & ( pTxDataHead - > byServiceField ) , ( u8 * ) & ( pTxDataHead - > bySignalField )
2009-06-13 11:38:31 +00:00
) ;
//Get Duration and TimeStampOff
2013-08-07 20:28:45 +00:00
pTxDataHead - > wDuration = cpu_to_le16 ( ( u16 ) s_uGetDataDuration ( pDevice ,
DATADUR_B , PK_TYPE_11B , false ) ) ;
2009-06-13 11:38:31 +00:00
pTxDataHead - > wTimeStampOff = wTimeStampOff [ pDevice - > byPreambleType % 2 ] [ wCurrentRate % MAX_RATE ] ;
cbHeaderSize = wTxBufSize + sizeof ( STxDataHead_ab ) ;
}
//Generate Beacon Header
2013-03-19 01:33:50 +00:00
pMACHeader = ( struct ieee80211_hdr * ) ( pbyTxBufferAddr + cbHeaderSize ) ;
2009-08-12 21:54:11 +00:00
memcpy ( pMACHeader , pPacket - > p80211Header , pPacket - > cbMPDULen ) ;
2009-06-13 11:38:31 +00:00
2013-03-19 01:33:50 +00:00
pMACHeader - > duration_id = 0 ;
pMACHeader - > seq_ctrl = cpu_to_le16 ( pDevice - > wSeqCounter < < 4 ) ;
2009-06-13 11:38:31 +00:00
pDevice - > wSeqCounter + + ;
if ( pDevice - > wSeqCounter > 0x0fff )
pDevice - > wSeqCounter = 0 ;
cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize ;
2013-02-26 01:32:52 +00:00
pTX_Buffer - > wTxByteCount = ( u16 ) cbReqCount ;
2013-02-26 01:32:51 +00:00
pTX_Buffer - > byPKTNO = ( u8 ) ( ( ( wCurrentRate < < 4 ) & 0x00F0 ) | ( ( pDevice - > wSeqCounter - 1 ) & 0x000F ) ) ;
2009-06-13 11:38:31 +00:00
pTX_Buffer - > byType = 0x01 ;
pContext - > pPacket = NULL ;
pContext - > Type = CONTEXT_MGMT_PACKET ;
2013-02-26 01:32:52 +00:00
pContext - > uBufLen = ( u16 ) cbReqCount + 4 ; //USB header
2009-06-13 11:38:31 +00:00
PIPEnsSendBulkOut ( pDevice , pContext ) ;
return CMD_STATUS_PENDING ;
}
2013-01-17 23:15:22 +00:00
void vDMA0_tx_80211 ( struct vnt_private * pDevice , struct sk_buff * skb )
{
struct vnt_manager * pMgmt = & pDevice - > vnt_mgmt ;
u8 byPktType ;
u8 * pbyTxBufferAddr ;
void * pvRTS , * pvCTS , * pvTxDataHd ;
u32 uDuration , cbReqCount ;
2013-03-19 01:33:50 +00:00
struct ieee80211_hdr * pMACHeader ;
2013-01-17 23:15:22 +00:00
u32 cbHeaderSize , cbFrameBodySize ;
2013-02-13 01:36:29 +00:00
int bNeedACK , bIsPSPOLL = false ;
2013-01-17 23:15:22 +00:00
PSTxBufHead pTxBufHead ;
u32 cbFrameSize ;
u32 cbIVlen = 0 , cbICVlen = 0 , cbMIClen = 0 , cbFCSlen = 4 ;
u32 uPadding = 0 ;
u32 cbMICHDR = 0 , uLength = 0 ;
u32 dwMICKey0 , dwMICKey1 ;
u32 dwMIC_Priority ;
u32 * pdwMIC_L , * pdwMIC_R ;
u16 wTxBufSize ;
u32 cbMacHdLen ;
2013-03-19 01:33:49 +00:00
struct ethhdr sEthHeader ;
2013-01-17 23:15:22 +00:00
void * pvRrvTime , * pMICHDR ;
u32 wCurrentRate = RATE_1M ;
PUWLAN_80211HDR p80211Header ;
u32 uNodeIndex = 0 ;
2013-02-13 01:36:29 +00:00
int bNodeExist = false ;
2013-01-17 23:15:22 +00:00
SKeyItem STempKey ;
PSKeyItem pTransmitKey = NULL ;
u8 * pbyIVHead , * pbyPayloadHead , * pbyMacHdr ;
u32 cbExtSuppRate = 0 ;
PTX_BUFFER pTX_Buffer ;
PUSB_SEND_CONTEXT pContext ;
2009-06-13 11:38:31 +00:00
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 ] ) ;
2013-02-26 01:32:51 +00:00
pbyTxBufferAddr = ( u8 * ) ( & pTX_Buffer - > adwTxKey [ 0 ] ) ;
2009-06-13 11:38:31 +00:00
pTxBufHead = ( PSTxBufHead ) pbyTxBufferAddr ;
wTxBufSize = sizeof ( STxBufHead ) ;
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 ) ;
2010-08-02 23:21:44 +00:00
if ( is_multicast_ether_addr ( p80211Header - > sA3 . abyAddr1 ) ) {
2013-02-13 01:36:29 +00:00
bNeedACK = false ;
2009-06-13 11:38:31 +00:00
if ( pDevice - > bEnableHostWEP ) {
uNodeIndex = 0 ;
2013-02-13 01:36:30 +00:00
bNodeExist = true ;
2011-04-10 21:31:32 +00:00
}
2009-06-13 11:38:31 +00:00
}
else {
if ( pDevice - > bEnableHostWEP ) {
2013-02-26 01:32:51 +00:00
if ( BSSbIsSTAInNodeDB ( pDevice , ( u8 * ) ( p80211Header - > sA3 . abyAddr1 ) , & uNodeIndex ) )
2013-02-13 01:36:30 +00:00
bNodeExist = true ;
2011-04-10 21:31:32 +00:00
}
2013-02-13 01:36:30 +00:00
bNeedACK = true ;
2009-06-13 11:38:31 +00:00
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) {
2013-02-13 01:36:29 +00:00
// bNeedACK = false;
2009-06-13 11:38:31 +00:00
// pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
//}
}
pTxBufHead - > wFIFOCtl | = ( FIFOCTL_GENINT | FIFOCTL_ISDMA0 ) ;
if ( ( p80211Header - > sA4 . wFrameCtl & TYPE_SUBTYPE_MASK ) = = TYPE_CTL_PSPOLL ) {
2013-02-13 01:36:30 +00:00
bIsPSPOLL = true ;
2009-06-13 11:38:31 +00:00
cbMacHdLen = WLAN_HDR_ADDR2_LEN ;
} else {
cbMacHdLen = WLAN_HDR_ADDR3_LEN ;
}
2012-08-26 15:16:43 +00:00
// hostapd daemon ext support rate patch
2009-06-13 11:38:31 +00:00
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
2013-02-26 01:32:52 +00:00
pTxBufHead - > wFragCtl | = cpu_to_le16 ( ( u16 ) cbMacHdLen < < 10 ) ;
2009-06-13 11:38:31 +00:00
// Notes:
// Although spec says MMPDU can be fragmented; In most case,
// no one will send a MMPDU under fragmentation. With RTS may occur.
2013-02-13 01:36:29 +00:00
pDevice - > bAES = false ; //Set FRAGCTL_WEPTYP
2009-06-13 11:38:31 +00:00
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 ;
2013-02-13 01:36:30 +00:00
pDevice - > bAES = true ;
2009-06-13 11:38:31 +00:00
}
//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
2013-02-13 01:36:30 +00:00
if ( pDevice - > bGrpAckPolicy = = true ) { //0000 0100 0000 0000
2009-06-13 11:38:31 +00:00
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 ) ;
}
2013-03-19 01:33:49 +00:00
memcpy ( & ( sEthHeader . h_dest [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
& ( p80211Header - > sA3 . abyAddr1 [ 0 ] ) ,
ETH_ALEN ) ;
2013-03-19 01:33:49 +00:00
memcpy ( & ( sEthHeader . h_source [ 0 ] ) ,
2010-04-14 00:54:48 +00:00
& ( p80211Header - > sA3 . abyAddr2 [ 0 ] ) ,
ETH_ALEN ) ;
2009-06-13 11:38:31 +00:00
//=========================
// No Fragmentation
//=========================
2013-02-26 01:32:52 +00:00
pTxBufHead - > wFragCtl | = ( u16 ) FRAGCTL_NONFRAG ;
2009-06-13 11:38:31 +00:00
//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 ,
2013-08-07 20:31:48 +00:00
AUTO_FB_NONE ) ;
2009-06-13 11:38:31 +00:00
2013-03-19 01:33:50 +00:00
pMACHeader = ( struct ieee80211_hdr * ) ( pbyTxBufferAddr + cbHeaderSize ) ;
2009-06-13 11:38:31 +00:00
cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + ( cbFrameBodySize + cbMIClen ) + cbExtSuppRate ;
2013-02-26 01:32:51 +00:00
pbyMacHdr = ( u8 * ) ( pbyTxBufferAddr + cbHeaderSize ) ;
pbyPayloadHead = ( u8 * ) ( pbyMacHdr + cbMacHdLen + uPadding + cbIVlen ) ;
pbyIVHead = ( u8 * ) ( pbyMacHdr + cbMacHdLen + uPadding ) ;
2009-06-13 11:38:31 +00:00
// Copy the Packet into a tx Buffer
memcpy ( pbyMacHdr , skb - > data , cbMacHdLen ) ;
// version set to 0, patch for hostapd deamon
2013-03-19 01:33:50 +00:00
pMACHeader - > frame_control & = cpu_to_le16 ( 0xfffc ) ;
2009-06-13 11:38:31 +00:00
memcpy ( pbyPayloadHead , ( skb - > data + cbMacHdLen ) , cbFrameBodySize ) ;
2012-08-26 15:16:43 +00:00
// replace support rate, patch for hostapd daemon( only support 11M)
2009-06-13 11:38:31 +00:00
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 ) ) {
2013-02-26 01:32:53 +00:00
dwMICKey0 = * ( u32 * ) ( & pTransmitKey - > abyKey [ 16 ] ) ;
dwMICKey1 = * ( u32 * ) ( & pTransmitKey - > abyKey [ 20 ] ) ;
2009-06-13 11:38:31 +00:00
// DO Software Michael
MIC_vInit ( dwMICKey0 , dwMICKey1 ) ;
2013-03-19 01:33:49 +00:00
MIC_vAppend ( ( u8 * ) & ( sEthHeader . h_dest [ 0 ] ) , 12 ) ;
2009-06-13 11:38:31 +00:00
dwMIC_Priority = 0 ;
2013-02-26 01:32:51 +00:00
MIC_vAppend ( ( u8 * ) & dwMIC_Priority , 4 ) ;
2012-11-11 15:45:52 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " DMA0_tx_8021:MIC KEY: " \
" %X, %X \n " , dwMICKey0 , dwMICKey1 ) ;
2009-06-13 11:38:31 +00:00
uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen ;
MIC_vAppend ( ( pbyTxBufferAddr + uLength ) , cbFrameBodySize ) ;
2013-02-26 01:32:53 +00:00
pdwMIC_L = ( u32 * ) ( pbyTxBufferAddr + uLength + cbFrameBodySize ) ;
pdwMIC_R = ( u32 * ) ( pbyTxBufferAddr + uLength + cbFrameBodySize + 4 ) ;
2009-06-13 11:38:31 +00:00
MIC_vGetMIC ( pdwMIC_L , pdwMIC_R ) ;
MIC_vUnInit ( ) ;
2013-02-13 01:36:30 +00:00
if ( pDevice - > bTxMICFail = = true ) {
2009-06-13 11:38:31 +00:00
* pdwMIC_L = 0 ;
* pdwMIC_R = 0 ;
2013-02-13 01:36:29 +00:00
pDevice - > bTxMICFail = false ;
2009-06-13 11:38:31 +00:00
}
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 ) ;
2012-11-11 15:45:52 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " MIC:%x, %x \n " ,
* pdwMIC_L , * pdwMIC_R ) ;
2009-06-13 11:38:31 +00:00
}
2013-02-26 01:32:51 +00:00
s_vFillTxKey ( pDevice , ( u8 * ) ( pTxBufHead - > adwTxKey ) , pbyIVHead , pTransmitKey ,
2013-02-26 01:32:52 +00:00
pbyMacHdr , ( u16 ) cbFrameBodySize , ( u8 * ) pMICHDR ) ;
2009-06-13 11:38:31 +00:00
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 ) ) {
2013-02-26 01:32:52 +00:00
s_vSWencryption ( pDevice , pTransmitKey , pbyPayloadHead , ( u16 ) ( cbFrameBodySize + cbMIClen ) ) ;
2009-06-13 11:38:31 +00:00
}
}
2013-03-19 01:33:50 +00:00
pMACHeader - > seq_ctrl = cpu_to_le16 ( pDevice - > wSeqCounter < < 4 ) ;
2009-06-13 11:38:31 +00:00
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 ) ;
}
}
2013-02-26 01:32:52 +00:00
pTX_Buffer - > wTxByteCount = cpu_to_le16 ( ( u16 ) ( cbReqCount ) ) ;
2013-02-26 01:32:51 +00:00
pTX_Buffer - > byPKTNO = ( u8 ) ( ( ( wCurrentRate < < 4 ) & 0x00F0 ) | ( ( pDevice - > wSeqCounter - 1 ) & 0x000F ) ) ;
2009-06-13 11:38:31 +00:00
pTX_Buffer - > byType = 0x00 ;
pContext - > pPacket = skb ;
pContext - > Type = CONTEXT_MGMT_PACKET ;
2013-02-26 01:32:52 +00:00
pContext - > uBufLen = ( u16 ) cbReqCount + 4 ; //USB header
2009-06-13 11:38:31 +00:00
2013-03-19 01:33:50 +00:00
if ( WLAN_GET_FC_TODS ( pMACHeader - > frame_control ) = = 0 ) {
s_vSaveTxPktInfo ( pDevice , ( u8 ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pMACHeader - > addr1 [ 0 ] ) , ( u16 ) cbFrameSize , pTX_Buffer - > wFIFOCtl ) ;
2009-06-13 11:38:31 +00:00
}
else {
2013-03-19 01:33:50 +00:00
s_vSaveTxPktInfo ( pDevice , ( u8 ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pMACHeader - > addr3 [ 0 ] ) , ( u16 ) cbFrameSize , pTX_Buffer - > wFIFOCtl ) ;
2009-06-13 11:38:31 +00:00
}
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
*/
2013-01-17 23:15:22 +00:00
int nsDMA_tx_packet ( struct vnt_private * pDevice ,
u32 uDMAIdx , struct sk_buff * skb )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
struct net_device_stats * pStats = & pDevice - > stats ;
struct vnt_manager * pMgmt = & pDevice - > vnt_mgmt ;
u32 BytesToWrite = 0 , uHeaderLen = 0 ;
u32 uNodeIndex = 0 ;
u8 byMask [ 8 ] = { 1 , 2 , 4 , 8 , 0x10 , 0x20 , 0x40 , 0x80 } ;
u16 wAID ;
u8 byPktType ;
2013-02-13 01:36:29 +00:00
int bNeedEncryption = false ;
2013-01-17 23:15:22 +00:00
PSKeyItem pTransmitKey = NULL ;
SKeyItem STempKey ;
int ii ;
2013-02-13 01:36:29 +00:00
int bTKIP_UseGTK = false ;
int bNeedDeAuth = false ;
2013-01-17 23:15:22 +00:00
u8 * pbyBSSID ;
2013-02-13 01:36:29 +00:00
int bNodeExist = false ;
2013-01-17 23:15:22 +00:00
PUSB_SEND_CONTEXT pContext ;
2013-02-13 01:36:28 +00:00
bool fConvertedPacket ;
2013-01-17 23:15:22 +00:00
PTX_BUFFER pTX_Buffer ;
u32 status ;
u16 wKeepRate = pDevice - > wCurrentRate ;
2013-02-13 01:36:29 +00:00
int bTxeapol_key = false ;
2009-06-13 11:38:31 +00:00
if ( pMgmt - > eCurrMode = = WMAC_MODE_ESS_AP ) {
if ( pDevice - > uAssocCount = = 0 ) {
dev_kfree_skb_irq ( skb ) ;
return 0 ;
}
2013-02-26 01:32:51 +00:00
if ( is_multicast_ether_addr ( ( u8 * ) ( skb - > data ) ) ) {
2009-06-13 11:38:31 +00:00
uNodeIndex = 0 ;
2013-02-13 01:36:30 +00:00
bNodeExist = true ;
2009-06-13 11:38:31 +00:00
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 ;
}
2012-08-13 12:21:50 +00:00
// multicast/broadcast data rate
2009-06-13 11:38:31 +00:00
if ( pDevice - > byBBType ! = BB_TYPE_11A )
pDevice - > wCurrentRate = RATE_2M ;
else
pDevice - > wCurrentRate = RATE_24M ;
// long preamble type
pDevice - > byPreambleType = PREAMBLE_SHORT ;
} else {
2013-02-26 01:32:51 +00:00
if ( BSSbIsSTAInNodeDB ( pDevice , ( u8 * ) ( skb - > data ) , & uNodeIndex ) ) {
2009-06-13 11:38:31 +00:00
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 ;
}
2013-02-13 01:36:30 +00:00
bNodeExist = true ;
2009-06-13 11:38:31 +00:00
}
}
2013-02-13 01:36:29 +00:00
if ( bNodeExist = = false ) {
2009-06-13 11:38:31 +00:00
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 ;
}
2013-03-19 01:33:49 +00:00
memcpy ( pDevice - > sTxEthHeader . h_dest , ( u8 * ) ( skb - > data ) , ETH_HLEN ) ;
2009-06-13 11:38:31 +00:00
//mike add:station mode check eapol-key challenge--->
{
2013-02-26 01:32:51 +00:00
u8 Protocol_Version ; //802.1x Authentication
u8 Packet_Type ; //802.1x Authentication
u8 Descriptor_type ;
2013-02-26 01:32:52 +00:00
u16 Key_info ;
2009-06-13 11:38:31 +00:00
2010-05-18 17:08:14 +00:00
Protocol_Version = skb - > data [ ETH_HLEN ] ;
Packet_Type = skb - > data [ ETH_HLEN + 1 ] ;
Descriptor_type = skb - > data [ ETH_HLEN + 1 + 1 + 2 ] ;
Key_info = ( skb - > data [ ETH_HLEN + 1 + 1 + 2 + 1 ] < < 8 ) | ( skb - > data [ ETH_HLEN + 1 + 1 + 2 + 2 ] ) ;
2013-03-19 01:33:49 +00:00
if ( pDevice - > sTxEthHeader . h_proto = = cpu_to_be16 ( ETH_P_PAE ) ) {
2012-08-29 22:08:21 +00:00
/* 802.1x OR eapol-key challenge frame transfer */
if ( ( ( Protocol_Version = = 1 ) | | ( Protocol_Version = = 2 ) ) & &
( Packet_Type = = 3 ) ) {
2013-02-13 01:36:30 +00:00
bTxeapol_key = true ;
2009-06-13 11:38:31 +00:00
if ( ! ( Key_info & BIT3 ) & & //WPA or RSN group-key challenge
( Key_info & BIT8 ) & & ( Key_info & BIT9 ) ) { //send 2/2 key
if ( Descriptor_type = = 254 ) {
2013-02-13 01:36:30 +00:00
pDevice - > fWPA_Authened = true ;
2009-06-13 11:38:31 +00:00
PRINT_K ( " WPA " ) ;
}
else {
2013-02-13 01:36:30 +00:00
pDevice - > fWPA_Authened = true ;
2009-06-13 11:38:31 +00:00
PRINT_K ( " WPA2(re-keying) " ) ;
}
PRINT_K ( " Authentication completed!! \n " ) ;
}
2012-08-26 15:16:43 +00:00
else if ( ( Key_info & BIT3 ) & & ( Descriptor_type = = 2 ) & & //RSN pairwise-key challenge
2009-06-13 11:38:31 +00:00
( Key_info & BIT8 ) & & ( Key_info & BIT9 ) ) {
2013-02-13 01:36:30 +00:00
pDevice - > fWPA_Authened = true ;
2009-06-13 11:38:31 +00:00
PRINT_K ( " WPA2 Authentication completed!! \n " ) ;
}
}
}
}
//mike add:station mode check eapol-key challenge<---
2013-02-13 01:36:30 +00:00
if ( pDevice - > bEncryptionEnable = = true ) {
bNeedEncryption = true ;
2009-06-13 11:38:31 +00:00
// get Transmit key
do {
if ( ( pMgmt - > eCurrMode = = WMAC_MODE_ESS_STA ) & &
( pMgmt - > eCurrState = = WMAC_STATE_ASSOC ) ) {
pbyBSSID = pDevice - > abyBSSID ;
// get pairwise key
2013-02-13 01:36:29 +00:00
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , PAIRWISE_KEY , & pTransmitKey ) = = false ) {
2009-06-13 11:38:31 +00:00
// get group key
2013-02-13 01:36:30 +00:00
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , GROUP_KEY , & pTransmitKey ) = = true ) {
bTKIP_UseGTK = true ;
2009-06-13 11:38:31 +00:00
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 ) {
2013-03-19 01:33:49 +00:00
/* TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 */
pbyBSSID = pDevice - > sTxEthHeader . h_dest ;
2009-06-13 11:38:31 +00:00
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
2013-02-13 01:36:30 +00:00
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , PAIRWISE_KEY , & pTransmitKey ) = = true )
2009-06-13 11:38:31 +00:00
break ;
}
// get group key
pbyBSSID = pDevice - > abyBroadcastAddr ;
2013-02-13 01:36:29 +00:00
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , GROUP_KEY , & pTransmitKey ) = = false ) {
2009-06-13 11:38:31 +00:00
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 {
2013-02-13 01:36:30 +00:00
bTKIP_UseGTK = true ;
2009-06-13 11:38:31 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " Get GTK. \n " ) ;
}
2013-02-13 01:36:29 +00:00
} while ( false ) ;
2009-06-13 11:38:31 +00:00
}
if ( pDevice - > bEnableHostWEP ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_DEBUG " acdma0: STA index %d \n " , uNodeIndex ) ;
2013-02-13 01:36:30 +00:00
if ( pDevice - > bEncryptionEnable = = true ) {
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
) ;
}
}
2013-02-26 01:32:51 +00:00
byPktType = ( u8 ) pDevice - > byPacketType ;
2009-06-13 11:38:31 +00:00
if ( pDevice - > bFixRate ) {
if ( pDevice - > byBBType = = BB_TYPE_11B ) {
if ( pDevice - > uConnectionRate > = RATE_11M ) {
pDevice - > wCurrentRate = RATE_11M ;
} else {
2013-02-26 01:32:52 +00:00
pDevice - > wCurrentRate = ( u16 ) pDevice - > uConnectionRate ;
2009-06-13 11:38:31 +00:00
}
} 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
2013-02-26 01:32:52 +00:00
pDevice - > wCurrentRate = ( u16 ) pDevice - > uConnectionRate ;
2009-06-13 11:38:31 +00:00
}
}
}
else {
if ( pDevice - > eOPMode = = OP_MODE_ADHOC ) {
// Adhoc Tx rate decided from node DB
2013-03-19 01:33:49 +00:00
if ( is_multicast_ether_addr ( pDevice - > sTxEthHeader . h_dest ) ) {
2009-06-13 11:38:31 +00:00
// Multicast use highest data rate
pDevice - > wCurrentRate = pMgmt - > sNodeDBTable [ 0 ] . wTxDataRate ;
// preamble type
pDevice - > byPreambleType = pDevice - > byShortPreamble ;
}
else {
2013-03-19 01:33:49 +00:00
if ( BSSbIsSTAInNodeDB ( pDevice , & ( pDevice - > sTxEthHeader . h_dest [ 0 ] ) , & uNodeIndex ) ) {
2009-06-13 11:38:31 +00:00
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 ;
}
}
2013-03-19 01:33:49 +00:00
if ( pDevice - > sTxEthHeader . h_proto = = cpu_to_be16 ( ETH_P_PAE ) ) {
2012-08-29 22:08:21 +00:00
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 ;
}
}
2009-06-13 11:38:31 +00:00
2010-05-06 23:34:29 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG ,
KERN_INFO " dma_tx: pDevice->wCurrentRate = %d \n " ,
pDevice - > wCurrentRate ) ;
2009-06-13 11:38:31 +00:00
if ( wKeepRate ! = pDevice - > wCurrentRate ) {
2010-05-06 23:34:29 +00:00
bScheduleCommand ( ( void * ) pDevice , WLAN_CMD_SETPOWER , NULL ) ;
2009-06-13 11:38:31 +00:00
}
if ( pDevice - > wCurrentRate < = RATE_11M ) {
byPktType = PK_TYPE_11B ;
}
2013-02-13 01:36:30 +00:00
if ( bNeedEncryption = = true ) {
2013-03-19 01:33:49 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " ntohs Pkt Type=%04x \n " , ntohs ( pDevice - > sTxEthHeader . h_proto ) ) ;
if ( ( pDevice - > sTxEthHeader . h_proto ) = = cpu_to_be16 ( ETH_P_PAE ) ) {
2013-02-13 01:36:29 +00:00
bNeedEncryption = false ;
2013-03-19 01:33:49 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Pkt Type=%04x \n " , ( pDevice - > sTxEthHeader . h_proto ) ) ;
2009-06-13 11:38:31 +00:00
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 {
2013-02-13 01:36:30 +00:00
if ( bTKIP_UseGTK = = true ) {
2009-06-13 11:38:31 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " error: KEY is GTK!!~~ \n " ) ;
}
else {
2012-11-11 15:45:52 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Find PTK [%X] \n " ,
pTransmitKey - > dwKeyIndex ) ;
2013-02-13 01:36:30 +00:00
bNeedEncryption = true ;
2009-06-13 11:38:31 +00:00
}
}
}
if ( pDevice - > bEnableHostWEP ) {
if ( ( uNodeIndex ! = 0 ) & &
( pMgmt - > sNodeDBTable [ uNodeIndex ] . dwKeyIndex & PAIRWISE_KEY ) ) {
2012-11-11 15:45:52 +00:00
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " Find PTK [%X] \n " ,
pTransmitKey - > dwKeyIndex ) ;
2013-02-13 01:36:30 +00:00
bNeedEncryption = true ;
2009-06-13 11:38:31 +00:00
}
}
}
else {
if ( pTransmitKey = = NULL ) {
DBG_PRT ( MSG_LEVEL_DEBUG , KERN_INFO " return no tx key \n " ) ;
2013-02-13 01:36:29 +00:00
pContext - > bBoolInUse = false ;
2009-06-13 11:38:31 +00:00
dev_kfree_skb_irq ( skb ) ;
pStats - > tx_dropped + + ;
return STATUS_FAILURE ;
}
}
}
fConvertedPacket = s_bPacketToWirelessUsb ( pDevice , byPktType ,
2013-02-26 01:32:51 +00:00
( u8 * ) ( & pContext - > Data [ 0 ] ) , bNeedEncryption ,
2009-06-13 11:38:31 +00:00
skb - > len , uDMAIdx , & pDevice - > sTxEthHeader ,
2013-02-26 01:32:51 +00:00
( u8 * ) skb - > data , pTransmitKey , uNodeIndex ,
2009-06-13 11:38:31 +00:00
pDevice - > wCurrentRate ,
& uHeaderLen , & BytesToWrite
) ;
2013-02-13 01:36:29 +00:00
if ( fConvertedPacket = = false ) {
pContext - > bBoolInUse = false ;
2009-06-13 11:38:31 +00:00
dev_kfree_skb_irq ( skb ) ;
return STATUS_FAILURE ;
}
2013-02-13 01:36:30 +00:00
if ( pDevice - > bEnablePSMode = = true ) {
2009-06-13 11:38:31 +00:00
if ( ! pDevice - > bPSModeTxBurst ) {
2010-05-06 23:34:29 +00:00
bScheduleCommand ( ( void * ) pDevice ,
WLAN_CMD_MAC_DISPOWERSAVING ,
NULL ) ;
2013-02-13 01:36:30 +00:00
pDevice - > bPSModeTxBurst = true ;
2009-06-13 11:38:31 +00:00
}
}
pTX_Buffer = ( PTX_BUFFER ) & ( pContext - > Data [ 0 ] ) ;
2013-02-26 01:32:51 +00:00
pTX_Buffer - > byPKTNO = ( u8 ) ( ( ( pDevice - > wCurrentRate < < 4 ) & 0x00F0 ) | ( ( pDevice - > wSeqCounter - 1 ) & 0x000F ) ) ;
2013-02-26 01:32:52 +00:00
pTX_Buffer - > wTxByteCount = ( u16 ) BytesToWrite ;
2009-06-13 11:38:31 +00:00
pContext - > pPacket = skb ;
pContext - > Type = CONTEXT_DATA_PACKET ;
2013-02-26 01:32:52 +00:00
pContext - > uBufLen = ( u16 ) BytesToWrite + 4 ; //USB header
2009-06-13 11:38:31 +00:00
2013-03-19 01:33:49 +00:00
s_vSaveTxPktInfo ( pDevice , ( u8 ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pContext - > sEthHeader . h_dest [ 0 ] ) , ( u16 ) ( BytesToWrite - uHeaderLen ) , pTX_Buffer - > wFIFOCtl ) ;
2009-06-13 11:38:31 +00:00
status = PIPEnsSendBulkOut ( pDevice , pContext ) ;
2013-02-13 01:36:30 +00:00
if ( bNeedDeAuth = = true ) {
2013-02-26 01:32:52 +00:00
u16 wReason = WLAN_MGMT_REASON_MIC_FAILURE ;
2009-06-13 11:38:31 +00:00
2013-02-26 01:32:51 +00:00
bScheduleCommand ( ( void * ) pDevice , WLAN_CMD_DEAUTH , ( u8 * ) & wReason ) ;
2009-06-13 11:38:31 +00:00
}
if ( status ! = STATUS_PENDING ) {
2013-02-13 01:36:29 +00:00
pContext - > bBoolInUse = false ;
2009-06-13 11:38:31 +00:00
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 :
2013-02-13 01:36:29 +00:00
* TURE , false
2009-06-13 11:38:31 +00:00
*
2013-02-13 01:36:30 +00:00
* Return Value : Return true if packet is copy to dma1 ; otherwise false
2009-06-13 11:38:31 +00:00
*/
2013-01-17 23:15:22 +00:00
int bRelayPacketSend ( struct vnt_private * pDevice , u8 * pbySkbData , u32 uDataLen ,
u32 uNodeIndex )
2009-06-13 11:38:31 +00:00
{
2013-01-17 23:15:22 +00:00
struct vnt_manager * pMgmt = & pDevice - > vnt_mgmt ;
u32 BytesToWrite = 0 , uHeaderLen = 0 ;
u8 byPktType = PK_TYPE_11B ;
2013-02-13 01:36:29 +00:00
int bNeedEncryption = false ;
2013-01-17 23:15:22 +00:00
SKeyItem STempKey ;
PSKeyItem pTransmitKey = NULL ;
u8 * pbyBSSID ;
PUSB_SEND_CONTEXT pContext ;
u8 byPktTyp ;
int fConvertedPacket ;
PTX_BUFFER pTX_Buffer ;
u32 status ;
u16 wKeepRate = pDevice - > wCurrentRate ;
2009-06-13 11:38:31 +00:00
pContext = ( PUSB_SEND_CONTEXT ) s_vGetFreeContext ( pDevice ) ;
if ( NULL = = pContext ) {
2013-02-13 01:36:29 +00:00
return false ;
2009-06-13 11:38:31 +00:00
}
2013-03-19 01:33:49 +00:00
memcpy ( pDevice - > sTxEthHeader . h_dest , ( u8 * ) pbySkbData , ETH_HLEN ) ;
2009-06-13 11:38:31 +00:00
2013-02-13 01:36:30 +00:00
if ( pDevice - > bEncryptionEnable = = true ) {
bNeedEncryption = true ;
2009-06-13 11:38:31 +00:00
// get group key
pbyBSSID = pDevice - > abyBroadcastAddr ;
2013-02-13 01:36:29 +00:00
if ( KeybGetTransmitKey ( & ( pDevice - > sKey ) , pbyBSSID , GROUP_KEY , & pTransmitKey ) = = false ) {
2009-06-13 11:38:31 +00:00
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 ) ) {
2013-02-13 01:36:29 +00:00
pContext - > bBoolInUse = false ;
return false ;
2009-06-13 11:38:31 +00:00
}
2013-02-26 01:32:51 +00:00
byPktTyp = ( u8 ) pDevice - > byPacketType ;
2009-06-13 11:38:31 +00:00
if ( pDevice - > bFixRate ) {
if ( pDevice - > byBBType = = BB_TYPE_11B ) {
if ( pDevice - > uConnectionRate > = RATE_11M ) {
pDevice - > wCurrentRate = RATE_11M ;
} else {
2013-02-26 01:32:52 +00:00
pDevice - > wCurrentRate = ( u16 ) pDevice - > uConnectionRate ;
2009-06-13 11:38:31 +00:00
}
} 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
2013-02-26 01:32:52 +00:00
pDevice - > wCurrentRate = ( u16 ) pDevice - > uConnectionRate ;
2009-06-13 11:38:31 +00:00
}
}
}
else {
pDevice - > wCurrentRate = pMgmt - > sNodeDBTable [ uNodeIndex ] . wTxDataRate ;
}
if ( wKeepRate ! = pDevice - > wCurrentRate ) {
2010-05-06 23:34:29 +00:00
bScheduleCommand ( ( void * ) pDevice , WLAN_CMD_SETPOWER , NULL ) ;
2009-06-13 11:38:31 +00:00
}
if ( pDevice - > wCurrentRate < = RATE_11M )
byPktType = PK_TYPE_11B ;
2010-07-12 19:28:32 +00:00
BytesToWrite = uDataLen + ETH_FCS_LEN ;
2009-06-13 11:38:31 +00:00
// Convert the packet to an usb frame and copy into our buffer
// and send the irp.
fConvertedPacket = s_bPacketToWirelessUsb ( pDevice , byPktType ,
2013-02-26 01:32:51 +00:00
( u8 * ) ( & pContext - > Data [ 0 ] ) , bNeedEncryption ,
2009-06-13 11:38:31 +00:00
uDataLen , TYPE_AC0DMA , & pDevice - > sTxEthHeader ,
pbySkbData , pTransmitKey , uNodeIndex ,
pDevice - > wCurrentRate ,
& uHeaderLen , & BytesToWrite
) ;
2013-02-13 01:36:29 +00:00
if ( fConvertedPacket = = false ) {
pContext - > bBoolInUse = false ;
return false ;
2009-06-13 11:38:31 +00:00
}
pTX_Buffer = ( PTX_BUFFER ) & ( pContext - > Data [ 0 ] ) ;
2013-02-26 01:32:51 +00:00
pTX_Buffer - > byPKTNO = ( u8 ) ( ( ( pDevice - > wCurrentRate < < 4 ) & 0x00F0 ) | ( ( pDevice - > wSeqCounter - 1 ) & 0x000F ) ) ;
2013-02-26 01:32:52 +00:00
pTX_Buffer - > wTxByteCount = ( u16 ) BytesToWrite ;
2009-06-13 11:38:31 +00:00
pContext - > pPacket = NULL ;
pContext - > Type = CONTEXT_DATA_PACKET ;
2013-02-26 01:32:52 +00:00
pContext - > uBufLen = ( u16 ) BytesToWrite + 4 ; //USB header
2009-06-13 11:38:31 +00:00
2013-03-19 01:33:49 +00:00
s_vSaveTxPktInfo ( pDevice , ( u8 ) ( pTX_Buffer - > byPKTNO & 0x0F ) , & ( pContext - > sEthHeader . h_dest [ 0 ] ) , ( u16 ) ( BytesToWrite - uHeaderLen ) , pTX_Buffer - > wFIFOCtl ) ;
2009-06-13 11:38:31 +00:00
status = PIPEnsSendBulkOut ( pDevice , pContext ) ;
2013-02-13 01:36:30 +00:00
return true ;
2009-06-13 11:38:31 +00:00
}