diff options
Diffstat (limited to 'drivers/staging/vt6655/rxtx.c')
-rw-r--r-- | drivers/staging/vt6655/rxtx.c | 2112 |
1 files changed, 337 insertions, 1775 deletions
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 7a183f55e7eb..61c39dd7ad01 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -50,17 +50,9 @@ #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 -------------------------*/ @@ -105,19 +97,6 @@ static const unsigned short wFB_Opt1[2][5] = { #define DATADUR_A_F1 13 /*--------------------- Static Functions --------------------------*/ - -static -void -s_vFillTxKey( - struct vnt_private *pDevice, - unsigned char *pbyBuf, - unsigned char *pbyIVHead, - PSKeyItem pTransmitKey, - unsigned char *pbyHdrBuf, - unsigned short wPayloadLen, - unsigned char *pMICHDR -); - static void s_vFillRTSHead( @@ -127,7 +106,7 @@ s_vFillRTSHead( unsigned int cbFrameLength, bool bNeedAck, bool bDisCRC, - PSEthernetHeader psEthHeader, + struct ieee80211_hdr *hdr, unsigned short wCurrentRate, unsigned char byFBOption ); @@ -144,26 +123,15 @@ s_vGenerateTxParameter( unsigned int cbFrameSize, bool bNeedACK, unsigned int uDMAIdx, - PSEthernetHeader psEthHeader, + void *psEthHeader, unsigned short wCurrentRate ); -static void s_vFillFragParameter( - struct vnt_private *pDevice, - unsigned char *pbyBuffer, - unsigned int uTxType, - void *pvtdCurr, - unsigned short wFragType, - unsigned int cbReqCount -); - static unsigned int s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, - unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize, + unsigned char *pbyTxBufferAddr, unsigned int uDMAIdx, PSTxDesc pHeadTD, - PSEthernetHeader psEthHeader, unsigned char *pPacket, - bool bNeedEncrypt, PSKeyItem pTransmitKey, - unsigned int uNodeIndex, unsigned int *puMACfragNum); + unsigned int uNodeIndex); static __le16 @@ -178,165 +146,12 @@ s_uFillDataHead( unsigned int cbLastFragmentSize, unsigned int uMACfragNum, unsigned char byFBOption, - unsigned short wCurrentRate + unsigned short wCurrentRate, + bool is_pspoll ); /*--------------------- Export Variables --------------------------*/ -static -void -s_vFillTxKey( - struct vnt_private *pDevice, - unsigned char *pbyBuf, - unsigned char *pbyIVHead, - PSKeyItem pTransmitKey, - unsigned char *pbyHdrBuf, - unsigned short wPayloadLen, - unsigned char *pMICHDR -) -{ - struct vnt_mic_hdr *mic_hdr = (struct vnt_mic_hdr *)pMICHDR; - unsigned long *pdwIV = (unsigned long *)pbyIVHead; - unsigned long *pdwExtIV = (unsigned long *)((unsigned char *)pbyIVHead+4); - PS802_11Header pMACHeader = (PS802_11Header)pbyHdrBuf; - unsigned long dwRevIVCounter; - unsigned char 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, (unsigned char *)&(dwRevIVCounter), 3); - memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); - } else { - memcpy(pbyBuf, (unsigned char *)&(dwRevIVCounter), 3); - memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); - if (pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) { - memcpy(pbyBuf+8, (unsigned char *)&(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 |= (unsigned long)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) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV - // Append IV&ExtIV after Mac Header - *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - pr_debug("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) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV - *pdwIV |= cpu_to_le16((unsigned short)(pTransmitKey->wTSC15_0)); - //Append IV&ExtIV after Mac Header - *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - - /* MICHDR0 */ - mic_hdr->id = 0x59; - mic_hdr->tx_priority = 0; - memcpy(mic_hdr->mic_addr2, pMACHeader->abyAddr2, ETH_ALEN); - - /* ccmp pn big endian order */ - mic_hdr->ccmp_pn[0] = (u8)(pTransmitKey->dwTSC47_16 >> 24); - mic_hdr->ccmp_pn[1] = (u8)(pTransmitKey->dwTSC47_16 >> 16); - mic_hdr->ccmp_pn[2] = (u8)(pTransmitKey->dwTSC47_16 >> 8); - mic_hdr->ccmp_pn[3] = (u8)pTransmitKey->dwTSC47_16; - mic_hdr->ccmp_pn[4] = (u8)(pTransmitKey->wTSC15_0 >> 8); - mic_hdr->ccmp_pn[5] = (u8)pTransmitKey->wTSC15_0; - - /* MICHDR1 */ - mic_hdr->payload_len = cpu_to_be16(wPayloadLen); - - if (pDevice->bLongHeader) - mic_hdr->hlen = cpu_to_be16(28); - else - mic_hdr->hlen = cpu_to_be16(22); - - memcpy(mic_hdr->addr1, pMACHeader->abyAddr1, ETH_ALEN); - memcpy(mic_hdr->addr2, pMACHeader->abyAddr2, ETH_ALEN); - - /* MICHDR2 */ - memcpy(mic_hdr->addr3, pMACHeader->abyAddr3, ETH_ALEN); - mic_hdr->frame_control = - cpu_to_le16(pMACHeader->wFrameCtl & 0xc78f); - mic_hdr->seq_ctrl = cpu_to_le16(pMACHeader->wSeqCtl & 0xf); - - if (pDevice->bLongHeader) - memcpy(mic_hdr->addr4, pMACHeader->abyAddr4, ETH_ALEN); - } -} - -static -void -s_vSWencryption( - struct vnt_private *pDevice, - PSKeyItem pTransmitKey, - unsigned char *pbyPayloadHead, - unsigned short wPayloadSize -) -{ - unsigned int cbICVlen = 4; - unsigned long dwICV = 0xFFFFFFFFL; - unsigned long *pdwICV; - - if (pTransmitKey == NULL) - return; - - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - //======================================================================= - // Append ICV after payload - dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) - pdwICV = (unsigned long *)(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 = (unsigned long *)(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); - //======================================================================= - } -} - static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate) { return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2] @@ -683,7 +498,8 @@ s_uFillDataHead( unsigned int cbLastFragmentSize, unsigned int uMACfragNum, unsigned char byFBOption, - unsigned short wCurrentRate + unsigned short wCurrentRate, + bool is_pspoll ) { @@ -702,15 +518,24 @@ s_uFillDataHead( pDevice->byTopCCKBasicRate, PK_TYPE_11B, &buf->b); - /* Get Duration and TimeStamp */ - buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, - byPktType, wCurrentRate, bNeedAck, uFragIdx, - cbLastFragmentSize, uMACfragNum, - byFBOption)); - buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, - PK_TYPE_11B, pDevice->byTopCCKBasicRate, - bNeedAck, uFragIdx, cbLastFragmentSize, - uMACfragNum, byFBOption)); + if (is_pspoll) { + __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); + + buf->duration_a = dur; + buf->duration_b = dur; + } else { + /* Get Duration and TimeStamp */ + buf->duration_a = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, + byPktType, wCurrentRate, bNeedAck, uFragIdx, + cbLastFragmentSize, uMACfragNum, + byFBOption)); + buf->duration_b = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, + PK_TYPE_11B, pDevice->byTopCCKBasicRate, + bNeedAck, uFragIdx, cbLastFragmentSize, + uMACfragNum, byFBOption)); + } buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate); buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate); @@ -764,11 +589,18 @@ s_uFillDataHead( vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, byPktType, &buf->ab); - /* Get Duration and TimeStampOff */ - buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, + if (is_pspoll) { + __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); + + buf->duration = dur; + } else { + /* Get Duration and TimeStampOff */ + buf->duration = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); + } buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); return buf->duration; @@ -778,17 +610,27 @@ s_uFillDataHead( /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, byPktType, &buf->ab); - /* Get Duration and TimeStampOff */ - buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, + + if (is_pspoll) { + __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); + + buf->duration = dur; + } else { + /* Get Duration and TimeStampOff */ + buf->duration = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); + } + buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); return buf->duration; } return 0; } + static void s_vFillRTSHead( @@ -798,7 +640,7 @@ s_vFillRTSHead( unsigned int cbFrameLength, bool bNeedAck, bool bDisCRC, - PSEthernetHeader psEthHeader, + struct ieee80211_hdr *hdr, unsigned short wCurrentRate, unsigned char byFBOption ) @@ -850,18 +692,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); - } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); - } - if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); - else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); - + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } else { struct vnt_rts_g_fb *buf = pvRTS; /* Get SignalField, ServiceField & Length */ @@ -914,19 +746,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); - } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); - } - - if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); - else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); - + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } // if (byFBOption == AUTO_FB_NONE) } else if (byPktType == PK_TYPE_11A) { if (byFBOption == AUTO_FB_NONE) { @@ -947,19 +768,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); - } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); - } - - if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); - else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); - + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } else { struct vnt_rts_a_fb *buf = pvRTS; /* Get SignalField, ServiceField & Length */ @@ -988,16 +798,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); - } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); - } - if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); - else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } } else if (byPktType == PK_TYPE_11B) { struct vnt_rts_ab *buf = pvRTS; @@ -1016,17 +818,8 @@ s_vFillRTSHead( buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); - } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); - } - - if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); - else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } } @@ -1093,7 +886,8 @@ s_vFillCTSHead( buf->reserved2 = 0x0; - memcpy(&buf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, + pDevice->abyCurrentNetAddr); } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) struct vnt_cts *buf = pvCTS; /* Get SignalField, ServiceField & Length */ @@ -1116,7 +910,8 @@ s_vFillCTSHead( IEEE80211_STYPE_CTS); buf->reserved2 = 0x0; - memcpy(&buf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, + pDevice->abyCurrentNetAddr); } } } @@ -1156,11 +951,10 @@ s_vGenerateTxParameter( unsigned int cbFrameSize, bool bNeedACK, unsigned int uDMAIdx, - PSEthernetHeader psEthHeader, + void *psEthHeader, unsigned short wCurrentRate ) { - unsigned int cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24 unsigned short wFifoCtl; bool bDisCRC = false; unsigned char byFBOption = AUTO_FB_NONE; @@ -1178,9 +972,6 @@ s_vGenerateTxParameter( else if (wFifoCtl & FIFOCTL_AUTO_FB_1) byFBOption = AUTO_FB_1; - if (pDevice->bLongHeader) - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - if (!pvRrvTime) return; @@ -1237,90 +1028,30 @@ s_vGenerateTxParameter( } } -static -void -s_vFillFragParameter( - struct vnt_private *pDevice, - unsigned char *pbyBuffer, - unsigned int uTxType, - void *pvtdCurr, - unsigned short wFragType, - unsigned int cbReqCount -) -{ - PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer; - - if (uTxType == TYPE_SYNCDMA) { - 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((unsigned short)(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)pvtdCurr; - //Set TSR1 & ReqCount in TxDescHead - ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(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 |= (unsigned short)wFragType;//0x0001; //0000 0000 0000 0001 -} - static unsigned int s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, - unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize, + unsigned char *pbyTxBufferAddr, unsigned int uDMAIdx, PSTxDesc pHeadTD, - PSEthernetHeader psEthHeader, unsigned char *pPacket, - bool bNeedEncrypt, PSKeyItem pTransmitKey, - unsigned int uNodeIndex, unsigned int *puMACfragNum) + unsigned int is_pspoll) { - unsigned int cbMACHdLen; + PDEVICE_TD_INFO td_info = pHeadTD->pTDInfo; + struct sk_buff *skb = td_info->skb; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct vnt_tx_fifo_head *tx_buffer_head = + (struct vnt_tx_fifo_head *)td_info->buf; + u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl); unsigned int cbFrameSize; - unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbFragPayloadSize; - unsigned int cbLastFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbLastFragPayloadSize; - unsigned int uFragIdx; - unsigned char *pbyPayloadHead; - unsigned char *pbyIVHead; - unsigned char *pbyMacHdr; - unsigned short wFragType; //00:Non-Frag, 01:Start, 10:Mid, 11:Last __le16 uDuration; unsigned char *pbyBuffer; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int cb802_1_H_len = 0; unsigned int uLength = 0; - unsigned int uTmpLen = 0; unsigned int cbMICHDR = 0; - u32 dwMICKey0, dwMICKey1; - u32 dwMIC_Priority; - u32 *pdwMIC_L; - u32 *pdwMIC_R; - u32 dwSafeMIC_L, dwSafeMIC_R; /* Fix "Last Frag Size" < "MIC length". */ - bool bMIC2Frag = false; - unsigned int uMICFragLen = 0; unsigned int uMACfragNum = 1; unsigned int uPadding = 0; unsigned int cbReqCount = 0; - - bool bNeedACK; - bool bRTS; - bool bIsAdhoc; - unsigned char *pbyType; + bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK); + bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS); PSTxDesc ptdCurr; - PSTxBufHead psTxBufHd = (PSTxBufHead) pbyTxBufferAddr; unsigned int cbHeaderLength = 0; void *pvRrvTime; struct vnt_mic_hdr *pMICHDR; @@ -1328,72 +1059,35 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, void *pvCTS; void *pvTxDataHd; unsigned short wTxBufSize; // FFinfo size - unsigned int uTotalCopyLength = 0; unsigned char byFBOption = AUTO_FB_NONE; - bool bIsWEP256 = false; - PSMgmtObject pMgmt = pDevice->pMgmt; pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) - bNeedACK = false; - else - bNeedACK = true; - bIsAdhoc = true; - } else { - // MSDUs in Infra mode always need ACK - bNeedACK = true; - bIsAdhoc = false; - } + cbFrameSize = skb->len + 4; - 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 + if (info->control.hw_key) { + switch (info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_CCMP: cbMICHDR = sizeof(struct vnt_mic_hdr); + default: + break; } + + cbFrameSize += info->control.hw_key->icv_len; + if (pDevice->byLocalID > REV_ID_VT3253_A1) { //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMACHdLen%4); + uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 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) + if (fifo_ctl & FIFOCTL_AUTO_FB_0) byFBOption = AUTO_FB_0; - else if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_1) + else if (fifo_ctl & FIFOCTL_AUTO_FB_1) byFBOption = AUTO_FB_1; ////////////////////////////////////////////////////// @@ -1487,1477 +1181,345 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, } } // Auto Fall Back } - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); - -////////////////////////////////////////////////////////////////// - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); - } else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); - } else { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]); - } - // DO Software Michael - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((unsigned char *)&(psEthHeader->abyDstAddr[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - pr_debug("MIC KEY: %X, %X\n", dwMICKey0, dwMICKey1); - } - -/////////////////////////////////////////////////////////////////// - - pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderLength); - pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen); - pbyIVHead = (unsigned char *)(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 = (unsigned short) ((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 - //========================= - pr_debug("Start Fragmentation...\n"); - wFragType = FRAGCTL_STAFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)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, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)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) > ETH_DATA_LEN) { - if ((psEthHeader->wType == TYPE_PKT_IPX) || - (psEthHeader->wType == cpu_to_le16(0xF380))) { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); - } else { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); - } - pbyType = (unsigned char *)(pbyPayloadHead + 6); - memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short)); - cb802_1_H_len = 8; - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize; - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)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)) { - pr_debug("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), (unsigned short)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, (void *)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 - //========================= - pr_debug("Last Fragmentation...\n"); - - wFragType = FRAGCTL_ENDFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)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, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbLastFragPayloadSize, (unsigned char *)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 = (unsigned char *)pHeadTD->pTDInfo->buf; - - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; - - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)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)) { - pr_debug("LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n", - uMICFragLen, - cbLastFragPayloadSize, - uTmpLen); - - if (bMIC2Frag == false) { - if (uTmpLen != 0) - MIC_vAppend((pbyBuffer + uLength), uTmpLen); - pdwMIC_L = (u32 *)(pbyBuffer + uLength + uTmpLen); - pdwMIC_R = (u32 *)(pbyBuffer + uLength + uTmpLen + 4); - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - pr_debug("Last MIC:%X, %X\n", - *pdwMIC_L, *pdwMIC_R); - } else { - if (uMICFragLen >= 4) { - memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)), - (cbMIClen - uMICFragLen)); - pr_debug("LAST: uMICFragLen >= 4: %X, %d\n", - *(unsigned char *)((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)), - (cbMIClen - uMICFragLen)); - - } else { - memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_L + uMICFragLen), - (4 - uMICFragLen)); - memcpy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4); - pr_debug("LAST: uMICFragLen < 4: %X, %d\n", - *(unsigned char *)((unsigned char *)&dwSafeMIC_R + uMICFragLen - 4), - (cbMIClen - uMICFragLen)); - } - } - 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), (unsigned short)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, (void *)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 - //========================= - pr_debug("Middle Fragmentation...\n"); - - wFragType = FRAGCTL_MIDFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)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, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)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 - //--------------------------- - - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; - - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)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 = (u32 *)(pbyBuffer + uLength + uTmpLen); - pdwMIC_R = (u32 *)(pbyBuffer + uLength + uTmpLen + 4); - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - dwSafeMIC_L = *pdwMIC_L; - dwSafeMIC_R = *pdwMIC_R; - - pr_debug("MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n", - uMICFragLen, - cbFragPayloadSize, - uTmpLen); - pr_debug("Fill MIC in Middle frag [%d]\n", - uMICFragLen); - pr_debug("Get MIC:%X, %X\n", - *pdwMIC_L, *pdwMIC_R); - } - pr_debug("Middle frag len: %d\n", - uTmpLen); - - } else { - ASSERT(uTmpLen == (cbFragPayloadSize)); - } - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)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, (void *)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 - //========================= - wFragType = FRAGCTL_NONFRAG; - - //Set FragCtl in TxBufferHead - psTxBufHd->wFragCtl |= (unsigned short)wFragType; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)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, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, 0); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)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) > ETH_DATA_LEN) { - if ((psEthHeader->wType == TYPE_PKT_IPX) || - (psEthHeader->wType == cpu_to_le16(0xF380))) { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); - } else { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); - } - pbyType = (unsigned char *)(pbyPayloadHead + 6); - memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short)); - cb802_1_H_len = 8; - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen); - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); + td_info->mic_hdr = pMICHDR; - // 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)) { - pr_debug("Length:%d, %d\n", - cbFrameBodySize - cb802_1_H_len, uLength); - - MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize); - - pdwMIC_L = (u32 *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize); - pdwMIC_R = (u32 *)(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; - } + memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); - pr_debug("uLength: %d, %d\n", uLength, cbFrameBodySize); - pr_debug("cbReqCount:%d, %d, %d, %d\n", - cbReqCount, cbHeaderLength, uPadding, cbIVlen); - pr_debug("MIC:%x, %x\n", *pdwMIC_L, *pdwMIC_R); + /* Fill FIFO,RrvTime,RTS,and CTS */ + s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS, + cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate); + /* Fill DataHead */ + uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, + 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll); - } + hdr->duration_id = uDuration; - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), - (unsigned short)(cbFrameBodySize + cbMIClen)); - cbReqCount += cbICVlen; - } - } + cbReqCount = cbHeaderLength + uPadding + skb->len; + pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; + uLength = cbHeaderLength + uPadding; - ptdCurr = (PSTxDesc)pHeadTD; + /* Copy the Packet into a tx Buffer */ + memcpy((pbyBuffer + uLength), skb->data, skb->len); - 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((unsigned short)(cbReqCount)); + ptdCurr = (PSTxDesc)pHeadTD; - pDevice->iTDUsed[uDMAIdx]++; - - } - *puMACfragNum = uMACfragNum; + 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((unsigned short)(cbReqCount)); return cbHeaderLength; } -void -vGenerateFIFOHeader(struct vnt_private *pDevice, unsigned char byPktType, - unsigned char *pbyTxBufferAddr, bool bNeedEncrypt, - unsigned int cbPayloadSize, unsigned int uDMAIdx, - PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, unsigned char *pPacket, - PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum, - unsigned int *pcbHeaderSize) +static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer, + struct ieee80211_key_conf *tx_key, + struct sk_buff *skb, u16 payload_len, + struct vnt_mic_hdr *mic_hdr) { - unsigned int wTxBufSize; // FFinfo size - bool bNeedACK; - bool bIsAdhoc; - unsigned short cbMacHdLen; - PSTxBufHead pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; - - wTxBufSize = sizeof(STxBufHead); - - memset(pTxBufHead, 0, wTxBufSize); - //Set FIFOCTL_NEEDACK - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) { - bNeedACK = false; - pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK); - } else { - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; + struct ieee80211_key_seq seq; + u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb)); + + /* strip header and icv len from payload */ + payload_len -= ieee80211_get_hdrlen_from_skb(skb); + payload_len -= tx_key->icv_len; + + switch (tx_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + memcpy(key_buffer, iv, 3); + memcpy(key_buffer + 3, tx_key->key, tx_key->keylen); + + if (tx_key->keylen == WLAN_KEY_LEN_WEP40) { + memcpy(key_buffer + 8, iv, 3); + memcpy(key_buffer + 11, + tx_key->key, WLAN_KEY_LEN_WEP40); } - 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((unsigned short)(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; - } - } - } - - RFbSetPower(pDevice, pDevice->wCurrentRate, pDevice->byCurrentCh); - - pTxBufHead->byTxPower = pDevice->byCurPwr; - - *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktType, pbyTxBufferAddr, cbPayloadSize, - uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt, - pTransmitKey, uNodeIndex, puMACfragNum); -} + break; + case WLAN_CIPHER_SUITE_TKIP: + ieee80211_get_tkip_p2k(tx_key, skb, key_buffer); -/*+ - * - * Description: - * Translate 802.3 to 802.11 header - * - * Parameters: - * In: - * pDevice - Pointer to adapter - * 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 - * - -*/ + break; + case WLAN_CIPHER_SUITE_CCMP: -void -vGenerateMACHeader( - struct vnt_private *pDevice, - unsigned char *pbyBufferAddr, - __le16 wDuration, - PSEthernetHeader psEthHeader, - bool bNeedEncrypt, - unsigned short wFragType, - unsigned int uDMAIdx, - unsigned int uFragIdx -) -{ - PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr; + if (!mic_hdr) + return; - memset(pMACHeader, 0, (sizeof(S802_11Header))); + mic_hdr->id = 0x59; + mic_hdr->payload_len = cpu_to_be16(payload_len); + ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2); - if (uDMAIdx == TYPE_ATIMDMA) - pMACHeader->wFrameCtl = TYPE_802_11_ATIM; - else - pMACHeader->wFrameCtl = TYPE_802_11_DATA; + ieee80211_get_key_tx_seq(tx_key, &seq); - if (pDevice->op_mode == NL80211_IFTYPE_AP) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - pMACHeader->wFrameCtl |= FC_FROMDS; - } else { - if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } else { - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - pMACHeader->wFrameCtl |= FC_TODS; - } - } + memcpy(mic_hdr->ccmp_pn, seq.ccmp.pn, IEEE80211_CCMP_PN_LEN); - if (bNeedEncrypt) - pMACHeader->wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_ISWEP(1)); + if (ieee80211_has_a4(hdr->frame_control)) + mic_hdr->hlen = cpu_to_be16(28); + else + mic_hdr->hlen = cpu_to_be16(22); - pMACHeader->wDurationID = le16_to_cpu(wDuration); + ether_addr_copy(mic_hdr->addr1, hdr->addr1); + ether_addr_copy(mic_hdr->addr2, hdr->addr2); + ether_addr_copy(mic_hdr->addr3, hdr->addr3); - if (pDevice->bLongHeader) { - PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr; + mic_hdr->frame_control = cpu_to_le16( + le16_to_cpu(hdr->frame_control) & 0xc78f); + mic_hdr->seq_ctrl = cpu_to_le16( + le16_to_cpu(hdr->seq_ctrl) & 0xf); - pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS); - memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN); - } - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); + if (ieee80211_has_a4(hdr->frame_control)) + ether_addr_copy(mic_hdr->addr4, hdr->addr4); - //Set FragNumber in Sequence Control - pMACHeader->wSeqCtl |= cpu_to_le16((unsigned short)uFragIdx); + memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP); - if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) { - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; + break; + default: + break; } - - if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) //StartFrag or MidFrag - pMACHeader->wFrameCtl |= FC_MOREFRAG; } -CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) +int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx, + PSTxDesc head_td, struct sk_buff *skb) { - PSTxDesc pFrstTD; - unsigned char byPktType; - unsigned char *pbyTxBufferAddr; - void *pvRTS; - struct vnt_cts *pCTS; - void *pvTxDataHd; - unsigned int uDuration; - unsigned int cbReqCount; - PS802_11Header pMACHeader; - unsigned int cbHeaderSize; - unsigned int cbFrameBodySize; - bool bNeedACK; - bool bIsPSPOLL = false; - PSTxBufHead pTxBufHead; - unsigned int cbFrameSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uPadding = 0; - unsigned short wTxBufSize; - unsigned int cbMacHdLen; - SEthernetHeader sEthHeader; - void *pvRrvTime; - void *pMICHDR; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wCurrentRate = RATE_1M; - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) - return CMD_STATUS_RESOURCES; - - pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; - pbyTxBufferAddr = (unsigned char *)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; + PDEVICE_TD_INFO td_info = head_td->pTDInfo; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_rate *tx_rate = &info->control.rates[0]; + struct ieee80211_rate *rate; + struct ieee80211_key_conf *tx_key; + struct ieee80211_hdr *hdr; + struct vnt_tx_fifo_head *tx_buffer_head = + (struct vnt_tx_fifo_head *)td_info->buf; + u16 tx_body_size = skb->len, current_rate; + u8 pkt_type; + bool is_pspoll = false; + + memset(tx_buffer_head, 0, sizeof(*tx_buffer_head)); + + hdr = (struct ieee80211_hdr *)(skb->data); + + rate = ieee80211_get_tx_rate(priv->hw, info); + + current_rate = rate->hw_value; + if (priv->wCurrentRate != current_rate && + !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { + priv->wCurrentRate = current_rate; + + RFbSetPower(priv, priv->wCurrentRate, + priv->hw->conf.chandef.chan->hw_value); } - // 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); + if (current_rate > RATE_11M) + pkt_type = (u8)priv->byPacketType; 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; + pkt_type = PK_TYPE_11B; + + /*Set fifo controls */ + if (pkt_type == PK_TYPE_11A) + tx_buffer_head->fifo_ctl = 0; + else if (pkt_type == PK_TYPE_11B) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B); + else if (pkt_type == PK_TYPE_11GB) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB); + else if (pkt_type == PK_TYPE_11GA) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA); + + /* generate interrupt */ + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); + + if (!ieee80211_is_data(hdr->frame_control)) { + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN); + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0); + tx_buffer_head->time_stamp = + cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); + } else { + tx_buffer_head->time_stamp = + cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); } - pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; - pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK); - if (is_multicast_ether_addr(&(pPacket->p80211Header->sA3.abyAddr1[0]))) - bNeedACK = false; - else { - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - } + if (ieee80211_has_retry(hdr->frame_control)) + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY); - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || - (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { - pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; - } + if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + priv->byPreambleType = PREAMBLE_SHORT; + else + priv->byPreambleType = PREAMBLE_LONG; - pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); + if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS) + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS); - if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { - bIsPSPOLL = true; - cbMacHdLen = WLAN_HDR_ADDR2_LEN; - } else { - cbMacHdLen = WLAN_HDR_ADDR3_LEN; + if (ieee80211_has_a4(hdr->frame_control)) { + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD); + priv->bLongHeader = true; } - //Set FRAGCTL_MACHDCNT - pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10)); - - // Notes: - // Although spec says MMPDU can be fragmented; In most cases, - // 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. - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - pTxBufHead->wFragCtl |= FRAGCTL_AES; - pDevice->bAES = true; + if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) + is_pspoll = true; + + tx_buffer_head->frag_ctl = + cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10); + + if (info->control.hw_key) { + tx_key = info->control.hw_key; + + switch (info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY); + break; + case WLAN_CIPHER_SUITE_TKIP: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP); + break; + case WLAN_CIPHER_SUITE_CCMP: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES); + default: + break; } - //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; + tx_buffer_head->current_rate = cpu_to_le16(current_rate); - //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() + /* legacy rates TODO use ieee80211_tx_rate */ + if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) { + if (priv->byAutoFBCtrl == AUTO_FB_0) + tx_buffer_head->fifo_ctl |= + cpu_to_le16(FIFOCTL_AUTO_FB_0); + else if (priv->byAutoFBCtrl == AUTO_FB_1) + tx_buffer_head->fifo_ctl |= + cpu_to_le16(FIFOCTL_AUTO_FB_1); - //Set RrvTime/RTS/CTS Buffer - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet - pvRrvTime = (void *) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = NULL; - pvRTS = NULL; - pCTS = (struct vnt_cts *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts)); - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts) + sizeof(struct vnt_cts)); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g); - } else { // 802.11a/b packet - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = NULL; - pvRTS = NULL; - pCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_ab)); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - sizeof(struct vnt_tx_datahead_ab); } - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - - memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), ETH_ALEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), ETH_ALEN); - //========================= - // No Fragmentation - //========================= - pTxBufHead->wFragCtl |= (unsigned short)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) { - unsigned char *pbyIVHead; - unsigned char *pbyPayloadHead; - unsigned char *pbyBSSID; - PSKeyItem pTransmitKey = NULL; - - pbyIVHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding); - pbyPayloadHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen); - - //Fill TXKEY - //Kyle: Need fix: TKIP and AES did't encrypt Mnt Packet. - //s_vFillTxKey(pDevice, (unsigned char *)pTxBufHead->adwTxKey, NULL); - - //Fill IV(ExtIV,RSNHDR) - //s_vFillPrePayload(pDevice, pbyIVHead, NULL); - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - do { - if ((pDevice->op_mode == NL80211_IFTYPE_STATION) && - (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) { - pr_debug("Get GTK\n"); - break; - } - } else { - pr_debug("Get PTK\n"); - break; - } - } - // get group key - pbyBSSID = pDevice->abyBroadcastAddr; - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - pr_debug("KEY is NULL. OP Mode[%d]\n", - pDevice->op_mode); - } else { - pr_debug("Get GTK\n"); - } - } while (false); - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize, NULL); - - memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen); - memcpy(pbyPayloadHead, ((unsigned char *)(pPacket->p80211Header) + cbMacHdLen), - cbFrameBodySize); - } else { - // Copy the Packet into a tx Buffer - memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); - } + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG); - 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 to 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) { - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - } else { - ((struct vnt_tx_datahead_ab *)pvTxDataHd)->duration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - } - } + s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head, + dma_idx, head_td, is_pspoll); - // 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((unsigned short)(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); + if (info->control.hw_key) { + tx_key = info->control.hw_key; + if (tx_key->keylen > 0) + vnt_fill_txkey(hdr, tx_buffer_head->tx_key, + tx_key, skb, tx_body_size, td_info->mic_hdr); } - pDevice->bPWBitOn = false; - - wmb(); - pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - - pDevice->iTDUsed[TYPE_TXDMA0]++; - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) - pr_debug(" available td0 <= 1\n"); - - pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; - - pDevice->nTxDataTimeCout = 0; //2008-8-21 chester <add> for send null packet - // Poll Transmit the adapter - MACvTransmit0(pDevice->PortOffset); - - return CMD_STATUS_PENDING; + return 0; } -CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) +static int vnt_beacon_xmit(struct vnt_private *priv, + struct sk_buff *skb) { - unsigned char byPktType; - unsigned char *pbyBuffer = (unsigned char *)pDevice->tx_beacon_bufs; - unsigned int cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN; - unsigned int cbHeaderSize = 0; struct vnt_tx_short_buf_head *short_head = - (struct vnt_tx_short_buf_head *)pbyBuffer; - PS802_11Header pMACHeader; - unsigned short wCurrentRate; - - memset(short_head, 0, sizeof(*short_head)); + (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs; + struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *) + (priv->tx_beacon_bufs + sizeof(*short_head)); + struct ieee80211_tx_info *info; + u32 frame_size = skb->len + 4; + u16 current_rate; - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - wCurrentRate = RATE_6M; - byPktType = PK_TYPE_11A; - } else { - wCurrentRate = RATE_2M; - byPktType = PK_TYPE_11B; - } + memset(priv->tx_beacon_bufs, 0, sizeof(*short_head)); - //Set Preamble type always long - pDevice->byPreambleType = PREAMBLE_LONG; + if (priv->byBBType == BB_TYPE_11A) { + current_rate = RATE_6M; - /* Set FIFOCTL_GENINT */ - short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); - - /* Set packet type & Get Duration */ - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - short_head->duration = - cpu_to_le16((u16)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 - short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B); + /* Get SignalField,ServiceField,Length */ + vnt_get_phy_field(priv, frame_size, current_rate, + PK_TYPE_11A, &short_head->ab); + /* Get Duration and TimeStampOff */ short_head->duration = - cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, - cbFrameSize, byPktType, wCurrentRate, false, - 0, 0, 1, AUTO_FB_NONE)); - } - - vnt_get_phy_field(pDevice, cbFrameSize, - wCurrentRate, byPktType, &short_head->ab); - - /* Get TimeStampOff */ - short_head->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); - cbHeaderSize = sizeof(struct vnt_tx_short_buf_head); - - //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; -} - -unsigned int -cbGetFragCount( - struct vnt_private *pDevice, - PSKeyItem pTransmitKey, - unsigned int cbFrameBodySize, - PSEthernetHeader psEthHeader -) -{ - unsigned int cbMACHdLen; - unsigned int cbFrameSize; - unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbFragPayloadSize; - unsigned int cbLastFragPayloadSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uMACfragNum = 1; - bool bNeedACK; - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - if (is_multicast_ether_addr(&(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 = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize); - cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize; - if (cbLastFragPayloadSize == 0) - cbLastFragPayloadSize = cbFragPayloadSize; - else - uMACfragNum++; - } - return uMACfragNum; -} - -void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb, - unsigned char *pbMPDU, unsigned int cbMPDULen) -{ - PSTxDesc pFrstTD; - unsigned char byPktType; - unsigned char *pbyTxBufferAddr; - void *pvRTS; - void *pvCTS; - void *pvTxDataHd; - unsigned int uDuration; - unsigned int cbReqCount; - PS802_11Header pMACHeader; - unsigned int cbHeaderSize; - unsigned int cbFrameBodySize; - bool bNeedACK; - bool bIsPSPOLL = false; - PSTxBufHead pTxBufHead; - unsigned int cbFrameSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uPadding = 0; - unsigned int cbMICHDR = 0; - unsigned int uLength = 0; - u32 dwMICKey0, dwMICKey1; - u32 dwMIC_Priority; - u32 *pdwMIC_L; - u32 *pdwMIC_R; - unsigned short wTxBufSize; - unsigned int cbMacHdLen; - SEthernetHeader sEthHeader; - void *pvRrvTime; - void *pMICHDR; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wCurrentRate = RATE_1M; - PUWLAN_80211HDR p80211Header; - unsigned int uNodeIndex = 0; - bool bNodeExist = false; - SKeyItem STempKey; - PSKeyItem pTransmitKey = NULL; - unsigned char *pbyIVHead; - unsigned char *pbyPayloadHead; - unsigned char *pbyMacHdr; - - unsigned int cbExtSuppRate = 0; - - 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; + cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B, + frame_size, PK_TYPE_11A, current_rate, + false, 0, 0, 1, AUTO_FB_NONE)); - pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; - pbyTxBufferAddr = (unsigned char *)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; + short_head->time_stamp_off = + vnt_time_stamp_off(priv, current_rate); } 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 to 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; - } - } - - pr_debug("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_ether_addr(&(p80211Header->sA3.abyAddr1[0]))) { - bNeedACK = false; - if (pDevice->bEnableHostWEP) { - uNodeIndex = 0; - bNodeExist = true; - } - } else { - if (pDevice->bEnableHostWEP) { - if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (unsigned char *)(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; - } - - 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; + current_rate = RATE_1M; + short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B); - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) - cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN; + /* Get SignalField,ServiceField,Length */ + vnt_get_phy_field(priv, frame_size, current_rate, + PK_TYPE_11B, &short_head->ab); - if (cbExtSuppRate > 0) - cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES; - } + /* Get Duration and TimeStampOff */ + short_head->duration = + cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B, + frame_size, PK_TYPE_11B, current_rate, + false, 0, 0, 1, AUTO_FB_NONE)); - //Set FRAGCTL_MACHDCNT - pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)cbMacHdLen << 10); - - // Notes: - // Although spec says MMPDU can be fragmented; In most cases, - // 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. - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - cbMICHDR = sizeof(struct vnt_mic_hdr); - pTxBufHead->wFragCtl |= FRAGCTL_AES; - pDevice->bAES = true; - } - //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMacHdLen%4); - uPadding %= 4; + short_head->time_stamp_off = + vnt_time_stamp_off(priv, current_rate); } - 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() + short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet + /* Copy Beacon */ + memcpy(mgmt_hdr, skb->data, skb->len); - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts)); - pvRTS = NULL; - pvCTS = (struct vnt_cts *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts) + cbMICHDR); - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts)); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g); + /* time stamp always 0 */ + mgmt_hdr->u.beacon.timestamp = 0; - } else {//802.11a/b packet - - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + - wTxBufSize + sizeof(struct vnt_rrv_time_ab)); - pvRTS = NULL; - pvCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + - wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - cbMICHDR + sizeof(struct vnt_tx_datahead_ab); + info = IEEE80211_SKB_CB(skb); + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr; + hdr->duration_id = 0; + hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4); } - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), ETH_ALEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), ETH_ALEN); - //========================= - // No Fragmentation - //========================= - pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS, - cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate); + priv->wSeqCounter++; + if (priv->wSeqCounter > 0x0fff) + priv->wSeqCounter = 0; - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, - 0, 0, 1, AUTO_FB_NONE, wCurrentRate); + priv->wBCNBufLen = sizeof(*short_head) + skb->len; - pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); + MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma); - cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate; + MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen); + /* Set auto Transmit on */ + MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + /* Poll Transmit the adapter */ + MACvTransmitBCN(priv->PortOffset); - pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize); - pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen); - pbyIVHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding); + return 0; +} - // Copy the Packet into a tx Buffer - memcpy(pbyMacHdr, pbMPDU, cbMacHdLen); +int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif) +{ + struct sk_buff *beacon; - // version set to 0, patch for hostapd deamon - pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc); - memcpy(pbyPayloadHead, (pbMPDU + cbMacHdLen), cbFrameBodySize); + beacon = ieee80211_beacon_get(priv->hw, vif); + if (!beacon) + return -ENOMEM; - // 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 -); - } + if (vnt_beacon_xmit(priv, beacon)) { + ieee80211_free_txskb(priv->hw, beacon); + return -ENODEV; } - // 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 = *(u32 *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); - - // DO Software Michael - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((unsigned char *)&(sEthHeader.abyDstAddr[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - pr_debug("DMA0_tx_8021:MIC KEY: %X, %X\n", - dwMICKey0, dwMICKey1); - - uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen; - - MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize); - - pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize); - pdwMIC_R = (u32 *)(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; - } - - pr_debug("uLength: %d, %d\n", uLength, cbFrameBodySize); - pr_debug("cbReqCount:%d, %d, %d, %d\n", - cbReqCount, cbHeaderSize, uPadding, cbIVlen); - pr_debug("MIC:%x, %x\n", *pdwMIC_L, *pdwMIC_R); - - } - - s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)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, (unsigned short)(cbFrameBodySize + cbMIClen)); - } + return 0; +} - 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) { - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_a = cpu_to_le16(p80211Header->sA2.wDurationID); - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_b = cpu_to_le16(p80211Header->sA2.wDurationID); - } else { - ((struct vnt_tx_datahead_ab *)pvTxDataHd)->duration = cpu_to_le16(p80211Header->sA2.wDurationID); - } - } +int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf) +{ + int ret; - // 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; + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); - wmb(); - pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - pDevice->iTDUsed[TYPE_TXDMA0]++; + CARDvSetFirstNextTBTT(priv, conf->beacon_int); - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) - pr_debug(" available td0 <= 1\n"); + CARDbSetBeaconPeriod(priv, conf->beacon_int); - pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; + ret = vnt_beacon_make(priv, vif); - // Poll Transmit the adapter - MACvTransmit0(pDevice->PortOffset); + return ret; } |