?? rtusb_data.c
字號:
if ((CipherSuite == Ndis802_11Encryption1Enabled) && (EAPOLFrame == FALSE) &&
(pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
{
// Prepare IV, IV offset, Key for Hardware encryption
RTMPInitWepEngine(
pAdapter,
pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].Key,
pAdapter->PortCfg.DefaultKeyId,
pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen,
(PUCHAR) &pTxD->Iv);
KeyID = pAdapter->PortCfg.DefaultKeyId;
// Set Iv offset in TxD
pTxD->IvOffset = LENGTH_802_11;
NdisMoveMemory(pDest, &pTxD->Iv, 4);
pDest += 4;
}
else if ((CipherSuite == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
{
INT i;
i = 0;
// Prepare IV, EIV, IV offset, Key for hardware encryption
RTMPInitTkipEngine(
pAdapter,
pWpaKey->Key,
pAdapter->PortCfg.DefaultKeyId, // This might cause problem when using peer key
Header_802_11.Controlhead.Addr2.Octet,
pWpaKey->TxMic,
pWpaKey->TxTsc,
0,
&Iv16,
&Iv32,
pDest);
// Increase TxTsc value for next transmission
while (++pWpaKey->TxTsc[i] == 0x0)
{
i++;
if (i == 6)
break;
}
if (i == 6)
{
// TODO: TSC has done one full cycle, do re-keying stuff follow specs
// Should send a special event microsoft defined to request re-key
}
// Copy IV
NdisMoveMemory(&pTxD->Iv, &Iv16, 4);
// Copy EIV
NdisMoveMemory(&pTxD->Eiv, &Iv32, 4);
// Set IV offset
pTxD->IvOffset = LENGTH_802_11;
NdisMoveMemory(pDest, &Iv16, 4);
pDest += 4;
NdisMoveMemory(pDest, &Iv32, 4);
pDest += 4;
}
else if ((CipherSuite == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL))
{
INT i;
PUCHAR pTmp;
i = 0;
pTmp = (PUCHAR) &Iv16;
*pTmp = pWpaKey->TxTsc[0];
*(pTmp + 1) = pWpaKey->TxTsc[1];
*(pTmp + 2) = 0;
*(pTmp + 3) = (pAdapter->PortCfg.DefaultKeyId << 6) | 0x20;
Iv32 = *(PULONG)(&pWpaKey->TxTsc[2]);
// Increase TxTsc value for next transmission
while (++pWpaKey->TxTsc[i] == 0x0)
{
i++;
if (i == 6)
break;
}
if (i == 6)
{
// TODO: TSC has done one full cycle, do re-keying stuff follow specs
// Should send a special event microsoft defined to request re-key
}
// Copy IV
NdisMoveMemory(&pTxD->Iv, &Iv16, 4);
// Copy EIV
NdisMoveMemory(&pTxD->Eiv, &Iv32, 4);
// Set IV offset
pTxD->IvOffset = LENGTH_802_11;
NdisMoveMemory(pDest, &Iv16, 4);
pDest += 4;
NdisMoveMemory(pDest, &Iv32, 4);
pDest += 4;
}
//
// Only the first fragment required LLC-SNAP header !!!
//
if ((StartOfFrame == TRUE) && (Encapped == TRUE))
{
// For WEP & no encryption required frame, just copy LLC header into buffer,
// Hardware will do the encryption job.
// For TKIP, we have to calculate MIC and store it first
if ((CipherSuite == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
{
// Calculate MSDU MIC Value
RTMPCalculateMICValue(pAdapter, skb, pEncap, 6, pWpaKey);
}
// For WEP & no encryption required frame, just copy LLC header into buffer,
// Hardware will do the encryption job.
// For TKIP, we have to calculate MIC and store it first
// Copy LLC header
NdisMoveMemory(pDest, pEncap, 6);
pDest += 6;
// Copy protocol type
pSrc = (PUCHAR) pVirtualAddress;
NdisMoveMemory(pDest, pSrc + 12, 2);
pDest += 2;
// Exclude 802.3 header size, we will recalculate the size at
// the end of fragment preparation.
NdisBufferLength -= LENGTH_802_3;
pSrc += LENGTH_802_3;
FreeFragSize -= LENGTH_802_1_H;
}
else if ((StartOfFrame == TRUE) && (Encapped == FALSE))
{
if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
{
// Calculate MSDU MIC Value
RTMPCalculateMICValue(pAdapter, skb, pEncap, 0, pWpaKey);
}
pSrc = (PUCHAR) pVirtualAddress + LENGTH_802_3;
NdisBufferLength -= LENGTH_802_3;
}
// Start copying payload
BytesCopied = 0;
do
{
if (NdisBufferLength >= FreeFragSize)
{
// Copy only the free fragment size, and save the pointer
// of current buffer descriptor for next fragment buffer.
NdisMoveMemory(pDest, pSrc, FreeFragSize);
BytesCopied += FreeFragSize;
pSrc += FreeFragSize;
pDest += FreeFragSize;
NdisBufferLength -= FreeFragSize;
break;
}
else
{
// Copy the rest of this buffer descriptor pointed data
// into ring buffer.
NdisMoveMemory(pDest, pSrc, NdisBufferLength);
BytesCopied += NdisBufferLength;
pDest += NdisBufferLength;
FreeFragSize -= NdisBufferLength;
}
// No more buffer descriptor
// Add MIC value if needed
if ((CipherSuite == Ndis802_11Encryption2Enabled) &&
(MICFrag == FALSE) &&
(pWpaKey != NULL))
{
INT i;
NdisBufferLength = 8; // Set length to MIC length
DBGPRINT_RAW(RT_DEBUG_INFO, "Calculated TX MIC value =");
for (i = 0; i < 8; i++)
{
DBGPRINT_RAW(RT_DEBUG_INFO, "%02x:", pAdapter->PrivateInfo.Tx.MIC[i]);
}
DBGPRINT_RAW(RT_DEBUG_INFO, "\n");
if (FreeFragSize >= NdisBufferLength)
{
NdisMoveMemory(pDest, pAdapter->PrivateInfo.Tx.MIC, NdisBufferLength);
BytesCopied += NdisBufferLength;
pDest += NdisBufferLength;
FreeFragSize -= NdisBufferLength;
NdisBufferLength = 0;
RemainSize += 8; // Need to add MIC as payload
}
else
{
NdisMoveMemory(pDest, pAdapter->PrivateInfo.Tx.MIC, FreeFragSize);
BytesCopied += FreeFragSize;
pSrc = pAdapter->PrivateInfo.Tx.MIC + FreeFragSize;
pDest += FreeFragSize;
NdisBufferLength -= FreeFragSize;
MICFrag = TRUE;
RemainSize += (8 - FreeFragSize); // Need to add MIC as payload
}
}
} while (FALSE); // End of copying payload
// Real packet size, No 802.1H header for fragments except the first one.
if ((StartOfFrame == TRUE) && (Encapped == TRUE))
{
TxSize = BytesCopied + LENGTH_802_11 + LENGTH_802_1_H;
}
else
{
TxSize = BytesCopied + LENGTH_802_11;
}
RemainSize = RemainSize - BytesCopied;
if ((CipherSuite == Ndis802_11Encryption1Enabled) && (Header_802_11.Controlhead.Frame.Wep == 1))
{
// IV + ICV which ASIC added after encryption done
TxSize += 4;
PLCPLength = TxSize + 8;
}
else if ((CipherSuite == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
{
// IV + EIV + ICV which ASIC added after encryption done
TxSize += 8;
PLCPLength = TxSize + 8;
}
else if ((CipherSuite == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL))
{
// IV + EIV + HW MIC
TxSize += 8;
PLCPLength = TxSize + 12;
}
else
{
PLCPLength = TxSize + 4;
}
DBGPRINT_RAW(RT_DEBUG_INFO, "TxSize = %d, PLCPLength = %d\n", TxSize, PLCPLength);//steven:for debug
// Prepare Tx descriptors before kicking tx.
// The BBP register index in Tx descriptor has to be configured too.
if (Header_802_11.Controlhead.Addr1.Octet[0] & 0x01)
{
INC_COUNTER(pAdapter->WlanCounters.MulticastTransmittedFrameCount);
// Multicast, retry bit is off
if (StartOfFrame == TRUE)
{
if (RTUSB_GET_PACKET_RTS(skb) != 1)
RTUSBWriteTxDescriptor(pTxD, FALSE, 0, FALSE, FALSE, TRUE, FrameGap, TxSize, Cipher, KeyID, CW_MIN_IN_BITS, CW_MAX_IN_BITS, PLCPLength, pAdapter->PortCfg.TxRate, 4, pAdapter->PortCfg.TxPreambleInUsed);
else
RTUSBWriteTxDescriptor(pTxD, FALSE, 0, FALSE, FALSE, TRUE, FrameGap, TxSize, Cipher, KeyID, 0, 0, PLCPLength, pAdapter->PortCfg.TxRate, 4, pAdapter->PortCfg.TxPreambleInUsed);
}
else
RTUSBWriteTxDescriptor(pTxD, FALSE, 0, FALSE, FALSE, FALSE, FrameGap, TxSize, Cipher, KeyID, 0, 0, PLCPLength, pAdapter->PortCfg.TxRate, 4, pAdapter->PortCfg.TxPreambleInUsed);
}
else
{
if (StartOfFrame == TRUE)
{
if (RTUSB_GET_PACKET_RTS(skb) != 1)
RTUSBWriteTxDescriptor(pTxD, MoreFragment, 7, TRUE, FALSE, TRUE, FrameGap, TxSize, Cipher, KeyID, CW_MIN_IN_BITS, CW_MAX_IN_BITS, PLCPLength, pAdapter->PortCfg.TxRate, 4, pAdapter->PortCfg.TxPreambleInUsed);
else
RTUSBWriteTxDescriptor(pTxD, MoreFragment, 7, TRUE, FALSE, TRUE, FrameGap, TxSize, Cipher, KeyID, 0, 0, PLCPLength, pAdapter->PortCfg.TxRate, 4, pAdapter->PortCfg.TxPreambleInUsed);
}
else
RTUSBWriteTxDescriptor(pTxD, MoreFragment, 7, TRUE, FALSE, FALSE, FrameGap, TxSize, Cipher, KeyID, 0, 0, PLCPLength, pAdapter->PortCfg.TxRate, 4, pAdapter->PortCfg.TxPreambleInUsed);
}
TransferBufferLength = TxSize + sizeof(TXD_STRUC);
if ((TransferBufferLength % 2) == 1)//always bulk out even number of bytes
TransferBufferLength++;
if ((TransferBufferLength % pAdapter->BulkOutMaxPacketSize) == 0)
TransferBufferLength += 2;
pTxContext->BulkOutSize = TransferBufferLength;
RTUSB_SET_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_DATA_NORMAL);
// Set frame gap for the rest of fragment burst.
// It won't matter if there is only one fragment (single fragment frame).
StartOfFrame = FALSE;
NumberRequired--;
if (NumberRequired == 0)
{
pTxContext->LastOne = TRUE;
}
else
{
pTxContext->LastOne = FALSE;
}
//steven:use ASIC counters to derive this count instead INC_COUNTER(pAdapter->WlanCounters.TransmittedFragmentCount);
//
// Increase BulkOut stanby count.
//
atomic_inc(&pAdapter->TxCount);
} while (NumberRequired > 0);
#if 0
// Add duplicate 1mb broadcast frames
do
{
if ((pAdapter->PortCfg.TxRate != RATE_1) && (Bcast_8023 == TRUE) && (SingleFrag == TRUE))
{
PTX_CONTEXT pTmpContext;
PTXD_STRUC pTmpTxD;
ULONG DataOffset = 0;
pSrc = pTxContext->TransferBuffer->WirelessPacket;
//
// Check the offset of the original 802.3 data packet
//
if (CipherSuite == Ndis802_11EncryptionDisabled)
DataOffset = 0;
else if (CipherSuite == Ndis802_11Encryption1Enabled)
DataOffset += 4; //Add IV
else if (CipherSuite == Ndis802_11Encryption2Enabled)
DataOffset += 8; //Add EIV
else if (CipherSuite == Ndis802_11Encryption3Enabled)
DataOffset += 8; //Add EIV
// Check for DHCP & BOOTP protocol
if ((*(pSrc + 0x35 + DataOffset) != 0x44) || (*(pSrc + 0x37 + DataOffset) != 0x43))
{
//
// 2054 (hex 0806) for ARP datagrams
// if this packet is not ARP datagrams, then do nothing
// ARP datagrams will also be duplicate at 1mb broadcast frames
//
if (Protocol != 0x0806 )
break;
}
// Get the Tx Ring descriptor & Dma Buffer address
pTmpContext = &pAdapter->TxContext[pAdapter->NextTxIndex];
pDest = pTmpContext->TransferBuffer->WirelessPacket;
if (pTmpContext->InUse == TRUE)
break; //No available Tx Ring for Send 1mb broadcast frames.
// Increase & maintain Tx Ring Index
pAdapter->NextTxIndex++;
if (pAdapter->NextTxIndex >= TX_RING_SIZE)
{
pAdapter->NextTxIndex = 0;
}
//
// Reset LastOne Tx Ring descriptor
//
pTmpContext->InUse = TRUE;
pTmpContext->LastOne = TRUE;
pTmpTxD = &(pTmpContext->TransferBuffer->TxDesc);
//
// Duplicate TxD descriptor, and we will reset the its value later.
//
NdisMoveMemory(pTmpTxD, pTxD, sizeof(TXD_STRUC));
// Start coping data to new ring
NdisMoveMemory(pDest, pSrc, pTxContext->BulkOutSize);
pTmpContext->BulkOutSize = pTxContext->BulkOutSize;
RTUSBWriteTxDescriptor(pTmpTxD, FALSE, 7, TRUE, FALSE, FALSE, FrameGap, TxSize, Cipher, KeyID, 0, 0, PLCPLength, RATE_1, 4, pAdapter->PortCfg.TxPreambleInUsed);
//
// Increase BulkOut stanby count.
//
atomic_inc(&pAdapter->TxCount);
DBGPRINT(RT_DEBUG_TRACE, "Send 1M broadcast frame!\n");
}
} while (FALSE);
#endif
// Acknowledge protocol send complete of pending packet.
RTUSBFreeSkbBuffer(skb);
return (NDIS_STATUS_SUCCESS);
}
VOID RTUSBRxPacket(unsigned long data)
//VOID RTUSBRxPacket(purbb_t pUrb)
{
//PRT2570ADAPTER pAdapter = (PRT2570ADAPTER)data;
purbb_t pUrb = (purbb_t)data;
PRT2570ADAPTER pAdapter;
PRX_CONTEXT pRxContext;
PRXD_STRUC pRxD;
NDIS_STATUS Status;
PHEADER_802_11 pHeader;
PUCHAR pData;
PUCHAR pDestMac, pSrcMac;
UCHAR KeyIdx;
ULONG i;
UINT PacketSize = 0;
PUCHAR pEncap;
UCHAR LLC_Len[2];
UCHAR Header802_3[14];
PWPA_KEY pWpaKey = NULL;
// To indicate cipher used for this packet
NDIS_802_11_ENCRYPTION_STATUS Cipher;
struct sk_buff *skb;
PVOID pManage;
pRxContext= (PRX_CONTEXT)pUrb->context;
pAdapter = pRxContext->pAdapter;
if( RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS) )
return;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -