📄 rtusb_data.c
字号:
} else if (CipherAlg == CIPHER_AES) { PUCHAR pTmp; pTmp = (PUCHAR) &Iv16; *pTmp = pKey->TxTsc[0]; *(pTmp + 1) = pKey->TxTsc[1]; *(pTmp + 2) = 0; *(pTmp + 3) = (pAd->PortCfg.DefaultKeyId << 6) | 0x20; Iv32 = *(PULONG)(&pKey->TxTsc[2]); memcpy(&pTxD->Iv, &Iv16, 4); // Copy IV memcpy(&pTxD->Eiv, &Iv32, 4); // Copy EIV INC_TX_TSC(pKey->TxTsc); // Increase TxTsc for next transmission } // // STEP 5.3 COPY 802.11 HEADER INTO 1ST DMA BUFFER // pDest = pWirelessPacket; memcpy(pDest, &Header_802_11, sizeof(Header_802_11)); pDest += sizeof(Header_802_11); // // Fragmentation is not allowed on multicast & broadcast // So, we need to used the MAX_FRAG_THRESHOLD instead of pAd->PortCfg.FragmentThreshold // otherwise if pSkb->len > pAd->PortCfg.FragmentThreshold then // packet will be fragment on multicast & broadcast. // // MpduRequired equals to 1 means this could be Aggretaion case. // if ((Header_802_11.Addr1[0] & 0x01) || MpduRequired == 1) { FreeMpduSize = MAX_FRAG_THRESHOLD - sizeof(Header_802_11) - LENGTH_CRC; } else { FreeMpduSize = pAd->PortCfg.FragmentThreshold - sizeof(Header_802_11) - LENGTH_CRC; }#if 0 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) { // copy QOS CONTROL bytes *pDest = (UserPriority & 0x0f) | pAd->PortCfg.AckPolicy[QueIdx]; *(pDest+1) = 0; pDest += 2; FreeMpduSize -= 2; if (pAd->PortCfg.AckPolicy[QueIdx] != NORMAL_ACK) { bAckRequired = FALSE; } }#endif // // STEP 5.4 COPY LLC/SNAP, CKIP MIC INTO 1ST DMA BUFFER ONLY WHEN THIS // MPDU IS THE 1ST OR ONLY FRAGMENT // if (Header_802_11.Frag == 0) { if (pExtraLlcSnapEncap) { if ((CipherAlg == CIPHER_TKIP_NO_MIC) && (pKey != NULL)) { // Calculate MSDU MIC Value RTMPCalculateMICValue(pAd, pSkb, pExtraLlcSnapEncap, pKey); } // Insert LLC-SNAP encapsulation memcpy(pDest, pExtraLlcSnapEncap, 6); pDest += 6; memcpy(pDest, pSrcBufVA + 12, 2); pDest += 2; pSrcBufVA += LENGTH_802_3; FreeMpduSize -= LENGTH_802_1_H; } else { if ((CipherAlg == CIPHER_TKIP_NO_MIC) && (pKey != NULL)) { // Calculate MSDU MIC Value RTMPCalculateMICValue(pAd, pSkb, pExtraLlcSnapEncap, pKey); } pSrcBufVA += LENGTH_802_3; } } // Start copying payload BytesCopied = 0; do { if (SrcBufLen >= FreeMpduSize) { // Copy only the free fragment size, and save the pointer // of current buffer descriptor for next fragment buffer. memcpy(pDest, pSrcBufVA, FreeMpduSize); BytesCopied += FreeMpduSize; pSrcBufVA += FreeMpduSize; pDest += FreeMpduSize; SrcBufLen -= FreeMpduSize; break; } else { // Copy the rest of this buffer descriptor pointed data // into ring buffer. memcpy(pDest, pSrcBufVA, SrcBufLen); BytesCopied += SrcBufLen; pDest += SrcBufLen; FreeMpduSize -= SrcBufLen; } // No more buffer descriptor // Add MIC value if needed //if ((pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && // (MICFrag == FALSE) && // (pKey != NULL)) if((CipherAlg == CIPHER_TKIP_NO_MIC) && (MICFrag == FALSE) && (pKey != NULL)) { // Fregment and TKIP// INT i; SrcBufLen = 8; // Set length to MIC length DBGPRINT(RT_DEBUG_INFO, "Calculated TX MIC value ="); for (i = 0; i < 8; i++) { DBGPRINT_RAW(RT_DEBUG_INFO, "%02x:", pAd->PrivateInfo.Tx.MIC[i]); } DBGPRINT_RAW(RT_DEBUG_INFO, "\n"); if (FreeMpduSize >= SrcBufLen) { memcpy(pDest, pAd->PrivateInfo.Tx.MIC, SrcBufLen); BytesCopied += SrcBufLen; pDest += SrcBufLen; FreeMpduSize -= SrcBufLen; SrcBufLen = 0; } else { memcpy(pDest, pAd->PrivateInfo.Tx.MIC, FreeMpduSize); BytesCopied += FreeMpduSize; pSrcBufVA = pAd->PrivateInfo.Tx.MIC + FreeMpduSize; pDest += FreeMpduSize; SrcBufLen -= FreeMpduSize; MICFrag = TRUE; } } } while (FALSE); // End of copying payload // Real packet size, No 802.1H header for fragments except the first one. if ((StartOfFrame == TRUE) && (pExtraLlcSnapEncap != NULL)) { TxSize = BytesCopied + LENGTH_802_11 + LENGTH_802_1_H + LengthQosPAD; } else { TxSize = BytesCopied + LENGTH_802_11 + LengthQosPAD; } SrcRemainingBytes -= BytesCopied; // // STEP 5.6 MODIFY MORE_FRAGMENT BIT & DURATION FIELD. WRITE TXD // pHeader80211 = (PHEADER_802_11)pWirelessPacket; if (SrcRemainingBytes > 0) // more fragment is required { ULONG NextMpduSize; pHeader80211->FC.MoreFrag = 1; NextMpduSize = min((ULONG)SrcRemainingBytes, (ULONG)pAd->PortCfg.FragmentThreshold); if (NextMpduSize < pAd->PortCfg.FragmentThreshold) { // In this case, we need to include LENGTH_802_11 and LENGTH_CRC for calculating Duration. pHeader80211->Duration = (3 * pAd->PortCfg.Dsifs) + (2 * AckDuration) + RTMPCalcDuration(pAd, TxRate, NextMpduSize + EncryptionOverhead + LENGTH_802_11 + LENGTH_CRC); } else { pHeader80211->Duration = (3 * pAd->PortCfg.Dsifs) + (2 * AckDuration) + RTMPCalcDuration(pAd, TxRate, NextMpduSize + EncryptionOverhead); }#ifdef BIG_ENDIAN RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_WRITE, FALSE); RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); *pDestTxD = TxD; pTxD = pDestTxD;#endif RTUSBWriteTxDescriptor(pAd, pTxD, CipherAlg, 0, KeyIdx, bAckRequired, TRUE, FALSE, RetryMode, FrameGap, TxRate, TxSize, QueIdx, 0, bRTS_CTSFrame); FrameGap = IFS_SIFS; // use SIFS for all subsequent fragments Header_802_11.Frag ++; // increase Frag # } else { pHeader80211->FC.MoreFrag = 0; if (pHeader80211->Addr1[0] & 0x01) // multicast/broadcast pHeader80211->Duration = 0; else pHeader80211->Duration = pAd->PortCfg.Dsifs + AckDuration; if ((bEAPOLFrame) && (TxRate > RATE_6)) TxRate = RATE_6;#ifdef BIG_ENDIAN RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_WRITE, FALSE); RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); *pDestTxD = TxD; pTxD = pDestTxD;#endif RTUSBWriteTxDescriptor(pAd, pTxD, CipherAlg, 0, KeyIdx, bAckRequired, FALSE, FALSE, RetryMode, FrameGap, TxRate, TxSize, QueIdx, 0, bRTS_CTSFrame); if (skb_queue_len(&pAd->SendTxWaitQueue[QueIdx]) > 1) pTxD->Burst = 1; } TransferBufferLength = TxSize + sizeof(TXD_STRUC); if ((TransferBufferLength % 4) == 1) TransferBufferLength += 3; else if ((TransferBufferLength % 4) == 2) TransferBufferLength += 2; else if ((TransferBufferLength % 4) == 3) TransferBufferLength += 1; if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0) TransferBufferLength += 4; pTxContext->BulkOutSize = TransferBufferLength; pTxContext->bWaitingBulkOut = TRUE; RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); // 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; } pAd->TxRingTotalNumber[QueIdx]++; // sync. to PendingTx } while (NumberRequired > 0); // // Check if MIC error twice within 60 seconds and send EAPOL MIC error to TX queue // then we enqueue a message for disasociating with the current AP // // Check for EAPOL frame sent after MIC countermeasures if (pAd->PortCfg.MicErrCnt >= 3) { MLME_DISASSOC_REQ_STRUCT DisassocReq; // disassoc from current AP first DBGPRINT(RT_DEBUG_INFO, "- (%s) disassociate with current AP after" " sending second continuous EAPOL frame\n", __FUNCTION__); DisassocParmFill(pAd, &DisassocReq, pAd->PortCfg.Bssid, REASON_MIC_FAILURE); MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; pAd->PortCfg.bBlockAssoc = TRUE; } // release the skb buffer RELEASE_NDIS_PACKET(pAd, pSkb); return (NDIS_STATUS_SUCCESS);}/* ======================================================================== Routine Description: Copy frame from waiting queue into relative ring buffer and set appropriate ASIC register to kick hardware transmit function Arguments: pAd Pointer to our adapter pBuffer Pointer to memory of outgoing frame Length Size of outgoing management frame Return Value: NDIS_STATUS_FAILURE NDIS_STATUS_PENDING NDIS_STATUS_SUCCESS Note: ========================================================================*/VOID RTUSBMlmeHardTransmit( IN PRTMP_ADAPTER pAd, IN PMGMT_STRUC pMgmt){ PTX_CONTEXT pMLMEContext; PTXD_STRUC pTxD;#ifdef BIG_ENDIAN PTXD_STRUC pDestTxD; TXD_STRUC TxD;#endif PUCHAR pDest; PHEADER_802_11 pHeader_802_11; BOOLEAN AckRequired, InsertTimestamp; ULONG TransferBufferLength; PVOID pBuffer = pMgmt->pBuffer; ULONG Length = pMgmt->Length; UCHAR QueIdx; UCHAR MlmeRate; unsigned long flags; // For 'Ndis' spin lock DBGPRINT(RT_DEBUG_INFO, "--->MlmeHardTransmit\n"); pAd->PrioRingTxCnt++; pMLMEContext = &pAd->MLMEContext[pAd->NextMLMEIndex]; pMLMEContext->InUse = TRUE; // Increase & maintain Tx Ring Index pAd->NextMLMEIndex++; if (pAd->NextMLMEIndex >= PRIO_RING_SIZE) { pAd->NextMLMEIndex = 0; } pDest = pMLMEContext->TransferBuffer->WirelessPacket;#ifndef BIG_ENDIAN pTxD = (PTXD_STRUC)(pMLMEContext->TransferBuffer);#else pDestTxD = (PTXD_STRUC)(pMLMEContext->TransferBuffer); TxD = *pDestTxD; pTxD = &TxD; RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);#endif memset(pTxD, 0, sizeof(TXD_STRUC)); pHeader_802_11 = (PHEADER_802_11) pBuffer; // Verify Mlme rate for a / g bands. if (pHeader_802_11->Addr1[0] & 0x01) { MlmeRate = pAd->PortCfg.BasicMlmeRate; } else { MlmeRate = pAd->PortCfg.MlmeRate; } if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band MlmeRate = RATE_6; DBGPRINT(RT_DEBUG_INFO, "- %s: Rate %d Channel %d\n", __FUNCTION__, MlmeRate, pAd->LatchRfRegs.Channel ); // Before radar detection done, mgmt frame can not be sent but probe req // Because we need to use probe req to trigger driver to send probe req in passive scan if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ) && (pAd->PortCfg.bIEEE80211H == 1) && (pAd->PortCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) { DBGPRINT(RT_DEBUG_ERROR, "RTUSBMlmeHardTransmit --> radar detect not in normal mode !!!\n"); return; } if (pHeader_802_11->FC.PwrMgmt != PWR_SAVE) { pHeader_802_11->FC.PwrMgmt = (pAd->PortCfg.Psm == PWR_SAVE); } InsertTimestamp = FALSE; if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL { AckRequired = FALSE; } else // BTYPE_MGMT or BMGMT_DATA(must be NULL frame) { pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER); pHeader_802_11->Sequence = pAd->Sequence; if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST { INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount); AckRequired = FALSE; pHeader_802_11->Duration = 0; } else { AckRequired = TRUE; pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14); if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) { InsertTimestamp = TRUE; } } } memcpy(pDest, pBuffer, Length); // Initialize Priority Descriptor // For inter-frame gap, the number is for this frame and next frame // For MLME rate, we will fix as 2Mb to match other vendor's implement QueIdx = QID_AC_BE;#ifdef BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); *pDestTxD = TxD; pTxD = pDestTxD;#endif RTUSBWriteTxDescriptor(pAd, pTxD, CIPHER_NONE, 0,0, AckRequired, FALSE, FALSE, SHORT_RETRY, IFS_BACKOFF, MlmeRate, /*Length+4*/ Length, QueIdx, PID_MGMT_FRAME, FALSE); // Build our URB for USBD TransferBufferLength = sizeof(TXD_STRUC) + Length; if ((TransferBufferLength % 2) == 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -