mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-14 12:37:32 +00:00
staging: vt6655: mac80211 conversion: s_cbFillTxBufHead
Covert to handle mac80211 sk_buff data removing fragmentation processing via s_vFillFragParameter and calls to vGenerateMACHeader and s_vSWencryption fragmentation is now handled by mac80211. There is still more todos with this function when legacy net device code have been remove from driver. Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
01eec153ab
commit
cfd9f0d6b1
1 changed files with 47 additions and 538 deletions
|
@ -144,7 +144,7 @@ s_vGenerateTxParameter(
|
|||
unsigned int cbFrameSize,
|
||||
bool bNeedACK,
|
||||
unsigned int uDMAIdx,
|
||||
PSEthernetHeader psEthHeader,
|
||||
void *psEthHeader,
|
||||
unsigned short wCurrentRate
|
||||
);
|
||||
|
||||
|
@ -1176,7 +1176,7 @@ s_vGenerateTxParameter(
|
|||
unsigned int cbFrameSize,
|
||||
bool bNeedACK,
|
||||
unsigned int uDMAIdx,
|
||||
PSEthernetHeader psEthHeader,
|
||||
void *psEthHeader,
|
||||
unsigned short wCurrentRate
|
||||
)
|
||||
{
|
||||
|
@ -1301,46 +1301,26 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
|
|||
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 *puMACfragNum)
|
||||
{
|
||||
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;
|
||||
|
@ -1348,72 +1328,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;
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
@ -1507,471 +1450,37 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
|
|||
}
|
||||
} // Auto Fall Back
|
||||
}
|
||||
|
||||
td_info->mic_hdr = pMICHDR;
|
||||
|
||||
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);
|
||||
}
|
||||
/* 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);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
hdr->duration_id = uDuration;
|
||||
|
||||
pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderLength);
|
||||
pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
|
||||
pbyIVHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding);
|
||||
cbReqCount = cbHeaderLength + uPadding + cbFrameBodySize;
|
||||
pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
|
||||
uLength = cbHeaderLength + 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++;
|
||||
/* Copy the Packet into a tx Buffer */
|
||||
memcpy((pbyBuffer + uLength), pPacket, cbFrameBodySize);
|
||||
|
||||
//[Hdr+(IV)+last fragment payload+(MIC)+(ICV)+FCS]
|
||||
cbLastFragmentSize = cbMACHdLen + cbLastFragPayloadSize + cbIVlen + cbICVlen + cbFCSlen;
|
||||
ptdCurr = (PSTxDesc)pHeadTD;
|
||||
|
||||
for (uFragIdx = 0; uFragIdx < uMACfragNum; uFragIdx++) {
|
||||
if (uFragIdx == 0) {
|
||||
//=========================
|
||||
// Start Fragmentation
|
||||
//=========================
|
||||
pr_debug("Start Fragmentation...\n");
|
||||
wFragType = FRAGCTL_STAFRAG;
|
||||
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));
|
||||
|
||||
//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);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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((unsigned short)(cbReqCount));
|
||||
|
||||
pDevice->iTDUsed[uDMAIdx]++;
|
||||
|
||||
}
|
||||
*puMACfragNum = uMACfragNum;
|
||||
|
||||
return cbHeaderLength;
|
||||
|
|
Loading…
Reference in a new issue