?? rtusb_data.c
字號:
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
VOID RTUSBRejectPendingPackets(
IN PRT2570ADAPTER pAdapter)
{
PQUEUE_HEADER pQueue = &(pAdapter->SendTxWaitQueue);
struct sk_buff *skb;
DBGPRINT_RAW(RT_DEBUG_TRACE, "--->RejectPendingPackets\n");
NdisAcquireSpinLock(&pAdapter->SendTxWaitQueueLock);
while (pAdapter->SendTxWaitQueue.Head != NULL)
{
DBGPRINT_RAW(RT_DEBUG_TRACE, " Remove 1 from SendTxWaitQueue\n");
skb = (struct sk_buff *)RemoveHeadQueue(pQueue);
RTUSBFreeSkbBuffer(skb);
}
NdisReleaseSpinLock(&pAdapter->SendTxWaitQueueLock);
DBGPRINT_RAW(RT_DEBUG_TRACE, "<---RejectPendingPackets\n");
}
/*
========================================================================
Routine Description:
Suspend MSDU transmission
Arguments:
pAdapter Pointer to our adapter
Return Value:
None
Note:
========================================================================
*/
VOID RTUSBSuspendMsduTransmission(
IN PRT2570ADAPTER pAdapter)
{
DBGPRINT(RT_DEBUG_TRACE,"SCANNING, suspend MSDU transmission ...\n");
RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
}
/*
========================================================================
Routine Description:
Resume MSDU transmission
Arguments:
pAdapter Pointer to our adapter
Return Value:
None
Note:
========================================================================
*/
VOID RTUSBResumeMsduTransmission(
IN PRT2570ADAPTER pAdapter)
{
DBGPRINT(RT_DEBUG_TRACE,"SCANNING, resume MSDU transmission ...\n");
RTMP_CLEAR_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS)) &&
(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF)))
{
// Call dequeue without selected queue, let the subroutine select the right priority
// Tx software queue
RTUSBDeQueuePacket(pAdapter);
}
// Kick bulk out
RTUSBKickBulkOut(pAdapter);
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
USHORT RTUSBCalcDuration(
IN PRT2570ADAPTER pAdapter,
IN UCHAR Rate,
IN ULONG Size)
{
ULONG Duration = 0;
if (Rate < RATE_FIRST_OFDM_RATE) // CCK
{
if ((Rate > RATE_1) && (pAdapter->PortCfg.TxPreambleInUsed == Rt802_11PreambleShort))
Duration = 96; // 72+24 preamble+plcp
else
Duration = 192; // 144+48 preamble+plcp
Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
if ((Size << 4) % RateIdTo500Kbps[Rate])
Duration ++;
}
else // OFDM rates
{
Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
Duration += 4;
}
return (USHORT)Duration;
}
/*
========================================================================
Routine Description:
Calculates the duration which is required to transmit out frames
with given size and specified rate.
Arguments:
pTxD Pointer to transmit descriptor
Ack Setting for Ack requirement bit
Fragment Setting for Fragment bit
RetryMode Setting for retry mode
Ifs Setting for IFS gap
Rate Setting for transmit rate
Service Setting for service
Length Frame length
Return Value:
None
========================================================================
*/
VOID RTUSBWriteTxDescriptor(
IN PTXD_STRUC pTxD,
IN BOOLEAN Fragment,
IN UCHAR RetryLimit,
IN BOOLEAN Ack,
IN BOOLEAN InsTimestamp,
IN BOOLEAN new_seq,
IN UCHAR Ifs,
IN UINT Length,
IN BOOLEAN Cipher,
IN UCHAR KeyID,
IN UCHAR CWMin,
IN UCHAR CWMax,
IN UINT PLCPLength,
IN UINT Rate,
IN UCHAR Service,
IN USHORT TxPreamble)
{
UINT Residual;
pTxD->RetryLimit = RetryLimit;
pTxD->MoreFrag = Fragment;
pTxD->ACK = Ack;
pTxD->Timestamp = InsTimestamp;
pTxD->newseq = new_seq;
pTxD->IFS = Ifs;
pTxD->DataByteCnt = Length;
pTxD->Cipher = Cipher;
pTxD->KeyID = KeyID;
pTxD->CWmin = CWMin; // 2^5-1 = 31
pTxD->CWmax = CWMax; // 2^10 -1 = 1023
pTxD->Aifs = 2; // TC0: SIFS + 2*Slot + Random(CWmin,CWmax)*Slot
if (Rate < RATE_FIRST_OFDM_RATE)
pTxD->Ofdm = 0;
else
pTxD->Ofdm = 1;
// fill up PLCP SIGNAL field
pTxD->PlcpSignal = PlcpSignal[Rate];
if (((Rate == RATE_2) || (Rate == RATE_5_5) || (Rate == RATE_11)) && (TxPreamble == Rt802_11PreambleShort)) // no short preamble for RATE_1
{
pTxD->PlcpSignal |= 0x0008;
}
// fill up PLCP SERVICE field, not used for OFDM rates
pTxD->PlcpService = Service;
// file up PLCP LENGTH_LOW and LENGTH_HIGH fields
if (Rate < RATE_FIRST_OFDM_RATE) // 11b - RATE_1, RATE_2, RATE_5_5, RATE_11
{
if ((Rate == RATE_1) || ( Rate == RATE_2))
{
PLCPLength = PLCPLength * 8 / (Rate + 1);
}
else
{
Residual = ((PLCPLength * 16) % (11 * (1 + Rate - RATE_5_5)));
PLCPLength = PLCPLength * 16 / (11 * (1 + Rate - RATE_5_5));
if (Residual != 0)
{
PLCPLength++;
}
if (Rate == RATE_11)
{
if ((Residual <= (3 * (1 + Rate - RATE_5_5))) && (Residual != 0))
{
pTxD->PlcpService |= 0x80; // 11b's PLCP Length extension bit
}
}
}
pTxD->PlcpLengthHigh = PLCPLength / 256;
pTxD->PlcpLengthLow = PLCPLength % 256;
}
else // OFDM - RATE_6, RATE_9, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48, RATE_54
{
pTxD->PlcpLengthHigh = PLCPLength / 64; // high 6-bit of total byte count
pTxD->PlcpLengthLow = PLCPLength % 64; // low 6-bit of total byte count
}
}
/*
========================================================================
Routine Description:
Calculates the duration which is required to transmit out frames
with given size and specified rate.
Arguments:
pTxD Pointer to transmit descriptor
Ack Setting for Ack requirement bit
Fragment Setting for Fragment bit
RetryMode Setting for retry mode
Ifs Setting for IFS gap
Rate Setting for transmit rate
Service Setting for service
Length Frame length
Return Value:
None
========================================================================
*/
VOID RTUSBWriteBeaconDescriptor(
IN PTXD_STRUC pTxD,
IN UINT Length,
IN UINT PLCPLength,
IN UINT Rate,
IN UCHAR Service,
IN USHORT TxPreamble)
{
UINT Residual;
pTxD->RetryLimit = 0;
pTxD->MoreFrag = 0;
pTxD->ACK = 0;
pTxD->Timestamp = 1;
pTxD->newseq = 1;
pTxD->IFS = IFS_NEW_BACKOFF;
pTxD->DataByteCnt = Length;
pTxD->Cipher = 0;
pTxD->KeyID = 0;
pTxD->CWmin = BEACON_CW_IN_BITS; // 2^5-1 = 31
pTxD->CWmax = BEACON_CW_IN_BITS; // 2^10 -1 = 1023
pTxD->Aifs = 2; // TC0: SIFS + 2*Slot + Random(CWmin,CWmax)*Slot
if (Rate < RATE_FIRST_OFDM_RATE)
pTxD->Ofdm = 0;
else
pTxD->Ofdm = 1;
// fill up PLCP SIGNAL field
pTxD->PlcpSignal = PlcpSignal[Rate];
if (((Rate == RATE_2) || (Rate == RATE_5_5) || (Rate == RATE_11)) && (TxPreamble == Rt802_11PreambleShort)) // no short preamble for RATE_1
{
pTxD->PlcpSignal |= 0x0008;
}
// fill up PLCP SERVICE field, not used for OFDM rates
pTxD->PlcpService = Service;
// file up PLCP LENGTH_LOW and LENGTH_HIGH fields
if (Rate < RATE_FIRST_OFDM_RATE) // 11b - RATE_1, RATE_2, RATE_5_5, RATE_11
{
if ((Rate == RATE_1) || ( Rate == RATE_2))
{
PLCPLength = PLCPLength * 8 / (Rate + 1);
}
else
{
Residual = ((PLCPLength * 16) % (11 * (1 + Rate - RATE_5_5)));
PLCPLength = PLCPLength * 16 / (11 * (1 + Rate - RATE_5_5));
if (Residual != 0)
{
PLCPLength++;
}
if ((Residual <= (3 * (1 + Rate - RATE_5_5))) && (Residual != 0))
{
pTxD->PlcpService |= 0x80; // 11b's PLCP Length extension bit
}
}
pTxD->PlcpLengthHigh = PLCPLength / 256;
pTxD->PlcpLengthLow = PLCPLength % 256;
}
else // OFDM - RATE_6, RATE_9, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48, RATE_54
{
pTxD->PlcpLengthHigh = PLCPLength / 64; // high 6-bit of total byte count
pTxD->PlcpLengthLow = PLCPLength % 64; // low 6-bit of total byte count
}
}
/*
========================================================================
Routine Description:
Copy frame from waiting queue into relative ring buffer and set
appropriate ASIC register to kick hardware encryption before really
sent out to air.
Arguments:
pAdapter Pointer to our adapter
PNDIS_PACKET Pointer to outgoing Ndis frame
NumberOfFrag Number of fragment required
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
NDIS_STATUS RTUSBHardEncrypt(
IN PRT2570ADAPTER pAdapter,
IN struct sk_buff *skb,
IN UCHAR NumberRequired,
IN ULONG EnableTxBurst)
{
PVOID pVirtualAddress;
UINT NdisBufferLength;
UINT BytesCopied;
UINT TxSize, PLCPLength;
UINT FreeFragSize;
UINT RemainSize;
USHORT Protocol;
UCHAR FrameGap;
HEADER_802_11 Header_802_11;
PUCHAR pDest;
PUCHAR pSrc;
PUCHAR pEncap = NULL;
PTX_CONTEXT pTxContext;
PTXD_STRUC pTxD;
BOOLEAN StartOfFrame;
BOOLEAN EAPOLFrame;
BOOLEAN Encapped;
ULONG Iv16;
ULONG Iv32;
BOOLEAN MICFrag;
PWPA_KEY pWpaKey = (PWPA_KEY) NULL;
BOOLEAN Cipher;
UCHAR KeyID = 0;
ULONG TransferBufferLength;
BOOLEAN MoreFragment;
UCHAR AckRate = RATE_2;
USHORT AckDuration = 0;
USHORT EncryptionOverhead = 0;
BOOLEAN Bcast_8023;
BOOLEAN SingleFrag;
//for re-calculating the number of Fragment required.
UINT AllowFragSize;
UCHAR NumberOfFrag;
UINT TotalPacketLength;
// To indicate cipher used for this packet
NDIS_802_11_ENCRYPTION_STATUS CipherSuite;
CipherSuite = pAdapter->PortCfg.WepStatus;
if (EnableTxBurst == 1)
FrameGap = IFS_SIFS;
else
FrameGap = IFS_BACKOFF; // Default frame gap mode
// Sequence Number is identical for all fragments belonged to the same frame
// Sequence is 0 - 4095
pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
AckRate = pAdapter->PortCfg.ExpectedACKRate[pAdapter->PortCfg.TxRate];
AckDuration = RTUSBCalcDuration(pAdapter, AckRate, 14);
pVirtualAddress = skb->data;
NdisBufferLength = skb->len;
if(pVirtualAddress == NULL)
{
DBGPRINT(RT_DEBUG_ERROR, "Error, Null skb data buffer!!!\n");
return (NDIS_STATUS_FAILURE);
}
if (NdisBufferLength < 14)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -