📄 rtusb_data.c
字号:
Note: ========================================================================*/VOID RTUSBRejectPendingPackets( IN PRT2570ADAPTER pAdapter){ DBGPRINT_RAW(RT_DEBUG_TRACE, "--->RejectPendingPackets\n"); NdisAcquireSpinLock(&pAdapter->SendTxWaitQueueLock); DBGPRINT_RAW(RT_DEBUG_TRACE, "Purge SendTxWaitQueue\n"); skb_queue_purge(&pAdapter->SendTxWaitQueue); 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 (pAdapter->PortCfg.BssType == BSS_MONITOR && pAdapter->PortCfg.MallowRFMONTx == TRUE) { pTxContext = &pAdapter->TxContext[pAdapter->NextTxIndex]; pTxContext->InUse = TRUE; pTxContext->LastOne = TRUE; pAdapter->NextTxIndex++; if (pAdapter->NextTxIndex >= TX_RING_SIZE) pAdapter->NextTxIndex = 0; pTxD = &(pTxContext->TransferBuffer->TxDesc); memset(pTxD, 0, sizeof(TXD_STRUC)); pDest = pTxContext->TransferBuffer->WirelessPacket; memcpy( pDest, skb->data, skb->len ); RTUSBWriteTxDescriptor(pTxD, FALSE, 0, FALSE, FALSE, TRUE, IFS_BACKOFF, skb->len, FALSE, 0, CW_MIN_IN_BITS, CW_MAX_IN_BITS, skb->len + 4, pAdapter->PortCfg.TxRate, 4, pAdapter->PortCfg.TxPreambleInUsed); TransferBufferLength = skb->len + sizeof(TXD_STRUC); if ((TransferBufferLength % 2) == 1) TransferBufferLength++; pTxContext->BulkOutSize = TransferBufferLength; atomic_inc(&pAdapter->TxCount); RTUSB_SET_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_DATA_FRAG); RTUSBFreeSkbBuffer(skb); return (NDIS_STATUS_SUCCESS); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -