diff options
| author | karlf <[email protected]> | 2016-08-11 13:28:13 -0700 |
|---|---|---|
| committer | karlf <[email protected]> | 2016-08-11 13:28:13 -0700 |
| commit | 96eb96dfb613e4c745db6bd1f53a92fe7e2290fc (patch) | |
| tree | ad5f3ede5cbcd6b598677ce41bcf8318471bdd92 /network/wlan/WDI/COMMON/Transmit.c | |
| parent | 687b274aa38fd05c8c26e3068932121876d7f745 (diff) | |
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'network/wlan/WDI/COMMON/Transmit.c')
| -rw-r--r-- | network/wlan/WDI/COMMON/Transmit.c | 3800 |
1 files changed, 0 insertions, 3800 deletions
diff --git a/network/wlan/WDI/COMMON/Transmit.c b/network/wlan/WDI/COMMON/Transmit.c deleted file mode 100644 index 226b7a1a..00000000 --- a/network/wlan/WDI/COMMON/Transmit.c +++ /dev/null @@ -1,3800 +0,0 @@ -#include "Mp_Precomp.h" - -#if WPP_SOFTWARE_TRACE -#include "Transmit.tmh" -#endif - -#define RT_PS_TX_STATUS u4Byte -#define RT_PS_TX_STATUS_SEND_PKT 0 -#define RT_PS_TX_STATUS_PKT_BUFFERED 1 -#define RT_PS_TX_STATUS_PKT_DROPPED 2 - - -RT_PS_TX_STATUS -VerifyPsOnTx( - PADAPTER pAdapter, - PRT_TCB pTcb - ) -{ - PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo); - RT_PS_TX_STATUS txPsStauts = RT_PS_TX_STATUS_SEND_PKT; - OCTET_STRING osMpdu; - pu1Byte pRaddr; - - FillOctetString(osMpdu, GET_FRAME_OF_FIRST_FRAG(pAdapter, pTcb), (u2Byte)pTcb->BufferList[0].Length); - - if(TEST_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_PS_PRE_TRANSMIT)) - { - CLEAR_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_PS_PRE_TRANSMIT); - PreTransmitTCB(pAdapter, pTcb); - return RT_PS_TX_STATUS_PKT_BUFFERED; - } - - if(!IsDataFrame(osMpdu.Octet)) - return txPsStauts; - - pRaddr = Frame_pRaddr(osMpdu); - - if(ACTING_AS_AP(pAdapter)) - { - if( !MacAddr_isMulticast(pRaddr) ) - { // Unicast. - PRT_WLAN_STA pEntry = AsocEntry_GetEntry(pMgntInfo, pRaddr); - - // No entry. - if(pEntry == NULL) - { - // Prefast warning C6011 : Dereferencing NULL pointer 'pEntry'. - //RT_PRINT_ADDR(COMP_AP, DBG_LOUD, "[WARNING] VerifyPsOnTx(): No Entry for client = ", pEntry->MacAddr); - RT_TRACE(COMP_AP, DBG_LOUD, ("[WARNING] VerifyPsOnTx(): No Entry for client!\n")); - return txPsStauts; - } - - // Queue the unicast packet if dest STA is in power-save mode. - if(pEntry->bPowerSave) - { - BOOLEAN bEospPkt = FALSE; - BOOLEAN bUAPSD = FALSE; - if(IsQoSDataFrame(osMpdu.Octet)) - { - // Check the UP for this packet and the UAPSD info from the assoication. - switch( GET_QOS_CTRL_WMM_UP(osMpdu.Octet) ) - { - case 0: - case 3: - bUAPSD = GET_BE_UAPSD(pEntry->WmmStaQosInfo); - break; - case 1: - case 2: - bUAPSD = GET_BK_UAPSD(pEntry->WmmStaQosInfo); - break; - case 4: - case 5: - bUAPSD = GET_VI_UAPSD(pEntry->WmmStaQosInfo); - break; - case 6: - case 7: - bUAPSD = GET_VO_UAPSD(pEntry->WmmStaQosInfo); - break; - } - } - bEospPkt = GET_QOS_CTRL_WMM_EOSP(osMpdu.Octet); - - if(bUAPSD) - { - if(bEospPkt) - { - // It's an ESOP packet, we shall send it. - } - else if(pEntry->WmmEosp != RT_STA_EOSP_STATE_OPENED || !RTIsListEmpty(&(pEntry->WmmPsQueue))) - { - // - // If the packets from the upper layer are queued, such as ping, the protocol layer or the socket - // will block the packets sent until these queued packets are returned. It causes the ping rate with - // large packet size low and fail in the P2P Test item 6.1.12/6.1.13/7.1.5. - // To speed up the sending rate of packets, we copy the system packet to local buffer and indicate - // to os (Ndis) as early. - // By Bruce, 2010-10-15. - // - TCB_CopySystemPacketToLocal(pAdapter, pTcb); - // The SP is ended or the WmmPsQueue is not empty, the following packets shall be queued. - RT_PRINT_ADDR(COMP_AP, DBG_LOUD, "VerifyPsOnTx(): Queue ps pkt for wmm client = ", pEntry->MacAddr); - RTInsertTailList(&(pEntry->WmmPsQueue), &(pTcb->List)); - txPsStauts = RT_PS_TX_STATUS_PKT_BUFFERED; - } - else - { // We can send packet immediately because the service period is opend. - BOOLEAN bSupportTxFeedback = FALSE; - - // Check if this chip supports per tx packet feedback. - bSupportTxFeedback = TxFeedbackInstallTxFeedbackInfoForTcb(pAdapter, pTcb); - - if(bSupportTxFeedback) - { - TxFeedbackFillTxFeedbackInfoUserConfiguration( - pTcb, - RT_TX_FEEDBACK_ID_AP_WMM_EOSP_ENDING, - pAdapter, - Ap_PsTxFeedbackCallback, - (PVOID) pEntry - ); - } - - if(bSupportTxFeedback) - pEntry->WmmEosp = RT_STA_EOSP_STATE_ENDING; - else - pEntry->WmmEosp = RT_STA_EOSP_STATE_ENDED; - - SET_QOS_CTRL_WMM_EOSP(osMpdu.Octet, 1); - RT_PRINT_ADDR(COMP_AP, DBG_LOUD, "VerifyPsOnTx(): Send packet directly wmm open client = ", pEntry->MacAddr); - } - } - else - { - if(TEST_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_PS_REPLY_PS_POLL)) - { // This packet is polled by ps-poll, we shoud send it immediately. - if(!RTIsListEmpty(&(pEntry->PsQueue))) - { // There are still packets queued in the queue, set the more data bit. - SET_80211_HDR_MORE_DATA(osMpdu.Octet, 1); - } - CLEAR_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_PS_REPLY_PS_POLL); - } - else - { - // Legacy PS. - // RT_PRINT_ADDR(COMP_AP, DBG_LOUD, "VerifyPsOnTx(): Queue ps pkt for legacy client = ", pEntry->MacAddr); - RTInsertTailList(&(pEntry->PsQueue), &(pTcb->List)); - txPsStauts = RT_PS_TX_STATUS_PKT_BUFFERED; - } - } - } - } - else - { // Bcst/Mcst. - if(TEST_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_PS_MCAST_DTIM)) - { // DTIM - if(!RTIsListEmpty(&(pMgntInfo->GroupPsQueue))) - { // There are still packets queued in the queue, set the more data bit. - SET_80211_HDR_MORE_DATA(osMpdu.Octet, 1); - } - CLEAR_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_PS_MCAST_DTIM); - } - // Queue the Mcst/Bcst packet if one ore more STA is in power-save mode. - else if(pMgntInfo->PowerSaveStationNum > 0) - { - // RT_TRACE_F(COMP_AP, DBG_LOUD, ("Queue Mcst/Bcst pkt\n")); - RTInsertTailList(&(pMgntInfo->GroupPsQueue), &(pTcb->List)); - txPsStauts = RT_PS_TX_STATUS_PKT_BUFFERED; - } - } - } - else - { - PRT_WLAN_STA pTDLSPsEntry=TDLS_PS_CheckPsTx(pAdapter, pTcb); - - if(pTDLSPsEntry!=NULL) - { - if(TDLS_PS_OnTx(pAdapter, pTDLSPsEntry, pTcb)) - txPsStauts = RT_PS_TX_STATUS_PKT_BUFFERED; - - return txPsStauts; - } - - // Set PwrMgnt bit, by Bruce, 2007-11-09. - //RT_PRINT_DATA(COMP_MLME, DBG_LOUD, "packet:\n", osMpdu.Octet, osMpdu.Length); - SET_80211_HDR_PWR_MGNT(osMpdu.Octet, MgntGetPwrMgntInfo(pAdapter, pTcb, TRUE)); - // - // Move from PreTransmitTCB() becsauce the TCBs in the wait queues sent without passing - // through PreTransmitTCB(). - // Only those packets without pwr mgnt bit set are considered as sent in awake - // By Bruce, 2008-01-18. - // - if(!GET_80211_HDR_PWR_MGNT(osMpdu.Octet)) - pMgntInfo->bAwakePktSent = TRUE; - if(pMgntInfo->mPss != eAwake) - { - do - { - // Note, if the NULL frame without pwr mgnt bit set, the packet still should be inserted into the queue. - if(IsMgntNullFrame(osMpdu.Octet) && GET_80211_HDR_PWR_MGNT(osMpdu.Octet)) - break; - - if(IN_LEGACY_POWER_SAVE(pMgntInfo->pStaQos)) - LPS_OnTx(pAdapter, pTcb); - else - WMMPS_OnTx(pAdapter, pTcb); - txPsStauts = RT_PS_TX_STATUS_PKT_BUFFERED; - }while(FALSE); - } - else - { - // - // If we have sent the trigger frame of the current APSD, set up service period to remain awake. By Bruce, 2007-11-15. - // - if(!IN_LEGACY_POWER_SAVE(pMgntInfo->pStaQos)) - { - if(IsStaQosTriggerFrame(&osMpdu, pMgntInfo->pStaQos->Curr4acUapsd)) - { - pMgntInfo->pStaQos->bInServicePeriod = TRUE; - } - } - } - } - - /* - if(txPsStauts == RT_PS_TX_STATUS_SEND_PKT) - { - // Set PwrMgnt bit, by Bruce, 2007-11-09. - SET_80211_HDR_PWR_MGNT(osMpdu.Octet, MgntGetPwrMgntInfo(pAdapter, pTcb, TRUE)); - - // - // Move from PreTransmitTCB() becsauce the TCBs in the wait queues sent without passing - // through PreTransmitTCB(). - // Only those packets without pwr mgnt bit set are considered as sent in awake - // By Bruce, 2008-01-18. - // - if(!GET_80211_HDR_PWR_MGNT(osMpdu.Octet)) - pMgntInfo->bAwakePktSent = TRUE; - } - */ - - return txPsStauts; -} - - - - -VOID -InitializeTxVariables( - PADAPTER Adapter - ) -{ - u2Byte i; - BOOLEAN bSupportEarlyMode; - - // Initialize each queue with the same number of TxDesc, - // except for BEACON_QUEUE. 2005.11.14, by rcnjko. - for(i = 0; i < MAX_TX_QUEUE;i++) - { - Adapter->NumTxDesc[i] = Adapter->RT_TXDESC_NUM; - } - // TODO: Emily 2006.11.15. If we are implmemting multiple BSSID feature, more - // TODO: than two descriptors may be required. - Adapter->NumTxDesc[BEACON_QUEUE] = 2; // BEACON_QUEUE - Adapter->NumTxDesc[BE_QUEUE] = Adapter->RT_TXDESC_NUM_BE_QUEUE; // BE queue need more descriptor for performance consideration - - Adapter->NumTcb = Adapter->RT_TCB_NUM; - Adapter->NumLocalBuffer = Adapter->RT_LOCAL_BUF_NUM; - Adapter->NumLocalFWBuffer = Adapter->RT_LOCAL_FW_BUF_NUM; - - - bSupportEarlyMode = FALSE; - Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_EARLY_MODE_SUPPORT, (pu1Byte)(&bSupportEarlyMode)); - if(bSupportEarlyMode) - { - Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_EARLY_MODE_THRESHOLD, &(Adapter->EarlyMode_Threshold)); - for(i=0 ; i<8 ; i++) - Adapter->EarlyMode_QueueNum[i] = 0; - - } - - RTInitializeListHead(&Adapter->TcbIdleQueue); - for(i=0;i<MAX_TX_QUEUE;i++) - { - RTInitializeListHead(&Adapter->TcbWaitQueue[i]); - RTInitializeListHead(&Adapter->TcbBusyQueue[i]); - RTInitializeListHead(&Adapter->TcbAggrQueue[i]); - Adapter->TcbCountInAggrQueue[i] = 0; - } - RTInitializeListHead(&Adapter->LocalBufferQueue); - RTInitializeListHead(&Adapter->LocalFWBufferQueue); - - ResetTxStatistics(Adapter); - -} - -RT_STATUS -PrepareTCBs( - PADAPTER Adapter - ) -{ - u2Byte i,j; - PRT_TCB pTcb; - PRT_TX_LOCAL_BUFFER pLocalBuffer; - RT_STATUS status; - u4Byte BufferLength,offset; - BufferLength = MAX_LLC_LENGTH + - MAX_802_11_HEADER_LENGTH*MAX_FRAGMENT_COUNT + - MAX_802_11_TRAILER_LENGTH + - MAX_FIRMWARE_INFORMATION_SIZE + - AMSDU_SUBHEADER_LENGTH; - do{ - //2 Allocate TCBs - Adapter->TcbBuffer.Length=Adapter->NumTcb*sizeof(RT_TCB); - status=PlatformAllocateMemory(Adapter, &Adapter->TcbBuffer.Ptr,Adapter->TcbBuffer.Length); - if(status!=RT_STATUS_SUCCESS) - return status; - - PlatformZeroMemory(Adapter->TcbBuffer.Ptr,Adapter->TcbBuffer.Length); - - pTcb=(PRT_TCB)Adapter->TcbBuffer.Ptr; - for(i=0;i<Adapter->NumTcb;i++) - { - status = PlatformAllocateSharedMemory(Adapter, &pTcb[i].Buffer, BufferLength); - if(status!=RT_STATUS_SUCCESS) - return status; - PlatformZeroMemory(pTcb[i].Buffer.VirtualAddress , BufferLength); - - GET_SHARED_MEMORY_WITH_OFFSET( - &pTcb[i].Buffer, - &pTcb[i].LLC, - 0, - MAX_LLC_LENGTH); - offset=MAX_LLC_LENGTH; - for(j=0;j<MAX_FRAGMENT_COUNT;j++) - { - GET_SHARED_MEMORY_WITH_OFFSET( - &pTcb[i].Buffer, - &pTcb[i].Header[j], - offset, - MAX_802_11_HEADER_LENGTH); - offset += MAX_802_11_HEADER_LENGTH; - } - GET_SHARED_MEMORY_WITH_OFFSET( - &pTcb[i].Buffer, - &pTcb[i].Tailer, - offset, - MAX_802_11_TRAILER_LENGTH); - offset+=MAX_802_11_TRAILER_LENGTH; - GET_SHARED_MEMORY_WITH_OFFSET( - &pTcb[i].Buffer, - &pTcb[i].FirewareInfo, - offset, - MAX_FIRMWARE_INFORMATION_SIZE); - offset+=MAX_FIRMWARE_INFORMATION_SIZE; - GET_SHARED_MEMORY_WITH_OFFSET( - &pTcb[i].Buffer, - &pTcb[i].AMSDU_SubHeader, - offset, - AMSDU_SUBHEADER_LENGTH); - - RTInsertTailListWithCnt(&Adapter->TcbIdleQueue, &pTcb[i].List, &Adapter->NumIdleTcb); - } - - //2 Allocate local buffers - Adapter->LocalBufferArray.Length=Adapter->NumLocalBuffer*sizeof(RT_TX_LOCAL_BUFFER); - status=PlatformAllocateMemory(Adapter, &Adapter->LocalBufferArray.Ptr,Adapter->LocalBufferArray.Length); - if(status!=RT_STATUS_SUCCESS) - return status; - - PlatformZeroMemory(Adapter->LocalBufferArray.Ptr,Adapter->LocalBufferArray.Length); - - pLocalBuffer=(PRT_TX_LOCAL_BUFFER)Adapter->LocalBufferArray.Ptr; - for(i=0;i<Adapter->NumLocalBuffer;i++) - { - status = PlatformAllocateSharedMemory(Adapter, &pLocalBuffer[i].Buffer, Adapter->MAX_TRANSMIT_BUFFER_SIZE); - if(status!=RT_STATUS_SUCCESS) - return status; - - RTInsertTailListWithCnt(&Adapter->LocalBufferQueue, &pLocalBuffer[i].List, &Adapter->NumLocalBufferIdle); - } - - //2 Allocate Firmware local buffers - Adapter->LocalFWBufferArray.Length=Adapter->NumLocalFWBuffer*sizeof(RT_TX_LOCAL_BUFFER); - status=PlatformAllocateMemory(Adapter, &Adapter->LocalFWBufferArray.Ptr,Adapter->LocalFWBufferArray.Length); - if(status!=RT_STATUS_SUCCESS) - return status; - - PlatformZeroMemory(Adapter->LocalFWBufferArray.Ptr,Adapter->LocalFWBufferArray.Length); - - pLocalBuffer=(PRT_TX_LOCAL_BUFFER)Adapter->LocalFWBufferArray.Ptr; - - for(i=0;i<Adapter->NumLocalFWBuffer;i++) - { - status = PlatformAllocateSharedMemory(Adapter, &pLocalBuffer[i].Buffer, RT_LOCAL_FW_BUF_SIZE+Adapter->HWDescHeadLength); - - if(status!=RT_STATUS_SUCCESS) - { - return status; - } - RTInsertTailListWithCnt(&Adapter->LocalFWBufferQueue, &pLocalBuffer[i].List, &Adapter->NumLocalFWBufferIdle); - } - }while(FALSE); - - return status; -} - -// -// Assumption: RT_TX_SPINLOCK is acquired. -// -VOID -FreeTCBs( - PADAPTER Adapter, - BOOLEAN bReset - ) -{ - u1Byte QueueID; - u4Byte nFreed; - PRT_TCB pTcb; - PRT_TX_LOCAL_BUFFER pLocalBuffer; - - RT_ASSERT(IS_TX_LOCKED(Adapter) == TRUE, ("FreeTCBs(): bTxLocked(%x) should be TRUE\n!", Adapter->bTxLocked)); - - //2 Return all TCB to Idle queue first - //2 And free Packet, RFD or local buffer hide in reserved field - for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++) - { - // 2004.08.11, revised by rcnjko. - while(!RTIsListEmpty(&Adapter->TcbBusyQueue[QueueID])) - { - pTcb=(PRT_TCB)RTRemoveHeadList(&Adapter->TcbBusyQueue[QueueID]); - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - } - Adapter->nBufInTxDesc[QueueID] = 0; - - while(!RTIsListEmpty(&Adapter->TcbWaitQueue[QueueID])) - { - pTcb=(PRT_TCB)RTRemoveHeadList(&Adapter->TcbWaitQueue[QueueID]); - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - } - - // Joseph test for A-MSDU aggregation - while(!RTIsListEmpty(&Adapter->TcbAggrQueue[QueueID])) - { - pTcb=(PRT_TCB)RTRemoveHeadList(&Adapter->TcbAggrQueue[QueueID]); - Adapter->TcbCountInAggrQueue[QueueID]--; - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - } - } - - if(!bReset) - { - //2 Free local buffers - if(!RTIsListEmpty(&Adapter->LocalBufferQueue)) - { - nFreed=0; - while(!RTIsListEmpty(&Adapter->LocalBufferQueue)) - { - pLocalBuffer=(PRT_TX_LOCAL_BUFFER)RTRemoveHeadListWithCnt(&Adapter->LocalBufferQueue, &Adapter->NumLocalBufferIdle); - - PlatformFreeSharedMemory(Adapter, &pLocalBuffer->Buffer); - nFreed++; - } - RT_ASSERT(nFreed==Adapter->NumLocalBuffer,("Freed local buffer(%ld) less than allocated(%ld)!!\n", nFreed, Adapter->NumLocalBuffer)); - } - if(Adapter->LocalBufferArray.Ptr != NULL) - { - PlatformFreeMemory(Adapter->LocalBufferArray.Ptr,Adapter->LocalBufferArray.Length); - } - - //2 Free Firmware local buffers - if(!RTIsListEmpty(&Adapter->LocalFWBufferQueue)) - { - nFreed=0; - while(!RTIsListEmpty(&Adapter->LocalFWBufferQueue)) - { - pLocalBuffer=(PRT_TX_LOCAL_BUFFER)RTRemoveHeadListWithCnt(&Adapter->LocalFWBufferQueue, &Adapter->NumLocalFWBufferIdle); - - PlatformFreeSharedMemory(Adapter, &pLocalBuffer->Buffer); - nFreed++; - } - RT_ASSERT(nFreed==Adapter->NumLocalFWBuffer,("Freed FW local buffer(%ld) less than allocated(%ld)!!\n", nFreed, Adapter->NumLocalFWBuffer)); - } - if(Adapter->LocalFWBufferArray.Ptr != NULL) - { - PlatformFreeMemory(Adapter->LocalFWBufferArray.Ptr,Adapter->LocalFWBufferArray.Length); - } - - - //2 Free idle queue - if(!RTIsListEmpty(&Adapter->TcbIdleQueue)) - { - nFreed=0; - while(!RTIsListEmpty(&Adapter->TcbIdleQueue)) - { - pTcb=(PRT_TCB)RTRemoveHeadListWithCnt(&Adapter->TcbIdleQueue, &Adapter->NumIdleTcb); - - PlatformFreeSharedMemory(Adapter, &pTcb->Buffer); - nFreed++; - } - RT_ASSERT(nFreed==Adapter->NumTcb,("Freed TCB(%ld) less than allocated(%ld)!!\n", nFreed, Adapter->NumTcb)); - } - if(Adapter->TcbBuffer.Ptr != NULL) - { - PlatformFreeMemory(Adapter->TcbBuffer.Ptr,Adapter->TcbBuffer.Length); - } - } -} - -VOID -RemoveZeroLengthBuffer( - PRT_TCB pTcb - ) -{ - u2Byte i,j; - u2Byte k = 0; - - for(i=0,j=0;i<pTcb->BufferCount;i++) - { - if(pTcb->BufferList[i].Length==0) - continue; - - if(i!=j) - { - pTcb->BufferList[j]=pTcb->BufferList[i]; - - if(IS_REMOVE_ZERO_LEN_BUF(pTcb->SourceAdapt)) - { - if(pTcb->SubHdrIndexAry[k] == (u1Byte)i) - { - pTcb->SubHdrIndexAry[k] = (u1Byte)j; - k++; - } - } - } - j++; - } - pTcb->BufferCount=j; -} - -BOOLEAN -RetrieveSegmentDataFromTCB( - PRT_TCB pTcb, - u1Byte SkipBuffers, - u4Byte DataOffset, - PVOID pDataBuffer, - u4Byte DataBufLength - ) -{ - BOOLEAN bResult = TRUE; - u4Byte BytesRead = 0; - u4Byte i; - u4Byte offset = 0; - pu1Byte pBuffer = (pu1Byte)pDataBuffer; - - for(i=SkipBuffers;i<pTcb->BufferCount;i++) - { - if(pTcb->BufferList[i].Length==0) - continue; - - for (; BytesRead!=DataBufLength; BytesRead++) - { - if ( (pTcb->BufferList[i].Length + offset) > (DataOffset + BytesRead) ) - { - pBuffer[BytesRead] = pTcb->BufferList[i].VirtualAddress[DataOffset+BytesRead-offset]; - } - else - break; - } - - if (BytesRead == DataBufLength) break; - - offset +=pTcb->BufferList[i].Length; - } - - if (BytesRead != DataBufLength) - { - RT_TRACE(COMP_SEND, DBG_LOUD, ("RetrieveSegmentDataFromTCB(): some data can not be retrived\n")); - bResult = FALSE; - } - - return bResult; -} - -/** -* Function: TcbGetTOSField -* -* Overview: Get TOS field of IP header in TCB buffer. -* Input the TCB pointer and indicate SkipBuffer number for this function to get the -* Ethernet packet sent from upper layer. -* Using this function before packet conversion. (TranslateHeader()) -* -* Input: -* PRT_TCB pTcb -* u1Byte SkipBuffers -* -* Output: -* None -* -* Return: -* TOS value -*/ -u1Byte -TcbGetTOSField( - PRT_TCB pTcb, - u1Byte SkipBuffers - ) -{ - u2Byte TypeLength; - u1Byte TypeLengthBuf[2]; - u1Byte TOS = 0; - - RetrieveSegmentDataFromTCB( - pTcb, - SkipBuffers, - 12, - TypeLengthBuf, - sizeof(TypeLengthBuf)); - - TypeLength = (((u2Byte)TypeLengthBuf[0])<<8) + TypeLengthBuf[1]; - - if(TypeLength == 0x0800) - { - RetrieveSegmentDataFromTCB( - pTcb, - SkipBuffers, - 15, - &TOS, - sizeof(TOS)); - TOS = TOS>>5; - } - - return TOS; -} - - -VOID -TranslateHeader( - PADAPTER Adapter, - PRT_TCB pTcb - ) -{ - u2Byte i; - u4Byte offset=0; - u2Byte TypeLength; - u1Byte TypeLengthBuf[2]; - u1Byte TOS; - static u1Byte SnapBridgeTunnel[6] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8 }; - static u1Byte Snap802_1H[6] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 }; - static u1Byte Snap_CKIP_MIC[8] = { 0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02 }; - pu1Byte pHeader; - u2Byte DAOffset,SAOffset,BSSIDOffset; - u1Byte PAEGroupAddress[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x03}; - u1Byte seqv[4]; - PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); - BOOLEAN bCCX8021xenable = FALSE; - BOOLEAN bAPSuportCCKM = FALSE; - PRT_SECURITY_T pSecInfo = &(pMgntInfo->SecurityInfo); - PRT_WLAN_STA pSTA=NULL; - u1Byte IP_Protocol, IP_HeaderLen, DHCP_Port[4]; - u2Byte DHCP_Src_Port, DHCP_Dst_Port; - u1Byte Addr1[6]; - u1Byte additionalHeaderLen = ETHERNET_ADDRESS_LENGTH*2 + ETHERNET_HEADER_SIZE + WAPI_EXT_LEN + 2 + 16 - 14; - - //2 Fill wireless header - pHeader=pTcb->BufferList[0].VirtualAddress; - - //1 Note: BufferList[0] is reserved for 802.11 header - //1 BufferList[1] is reserved for LLC - - pTcb->bBroadcast = MacAddr_isBcst(pTcb->BufferList[2].VirtualAddress); - if( pTcb->bBroadcast == FALSE ) - pTcb->bMulticast = MacAddr_isMulticast(pTcb->BufferList[2].VirtualAddress); - else - pTcb->bMulticast = FALSE; - - if( (CheckFragment(Adapter, pTcb, Adapter->TXPacketShiftBytes) == FALSE) && - ( (pTcb->PacketLength + additionalHeaderLen ) <= FRAGMENT_THRESHOLD(Adapter) ) ) - { - - } - - { - SET_80211_HDR_FRAME_CONTROL(pHeader, 0); - SET_80211_HDR_TYPE_AND_SUBTYPE(pHeader, Type_Data); - - pTcb->bTDLPacket = FALSE; - - switch(pMgntInfo->OpMode) - { - case RT_OP_MODE_IBSS: // 0,0 - DAOffset=4; - SAOffset=10; - BSSIDOffset=16; - break; - case RT_OP_MODE_AP: // 0,1 - SET_80211_HDR_FROM_DS(pHeader, 1); - DAOffset=4; - SAOffset=16; - BSSIDOffset=10; - break; - case RT_OP_MODE_INFRASTRUCTURE: // 1,0 - DAOffset=16; - SAOffset=10; - BSSIDOffset=4; - SET_80211_HDR_TO_DS(pHeader, 1); - break; - default: - RT_ASSERT(FALSE, ("TranslateHeader(): Unknown OpMode: %d\n", pMgntInfo->OpMode)); - // Handle it as IBSS, 2004.08.21, by rcnjko. - DAOffset=4; - SAOffset=10; - BSSIDOffset=16; - break; - } - SET_80211_HDR_DURATION(pHeader, 0); - PlatformMoveMemory(&pTcb->BufferList[0].VirtualAddress[BSSIDOffset], pMgntInfo->Bssid, ETHERNET_ADDRESS_LENGTH); - - // If in PSP XLink mode, pass the source address in 802.3 header rather than current MAC address. - // 2006.09.04, by shien chang. - if (pMgntInfo->bPSPXlinkMode) - { - PlatformMoveMemory(&pTcb->BufferList[0].VirtualAddress[SAOffset], &pTcb->BufferList[2].VirtualAddress[6], ETHERNET_ADDRESS_LENGTH); - PlatformMoveMemory(pTcb->SourceAddress, &pTcb->BufferList[2].VirtualAddress[6], ETHERNET_ADDRESS_LENGTH); - } - else - { - //2004/07/22, kcwu - PlatformMoveMemory(&pTcb->BufferList[0].VirtualAddress[SAOffset], Adapter->CurrentAddress, ETHERNET_ADDRESS_LENGTH); - PlatformMoveMemory(pTcb->SourceAddress, Adapter->CurrentAddress, ETHERNET_ADDRESS_LENGTH); - } - - PlatformMoveMemory(&pTcb->BufferList[0].VirtualAddress[DAOffset], pTcb->BufferList[2].VirtualAddress, ETHERNET_ADDRESS_LENGTH); - //2004/07/22, kcwu - PlatformMoveMemory(pTcb->DestinationAddress, pTcb->BufferList[2].VirtualAddress, ETHERNET_ADDRESS_LENGTH); - SET_80211_HDR_FRAGMENT_SEQUENCE(pHeader, 0); - } - - //Get Address1 for later use. 2007.04.03, by shien chang. - GET_80211_HDR_ADDRESS1(pHeader, Addr1); - -#if TX_TCP_SEQ_CHECK - TxTcpSeqCheck(Adapter, pTcb, 2); -#endif - - //2 Add LLC if need - // Find TypeLength, 2006.10.27, refined by shien chang. - RetrieveSegmentDataFromTCB( - pTcb, - 2, // The number of buffer in bufferlist to skip. - 12, // The TypeLength offset. - TypeLengthBuf, // 2 Byte buffer for TypeLength data. - sizeof(TypeLengthBuf)); // Buffer length. - - TypeLength=(((u2Byte)EF1Byte(TypeLengthBuf[0]))<<8) + EF1Byte(TypeLengthBuf[1]); - - if(TypeLength == 0x888e) - { // EAPOL packet. - int nTmpOffset = 0; - u1Byte btTmp = 0; - - // For delaying enter PS mode for FW control LPS. by tynli. - if(GET_POWER_SAVE_CONTROL(pMgntInfo)->bFwCtrlLPS && - GET_POWER_SAVE_CONTROL(pMgntInfo)->bLeisurePs) - { - //DbgPrint("EAPOL packet----->\n"); - pMgntInfo->DelayLPSLastTimeStamp = PlatformGetCurrentTime(); - - // 20100902 Joseph: Since we send NULL frame in LeisurePSLeave() function, TX_SPINLOCK - // shall be release for all product and OS. Originally, TX_SPINLOCK is raised twice here and - // system hang immediately. - // We should call LeisurePSLeave to turn the RF on to receive EAPOL/DHCP/ARP packets, - // and release TX spinlock first beacuse we will acquire TX spinlock for FW H2C commands in 92su. - PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); - LeisurePSLeave(Adapter, LPS_DISABLE_TX_EAPOL_PKT); - PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); - } - - if( !SecIsTxKeyInstalled(Adapter, Addr1) ) - { - pTcb->EncInfo.SecProtInfo = RT_SEC_EAPOL_BEFORE_KEY_INSTALLED; - } - else - { - pTcb->EncInfo.SecProtInfo = RT_SEC_EAPOL_AFTER_KEY_INSTALLED; - } - - // Send in lowest basic rate to get more time for adding key. 2005.04.19, by rcnjko. - if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) - { - pTcb->DataRate = MgntQuery_TxRateExcludeCCKRates(pMgntInfo->mBrates);//0xc;//ofdm 6m - pTcb->bTxDisableRateFallBack = FALSE; - } - else - { - pTcb->DataRate = Adapter->MgntInfo.LowestBasicRate; - //disable rate fallback for EAPOL packate to resolve 5G ad hoc cck hang. zhiyuan 2012/04/28 - if(IS_WIRELESS_MODE_A(Adapter) || IS_WIRELESS_MODE_N_5G(Adapter)) - pTcb->bTxDisableRateFallBack = TRUE; - } - - RT_DISP(FDM, WA_IOT, ("EAPOL TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate)); - pTcb->bTxUseDriverAssingedRate = TRUE; - - // Check if this is a MIC failure report packet. 2005.09.06, by rcnjko. - for(i = 2; i < pTcb->BufferCount; i++) - { - if(pTcb->BufferList[i].Length == 0) - continue; - - if(pTcb->BufferList[i].Length + nTmpOffset > 19) - { - btTmp = EF1Byte(pTcb->BufferList[i].VirtualAddress[19-nTmpOffset]); - - if(btTmp == 0x0d || btTmp == 0x0f) - { - pTcb->EncInfo.SecProtInfo |= RT_SEC_MIC_FAILURE_REPORT; - } - - break; - } - - nTmpOffset += pTcb->BufferList[i].Length; - } - } - else - { // Non-EAPOL packets. - pTcb->EncInfo.SecProtInfo = RT_SEC_NORMAL_DATA; - } - - CCX_QueryCCKMSupport(Adapter, &bCCX8021xenable, &bAPSuportCCKM); - - { - // Insert LLC in need - if(TypeLength > (MAXIMUM_ETHERNET_PACKET_SIZE-ETHERNET_HEADER_SIZE) ) - { - if ((TypeLength == 0x8137) || (TypeLength == 0x80F3)) - { // Bridge tunneling - PlatformMoveMemory( - pTcb->BufferList[1].VirtualAddress, - SnapBridgeTunnel, - LLC_HEADER_SIZE); - - pTcb->BufferList[1].Length=LLC_HEADER_SIZE; - pTcb->PacketLength += LLC_HEADER_SIZE; - } - //else if( pSecInfo->pCkipPara->bIsMIC) It will add SNAP to EAPOL packet in 802.1x ,2006.10.04 CCW - else if(pSecInfo->pCkipPara->bIsMIC && (pTcb->EncInfo.SecProtInfo != RT_SEC_EAPOL_BEFORE_KEY_INSTALLED) - && !(( pSecInfo->PairwiseEncAlgorithm == RT_ENC_ALG_WEP40 || - pSecInfo->PairwiseEncAlgorithm ==RT_ENC_ALG_WEP104 ) && // WEP mode - pSecInfo->AuthMode == RT_802_11AuthModeOpen && // Open mode - !( bCCX8021xenable && bAPSuportCCKM ) && // Not in CCKM mode - IsSecProtEapol(pTcb->EncInfo.SecProtInfo) == TRUE) // Is EPAOL Packet - ) - { // CKIP MIC SNAP - RT_TRACE( COMP_CKIP, DBG_LOUD, ("[CKIP] TranslateHeader(): CMIC snap case!\n") ); - - // Set CKIP Snap - PlatformMoveMemory( - pTcb->BufferList[1].VirtualAddress, - Snap_CKIP_MIC, - 8); - // Set MIC and SEQ to zero - PlatformZeroMemory( - pTcb->BufferList[1].VirtualAddress + 8, - 8); - - //Set SEQ - CKIP_SEQ_DECIMAL2ARRAY( pSecInfo->pCkipPara->ulSeqUpLink, seqv ); - PlatformMoveMemory( - pTcb->BufferList[1].VirtualAddress + 12, - seqv, - 4); - pSecInfo->pCkipPara->ulSeqUpLink += 2; - - pTcb->BufferList[1].Length=16; - pTcb->PacketLength += 16; - } - else - { // 802.1h - PlatformMoveMemory( - pTcb->BufferList[1].VirtualAddress, - Snap802_1H, - LLC_HEADER_SIZE); - - pTcb->BufferList[1].Length=LLC_HEADER_SIZE; - pTcb->PacketLength += LLC_HEADER_SIZE; - } - - offset=ETHERNET_HEADER_SIZE - TYPE_LENGTH_FIELD_SIZE; - } - else - { - offset=ETHERNET_HEADER_SIZE; - } - } - - // - // Parsing the DSCP in IP header TOS field. - // Set default priority for the packets other than IP. Revised by Joseph - // - if( TypeLength == 0x0800 ) // IP header - { - RetrieveSegmentDataFromTCB( - pTcb, - 2, - 15, - &TOS, - sizeof(TOS)); - pTcb->priority = TOS>>5; - RT_DISP(FQoS, QoS_INIT, ("Translate Header pTcb->priority = %d\r\n", pTcb->priority)); - } - else - { - pTcb->priority = 0; - } - - //************************************************************************* - // cosa added 03/12/2008 - // The following is for DHCP and ARP packet, we use cck1M to tx these packets to prevent - // DHCP protocol fail - if( TypeLength == 0x0800 ) // IP header - { - RetrieveSegmentDataFromTCB( - pTcb, - 2, - 14+9, - &IP_Protocol, - sizeof(IP_Protocol)); - - if(IP_Protocol == 0x11) // UDP protocol - { - //DbgPrint("UDP Protocol !!\n"); - RetrieveSegmentDataFromTCB( - pTcb, - 2, - 14, // 14 is the start of the IP Header - &IP_HeaderLen, // each unit = 4 bytes. - sizeof(IP_HeaderLen)); - IP_HeaderLen &= 0xf; //bit0~3 - IP_HeaderLen *= 4; //Bytes of IP Header. - //DbgPrint("IP_HeaderLen = %d\n", IP_HeaderLen); - - RetrieveSegmentDataFromTCB( - pTcb, - 2, - 14+IP_HeaderLen, // 14 is the start of the IP Header - DHCP_Port, // each unit = 4 bytes. - sizeof(DHCP_Port)); - //DbgPrint("DHCP_Port = [0]=%x,[1]=%x, [2]=%x, [3]=%x \n", DHCP_Port[0], DHCP_Port[1], DHCP_Port[2], DHCP_Port[3]); - DHCP_Src_Port = (((u2Byte)DHCP_Port[0])<<8) + DHCP_Port[1]; - DHCP_Dst_Port = (((u2Byte)DHCP_Port[2])<<8) + DHCP_Port[3]; - //DbgPrint("DHCP_Src_Port = %d, DHCP_Dst_Port = %d \n", DHCP_Src_Port, DHCP_Dst_Port); - if((DHCP_Src_Port == 68 && DHCP_Dst_Port == 67) || - (DHCP_Src_Port == 67 && DHCP_Dst_Port == 68)) - { - OCTET_STRING osMpdu; - pu1Byte pRaddr = NULL; - - //Note: - // osMpdu may not include the packet content but just 802.11 header. - FillOctetString(osMpdu, pTcb->BufferList[0].VirtualAddress, (u2Byte)pTcb->BufferList[0].Length); - pRaddr = Frame_pRaddr(osMpdu); - - // - // Translate the DHCP offer packet from multicast packet to unicast so that the client - // can receive the DHCP response easier. By Bruce, 2011-01-06. - // - if(ACTING_AS_AP(pTcb->SourceAdapt) && MacAddr_isMulticast(pRaddr)) - { - u1Byte ClientMac[6]; - PRT_WLAN_STA pEntry; - - // Get the Mac address in DHCP packet. - RetrieveSegmentDataFromTCB( - pTcb, - 2, - IP_HeaderLen + 14 + 8 + 28, // UDP header(8) + Client Mac Address offset (28) - ClientMac, // each unit = 4 bytes. - 6); - - // Check if this mac address is belong to one of the clients. - pEntry = AsocEntry_GetEntry(&pTcb->SourceAdapt->MgntInfo, ClientMac); - - if(pEntry != NULL) - { - RT_PRINT_ADDR(COMP_AP, DBG_LOUD, "Replace the DHCP receiver address from multicast to ", ClientMac); - PlatformMoveMemory(pRaddr, ClientMac, 6); - PlatformMoveMemory(pTcb->DestinationAddress, ClientMac, 6); - } - } - // 68 : UDP BOOTP client - // 67 : UDP BOOTP server - //DbgPrint("DHCP Protocol !!\n"); - // Use low rate to send DHCP packet. - if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) - { - pTcb->DataRate = MgntQuery_TxRateExcludeCCKRates(pMgntInfo->mBrates);//0xc;//ofdm 6m - pTcb->bTxDisableRateFallBack = FALSE; - } - else - pTcb->DataRate = Adapter->MgntInfo.LowestBasicRate; - RT_DISP(FDM, WA_IOT, ("DHCP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate)); - pTcb->bTxUseDriverAssingedRate = TRUE; - pTcb->specialDataType = PACKET_DHCP; - pMgntInfo->LPSDelayCnt= - GET_POWER_SAVE_CONTROL(pMgntInfo)->LPSAwakeIntvl*2; - // For delaying enter PS mode for FW control LPS. by tynli. - if( GET_POWER_SAVE_CONTROL(pMgntInfo)->bFwCtrlLPS && - GET_POWER_SAVE_CONTROL(pMgntInfo)->bLeisurePs) - { //by tynli - pMgntInfo->DelayLPSLastTimeStamp = PlatformGetCurrentTime(); - - // 20100902 Joseph: Since we send NULL frame in LeisurePSLeave() function, TX_SPINLOCK - // shall be release for all product and OS. Originally, TX_SPINLOCK is raised twice here and - // system hang immediately. - PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); - LeisurePSLeave(Adapter, LPS_DISABLE_TX_DHCP_PKT); - PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); - } - } - } - } - if( TypeLength == 0x0806 ) // IP ARP packet - { - //DbgPrint("IP ARP !!\n"); - pMgntInfo->LPSDelayCnt = pMgntInfo->mDtimCount; - if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) - { - pTcb->DataRate = MgntQuery_TxRateExcludeCCKRates(pMgntInfo->mBrates);//0xc;//ofdm 6m - pTcb->bTxDisableRateFallBack = FALSE; - } - else - pTcb->DataRate = pMgntInfo->LowestBasicRate; - RT_DISP(FDM, WA_IOT, ("ARP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate)); - pTcb->bTxUseDriverAssingedRate = TRUE; - pTcb->specialDataType = PACKET_ARP; - if( GET_POWER_SAVE_CONTROL(pMgntInfo)->bFwCtrlLPS && - GET_POWER_SAVE_CONTROL(pMgntInfo)->bLeisurePs) - { // by tynli - //DbgPrint("ARP packet----->\n"); - pMgntInfo->DelayLPSLastTimeStamp = PlatformGetCurrentTime(); - - // 20100902 Joseph: Since we send NULL frame in LeisurePSLeave() function, TX_SPINLOCK - // shall be release for all product and OS. Originally, TX_SPINLOCK is raised twice here and - // system hang immediately. - PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); - LeisurePSLeave(Adapter, LPS_DISABLE_TX_ARP_PKT); - PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); - } - } - //************************************************************************* - - TDLS_TxTranslateHeader(Adapter, pTcb, RT_PROTOCOL_802_3); - - // Remove 802.3 header - pTcb->PacketLength -= offset; - - //3 Add SecurityHeader - if(!IsSecProtEapolBeforeKeyInstalled(pTcb->EncInfo.SecProtInfo)) - { - u1Byte CurrCcxVerNumber = 0; - - CCX_QueryVersionNum(Adapter, &CurrCcxVerNumber); - - if(!(( pSecInfo->PairwiseEncAlgorithm == RT_ENC_ALG_WEP40 || - pSecInfo->PairwiseEncAlgorithm ==RT_ENC_ALG_WEP104 ) && // WEP mode - pSecInfo->AuthMode == RT_802_11AuthModeOpen && // Open mode - !( bCCX8021xenable && bAPSuportCCKM && CurrCcxVerNumber >= 2 ) && // Not in CCKM mode - IsSecProtEapol(pTcb->EncInfo.SecProtInfo) == TRUE // Is EPAOL Packet - )) - { - pTcb->BufferList[0].Length = (sMacHdrLng + pSecInfo->EncryptionHeadOverhead); - } - else - { - if(!PlatformCompareMemory(PAEGroupAddress, pTcb->DestinationAddress, ETHERNET_ADDRESS_LENGTH)) - { // <RJ_TODO> Does this case happen after PTK installed? - PlatformMoveMemory(pTcb->DestinationAddress, pMgntInfo->Bssid, ETHERNET_ADDRESS_LENGTH); - } - - pTcb->BufferList[0].Length = sMacHdrLng; - } - } - else - { - if(!PlatformCompareMemory(PAEGroupAddress, pTcb->DestinationAddress, ETHERNET_ADDRESS_LENGTH)) - { // <RJ_TODO> Does this case happen after PTK installed? - PlatformMoveMemory(pTcb->DestinationAddress, pMgntInfo->Bssid, ETHERNET_ADDRESS_LENGTH); - } - - pTcb->BufferList[0].Length = sMacHdrLng; - } - - //3 Added QoS Control - if(ACTING_AS_AP(Adapter) || Adapter->MgntInfo.mIbss ) - pSTA = AsocEntry_GetEntry(pMgntInfo, Addr1); - - RT_DISP(FQoS, QoS_INIT, ("TranslateHeader QoS header\r\n")); - - if( (pMgntInfo->pStaQos->CurrentQosMode > QOS_DISABLE ) && - (((ACTING_AS_AP(Adapter) || pMgntInfo->mIbss) && pSTA != NULL)?((pSTA->QosMode)>QOS_DISABLE):TRUE) && - (MacAddr_isMulticast(Addr1)==FALSE) && - (MacAddr_isBcst(Addr1)==FALSE) ) - { - // 1. Reserve 2-bytes QoS Control Field for unicast QoS Data frame. - pTcb->BufferList[0].Length += sQoSCtlLng; - - if(pMgntInfo->pHTInfo->bRDGEnable) - { - pTcb->BufferList[0].Length += 4; //HTC len - SET_80211_HDR_ORDER(pHeader,1); - pTcb->BufferList[0].VirtualAddress[24+2+3] = 0x80; - } - - // 2. Change SubType in Frame Control. - SET_80211_HDR_QOS_EN(pHeader, 1); - - // 4. Use highest priority to send EPAOL-Key packet. Annie, 2005-12-22. - // Ref: 802.11e/D13.0, 8.5.2, in page 67: - // "When priority processing of data frames is supported, a STA's SME should send EAPOL-Key frames at the highest priority." - if( TypeLength == 0x888e ) - { - pTcb->priority = 7; - } - } - - pTcb->PacketLength += pTcb->BufferList[0].Length; - - for(i=2;i<pTcb->BufferCount && offset > 0;i++) - { - if(pTcb->BufferList[i].Length==0) - continue; - - if(pTcb->BufferList[i].Length >= offset) - { - MAKE_SHARED_MEMORY_OFFSET_AT_FRONT(&pTcb->BufferList[i], offset); - offset=0; - } - else - { - offset-=pTcb->BufferList[i].Length; - pTcb->BufferList[i].Length=0; - } - } - - // If original 802.3 header size is small than 4 byte, append it to LLC header and remove it. - if(pTcb->BufferList[1].Length > 0) - { - for(i=2;i<pTcb->BufferCount;i++) - { // Only check first nonzero buffer - if(pTcb->BufferList[i].Length==0) - continue; - - if(pTcb->BufferList[i].Length < MIN_DESC_BUFFER_LENGTH) - { - PlatformMoveMemory( - &pTcb->BufferList[1].VirtualAddress[pTcb->BufferList[1].Length], - pTcb->BufferList[i].VirtualAddress, - pTcb->BufferList[i].Length); - pTcb->BufferList[1].Length += pTcb->BufferList[i].Length; - pTcb->BufferList[i].Length=0; - } - break; - } - } - -} - -// 20100309 Joseph: Revise special frame parsing in Tx path. -// Also handling the packets saved in LOCAL_BUFFER. The buffer offset and index is different from the -// buffer in SYSTEM_BUFFER. -BOOLEAN -CheckSpecialTxPktContentFromHighLayer( - PRT_TCB pTcb - ) -{ - u1Byte IP_Protocol, IP_HeaderLen; - u2Byte IP_Src_Port = 0, IP_Dst_Port = 0; - u2Byte u2Tmp = 0; - - u1Byte Check_Buf_Index, Check_Buf_Offset; - - if(pTcb->BufferType==RT_TCB_BUFFER_TYPE_LOCAL) - { - // 20100309 Joseph: Add packet parsing for LOCAL BUFFER case. - // Payload is saved in buffer 1. - // Since LLC header is coalesced with oter payload in buffer 1, we just skip first 8 bytes LLC - // in front of buffer to get the paylaod. - Check_Buf_Index = 1; - Check_Buf_Offset = 8; - } - else - { - // 20100309 Joseph: Normal case. - // Payload is saved in buffer 2 and LLC is separate with it in buffer 1. - Check_Buf_Index = 2; - Check_Buf_Offset = 0; - } - - RetrieveSegmentDataFromTCB( - pTcb, - Check_Buf_Index, - 9+Check_Buf_Offset, // Get payload offset 9 to get protocol type. - &IP_Protocol, - sizeof(IP_Protocol)); - - // DbgPrint("IP_Protocol = %d\n", IP_Protocol); - RetrieveSegmentDataFromTCB( - pTcb, - Check_Buf_Index, - 0+Check_Buf_Offset, // Offset 0 is the start of the IP Header - &IP_HeaderLen, // each unit = 4 bytes. - sizeof(IP_HeaderLen)); - IP_HeaderLen &= 0xf; //bit0~3 - IP_HeaderLen *= 4; //Bytes of IP Header. - //DbgPrint("IP_HeaderLen = %d\n", IP_HeaderLen); - - if(0x11 == IP_Protocol || 0x06 == IP_Protocol) - { - // Get source port - RetrieveSegmentDataFromTCB( - pTcb, - Check_Buf_Index, - IP_HeaderLen+Check_Buf_Offset, - &u2Tmp, - 2); - IP_Src_Port = H2N2BYTE(u2Tmp); - - // Get source port - RetrieveSegmentDataFromTCB( - pTcb, - Check_Buf_Index, - IP_HeaderLen + Check_Buf_Offset + 2, - &u2Tmp, - 2); - IP_Dst_Port = H2N2BYTE(u2Tmp); - } - - if(IP_Protocol == 0x11) // UDP protocol - { - pTcb->IPType = TX_IPTYPE_UDP; - - //DbgPrint("DHCP_Src_Port = %d, DHCP_Dst_Port = %d \n", DHCP_Src_Port, DHCP_Dst_Port); - if((IP_Src_Port == 68 && IP_Dst_Port == 67) || - (IP_Src_Port == 67 && IP_Dst_Port == 68)) - { - OCTET_STRING osMpdu; - pu1Byte pRaddr = NULL; - - //Note: - // osMpdu may not include the packet content but just 802.11 header. - FillOctetString(osMpdu, pTcb->BufferList[0].VirtualAddress, (u2Byte)pTcb->BufferList[0].Length); - pRaddr = Frame_pRaddr(osMpdu); - - // - // Translate the DHCP offer packet from multicast packet to unicast so that the client - // can receive the DHCP response easier. By Bruce, 2011-01-06. - // - if(ACTING_AS_AP(pTcb->SourceAdapt) && MacAddr_isMulticast(pRaddr)) - { - u1Byte ClientMac[6]; - PRT_WLAN_STA pEntry; - - // Get the Mac address in DHCP packet. - RetrieveSegmentDataFromTCB( - pTcb, - Check_Buf_Index, - IP_HeaderLen + Check_Buf_Offset + 8 + 28, // UDP header(8) + Client Mac Address offset (28) - ClientMac, // each unit = 4 bytes. - 6); - - // Check if this mac address is belong to one of the clients. - pEntry = AsocEntry_GetEntry(&pTcb->SourceAdapt->MgntInfo, ClientMac); - - if(pEntry != NULL) - { - RT_PRINT_ADDR(COMP_AP, DBG_LOUD, "Replace the DHCP receiver address from multicast to ", ClientMac); - // Copy the client mac address to the ra. - PlatformMoveMemory(pRaddr, ClientMac, 6); - PlatformMoveMemory(pTcb->DestinationAddress, ClientMac, 6); - } - } - - return TRUE; - } - else - { - return FALSE; - } - } - else if(0x06 == IP_Protocol) // TCP - { - pTcb->IPType = TX_IPTYPE_TCP; - - // DbgPrint("TCP src port = %d, dst port = %d\n", IP_Src_Port, IP_Dst_Port); - if(IP_Src_Port == 7236 || IP_Dst_Port == 7236 || - IP_Src_Port == 8554 || IP_Dst_Port == 8554) - { - u1Byte offset = Check_Buf_Index; - RT_TRACE_F(COMP_P2P, DBG_LOUD, ("[MIRACAST/P2P] Tx Display Packet:\n")); - for(offset = Check_Buf_Index; offset < pTcb->BufferCount; offset ++) - { - if(0 == pTcb->BufferList[offset].Length) - continue; - RT_PRINT_DATA(COMP_P2P, DBG_LOUD, "", - pTcb->BufferList[offset].VirtualAddress, pTcb->BufferList[offset].Length); - } - } - } - return FALSE; -} - -// -// For NDIS6 802.11 Tx frame handling. -// Added by Annie, 2006-10-20. -// -VOID -FillPartialHeader( - PADAPTER Adapter, - PRT_TCB pTcb - ) -{ - u2Byte TypeLength; - u1Byte TypeLengthBuf[2]; - pu1Byte pHeader = pTcb->BufferList[0].VirtualAddress; - u1Byte PAEGroupAddress[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x03}; - PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); - PRT_POWER_SAVE_CONTROL pPSC = GET_POWER_SAVE_CONTROL(pMgntInfo); - PRT_SECURITY_T pSecInfo = &(pMgntInfo->SecurityInfo); - u1Byte Addr1[6]; - BOOLEAN bIsSpecialPkt = FALSE; - - //2 Fill wireless header (Some field is filled by upper layer) - SET_80211_HDR_DURATION(pHeader, 0); - SET_80211_HDR_FRAGMENT_SEQUENCE(pHeader, 0); - - pTcb->bTDLPacket = FALSE; - - // <SC_TODO: to take care of PSP X-Link mode> - if( GET_80211_HDR_TO_DS(pHeader)==0 && GET_80211_HDR_FROM_DS(pHeader)==0) - { - // IBSS - GET_80211_HDR_ADDRESS2(pHeader, pTcb->SourceAddress); - GET_80211_HDR_ADDRESS1(pHeader, pTcb->DestinationAddress); - - if( MgntActQuery_ApType(Adapter) == RT_AP_TYPE_IBSS_EMULATED - || MgntActQuery_ApType(Adapter) == RT_AP_TYPE_LINUX) - { - // - // 061227, rcnjko: - // Translate header for NDIS6 faked AP mode (UI make upper layer take us as AdHoc mode). - // - if( pMgntInfo->OpMode == RT_OP_MODE_AP && IsFrameTypeData((pTcb->BufferList[0].VirtualAddress)) ) - { - u1Byte tmpAddr[6]; - u1Byte tmpAddr2[6]; - - SET_80211_HDR_TO_DS(pHeader, 0); - SET_80211_HDR_FROM_DS(pHeader, 1); - - GET_80211_HDR_ADDRESS2(pHeader,tmpAddr); - GET_80211_HDR_ADDRESS3(pHeader,tmpAddr2); - SET_80211_HDR_ADDRESS2(pHeader,tmpAddr2); - SET_80211_HDR_ADDRESS3(pHeader,tmpAddr); - } - } - } - else if (GET_80211_HDR_TO_DS(pHeader) == 1 && GET_80211_HDR_FROM_DS(pHeader) == 0) - { - // From STA to AP. - GET_80211_HDR_ADDRESS2(pHeader,pTcb->SourceAddress); - GET_80211_HDR_ADDRESS3(pHeader,pTcb->DestinationAddress); - - } - else if (GET_80211_HDR_TO_DS(pHeader) == 0 && GET_80211_HDR_FROM_DS(pHeader) == 1) - { - // From AP to STA. - GET_80211_HDR_ADDRESS3(pHeader,pTcb->SourceAddress); - GET_80211_HDR_ADDRESS1(pHeader,pTcb->DestinationAddress); - } - else - { - // WDS - // <SC_TODO:> - } - - pTcb->bBroadcast = MacAddr_isBcst(pTcb->DestinationAddress); - if( pTcb->bBroadcast == FALSE ) - pTcb->bMulticast = MacAddr_isMulticast(pTcb->DestinationAddress); - else - pTcb->bMulticast = FALSE; - - GET_80211_HDR_ADDRESS1(pHeader, Addr1); - - // Find TypeLength, 2006.10.27, refined by shien chang. - RetrieveSegmentDataFromTCB( - pTcb, - 0, // The number of buffer in bufferlist to skip. - 30, // The TypeLength offset. 24 for Wireless header, 6 for LLC - TypeLengthBuf, // 2 Byte buffer for TypeLength data. - sizeof(TypeLengthBuf)); // Buffer length. - - TypeLength=(((u2Byte)TypeLengthBuf[0])<<8) + TypeLengthBuf[1]; - - if(TypeLength == 0x888e) - { // EAPOL packet. - - bIsSpecialPkt = TRUE; - pTcb->specialDataType = PACKET_EAPOL; - - if(!SecIsTxKeyInstalled(Adapter, Addr1) ) - { - pTcb->EncInfo.SecProtInfo = RT_SEC_EAPOL_BEFORE_KEY_INSTALLED; - } - else - { - pTcb->EncInfo.SecProtInfo = RT_SEC_EAPOL_AFTER_KEY_INSTALLED; - } - } - else - { // Non-EAPOL packets. - pTcb->EncInfo.SecProtInfo = RT_SEC_NORMAL_DATA; - } - -#if TX_TCP_SEQ_CHECK - TxTcpSeqCheck(Adapter, pTcb, 2); -#endif - - - //************************************************************************* - // cosa added 03/12/2008 - // The following is for DHCP and ARP packet, we use cck1M to tx these packets to prevent - // DHCP protocol fail - // 20100309 Joseph: Revise special frame parsing in Tx path. - if( TypeLength == 0x0800 ) // IP header - { - bIsSpecialPkt = CheckSpecialTxPktContentFromHighLayer(pTcb); - if(bIsSpecialPkt) - pTcb->specialDataType = PACKET_DHCP; - } - else if( TypeLength == 0x0806 ) // IP ARP packet - { - bIsSpecialPkt = TRUE; - pTcb->specialDataType = PACKET_ARP; - } - - if(bIsSpecialPkt) - { - // Use low rate to send DHCP packet. - if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) - { - pTcb->DataRate = MgntQuery_TxRateExcludeCCKRates(pMgntInfo->mBrates);//0xc;//ofdm 6m - pTcb->bTxDisableRateFallBack = FALSE; - } - else - { - pTcb->DataRate = pMgntInfo->HighestBasicRate; - //disable rate fallback for EAPOL packate to resolve 5G ad hoc cck hang. zhiyuan 2012/04/28 - //SUT disconnect,DUT will indication OS start association succuss,and send eapol packet in AES MODE.this will cause cck hang on 5G. - if(IS_WIRELESS_MODE_A(Adapter) || IS_WIRELESS_MODE_N_5G(Adapter)) - pTcb->bTxDisableRateFallBack = TRUE; - } - - RT_DISP(FDM, WA_IOT, ("DHCP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate)); - pTcb->bTxUseDriverAssingedRate = TRUE; - - // For delaying enter PS mode for FW control LPS. by tynli. - pMgntInfo->LPSDelayCnt= GET_POWER_SAVE_CONTROL(pMgntInfo)->LPSAwakeIntvl*2; - if(GET_POWER_SAVE_CONTROL(pMgntInfo)->bFwCtrlLPS && - GET_POWER_SAVE_CONTROL(pMgntInfo)->bLeisurePs) - { //by tynli - pMgntInfo->DelayLPSLastTimeStamp = PlatformGetCurrentTime(); - - // 20100902 Joseph: Since we send NULL frame in LeisurePSLeave() function, TX_SPINLOCK - // shall be release for all product and OS. Originally, TX_SPINLOCK is raised twice here and - // system hang immediately. - if(!(pPSC->RegAdvancedLPs && (pTcb->specialDataType == PACKET_ARP))) - { - PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); - LeisurePSLeave(Adapter, LPS_DISABLE_TX_SPECIAL_PKT); - PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); - } - } - } - //************************************************************************* - - - //3 Add SecurityHeader - if(!IsSecProtEapolBeforeKeyInstalled(pTcb->EncInfo.SecProtInfo) && MgntGetEncryptionInfo(Adapter,pTcb,&pTcb->EncInfo,FALSE) - && !pMgntInfo->SafeModeEnabled) - { - pTcb->BufferList[0].Length += pSecInfo->EncryptionHeadOverhead; - pTcb->PacketLength += pSecInfo->EncryptionHeadOverhead; - } - else - { - if(!PlatformCompareMemory(PAEGroupAddress, pTcb->DestinationAddress, ETHERNET_ADDRESS_LENGTH)) - { // <RJ_TODO> Does this case happen after PTK installed? - PlatformMoveMemory(pTcb->DestinationAddress, Adapter->MgntInfo.Bssid, ETHERNET_ADDRESS_LENGTH); - } - - pTcb->BufferList[0].Length = sMacHdrLng; - } - - RT_DISP(FQoS, QoS_INIT, ("FillPartialHeader CurrentQosMode=%d\r\n", pMgntInfo->pStaQos->CurrentQosMode)); - - //3 Added QoS Control - if(!MacAddr_isMulticast(Addr1) && (pMgntInfo->pStaQos->CurrentQosMode > QOS_DISABLE )) - { - BOOLEAN bInsertQoS = FALSE; - if(ACTING_AS_AP(Adapter)|| ACTING_AS_IBSS(Adapter)) - { - pu1Byte dstaddr = (pu1Byte)pTcb->DestinationAddress; - PRT_WLAN_STA pSTA = AsocEntry_GetEntry( pMgntInfo, dstaddr); - - if(pSTA!=NULL) - { - if(pSTA->QosMode > QOS_DISABLE ) - bInsertQoS = TRUE; - } - } - else// if(pMgntInfo->mActingAsAp && pSTA!=NULL) - bInsertQoS = TRUE; - - if(bInsertQoS == TRUE) - { - pTcb->BufferList[0].Length += sQoSCtlLng; - pTcb->PacketLength += sQoSCtlLng; // 2006.10.21, by Annie. - - // 2. Change SubType in Frame Control. - SET_80211_HDR_QOS_EN(pHeader, 1); - - // 4. Use highest priority to send EPAOL-Key packet. Annie, 2005-12-22. - // Ref: 802.11e/D13.0, 8.5.2, in page 67: - // "When priority processing of data frames is supported, a STA's SME should send EAPOL-Key frames at the highest priority." - if( TypeLength == 0x888e ) - { - pTcb->priority = 7; - } - } - } - - TDLS_TxTranslateHeader(Adapter, pTcb, RT_PROTOCOL_802_11); -} - - -#define MAC_BUFFER0_LENGTH 200 -#define MAX_SUBFRAME_HEADER_LENGTH 18 // header 14 + padding 4 - - -BOOLEAN -TxDoCoalescePciE( - PADAPTER Adapter, - PRT_TCB pTcb - ) -{ - return FALSE; -} - - -pu1Byte -GET_FRAME_OF_FIRST_FRAG( - PADAPTER Adapter, - PRT_TCB pTcb -) -{ - return (pu1Byte)&pTcb->BufferList[0].VirtualAddress[Adapter->TXPacketShiftBytes]; -} - -pu1Byte -DOT11_HEADER_FROM_TCB( - PADAPTER Adapter, - PRT_TCB pTcb -) -{ - return pTcb->BufferList[0].VirtualAddress + Adapter->TXPacketShiftBytes; -} - -VOID -GetTcbDestaddr( - PADAPTER Adapter, - PRT_TCB pTcb, - pu1Byte * ppDestaddr -) -{ - if( pTcb->ProtocolType==RT_PROTOCOL_802_3 ) - { - *ppDestaddr = pTcb->BufferList[0].VirtualAddress; - } - else - { - *ppDestaddr = pTcb->BufferList[0].VirtualAddress+4; - } - if( TEST_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_USE_COALESCE_BUFFER) || - TEST_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_USE_PACKET_SHIFT)) - *ppDestaddr += Adapter->TXPacketShiftBytes; - -} - - -/* -* Attention!! We will do Coalesce if we using SW encryption!! -* But for A-MSDU, the packet length may larger than local buffer size. -* SW encryption + A-MSDU may cause error!! -*/ - -BOOLEAN -PreTransmitTxDoCoalesce( - PADAPTER Adapter, - PRT_TCB pTcb, - pu1Byte *pHeader// '*' add by ylb 20130508 for pHeader is wrong when enable AMSDU -) -{ - BOOLEAN bColoaseResult = TRUE; - - if(pTcb->ColoaseMethod == 2) - bColoaseResult = TxDoCoalescePciE(Adapter, pTcb); - else - { - bColoaseResult = TxDoCoalesce(Adapter, pTcb); - } - - if(!bColoaseResult) - { - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - return FALSE; - } - - // pTcb->BufferList[0] is changed after coalesced. - // 8187 must be coalesced and inerted Tx descriptor into beginning of buffer. - *pHeader = GET_FRAME_OF_FIRST_FRAG(Adapter, pTcb);// '*' add by ylb 20130508 for pHeader is wrong when enable AMSDU - return TRUE; -} - -BOOLEAN -PreTransmitWaitQueue( - PADAPTER Adapter, - PRT_TCB pTcb, - PBOOLEAN bImmediateComplete -) -{ - if(!RTIsListEmpty(Get_WAIT_QUEUE(Adapter, pTcb->SpecifiedQueueID))) - { - RT_TRACE( COMP_SEND, DBG_TRACE, - ("PreTransmitTCB(): there is already packets queued in wait queue(%d)\n", - pTcb->SpecifiedQueueID)); - RTInsertTailListWithCnt(Get_WAIT_QUEUE(Adapter, pTcb->SpecifiedQueueID), &pTcb->List, GET_WAIT_QUEUE_CNT(Adapter,pTcb->SpecifiedQueueID)); - - // If buffer is coalesced, packet should be returned immediately in Platform. - // 2007.07.17, by shien chang. - if ( (ACTING_AS_AP(Adapter) == FALSE) && - (pTcb->BufferType == RT_TCB_BUFFER_TYPE_SYSTEM) && - (TEST_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_USE_COALESCE_BUFFER)) && - (Adapter->NumIdleTcb < TCB_RESOURCE_THRESHOLD) ) - { - if(!pTcb->bAggregate && !pTcb->bAMSDUProcessed) - *bImmediateComplete = TRUE; - } - return TRUE; - } - return FALSE; -} - - - - -BOOLEAN -PreTransmitTCB( - PADAPTER Adapter, - PRT_TCB pTcb - ) -{ - //1 Note: Buffer list in pTcb may contain zero-length buffer(include first one) - PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); - PRT_SECURITY_T pSecInfo = &(pMgntInfo->SecurityInfo); - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); - pu1Byte pHeader = pTcb->BufferList[0].VirtualAddress; - BOOLEAN bMicFailureReport = FALSE; - RT_RF_POWER_STATE rtState; - BOOLEAN bCheckLocalToWds = FALSE; - BOOLEAN bImmediateComplete = FALSE; - RT_PS_TX_STATUS psTxStatus; - pu1Byte pRevAddr=NULL; - PADAPTER DefAdapter = GetDefaultAdapter(Adapter); - PMGNT_INFO pDefaultMgntInfo =&(DefAdapter->MgntInfo); - RT_STATUS rtStatus; - - pTcb->SourceAdapt = Adapter; - - Adapter->ShortcutIndex = 0; - - if( Adapter->SNForShortcut >= 255 ) - Adapter->SNForShortcut = 1; - else - Adapter->SNForShortcut++; - pTcb->SNForShortcut = Adapter->SNForShortcut; - - if(RT_DRIVER_STOP(Adapter)) - { - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - return FALSE; - } - - Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); - - if(rtState == eRfOff) - { // This packet should not be sent if RF is OFF, drop it !! - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - RT_TRACE(COMP_SEND, DBG_LOUD, ("PreTransmitTCB(): RF is off, returnTCB!\n")); - return FALSE; - } -//Go skip sending probeRsp when scanning -//by sherry 20130117 - if((GetFirstGOPort(Adapter)!= NULL) && (MgntScanInProgress(&DefAdapter->MgntInfo)) && IsMgntProbeRsp(pTcb->BufferList[0].VirtualAddress)&& GetDefaultAdapter(Adapter)->bInHctTest) - { - RT_TRACE(COMP_MLME, DBG_LOUD, ("===>PreTransmitTCB(): GO do not send any packet during default port is in scan\n")); - RT_PRINT_DATA(COMP_MLME,DBG_LOUD,"send data content: \n",pTcb->BufferList[0].VirtualAddress,24); - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - return FALSE; - } - - do{ - - { - if(pTcb->bAMSDUProcessed == FALSE) - { - - if(!MgntFilterTransmitPacket(Adapter, pTcb) && !GET_SIMPLE_CONFIG_ENABLED(pDefaultMgntInfo)) - { // This packet should not be sent, drop it !! - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - break; - } - - //2 Set all unspecified data to valid value - if(pTcb->ProtocolType==RT_PROTOCOL_802_3) - { - RT_DISP(FQoS, QoS_INIT, ("RT_PROTOCOL_802_3 PreTransmitTCB\n")); - - TranslateHeader(Adapter, pTcb); - - pTcb->ProtocolType=RT_PROTOCOL_802_11; - - // We only check if GroupTransmitKey exists when - // sending non-EAPPacket in Ad-Hoc mode with AES or TKIP encryption. - // 2004.11.30, by rcnjko. - if( pMgntInfo->mIbss && !IsSecProtEapol(pTcb->EncInfo.SecProtInfo) ) - { - if( pSecInfo->PairwiseEncAlgorithm == RT_ENC_ALG_TKIP || - pSecInfo->PairwiseEncAlgorithm == RT_ENC_ALG_AESCCMP ) - { - if(pSecInfo->KeyLen[pSecInfo->DefaultTransmitKeyIdx] == 0) - { - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - break; - } - } - } - - // Not to send packet if there is no key. Added by Annie , 2006-04-27. - if( SecDropForKeyAbsent( Adapter, pTcb ) ) - { - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - break; - } - - bCheckLocalToWds = TRUE; - } - else - { - if( ACTING_AS_AP(Adapter) ) - { - OCTET_STRING pduOS; - pduOS.Octet = pTcb->BufferList[0].VirtualAddress; - pduOS.Length = (u2Byte)pTcb->BufferList[0].Length; - CopyMem(pTcb->DestinationAddress, Frame_pDaddr(pduOS), ETHERNET_ADDRESS_LENGTH); - CopyMem(pTcb->SourceAddress, Frame_pSaddr(pduOS), ETHERNET_ADDRESS_LENGTH); - } - - if (pTcb->bFromUpperLayer == TRUE) - { - RT_DISP(FQoS, QoS_INIT, ("Data from upper layer FillPartialHeader\n")); - // <SC_TODO: always data ?> - if( pTcb->BufferList[0].VirtualAddress[0] == Type_Data ) - { - FillPartialHeader( Adapter, pTcb ); - bCheckLocalToWds = TRUE; - - if(SecDropForKeyAbsent( Adapter, pTcb ) ) - { - RT_TRACE(COMP_SEC,DBG_LOUD,("PreTransmit :SecDropForKeyAbsent: drop data \n")); - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - break; - } - } - } - else - { - OCTET_STRING pduOS; - pduOS.Octet = pTcb->BufferList[0].VirtualAddress; - pduOS.Length = (u2Byte)pTcb->BufferList[0].Length; - CopyMem(pTcb->DestinationAddress, Frame_pDaddr(pduOS), ETHERNET_ADDRESS_LENGTH); - CopyMem(pTcb->SourceAddress, Frame_pSaddr(pduOS), ETHERNET_ADDRESS_LENGTH); - - MgntGetEncryptionInfo(Adapter, pTcb, &pTcb->EncInfo, FALSE); - } - } - - // - // Our parser only apply to data frame from upper layer. - // So as admission control. 2007.06.28, by shien chang. - // - if( IsDataFrame(pHeader) && (pTcb->bFromUpperLayer == TRUE)) - { - BOOLEAN bCcxCACEnable = FALSE; - u1Byte CurrCcxVerNumber = 0; - - CCX_QueryVersionNum(Adapter, &CurrCcxVerNumber); - CCX_QueryCACSupport(Adapter, &bCcxCACEnable); - - if((bCcxCACEnable) && CurrCcxVerNumber >= 4) - { - TR_ACTION trAction = TR_ACTION_CONTINUE; - // Parse the packet and decide which action should be take. - trAction = GPParseTCB(Adapter, pTcb, PROTO_WLAN_80211); - if (trAction != TR_ACTION_CONTINUE) - { - // Note: We assume packet were handled in GPParseTCB. - RT_TRACE(COMP_SEND, DBG_TRACE, ("PreTransmitTCB(): Packet were handled\n")); - if (trAction == TR_ACTION_DROPPED) - { - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - } - break; - } - } - - // Admission control by SW. By Bruce, 2009-03-25. - if(pMgntInfo->pStaQos->AcmMethod == eAcmWay2_SW) - { - // - // In admission cotrolled queue, the packet should be - // (1) sent as the UP defined, or - // (2) dropped, if the TSID is defined but the TS is invalid/rejected/non-used, or - // (3) buffered, if the TSID and TS is valid but the used time exceeds the admitted time, or - // (4) mapped to the lower UP that does not require ACM (WiFi test). - // Note: - // If the pMgntInfo->pStaQos->AcmMethod is set eAcmWay2_SW, the ACM is absolutely - // handled by SW and the actions follow the 4 items described of the above. - // By Bruce, 2009-03-25. - // - if (QosAdmissionControl(Adapter, pTcb) ) - { - break; - } - } - - if(RT_SA_QUERY_STATE_UNINITIALIZED != pSecInfo->pmfSaState && !ACTING_AS_AP(Adapter)) - { - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - break; - } - } - - if(AMSDUTransmitTCB(Adapter, &pTcb, pHeader) == FALSE) - return FALSE; - } - - SecFillProtectTxMgntFrameHeader(Adapter, pTcb); - - // <ToDo> - // We need to move this code to TDLS. - if(Adapter->TDLSSupport && pTcb->bTDLPacket && pTcb->bNeedTxReport) - { - if(!TDLS_PrepareTxFeedback(Adapter, pTcb)) - { - RT_TRACE_F(COMP_TDLS, DBG_WARNING, ("TDLS_PrepareTxFeedback failed!\n")); - } - } - - // Forward the frame from local machine to WDS if necessary. - if(bCheckLocalToWds && ACTING_AS_AP(Adapter) && pMgntInfo->WdsMode != WDS_DISABLED) - { - AP_WdsTx(Adapter, pTcb); - } - - bMicFailureReport = IsSecProtMicFailureReport(pTcb->EncInfo.SecProtInfo); - - // Query management for data rate - pTcb->DataRate = MgntQuery_FrameTxRate( Adapter, pTcb ); - - // Calculate TKIP MIC if this packet will be encrypted by HW or SW. - if( (IsFrameTypeData(pHeader) && !IsMgntNullFrame(pHeader)) && // Do not calc MIC for Null Function Data frame. 2005.03.23, by rcnjko. - (!IsSecProtEapolBeforeKeyInstalled(pTcb->EncInfo.SecProtInfo)) && // Do not calc MIC for EAPOL packet before PTK installed. - (!IsFrameWithAddr4(pHeader)) ) // Don't calc MIC for WDS frame since we don't plan to implement TKIP for WDS. 2006.06.12, by rcnjko. - { - SecCalculateMIC(Adapter, pTcb); - }else if( pTcb->EncInfo.bMFPPacket ) - { - // TKIP MFP case - RT_TRACE( COMP_CCX , DBG_LOUD , ("===> TKIP MFP Calculate MIC \n") ); - SecCalculateMIC(Adapter, pTcb); - } - - RemoveZeroLengthBuffer(pTcb); - //2 After this point, the TCB should never contain zero-length buffer - //2 Because all zero-length buffers are reserved for header translation - if( IsFrameTypeData(pHeader) ) - { - if(RT_STATUS_SUCCESS == WAPI_SecFuncHandler(WAPI_PRETRANSMITTCB, Adapter, (PVOID)pTcb, WAPI_END)) - break; - } - - }// end if(pTcb->bDrvAggrProcessed == FALSE) - - if(TxCheckCoalesce(Adapter, pTcb)) - { - if(PreTransmitTxDoCoalesce(Adapter, pTcb, &pHeader) == FALSE)// '&' add by ylb 20130508 for pHeader is wrong when enable AMSDU - break; - } - - //1 Caution: Don't add any code between coalesce and fragment. - //1 Because the length information may be wrong. - if(CheckFragment(Adapter, pTcb, Adapter->TXPacketShiftBytes)) - { - FragmentTCB(Adapter, pTcb); - } - - - //1 Note: In fragment case, we should use FragLength instead of PacketLength - - // Update fragment information for non-fragment case. 2005.03.08, by rcnjko. - if(pTcb->FragCount==1) - { - pTcb->FragLength[0]=(u2Byte)pTcb->PacketLength; - pTcb->FragBufCount[0]=pTcb->BufferCount; - } - - // - // Do not enter QosFillHeader if the frame is NULL frame, because the function will modify - // the QueueID of the TCB. By Bruce, 2008-01-18. - // - if( IsDataFrame(pHeader) && !IsMgntNullFrame(pHeader) && (pMgntInfo->bNicVerifyPkt!=TRUE)) - { - QosFillHeader( Adapter, pTcb ); - } - - RT_ASSERT( pTcb->SpecifiedQueueID!=UNSPECIFIED_QUEUE_ID, ("PreTransmitTCB(): %d: SpecifiedQueueID should not be UNSPECIFIED!!\n", pTcb->SpecifiedQueueID ) ); - - // Fill up WEP bit and IV of each fragment in the TCB if necessary. - if (SecFillHeader(Adapter, pTcb)) - { - // Do software encryption if necessary. - if( !pTcb->EncInfo.IsEncByHW || pSecInfo->SWTxEncryptFlag ) - { - SecSoftwareEncryption(Adapter, pTcb); - } - } - - - // Try to Get SNose for S5 - if( !ACTING_AS_AP(Adapter) && pMgntInfo->PowerSaveControl.WoWLANS5Support) - { - pu1Byte pEapMess = NULL; - u4Byte EapPkLen =0; - BOOLEAN bEncrypt = MgntGetEncryptionInfo( Adapter, pTcb, &pTcb->EncInfo,TRUE); - // We need call this after Coalesce , and EAPoL all need to Coalesced - // EAPoL can't be Fragment !! - if( IsSecProtEapol(pTcb->EncInfo.SecProtInfo) ) - { - // Get 4-Way 2nd Packet!! EAP_HDR_LEN - pEapMess = pTcb->BufferList[0].VirtualAddress + EAP_HDR_LEN; - EapPkLen = pTcb->PacketLength - EAP_HDR_LEN; - if( bEncrypt ) - { - pEapMess = pEapMess + pMgntInfo->SecurityInfo.EncryptionHeadOverhead; - EapPkLen = EapPkLen - pMgntInfo->SecurityInfo.EncryptionHeadOverhead; - } - - if(IsQoSDataFrame(pHeader)) - { - pEapMess = pEapMess + sQoSCtlLng; - EapPkLen = EapPkLen - sQoSCtlLng; - } - //RT_PRINT_DATA(COMP_SEC, DBG_LOUD, "S5 EAPOL remove HDR \n", pEapMess, EapPkLen); - if( (u1Byte)( *(pEapMess+1) ) == LIB1X_EAPOL_KEY) - { - OCTET_STRING pEapKeyMess; - - pEapKeyMess.Octet = pEapMess + LIB1X_EAPOL_HDRLEN; - pEapKeyMess.Length = (u2Byte)(EapPkLen- LIB1X_EAPOL_HDRLEN); - - - if( Message_KeyType(pEapKeyMess) == type_Pairwise ) - { - pu1Byte mbS5SNose = NULL; - u1Byte indexSn = 0; - - mbS5SNose = pEapKeyMess.Octet + KeyNoncePos; - for(indexSn = 0 ; indexSn < KEY_NONCE_LEN ; indexSn++) - { - // Check SNonse != all 0 - if( mbS5SNose[indexSn] != 0 ) - { - PlatformMoveMemory(pMgntInfo->mbS5SNose, mbS5SNose , KEY_NONCE_LEN); - break; - } - } - - } - - } - - RT_PRINT_DATA(COMP_SEC, DBG_LOUD, "S5 mbS5SNose \n", pMgntInfo->mbS5SNose , KEY_NONCE_LEN); - - } - } - - // <ToDo> - // This packet is queued, and just return immediately. - // This is a temporal solution. A known issue between tx aggregation and PS may cause TCBs corrupted. - // Do not check-in this code into the 92SU project. - // By Bruce, 2010-06-02. - psTxStatus = VerifyPsOnTx(Adapter, pTcb); - if(psTxStatus == RT_PS_TX_STATUS_PKT_DROPPED) - { - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - break; - } - else if(psTxStatus == RT_PS_TX_STATUS_PKT_BUFFERED) - { - // RT_PRINT_ADDR(COMP_P2P, DBG_LOUD, "PreTransmitTCB(): Packet Buffered pTcb->DestinationAddress: ", pTcb->DestinationAddress); - break; - } - - // - // Map channel switch pkt to power save condition - // TRUE: buffer pkt - // FALSE: send pkt immediately - if(TDLS_CS_BufferCSTx(Adapter, pTcb)) - { - break; - } -//move redirect Queue for TransmitTCB to here, to fix queue is error after scan -//by sherry 20130117 -#if (MULTICHANNEL_SUPPORT == 1) - { // Redirect packets to specific queue in order to use TxPause to cease packet transmission for a client easily - u1Byte QueueID; - if( - MgntLinkStatusQuery(GetFirstGOPort(Adapter)) == RT_MEDIA_CONNECT || - MgntLinkStatusQuery(GetFirstClientPort(Adapter)) == RT_MEDIA_CONNECT - ) - { - - // Redirect to Specific Queue ------------------------------------------------------- - - // - // <Roger_Notes> We should not redirect queue ID for upper Miracast application, it might cause - // compatibility issue for multi-queue transmission on DMP site. And we need to decide TCB priority for HW-AC mapping - // as well to prevent incorrect TXDMA mapping, e.g., VI_QUEUE(LOW_QUEUE for Non-Qos and default specific queue in AP mode) - // map to QSLT_BE. - // 2013.10.14. - // - if(GetDefaultAdapter(Adapter)->bInHctTest) - QueueID = pTcb->SpecifiedQueueID = MultiChannelRedirectPacketToSpecificQueue(pTcb); - else - QueueID = pTcb->SpecifiedQueueID; - - // ------------------------------------------------------------------------------ - - // SW-AC Queue and HW-AC Queue Coherence (cf. MapHwQueueToFirmwareQueue) --- - switch(QueueID) - { - case BE_QUEUE: pTcb->priority = QSLT_BE; break; - case BK_QUEUE: pTcb->priority = QSLT_BK; break; - case VI_QUEUE: pTcb->priority = QSLT_VI; break; - case VO_QUEUE: pTcb->priority = QSLT_VO; break; - } - // ------------------------------------------------------------------------ - } - RT_TRACE(COMP_MULTICHANNEL, DBG_TRACE,("pretransmitTCB: pTcb->SpecifiedQueueID = %d \n",pTcb->SpecifiedQueueID)); - - // - // Drop miracast RTP packet if necessary - // - { - PMULTICHANNEL_PORT_CONTEXT pPortContext = (PMULTICHANNEL_PORT_CONTEXT)(pTcb->SourceAdapt->MultiChannel); - if(TEST_FLAG(pPortContext->FCSPortState, FCS_STATE_PKT_DROPPED) && (TX_IPTYPE_UDP == pTcb->IPType) ) - { - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - break; - } - } - } -#endif - - if(pHalData->bAutoAMPDUBurstMode && pTcb->SpecifiedQueueID < BEACON_QUEUE) - { - if(pMgntInfo->LinkDetectInfo.bBusyTrafficAccordingTP && pMgntInfo->bMediaConnect && (Adapter->bInHctTest==FALSE)) - { - if( IsFrameTypeData(pHeader)) - { - RTInsertTailListWithCnt(Get_WAIT_QUEUE(Adapter, pTcb->SpecifiedQueueID), &pTcb->List, GET_WAIT_QUEUE_CNT(Adapter,pTcb->SpecifiedQueueID)); - return FALSE; - } - } - - if(!pMgntInfo->LinkDetectInfo.bBusyTrafficAccordingTP && (*GET_WAIT_QUEUE_CNT(Adapter,pTcb->SpecifiedQueueID))> 0) - { - HAL_HW_TIMER_TYPE TimerType = HAL_TIMER_EARLYMODE; - Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_HW_REG_TIMER_RESTART, (pu1Byte)(&TimerType)); - } - } - - // <RJ_TODO> - // 1. We should insert the packet into tail of TcbWaitQueue, - // and transmit it TxHandleInterrupt() or UsbIoCompeleteSentXXX() - // with TransmitTCB(). - // 2. Other conditions: - // Out of TCB, TxDesc, NetworkSetupInProgress(). - if( (IsFrameTypeData(pHeader) && - - ((pMgntInfo->bScanInProgress) || GET_HAL_DATA(Adapter)->bNeedQueuePacketInIQKProgress) && // Marked: To shorten the Ping roundtrip time. Use TxPause to hold packets. - - !IsMgntNullFrame(pHeader) && - !pMgntInfo->bScanWithMagicPacket ) || - FwLPSCheckChangeTxBoundary(Adapter)) // For WOL feature, we must pass data frame in this case. 2005.06.27, by rcnjko. - { - - // We must queue the packet to send during scanning, otherwise - // scan with ping will loss packet. 2004.11.30, by rcnjko. - RTInsertTailListWithCnt(Get_WAIT_QUEUE(Adapter, pTcb->SpecifiedQueueID), &pTcb->List,GET_WAIT_QUEUE_CNT(Adapter,pTcb->SpecifiedQueueID)); - - // If buffer is coalesced, packet should be returned immediately in Platform. - // 2007.07.17, by shien chang. - if ( (ACTING_AS_AP(Adapter) == FALSE) && - (pTcb->BufferType == RT_TCB_BUFFER_TYPE_SYSTEM) && - (TEST_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_USE_COALESCE_BUFFER)) && - (Adapter->NumIdleTcb < TCB_RESOURCE_THRESHOLD) ) - { - { - if(!pTcb->bAggregate && !pTcb->bAMSDUProcessed) - bImmediateComplete = TRUE; - } - } - break; - } - - // Buffer this MPDU if there is already packets in wait queue. 2006.09.22, by rcnjko. - if(PreTransmitWaitQueue(Adapter, pTcb, &bImmediateComplete) == TRUE) - break; - - if(GET_HAL_DATA(Adapter)->AMPDUBurstMode == RT_AMPDU_BRUST_92D || - (GET_HAL_DATA(Adapter)->AMPDUBurstMode == RT_AMPDU_BRUST_8814A )|| - (GET_HAL_DATA(Adapter)->AMPDUBurstMode == RT_AMPDU_BRUST_8822B)) - { - GetTcbDestaddr(Adapter, pTcb, &pRevAddr); - // Check if the A-MPDU aggreagtion is allowed and get its aggregation capabilities/ - MgntQuery_AggregationCapability(Adapter, pRevAddr, pTcb); - //If we use 92D early mode, just insert into WaitQueue for Qos Data. pTcb->bAMPDUEnable not used. - if( pTcb->bAMPDUEnable && Adapter->EarlyMode_QueueNum[pTcb->priority] > Adapter->EarlyMode_Threshold) - { - RTInsertTailList(&Adapter->TcbWaitQueue[pTcb->SpecifiedQueueID], &pTcb->List); - RT_TRACE(COMP_SEND,DBG_LOUD,("InsertTailList(&Adapter->TcbWaitQueue--3.Adapter->EarlyMode_QueueNum[%d]:%d\n",pTcb->priority,Adapter->EarlyMode_QueueNum[pTcb->priority])); - break; - } - } - - if( IsFrameTypeData(pHeader) ) - { - // Start Timer for LED Tx/Rx blinking - if(Adapter->bInHctTest) - { - Adapter->HalFunc.LedControlHandler( Adapter, LED_CTL_TX); - } - else - { - if (Adapter->LedTxCnt == 0) - PlatformSetTimer(Adapter, &pMgntInfo->LedTimer, 50); - } - - Adapter->LedTxCnt++; - } - - // - // NOTE! DO NOT ACCESS pTcb after TransmitTCB() return sucessfully. - // Otherwise, it will cause Tx dead locked at USB path. - // 061122, by rcnjko. - // - rtStatus = TransmitTCB(Adapter, pTcb); - if(RT_STATUS_SUCCESS != rtStatus && RT_STATUS_PKT_DROP != rtStatus) - { - RT_TRACE(COMP_SEND, DBG_LOUD, ("TransmitTcb fail\n")); - RTInsertTailListWithCnt(Get_WAIT_QUEUE(Adapter, pTcb->SpecifiedQueueID), &pTcb->List, GET_WAIT_QUEUE_CNT(Adapter,pTcb->SpecifiedQueueID)); - - // If buffer is coalesced, packet should be returned immediately in Platform. - // 2007.07.17, by shien chang. - if ( (ACTING_AS_AP(Adapter) == FALSE) && - (pTcb->BufferType == RT_TCB_BUFFER_TYPE_SYSTEM) && - (TEST_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_USE_COALESCE_BUFFER)) && - (Adapter->NumIdleTcb < TCB_RESOURCE_THRESHOLD) ) - { - { - if(!pTcb->bAggregate && !pTcb->bAMSDUProcessed) - { - //pTcb->Reserved = NULL; - bImmediateComplete = TRUE; - } - } - //return TRUE; - } - } - - // - // 041005, rcnjko: - // Disassociate from the AP after MIC failure report sent - // if twice MIC error occured in 60 seconds. - // - if( bMicFailureReport && // Replaced with a local varible to prevent access pTcb after TransmitTCB(), 061122, by rcnjko. - pSecInfo->bToDisassocAfterMICFailureReportSend ) // Modified by Annie for WiFi WPA2 Test in SGS, 2006-06-14. - { - // For debug purpose. - RT_PRINT_DATA( COMP_SEC, DBG_LOUD, "PreTransmitTCB(): Send MIC Report", pTcb->BufferList[0].VirtualAddress, pTcb->BufferList[0].Length); - - // Reset bToDisassocAfterMICFailureReportSend. - // <RJ_TODO> bToDisassocAfterMICFailureReportSend has better to be reset - // if the MIC failure report is not sent by upper layer after a period. - pSecInfo->bToDisassocAfterMICFailureReportSend = FALSE; - - // Disassociate from AP. - // Note that, we must relase Tx spinlock before calling MgntActSet_802_11_DISASSOCIATE() - // because SendDisassociation() will acquire it again, which will cause OS hang. - // 2005.08.02, by rcnjko. - PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); - MgntActSet_802_11_DEAUTHENTICATION(Adapter, mic_failure); // Modified for WiFi Mandatory Testplan v1.2: We shall send Deauthentication packet instead of Disassociation packet. Annie, 2006-05-04. - PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); - } - }while(FALSE); - return bImmediateComplete; -} - -BOOLEAN -TxCheckCoalesce( - PADAPTER Adapter, - PRT_TCB pTcb - ) -{ - return TRUE; -} - -BOOLEAN -TxDoCoalesce( - PADAPTER Adapter, - PRT_TCB pTcb - ) -{ - u2Byte i ,BytesCopied=0; - u2Byte FragThreshold, FragLength, Offset, Length; - u1Byte QosCtrlLen = 0; // Added by Annie, 2006-01-08. - BOOLEAN bFragment; - PRT_TX_LOCAL_BUFFER pCoalseceBuffer; - PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); - - //2 Note: Fragment header and encryption header should be reserved here. - - pCoalseceBuffer=GetLocalBuffer(Adapter); - if(pCoalseceBuffer==NULL) - return FALSE; - - // Note that! we have not yet reserved Tx Desc for 8187, so header offset is 0. - bFragment=CheckFragment(Adapter, pTcb, 0); - BytesCopied = Adapter->TXPacketShiftBytes; - - // Consider QoS data frame. Added by Annie, 2006-01-08. - if( IsQoSDataFrame( pTcb->BufferList[0].VirtualAddress ) ) - { - QosCtrlLen = sQoSCtlLng; - } - - //2 Coalesce data - if(!bFragment) - { - for(i=0;i<pTcb->BufferCount;i++) - { - PlatformMoveMemory( - pCoalseceBuffer->Buffer.VirtualAddress+BytesCopied, - pTcb->BufferList[i].VirtualAddress, - pTcb->BufferList[i].Length); - BytesCopied += (u2Byte)pTcb->BufferList[i].Length; - } - - RT_ASSERT(BytesCopied==(pTcb->PacketLength+Adapter->TXPacketShiftBytes), ("Coalesce length mismatch !!\n")); - } - else - { - FragThreshold=FRAGMENT_THRESHOLD(Adapter); - Offset=0; - FragLength=0; - for(i=0;i<pTcb->BufferCount;) - { - if(((pTcb->BufferList[i].Length - Offset) + FragLength) > FragThreshold) - Length=FragThreshold - FragLength; - else - Length=(u2Byte)(pTcb->BufferList[i].Length - Offset); - - PlatformMoveMemory( - pCoalseceBuffer->Buffer.VirtualAddress+BytesCopied, - pTcb->BufferList[i].VirtualAddress + Offset, - Length); - BytesCopied += Length; - FragLength += Length; - Offset += Length; - - if(Offset==pTcb->BufferList[i].Length) - { - Offset=0; - i++; - } - - if(FragLength==FragThreshold && i!=pTcb->BufferCount) - { - BytesCopied += Adapter->TXPacketShiftBytes; - - // Add for ICV or MIC , 2007/12/28 by CCW - BytesCopied += pMgntInfo->SecurityInfo.EncryptionTailOverhead; - - BytesCopied += (sMacHdrLng + QosCtrlLen + pMgntInfo->SecurityInfo.EncryptionHeadOverhead); - FragLength = (sMacHdrLng + QosCtrlLen + pMgntInfo->SecurityInfo.EncryptionHeadOverhead); - } - } - } - - //2 Modify buffer list - pTcb->BufferList[0]=pCoalseceBuffer->Buffer; - pTcb->BufferList[0].Length=BytesCopied; - pTcb->BufferCount=1; - - pTcb->pCoalesceBuffer=pCoalseceBuffer; - SET_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_USE_COALESCE_BUFFER); - - return TRUE; -} - -BOOLEAN -CheckFragment( - PADAPTER Adapter, - PRT_TCB pTcb, - int nHdrOffset // This is the offset of 802.11 header, e.g. 8185=>0, 8187=>USB_HWDESC_HEADER_LEN. - ) -{ - PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; - pu1Byte pHeader = NULL; - pu1Byte pRaddr = NULL; - - pHeader = pTcb->BufferList[0].VirtualAddress+ nHdrOffset; - - pRaddr = pHeader + 4; - - - if(pTcb->bBTTxPacket) - return FALSE; - - //2 Check length - if(pTcb->PacketLength <= FRAGMENT_THRESHOLD(Adapter)) - { - return FALSE; - } - - //2 Check multicast/broadcast - if(MacAddr_isMulticast(pRaddr)) - { - return FALSE; - } - - // Don't perform fragmentation on WDS frame. - if(IsFrameWithAddr4(pHeader)) - { - return FALSE; - } - - //2 Check A-MPDU and A-MSDU aggregation condition - if( pMgntInfo->pHTInfo->bCurrentHTSupport && - (pMgntInfo->pHTInfo->bCurrentAMPDUEnable || - pMgntInfo->pHTInfo->bCurrent_AMSDU_Support || - pMgntInfo->pHTInfo->ForcedAMPDUMode == HT_AMPDU_ENABLE || - (ACTING_AS_AP(Adapter) || ACTING_AS_IBSS(Adapter))) - ) - { - if(ACTING_AS_AP(Adapter) || ACTING_AS_IBSS(Adapter)) - { - PRT_WLAN_STA pEntry = AsocEntry_GetEntry( pMgntInfo, pTcb->DestinationAddress); - if(pEntry != NULL) - { - if(pEntry->IOTAction & HT_IOT_ACT_AMSDU_ENABLE) - return FALSE; - else if(pEntry->IOTAction & HT_IOT_ACT_AMSDU_AMPDU) - return FALSE; - } - } - else - return FALSE; - } - - // Don't do fragmentation on EAP Packet - if( IsSecProtEapol(pTcb->EncInfo.SecProtInfo)== TRUE ) - { - return FALSE; - } - - return TRUE; -} - -VOID -FragmentTCB( - PADAPTER Adapter, - PRT_TCB pTcb - ) -{ - u2Byte i, AddLen, Length, Offset=0; - u2Byte FragThreshold; - u2Byte FragIndex=0, FragLen, FragBufferCount; - u2Byte ReadBufferIndex, WriteBufferIndex=0; - u2Byte BufferCount; - SHARED_MEMORY CoalesceBuffer, BufferList[MAX_PER_PACKET_BUFFER_LIST_LENGTH]; - PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); - u1Byte QosCtrlLen = 0; // Added by Annie, 2006-01-09. - - if(CheckFragment(Adapter, pTcb, Adapter->TXPacketShiftBytes) == FALSE) - return; - - FragThreshold=FRAGMENT_THRESHOLD(Adapter); - - if(TEST_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_USE_COALESCE_BUFFER)) - { // Coalesce case - //2 Note: In this case, header and encryption overhead is already reserved. - - CoalesceBuffer=pTcb->BufferList[0]; - - FragThreshold += Adapter->TXPacketShiftBytes; - - do{ - if((CoalesceBuffer.Length-Offset) > FragThreshold) - { - - Length = FragThreshold; - - } - else - { - Length=(u2Byte)(CoalesceBuffer.Length-Offset); - } - - GET_SHARED_MEMORY_WITH_OFFSET( - &CoalesceBuffer, - &pTcb->BufferList[FragIndex], - Offset, - Length); - - pTcb->FragLength[FragIndex]=Length; - pTcb->FragBufCount[FragIndex]=1; - - Offset+=Length; - - // offset ICV or MIC fild ,2007/12/28 by CCW - Offset += pMgntInfo->SecurityInfo.EncryptionTailOverhead; - - FragIndex++; - }while(Offset<CoalesceBuffer.Length); - - pTcb->FragCount=FragIndex; - pTcb->BufferCount=FragIndex; - } - else - { - // Consider QoS data frame. Added by Annie, 2006-01-09. - if( IsQoSDataFrame( pTcb->BufferList[0].VirtualAddress ) ) - { - QosCtrlLen = sQoSCtlLng; - } - - //2 Duplicate buffer list - BufferCount=pTcb->BufferCount; - PlatformMoveMemory(BufferList, pTcb->BufferList, BufferCount*sizeof(SHARED_MEMORY)); - - FragLen=0; - FragBufferCount=0; - - //2 Get new buffer list and generate fragment information - for(ReadBufferIndex=0; ReadBufferIndex < BufferCount;) - { - if(FragLen + BufferList[ReadBufferIndex].Length > FragThreshold) - { - AddLen=FragThreshold-FragLen; - - pTcb->BufferList[WriteBufferIndex]=BufferList[ReadBufferIndex]; - pTcb->BufferList[WriteBufferIndex].Length=AddLen; - - MAKE_SHARED_MEMORY_OFFSET_AT_FRONT( - &BufferList[ReadBufferIndex], - AddLen); - } - else - { - pTcb->BufferList[WriteBufferIndex]=BufferList[ReadBufferIndex]; - ReadBufferIndex++; - } - FragLen +=(u2Byte)pTcb->BufferList[WriteBufferIndex].Length; - WriteBufferIndex++; - FragBufferCount++; - - if(FragLen==FragThreshold || ReadBufferIndex == BufferCount) - { - pTcb->FragLength[FragIndex]=FragLen; - pTcb->FragBufCount[FragIndex++]=FragBufferCount; - - if(ReadBufferIndex != BufferCount) - { //2 Insert header for 2~ fragment - pTcb->Header[FragIndex].Length=sMacHdrLng+QosCtrlLen+pMgntInfo->SecurityInfo.EncryptionHeadOverhead; - pTcb->BufferList[WriteBufferIndex++]=pTcb->Header[FragIndex]; - - FragLen=sMacHdrLng+QosCtrlLen+pMgntInfo->SecurityInfo.EncryptionHeadOverhead; - FragBufferCount=1; - } - } - } - pTcb->FragCount=FragIndex; - pTcb->BufferCount=WriteBufferIndex; - } - - //2 Duplicate header and set fragment number and more frag - SET_80211_HDR_MORE_FRAG(pTcb->BufferList[0].VirtualAddress+Adapter->TXPacketShiftBytes, 1); // Set more frag - - FragIndex=pTcb->FragBufCount[0]; - for(i=1;i<pTcb->FragCount;i++) - { - PlatformMoveMemory( - pTcb->BufferList[FragIndex].VirtualAddress + Adapter->TXPacketShiftBytes, - pTcb->BufferList[0].VirtualAddress + Adapter->TXPacketShiftBytes, - sMacHdrLng); - - if(i==(pTcb->FragCount-1)) - { - SET_80211_HDR_MORE_FRAG(pTcb->BufferList[FragIndex].VirtualAddress+Adapter->TXPacketShiftBytes, 0); // Clear more frag for last fragment - } - - SET_80211_HDR_FRAGMENT(pTcb->BufferList[FragIndex].VirtualAddress+Adapter->TXPacketShiftBytes, (u1Byte)i); - - FragIndex+=pTcb->FragBufCount[i]; - } -} - -/*----------------------------------------------------------------------------- -// Procedure: Transmit one packet -// - Description: Emily 2006/04/30, For 8190 PCI - When configure tx descriptor under 8190Pci hardware, reserve the - first one descriptor for Firmware Info(not insert, cause the descriptor - address nust be contineous). Then, fill descriptor for each packet - buffer from the second descriptor. Configure first descriptor and - pTcb->nDescUsed++ before set Own bit. - - Joseph 2006/10/13, Revision - Integrate the procedure of protection mode determination and duration - calculation into single function respectively. - TransmitTcb() handle the information of each MSDU. - For further improvement, we can add an function like "HandleMPDUInfo" - to handle specific information of every fragment of MSDU. But now there - are only TxTime calculation is specific to each MPDU, so just leave this - idea for future extension. - Return value: - TransmitTCB returns RT_STATUS_RESOURCE if TransmitTCB occur some error and cannot Tx. - TransmitTCB returns RT_STATUS_PKT_DROP if The current link was teardown, and need to drop packet here. - TransmitTCB returns RT_STATUS_SUCCESS if TransmitTCB OK. -//-----------------------------------------------------------------------------*/ -RT_STATUS -TransmitTCB( - PADAPTER pAdapter, - PRT_TCB pTcb - ) -{ - PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo); - - s2Byte i; - u2Byte firstDesc=0,curDesc=0; - u2Byte FragIndex=0, FragBufferIndex=0, FragBufCount=0; - u2Byte SequenceNumber = 0; - pu1Byte pFrame = GET_FRAME_OF_FIRST_FRAG(pAdapter, pTcb); - u1Byte QueueID = pTcb->SpecifiedQueueID; - pu1Byte pRecvAddr = NULL; - s2Byte BufferCount; - RT_RF_POWER_STATE rfState; - PADAPTER Adapter = GetDefaultAdapter(pAdapter); - - - pMgntInfo = &(Adapter->MgntInfo); - Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (pu1Byte)(&rfState)); - - if(rfState != eRfOn) - { - RT_TRACE(COMP_INIT, DBG_LOUD, ("TransmitTCB return by rfoff, return RT_STATUS_RESOURCE\n")); - return RT_STATUS_RESOURCE; - } - else if (Adapter->ResetProgress != RESET_TYPE_NORESET) - { //cosa add for debug use. 08/23/2007 - return RT_STATUS_RESOURCE; - } - -{ //tynli_test_32k 2011.02.25. - u1Byte FwPSState; - Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_FW_PS_STATE, &FwPSState); - if(IS_IN_LOW_POWER_STATE(pAdapter, FwPSState)) - { - RT_TRACE(COMP_SEND, DBG_LOUD, ("TransmitTCB(): CANNOT TX---> Wake up Hw. return RT_STATUS_RESOURCE\n")); - if( PlatformIsWorkItemScheduled(&(pMgntInfo->PowerSaveControl.FwPsClockOnWorkitem)) == FALSE) - { - RT_TRACE(COMP_SEND, DBG_TRACE, ("ScheduleWorkItem -> FwPsClockOnWorkitem.\n")); - PlatformScheduleWorkItem(&(pMgntInfo->PowerSaveControl.FwPsClockOnWorkitem)); - } - return RT_STATUS_RESOURCE; - } -} - - Adapter->TxStats.NumTransmitTCBCalled[QueueID]++; - - GetTcbDestaddr(Adapter, pTcb, &pRecvAddr); - - // - //<Roger_Notes> Revise following condition to check specific Tx queue for aggregation case. - // -#if TX_AGGREGATION - if(FALSE == pTcb->outPending) - { - if(FALSE == PlatformIsTxQueueAvailable(Adapter, QueueID, pTcb->BufferCount)) - { - Adapter->TxStats.NumTransmitTCBNotAvailable[QueueID]++; - return RT_STATUS_RESOURCE; - } - } - - if(TRUE == pTcb->isUsbTxAgg){ - Adapter->HalFunc.TxFillDescriptorHandler(Adapter, pTcb, 0, 0, 0, 0); - return RT_STATUS_SUCCESS; - } - -#else - if(FALSE == PlatformIsTxQueueAvailable(Adapter, QueueID, pTcb->BufferCount)) - { - Adapter->TxStats.NumTransmitTCBNotAvailable[QueueID]++; - return RT_STATUS_RESOURCE; - } -#endif - - - // Note: - // To prevent lossing tx report from the HW restriction, make sure only one tcb - // with tx feedback info in HW queue. - if(TxFeedbackIsTxFeedbackInfoInstalled(pTcb)) - { - // If this tcb needs tx report, check all queues if there is one tcb with tx - // feedback already in HW tx queues. - if(TxFeedbackExistActiveTxFeedbackInfo(Adapter)) - { - RT_TRACE_F(COMP_CMD, DBG_LOUD, ("Already one tcb with tx feedback in Tx Queue, return FALSE to insert this TCB into wait queue! return RT_STATUS_RESOURCE\n")); - return RT_STATUS_RESOURCE; - } - } - - if(RT_IN_PS_LEVEL(Adapter, RT_RF_LPS_DISALBE_2R)) - { - BOOLEAN Disable2R = FALSE; - Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_RF_2R_DISABLE, (pu1Byte)&Disable2R); - } - - // - // Fill the settings into TCB - // - pTcb->bBroadcast = MgntIsBroadcastFrame( Adapter, pTcb ); - pTcb->bMulticast = MgntIsMulticastFrame( Adapter, pTcb ); - pTcb->bEncrypt = pTcb->EncInfo.IsEncByHW; - - { - MgntQuery_PreambleMode(Adapter, pTcb); - - MgntQuery_TxRateSelectMode(pTcb->SourceAdapt, pTcb); - - if(pTcb->macId == MAC_ID_STATIC_UNSPECIFIED_MACID) - { - RT_TRACE_F(COMP_CMD, DBG_LOUD, ("Return TRUE because Entry was release and the data frame needs to drop, return RT_STATUS_RESOURCE\n")); - ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); - return RT_STATUS_PKT_DROP; - }//if - - // Check if the A-MPDU aggreagtion is allowed and get its aggregation capabilities/ - MgntQuery_AggregationCapability(pTcb->SourceAdapt, pRecvAddr, pTcb); - - /* 2007/03/06 MH This function check if short GI is enabled, and current - transmit bandwidth for TX firmware info in RTL8190. */ - MgntQuery_ShortGI(pTcb->SourceAdapt, pTcb); - - // Get the state if this packet sent by LDPC - MgntQuery_Tx_LDPC(pTcb->SourceAdapt, pTcb); - - // Get the state if this packet sent by STBC - MgntQuery_Tx_STBC(pTcb->SourceAdapt, pTcb); - - // Choose Bandwidth and sub-channel settings - MgntQuery_BandwidthMode(pTcb->SourceAdapt, pTcb); - - // Check if 802.11z is supported - if(pTcb->SourceAdapt->TDLSSupport) - TDLS_QueryCapability(pTcb->SourceAdapt, pTcb); - - - - // - // This function will determine if we need to send protection frame and how to send protection frame. - // And save the result in TCB. - // Although protection mode is determined for each MSDU. This function will use the first fragment of - // the MSDU to make decision and apply the decision to other fragment in this MSDU. - // - MgntQuery_ProtectionFrame(pTcb->SourceAdapt, pTcb); - - } - // - // Sequence number should be the same for every fragment of this packet. 2005.04.14, by rcnjko. - // Management frame and Legacy Data frame use the same number sequence. - // Qos Data frame will use individual number sequence according to destination address and TID. - // - SequenceNumber = MgntQuery_SequenceNumber( - pTcb->SourceAdapt, - pFrame, - pTcb->bBTTxPacket, - pRecvAddr, - pTcb->priority - ); - // - // This function will calculate the duration for each fragmentation(MPDU) of this MSDU. - // The result will save in TCB. - // - MgntQuery_TxTime(pTcb->SourceAdapt, pTcb); - - // - // Filling the information into frame header. - // Duration field and SeqNum field is now handled in this function. - // - FillFrameField(Adapter, pTcb, SequenceNumber); - -#if WLAN_ETW_SUPPORT - // - // Assign sequence number - // - pTcb->TcbSequence = SequenceNumber; -#endif - - //cosa add for debug use. 08/23/2007 - Adapter->TxStats.NumTransmitTCBAvailable[QueueID]++; - - // - // Fill Tx Descriptor - // - if(IS_RW_PTR(Adapter)) - firstDesc=0; - else - firstDesc = curDesc = Adapter->NextTxDescToFill[QueueID]; - - pTcb->nDescUsed=0; - pTcb->nFragSent = 0; - pTcb->nFragCompleted = 0; - Adapter->nFragDescUsed=0; - - BufferCount = pTcb->BufferCount; - - for(i=0;i< pTcb->BufferCount;i++) - { - BOOLEAN bFirstSeg, bLastSeg; - - if(IS_RW_PTR(Adapter)) - { - if(FragBufferIndex == 0) - { - FragBufCount = pTcb->FragBufCount[FragIndex]; - pTcb->nDescUsed++; - Adapter->nFragDescUsed++; - } - } - else - { - if(FragBufferIndex == 0) - FragBufCount = pTcb->FragBufCount[FragIndex]; - Adapter->nFragDescUsed = 1; - pTcb->nDescUsed++; - } - -#if !defined(MUTIPLE_BULK_OUT) - // - // 050413, rcnjko: - // For 8187, we must keep at most one Irp Pending in each endpoint, - // so, we send one fragment in TransmitTCB() and will handle other fragment - // in the complete handler of this endpoint. - // - if(pTcb->nDescUsed == 1) -#endif - { - if(FragBufferIndex == (FragBufCount-1)) - pTcb->nFragSent++; - - if(IS_RW_PTR(Adapter)) - curDesc = Adapter->CurrentTXWritePoint[QueueID]; - -#if WLAN_ETW_SUPPORT - - // - // <Roger_Notes> No activity needs to be associated with this event, the ActivityId is optional and can be NULL. - // 2014.01.14. - // - EventWriteTxSubmissionToNIC( - NULL, //Without associated with the event - pTcb->TcbFrameUniqueueID, //FrameUniqueueID - 0, // QueueLength - 0, // QueueState - 0, // Status - 0, // CustomData1 - 0, // CustomData2 - 0); // CustomData3 -#endif - - Adapter->HalFunc.TxFillDescriptorHandler(Adapter, pTcb, i, FragIndex, FragBufferIndex, curDesc); - } - - bFirstSeg = (FragBufferIndex == 0); - bLastSeg = (FragBufferIndex==(pTcb->FragBufCount[FragIndex]-1) ); - - FragBufferIndex++; - if(FragBufferIndex == FragBufCount) - { - FragIndex++; - FragBufferIndex=0; - } - - if(!IS_RW_PTR(Adapter)) - curDesc=(curDesc+1)%Adapter->NumTxDesc[QueueID]; - - } - - return RT_STATUS_SUCCESS; -} - - - - - -VOID -ResetTxStatistics( - PADAPTER Adapter - ) -{ - PlatformZeroMemory( &Adapter->TxStats, sizeof(RT_TX_STATISTICS) ); -} - - - -VOID -CountTxStatistics( - PADAPTER Adapter, - PRT_TCB pTcb - ) -{ - PMGNT_INFO pMgntInfo=&Adapter->MgntInfo; - PRT_POWER_SAVE_CONTROL pPSC = GET_POWER_SAVE_CONTROL(pMgntInfo); - RT_RF_POWER_STATE rtState; - - Adapter->HalFunc.GetHwRegHandler(GetDefaultAdapter(Adapter), HW_VAR_RF_STATE, (pu1Byte)(&rtState)); - - // When RF is off, we should not count the packet for hw/sw synchronize - // reason, ie. there may be a duration while sw switch is changed and hw - // switch is being changed. 2006.12.04, by shien chang. - if (rtState == eRfOff) - { - return; - } - - if( pTcb->status.TOK ) - { - - //Just record data packets to reduce the traffic flow. 2009.02.02 by tynli. - if(MgntIsDataOnlyFrame(Adapter, pTcb)) - { - Adapter->TxStats.NumTxOkTotal++; - if((pMgntInfo->StaCount > 0)&&(ACTING_AS_AP(Adapter))) - Adapter->TxStats.NumTxOkBytesTotal += pTcb->PacketLength; - else if(!ACTING_AS_AP(Adapter)) - Adapter->TxStats.NumTxOkBytesTotal += pTcb->PacketLength; - pMgntInfo->LinkDetectInfo.NumTxOkInPeriod++; - } - - if(MgntIsMulticastFrame(Adapter, pTcb)) - { - Adapter->TxStats.NumTxMulticast++; - Adapter->TxStats.NumTxBytesMulticast += pTcb->PacketLength; - } - else if(MgntIsBroadcastFrame(Adapter, pTcb)) - { - Adapter->TxStats.NumTxBroadcast++; - Adapter->TxStats.NumTxBytesBroadcast += pTcb->PacketLength; - } - else - { - Adapter->TxStats.NumTxUnicast++; - Adapter->TxStats.NumTxBytesUnicast += pTcb->PacketLength; - - TDLS_CountTxStatistics(Adapter, pTcb); - } - } - else - { - Adapter->TxStats.NumTxErrTotal++; - Adapter->TxStats.NumTxErrBytesTotal += pTcb->PacketLength; - - if(MgntIsMulticastFrame(Adapter, pTcb)) - { - Adapter->TxStats.NumTxErrMulticast++; - } - else if(MgntIsBroadcastFrame(Adapter, pTcb)) - { - Adapter->TxStats.NumTxErrBroadcast++; - } - else - { - Adapter->TxStats.NumTxErrUnicast++; - } - } - Adapter->TxStats.NumTxRetryCount += pTcb->status.DataRetryCount; - -} - -/* - Function:UpdateEarlyModeInfo - Decide the packet whether using Early Mode and the max mumber of packet can be pre-connected. - Just for 92D.by wl. -*/ -BOOLEAN -UpdateEarlyModeInfo( - IN PADAPTER Adapter, - IN PRT_TCB pTcb, - IN PRT_LIST_ENTRY plistHead - ) -{ - PRT_TCB pNextTcb=NULL; - PRT_LIST_ENTRY pEntry=NULL; - pu1Byte pFrame = GET_FRAME_OF_FIRST_FRAG(Adapter, pTcb); - PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; - RT_ENC_ALG ulSwitchCondition =pMgntInfo->SecurityInfo.PairwiseEncAlgorithm; - u1Byte additionLen=0, maxPktNum = EARLY_MODE_MAX_PKT_NUM; - - switch(GET_HAL_DATA(Adapter)->AMPDUBurstMode){ - case RT_AMPDU_BRUST_92D: - maxPktNum = EARLY_MODE_MAX_PKT_NUM_92D; - break; - case RT_AMPDU_BRUST_88E: - maxPktNum = EARLY_MODE_MAX_PKT_NUM_88E; - break; - case RT_AMPDU_BRUST_8812_4: - maxPktNum = 4; - break; - case RT_AMPDU_BRUST_8812_8: - maxPktNum = 8; - break; - case RT_AMPDU_BRUST_8812_12: - maxPktNum = 12; - break; - case RT_AMPDU_BRUST_8812_15: - maxPktNum = EARLY_MODE_MAX_PKT_NUM_8812; - break; - case RT_AMPDU_BRUST_8723B: - maxPktNum = EARLY_MODE_MAX_PKT_NUM_8723B; - break; - case RT_AMPDU_BRUST_8814A: - maxPktNum = EARLY_MODE_MAX_PKT_NUM_8814A; - break; - case RT_AMPDU_BRUST_8822B: - maxPktNum = EARLY_MODE_MAX_PKT_NUM_8822B; - break; - default: - maxPktNum = 0; - break; - } - - if(GET_HAL_DATA(Adapter)->AMPDUBurstNum < maxPktNum) - maxPktNum = GET_HAL_DATA(Adapter)->AMPDUBurstNum; - - switch( ulSwitchCondition ) - { - case RT_ENC_ALG_NO_CIPHER: - additionLen = 4; - break; - - case RT_ENC_ALG_WEP40: - case RT_ENC_ALG_WEP104: - additionLen = 8; - break; - - case RT_ENC_ALG_TKIP: - additionLen = 16; - break; - - case RT_ENC_ALG_AESCCMP: - additionLen = 12; - break; - - case RT_ENC_ALG_SMS4: - additionLen = 20; - break; - - case RT_ENC_ALG_WEP: - default: - break; - } - - if(MacAddr_isBcst(pTcb->DestinationAddress) ||MacAddr_isMulticast(pTcb->DestinationAddress) || !IsQoSDataFrame(pFrame)) - return FALSE; - - // Prefast warning 6011 - if(plistHead != NULL && RTIsListEmpty(plistHead)) - return FALSE; - - // Prefast warning 6011 - if (plistHead != NULL) - { - pEntry = RTGetHeadList(plistHead); - } - - pTcb->EMPktNum = 0; - do{ - pNextTcb = (PRT_TCB)pEntry; - // Prefast warning C6011: Dereferencing NULL pointer 'pNextTcb'. - if((pNextTcb != NULL) && (PlatformCompareMemory(pTcb->DestinationAddress,pNextTcb->DestinationAddress,ETHERNET_ADDRESS_LENGTH) == 0) - && (pTcb->priority == pNextTcb->priority)) - { - pTcb->EMPktLen[pTcb->EMPktNum] =pNextTcb->FragLength[0]+additionLen; - pTcb->EMPktNum ++; - } - else - break; - - // Prefast warning C6011: Dereferencing NULL pointer 'pEntry'. - if (pEntry != NULL) - { - pEntry = pEntry->Flink; - } - }while(pEntry && pEntry != plistHead && pTcb->EMPktNum < maxPktNum); - - return TRUE; -} - -/* -* <Assumption: RT_TX_SPINLOCK is acquired.> -* First added: 2006.11.19 by emily -*/ -RESET_TYPE -TxCheckStuck( - IN PADAPTER Adapter - ) -{ - BOOLEAN bCheckFwTxCnt = FALSE; - u1Byte QueueID; - PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; - PRT_TCB pTcb; - u1Byte ResetThreshold=NIC_SEND_HANG_THRESHOLD_NORMAL; - - // - // Decide Stuch threshold according to current power save mode - // - - switch (pMgntInfo->dot11PowerSaveMode) - { - // The threshold value may required to be adjusted . - case eActive: // Active/Continuous access. - ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL; - break; - case eMaxPs: // Max power save mode. - ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; - break; - case eFastPs: // Fast power save mode. - ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; - break; - default: //for MacOS comipler warning: "eAutoPs" not handled in switch - break; - } - - // - // Check whether specific tcb has been queued for a specific time - // - for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++) - { - - if(RTIsListEmpty(&Adapter->TcbBusyQueue[QueueID])) - continue; - else - { - pTcb = (PRT_TCB)RTGetHeadList(&Adapter->TcbBusyQueue[QueueID]); - pTcb->nStuckCount++; - - if(pTcb->nStuckCount > ResetThreshold) - { - RT_TRACE( COMP_SEND, DBG_SERIOUS, ("<== TxCheckStuck()\n") ); - return RESET_TYPE_SILENT; - } - - bCheckFwTxCnt = TRUE; - } - } - - - if(bCheckFwTxCnt) - { - if(Adapter->HalFunc.TxCheckStuckHandler(Adapter)) - { - RT_TRACE(COMP_SEND, DBG_LOUD, ("TxCheckStuck(): Fw indicates no Tx condition! \n")); - return RESET_TYPE_SILENT; - } - } - - return RESET_TYPE_NORESET; -} -#if TX_AGGREGATION -// -// Assumption: RT_TX_SPINLOCK is acquired. -// -VOID -_ReturnTCB( - PADAPTER pAdapter, - PRT_TCB pTcb, - RT_STATUS status - ) -{ - PADAPTER Adapter = GetDefaultAdapter(pAdapter); - RT_ASSERT(IS_TX_LOCKED(Adapter) == TRUE, ("ReturnTCB(): bTxLocked(%x) should be TRUE\n!", Adapter->bTxLocked)); - - if(pTcb == NULL) - { - // Prevent access violation, 2005.03.06, by rcnjko. - RT_TRACE(COMP_SEND, DBG_SERIOUS, ("ReturnTCB(): pTcb==NULL !!! \n")); - return; - } - - if (TEST_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_USE_COALESCE_BUFFER) && (pTcb->pCoalesceBuffer != NULL)) - { - ReturnLocalBuffer(Adapter, pTcb->pCoalesceBuffer); - } - - switch(pTcb->BufferType) - { - case RT_TCB_BUFFER_TYPE_SYSTEM: - // We MUST release tx spin lock acquired before DrvIFCompletePacket(). - // Otherwise, nested lock acquiration might happen. - // For example, when we plug two 8187 in one machine, it will cause - // OS hangs at RtUsbSend(). 2005.11.17, by rcnjko. - if(pTcb->Reserved != NULL) - { - PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); - DrvIFCompletePacket(Adapter, pTcb, status); - PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); - } - break; - - case RT_TCB_BUFFER_TYPE_LOCAL: - ReturnLocalBuffer(Adapter, (PRT_TX_LOCAL_BUFFER)pTcb->Reserved); - break; - - case RT_TCB_BUFFER_TYPE_BT_LOCAL: - break; - - case RT_TCB_BUFFER_TYPE_RFD: - ReturnRFDList(Adapter, (PRT_RFD)pTcb->Reserved); - break; - - case RT_TCB_BUFFER_TYPE_FW_LOCAL: - ReturnLocalFWBuffer(Adapter, (PRT_TX_LOCAL_BUFFER)pTcb->Reserved); - break; - - default: - RT_ASSERT(FALSE, ("ReturnTCB: unknow pTcb->BufferType: 0x%x!!!\n", pTcb->BufferType)); - break; - } - - if(pTcb->bAggregate) - { - u1Byte i; - for(i = 0; i < pTcb->AggregateNum; i++) - ReturnTCB(Adapter, pTcb->AggregatedTCB[i], RT_STATUS_SUCCESS); - } - - // Initialize TCB before insert it into TcbIdleQueue, 2005.07.06, by rcnjko. - CLEAR_FLAGS(pTcb->tcbFlags); - pTcb->DataRate=UNSPECIFIED_DATA_RATE; - pTcb->bSpecifShortGI = FALSE; - pTcb->bUseShortGI = FALSE; - pTcb->bLDPC = FALSE; - pTcb->bSTBC = FALSE; - pTcb->PacketLength = 0; - pTcb->BufferCount = 0; - pTcb->Reserved = NULL; - pTcb->priority = 0; - pTcb->EncInfo.SecProtInfo = RT_SEC_NORMAL_DATA; - pTcb->EncInfo.IsEncByHW = FALSE; // Null Function Data Len_Adjust debug, Annie, 2006-01-06. - pTcb->bFromUpperLayer = FALSE; - pTcb->TSID = DEFAULT_TSID; - pTcb->BWOfPacket = CHANNEL_WIDTH_20; - pTcb->bAggregate = FALSE; - pTcb->bAMSDUProcessed = FALSE; - pTcb->nStuckCount = 0; - pTcb->bAMPDUEnable = FALSE; - pTcb->AMPDUDensity = 0; - pTcb->AMPDUFactor = 0; - pTcb->bTxDisableRateFallBack = FALSE; - pTcb->bTxUseDriverAssingedRate = FALSE; - pTcb->bTxCalculatedSwDur = FALSE; - pTcb->bTxEnableSwCalcDur = FALSE; - pTcb->specialDataType = PACKET_NORMAL; - pTcb->macId = 0; - pTcb->P_AID = 0; - pTcb->G_ID = 0; - pTcb->bBTTxPacket = FALSE; - pTcb->BT_macId = 0; - pTcb->sysTime[0] = 0; - pTcb->sysTime[1] = 0; - pTcb->sysTime[2] = 0; - pTcb->sysTime[3] = 0; - pTcb->TxBFPktType = RT_BF_PKT_TYPE_NONE; - - pTcb->TcpOffloadMode = 0; - pTcb->MACHeardLen = 0; - - pTcb->outPending = FALSE; - pTcb->isUsbTxAgg = FALSE; - pTcb->aggNum = 0; - - pTcb->bNeedTxReport = FALSE; - pTcb->bTDLPacket = FALSE; - pTcb->bSendPTIRsp = FALSE; - pTcb->bSleepPkt = FALSE; - if(GET_HAL_DATA(Adapter)->AMPDUBurstMode) - { - pTcb->bEnableEarlyMode = FALSE; - pTcb->EMPktNum = 0; - PlatformZeroMemory(pTcb->EMPktLen,sizeof(pTcb->EMPktLen)); - } - RESET_CCX_PACKET_TX_INFO(pTcb); - - TxFeedbackDeInstallTxFeedbackInfoForTcb(Adapter, pTcb); - - RTInsertTailListWithCnt(&Adapter->TcbIdleQueue, &pTcb->List, &Adapter->NumIdleTcb); - RT_TRACE(COMP_SEND, DBG_LOUD, ("_ReturnTCB(), Adapter->NumIdleTcb = %d\n", Adapter->NumIdleTcb)); -} - - -VOID -ReturnTCB( - PADAPTER pAdapter, - PRT_TCB pTcb, - RT_STATUS status - ) -{ - if(pTcb->isUsbTxAgg) - { - RT_LIST_ENTRY aggList; - - if(RTIsListEmpty(&pTcb->aggListHead)){ - _ReturnTCB(pAdapter, pTcb, status); - return; - } - - RTInitializeListHead(&aggList); - RTSwitchListHead(&pTcb->aggListHead, &aggList); - _ReturnTCB(pAdapter, pTcb, status); - - while(RTIsListNotEmpty(&aggList)) - { - PRT_TCB pAggTcb = (PRT_TCB)RTRemoveHeadList(&aggList); - _ReturnTCB(pAdapter, pAggTcb, status); - } - } - else - _ReturnTCB(pAdapter, pTcb, status); -} - - -#else -// -// Assumption: RT_TX_SPINLOCK is acquired. -// -VOID -ReturnTCB( - PADAPTER pAdapter, - PRT_TCB pTcb, - RT_STATUS status - ) -{ - PADAPTER pDefaultAdapter = GetDefaultAdapter(pAdapter); - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pDefaultAdapter); - - RT_ASSERT(IS_TX_LOCKED(pDefaultAdapter) == TRUE, ("ReturnTCB(): bTxLocked(%x) should be TRUE\n!", pDefaultAdapter->bTxLocked)); - - if(pTcb == NULL) - { - // Prevent access violation, 2005.03.06, by rcnjko. - RT_TRACE(COMP_SEND, DBG_SERIOUS, ("ReturnTCB(): pTcb==NULL !!! \n")); - return; - } - - if (TEST_FLAG(pTcb->tcbFlags, RT_TCB_FLAG_USE_COALESCE_BUFFER)) - { - ReturnLocalBuffer(pDefaultAdapter, pTcb->pCoalesceBuffer); // coalesece buffer is belong to each adapter. - } - - switch(pTcb->BufferType) - { - case RT_TCB_BUFFER_TYPE_SYSTEM: - - if(pTcb->ColoaseMethod == 2) - { - u1Byte i=0; - - for (i=0; i<pTcb->BufferBackCount; i++) - { - //pTcb->BufferList[i+1] = pTcb->BufferListBack[i]; - //pTcb->BufferList[i+1].Length= pTcb->BufferListBack[i].Length; - pTcb->BufferList[i] = pTcb->BufferListBack[i]; - } - } - - // We MUST release tx spin lock acquired before DrvIFCompletePacket(). - // Otherwise, nested lock acquiration might happen. - // For example, when we plug two 8187 in one machine, it will cause - // OS hangs at RtUsbSend(). 2005.11.17, by rcnjko. - if(pTcb->Reserved != NULL) - { - PlatformReleaseSpinLock(pDefaultAdapter, RT_TX_SPINLOCK); - DrvIFCompletePacket(pDefaultAdapter, pTcb, status); - PlatformAcquireSpinLock(pDefaultAdapter, RT_TX_SPINLOCK); - } - break; - - case RT_TCB_BUFFER_TYPE_LOCAL: - if(pTcb->bTxCompleteLater) - { - PlatformReleaseSpinLock(pDefaultAdapter, RT_TX_SPINLOCK); - DrvIFCompletePacket(pDefaultAdapter, pTcb, RT_STATUS_SUCCESS); - PlatformAcquireSpinLock(pDefaultAdapter, RT_TX_SPINLOCK); - } - ReturnLocalBuffer(pDefaultAdapter, (PRT_TX_LOCAL_BUFFER)pTcb->Reserved); - break; - - case RT_TCB_BUFFER_TYPE_BT_LOCAL: - BT_ReturnDataBuffer(pDefaultAdapter, (PRT_TX_LOCAL_BUFFER)pTcb->Reserved); - break; - - case RT_TCB_BUFFER_TYPE_RFD: - ReturnRFDList(pDefaultAdapter, (PRT_RFD)pTcb->Reserved); - break; - - case RT_TCB_BUFFER_TYPE_FW_LOCAL: - ReturnLocalFWBuffer(pDefaultAdapter, (PRT_TX_LOCAL_BUFFER)pTcb->Reserved); - break; - - default: - RT_ASSERT(FALSE, ("ReturnTCB: unknow pTcb->BufferType: 0x%x!!!\n", pTcb->BufferType)); - break; - } - - if(pTcb->bAggregate) - { - u1Byte i; - for(i = 0; i < pTcb->AggregateNum; i++) - ReturnTCB(pDefaultAdapter, pTcb->AggregatedTCB[i], RT_STATUS_SUCCESS); - } - - // Initialize TCB before insert it into TcbIdleQueue, 2005.07.06, by rcnjko. - CLEAR_FLAGS(pTcb->tcbFlags); - if(pTcb->bTxCompleteLater) - { - pTcb->bTxCompleteLater = FALSE; - pTcb->ReservedBack = NULL; - } - pTcb->DataRate=UNSPECIFIED_DATA_RATE; - pTcb->bSpecifShortGI = FALSE; - pTcb->bUseShortGI = FALSE; - pTcb->bLDPC = FALSE; - pTcb->bSTBC = FALSE; - pTcb->PacketLength = 0; - pTcb->BufferCount = 0; - pTcb->BufferType = RT_TCB_BUFFER_TYPE_NONE; - pTcb->Reserved = NULL; - pTcb->priority = 0; - pTcb->EncInfo.SecProtInfo = RT_SEC_NORMAL_DATA; - pTcb->EncInfo.IsEncByHW = FALSE; // Null Function Data Len_Adjust debug, Annie, 2006-01-06. - pTcb->bFromUpperLayer = FALSE; - pTcb->TSID = DEFAULT_TSID; - pTcb->BWOfPacket = CHANNEL_WIDTH_20; - pTcb->bAggregate = FALSE; - pTcb->bAMSDUProcessed = FALSE; - pTcb->nStuckCount = 0; - pTcb->bAMPDUEnable = FALSE; - pTcb->AMPDUDensity = 0; - pTcb->AMPDUFactor = 0; - pTcb->bTxDisableRateFallBack = FALSE; - pTcb->bTxUseDriverAssingedRate = FALSE; - pTcb->bTxCalculatedSwDur = FALSE; - pTcb->bTxEnableSwCalcDur = FALSE; - pTcb->specialDataType = PACKET_NORMAL; - pTcb->macId = 0; - pTcb->P_AID = 0; - pTcb->G_ID = 0; - pTcb->bBTTxPacket = FALSE; - pTcb->BT_macId = 0; - pTcb->EncInfo.bMFPPacket = FALSE; // CCX V65 Reset - pTcb->sysTime[0] = 0; - pTcb->sysTime[1] = 0; - pTcb->sysTime[2] = 0; - pTcb->sysTime[3] = 0; - - pTcb->TcpOffloadMode = 0; - pTcb->MACHeardLen = 0; - pTcb->IPType = 0; - - -#if TX_AGGREGATION - pTcb->outPending = FALSE; - pTcb->isUsbTxAgg = FALSE; -#endif - - pTcb->bNeedTxReport = FALSE; - pTcb->bTDLPacket = FALSE; - pTcb->bSendPTIRsp = FALSE; - pTcb->bSleepPkt = FALSE; - pTcb->bInsert8BytesForEarlyMode = FALSE; - pTcb->status.TOK=FALSE; - pTcb->CurrentWritePoint = 0; - pTcb->bHwProtection = FALSE; - -#if WLAN_ETW_SUPPORT - // - // <MIRACAST_TODO> - // - pTcb->TcbFrameUniqueueID = 0; -#endif - - if(GET_HAL_DATA(pDefaultAdapter)->AMPDUBurstMode) - { - pTcb->bEnableEarlyMode = FALSE; - pTcb->EMPktNum = 0; - PlatformZeroMemory(pTcb->EMPktLen,sizeof(pTcb->EMPktLen)); - } - - RESET_CCX_PACKET_TX_INFO(pTcb); - - TxFeedbackDeInstallTxFeedbackInfoForTcb(pDefaultAdapter, pTcb); - - RTInsertTailListWithCnt(&pDefaultAdapter->TcbIdleQueue, &pTcb->List, &pDefaultAdapter->NumIdleTcb); - RT_TRACE(COMP_SEND, DBG_LOUD, ("ReturnTCB(), pAdapter->NumIdleTcb = %d\n", pDefaultAdapter->NumIdleTcb)); -} -#endif - -PRT_TX_LOCAL_BUFFER -GetLocalFWBuffer( - PADAPTER Adapter - ) -{ - PRT_TX_LOCAL_BUFFER pBuffer; - PADAPTER pDefaultAdapter = GetDefaultAdapter(Adapter); - - if(RTIsListEmpty(&pDefaultAdapter->LocalFWBufferQueue)) - return NULL; - - pBuffer=(PRT_TX_LOCAL_BUFFER)RTRemoveHeadListWithCnt(&pDefaultAdapter->LocalFWBufferQueue, &pDefaultAdapter->NumLocalFWBufferIdle); - - return pBuffer; -} - -PRT_TX_LOCAL_BUFFER -GetLocalBuffer( - PADAPTER pAdapter - ) -{ - PRT_TX_LOCAL_BUFFER pBuffer; - PADAPTER pDefaultAdapter = GetDefaultAdapter(pAdapter); - - if(RTIsListEmpty(&pDefaultAdapter->LocalBufferQueue)) - return NULL; - - pBuffer=(PRT_TX_LOCAL_BUFFER)RTRemoveHeadListWithCnt(&pDefaultAdapter->LocalBufferQueue, &pDefaultAdapter->NumLocalBufferIdle); - - return pBuffer; -} - -VOID -ReturnLocalBuffer( - PADAPTER pAdapter, - PRT_TX_LOCAL_BUFFER pLocalBuffer - ) -{ - PADAPTER pDefaultAdapter = GetDefaultAdapter(pAdapter); - //RTInsertTailList(&Adapter->LocalBufferQueue, &pLocalBuffer->List); - RTInsertTailListWithCnt(&pDefaultAdapter->LocalBufferQueue, &pLocalBuffer->List, &pDefaultAdapter->NumLocalBufferIdle); - -} - -VOID -ReturnLocalFWBuffer( - PADAPTER Adapter, - PRT_TX_LOCAL_BUFFER pLocalBuffer - ) -{ - PADAPTER pDefaultAdapter = GetDefaultAdapter(Adapter); - RTInsertTailListWithCnt(&pDefaultAdapter->LocalFWBufferQueue, &pLocalBuffer->List, &pDefaultAdapter->NumLocalFWBufferIdle); -} - -// -// Description: -// Wait all the packets queued in the tx busy queues until these packets completed or timeout. -// Return Value: -// TRUE: All packets are completed. -// FALSE: Timeout, but not all packets are completed. -// Assumption: -// PASSIVE_LEVEL -// Note: -// (1) If this procedure should be separated by HAL Code based, move it to HAL. -// By Bruce, 2008-01-17. -// -BOOLEAN -WaitTxBusyQueueComplete( - PADAPTER Adapter - ) -{ - BOOLEAN bResult = TRUE; - u1Byte QueueID; - int WaitingCnt; - - for(QueueID = 0, WaitingCnt = 0; QueueID < MAX_TX_QUEUE; ) - { - if(RTIsListEmpty(&Adapter->TcbBusyQueue[QueueID])) - { - QueueID++; - continue; - } - else - { - RT_TRACE(COMP_POWER, DBG_TRACE, ("WaitTxBusyQueueComplete(): %d times TcbBusyQueue[%d] !=0 !\n", (WaitingCnt+1), QueueID)); - PlatformSleepUs(10); - WaitingCnt ++; - } - - if(WaitingCnt >= MAX_DOZE_WAITING_TIMES) - { - RT_TRACE(COMP_POWER, DBG_WARNING, ("\n\nWaitTxBusyQueueComplete(): %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES, QueueID)); - bResult = FALSE; - break; - } - } - return bResult; -} - -// -// Description: -// Release all the packets from Tx/Rx Wait queues and return them to the upper layer. -// Assumption: -// RT_TX_SPIN_LOCK is not acquired. -// By Bruce, 2008-11-28. -// -VOID -ReleaseDataFrameQueued( - IN PADAPTER pAdapter - ) -{ - u1Byte QueueID; - PRT_TCB pTcb; - PRT_LIST_ENTRY pEntry; - u4Byte RtnCnt=0; - - PlatformAcquireSpinLock(pAdapter, RT_TX_SPINLOCK); - - // Return all packets in Tcb wait queues. - for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++) - { - pEntry = RTGetHeadList(Get_WAIT_QUEUE(pAdapter, QueueID)); - - while(!RTIsListHead((Get_WAIT_QUEUE(pAdapter,QueueID)), pEntry)) - { - pTcb = (PRT_TCB)pEntry; - pEntry = RTNextEntryList(pEntry); - - if(pAdapter == pTcb->SourceAdapt) - { - RTRemoveEntryListWithCnt((PRT_LIST_ENTRY)pTcb, GET_WAIT_QUEUE_CNT(pAdapter, QueueID)); - RtnCnt++; - ReturnTCB(pAdapter, pTcb, RT_STATUS_SUCCESS); - } - } - } - - RT_TRACE(COMP_SEND, DBG_LOUD, ("ReleaseDataFramemQueued(), free %d pTcb from TcbWaitQueue[].\n", RtnCnt)); - - if(!OS_SUPPORT_WDI(pAdapter)) - { - // Return all packets in platform wait queue. - PlatformReleaseDataFrameQueued(pAdapter); - } - - PlatformReleaseSpinLock(pAdapter, RT_TX_SPINLOCK); -} - -// -// Description: -// Copy the packet from the os to the local buffer. -// Arguments: -// [in] pAdapter - -// The adpater context. -// [in, out] pTcb - -// The TCB to colesce. -// Return: -// Return TRUE if coalescence is performed, or return FALSE. -// Note: -// RT_TX_SPINLOCK is already acquired. -// By Bruce, 2010-10-14. -// -BOOLEAN -TCB_CopySystemPacketToLocal( - IN PADAPTER pAdapter, - IN OUT PRT_TCB pTcb - ) -{ - PRT_TX_LOCAL_BUFFER pBuf; - u1Byte i = 0; - SHARED_MEMORY tmpBufferList[MAX_PER_PACKET_BUFFER_LIST_LENGTH]; - u4Byte localBufOffset = 0; - - // If the buffer type is already local buffer, do nothing. - if(pTcb->BufferType != RT_TCB_BUFFER_TYPE_SYSTEM) - return FALSE; - - pBuf = GetLocalBuffer(pAdapter); - if(pBuf == NULL) - { - RT_TRACE_F(COMP_MLME, DBG_WARNING, ("[WARNING] No local buffer to copy this packet to local!\n")); - return FALSE; - } - - for(i = 0; i < pTcb->BufferCount; i ++) - { - // Point to the local buffer. - tmpBufferList[i].VirtualAddress = pBuf->Buffer.VirtualAddress + localBufOffset; - tmpBufferList[i].PhysicalAddressLow = pBuf->Buffer.PhysicalAddressLow + localBufOffset; - tmpBufferList[i].PhysicalAddressHigh = pBuf->Buffer.PhysicalAddressHigh; - if(tmpBufferList[i].PhysicalAddressLow < pBuf->Buffer.PhysicalAddressLow) - tmpBufferList[i].PhysicalAddressHigh ++; - - if(pTcb->BufferList[i].Length > 0) - { - PlatformMoveMemory(tmpBufferList[i].VirtualAddress, pTcb->BufferList[i].VirtualAddress, pTcb->BufferList[i].Length); - } - tmpBufferList[i].Length = pTcb->BufferList[i].Length; - - localBufOffset += pTcb->BufferList[i].Length; - } - - // Complete this packet to OS. - PlatformReleaseSpinLock(pAdapter, RT_TX_SPINLOCK); - DrvIFCompletePacket(pAdapter, pTcb, RT_STATUS_SUCCESS); - PlatformAcquireSpinLock(pAdapter, RT_TX_SPINLOCK); - - // Resotre the content buffer - for(i = 0; i < pTcb->BufferCount; i ++) - { - pTcb->BufferList[i] = tmpBufferList[i]; - } - pTcb->BufferType = RT_TCB_BUFFER_TYPE_LOCAL; - pTcb->Reserved = pBuf; - - return TRUE; -} - - - - - -#if 1 -//================================================== -// For general tx handle thread -//================================================== -VOID -tx_generalThreadCallback( - IN PVOID pContext - ) -{ - PADAPTER Adapter=((PRT_THREAD)pContext)->Adapter; - - if (KeGetCurrentIrql() > PASSIVE_LEVEL) - { - RT_ASSERT(FALSE, ("[TX], tx_generalThreadCallback() can only run under PASSIVE_LEVEL!!\n")); - return; - } - else - { - RT_TRACE(COMP_INIT, DBG_LOUD, ("[TX], Tx general thread is started!!!\n")); - } - - while(1) - { - if(RT_DRIVER_HALT(Adapter)) - { - RT_TRACE(COMP_SEND, DBG_LOUD, ("[TX], Tx general thread is stopped because bDriverStopped(%d) or bSurpriseRemoved(%d)!!!\n", - Adapter->bDriverStopped, Adapter->bSurpriseRemoved)); - break; - } - - if( PlatformAcquireSemaphore(&Adapter->txGen.txGenSemaphore) != RT_STATUS_SUCCESS ) - { - RT_TRACE(COMP_SEND, DBG_LOUD, ("[TX], Acquire Tx general thread semaphore not successful !!!\n")); - break; - } - else - { - RT_TRACE(COMP_SEND, DBG_LOUD, ("[TX], Tx general thread to execute normal routine !!!\n")); - DrvIFCheckTxCredit(Adapter); - } - } - - RT_TRACE(COMP_INIT, DBG_LOUD, ("[TX], Tx general thread is ended!!!\n")); -} - - -VOID -TX_InitThreads( - IN PADAPTER Adapter - ) -{ - RT_TRACE(COMP_INIT, DBG_LOUD, ("[TX], TX_InitThreads()\n")); - - PlatformInitializeSemaphore(&Adapter->txGen.txGenSemaphore, 0); - - PlatformInitializeThread( - Adapter, - &Adapter->txGen.txGenThread, - (RT_THREAD_CALL_BACK)tx_generalThreadCallback, - "tx_generalThreadCallback", - FALSE, - 0, - NULL); - - PlatformRunThread( - Adapter, - &Adapter->txGen.txGenThread, - PASSIVE_LEVEL, - NULL); -} - -VOID -TX_DeInitThreads( - IN PADAPTER Adapter - ) -{ - RT_TRACE(COMP_INIT, DBG_LOUD, ("[TX], TX_DeInitThreads()\n")); - - PlatformReleaseSemaphore(&Adapter->txGen.txGenSemaphore); - PlatformFreeSemaphore(&Adapter->txGen.txGenSemaphore); - - PlatformWaitThreadEnd(Adapter, &(Adapter->txGen.txGenThread)); - PlatformCancelThread(Adapter, &(Adapter->txGen.txGenThread)); - PlatformReleaseThread(Adapter, &(Adapter->txGen.txGenThread)); -} - -VOID -TX_InitializeVariables( - IN PADAPTER Adapter - ) -{ - RT_TRACE(COMP_INIT, DBG_LOUD, ("[TX], TX_InitializeVariables()\n")); -} - -VOID -TX_InitializeSpinlock( - IN PADAPTER Adapter - ) -{ - RT_TRACE(COMP_INIT, DBG_LOUD, ("[TX], TX_InitializeSpinlock()\n")); - -} - -VOID -TX_FreeSpinlock( - IN PADAPTER Adapter - ) -{ - RT_TRACE(COMP_INIT, DBG_LOUD, ("[TX], TX_FreeSpinlock()\n")); - -} - -#endif - - - |
