|  | /* | 
|  | * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. | 
|  | * All rights reserved. | 
|  | * | 
|  | * This program is free software; you can redistribute it and/or modify | 
|  | * it under the terms of the GNU General Public License as published by | 
|  | * the Free Software Foundation; either version 2 of the License, or | 
|  | * (at your option) any later version. | 
|  | * | 
|  | * This program is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | * GNU General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU General Public License along | 
|  | * with this program; if not, write to the Free Software Foundation, Inc., | 
|  | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 
|  | * | 
|  | * File: rxtx.c | 
|  | * | 
|  | * Purpose: handle WMAC/802.3/802.11 rx & tx functions | 
|  | * | 
|  | * Author: Lyndon Chen | 
|  | * | 
|  | * Date: May 20, 2003 | 
|  | * | 
|  | * Functions: | 
|  | *      s_vGenerateTxParameter - Generate tx dma requried parameter. | 
|  | *      vGenerateMACHeader - Translate 802.3 to 802.11 header | 
|  | *      cbGetFragCount - Caculate fragement number count | 
|  | *      csBeacon_xmit - beacon tx function | 
|  | *      csMgmt_xmit - management tx function | 
|  | *      s_cbFillTxBufHead - fulfill tx dma buffer header | 
|  | *      s_uGetDataDuration - get tx data required duration | 
|  | *      s_uFillDataHead- fulfill tx data duration header | 
|  | *      s_uGetRTSCTSDuration- get rtx/cts requried duration | 
|  | *      s_uGetRTSCTSRsvTime- get rts/cts reserved time | 
|  | *      s_uGetTxRsvTime- get frame reserved time | 
|  | *      s_vFillCTSHead- fulfill CTS ctl header | 
|  | *      s_vFillFragParameter- Set fragement ctl parameter. | 
|  | *      s_vFillRTSHead- fulfill RTS ctl header | 
|  | *      s_vFillTxKey- fulfill tx encrypt key | 
|  | *      s_vSWencryption- Software encrypt header | 
|  | *      vDMA0_tx_80211- tx 802.11 frame via dma0 | 
|  | *      vGenerateFIFOHeader- Generate tx FIFO ctl header | 
|  | * | 
|  | * Revision History: | 
|  | * | 
|  | */ | 
|  |  | 
|  | #include "device.h" | 
|  | #include "rxtx.h" | 
|  | #include "tether.h" | 
|  | #include "card.h" | 
|  | #include "bssdb.h" | 
|  | #include "mac.h" | 
|  | #include "baseband.h" | 
|  | #include "michael.h" | 
|  | #include "tkip.h" | 
|  | #include "tcrc.h" | 
|  | #include "wctl.h" | 
|  | #include "wroute.h" | 
|  | #include "hostap.h" | 
|  | #include "rf.h" | 
|  |  | 
|  | /*---------------------  Static Definitions -------------------------*/ | 
|  |  | 
|  | /*---------------------  Static Classes  ----------------------------*/ | 
|  |  | 
|  | /*---------------------  Static Variables  --------------------------*/ | 
|  | //static int          msglevel                =MSG_LEVEL_DEBUG; | 
|  | static int          msglevel                =MSG_LEVEL_INFO; | 
|  |  | 
|  | #define	PLICE_DEBUG | 
|  |  | 
|  |  | 
|  | /*---------------------  Static Functions  --------------------------*/ | 
|  |  | 
|  | /*---------------------  Static Definitions -------------------------*/ | 
|  | #define CRITICAL_PACKET_LEN      256    // if packet size < 256 -> in-direct send | 
|  | //    packet size >= 256 -> direct send | 
|  |  | 
|  | const WORD wTimeStampOff[2][MAX_RATE] = { | 
|  | {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble | 
|  | {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble | 
|  | }; | 
|  |  | 
|  | const WORD wFB_Opt0[2][5] = { | 
|  | {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0 | 
|  | {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1 | 
|  | }; | 
|  | const WORD wFB_Opt1[2][5] = { | 
|  | {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0 | 
|  | {RATE_6M , RATE_6M,  RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1 | 
|  | }; | 
|  |  | 
|  |  | 
|  | #define RTSDUR_BB       0 | 
|  | #define RTSDUR_BA       1 | 
|  | #define RTSDUR_AA       2 | 
|  | #define CTSDUR_BA       3 | 
|  | #define RTSDUR_BA_F0    4 | 
|  | #define RTSDUR_AA_F0    5 | 
|  | #define RTSDUR_BA_F1    6 | 
|  | #define RTSDUR_AA_F1    7 | 
|  | #define CTSDUR_BA_F0    8 | 
|  | #define CTSDUR_BA_F1    9 | 
|  | #define DATADUR_B       10 | 
|  | #define DATADUR_A       11 | 
|  | #define DATADUR_A_F0    12 | 
|  | #define DATADUR_A_F1    13 | 
|  |  | 
|  | /*---------------------  Static Functions  --------------------------*/ | 
|  |  | 
|  |  | 
|  |  | 
|  | static | 
|  | VOID | 
|  | s_vFillTxKey( | 
|  | IN  PSDevice   pDevice, | 
|  | IN  PBYTE      pbyBuf, | 
|  | IN  PBYTE      pbyIVHead, | 
|  | IN  PSKeyItem  pTransmitKey, | 
|  | IN  PBYTE      pbyHdrBuf, | 
|  | IN  WORD       wPayloadLen, | 
|  | OUT PBYTE      pMICHDR | 
|  | ); | 
|  |  | 
|  |  | 
|  |  | 
|  | static | 
|  | VOID | 
|  | s_vFillRTSHead( | 
|  | IN PSDevice         pDevice, | 
|  | IN BYTE             byPktType, | 
|  | IN PVOID            pvRTS, | 
|  | IN UINT             cbFrameLength, | 
|  | IN BOOL             bNeedAck, | 
|  | IN BOOL             bDisCRC, | 
|  | IN PSEthernetHeader psEthHeader, | 
|  | IN WORD             wCurrentRate, | 
|  | IN BYTE             byFBOption | 
|  | ); | 
|  |  | 
|  | static | 
|  | VOID | 
|  | s_vGenerateTxParameter( | 
|  | IN PSDevice         pDevice, | 
|  | IN  BYTE            byPktType, | 
|  | IN PVOID            pTxBufHead, | 
|  | IN PVOID            pvRrvTime, | 
|  | IN PVOID            pvRTS, | 
|  | IN PVOID            pvCTS, | 
|  | IN UINT             cbFrameSize, | 
|  | IN BOOL             bNeedACK, | 
|  | IN UINT             uDMAIdx, | 
|  | IN PSEthernetHeader psEthHeader, | 
|  | IN WORD             wCurrentRate | 
|  | ); | 
|  |  | 
|  |  | 
|  |  | 
|  | static void s_vFillFragParameter( | 
|  | IN PSDevice pDevice, | 
|  | IN PBYTE    pbyBuffer, | 
|  | IN UINT     uTxType, | 
|  | IN PVOID    pvtdCurr, | 
|  | IN WORD     wFragType, | 
|  | IN UINT     cbReqCount | 
|  | ); | 
|  |  | 
|  |  | 
|  | static | 
|  | UINT | 
|  | s_cbFillTxBufHead ( | 
|  | IN  PSDevice         pDevice, | 
|  | IN  BYTE             byPktType, | 
|  | IN  PBYTE            pbyTxBufferAddr, | 
|  | IN  UINT             cbFrameBodySize, | 
|  | IN  UINT             uDMAIdx, | 
|  | IN  PSTxDesc         pHeadTD, | 
|  | IN  PSEthernetHeader psEthHeader, | 
|  | IN  PBYTE            pPacket, | 
|  | IN  BOOL             bNeedEncrypt, | 
|  | IN  PSKeyItem        pTransmitKey, | 
|  | IN  UINT             uNodeIndex, | 
|  | OUT PUINT            puMACfragNum | 
|  | ); | 
|  |  | 
|  |  | 
|  | static | 
|  | UINT | 
|  | s_uFillDataHead ( | 
|  | IN PSDevice pDevice, | 
|  | IN BYTE     byPktType, | 
|  | IN PVOID    pTxDataHead, | 
|  | IN UINT     cbFrameLength, | 
|  | IN UINT     uDMAIdx, | 
|  | IN BOOL     bNeedAck, | 
|  | IN UINT     uFragIdx, | 
|  | IN UINT     cbLastFragmentSize, | 
|  | IN UINT     uMACfragNum, | 
|  | IN BYTE     byFBOption, | 
|  | IN WORD     wCurrentRate | 
|  | ); | 
|  |  | 
|  |  | 
|  | /*---------------------  Export Variables  --------------------------*/ | 
|  |  | 
|  |  | 
|  |  | 
|  | static | 
|  | VOID | 
|  | s_vFillTxKey ( | 
|  | IN  PSDevice   pDevice, | 
|  | IN  PBYTE      pbyBuf, | 
|  | IN  PBYTE      pbyIVHead, | 
|  | IN  PSKeyItem  pTransmitKey, | 
|  | IN  PBYTE      pbyHdrBuf, | 
|  | IN  WORD       wPayloadLen, | 
|  | OUT PBYTE      pMICHDR | 
|  | ) | 
|  | { | 
|  | PDWORD          pdwIV = (PDWORD) pbyIVHead; | 
|  | PDWORD          pdwExtIV = (PDWORD) ((PBYTE)pbyIVHead+4); | 
|  | WORD            wValue; | 
|  | PS802_11Header  pMACHeader = (PS802_11Header)pbyHdrBuf; | 
|  | DWORD           dwRevIVCounter; | 
|  | BYTE            byKeyIndex = 0; | 
|  |  | 
|  |  | 
|  |  | 
|  | //Fill TXKEY | 
|  | if (pTransmitKey == NULL) | 
|  | return; | 
|  |  | 
|  | dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter); | 
|  | *pdwIV = pDevice->dwIVCounter; | 
|  | byKeyIndex = pTransmitKey->dwKeyIndex & 0xf; | 
|  |  | 
|  | if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { | 
|  | if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){ | 
|  | memcpy(pDevice->abyPRNG, (PBYTE)&(dwRevIVCounter), 3); | 
|  | memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); | 
|  | } else { | 
|  | memcpy(pbyBuf, (PBYTE)&(dwRevIVCounter), 3); | 
|  | memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); | 
|  | if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) { | 
|  | memcpy(pbyBuf+8, (PBYTE)&(dwRevIVCounter), 3); | 
|  | memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength); | 
|  | } | 
|  | memcpy(pDevice->abyPRNG, pbyBuf, 16); | 
|  | } | 
|  | // Append IV after Mac Header | 
|  | *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111 | 
|  | *pdwIV |= (byKeyIndex << 30); | 
|  | *pdwIV = cpu_to_le32(*pdwIV); | 
|  | pDevice->dwIVCounter++; | 
|  | if (pDevice->dwIVCounter > WEP_IV_MASK) { | 
|  | pDevice->dwIVCounter = 0; | 
|  | } | 
|  | } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { | 
|  | pTransmitKey->wTSC15_0++; | 
|  | if (pTransmitKey->wTSC15_0 == 0) { | 
|  | pTransmitKey->dwTSC47_16++; | 
|  | } | 
|  | TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, | 
|  | pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); | 
|  | memcpy(pbyBuf, pDevice->abyPRNG, 16); | 
|  | // Make IV | 
|  | memcpy(pdwIV, pDevice->abyPRNG, 3); | 
|  |  | 
|  | *(pbyIVHead+3) = (BYTE)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV | 
|  | // Append IV&ExtIV after Mac Header | 
|  | *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV); | 
|  |  | 
|  | } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { | 
|  | pTransmitKey->wTSC15_0++; | 
|  | if (pTransmitKey->wTSC15_0 == 0) { | 
|  | pTransmitKey->dwTSC47_16++; | 
|  | } | 
|  | memcpy(pbyBuf, pTransmitKey->abyKey, 16); | 
|  |  | 
|  | // Make IV | 
|  | *pdwIV = 0; | 
|  | *(pbyIVHead+3) = (BYTE)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV | 
|  | *pdwIV |= cpu_to_le16((WORD)(pTransmitKey->wTSC15_0)); | 
|  | //Append IV&ExtIV after Mac Header | 
|  | *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); | 
|  |  | 
|  | //Fill MICHDR0 | 
|  | *pMICHDR = 0x59; | 
|  | *((PBYTE)(pMICHDR+1)) = 0; // TxPriority | 
|  | memcpy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6); | 
|  | *((PBYTE)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16)); | 
|  | *((PBYTE)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16)); | 
|  | *((PBYTE)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16)); | 
|  | *((PBYTE)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16)); | 
|  | *((PBYTE)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0); | 
|  | *((PBYTE)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0); | 
|  | *((PBYTE)(pMICHDR+14)) = HIBYTE(wPayloadLen); | 
|  | *((PBYTE)(pMICHDR+15)) = LOBYTE(wPayloadLen); | 
|  |  | 
|  | //Fill MICHDR1 | 
|  | *((PBYTE)(pMICHDR+16)) = 0; // HLEN[15:8] | 
|  | if (pDevice->bLongHeader) { | 
|  | *((PBYTE)(pMICHDR+17)) = 28; // HLEN[7:0] | 
|  | } else { | 
|  | *((PBYTE)(pMICHDR+17)) = 22; // HLEN[7:0] | 
|  | } | 
|  | wValue = cpu_to_le16(pMACHeader->wFrameCtl & 0xC78F); | 
|  | memcpy(pMICHDR+18, (PBYTE)&wValue, 2); // MSKFRACTL | 
|  | memcpy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6); | 
|  | memcpy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6); | 
|  |  | 
|  | //Fill MICHDR2 | 
|  | memcpy(pMICHDR+32, &(pMACHeader->abyAddr3[0]), 6); | 
|  | wValue = pMACHeader->wSeqCtl; | 
|  | wValue &= 0x000F; | 
|  | wValue = cpu_to_le16(wValue); | 
|  | memcpy(pMICHDR+38, (PBYTE)&wValue, 2); // MSKSEQCTL | 
|  | if (pDevice->bLongHeader) { | 
|  | memcpy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | static | 
|  | VOID | 
|  | s_vSWencryption ( | 
|  | IN  PSDevice            pDevice, | 
|  | IN  PSKeyItem           pTransmitKey, | 
|  | IN  PBYTE               pbyPayloadHead, | 
|  | IN  WORD                wPayloadSize | 
|  | ) | 
|  | { | 
|  | UINT   cbICVlen = 4; | 
|  | DWORD  dwICV = 0xFFFFFFFFL; | 
|  | PDWORD pdwICV; | 
|  |  | 
|  | if (pTransmitKey == NULL) | 
|  | return; | 
|  |  | 
|  | if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { | 
|  | //======================================================================= | 
|  | // Append ICV after payload | 
|  | dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) | 
|  | pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize); | 
|  | // finally, we must invert dwCRC to get the correct answer | 
|  | *pdwICV = cpu_to_le32(~dwICV); | 
|  | // RC4 encryption | 
|  | rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3); | 
|  | rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); | 
|  | //======================================================================= | 
|  | } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { | 
|  | //======================================================================= | 
|  | //Append ICV after payload | 
|  | dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) | 
|  | pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize); | 
|  | // finally, we must invert dwCRC to get the correct answer | 
|  | *pdwICV = cpu_to_le32(~dwICV); | 
|  | // RC4 encryption | 
|  | rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); | 
|  | rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); | 
|  | //======================================================================= | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | /*byPktType : PK_TYPE_11A     0 | 
|  | PK_TYPE_11B     1 | 
|  | PK_TYPE_11GB    2 | 
|  | PK_TYPE_11GA    3 | 
|  | */ | 
|  | static | 
|  | UINT | 
|  | s_uGetTxRsvTime ( | 
|  | IN PSDevice pDevice, | 
|  | IN BYTE     byPktType, | 
|  | IN UINT     cbFrameLength, | 
|  | IN WORD     wRate, | 
|  | IN BOOL     bNeedAck | 
|  | ) | 
|  | { | 
|  | UINT uDataTime, uAckTime; | 
|  |  | 
|  | uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate); | 
|  | #ifdef	PLICE_DEBUG | 
|  | //printk("s_uGetTxRsvTime is %d\n",uDataTime); | 
|  | #endif | 
|  | if (byPktType == PK_TYPE_11B) {//llb,CCK mode | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopCCKBasicRate); | 
|  | } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopOFDMBasicRate); | 
|  | } | 
|  |  | 
|  | if (bNeedAck) { | 
|  | return (uDataTime + pDevice->uSIFS + uAckTime); | 
|  | } | 
|  | else { | 
|  | return uDataTime; | 
|  | } | 
|  | } | 
|  |  | 
|  | //byFreqType: 0=>5GHZ 1=>2.4GHZ | 
|  | static | 
|  | UINT | 
|  | s_uGetRTSCTSRsvTime ( | 
|  | IN PSDevice pDevice, | 
|  | IN BYTE byRTSRsvType, | 
|  | IN BYTE byPktType, | 
|  | IN UINT cbFrameLength, | 
|  | IN WORD wCurrentRate | 
|  | ) | 
|  | { | 
|  | UINT uRrvTime  , uRTSTime, uCTSTime, uAckTime, uDataTime; | 
|  |  | 
|  | uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0; | 
|  |  | 
|  |  | 
|  | uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate); | 
|  | if (byRTSRsvType == 0) { //RTSTxRrvTime_bb | 
|  | uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate); | 
|  | uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); | 
|  | } | 
|  | else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ | 
|  | uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate); | 
|  | uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | } | 
|  | else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa | 
|  | uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate); | 
|  | uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | } | 
|  | else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ | 
|  | uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS; | 
|  | return uRrvTime; | 
|  | } | 
|  |  | 
|  | //RTSRrvTime | 
|  | uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS; | 
|  | return uRrvTime; | 
|  | } | 
|  |  | 
|  | //byFreqType 0: 5GHz, 1:2.4Ghz | 
|  | static | 
|  | UINT | 
|  | s_uGetDataDuration ( | 
|  | IN PSDevice pDevice, | 
|  | IN BYTE     byDurType, | 
|  | IN UINT     cbFrameLength, | 
|  | IN BYTE     byPktType, | 
|  | IN WORD     wRate, | 
|  | IN BOOL     bNeedAck, | 
|  | IN UINT     uFragIdx, | 
|  | IN UINT     cbLastFragmentSize, | 
|  | IN UINT     uMACfragNum, | 
|  | IN BYTE     byFBOption | 
|  | ) | 
|  | { | 
|  | BOOL bLastFrag = 0; | 
|  | UINT uAckTime =0, uNextPktTime = 0; | 
|  |  | 
|  |  | 
|  |  | 
|  | if (uFragIdx == (uMACfragNum-1)) { | 
|  | bLastFrag = 1; | 
|  | } | 
|  |  | 
|  |  | 
|  | switch (byDurType) { | 
|  |  | 
|  | case DATADUR_B:    //DATADUR_B | 
|  | if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag | 
|  | if (bNeedAck) { | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); | 
|  | return (pDevice->uSIFS + uAckTime); | 
|  | } else { | 
|  | return 0; | 
|  | } | 
|  | } | 
|  | else {//First Frag or Mid Frag | 
|  | if (uFragIdx == (uMACfragNum-2)) { | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck); | 
|  | } else { | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); | 
|  | } | 
|  | if (bNeedAck) { | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); | 
|  | return (pDevice->uSIFS + uAckTime + uNextPktTime); | 
|  | } else { | 
|  | return (pDevice->uSIFS + uNextPktTime); | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | case DATADUR_A:    //DATADUR_A | 
|  | if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag | 
|  | if(bNeedAck){ | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | return (pDevice->uSIFS + uAckTime); | 
|  | } else { | 
|  | return 0; | 
|  | } | 
|  | } | 
|  | else {//First Frag or Mid Frag | 
|  | if(uFragIdx == (uMACfragNum-2)){ | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck); | 
|  | } else { | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); | 
|  | } | 
|  | if(bNeedAck){ | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | return (pDevice->uSIFS + uAckTime + uNextPktTime); | 
|  | } else { | 
|  | return (pDevice->uSIFS + uNextPktTime); | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | case DATADUR_A_F0:    //DATADUR_A_F0 | 
|  | if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag | 
|  | if(bNeedAck){ | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | return (pDevice->uSIFS + uAckTime); | 
|  | } else { | 
|  | return 0; | 
|  | } | 
|  | } | 
|  | else { //First Frag or Mid Frag | 
|  | if (byFBOption == AUTO_FB_0) { | 
|  | if (wRate < RATE_18M) | 
|  | wRate = RATE_18M; | 
|  | else if (wRate > RATE_54M) | 
|  | wRate = RATE_54M; | 
|  |  | 
|  | if(uFragIdx == (uMACfragNum-2)){ | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); | 
|  | } else { | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); | 
|  | } | 
|  | } else { // (byFBOption == AUTO_FB_1) | 
|  | if (wRate < RATE_18M) | 
|  | wRate = RATE_18M; | 
|  | else if (wRate > RATE_54M) | 
|  | wRate = RATE_54M; | 
|  |  | 
|  | if(uFragIdx == (uMACfragNum-2)){ | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); | 
|  | } else { | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); | 
|  | } | 
|  | } | 
|  |  | 
|  | if(bNeedAck){ | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | return (pDevice->uSIFS + uAckTime + uNextPktTime); | 
|  | } else { | 
|  | return (pDevice->uSIFS + uNextPktTime); | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | case DATADUR_A_F1:    //DATADUR_A_F1 | 
|  | if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag | 
|  | if(bNeedAck){ | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | return (pDevice->uSIFS + uAckTime); | 
|  | } else { | 
|  | return 0; | 
|  | } | 
|  | } | 
|  | else { //First Frag or Mid Frag | 
|  | if (byFBOption == AUTO_FB_0) { | 
|  | if (wRate < RATE_18M) | 
|  | wRate = RATE_18M; | 
|  | else if (wRate > RATE_54M) | 
|  | wRate = RATE_54M; | 
|  |  | 
|  | if(uFragIdx == (uMACfragNum-2)){ | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); | 
|  | } else { | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); | 
|  | } | 
|  |  | 
|  | } else { // (byFBOption == AUTO_FB_1) | 
|  | if (wRate < RATE_18M) | 
|  | wRate = RATE_18M; | 
|  | else if (wRate > RATE_54M) | 
|  | wRate = RATE_54M; | 
|  |  | 
|  | if(uFragIdx == (uMACfragNum-2)){ | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); | 
|  | } else { | 
|  | uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); | 
|  | } | 
|  | } | 
|  | if(bNeedAck){ | 
|  | uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | return (pDevice->uSIFS + uAckTime + uNextPktTime); | 
|  | } else { | 
|  | return (pDevice->uSIFS + uNextPktTime); | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | default: | 
|  | break; | 
|  | } | 
|  |  | 
|  | ASSERT(FALSE); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | //byFreqType: 0=>5GHZ 1=>2.4GHZ | 
|  | static | 
|  | UINT | 
|  | s_uGetRTSCTSDuration ( | 
|  | IN PSDevice pDevice, | 
|  | IN BYTE byDurType, | 
|  | IN UINT cbFrameLength, | 
|  | IN BYTE byPktType, | 
|  | IN WORD wRate, | 
|  | IN BOOL bNeedAck, | 
|  | IN BYTE byFBOption | 
|  | ) | 
|  | { | 
|  | UINT uCTSTime = 0, uDurTime = 0; | 
|  |  | 
|  |  | 
|  | switch (byDurType) { | 
|  |  | 
|  | case RTSDUR_BB:    //RTSDuration_bb | 
|  | uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); | 
|  | uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); | 
|  | break; | 
|  |  | 
|  | case RTSDUR_BA:    //RTSDuration_ba | 
|  | uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); | 
|  | uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); | 
|  | break; | 
|  |  | 
|  | case RTSDUR_AA:    //RTSDuration_aa | 
|  | uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); | 
|  | break; | 
|  |  | 
|  | case CTSDUR_BA:    //CTSDuration_ba | 
|  | uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); | 
|  | break; | 
|  |  | 
|  | case RTSDUR_BA_F0: //RTSDuration_ba_f0 | 
|  | uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); | 
|  | if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); | 
|  | } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); | 
|  | } | 
|  | break; | 
|  |  | 
|  | case RTSDUR_AA_F0: //RTSDuration_aa_f0 | 
|  | uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); | 
|  | } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); | 
|  | } | 
|  | break; | 
|  |  | 
|  | case RTSDUR_BA_F1: //RTSDuration_ba_f1 | 
|  | uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); | 
|  | if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); | 
|  | } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); | 
|  | } | 
|  | break; | 
|  |  | 
|  | case RTSDUR_AA_F1: //RTSDuration_aa_f1 | 
|  | uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); | 
|  | if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); | 
|  | } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); | 
|  | } | 
|  | break; | 
|  |  | 
|  | case CTSDUR_BA_F0: //CTSDuration_ba_f0 | 
|  | if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); | 
|  | } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); | 
|  | } | 
|  | break; | 
|  |  | 
|  | case CTSDUR_BA_F1: //CTSDuration_ba_f1 | 
|  | if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); | 
|  | } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { | 
|  | uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); | 
|  | } | 
|  | break; | 
|  |  | 
|  | default: | 
|  | break; | 
|  | } | 
|  |  | 
|  | return uDurTime; | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | static | 
|  | UINT | 
|  | s_uFillDataHead ( | 
|  | IN PSDevice pDevice, | 
|  | IN BYTE     byPktType, | 
|  | IN PVOID    pTxDataHead, | 
|  | IN UINT     cbFrameLength, | 
|  | IN UINT     uDMAIdx, | 
|  | IN BOOL     bNeedAck, | 
|  | IN UINT     uFragIdx, | 
|  | IN UINT     cbLastFragmentSize, | 
|  | IN UINT     uMACfragNum, | 
|  | IN BYTE     byFBOption, | 
|  | IN WORD     wCurrentRate | 
|  | ) | 
|  | { | 
|  | WORD  wLen = 0x0000; | 
|  |  | 
|  | if (pTxDataHead == NULL) { | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { | 
|  | if (byFBOption == AUTO_FB_NONE) { | 
|  | PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) | 
|  | ); | 
|  | pBuf->wTransmitLength_a = cpu_to_le16(wLen); | 
|  | BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) | 
|  | ); | 
|  | pBuf->wTransmitLength_b = cpu_to_le16(wLen); | 
|  | //Get Duration and TimeStamp | 
|  | pBuf->wDuration_a = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, | 
|  | byPktType, wCurrentRate, bNeedAck, uFragIdx, | 
|  | cbLastFragmentSize, uMACfragNum, | 
|  | byFBOption)); //1: 2.4GHz | 
|  | pBuf->wDuration_b = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, | 
|  | PK_TYPE_11B, pDevice->byTopCCKBasicRate, | 
|  | bNeedAck, uFragIdx, cbLastFragmentSize, | 
|  | uMACfragNum, byFBOption)); //1: 2.4 | 
|  |  | 
|  | pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); | 
|  | pBuf->wTimeStampOff_b = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE]); | 
|  |  | 
|  | return (pBuf->wDuration_a); | 
|  | } else { | 
|  | // Auto Fallback | 
|  | PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) | 
|  | ); | 
|  | pBuf->wTransmitLength_a = cpu_to_le16(wLen); | 
|  | BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) | 
|  | ); | 
|  | pBuf->wTransmitLength_b = cpu_to_le16(wLen); | 
|  | //Get Duration and TimeStamp | 
|  | pBuf->wDuration_a = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, | 
|  | wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz | 
|  | pBuf->wDuration_b = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B, | 
|  | pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz | 
|  | pBuf->wDuration_a_f0 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, | 
|  | wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz | 
|  | pBuf->wDuration_a_f1 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, | 
|  | wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz | 
|  |  | 
|  | pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); | 
|  | pBuf->wTimeStampOff_b = cpu_to_le16(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)) { | 
|  | // Auto Fallback | 
|  | PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) | 
|  | ); | 
|  | pBuf->wTransmitLength = cpu_to_le16(wLen); | 
|  | //Get Duration and TimeStampOff | 
|  |  | 
|  | pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, | 
|  | wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz | 
|  | pBuf->wDuration_f0 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, | 
|  | wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz | 
|  | pBuf->wDuration_f1 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, | 
|  | wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz | 
|  | pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); | 
|  | return (pBuf->wDuration); | 
|  | } else { | 
|  | PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) | 
|  | ); | 
|  | pBuf->wTransmitLength = cpu_to_le16(wLen); | 
|  | //Get Duration and TimeStampOff | 
|  |  | 
|  | pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, | 
|  | wCurrentRate, bNeedAck, uFragIdx, | 
|  | cbLastFragmentSize, uMACfragNum, | 
|  | byFBOption)); | 
|  |  | 
|  | pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); | 
|  | return (pBuf->wDuration); | 
|  | } | 
|  | } | 
|  | else { | 
|  | PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) | 
|  | ); | 
|  | pBuf->wTransmitLength = cpu_to_le16(wLen); | 
|  | //Get Duration and TimeStampOff | 
|  | pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, | 
|  | wCurrentRate, bNeedAck, uFragIdx, | 
|  | cbLastFragmentSize, uMACfragNum, | 
|  | byFBOption)); | 
|  | pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); | 
|  | return (pBuf->wDuration); | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | static | 
|  | VOID | 
|  | s_vFillRTSHead ( | 
|  | IN PSDevice         pDevice, | 
|  | IN BYTE             byPktType, | 
|  | IN PVOID            pvRTS, | 
|  | IN UINT             cbFrameLength, | 
|  | IN BOOL             bNeedAck, | 
|  | IN BOOL             bDisCRC, | 
|  | IN PSEthernetHeader psEthHeader, | 
|  | IN WORD             wCurrentRate, | 
|  | IN BYTE             byFBOption | 
|  | ) | 
|  | { | 
|  | UINT uRTSFrameLen = 20; | 
|  | WORD  wLen = 0x0000; | 
|  |  | 
|  | if (pvRTS == NULL) | 
|  | return; | 
|  |  | 
|  | if (bDisCRC) { | 
|  | // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame, | 
|  | // in this case we need to decrease its length by 4. | 
|  | uRTSFrameLen -= 4; | 
|  | } | 
|  |  | 
|  | // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account. | 
|  | //       Otherwise, we need to modified codes for them. | 
|  | if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { | 
|  | if (byFBOption == AUTO_FB_NONE) { | 
|  | PSRTS_g pBuf = (PSRTS_g)pvRTS; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) | 
|  | ); | 
|  | pBuf->wTransmitLength_b = cpu_to_le16(wLen); | 
|  | BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) | 
|  | ); | 
|  | pBuf->wTransmitLength_a = cpu_to_le16(wLen); | 
|  | //Get Duration | 
|  | pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData | 
|  | pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData | 
|  | pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data | 
|  |  | 
|  | pBuf->Data.wDurationID = pBuf->wDuration_aa; | 
|  | //Get RTS Frame body | 
|  | pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 | 
|  | if ((pDevice->eOPMode == OP_MODE_ADHOC) || | 
|  | (pDevice->eOPMode == OP_MODE_AP)) { | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | else { | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | if (pDevice->eOPMode == OP_MODE_AP) { | 
|  | memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | else { | 
|  | memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | } | 
|  | else { | 
|  | PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) | 
|  | ); | 
|  | pBuf->wTransmitLength_b = cpu_to_le16(wLen); | 
|  | BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) | 
|  | ); | 
|  | pBuf->wTransmitLength_a = cpu_to_le16(wLen); | 
|  |  | 
|  | //Get Duration | 
|  | pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData | 
|  | pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData | 
|  | pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData | 
|  | pBuf->wRTSDuration_ba_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData | 
|  | pBuf->wRTSDuration_aa_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData | 
|  | pBuf->wRTSDuration_ba_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData | 
|  | pBuf->wRTSDuration_aa_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData | 
|  | pBuf->Data.wDurationID = pBuf->wDuration_aa; | 
|  | //Get RTS Frame body | 
|  | pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 | 
|  |  | 
|  | if ((pDevice->eOPMode == OP_MODE_ADHOC) || | 
|  | (pDevice->eOPMode == OP_MODE_AP)) { | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | else { | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  |  | 
|  | if (pDevice->eOPMode == OP_MODE_AP) { | 
|  | memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | else { | 
|  | memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  |  | 
|  | } // if (byFBOption == AUTO_FB_NONE) | 
|  | } | 
|  | else if (byPktType == PK_TYPE_11A) { | 
|  | if (byFBOption == AUTO_FB_NONE) { | 
|  | PSRTS_ab pBuf = (PSRTS_ab)pvRTS; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) | 
|  | ); | 
|  | pBuf->wTransmitLength = cpu_to_le16(wLen); | 
|  | //Get Duration | 
|  | pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData | 
|  | pBuf->Data.wDurationID = pBuf->wDuration; | 
|  | //Get RTS Frame body | 
|  | pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 | 
|  |  | 
|  | if ((pDevice->eOPMode == OP_MODE_ADHOC) || | 
|  | (pDevice->eOPMode == OP_MODE_AP)) { | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | else { | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  |  | 
|  | if (pDevice->eOPMode == OP_MODE_AP) { | 
|  | memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | else { | 
|  | memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  |  | 
|  | } | 
|  | else { | 
|  | PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) | 
|  | ); | 
|  | pBuf->wTransmitLength = cpu_to_le16(wLen); | 
|  | //Get Duration | 
|  | pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData | 
|  | pBuf->wRTSDuration_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData | 
|  | pBuf->wRTSDuration_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0: | 
|  | pBuf->Data.wDurationID = pBuf->wDuration; | 
|  | //Get RTS Frame body | 
|  | pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 | 
|  |  | 
|  | if ((pDevice->eOPMode == OP_MODE_ADHOC) || | 
|  | (pDevice->eOPMode == OP_MODE_AP)) { | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | else { | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | if (pDevice->eOPMode == OP_MODE_AP) { | 
|  | memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | else { | 
|  | memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | } | 
|  | } | 
|  | else if (byPktType == PK_TYPE_11B) { | 
|  | PSRTS_ab pBuf = (PSRTS_ab)pvRTS; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) | 
|  | ); | 
|  | pBuf->wTransmitLength = cpu_to_le16(wLen); | 
|  | //Get Duration | 
|  | pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData | 
|  | pBuf->Data.wDurationID = pBuf->wDuration; | 
|  | //Get RTS Frame body | 
|  | pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 | 
|  |  | 
|  |  | 
|  | if ((pDevice->eOPMode == OP_MODE_ADHOC) || | 
|  | (pDevice->eOPMode == OP_MODE_AP)) { | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | else { | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  |  | 
|  | if (pDevice->eOPMode == OP_MODE_AP) { | 
|  | memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | else { | 
|  | memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | static | 
|  | VOID | 
|  | s_vFillCTSHead ( | 
|  | IN PSDevice pDevice, | 
|  | IN UINT     uDMAIdx, | 
|  | IN BYTE     byPktType, | 
|  | IN PVOID    pvCTS, | 
|  | IN UINT     cbFrameLength, | 
|  | IN BOOL     bNeedAck, | 
|  | IN BOOL     bDisCRC, | 
|  | IN WORD     wCurrentRate, | 
|  | IN BYTE     byFBOption | 
|  | ) | 
|  | { | 
|  | UINT uCTSFrameLen = 14; | 
|  | WORD  wLen = 0x0000; | 
|  |  | 
|  | if (pvCTS == NULL) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (bDisCRC) { | 
|  | // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame, | 
|  | // in this case we need to decrease its length by 4. | 
|  | uCTSFrameLen -= 4; | 
|  | } | 
|  |  | 
|  | if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { | 
|  | if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) { | 
|  | // Auto Fall back | 
|  | PSCTS_FB pBuf = (PSCTS_FB)pvCTS; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) | 
|  | ); | 
|  |  | 
|  |  | 
|  | pBuf->wTransmitLength_b = cpu_to_le16(wLen); | 
|  |  | 
|  | pBuf->wDuration_ba = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data | 
|  | pBuf->wDuration_ba += pDevice->wCTSDuration; | 
|  | pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba); | 
|  | //Get CTSDuration_ba_f0 | 
|  | pBuf->wCTSDuration_ba_f0 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data | 
|  | pBuf->wCTSDuration_ba_f0 += pDevice->wCTSDuration; | 
|  | pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0); | 
|  | //Get CTSDuration_ba_f1 | 
|  | pBuf->wCTSDuration_ba_f1 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data | 
|  | pBuf->wCTSDuration_ba_f1 += pDevice->wCTSDuration; | 
|  | pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1); | 
|  | //Get CTS Frame body | 
|  | pBuf->Data.wDurationID = pBuf->wDuration_ba; | 
|  | pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4 | 
|  | pBuf->Data.wReserved = 0x0000; | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN); | 
|  |  | 
|  | } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) | 
|  | PSCTS pBuf = (PSCTS)pvCTS; | 
|  | //Get SignalField,ServiceField,Length | 
|  | BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, | 
|  | (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) | 
|  | ); | 
|  | pBuf->wTransmitLength_b = cpu_to_le16(wLen); | 
|  | //Get CTSDuration_ba | 
|  | pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data | 
|  | pBuf->wDuration_ba += pDevice->wCTSDuration; | 
|  | pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba); | 
|  |  | 
|  | //Get CTS Frame body | 
|  | pBuf->Data.wDurationID = pBuf->wDuration_ba; | 
|  | pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4 | 
|  | pBuf->Data.wReserved = 0x0000; | 
|  | memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | /*+ | 
|  | * | 
|  | * 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 | 
|  | *      uDescIdx        - Desc Index | 
|  | *  Out: | 
|  | *      none | 
|  | * | 
|  | * Return Value: none | 
|  | * | 
|  | -*/ | 
|  | // UINT            cbFrameSize,//Hdr+Payload+FCS | 
|  | static | 
|  | VOID | 
|  | s_vGenerateTxParameter ( | 
|  | IN PSDevice         pDevice, | 
|  | IN BYTE             byPktType, | 
|  | IN PVOID            pTxBufHead, | 
|  | IN PVOID            pvRrvTime, | 
|  | IN PVOID            pvRTS, | 
|  | IN PVOID            pvCTS, | 
|  | IN UINT             cbFrameSize, | 
|  | IN BOOL             bNeedACK, | 
|  | IN UINT             uDMAIdx, | 
|  | IN PSEthernetHeader psEthHeader, | 
|  | IN WORD             wCurrentRate | 
|  | ) | 
|  | { | 
|  | UINT cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24 | 
|  | WORD wFifoCtl; | 
|  | BOOL bDisCRC = FALSE; | 
|  | BYTE byFBOption = AUTO_FB_NONE; | 
|  | //    WORD wCurrentRate = pDevice->wCurrentRate; | 
|  |  | 
|  | //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n"); | 
|  | PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead; | 
|  | pFifoHead->wReserved = wCurrentRate; | 
|  | wFifoCtl = pFifoHead->wFIFOCtl; | 
|  |  | 
|  | if (wFifoCtl & FIFOCTL_CRCDIS) { | 
|  | bDisCRC = TRUE; | 
|  | } | 
|  |  | 
|  | if (wFifoCtl & FIFOCTL_AUTO_FB_0) { | 
|  | byFBOption = AUTO_FB_0; | 
|  | } | 
|  | else if (wFifoCtl & FIFOCTL_AUTO_FB_1) { | 
|  | byFBOption = AUTO_FB_1; | 
|  | } | 
|  |  | 
|  | if (pDevice->bLongHeader) | 
|  | cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; | 
|  |  | 
|  | if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { | 
|  |  | 
|  | if (pvRTS != NULL) { //RTS_need | 
|  | //Fill RsvTime | 
|  | if (pvRrvTime) { | 
|  | PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime; | 
|  | pBuf->wRTSTxRrvTime_aa = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz | 
|  | pBuf->wRTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz | 
|  | pBuf->wRTSTxRrvTime_bb = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz | 
|  | pBuf->wTxRrvTime_a = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM | 
|  | pBuf->wTxRrvTime_b = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK | 
|  | } | 
|  | //Fill RTS | 
|  | s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); | 
|  | } | 
|  | else {//RTS_needless, PCF mode | 
|  |  | 
|  | //Fill RsvTime | 
|  | if (pvRrvTime) { | 
|  | PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime; | 
|  | pBuf->wTxRrvTime_a = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM | 
|  | pBuf->wTxRrvTime_b = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK | 
|  | pBuf->wCTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz | 
|  | } | 
|  |  | 
|  |  | 
|  | //Fill CTS | 
|  | s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption); | 
|  | } | 
|  | } | 
|  | else if (byPktType == PK_TYPE_11A) { | 
|  |  | 
|  | if (pvRTS != NULL) {//RTS_need, non PCF mode | 
|  | //Fill RsvTime | 
|  | if (pvRrvTime) { | 
|  | PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; | 
|  | pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz | 
|  | pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM | 
|  | } | 
|  | //Fill RTS | 
|  | s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); | 
|  | } | 
|  | else if (pvRTS == NULL) {//RTS_needless, non PCF mode | 
|  | //Fill RsvTime | 
|  | if (pvRrvTime) { | 
|  | PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; | 
|  | pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM | 
|  | } | 
|  | } | 
|  | } | 
|  | else if (byPktType == PK_TYPE_11B) { | 
|  |  | 
|  | if ((pvRTS != NULL)) {//RTS_need, non PCF mode | 
|  | //Fill RsvTime | 
|  | if (pvRrvTime) { | 
|  | PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; | 
|  | pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz | 
|  | pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK | 
|  | } | 
|  | //Fill RTS | 
|  | s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); | 
|  | } | 
|  | else { //RTS_needless, non PCF mode | 
|  | //Fill RsvTime | 
|  | if (pvRrvTime) { | 
|  | PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; | 
|  | pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK | 
|  | } | 
|  | } | 
|  | } | 
|  | //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n"); | 
|  | } | 
|  | /* | 
|  | PBYTE pbyBuffer,//point to pTxBufHead | 
|  | WORD  wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last | 
|  | UINT  cbFragmentSize,//Hdr+payoad+FCS | 
|  | */ | 
|  | static | 
|  | VOID | 
|  | s_vFillFragParameter( | 
|  | IN PSDevice pDevice, | 
|  | IN PBYTE    pbyBuffer, | 
|  | IN UINT     uTxType, | 
|  | IN PVOID    pvtdCurr, | 
|  | IN WORD     wFragType, | 
|  | IN UINT     cbReqCount | 
|  | ) | 
|  | { | 
|  | PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer; | 
|  | //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vFillFragParameter...\n"); | 
|  |  | 
|  | if (uTxType == TYPE_SYNCDMA) { | 
|  | //PSTxSyncDesc ptdCurr = (PSTxSyncDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx); | 
|  | PSTxSyncDesc ptdCurr = (PSTxSyncDesc)pvtdCurr; | 
|  |  | 
|  | //Set FIFOCtl & TimeStamp in TxSyncDesc | 
|  | ptdCurr->m_wFIFOCtl = pTxBufHead->wFIFOCtl; | 
|  | ptdCurr->m_wTimeStamp = pTxBufHead->wTimeStamp; | 
|  | //Set TSR1 & ReqCount in TxDescHead | 
|  | ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount)); | 
|  | if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation | 
|  | ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); | 
|  | } | 
|  | else { | 
|  | ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP); | 
|  | } | 
|  | } | 
|  | else { | 
|  | //PSTxDesc ptdCurr = (PSTxDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx); | 
|  | PSTxDesc ptdCurr = (PSTxDesc)pvtdCurr; | 
|  | //Set TSR1 & ReqCount in TxDescHead | 
|  | ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount)); | 
|  | if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation | 
|  | ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); | 
|  | } | 
|  | else { | 
|  | ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP); | 
|  | } | 
|  | } | 
|  |  | 
|  | pTxBufHead->wFragCtl |= (WORD)wFragType;//0x0001; //0000 0000 0000 0001 | 
|  |  | 
|  | //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vFillFragParameter END\n"); | 
|  | } | 
|  |  | 
|  | static | 
|  | UINT | 
|  | s_cbFillTxBufHead ( | 
|  | IN  PSDevice         pDevice, | 
|  | IN  BYTE             byPktType, | 
|  | IN  PBYTE            pbyTxBufferAddr, | 
|  | IN  UINT             cbFrameBodySize, | 
|  | IN  UINT             uDMAIdx, | 
|  | IN  PSTxDesc         pHeadTD, | 
|  | IN  PSEthernetHeader psEthHeader, | 
|  | IN  PBYTE            pPacket, | 
|  | IN  BOOL             bNeedEncrypt, | 
|  | IN  PSKeyItem        pTransmitKey, | 
|  | IN  UINT             uNodeIndex, | 
|  | OUT PUINT            puMACfragNum | 
|  | ) | 
|  | { | 
|  | UINT           cbMACHdLen; | 
|  | UINT           cbFrameSize; | 
|  | UINT           cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS | 
|  | UINT           cbFragPayloadSize; | 
|  | UINT           cbLastFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS | 
|  | UINT           cbLastFragPayloadSize; | 
|  | UINT           uFragIdx; | 
|  | PBYTE          pbyPayloadHead; | 
|  | PBYTE          pbyIVHead; | 
|  | PBYTE          pbyMacHdr; | 
|  | WORD           wFragType; //00:Non-Frag, 01:Start, 10:Mid, 11:Last | 
|  | UINT           uDuration; | 
|  | PBYTE          pbyBuffer; | 
|  | //    UINT           uKeyEntryIdx = NUM_KEY_ENTRY+1; | 
|  | //    BYTE           byKeySel = 0xFF; | 
|  | UINT           cbIVlen = 0; | 
|  | UINT           cbICVlen = 0; | 
|  | UINT           cbMIClen = 0; | 
|  | UINT           cbFCSlen = 4; | 
|  | UINT           cb802_1_H_len = 0; | 
|  | UINT           uLength = 0; | 
|  | UINT           uTmpLen = 0; | 
|  | //    BYTE           abyTmp[8]; | 
|  | //    DWORD          dwCRC; | 
|  | UINT           cbMICHDR = 0; | 
|  | DWORD          dwMICKey0, dwMICKey1; | 
|  | DWORD          dwMIC_Priority; | 
|  | PDWORD         pdwMIC_L; | 
|  | PDWORD         pdwMIC_R; | 
|  | DWORD          dwSafeMIC_L, dwSafeMIC_R; //Fix "Last Frag Size" < "MIC length". | 
|  | BOOL           bMIC2Frag = FALSE; | 
|  | UINT           uMICFragLen = 0; | 
|  | UINT           uMACfragNum = 1; | 
|  | UINT           uPadding = 0; | 
|  | UINT           cbReqCount = 0; | 
|  |  | 
|  | BOOL           bNeedACK; | 
|  | BOOL           bRTS; | 
|  | BOOL           bIsAdhoc; | 
|  | PBYTE          pbyType; | 
|  | PSTxDesc       ptdCurr; | 
|  | PSTxBufHead    psTxBufHd = (PSTxBufHead) pbyTxBufferAddr; | 
|  | //    UINT           tmpDescIdx; | 
|  | UINT           cbHeaderLength = 0; | 
|  | PVOID          pvRrvTime; | 
|  | PSMICHDRHead   pMICHDR; | 
|  | PVOID          pvRTS; | 
|  | PVOID          pvCTS; | 
|  | PVOID          pvTxDataHd; | 
|  | WORD           wTxBufSize;   // FFinfo size | 
|  | UINT           uTotalCopyLength = 0; | 
|  | BYTE           byFBOption = AUTO_FB_NONE; | 
|  | BOOL           bIsWEP256 = FALSE; | 
|  | PSMgmtObject    pMgmt = pDevice->pMgmt; | 
|  |  | 
|  |  | 
|  | pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; | 
|  |  | 
|  | //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_cbFillTxBufHead...\n"); | 
|  | if ((pDevice->eOPMode == OP_MODE_ADHOC) || | 
|  | (pDevice->eOPMode == OP_MODE_AP)) { | 
|  |  | 
|  | if (IS_MULTICAST_ADDRESS(&(psEthHeader->abyDstAddr[0])) || | 
|  | IS_BROADCAST_ADDRESS(&(psEthHeader->abyDstAddr[0]))) { | 
|  | bNeedACK = FALSE; | 
|  | } | 
|  | else { | 
|  | bNeedACK = TRUE; | 
|  | } | 
|  | bIsAdhoc = TRUE; | 
|  | } | 
|  | else { | 
|  | // MSDUs in Infra mode always need ACK | 
|  | bNeedACK = TRUE; | 
|  | bIsAdhoc = FALSE; | 
|  | } | 
|  |  | 
|  | if (pDevice->bLongHeader) | 
|  | cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; | 
|  | else | 
|  | cbMACHdLen = WLAN_HDR_ADDR3_LEN; | 
|  |  | 
|  |  | 
|  | if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL)) { | 
|  | if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { | 
|  | cbIVlen = 4; | 
|  | cbICVlen = 4; | 
|  | if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) { | 
|  | bIsWEP256 = TRUE; | 
|  | } | 
|  | } | 
|  | if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { | 
|  | cbIVlen = 8;//IV+ExtIV | 
|  | cbMIClen = 8; | 
|  | cbICVlen = 4; | 
|  | } | 
|  | if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { | 
|  | cbIVlen = 8;//RSN Header | 
|  | cbICVlen = 8;//MIC | 
|  | cbMICHDR = sizeof(SMICHDRHead); | 
|  | } | 
|  | if (pDevice->byLocalID > REV_ID_VT3253_A1) { | 
|  | //MAC Header should be padding 0 to DW alignment. | 
|  | uPadding = 4 - (cbMACHdLen%4); | 
|  | uPadding %= 4; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen; | 
|  |  | 
|  | if ((bNeedACK == FALSE) || | 
|  | (cbFrameSize < pDevice->wRTSThreshold) || | 
|  | ((cbFrameSize >= pDevice->wFragmentationThreshold) && (pDevice->wFragmentationThreshold <= pDevice->wRTSThreshold)) | 
|  | ) { | 
|  | bRTS = FALSE; | 
|  | } | 
|  | else { | 
|  | bRTS = TRUE; | 
|  | psTxBufHd->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY); | 
|  | } | 
|  | // | 
|  | // Use for AUTO FALL BACK | 
|  | // | 
|  | if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_0) { | 
|  | byFBOption = AUTO_FB_0; | 
|  | } | 
|  | else if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_1) { | 
|  | byFBOption = AUTO_FB_1; | 
|  | } | 
|  |  | 
|  | ////////////////////////////////////////////////////// | 
|  | //Set RrvTime/RTS/CTS Buffer | 
|  | wTxBufSize = sizeof(STxBufHead); | 
|  | if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet | 
|  |  | 
|  | if (byFBOption == AUTO_FB_NONE) { | 
|  | if (bRTS == TRUE) {//RTS_need | 
|  | pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize); | 
|  | pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS)); | 
|  | pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR); | 
|  | pvCTS = NULL; | 
|  | pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g)); | 
|  | cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g) + sizeof(STxDataHead_g); | 
|  | } | 
|  | else { //RTS_needless | 
|  | pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); | 
|  | pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); | 
|  | pvRTS = NULL; | 
|  | pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); | 
|  | pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS)); | 
|  | cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g); | 
|  | } | 
|  | } else { | 
|  | // Auto Fall Back | 
|  | if (bRTS == TRUE) {//RTS_need | 
|  | pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize); | 
|  | pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS)); | 
|  | pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR); | 
|  | pvCTS = NULL; | 
|  | pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB)); | 
|  | cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB) + sizeof(STxDataHead_g_FB); | 
|  | } | 
|  | else { //RTS_needless | 
|  | pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); | 
|  | pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); | 
|  | pvRTS = NULL; | 
|  | pvCTS = (PSCTS_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); | 
|  | pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB)); | 
|  | cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB) + sizeof(STxDataHead_g_FB); | 
|  | } | 
|  | } // Auto Fall Back | 
|  | } | 
|  | else {//802.11a/b packet | 
|  |  | 
|  | if (byFBOption == AUTO_FB_NONE) { | 
|  | if (bRTS == TRUE) { | 
|  | 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(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab)); | 
|  | cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab); | 
|  | } | 
|  | else { //RTS_needless, need MICHDR | 
|  | pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); | 
|  | pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); | 
|  | pvRTS = NULL; | 
|  | pvCTS = NULL; | 
|  | pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); | 
|  | cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab); | 
|  | } | 
|  | } else { | 
|  | // Auto Fall Back | 
|  | if (bRTS == TRUE) {//RTS_need | 
|  | pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); | 
|  | pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); | 
|  | pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); | 
|  | pvCTS = NULL; | 
|  | pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB)); | 
|  | cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB); | 
|  | } | 
|  | else { //RTS_needless | 
|  | pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); | 
|  | pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); | 
|  | pvRTS = NULL; | 
|  | pvCTS = NULL; | 
|  | pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); | 
|  | cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_a_FB); | 
|  | } | 
|  | } // Auto Fall Back | 
|  | } | 
|  | memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); | 
|  |  | 
|  | ////////////////////////////////////////////////////////////////// | 
|  | if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { | 
|  | if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { | 
|  | dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]); | 
|  | dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]); | 
|  | } | 
|  | else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) { | 
|  | dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]); | 
|  | dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]); | 
|  | } | 
|  | else { | 
|  | dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[24]); | 
|  | dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[28]); | 
|  | } | 
|  | // DO Software Michael | 
|  | MIC_vInit(dwMICKey0, dwMICKey1); | 
|  | MIC_vAppend((PBYTE)&(psEthHeader->abyDstAddr[0]), 12); | 
|  | dwMIC_Priority = 0; | 
|  | MIC_vAppend((PBYTE)&dwMIC_Priority, 4); | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1); | 
|  | } | 
|  |  | 
|  | /////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderLength); | 
|  | pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen); | 
|  | pbyIVHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding); | 
|  |  | 
|  | if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == TRUE) && (bIsWEP256 == FALSE)) { | 
|  | // Fragmentation | 
|  | // FragThreshold = Fragment size(Hdr+(IV)+fragment payload+(MIC)+(ICV)+FCS) | 
|  | cbFragmentSize = pDevice->wFragmentationThreshold; | 
|  | cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen; | 
|  | //FragNum = (FrameSize-(Hdr+FCS))/(Fragment Size -(Hrd+FCS))) | 
|  | uMACfragNum = (WORD) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize); | 
|  | cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize; | 
|  | if (cbLastFragPayloadSize == 0) { | 
|  | cbLastFragPayloadSize = cbFragPayloadSize; | 
|  | } else { | 
|  | uMACfragNum++; | 
|  | } | 
|  | //[Hdr+(IV)+last fragment payload+(MIC)+(ICV)+FCS] | 
|  | cbLastFragmentSize = cbMACHdLen + cbLastFragPayloadSize + cbIVlen + cbICVlen + cbFCSlen; | 
|  |  | 
|  | for (uFragIdx = 0; uFragIdx < uMACfragNum; uFragIdx ++) { | 
|  | if (uFragIdx == 0) { | 
|  | //========================= | 
|  | //    Start Fragmentation | 
|  | //========================= | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Start Fragmentation...\n"); | 
|  | wFragType = FRAGCTL_STAFRAG; | 
|  |  | 
|  |  | 
|  | //Fill FIFO,RrvTime,RTS,and CTS | 
|  | s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS, | 
|  | cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); | 
|  | //Fill DataHead | 
|  | uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, | 
|  | uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); | 
|  | // Generate TX MAC Header | 
|  | vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt, | 
|  | wFragType, uDMAIdx, uFragIdx); | 
|  |  | 
|  | if (bNeedEncrypt == TRUE) { | 
|  | //Fill TXKEY | 
|  | s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, | 
|  | pbyMacHdr, (WORD)cbFragPayloadSize, (PBYTE)pMICHDR); | 
|  | //Fill IV(ExtIV,RSNHDR) | 
|  | if (pDevice->bEnableHostWEP) { | 
|  | pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; | 
|  | pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | // 802.1H | 
|  | if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) { | 
|  | if ((psEthHeader->wType == TYPE_PKT_IPX) || | 
|  | (psEthHeader->wType == cpu_to_le16(0xF380))) { | 
|  | memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); | 
|  | } | 
|  | else { | 
|  | memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); | 
|  | } | 
|  | pbyType = (PBYTE) (pbyPayloadHead + 6); | 
|  | memcpy(pbyType, &(psEthHeader->wType), sizeof(WORD)); | 
|  | cb802_1_H_len = 8; | 
|  | } | 
|  |  | 
|  | cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize; | 
|  | //--------------------------- | 
|  | // S/W or H/W Encryption | 
|  | //--------------------------- | 
|  | //Fill MICHDR | 
|  | //if (pDevice->bAES) { | 
|  | //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFragPayloadSize); | 
|  | //} | 
|  | //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (PVOID)psTxBufHd, byKeySel, | 
|  | //                                pbyPayloadHead, (WORD)cbFragPayloadSize, uDMAIdx); | 
|  |  | 
|  |  | 
|  |  | 
|  | //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr; | 
|  | pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf; | 
|  |  | 
|  | uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; | 
|  | //copy TxBufferHeader + MacHeader to desc | 
|  | memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength); | 
|  |  | 
|  | // Copy the Packet into a tx Buffer | 
|  | memcpy((pbyBuffer + uLength), (pPacket + 14), (cbFragPayloadSize - cb802_1_H_len)); | 
|  |  | 
|  |  | 
|  | uTotalCopyLength += cbFragPayloadSize - cb802_1_H_len; | 
|  |  | 
|  | if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Start MIC: %d\n", cbFragPayloadSize); | 
|  | MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFragPayloadSize); | 
|  |  | 
|  | } | 
|  |  | 
|  | //--------------------------- | 
|  | // S/W Encryption | 
|  | //--------------------------- | 
|  | if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { | 
|  | if (bNeedEncrypt) { | 
|  | s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), (WORD)cbFragPayloadSize); | 
|  | cbReqCount += cbICVlen; | 
|  | } | 
|  | } | 
|  |  | 
|  | ptdCurr = (PSTxDesc)pHeadTD; | 
|  | //-------------------- | 
|  | //1.Set TSR1 & ReqCount in TxDescHead | 
|  | //2.Set FragCtl in TxBufferHead | 
|  | //3.Set Frame Control | 
|  | //4.Set Sequence Control | 
|  | //5.Get S/W generate FCS | 
|  | //-------------------- | 
|  | s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (PVOID)ptdCurr, wFragType, cbReqCount); | 
|  |  | 
|  | ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; | 
|  | ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; | 
|  | ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; | 
|  | ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); | 
|  | pDevice->iTDUsed[uDMAIdx]++; | 
|  | pHeadTD = ptdCurr->next; | 
|  | } | 
|  | else if (uFragIdx == (uMACfragNum-1)) { | 
|  | //========================= | 
|  | //    Last Fragmentation | 
|  | //========================= | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Last Fragmentation...\n"); | 
|  | //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx]; | 
|  |  | 
|  | wFragType = FRAGCTL_ENDFRAG; | 
|  |  | 
|  | //Fill FIFO,RrvTime,RTS,and CTS | 
|  | s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS, | 
|  | cbLastFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); | 
|  | //Fill DataHead | 
|  | uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbLastFragmentSize, uDMAIdx, bNeedACK, | 
|  | uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); | 
|  |  | 
|  | // Generate TX MAC Header | 
|  | vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt, | 
|  | wFragType, uDMAIdx, uFragIdx); | 
|  |  | 
|  | if (bNeedEncrypt == TRUE) { | 
|  | //Fill TXKEY | 
|  | s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, | 
|  | pbyMacHdr, (WORD)cbLastFragPayloadSize, (PBYTE)pMICHDR); | 
|  |  | 
|  | if (pDevice->bEnableHostWEP) { | 
|  | pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; | 
|  | pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  | cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbLastFragPayloadSize; | 
|  | //--------------------------- | 
|  | // S/W or H/W Encryption | 
|  | //--------------------------- | 
|  |  | 
|  |  | 
|  |  | 
|  | pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf; | 
|  | //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr; | 
|  |  | 
|  | uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; | 
|  |  | 
|  | //copy TxBufferHeader + MacHeader to desc | 
|  | memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength); | 
|  |  | 
|  | // Copy the Packet into a tx Buffer | 
|  | if (bMIC2Frag == FALSE) { | 
|  |  | 
|  | memcpy((pbyBuffer + uLength), | 
|  | (pPacket + 14 + uTotalCopyLength), | 
|  | (cbLastFragPayloadSize - cbMIClen) | 
|  | ); | 
|  | //TODO check uTmpLen ! | 
|  | uTmpLen = cbLastFragPayloadSize - cbMIClen; | 
|  |  | 
|  | } | 
|  | if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n", | 
|  | uMICFragLen, cbLastFragPayloadSize, uTmpLen); | 
|  |  | 
|  | if (bMIC2Frag == FALSE) { | 
|  | if (uTmpLen != 0) | 
|  | MIC_vAppend((pbyBuffer + uLength), uTmpLen); | 
|  | pdwMIC_L = (PDWORD)(pbyBuffer + uLength + uTmpLen); | 
|  | pdwMIC_R = (PDWORD)(pbyBuffer + uLength + uTmpLen + 4); | 
|  | MIC_vGetMIC(pdwMIC_L, pdwMIC_R); | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Last MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R); | 
|  | } else { | 
|  | if (uMICFragLen >= 4) { | 
|  | memcpy((pbyBuffer + uLength), ((PBYTE)&dwSafeMIC_R + (uMICFragLen - 4)), | 
|  | (cbMIClen - uMICFragLen)); | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen >= 4: %X, %d\n", | 
|  | *(PBYTE)((PBYTE)&dwSafeMIC_R + (uMICFragLen - 4)), | 
|  | (cbMIClen - uMICFragLen)); | 
|  |  | 
|  | } else { | 
|  | memcpy((pbyBuffer + uLength), ((PBYTE)&dwSafeMIC_L + uMICFragLen), | 
|  | (4 - uMICFragLen)); | 
|  | memcpy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4); | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen < 4: %X, %d\n", | 
|  | *(PBYTE)((PBYTE)&dwSafeMIC_R + uMICFragLen - 4), | 
|  | (cbMIClen - uMICFragLen)); | 
|  | } | 
|  | /* | 
|  | for (ii = 0; ii < cbLastFragPayloadSize + 8 + 24; ii++) { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii - 8 - 24))); | 
|  | } | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n"); | 
|  | */ | 
|  | } | 
|  | MIC_vUnInit(); | 
|  | } else { | 
|  | ASSERT(uTmpLen == (cbLastFragPayloadSize - cbMIClen)); | 
|  | } | 
|  |  | 
|  |  | 
|  | //--------------------------- | 
|  | // S/W Encryption | 
|  | //--------------------------- | 
|  | if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { | 
|  | if (bNeedEncrypt) { | 
|  | s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (WORD)cbLastFragPayloadSize); | 
|  | cbReqCount += cbICVlen; | 
|  | } | 
|  | } | 
|  |  | 
|  | ptdCurr = (PSTxDesc)pHeadTD; | 
|  |  | 
|  | //-------------------- | 
|  | //1.Set TSR1 & ReqCount in TxDescHead | 
|  | //2.Set FragCtl in TxBufferHead | 
|  | //3.Set Frame Control | 
|  | //4.Set Sequence Control | 
|  | //5.Get S/W generate FCS | 
|  | //-------------------- | 
|  |  | 
|  |  | 
|  | s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (PVOID)ptdCurr, wFragType, cbReqCount); | 
|  |  | 
|  | ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; | 
|  | ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; | 
|  | ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; | 
|  | ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); | 
|  | pDevice->iTDUsed[uDMAIdx]++; | 
|  | pHeadTD = ptdCurr->next; | 
|  |  | 
|  | } | 
|  | else { | 
|  | //========================= | 
|  | //    Middle Fragmentation | 
|  | //========================= | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Middle Fragmentation...\n"); | 
|  | //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx]; | 
|  |  | 
|  | wFragType = FRAGCTL_MIDFRAG; | 
|  |  | 
|  | //Fill FIFO,RrvTime,RTS,and CTS | 
|  | s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS, | 
|  | cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); | 
|  | //Fill DataHead | 
|  | uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, | 
|  | uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); | 
|  |  | 
|  | // Generate TX MAC Header | 
|  | vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt, | 
|  | wFragType, uDMAIdx, uFragIdx); | 
|  |  | 
|  |  | 
|  | if (bNeedEncrypt == TRUE) { | 
|  | //Fill TXKEY | 
|  | s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, | 
|  | pbyMacHdr, (WORD)cbFragPayloadSize, (PBYTE)pMICHDR); | 
|  |  | 
|  | if (pDevice->bEnableHostWEP) { | 
|  | pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; | 
|  | pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; | 
|  | } | 
|  | } | 
|  |  | 
|  | cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize; | 
|  | //--------------------------- | 
|  | // S/W or H/W Encryption | 
|  | //--------------------------- | 
|  | //Fill MICHDR | 
|  | //if (pDevice->bAES) { | 
|  | //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFragPayloadSize); | 
|  | //} | 
|  | //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (PVOID)psTxBufHd, byKeySel, | 
|  | //                              pbyPayloadHead, (WORD)cbFragPayloadSize, uDMAIdx); | 
|  |  | 
|  |  | 
|  | pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf; | 
|  | //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr; | 
|  |  | 
|  |  | 
|  | uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; | 
|  |  | 
|  | //copy TxBufferHeader + MacHeader to desc | 
|  | memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength); | 
|  |  | 
|  | // Copy the Packet into a tx Buffer | 
|  | memcpy((pbyBuffer + uLength), | 
|  | (pPacket + 14 + uTotalCopyLength), | 
|  | cbFragPayloadSize | 
|  | ); | 
|  | uTmpLen = cbFragPayloadSize; | 
|  |  | 
|  | uTotalCopyLength += uTmpLen; | 
|  |  | 
|  | if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { | 
|  |  | 
|  | MIC_vAppend((pbyBuffer + uLength), uTmpLen); | 
|  |  | 
|  | if (uTmpLen < cbFragPayloadSize) { | 
|  | bMIC2Frag = TRUE; | 
|  | uMICFragLen = cbFragPayloadSize - uTmpLen; | 
|  | ASSERT(uMICFragLen < cbMIClen); | 
|  |  | 
|  | pdwMIC_L = (PDWORD)(pbyBuffer + uLength + uTmpLen); | 
|  | pdwMIC_R = (PDWORD)(pbyBuffer + uLength + uTmpLen + 4); | 
|  | MIC_vGetMIC(pdwMIC_L, pdwMIC_R); | 
|  | dwSafeMIC_L = *pdwMIC_L; | 
|  | dwSafeMIC_R = *pdwMIC_R; | 
|  |  | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n", | 
|  | uMICFragLen, cbFragPayloadSize, uTmpLen); | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MIC in Middle frag [%d]\n", uMICFragLen); | 
|  | /* | 
|  | for (ii = 0; ii < uMICFragLen; ii++) { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength + uTmpLen) + ii))); | 
|  | } | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); | 
|  | */ | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R); | 
|  | } | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Middle frag len: %d\n", uTmpLen); | 
|  | /* | 
|  | for (ii = 0; ii < uTmpLen; ii++) { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii))); | 
|  | } | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n"); | 
|  | */ | 
|  |  | 
|  | } else { | 
|  | ASSERT(uTmpLen == (cbFragPayloadSize)); | 
|  | } | 
|  |  | 
|  | if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { | 
|  | if (bNeedEncrypt) { | 
|  | s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (WORD)cbFragPayloadSize); | 
|  | cbReqCount += cbICVlen; | 
|  | } | 
|  | } | 
|  |  | 
|  | ptdCurr = (PSTxDesc)pHeadTD; | 
|  |  | 
|  | //-------------------- | 
|  | //1.Set TSR1 & ReqCount in TxDescHead | 
|  | //2.Set FragCtl in TxBufferHead | 
|  | //3.Set Frame Control | 
|  | //4.Set Sequence Control | 
|  | //5.Get S/W generate FCS | 
|  | //-------------------- | 
|  |  | 
|  | s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (PVOID)ptdCurr, wFragType, cbReqCount); | 
|  |  | 
|  | ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; | 
|  | ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; | 
|  | ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; | 
|  | ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); | 
|  | pDevice->iTDUsed[uDMAIdx]++; | 
|  | pHeadTD = ptdCurr->next; | 
|  | } | 
|  | }  // for (uMACfragNum) | 
|  | } | 
|  | else { | 
|  | //========================= | 
|  | //    No Fragmentation | 
|  | //========================= | 
|  | //DBG_PRTGRP03(("No Fragmentation...\n")); | 
|  | //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n"); | 
|  | wFragType = FRAGCTL_NONFRAG; | 
|  |  | 
|  | //Set FragCtl in TxBufferHead | 
|  | psTxBufHd->wFragCtl |= (WORD)wFragType; | 
|  |  | 
|  | //Fill FIFO,RrvTime,RTS,and CTS | 
|  | s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS, | 
|  | cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); | 
|  | //Fill DataHead | 
|  | uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, | 
|  | 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate); | 
|  |  | 
|  | // Generate TX MAC Header | 
|  | vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt, | 
|  | wFragType, uDMAIdx, 0); | 
|  |  | 
|  | if (bNeedEncrypt == TRUE) { | 
|  | //Fill TXKEY | 
|  | s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, | 
|  | pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR); | 
|  |  | 
|  | if (pDevice->bEnableHostWEP) { | 
|  | pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; | 
|  | pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; | 
|  | } | 
|  | } | 
|  |  | 
|  | // 802.1H | 
|  | if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) { | 
|  | if ((psEthHeader->wType == TYPE_PKT_IPX) || | 
|  | (psEthHeader->wType == cpu_to_le16(0xF380))) { | 
|  | memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); | 
|  | } | 
|  | else { | 
|  | memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); | 
|  | } | 
|  | pbyType = (PBYTE) (pbyPayloadHead + 6); | 
|  | memcpy(pbyType, &(psEthHeader->wType), sizeof(WORD)); | 
|  | cb802_1_H_len = 8; | 
|  | } | 
|  |  | 
|  | cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen); | 
|  | //--------------------------- | 
|  | // S/W or H/W Encryption | 
|  | //--------------------------- | 
|  | //Fill MICHDR | 
|  | //if (pDevice->bAES) { | 
|  | //    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MICHDR...\n"); | 
|  | //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFrameBodySize); | 
|  | //} | 
|  |  | 
|  | pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf; | 
|  | //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr; | 
|  |  | 
|  | uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; | 
|  |  | 
|  | //copy TxBufferHeader + MacHeader to desc | 
|  | memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength); | 
|  |  | 
|  | // Copy the Packet into a tx Buffer | 
|  | memcpy((pbyBuffer + uLength), | 
|  | (pPacket + 14), | 
|  | cbFrameBodySize - cb802_1_H_len | 
|  | ); | 
|  |  | 
|  | if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)){ | 
|  |  | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Length:%d, %d\n", cbFrameBodySize - cb802_1_H_len, uLength); | 
|  | /* | 
|  | for (ii = 0; ii < (cbFrameBodySize - cb802_1_H_len); ii++) { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii))); | 
|  | } | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); | 
|  | */ | 
|  |  | 
|  | MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize); | 
|  |  | 
|  | pdwMIC_L = (PDWORD)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize); | 
|  | pdwMIC_R = (PDWORD)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize + 4); | 
|  |  | 
|  | MIC_vGetMIC(pdwMIC_L, pdwMIC_R); | 
|  | MIC_vUnInit(); | 
|  |  | 
|  |  | 
|  | if (pDevice->bTxMICFail == TRUE) { | 
|  | *pdwMIC_L = 0; | 
|  | *pdwMIC_R = 0; | 
|  | pDevice->bTxMICFail = FALSE; | 
|  | } | 
|  |  | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize); | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen); | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R); | 
|  | /* | 
|  | for (ii = 0; ii < 8; ii++) { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(((PBYTE)(pdwMIC_L) + ii))); | 
|  | } | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); | 
|  | */ | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  | if ((pDevice->byLocalID <= REV_ID_VT3253_A1)){ | 
|  | if (bNeedEncrypt) { | 
|  | s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), | 
|  | (WORD)(cbFrameBodySize + cbMIClen)); | 
|  | cbReqCount += cbICVlen; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | ptdCurr = (PSTxDesc)pHeadTD; | 
|  |  | 
|  | ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; | 
|  | ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; | 
|  | ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; | 
|  | ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); | 
|  | //Set TSR1 & ReqCount in TxDescHead | 
|  | ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); | 
|  | ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount)); | 
|  |  | 
|  | pDevice->iTDUsed[uDMAIdx]++; | 
|  |  | 
|  |  | 
|  | //   DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" ptdCurr->m_dwReserved0[%d] ptdCurr->m_dwReserved1[%d].\n", ptdCurr->pTDInfo->dwReqCount, ptdCurr->pTDInfo->dwHeaderLength); | 
|  | //   DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cbHeaderLength[%d]\n", cbHeaderLength); | 
|  |  | 
|  | } | 
|  | *puMACfragNum = uMACfragNum; | 
|  | //DBG_PRTGRP03(("s_cbFillTxBufHead END\n")); | 
|  | return cbHeaderLength; | 
|  | } | 
|  |  | 
|  |  | 
|  | VOID | 
|  | vGenerateFIFOHeader ( | 
|  | IN  PSDevice         pDevice, | 
|  | IN  BYTE             byPktType, | 
|  | IN  PBYTE            pbyTxBufferAddr, | 
|  | IN  BOOL             bNeedEncrypt, | 
|  | IN  UINT             cbPayloadSize, | 
|  | IN  UINT             uDMAIdx, | 
|  | IN  PSTxDesc         pHeadTD, | 
|  | IN  PSEthernetHeader psEthHeader, | 
|  | IN  PBYTE            pPacket, | 
|  | IN  PSKeyItem        pTransmitKey, | 
|  | IN  UINT             uNodeIndex, | 
|  | OUT PUINT            puMACfragNum, | 
|  | OUT PUINT            pcbHeaderSize | 
|  | ) | 
|  | { | 
|  | UINT            wTxBufSize;       // FFinfo size | 
|  | BOOL            bNeedACK; | 
|  | BOOL            bIsAdhoc; | 
|  | WORD            cbMacHdLen; | 
|  | PSTxBufHead     pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; | 
|  |  | 
|  | wTxBufSize = sizeof(STxBufHead); | 
|  |  | 
|  | memset(pTxBufHead, 0, wTxBufSize); | 
|  | //Set FIFOCTL_NEEDACK | 
|  |  | 
|  | if ((pDevice->eOPMode == OP_MODE_ADHOC) || | 
|  | (pDevice->eOPMode == OP_MODE_AP)) { | 
|  | if (IS_MULTICAST_ADDRESS(&(psEthHeader->abyDstAddr[0])) || | 
|  | IS_BROADCAST_ADDRESS(&(psEthHeader->abyDstAddr[0]))) { | 
|  | bNeedACK = FALSE; | 
|  | pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK); | 
|  | } | 
|  | else { | 
|  | bNeedACK = TRUE; | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; | 
|  | } | 
|  | bIsAdhoc = TRUE; | 
|  | } | 
|  | else { | 
|  | // MSDUs in Infra mode always need ACK | 
|  | bNeedACK = TRUE; | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; | 
|  | bIsAdhoc = FALSE; | 
|  | } | 
|  |  | 
|  |  | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; | 
|  | pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); | 
|  |  | 
|  | //Set FIFOCTL_LHEAD | 
|  | if (pDevice->bLongHeader) | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD; | 
|  |  | 
|  | //Set FIFOCTL_GENINT | 
|  |  | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT; | 
|  |  | 
|  |  | 
|  | //Set FIFOCTL_ISDMA0 | 
|  | if (TYPE_TXDMA0 == uDMAIdx) { | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_ISDMA0; | 
|  | } | 
|  |  | 
|  | //Set FRAGCTL_MACHDCNT | 
|  | if (pDevice->bLongHeader) { | 
|  | cbMacHdLen = WLAN_HDR_ADDR3_LEN + 6; | 
|  | } else { | 
|  | cbMacHdLen = WLAN_HDR_ADDR3_LEN; | 
|  | } | 
|  | pTxBufHead->wFragCtl |= cpu_to_le16((WORD)(cbMacHdLen << 10)); | 
|  |  | 
|  | //Set packet type | 
|  | if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 | 
|  | ; | 
|  | } | 
|  | 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; | 
|  | } | 
|  | //Set FIFOCTL_GrpAckPolicy | 
|  | if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000 | 
|  | pTxBufHead->wFIFOCtl |=	FIFOCTL_GRPACK; | 
|  | } | 
|  |  | 
|  | //Set Auto Fallback Ctl | 
|  | if (pDevice->wCurrentRate >= RATE_18M) { | 
|  | if (pDevice->byAutoFBCtrl == AUTO_FB_0) { | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0; | 
|  | } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) { | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1; | 
|  | } | 
|  | } | 
|  |  | 
|  | //Set FRAGCTL_WEPTYP | 
|  | pDevice->bAES = FALSE; | 
|  |  | 
|  | //Set FRAGCTL_WEPTYP | 
|  | if (pDevice->byLocalID > REV_ID_VT3253_A1) { | 
|  | if ((bNeedEncrypt) && (pTransmitKey != NULL))  { //WEP enabled | 
|  | if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { | 
|  | pTxBufHead->wFragCtl |= FRAGCTL_TKIP; | 
|  | } | 
|  | else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104 | 
|  | if (pTransmitKey->uKeyLength != WLAN_WEP232_KEYLEN) | 
|  | pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; | 
|  | } | 
|  | else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP | 
|  | pTxBufHead->wFragCtl |= FRAGCTL_AES; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | #ifdef	PLICE_DEBUG | 
|  | //printk("Func:vGenerateFIFOHeader:TxDataRate is %d,TxPower is %d\n",pDevice->wCurrentRate,pDevice->byCurPwr); | 
|  |  | 
|  | //if (pDevice->wCurrentRate <= 3) | 
|  | //{ | 
|  | //	RFbRawSetPower(pDevice,36,pDevice->wCurrentRate); | 
|  | //} | 
|  | //else | 
|  |  | 
|  | RFbSetPower(pDevice, pDevice->wCurrentRate, pDevice->byCurrentCh); | 
|  | #endif | 
|  | //if (pDevice->wCurrentRate == 3) | 
|  | //pDevice->byCurPwr = 46; | 
|  | pTxBufHead->byTxPower = pDevice->byCurPwr; | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | /* | 
|  | if(pDevice->bEnableHostWEP) | 
|  | pTxBufHead->wFragCtl &=  ~(FRAGCTL_TKIP | FRAGCTL_LEGACY |FRAGCTL_AES); | 
|  | */ | 
|  | *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktType, pbyTxBufferAddr, cbPayloadSize, | 
|  | uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt, | 
|  | pTransmitKey, uNodeIndex, puMACfragNum); | 
|  |  | 
|  | return; | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | /*+ | 
|  | * | 
|  | * Description: | 
|  | *      Translate 802.3 to 802.11 header | 
|  | * | 
|  | * Parameters: | 
|  | *  In: | 
|  | *      pDevice         - Pointer to adpater | 
|  | *      dwTxBufferAddr  - Transmit Buffer | 
|  | *      pPacket         - Packet from upper layer | 
|  | *      cbPacketSize    - Transmit Data Length | 
|  | *  Out: | 
|  | *      pcbHeadSize         - Header size of MAC&Baseband control and 802.11 Header | 
|  | *      pcbAppendPayload    - size of append payload for 802.1H translation | 
|  | * | 
|  | * Return Value: none | 
|  | * | 
|  | -*/ | 
|  |  | 
|  | VOID | 
|  | vGenerateMACHeader ( | 
|  | IN PSDevice         pDevice, | 
|  | IN PBYTE            pbyBufferAddr, | 
|  | IN WORD             wDuration, | 
|  | IN PSEthernetHeader psEthHeader, | 
|  | IN BOOL             bNeedEncrypt, | 
|  | IN WORD             wFragType, | 
|  | IN UINT             uDMAIdx, | 
|  | IN UINT             uFragIdx | 
|  | ) | 
|  | { | 
|  | PS802_11Header  pMACHeader = (PS802_11Header)pbyBufferAddr; | 
|  |  | 
|  | memset(pMACHeader, 0, (sizeof(S802_11Header)));  //- sizeof(pMACHeader->dwIV))); | 
|  |  | 
|  | if (uDMAIdx == TYPE_ATIMDMA) { | 
|  | pMACHeader->wFrameCtl = TYPE_802_11_ATIM; | 
|  | } else { | 
|  | pMACHeader->wFrameCtl = TYPE_802_11_DATA; | 
|  | } | 
|  |  | 
|  | if (pDevice->eOPMode == OP_MODE_AP) { | 
|  | memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); | 
|  | memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); | 
|  | pMACHeader->wFrameCtl |= FC_FROMDS; | 
|  | } | 
|  | else { | 
|  | if (pDevice->eOPMode == OP_MODE_ADHOC) { | 
|  | memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); | 
|  | memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); | 
|  | memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | } | 
|  | else { | 
|  | memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); | 
|  | memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); | 
|  | memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); | 
|  | pMACHeader->wFrameCtl |= FC_TODS; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (bNeedEncrypt) | 
|  | pMACHeader->wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_ISWEP(1)); | 
|  |  | 
|  | pMACHeader->wDurationID = cpu_to_le16(wDuration); | 
|  |  | 
|  | if (pDevice->bLongHeader) { | 
|  | PWLAN_80211HDR_A4 pMACA4Header  = (PWLAN_80211HDR_A4) pbyBufferAddr; | 
|  | pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS); | 
|  | memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN); | 
|  | } | 
|  | pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); | 
|  |  | 
|  | //Set FragNumber in Sequence Control | 
|  | pMACHeader->wSeqCtl |= cpu_to_le16((WORD)uFragIdx); | 
|  |  | 
|  | if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) { | 
|  | pDevice->wSeqCounter++; | 
|  | if (pDevice->wSeqCounter > 0x0fff) | 
|  | pDevice->wSeqCounter = 0; | 
|  | } | 
|  |  | 
|  | if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag | 
|  | pMACHeader->wFrameCtl |= FC_MOREFRAG; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { | 
|  |  | 
|  | PSTxDesc        pFrstTD; | 
|  | BYTE            byPktType; | 
|  | PBYTE           pbyTxBufferAddr; | 
|  | PVOID           pvRTS; | 
|  | PSCTS           pCTS; | 
|  | PVOID           pvTxDataHd; | 
|  | UINT            uDuration; | 
|  | UINT            cbReqCount; | 
|  | PS802_11Header  pMACHeader; | 
|  | UINT            cbHeaderSize; | 
|  | UINT            cbFrameBodySize; | 
|  | BOOL            bNeedACK; | 
|  | BOOL            bIsPSPOLL = FALSE; | 
|  | PSTxBufHead     pTxBufHead; | 
|  | UINT            cbFrameSize; | 
|  | UINT            cbIVlen = 0; | 
|  | UINT            cbICVlen = 0; | 
|  | UINT            cbMIClen = 0; | 
|  | UINT            cbFCSlen = 4; | 
|  | UINT            uPadding = 0; | 
|  | WORD            wTxBufSize; | 
|  | UINT            cbMacHdLen; | 
|  | SEthernetHeader sEthHeader; | 
|  | PVOID           pvRrvTime; | 
|  | PVOID           pMICHDR; | 
|  | PSMgmtObject    pMgmt = pDevice->pMgmt; | 
|  | WORD            wCurrentRate = RATE_1M; | 
|  |  | 
|  |  | 
|  | if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { | 
|  | return CMD_STATUS_RESOURCES; | 
|  | } | 
|  |  | 
|  | pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; | 
|  | pbyTxBufferAddr = (PBYTE)pFrstTD->pTDInfo->buf; | 
|  | cbFrameBodySize = pPacket->cbPayloadLen; | 
|  | pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; | 
|  | wTxBufSize = sizeof(STxBufHead); | 
|  | memset(pTxBufHead, 0, wTxBufSize); | 
|  |  | 
|  | if (pDevice->eCurrentPHYType == PHY_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 (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) { | 
|  |  | 
|  | RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh); | 
|  | } else { | 
|  | RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel); | 
|  | } | 
|  | pTxBufHead->byTxPower = pDevice->byCurPwr; | 
|  | //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++ | 
|  | if (pDevice->byFOETuning) { | 
|  | if ((pPacket->p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) { | 
|  | wCurrentRate = RATE_24M; | 
|  | byPktType = PK_TYPE_11GA; | 
|  | } | 
|  | } | 
|  |  | 
|  | //Set packet type | 
|  | if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 | 
|  | pTxBufHead->wFIFOCtl = 0; | 
|  | } | 
|  | else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_11B; | 
|  | } | 
|  | else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; | 
|  | } | 
|  | else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; | 
|  | } | 
|  |  | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; | 
|  | pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); | 
|  |  | 
|  |  | 
|  | if (IS_MULTICAST_ADDRESS(&(pPacket->p80211Header->sA3.abyAddr1[0])) || | 
|  | IS_BROADCAST_ADDRESS(&(pPacket->p80211Header->sA3.abyAddr1[0]))) { | 
|  | bNeedACK = FALSE; | 
|  | } | 
|  | else { | 
|  | bNeedACK = TRUE; | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; | 
|  | }; | 
|  |  | 
|  | if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || | 
|  | (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) { | 
|  |  | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; | 
|  | //Set Preamble type always long | 
|  | //pDevice->byPreambleType = PREAMBLE_LONG; | 
|  | // probe-response don't retry | 
|  | //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) { | 
|  | //     bNeedACK = FALSE; | 
|  | //     pTxBufHead->wFIFOCtl  &= (~FIFOCTL_NEEDACK); | 
|  | //} | 
|  | } | 
|  |  | 
|  | pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); | 
|  |  | 
|  | if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { | 
|  | bIsPSPOLL = TRUE; | 
|  | cbMacHdLen = WLAN_HDR_ADDR2_LEN; | 
|  | } else { | 
|  | cbMacHdLen = WLAN_HDR_ADDR3_LEN; | 
|  | } | 
|  |  | 
|  | //Set FRAGCTL_MACHDCNT | 
|  | pTxBufHead->wFragCtl |= cpu_to_le16((WORD)(cbMacHdLen << 10)); | 
|  |  | 
|  | // Notes: | 
|  | // Although spec says MMPDU can be fragmented; In most case, | 
|  | // no one will send a MMPDU under fragmentation. With RTS may occur. | 
|  | pDevice->bAES = FALSE;  //Set FRAGCTL_WEPTYP | 
|  |  | 
|  | if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { | 
|  | if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { | 
|  | cbIVlen = 4; | 
|  | cbICVlen = 4; | 
|  | pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; | 
|  | } | 
|  | else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { | 
|  | cbIVlen = 8;//IV+ExtIV | 
|  | cbMIClen = 8; | 
|  | cbICVlen = 4; | 
|  | pTxBufHead->wFragCtl |= FRAGCTL_TKIP; | 
|  | //We need to get seed here for filling TxKey entry. | 
|  | //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, | 
|  | //            pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); | 
|  | } | 
|  | else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { | 
|  | cbIVlen = 8;//RSN Header | 
|  | cbICVlen = 8;//MIC | 
|  | pTxBufHead->wFragCtl |= FRAGCTL_AES; | 
|  | pDevice->bAES = TRUE; | 
|  | } | 
|  | //MAC Header should be padding 0 to DW alignment. | 
|  | uPadding = 4 - (cbMacHdLen%4); | 
|  | uPadding %= 4; | 
|  | } | 
|  |  | 
|  | cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen; | 
|  |  | 
|  | //Set FIFOCTL_GrpAckPolicy | 
|  | if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000 | 
|  | pTxBufHead->wFIFOCtl |=	FIFOCTL_GRPACK; | 
|  | } | 
|  | //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() | 
|  |  | 
|  | //Set RrvTime/RTS/CTS Buffer | 
|  | if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet | 
|  |  | 
|  | pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); | 
|  | pMICHDR = NULL; | 
|  | pvRTS = NULL; | 
|  | pCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); | 
|  | pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS)); | 
|  | cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS) + sizeof(STxDataHead_g); | 
|  | } | 
|  | else { // 802.11a/b packet | 
|  | pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); | 
|  | pMICHDR = NULL; | 
|  | pvRTS = NULL; | 
|  | pCTS = NULL; | 
|  | pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); | 
|  | cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab); | 
|  | } | 
|  |  | 
|  | memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); | 
|  |  | 
|  | memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN); | 
|  | memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN); | 
|  | //========================= | 
|  | //    No Fragmentation | 
|  | //========================= | 
|  | pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG; | 
|  |  | 
|  |  | 
|  | //Fill FIFO,RrvTime,RTS,and CTS | 
|  | s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS, | 
|  | cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate); | 
|  |  | 
|  | //Fill DataHead | 
|  | uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, | 
|  | 0, 0, 1, AUTO_FB_NONE, wCurrentRate); | 
|  |  | 
|  | pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); | 
|  |  | 
|  | cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize; | 
|  |  | 
|  | if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { | 
|  | PBYTE           pbyIVHead; | 
|  | PBYTE           pbyPayloadHead; | 
|  | PBYTE           pbyBSSID; | 
|  | PSKeyItem       pTransmitKey = NULL; | 
|  |  | 
|  | pbyIVHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding); | 
|  | pbyPayloadHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen); | 
|  |  | 
|  | //Fill TXKEY | 
|  | //Kyle: Need fix: TKIP and AES did't encryt Mnt Packet. | 
|  | //s_vFillTxKey(pDevice, (PBYTE)pTxBufHead->adwTxKey, NULL); | 
|  |  | 
|  | //Fill IV(ExtIV,RSNHDR) | 
|  | //s_vFillPrePayload(pDevice, pbyIVHead, NULL); | 
|  | //--------------------------- | 
|  | // S/W or H/W Encryption | 
|  | //--------------------------- | 
|  | //Fill MICHDR | 
|  | //if (pDevice->bAES) { | 
|  | //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, (PBYTE)pMACHeader, (WORD)cbFrameBodySize); | 
|  | //} | 
|  | do { | 
|  | if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) && | 
|  | (pDevice->bLinkPass == TRUE)) { | 
|  | pbyBSSID = pDevice->abyBSSID; | 
|  | // get pairwise key | 
|  | if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == FALSE) { | 
|  | // get group key | 
|  | if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == TRUE) { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n"); | 
|  | break; | 
|  | } | 
|  | } else { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n"); | 
|  | break; | 
|  | } | 
|  | } | 
|  | // get group key | 
|  | pbyBSSID = pDevice->abyBroadcastAddr; | 
|  | if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) { | 
|  | pTransmitKey = NULL; | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode); | 
|  | } else { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n"); | 
|  | } | 
|  | } while(FALSE); | 
|  | //Fill TXKEY | 
|  | s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, | 
|  | (PBYTE)pMACHeader, (WORD)cbFrameBodySize, NULL); | 
|  |  | 
|  | memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen); | 
|  | memcpy(pbyPayloadHead, ((PBYTE)(pPacket->p80211Header) + cbMacHdLen), | 
|  | cbFrameBodySize); | 
|  | } | 
|  | else { | 
|  | // Copy the Packet into a tx Buffer | 
|  | memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); | 
|  | } | 
|  |  | 
|  | pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); | 
|  | pDevice->wSeqCounter++ ; | 
|  | if (pDevice->wSeqCounter > 0x0fff) | 
|  | pDevice->wSeqCounter = 0; | 
|  |  | 
|  | if (bIsPSPOLL) { | 
|  | // The MAC will automatically replace the Duration-field of MAC header by Duration-field | 
|  | // of  FIFO control header. | 
|  | // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is | 
|  | // in the same place of other packet's Duration-field). | 
|  | // And it will cause Cisco-AP to issue Disassociation-packet | 
|  | if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { | 
|  | ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); | 
|  | ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); | 
|  | } else { | 
|  | ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | // first TD is the only TD | 
|  | //Set TSR1 & ReqCount in TxDescHead | 
|  | pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU); | 
|  | pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma; | 
|  | pFrstTD->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount)); | 
|  | pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma); | 
|  | pFrstTD->pTDInfo->byFlags = 0; | 
|  |  | 
|  | if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { | 
|  | // Disable PS | 
|  | MACbPSWakeup(pDevice->PortOffset); | 
|  | } | 
|  | pDevice->bPWBitOn = FALSE; | 
|  |  | 
|  | wmb(); | 
|  | pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; | 
|  | wmb(); | 
|  |  | 
|  | pDevice->iTDUsed[TYPE_TXDMA0]++; | 
|  |  | 
|  | if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n"); | 
|  | } | 
|  |  | 
|  | pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; | 
|  | #ifdef	PLICE_DEBUG | 
|  | //printk("SCAN:CurrentRate is  %d,TxPower is %d\n",wCurrentRate,pTxBufHead->byTxPower); | 
|  | #endif | 
|  |  | 
|  | #ifdef TxInSleep | 
|  | pDevice->nTxDataTimeCout=0; //2008-8-21 chester <add> for send null packet | 
|  | #endif | 
|  |  | 
|  | // Poll Transmit the adapter | 
|  | MACvTransmit0(pDevice->PortOffset); | 
|  |  | 
|  | return CMD_STATUS_PENDING; | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  | CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { | 
|  |  | 
|  | BYTE             byPktType; | 
|  | PBYTE            pbyBuffer = (PBYTE)pDevice->tx_beacon_bufs; | 
|  | UINT             cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN; | 
|  | UINT             cbHeaderSize = 0; | 
|  | WORD             wTxBufSize = sizeof(STxShortBufHead); | 
|  | PSTxShortBufHead pTxBufHead = (PSTxShortBufHead) pbyBuffer; | 
|  | PSTxDataHead_ab  pTxDataHead = (PSTxDataHead_ab) (pbyBuffer + wTxBufSize); | 
|  | PS802_11Header   pMACHeader; | 
|  | WORD             wCurrentRate; | 
|  | WORD             wLen = 0x0000; | 
|  |  | 
|  |  | 
|  | memset(pTxBufHead, 0, wTxBufSize); | 
|  |  | 
|  | if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { | 
|  | wCurrentRate = RATE_6M; | 
|  | byPktType = PK_TYPE_11A; | 
|  | } else { | 
|  | wCurrentRate = RATE_2M; | 
|  | byPktType = PK_TYPE_11B; | 
|  | } | 
|  |  | 
|  | //Set Preamble type always long | 
|  | pDevice->byPreambleType = PREAMBLE_LONG; | 
|  |  | 
|  | //Set FIFOCTL_GENINT | 
|  |  | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT; | 
|  |  | 
|  |  | 
|  | //Set packet type & Get Duration | 
|  | if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 | 
|  | pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, byPktType, | 
|  | wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE)); | 
|  | } | 
|  | else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_11B; | 
|  | pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, byPktType, | 
|  | wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE)); | 
|  | } | 
|  |  | 
|  | BBvCaculateParameter(pDevice, cbFrameSize, wCurrentRate, byPktType, | 
|  | (PWORD)&(wLen), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField) | 
|  | ); | 
|  | pTxDataHead->wTransmitLength = cpu_to_le16(wLen); | 
|  | //Get TimeStampOff | 
|  | pTxDataHead->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); | 
|  | cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab); | 
|  |  | 
|  | //Generate Beacon Header | 
|  | pMACHeader = (PS802_11Header)(pbyBuffer + cbHeaderSize); | 
|  | memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); | 
|  |  | 
|  | pMACHeader->wDurationID = 0; | 
|  | pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); | 
|  | pDevice->wSeqCounter++ ; | 
|  | if (pDevice->wSeqCounter > 0x0fff) | 
|  | pDevice->wSeqCounter = 0; | 
|  |  | 
|  | // Set Beacon buffer length | 
|  | pDevice->wBCNBufLen = pPacket->cbMPDULen + cbHeaderSize; | 
|  |  | 
|  | MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, (pDevice->tx_beacon_dma)); | 
|  |  | 
|  | MACvSetCurrBCNLength(pDevice->PortOffset, pDevice->wBCNBufLen); | 
|  | // Set auto Transmit on | 
|  | MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); | 
|  | // Poll Transmit the adapter | 
|  | MACvTransmitBCN(pDevice->PortOffset); | 
|  |  | 
|  | return CMD_STATUS_PENDING; | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | UINT | 
|  | cbGetFragCount ( | 
|  | IN  PSDevice         pDevice, | 
|  | IN  PSKeyItem        pTransmitKey, | 
|  | IN  UINT             cbFrameBodySize, | 
|  | IN  PSEthernetHeader psEthHeader | 
|  | ) | 
|  | { | 
|  | UINT           cbMACHdLen; | 
|  | UINT           cbFrameSize; | 
|  | UINT           cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS | 
|  | UINT           cbFragPayloadSize; | 
|  | UINT           cbLastFragPayloadSize; | 
|  | UINT           cbIVlen = 0; | 
|  | UINT           cbICVlen = 0; | 
|  | UINT           cbMIClen = 0; | 
|  | UINT           cbFCSlen = 4; | 
|  | UINT           uMACfragNum = 1; | 
|  | BOOL           bNeedACK; | 
|  |  | 
|  |  | 
|  |  | 
|  | if ((pDevice->eOPMode == OP_MODE_ADHOC) || | 
|  | (pDevice->eOPMode == OP_MODE_AP)) { | 
|  | if (IS_MULTICAST_ADDRESS(&(psEthHeader->abyDstAddr[0])) || | 
|  | IS_BROADCAST_ADDRESS(&(psEthHeader->abyDstAddr[0]))) { | 
|  | bNeedACK = FALSE; | 
|  | } | 
|  | else { | 
|  | bNeedACK = TRUE; | 
|  | } | 
|  | } | 
|  | else { | 
|  | // MSDUs in Infra mode always need ACK | 
|  | bNeedACK = TRUE; | 
|  | } | 
|  |  | 
|  | if (pDevice->bLongHeader) | 
|  | cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; | 
|  | else | 
|  | cbMACHdLen = WLAN_HDR_ADDR3_LEN; | 
|  |  | 
|  |  | 
|  | if (pDevice->bEncryptionEnable == TRUE) { | 
|  |  | 
|  | if (pTransmitKey == NULL) { | 
|  | if ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) || | 
|  | (pDevice->pMgmt->eAuthenMode < WMAC_AUTH_WPA)) { | 
|  | cbIVlen = 4; | 
|  | cbICVlen = 4; | 
|  | } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { | 
|  | cbIVlen = 8;//IV+ExtIV | 
|  | cbMIClen = 8; | 
|  | cbICVlen = 4; | 
|  | } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { | 
|  | cbIVlen = 8;//RSN Header | 
|  | cbICVlen = 8;//MIC | 
|  | } | 
|  | } else 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; | 
|  | } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { | 
|  | cbIVlen = 8;//RSN Header | 
|  | cbICVlen = 8;//MIC | 
|  | } | 
|  | } | 
|  |  | 
|  | cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen; | 
|  |  | 
|  | if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == TRUE)) { | 
|  | // Fragmentation | 
|  | cbFragmentSize = pDevice->wFragmentationThreshold; | 
|  | cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen; | 
|  | uMACfragNum = (WORD) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize); | 
|  | cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize; | 
|  | if (cbLastFragPayloadSize == 0) { | 
|  | cbLastFragPayloadSize = cbFragPayloadSize; | 
|  | } else { | 
|  | uMACfragNum++; | 
|  | } | 
|  | } | 
|  | return uMACfragNum; | 
|  | } | 
|  |  | 
|  |  | 
|  | VOID | 
|  | vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDULen) { | 
|  |  | 
|  | PSTxDesc        pFrstTD; | 
|  | BYTE            byPktType; | 
|  | PBYTE           pbyTxBufferAddr; | 
|  | PVOID           pvRTS; | 
|  | PVOID           pvCTS; | 
|  | PVOID           pvTxDataHd; | 
|  | UINT            uDuration; | 
|  | UINT            cbReqCount; | 
|  | PS802_11Header  pMACHeader; | 
|  | UINT            cbHeaderSize; | 
|  | UINT            cbFrameBodySize; | 
|  | BOOL            bNeedACK; | 
|  | BOOL            bIsPSPOLL = FALSE; | 
|  | PSTxBufHead     pTxBufHead; | 
|  | UINT            cbFrameSize; | 
|  | UINT            cbIVlen = 0; | 
|  | UINT            cbICVlen = 0; | 
|  | UINT            cbMIClen = 0; | 
|  | UINT            cbFCSlen = 4; | 
|  | UINT            uPadding = 0; | 
|  | UINT            cbMICHDR = 0; | 
|  | UINT            uLength = 0; | 
|  | DWORD           dwMICKey0, dwMICKey1; | 
|  | DWORD           dwMIC_Priority; | 
|  | PDWORD          pdwMIC_L; | 
|  | PDWORD          pdwMIC_R; | 
|  | WORD            wTxBufSize; | 
|  | UINT            cbMacHdLen; | 
|  | SEthernetHeader sEthHeader; | 
|  | PVOID           pvRrvTime; | 
|  | PVOID           pMICHDR; | 
|  | PSMgmtObject    pMgmt = pDevice->pMgmt; | 
|  | WORD            wCurrentRate = RATE_1M; | 
|  | PUWLAN_80211HDR  p80211Header; | 
|  | UINT             uNodeIndex = 0; | 
|  | BOOL            bNodeExist = FALSE; | 
|  | SKeyItem        STempKey; | 
|  | PSKeyItem       pTransmitKey = NULL; | 
|  | PBYTE           pbyIVHead; | 
|  | PBYTE           pbyPayloadHead; | 
|  | PBYTE           pbyMacHdr; | 
|  |  | 
|  | UINT            cbExtSuppRate = 0; | 
|  | //    PWLAN_IE        pItem; | 
|  |  | 
|  |  | 
|  | pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; | 
|  |  | 
|  | if(cbMPDULen <= WLAN_HDR_ADDR3_LEN) { | 
|  | cbFrameBodySize = 0; | 
|  | } | 
|  | else { | 
|  | cbFrameBodySize = cbMPDULen - WLAN_HDR_ADDR3_LEN; | 
|  | } | 
|  | p80211Header = (PUWLAN_80211HDR)pbMPDU; | 
|  |  | 
|  |  | 
|  | pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; | 
|  | pbyTxBufferAddr = (PBYTE)pFrstTD->pTDInfo->buf; | 
|  | pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; | 
|  | wTxBufSize = sizeof(STxBufHead); | 
|  | memset(pTxBufHead, 0, wTxBufSize); | 
|  |  | 
|  | if (pDevice->eCurrentPHYType == PHY_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 (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) { | 
|  | RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh); | 
|  | } else { | 
|  | RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel); | 
|  | } | 
|  | pTxBufHead->byTxPower = pDevice->byCurPwr; | 
|  |  | 
|  | //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++ | 
|  | if (pDevice->byFOETuning) { | 
|  | if ((p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) { | 
|  | wCurrentRate = RATE_24M; | 
|  | byPktType = PK_TYPE_11GA; | 
|  | } | 
|  | } | 
|  |  | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl); | 
|  |  | 
|  | //Set packet type | 
|  | if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 | 
|  | pTxBufHead->wFIFOCtl = 0; | 
|  | } | 
|  | else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_11B; | 
|  | } | 
|  | else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; | 
|  | } | 
|  | else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; | 
|  | } | 
|  |  | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; | 
|  | pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); | 
|  |  | 
|  |  | 
|  | if (IS_MULTICAST_ADDRESS(&(p80211Header->sA3.abyAddr1[0])) || | 
|  | IS_BROADCAST_ADDRESS(&(p80211Header->sA3.abyAddr1[0]))) { | 
|  | bNeedACK = FALSE; | 
|  | if (pDevice->bEnableHostWEP) { | 
|  | uNodeIndex = 0; | 
|  | bNodeExist = TRUE; | 
|  | }; | 
|  | } | 
|  | else { | 
|  | if (pDevice->bEnableHostWEP) { | 
|  | if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (PBYTE)(p80211Header->sA3.abyAddr1), &uNodeIndex)) | 
|  | bNodeExist = TRUE; | 
|  | }; | 
|  | bNeedACK = TRUE; | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; | 
|  | }; | 
|  |  | 
|  | if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || | 
|  | (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) { | 
|  |  | 
|  | pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; | 
|  | //Set Preamble type always long | 
|  | //pDevice->byPreambleType = PREAMBLE_LONG; | 
|  |  | 
|  | // probe-response don't retry | 
|  | //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) { | 
|  | //     bNeedACK = FALSE; | 
|  | //     pTxBufHead->wFIFOCtl  &= (~FIFOCTL_NEEDACK); | 
|  | //} | 
|  | } | 
|  |  | 
|  | pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); | 
|  |  | 
|  | if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { | 
|  | bIsPSPOLL = TRUE; | 
|  | cbMacHdLen = WLAN_HDR_ADDR2_LEN; | 
|  | } else { | 
|  | cbMacHdLen = WLAN_HDR_ADDR3_LEN; | 
|  | } | 
|  |  | 
|  | // hostapd deamon ext support rate patch | 
|  | if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { | 
|  |  | 
|  | if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) { | 
|  | cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN; | 
|  | } | 
|  |  | 
|  | if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) { | 
|  | cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN; | 
|  | } | 
|  |  | 
|  | if (cbExtSuppRate >0) { | 
|  | cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | //Set FRAGCTL_MACHDCNT | 
|  | pTxBufHead->wFragCtl |= cpu_to_le16((WORD)cbMacHdLen << 10); | 
|  |  | 
|  | // Notes: | 
|  | // Although spec says MMPDU can be fragmented; In most case, | 
|  | // no one will send a MMPDU under fragmentation. With RTS may occur. | 
|  | pDevice->bAES = FALSE;  //Set FRAGCTL_WEPTYP | 
|  |  | 
|  |  | 
|  | if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) { | 
|  | if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { | 
|  | cbIVlen = 4; | 
|  | cbICVlen = 4; | 
|  | pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; | 
|  | } | 
|  | else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { | 
|  | cbIVlen = 8;//IV+ExtIV | 
|  | cbMIClen = 8; | 
|  | cbICVlen = 4; | 
|  | pTxBufHead->wFragCtl |= FRAGCTL_TKIP; | 
|  | //We need to get seed here for filling TxKey entry. | 
|  | //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, | 
|  | //            pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); | 
|  | } | 
|  | else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { | 
|  | cbIVlen = 8;//RSN Header | 
|  | cbICVlen = 8;//MIC | 
|  | cbMICHDR = sizeof(SMICHDRHead); | 
|  | pTxBufHead->wFragCtl |= FRAGCTL_AES; | 
|  | pDevice->bAES = TRUE; | 
|  | } | 
|  | //MAC Header should be padding 0 to DW alignment. | 
|  | uPadding = 4 - (cbMacHdLen%4); | 
|  | uPadding %= 4; | 
|  | } | 
|  |  | 
|  | cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate; | 
|  |  | 
|  | //Set FIFOCTL_GrpAckPolicy | 
|  | if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000 | 
|  | pTxBufHead->wFIFOCtl |=	FIFOCTL_GRPACK; | 
|  | } | 
|  | //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() | 
|  |  | 
|  |  | 
|  | if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet | 
|  |  | 
|  | pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); | 
|  | pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); | 
|  | pvRTS = NULL; | 
|  | pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); | 
|  | pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS)); | 
|  | cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g); | 
|  |  | 
|  | } | 
|  | else {//802.11a/b packet | 
|  |  | 
|  | pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); | 
|  | pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); | 
|  | pvRTS = NULL; | 
|  | pvCTS = NULL; | 
|  | pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); | 
|  | cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab); | 
|  |  | 
|  | } | 
|  |  | 
|  | memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); | 
|  | memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN); | 
|  | memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN); | 
|  | //========================= | 
|  | //    No Fragmentation | 
|  | //========================= | 
|  | pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG; | 
|  |  | 
|  |  | 
|  | //Fill FIFO,RrvTime,RTS,and CTS | 
|  | s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS, | 
|  | cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate); | 
|  |  | 
|  | //Fill DataHead | 
|  | uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, | 
|  | 0, 0, 1, AUTO_FB_NONE, wCurrentRate); | 
|  |  | 
|  | pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); | 
|  |  | 
|  | cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate; | 
|  |  | 
|  | pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderSize); | 
|  | pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen); | 
|  | pbyIVHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding); | 
|  |  | 
|  | // Copy the Packet into a tx Buffer | 
|  | memcpy(pbyMacHdr, pbMPDU, cbMacHdLen); | 
|  |  | 
|  | // version set to 0, patch for hostapd deamon | 
|  | pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc); | 
|  | memcpy(pbyPayloadHead, (pbMPDU + cbMacHdLen), cbFrameBodySize); | 
|  |  | 
|  | // replace support rate, patch for hostapd deamon( only support 11M) | 
|  | if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { | 
|  | if (cbExtSuppRate != 0) { | 
|  | if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) | 
|  | memcpy((pbyPayloadHead + cbFrameBodySize), | 
|  | pMgmt->abyCurrSuppRates, | 
|  | ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN | 
|  | ); | 
|  | if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) | 
|  | memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN, | 
|  | pMgmt->abyCurrExtSuppRates, | 
|  | ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Set wep | 
|  | if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) { | 
|  |  | 
|  | if (pDevice->bEnableHostWEP) { | 
|  | pTransmitKey = &STempKey; | 
|  | pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; | 
|  | pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; | 
|  | pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; | 
|  | pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; | 
|  | pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; | 
|  | memcpy(pTransmitKey->abyKey, | 
|  | &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], | 
|  | pTransmitKey->uKeyLength | 
|  | ); | 
|  | } | 
|  |  | 
|  | if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { | 
|  |  | 
|  | dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]); | 
|  | dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]); | 
|  |  | 
|  | // DO Software Michael | 
|  | MIC_vInit(dwMICKey0, dwMICKey1); | 
|  | MIC_vAppend((PBYTE)&(sEthHeader.abyDstAddr[0]), 12); | 
|  | dwMIC_Priority = 0; | 
|  | MIC_vAppend((PBYTE)&dwMIC_Priority, 4); | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1); | 
|  |  | 
|  | uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen; | 
|  |  | 
|  | MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize); | 
|  |  | 
|  | pdwMIC_L = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize); | 
|  | pdwMIC_R = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4); | 
|  |  | 
|  | MIC_vGetMIC(pdwMIC_L, pdwMIC_R); | 
|  | MIC_vUnInit(); | 
|  |  | 
|  | if (pDevice->bTxMICFail == TRUE) { | 
|  | *pdwMIC_L = 0; | 
|  | *pdwMIC_R = 0; | 
|  | pDevice->bTxMICFail = FALSE; | 
|  | } | 
|  |  | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize); | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen); | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R); | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  | s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, | 
|  | pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR); | 
|  |  | 
|  | if (pDevice->bEnableHostWEP) { | 
|  | pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; | 
|  | pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; | 
|  | } | 
|  |  | 
|  | if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { | 
|  | s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (WORD)(cbFrameBodySize + cbMIClen)); | 
|  | } | 
|  | } | 
|  |  | 
|  | pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); | 
|  | pDevice->wSeqCounter++ ; | 
|  | if (pDevice->wSeqCounter > 0x0fff) | 
|  | pDevice->wSeqCounter = 0; | 
|  |  | 
|  |  | 
|  | if (bIsPSPOLL) { | 
|  | // The MAC will automatically replace the Duration-field of MAC header by Duration-field | 
|  | // of  FIFO control header. | 
|  | // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is | 
|  | // in the same place of other packet's Duration-field). | 
|  | // And it will cause Cisco-AP to issue Disassociation-packet | 
|  | if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { | 
|  | ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID); | 
|  | ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID); | 
|  | } else { | 
|  | ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID); | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | // first TD is the only TD | 
|  | //Set TSR1 & ReqCount in TxDescHead | 
|  | pFrstTD->pTDInfo->skb = skb; | 
|  | pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU); | 
|  | pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma; | 
|  | pFrstTD->m_td1TD1.wReqCount = cpu_to_le16(cbReqCount); | 
|  | pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma); | 
|  | pFrstTD->pTDInfo->byFlags = 0; | 
|  | pFrstTD->pTDInfo->byFlags |= TD_FLAGS_PRIV_SKB; | 
|  |  | 
|  | if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { | 
|  | // Disable PS | 
|  | MACbPSWakeup(pDevice->PortOffset); | 
|  | } | 
|  | pDevice->bPWBitOn = FALSE; | 
|  |  | 
|  | wmb(); | 
|  | pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; | 
|  | wmb(); | 
|  |  | 
|  | pDevice->iTDUsed[TYPE_TXDMA0]++; | 
|  |  | 
|  | if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) { | 
|  | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n"); | 
|  | } | 
|  |  | 
|  | pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; | 
|  |  | 
|  | // Poll Transmit the adapter | 
|  | MACvTransmit0(pDevice->PortOffset); | 
|  |  | 
|  | return; | 
|  | } | 
|  |  | 
|  |  |