diff options
Diffstat (limited to 'drivers/staging/rt3070/common/cmm_data_2870.c')
-rw-r--r-- | drivers/staging/rt3070/common/cmm_data_2870.c | 981 |
1 files changed, 1 insertions, 980 deletions
diff --git a/drivers/staging/rt3070/common/cmm_data_2870.c b/drivers/staging/rt3070/common/cmm_data_2870.c index b1066aa2bb23..0e51ee414a2c 100644 --- a/drivers/staging/rt3070/common/cmm_data_2870.c +++ b/drivers/staging/rt3070/common/cmm_data_2870.c @@ -1,980 +1 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* -*/ -/* - All functions in this file must be USB-depended, or you should out your function - in other files. - -*/ -#include "../rt_config.h" - - -/* - We can do copy the frame into pTxContext when match following conditions. - => - => - => -*/ -static inline NDIS_STATUS RtmpUSBCanDoWrite( - IN RTMP_ADAPTER *pAd, - IN UCHAR QueIdx, - IN HT_TX_CONTEXT *pHTTXContext) -{ - NDIS_STATUS canWrite = NDIS_STATUS_RESOURCES; - - if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition) - { - DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n")); - RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); - } - else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE)) - { - DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n")); - RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); - } - else if (pHTTXContext->bCurWriting == TRUE) - { - DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n")); - } - else - { - canWrite = NDIS_STATUS_SUCCESS; - } - - - return canWrite; -} - - -USHORT RtmpUSB_WriteSubTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN BOOLEAN bIsLast, - OUT USHORT *FreeNumber) -{ - - // Dummy function. Should be removed in the future. - return 0; - -} - -USHORT RtmpUSB_WriteFragTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN UCHAR fragNum, - OUT USHORT *FreeNumber) -{ - HT_TX_CONTEXT *pHTTXContext; - USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length. - UINT32 fillOffset; - TXINFO_STRUC *pTxInfo; - TXWI_STRUC *pTxWI; - PUCHAR pWirelessPacket = NULL; - UCHAR QueIdx; - NDIS_STATUS Status; - unsigned long IrqFlags; - UINT32 USBDMApktLen = 0, DMAHdrLen, padding; - BOOLEAN TxQLastRound = FALSE; - - // - // get Tx Ring Resource & Dma Buffer address - // - QueIdx = pTxBlk->QueIdx; - pHTTXContext = &pAd->TxContext[QueIdx]; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - pHTTXContext = &pAd->TxContext[QueIdx]; - fillOffset = pHTTXContext->CurWritePosition; - - if(fragNum == 0) - { - // Check if we have enough space for this bulk-out batch. - Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); - if (Status == NDIS_STATUS_SUCCESS) - { - pHTTXContext->bCurWriting = TRUE; - - // Reserve space for 8 bytes padding. - if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) - { - pHTTXContext->ENextBulkOutPosition += 8; - pHTTXContext->CurWritePosition += 8; - fillOffset += 8; - } - pTxBlk->Priv = 0; - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - } - else - { - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); - return(Status); - } - } - else - { - // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. - Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE); - if (Status == NDIS_STATUS_SUCCESS) - { - fillOffset += pTxBlk->Priv; - } - else - { - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); - return(Status); - } - } - - NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE); - pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); - pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); - - pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; - - // copy TXWI + WLAN Header + LLC into DMA Header Buffer - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); - hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - // Build our URB for USBD - DMAHdrLen = TXWI_SIZE + hwHdrLen; - USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen; - padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment - USBDMApktLen += padding; - - pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen); - - // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload - RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); - - if (fragNum == pTxBlk->TotalFragNum) - { - pTxInfo->USBDMATxburst = 0; - if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT) - { - pTxInfo->SwUseLastRound = 1; - TxQLastRound = TRUE; - } - } - else - { - pTxInfo->USBDMATxburst = 1; - } - - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen); -#ifdef RT_BIG_ENDIAN - RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE); -#endif // RT_BIG_ENDIAN // - pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); - - // Zero the last padding. - pWirelessPacket += pTxBlk->SrcBufLen; - NdisZeroMemory(pWirelessPacket, padding + 8); - - if (fragNum == pTxBlk->TotalFragNum) - { - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - // Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame. - pHTTXContext->CurWritePosition += pTxBlk->Priv; - if (TxQLastRound == TRUE) - pHTTXContext->CurWritePosition = 8; - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - - // Finally, set bCurWriting as FALSE - pHTTXContext->bCurWriting = FALSE; - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - // succeed and release the skb buffer - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); - } - - - return(Status); - -} - - -USHORT RtmpUSB_WriteSingleTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN BOOLEAN bIsLast, - OUT USHORT *FreeNumber) -{ - HT_TX_CONTEXT *pHTTXContext; - USHORT hwHdrLen; - UINT32 fillOffset; - TXINFO_STRUC *pTxInfo; - TXWI_STRUC *pTxWI; - PUCHAR pWirelessPacket; - UCHAR QueIdx; - unsigned long IrqFlags; - NDIS_STATUS Status; - UINT32 USBDMApktLen = 0, DMAHdrLen, padding; - BOOLEAN bTxQLastRound = FALSE; - - // For USB, didn't need PCI_MAP_SINGLE() - //SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE); - - - // - // get Tx Ring Resource & Dma Buffer address - // - QueIdx = pTxBlk->QueIdx; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - pHTTXContext = &pAd->TxContext[QueIdx]; - fillOffset = pHTTXContext->CurWritePosition; - - - - // Check ring full. - Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); - if(Status == NDIS_STATUS_SUCCESS) - { - pHTTXContext->bCurWriting = TRUE; - - pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); - pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); - - // Reserve space for 8 bytes padding. - if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) - { - pHTTXContext->ENextBulkOutPosition += 8; - pHTTXContext->CurWritePosition += 8; - fillOffset += 8; - } - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; - - // copy TXWI + WLAN Header + LLC into DMA Header Buffer - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); - hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - // Build our URB for USBD - DMAHdrLen = TXWI_SIZE + hwHdrLen; - USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen; - padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment - USBDMApktLen += padding; - - pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen); - - // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload - //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) -#ifdef CONFIG_STA_SUPPORT - IF_DEV_CONFIG_OPMODE_ON_STA(pAd) - RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); -#endif // CONFIG_STA_SUPPORT // - - if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT) - { - pTxInfo->SwUseLastRound = 1; - bTxQLastRound = TRUE; - } - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen); -#ifdef RT_BIG_ENDIAN - RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE); -#endif // RT_BIG_ENDIAN // - pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - - // We unlock it here to prevent the first 8 bytes maybe over-writed issue. - // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext. - // 2. An interrupt break our routine and handle bulk-out complete. - // 3. In the bulk-out compllete, it need to do another bulk-out, - // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, - // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. - // 4. Interrupt complete. - // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. - // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. - // and the packet will wrong. - pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); - pWirelessPacket += pTxBlk->SrcBufLen; - NdisZeroMemory(pWirelessPacket, padding + 8); - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - pHTTXContext->CurWritePosition += pTxBlk->Priv; - if (bTxQLastRound) - pHTTXContext->CurWritePosition = 8; - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - pHTTXContext->bCurWriting = FALSE; - } - - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - - // succeed and release the skb buffer - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); - - return(Status); - -} - - -USHORT RtmpUSB_WriteMultiTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN UCHAR frameNum, - OUT USHORT *FreeNumber) -{ - HT_TX_CONTEXT *pHTTXContext; - USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length. - UINT32 fillOffset; - TXINFO_STRUC *pTxInfo; - TXWI_STRUC *pTxWI; - PUCHAR pWirelessPacket = NULL; - UCHAR QueIdx; - NDIS_STATUS Status; - unsigned long IrqFlags; - //UINT32 USBDMApktLen = 0, DMAHdrLen, padding; - - // - // get Tx Ring Resource & Dma Buffer address - // - QueIdx = pTxBlk->QueIdx; - pHTTXContext = &pAd->TxContext[QueIdx]; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - if(frameNum == 0) - { - // Check if we have enough space for this bulk-out batch. - Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); - if (Status == NDIS_STATUS_SUCCESS) - { - pHTTXContext->bCurWriting = TRUE; - - pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); - pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); - - - // Reserve space for 8 bytes padding. - if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) - { - - pHTTXContext->CurWritePosition += 8; - pHTTXContext->ENextBulkOutPosition += 8; - } - fillOffset = pHTTXContext->CurWritePosition; - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; - - // - // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer - // - if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; - hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD; - else if (pTxBlk->TxFrameType == TX_RALINK_FRAME) - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; - hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD; - else - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); - hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - // Update the pTxBlk->Priv. - pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen; - - // pTxInfo->USBDMApktLen now just a temp value and will to correct latter. - RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); - - // Copy it. - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv); -#ifdef RT_BIG_ENDIAN - RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE); -#endif // RT_BIG_ENDIAN // - pHTTXContext->CurWriteRealPos += pTxBlk->Priv; - pWirelessPacket += pTxBlk->Priv; - } - } - else - { // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. - - Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE); - if (Status == NDIS_STATUS_SUCCESS) - { - fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv); - pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; - - //hwHdrLen = pTxBlk->MpduHeaderLen; - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen); - pWirelessPacket += (pTxBlk->MpduHeaderLen); - pTxBlk->Priv += pTxBlk->MpduHeaderLen; - } - else - { // It should not happened now unless we are going to shutdown. - DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n")); - Status = NDIS_STATUS_FAILURE; - } - } - - - // We unlock it here to prevent the first 8 bytes maybe over-write issue. - // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext. - // 2. An interrupt break our routine and handle bulk-out complete. - // 3. In the bulk-out compllete, it need to do another bulk-out, - // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, - // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. - // 4. Interrupt complete. - // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. - // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. - // and the packet will wrong. - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - if (Status != NDIS_STATUS_SUCCESS) - { - DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition)); - goto done; - } - - // Copy the frame content into DMA buffer and update the pTxBlk->Priv - NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); - pWirelessPacket += pTxBlk->SrcBufLen; - pTxBlk->Priv += pTxBlk->SrcBufLen; - -done: - // Release the skb buffer here - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); - - return(Status); - -} - - -VOID RtmpUSB_FinalWriteTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN USHORT totalMPDUSize, - IN USHORT TxIdx) -{ - UCHAR QueIdx; - HT_TX_CONTEXT *pHTTXContext; - UINT32 fillOffset; - TXINFO_STRUC *pTxInfo; - TXWI_STRUC *pTxWI; - UINT32 USBDMApktLen, padding; - unsigned long IrqFlags; - PUCHAR pWirelessPacket; - - QueIdx = pTxBlk->QueIdx; - pHTTXContext = &pAd->TxContext[QueIdx]; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - if (pHTTXContext->bCurWriting == TRUE) - { - fillOffset = pHTTXContext->CurWritePosition; - if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) - && (pHTTXContext->bCopySavePad == TRUE)) - pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]); - else - pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]); - - // - // Update TxInfo->USBDMApktLen , - // the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding - // - pTxInfo = (PTXINFO_STRUC)(pWirelessPacket); - - // Calculate the bulk-out padding - USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE; - padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment - USBDMApktLen += padding; - - pTxInfo->USBDMATxPktLen = USBDMApktLen; - - // - // Update TXWI->MPDUtotalByteCount , - // the length = 802.11 header + payload_of_all_batch_frames - pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE); - pTxWI->MPDUtotalByteCount = totalMPDUSize; - - // - // Update the pHTTXContext->CurWritePosition - // - pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen); - if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT) - { // Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame. - pHTTXContext->CurWritePosition = 8; - pTxInfo->SwUseLastRound = 1; - } - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - - // - // Zero the last padding. - // - pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]); - NdisZeroMemory(pWirelessPacket, padding + 8); - - // Finally, set bCurWriting as FALSE - pHTTXContext->bCurWriting = FALSE; - - } - else - { // It should not happened now unless we are going to shutdown. - DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n")); - } - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - -} - - -VOID RtmpUSBDataLastTxIdx( - IN PRTMP_ADAPTER pAd, - IN UCHAR QueIdx, - IN USHORT TxIdx) -{ - // DO nothing for USB. -} - - -/* - When can do bulk-out: - 1. TxSwFreeIdx < TX_RING_SIZE; - It means has at least one Ring entity is ready for bulk-out, kick it out. - 2. If TxSwFreeIdx == TX_RING_SIZE - Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out. - -*/ -VOID RtmpUSBDataKickOut( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN UCHAR QueIdx) -{ - RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); - RTUSBKickBulkOut(pAd); - -} - - -/* - Must be run in Interrupt context - This function handle RT2870 specific TxDesc and cpu index update and kick the packet out. - */ -int RtmpUSBMgmtKickOut( - IN RTMP_ADAPTER *pAd, - IN UCHAR QueIdx, - IN PNDIS_PACKET pPacket, - IN PUCHAR pSrcBufVA, - IN UINT SrcBufLen) -{ - PTXINFO_STRUC pTxInfo; - ULONG BulkOutSize; - UCHAR padLen; - PUCHAR pDest; - ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; - PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa; - unsigned long IrqFlags; - - - pTxInfo = (PTXINFO_STRUC)(pSrcBufVA); - - // Build our URB for USBD - BulkOutSize = SrcBufLen; - BulkOutSize = (BulkOutSize + 3) & (~3); - RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); - - BulkOutSize += 4; // Always add 4 extra bytes at every packet. - - // If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. - if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0) - BulkOutSize += 4; - - padLen = BulkOutSize - SrcBufLen; - ASSERT((padLen <= RTMP_PKT_TAIL_PADDING)); - - // Now memzero all extra padding bytes. - pDest = (PUCHAR)(pSrcBufVA + SrcBufLen); - skb_put(GET_OS_PKT_TYPE(pPacket), padLen); - NdisZeroMemory(pDest, padLen); - - RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); - - pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket; - pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket)); - - // Length in TxInfo should be 8 less than bulkout size. - pMLMEContext->BulkOutSize = BulkOutSize; - pMLMEContext->InUse = TRUE; - pMLMEContext->bWaitingBulkOut = TRUE; - - - //for debug - //hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); - - //pAd->RalinkCounters.KickTxCount++; - //pAd->RalinkCounters.OneSecTxDoneCount++; - - //if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) - // needKickOut = TRUE; - - // Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX - pAd->MgmtRing.TxSwFreeIdx--; - INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); - - RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); - - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); - //if (needKickOut) - RTUSBKickBulkOut(pAd); - - return 0; -} - - -VOID RtmpUSBNullFrameKickOut( - IN RTMP_ADAPTER *pAd, - IN UCHAR QueIdx, - IN UCHAR *pNullFrame, - IN UINT32 frameLen) -{ - if (pAd->NullContext.InUse == FALSE) - { - PTX_CONTEXT pNullContext; - PTXINFO_STRUC pTxInfo; - PTXWI_STRUC pTxWI; - PUCHAR pWirelessPkt; - - pNullContext = &(pAd->NullContext); - - // Set the in use bit - pNullContext->InUse = TRUE; - pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0]; - - RTMPZeroMemory(&pWirelessPkt[0], 100); - pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0]; - RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); - pTxInfo->QSEL = FIFO_EDCA; - pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE]; - RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)), - 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit); -#ifdef RT_BIG_ENDIAN - RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI); -#endif // RT_BIG_ENDIAN // - - RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11)); -#ifdef RT_BIG_ENDIAN - RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWI_SIZE], DIR_WRITE, FALSE); -#endif // RT_BIG_ENDIAN // - pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4; - - // Fill out frame length information for global Bulk out arbitor - //pNullContext->BulkOutSize = TransferBufferLength; - DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate])); - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); - - // Kick bulk out - RTUSBKickBulkOut(pAd); - } - -} - -#ifdef CONFIG_STA_SUPPORT -/* - ======================================================================== - - Routine Description: - Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound - - Arguments: - pRxD Pointer to the Rx descriptor - - Return Value: - NDIS_STATUS_SUCCESS No err - NDIS_STATUS_FAILURE Error - - Note: - - ======================================================================== -*/ -NDIS_STATUS RTMPCheckRxError( - IN PRTMP_ADAPTER pAd, - IN PHEADER_802_11 pHeader, - IN PRXWI_STRUC pRxWI, - IN PRT28XX_RXD_STRUC pRxINFO) -{ - PCIPHER_KEY pWpaKey; - INT dBm; - - if (pAd->bPromiscuous == TRUE) - return(NDIS_STATUS_SUCCESS); - if(pRxINFO == NULL) - return(NDIS_STATUS_FAILURE); - - // Phy errors & CRC errors - if (pRxINFO->Crc) - { - // Check RSSI for Noise Hist statistic collection. - dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta; - if (dBm <= -87) - pAd->StaCfg.RPIDensity[0] += 1; - else if (dBm <= -82) - pAd->StaCfg.RPIDensity[1] += 1; - else if (dBm <= -77) - pAd->StaCfg.RPIDensity[2] += 1; - else if (dBm <= -72) - pAd->StaCfg.RPIDensity[3] += 1; - else if (dBm <= -67) - pAd->StaCfg.RPIDensity[4] += 1; - else if (dBm <= -62) - pAd->StaCfg.RPIDensity[5] += 1; - else if (dBm <= -57) - pAd->StaCfg.RPIDensity[6] += 1; - else if (dBm > -57) - pAd->StaCfg.RPIDensity[7] += 1; - - return(NDIS_STATUS_FAILURE); - } - - // Add Rx size to channel load counter, we should ignore error counts - pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14); - - // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics - if (pHeader->FC.ToDs) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n")); - return NDIS_STATUS_FAILURE; - } - - // Paul 04-03 for OFDM Rx length issue - if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n")); - return NDIS_STATUS_FAILURE; - } - - // Drop not U2M frames, cant's drop here because we will drop beacon in this case - // I am kind of doubting the U2M bit operation - // if (pRxD->U2M == 0) - // return(NDIS_STATUS_FAILURE); - - // drop decyption fail frame - if (pRxINFO->Decrypted && pRxINFO->CipherErr) - { - - // - // MIC Error - // - if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss) - { - pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex]; - RTMPReportMicError(pAd, pWpaKey); - DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n")); - } - - if (pRxINFO->Decrypted && - (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) && - (pHeader->Sequence == pAd->FragFrame.Sequence)) - { - // - // Acceptable since the First FragFrame no CipherErr problem. - // - return(NDIS_STATUS_SUCCESS); - } - - return(NDIS_STATUS_FAILURE); - } - - return(NDIS_STATUS_SUCCESS); -} - -VOID RT28xxUsbStaAsicForceWakeup( - IN PRTMP_ADAPTER pAd, - IN BOOLEAN bFromTx) -{ - AUTO_WAKEUP_STRUC AutoWakeupCfg; - - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - - AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); - - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); -} - -VOID RT28xxUsbStaAsicSleepThenAutoWakeup( - IN PRTMP_ADAPTER pAd, - IN USHORT TbttNumToNextWakeUp) -{ - AUTO_WAKEUP_STRUC AutoWakeupCfg; - - // we have decided to SLEEP, so at least do it for a BEACON period. - if (TbttNumToNextWakeUp == 0) - TbttNumToNextWakeUp = 1; - - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - - AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1; - AutoWakeupCfg.field.EnableAutoWakeup = 1; - AutoWakeupCfg.field.AutoLeadTime = 5; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - - AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); // send POWER-SAVE command to MCU. Timeout 40us. - - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE); - -} -#endif // CONFIG_STA_SUPPORT // - -VOID RT28xxUsbMlmeRadioOn( - IN PRTMP_ADAPTER pAd) -{ - DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n")); - - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) - return; - -#ifdef CONFIG_STA_SUPPORT - IF_DEV_CONFIG_OPMODE_ON_STA(pAd) - { - AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); - RTMPusecDelay(10000); - } -#endif // CONFIG_STA_SUPPORT // - NICResetFromError(pAd); - - // Enable Tx/Rx - RTMPEnableRxTx(pAd); - -#ifdef RT3070 - if (IS_RT3071(pAd)) - { - RT30xxReverseRFSleepModeSetup(pAd); - } -#endif // RT3070 // - - // Clear Radio off flag - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - -#ifdef CONFIG_STA_SUPPORT - IF_DEV_CONFIG_OPMODE_ON_STA(pAd) - RTUSBBulkReceive(pAd); -#endif // CONFIG_STA_SUPPORT // - - // Set LED - RTMPSetLED(pAd, LED_RADIO_ON); -} - -VOID RT28xxUsbMlmeRadioOFF( - IN PRTMP_ADAPTER pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - UINT32 Value, i; - - DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n")); - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) - return; - - // Set LED - RTMPSetLED(pAd, LED_RADIO_OFF); - // Set Radio off flag - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - -#ifdef CONFIG_STA_SUPPORT - IF_DEV_CONFIG_OPMODE_ON_STA(pAd) - { - // Link down first if any association exists - if (INFRA_ON(pAd) || ADHOC_ON(pAd)) - LinkDown(pAd, FALSE); - RTMPusecDelay(10000); - - //========================================== - // Clean up old bss table - BssTableInit(&pAd->ScanTab); - } -#endif // CONFIG_STA_SUPPORT // - - - if (pAd->CommonCfg.BBPCurrentBW == BW_40) - { - // Must using 40MHz. - AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel); - } - else - { - // Must using 20MHz. - AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel); - } - - // Disable Tx/Rx DMA - RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA - GloCfg.field.EnableTxDMA = 0; - GloCfg.field.EnableRxDMA = 0; - RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings - - // Waiting for DMA idle - i = 0; - do - { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) - break; - - RTMPusecDelay(1000); - }while (i++ < 100); - - // Disable MAC Tx/Rx - RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); - Value &= (0xfffffff3); - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value); - - // MAC_SYS_CTRL => value = 0x0 => 40mA - //RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0); - - // PWR_PIN_CFG => value = 0x0 => 40mA - //RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0); - - // TX_PIN_CFG => value = 0x0 => 20mA - //RTMP_IO_WRITE32(pAd, TX_PIN_CFG, 0); - -#ifdef CONFIG_STA_SUPPORT - IF_DEV_CONFIG_OPMODE_ON_STA(pAd) - AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); -#endif // CONFIG_STA_SUPPORT // -} - +#include "../../rt2870/common/cmm_data_2870.c" |