Files
Linux_Drivers/osdrv/extdrv/wireless/mediatek/mt7603/common/rtusb_bulk.c
forum_service 213c880673 add driver of tp、wiegand-gpio and wireless
Change-Id: Ie3c11d9d85cf1a05042f5690ac711856fe8b1ad7
2023-12-22 09:56:05 +08:00

2542 lines
76 KiB
C

/*
***************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
*
* (c) Copyright 2002-2006, Ralink Technology, Inc.
*
* All rights reserved. Ralink's source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of Ralink Tech. Any attemp
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of Ralink Technology, Inc. is obtained.
***************************************************************************
Module Name:
rtusb_bulk.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Name Date Modification logs
*/
#ifdef RTMP_MAC_USB
#include "rt_config.h"
/* Match total 6 bulkout endpoint to corresponding queue.*/
UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT};
#ifdef INF_AMAZON_SE
UINT16 MaxBulkOutsSizeLimit[5][4] =
{
#ifdef RELEASE_EXCLUDE
/*
our chip might hang for unknown reason when we bulk out multiACs with bulkout size > 10k
*/
#endif /* RELEASE_EXCLUDE */
/* Priority high -> low*/
{ 24576, 2048, 2048, 2048 }, /* 0 AC */
{ 24576, 2048, 2048, 2048 }, /* 1 AC */
{ 24576, 2048, 2048, 2048 }, /* 2 ACs*/
{ 24576, 6144, 2048, 2048 }, /* 3 ACs*/
{ 24576, 6144, 4096, 2048 } /* 4 ACs*/
};
VOID SoftwareFlowControl(
IN PRTMP_ADAPTER pAd)
{
BOOLEAN ResetBulkOutSize=FALSE;
UCHAR i=0,RunningQueueNo=0,QueIdx=0,HighWorkingAcCount=0;
UINT PacketsInQueueSize=0;
UCHAR Priority[]={1,0,2,3};
for (i=0;i<NUM_OF_TX_RING;i++)
{
if (pAd->TxContext[i].CurWritePosition>=pAd->TxContext[i].ENextBulkOutPosition)
{
PacketsInQueueSize=pAd->TxContext[i].CurWritePosition-pAd->TxContext[i].ENextBulkOutPosition;
}
else
{
PacketsInQueueSize=MAX_TXBULK_SIZE-pAd->TxContext[i].ENextBulkOutPosition+pAd->TxContext[i].CurWritePosition;
}
if (pAd->BulkOutDataSizeCount[i]>20480 || PacketsInQueueSize>6144)
{
RunningQueueNo++;
pAd->BulkOutDataFlag[i]=TRUE;
}
else
pAd->BulkOutDataFlag[i]=FALSE;
pAd->BulkOutDataSizeCount[i]=0;
}
if (RunningQueueNo>pAd->LastRunningQueueNo)
{
DBGPRINT(RT_DEBUG_INFO,("SoftwareFlowControl reset %d > %d \n",RunningQueueNo,pAd->LastRunningQueueNo));
ResetBulkOutSize=TRUE;
pAd->RunningQueueNoCount=0;
pAd->LastRunningQueueNo=RunningQueueNo;
}
else if (RunningQueueNo==pAd->LastRunningQueueNo)
{
pAd->RunningQueueNoCount=0;
}
else if (RunningQueueNo<pAd->LastRunningQueueNo)
{
DBGPRINT(RT_DEBUG_INFO,("SoftwareFlowControl reset %d < %d \n",RunningQueueNo,pAd->LastRunningQueueNo));
pAd->RunningQueueNoCount++;
if (pAd->RunningQueueNoCount>=6)
{
ResetBulkOutSize=TRUE;
pAd->RunningQueueNoCount=0;
pAd->LastRunningQueueNo=RunningQueueNo;
}
}
if (ResetBulkOutSize==TRUE)
{
for (QueIdx=0;QueIdx<NUM_OF_TX_RING;QueIdx++)
{
HighWorkingAcCount=0;
for (i=0;i<NUM_OF_TX_RING;i++)
{
if (QueIdx==i)
continue;
if (pAd->BulkOutDataFlag[i]==TRUE && Priority[i]>Priority[QueIdx])
HighWorkingAcCount++;
}
pAd->BulkOutDataSizeLimit[QueIdx]=MaxBulkOutsSizeLimit[RunningQueueNo][HighWorkingAcCount];
}
DBGPRINT(RT_DEBUG_TRACE, ("Reset bulkout size AC0(BE):%7d AC1(BK):%7d AC2(VI):%7d AC3(VO):%7d %d\n",
pAd->BulkOutDataSizeLimit[0], pAd->BulkOutDataSizeLimit[1]
,pAd->BulkOutDataSizeLimit[2], pAd->BulkOutDataSizeLimit[3], RunningQueueNo));
}
}
#endif /* INF_AMAZON_SE */
VOID RTUSBInitTxDesc(
IN PRTMP_ADAPTER pAd,
IN PTX_CONTEXT pTxContext,
IN UCHAR BulkOutPipeId,
IN usb_complete_t Func)
{
PURB pUrb;
PUCHAR pSrc = NULL;
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
pUrb = pTxContext->pUrb;
ASSERT(pUrb);
if (BulkOutPipeId >= 5) {
DBGPRINT(RT_DEBUG_ERROR, ("%s:Invalid BulkOutPipeId\n", __func__));
return;
}
/* Store BulkOut PipeId*/
pTxContext->BulkOutPipeId = BulkOutPipeId;
if (pTxContext->bAggregatible)
{
pSrc = &pTxContext->TransferBuffer->Aggregation[2];
RTUSB_FILL_TX_BULK_URB(pUrb,
pObj->pUsb_Dev,
pChipCap->WMM0ACBulkOutAddr[BulkOutPipeId],
pSrc,
pTxContext->BulkOutSize,
Func,
pTxContext,
(pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2));
}
else
{
pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
#ifdef MT_MAC
if ((pAd->chipCap.hif_type == HIF_MT) && (pTxContext == (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa))
{
RTUSB_FILL_TX_BULK_URB(pUrb,
pObj->pUsb_Dev,
pChipCap->CommandBulkOutAddr,
pSrc,
pTxContext->BulkOutSize,
Func,
pTxContext,
pTxContext->data_dma);
}
else if ((pAd->chipCap.hif_type == HIF_MT) && (pTxContext == (PTX_CONTEXT)pAd->BcnRing.Cell[pAd->BcnRing.TxDmaIdx].AllocVa))
{
RTUSB_FILL_TX_BULK_URB(pUrb,
pObj->pUsb_Dev,
pChipCap->CommandBulkOutAddr,
pSrc,
pTxContext->BulkOutSize,
Func,
pTxContext,
pTxContext->data_dma);
}
else
#endif
if (BulkOutPipeId == MGMTPIPEIDX)
{
RTUSB_FILL_TX_BULK_URB(pUrb,
pObj->pUsb_Dev,
pChipCap->CommandBulkOutAddr,
pSrc,
pTxContext->BulkOutSize,
Func,
pTxContext,
pTxContext->data_dma);
}
else
{
RTUSB_FILL_TX_BULK_URB(pUrb,
pObj->pUsb_Dev,
pChipCap->WMM0ACBulkOutAddr[BulkOutPipeId],
pSrc,
pTxContext->BulkOutSize,
Func,
pTxContext,
pTxContext->data_dma);
}
}
}
#ifdef MULTI_WMM_SUPPORT
VOID RTUSBInitHTTxWmm1Desc(
IN PRTMP_ADAPTER pAd,
IN PHT_TX_CONTEXT pTxContext,
IN UCHAR BulkOutPipeId,
IN ULONG BulkOutSize,
IN usb_complete_t Func)
{
PURB pUrb;
PUCHAR pSrc = NULL;
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
#ifdef USB_BULK_BUF_ALIGMENT
INT idx;
idx = pTxContext->CurtBulkIdx;
pUrb = pTxContext->pUrb[idx];
#else
pUrb = pTxContext->pUrb;
#endif /* USB_BULK_BUF_ALIGMENT */
ASSERT(pUrb);
/* Store BulkOut PipeId*/
pTxContext->BulkOutPipeId = BulkOutPipeId;
#ifdef USB_BULK_BUF_ALIGMENT
pSrc = &pTxContext->TransferBuffer[idx]->field.WirelessPacket[idx];
#else
pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
#endif /* USB_BULK_BUF_ALIGMENT */
RTUSB_FILL_HTTX_BULK_URB(pUrb,
pObj->pUsb_Dev,
pChipCap->WMM1ACBulkOutAddr,
pSrc,
BulkOutSize,
Func,
pTxContext,
#ifdef USB_BULK_BUF_ALIGMENT
(pTxContext->data_dma[idx]);
#else
(pTxContext->data_dma + pTxContext->NextBulkOutPosition));
#endif /* USB_BULK_BUF_ALIGMENT */
}
#endif /* MULTI_WMM_SUPPORT */
VOID RTUSBInitHTTxDesc(
IN PRTMP_ADAPTER pAd,
IN PHT_TX_CONTEXT pTxContext,
IN UCHAR BulkOutPipeId,
IN ULONG BulkOutSize,
IN usb_complete_t Func)
{
PURB pUrb;
PUCHAR pSrc = NULL;
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
#ifndef USB_IOT_WORKAROUND
#ifdef USB_BULK_BUF_ALIGMENT
INT idx;
idx = pTxContext->CurtBulkIdx;
pUrb = pTxContext->pUrb[idx];
#else
pUrb = pTxContext->pUrb;
#endif /* USB_BULK_BUF_ALIGMENT */
ASSERT(pUrb);
if (BulkOutPipeId >= 5) {
DBGPRINT(RT_DEBUG_ERROR, ("%s:Invalid BulkOutPipeId\n", __FUNCTION__));
return;
}
/* Store BulkOut PipeId*/
pTxContext->BulkOutPipeId = BulkOutPipeId;
#ifdef USB_BULK_BUF_ALIGMENT
pSrc = &pTxContext->TransferBuffer[idx]->field.WirelessPacket[pTxContext->NextBulkOutPosition];
#else
pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
#endif /* USB_BULK_BUF_ALIGMENT */
RTUSB_FILL_HTTX_BULK_URB(pUrb,
pObj->pUsb_Dev,
pChipCap->WMM0ACBulkOutAddr[BulkOutPipeId],
pSrc,
BulkOutSize,
Func,
pTxContext,
#ifdef USB_BULK_BUF_ALIGMENT
(pTxContext->data_dma[idx]));
#else
(pTxContext->data_dma + pTxContext->NextBulkOutPosition));
#endif /* USB_BULK_BUF_ALIGMENT */
#else /*USB_IOT_WORKAROUND*/
PHT_TX_CONTEXT pTxContext2 = &pAd->TxContext2[BulkOutPipeId];
int padding = 0;
int sendlen = 0;
padding = 512 - (BulkOutSize%512);
pUrb = pTxContext->pUrb;
ASSERT(pUrb);
/* Store BulkOut PipeId*/
pTxContext->BulkOutPipeId = BulkOutPipeId;
pSrc = &pTxContext2->TransferBuffer->field.WirelessPacket[0];
// copy data to new place
NdisCopyMemory(pSrc,
&pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition], BulkOutSize);
sendlen = BulkOutSize;
// add padding to 512 boundary
NdisZeroMemory(pSrc+sendlen, padding);
sendlen += padding;
// copy a valid TxD
NdisCopyMemory(pSrc+sendlen, pSrc, 512);
// Modify padding TxD
if (1)
{
TMAC_TXD_L *txd_l = (TMAC_TXD_L *)(pSrc+sendlen);
TMAC_TXD_S *txd_s = (TMAC_TXD_S *)(pSrc+sendlen);
TMAC_TXD_0 *txd_0 = &txd_s->txd_0;
TMAC_TXD_1 *txd_1 = &txd_s->txd_1;
TMAC_TXD_3 *txd_3 = &txd_l->txd_3;
TMAC_TXD_5 *txd_5 = &txd_l->txd_5;
txd_0->tx_byte_cnt = 512;
txd_1->wlan_idx = 0;
txd_3->remain_tx_cnt = 0;
}
sendlen += 512;
// add final 4 bytes padding
NdisZeroMemory(pSrc+sendlen, 4);
sendlen += 4;
RTUSB_FILL_HTTX_BULK_URB(pUrb,
pObj->pUsb_Dev,
pChipCap->WMM0ACBulkOutAddr[BulkOutPipeId],
pSrc,
sendlen,
Func,
pTxContext,
pTxContext2->data_dma);
#endif /*USB_IOT_WORKAROUND*/
}
VOID RTUSBInitRxDesc(
IN PRTMP_ADAPTER pAd,
IN PRX_CONTEXT pRxContext)
{
PURB pUrb;
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
ULONG RX_bulk_size;
RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
pUrb = pRxContext->pUrb;
ASSERT(pUrb);
if (pAd->BulkInMaxPacketSize == 64)
RX_bulk_size = 4096;
else
RX_bulk_size = MAX_RXBULK_SIZE;
RTUSB_FILL_RX_BULK_URB(pUrb,
pObj->pUsb_Dev,
pChipCap->DataBulkInAddr,
&(pRxContext->TransferBuffer[0]),
RX_bulk_size,
RtmpUsbBulkRxComplete,
(void *)pRxContext,
pRxContext->data_dma);
}
#if 0
VOID RTUSBInitCmdRspEventDesc(
PRTMP_ADAPTER pAd,
PCMD_RSP_CONTEXT pCmdRspEventContext)
{
PURB pUrb = pCmdRspEventContext->pUrb;
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
RTUSB_FILL_RX_BULK_URB(pUrb,
pObj->pUsb_Dev,
pChipCap->CommandRspBulkInAddr,
pCmdRspEventContext->CmdRspBuffer,
CMD_RSP_BULK_SIZE,
RtmpUsbBulkCmdRspEventComplete,
(void *)pCmdRspEventContext,
pCmdRspEventContext->data_dma);
}
#endif
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
#define BULK_OUT_LOCK(pLock, IrqFlags) \
if(1 /*!(in_interrupt() & 0xffff0000)*/) \
RTMP_IRQ_LOCK((pLock), IrqFlags);
#define BULK_OUT_UNLOCK(pLock, IrqFlags) \
if(1 /*!(in_interrupt() & 0xffff0000)*/) \
RTMP_IRQ_UNLOCK((pLock), IrqFlags);
#ifdef MULTI_WMM_SUPPORT
VOID RTUSBBulkOutWmm1DataPacket(RTMP_ADAPTER *pAd, UCHAR BulkOutPipeId, UCHAR Index)
{
PHT_TX_CONTEXT pHTTXContext;
PURB pUrb;
int ret = 0;
TXINFO_STRUC *pTxInfo, *pLastTxInfo = NULL;
TXWI_STRUC *pTxWI;
USHORT txwi_pkt_len = 0;
UCHAR ampdu = 0, phy_mode = 0, pid;
ULONG TmpBulkEndPos, ThisBulkSize;
unsigned long IrqFlags = 0, IrqFlags2 = 0;
UCHAR *pWirelessPkt, *pAppendant;
UINT32 aggregation_num = 0, padding = 0;
#ifdef USB_BULK_BUF_ALIGMENT
BOOLEAN bLasAlignmentsectiontRound = FALSE;
#else
BOOLEAN bTxQLastRound = FALSE;
UCHAR allzero[4]= {0x0,0x0,0x0,0x0};
#endif /* USB_BULK_BUF_ALIGMENT */
BULK_OUT_LOCK(&pAd->BulkOutWmm1Lock[BulkOutPipeId], IrqFlags);
if ((pAd->BulkOutWmm1Pending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
{
BULK_OUT_UNLOCK(&pAd->BulkOutWmm1Lock[BulkOutPipeId], IrqFlags);
#ifdef CONFIG_DVT_MODE
DBGPRINT(RT_DEBUG_TRACE, ("%s::BulkOutPending[%d]=%d, NEED_STOP_TX(%d)\n", __FUNCTION__, BulkOutPipeId, pAd->BulkOutPending[BulkOutPipeId], RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)));
#endif /* CONFIG_DVT_MODE */
return;
}
pAd->BulkOutWmm1Pending[BulkOutPipeId] = TRUE;
if (((!OPSTATUS_TEST_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED)) &&
( !OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)))
#ifdef MESH_SUPPORT
&& !MESH_ON(pAd)
#endif /* MESH_SUPPORT */
#ifdef P2P_SUPPORT
&& !(P2P_GO_ON(pAd) || P2P_CLI_ON(pAd))
#endif /* P2P_SUPPORT */
#ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE
&& !(RTMP_CFG80211_VIF_P2P_GO_ON(pAd) || RTMP_CFG80211_VIF_P2P_CLI_ON(pAd))
#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */
)
{
pAd->BulkOutWmm1Pending[BulkOutPipeId] = FALSE;
BULK_OUT_UNLOCK(&pAd->BulkOutWmm1Lock[BulkOutPipeId], IrqFlags);
return;
}
BULK_OUT_UNLOCK(&pAd->BulkOutWmm1Lock[BulkOutPipeId], IrqFlags);
pHTTXContext = &(pAd->TxContextWmm1[BulkOutPipeId]);
BULK_OUT_LOCK(&pAd->TxContextQueueWmm1Lock[BulkOutPipeId], IrqFlags2);
#ifdef USB_BULK_BUF_ALIGMENT
if ( (pHTTXContext->NextBulkIdx != pHTTXContext->CurtBulkIdx)
|| ((pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition) &&(pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx))
|| ((pHTTXContext->CurWriteRealPos == 0) && (pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx))
)
#else
if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
|| ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
#endif /* USB_BULK_BUF_ALIGMENT */
/* druing writing. */
{
BULK_OUT_UNLOCK(&pAd->TxContextQueueWmm1Lock[BulkOutPipeId], IrqFlags2);
BULK_OUT_LOCK(&pAd->BulkOutWmm1Lock[BulkOutPipeId], IrqFlags);
pAd->BulkOutWmm1Pending[BulkOutPipeId] = FALSE;
/* Clear Data flag*/
RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_WMM1_FRAG << BulkOutPipeId));
RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_WMM1_NORMAL << BulkOutPipeId));
BULK_OUT_UNLOCK(&pAd->BulkOutWmm1Lock[BulkOutPipeId], IrqFlags);
return;
}
/* Clear Data flag*/
RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_WMM1_FRAG << BulkOutPipeId));
RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_WMM1_NORMAL << BulkOutPipeId));
/*
DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n",
in_interrupt(),
pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition,
pHTTXContext->bCopySavePad));
*/
pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
ThisBulkSize = 0;
TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
#ifdef USB_BULK_BUF_ALIGMENT
INT idx;
idx = pHTTXContext->NextBulkIdx;
pWirelessPkt = &pHTTXContext->TransferBuffer[idx]->field.WirelessPacket[0];
#else
pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
#endif /* USB_BULK_BUF_ALIGMENT */
#ifndef USB_BULK_BUF_ALIGMENT
if ((pHTTXContext->bCopySavePad == TRUE))
{
if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
{
DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n",
pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
}
NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
pHTTXContext->bCopySavePad = FALSE;
if (pAd->bForcePrintTX == TRUE)
DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n",
pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
}
#endif /* USB_BULK_BUF_ALIGMENT */
do
{
#ifdef MT_MAC
TMAC_TXD_L *txd_l = (TMAC_TXD_L *)&pWirelessPkt[TmpBulkEndPos];
TMAC_TXD_S *txd_s = (TMAC_TXD_S *)&pWirelessPkt[TmpBulkEndPos];
TMAC_TXD_0 *txd_0 = &txd_s->txd_0;
TMAC_TXD_1 *txd_1 = &txd_s->txd_1;
TMAC_TXD_7 *txd_7;
if (txd_1->ft == TMI_FT_SHORT)
txd_7 = &txd_s->txd_7;
else
txd_7 = &txd_l->txd_7;
#else
pTxInfo = (TXINFO_STRUC *)&pWirelessPkt[TmpBulkEndPos];
pTxWI = (TXWI_STRUC *)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
#endif /* MT_MAC */
#ifdef RLT_MAC
if (pAd->chipCap.hif_type == HIF_RLT) {
#ifdef MT7601
if (IS_MT7601(pAd)) {
ampdu = pTxWI->TXWI_X.AMPDU;
phy_mode = pTxWI->TXWI_X.PHYMODE;
pid = pTxWI->TXWI_X.PacketId;
txwi_pkt_len = pTxWI->TXWI_X.MPDUtotalByteCnt;
}
else
#endif /* MT7601 */
{
ampdu = pTxWI->TXWI_N.AMPDU;
phy_mode = pTxWI->TXWI_N.PHYMODE;
pid = pTxWI->TXWI_N.TxPktId;
txwi_pkt_len = pTxWI->TXWI_N.MPDUtotalByteCnt;
}
}
#endif /* RLT_MAC */
#ifdef RTMP_MAC
if (pAd->chipCap.hif_type == HIF_RTMP) {
ampdu = pTxWI->TXWI_O.AMPDU;
phy_mode = pTxWI->TXWI_O.PHYMODE;
pid = pTxWI->TXWI_O.PacketId;
txwi_pkt_len = pTxWI->TXWI_O.MPDUtotalByteCnt;
}
#endif /* RTMP_MAC */
if (pAd->bForcePrintTX == TRUE)
DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", ampdu));
#ifdef USB_BULK_BUF_ALIGMENT
if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE))
#else
if (((ThisBulkSize & 0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
#endif /* USB_BULK_BUF_ALIGMENT */
{ /* Limit BulkOut size to about 24k bytes.*/
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
#ifdef USB_BULK_BUF_ALIGMENT
/*
when bulk size is > 0x6000, it mean that this is the lasttround at this alignmnet section.
*/
bLasAlignmentsectiontRound = TRUE;
/* printk("data bulk out bLasAlignmentsectiontRound \n");*/
#endif /* USB_BULK_BUF_ALIGMENT */
break;
}
#ifndef USB_BULK_BUF_ALIGMENT
else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
{ /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */
/* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.*/
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
break;
}
#else
else if (((pAd->BulkOutMaxPacketSize < 512) && (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE)) ))
{
/* Limit BulkOut size to about 24k bytes.*/
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
/*
when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section.
*/
bLasAlignmentsectiontRound = TRUE;
break;
}
#endif /* USB_BULK_BUF_ALIGMENT */
#ifdef USB_BULK_BUF_ALIGMENT
if ((TmpBulkEndPos == pHTTXContext->CurWritePosition) && (pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx))
#else
if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
#endif /* USB_BULK_BUF_ALIGMENT */
{
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
break;
}
padding = (4 - (txd_0->tx_byte_cnt % 4)) & 0x03;
ThisBulkSize += txd_0->tx_byte_cnt+padding;
TmpBulkEndPos += txd_0->tx_byte_cnt+padding;
if (txd_7->sw_field == 1)
{
txd_7->sw_field = 0;
bTxQLastRound = TRUE;
pHTTXContext->ENextBulkOutPosition = 8;
break;
}
aggregation_num++;
if ((aggregation_num == 1) && (!pAd->usb_ctl.usb_aggregation)) {
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
break;
}
}while (TRUE);
#ifdef CONFIG_DVT_MODE
DBGPRINT(RT_DEBUG_TRACE, ("%s::aggregation_num(%d), usb_aggregation(%d)\n", __FUNCTION__, aggregation_num, pAd->usb_ctl.usb_aggregation));
#endif /* CONFIG_DVT_MODE */
/*
We need to copy SavedPad when following condition matched!
1. Not the last round of the TxQueue and
2. any match of following cases:
(1). The End Position of this bulk out is reach to the Currenct Write position and
the TxInfo and related header already write to the CurWritePosition.
=>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
(2). The EndPosition of the bulk out is not reach to the Current Write Position.
=>(ENextBulkOutPosition != CurWritePosition)
*/
#ifndef USB_BULK_BUF_ALIGMENT
if ((bTxQLastRound == FALSE) &&
(((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
(pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
)
{
NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
pHTTXContext->bCopySavePad = TRUE;
if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
{
PUCHAR pBuf = &pHTTXContext->SavedPad[0];
DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7]));
}
/*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));*/
}
#endif /* USB_BULK_BUF_ALIGMENT */
if (pAd->bForcePrintTX == TRUE)
DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
/*DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));*/
/* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.*/
pAppendant = &pWirelessPkt[TmpBulkEndPos];
NdisZeroMemory(pAppendant, 8);
ThisBulkSize += 4;
pHTTXContext->LastOne = TRUE;
pHTTXContext->BulkOutSize = ThisBulkSize;
#ifdef USB_BULK_BUF_ALIGMENT
/*
if it is the last alignment section round,that we just need to add nextbulkindex,
otherwise we both need to add nextbulkindex and CurWriteIdx
(because when alignment section round happened, the CurWriteIdx is added at function writing resource.)
*/
if(bLasAlignmentsectiontRound == TRUE)
{
CUR_WRITE_IDX_INC(pHTTXContext->NextBulkIdx, BUF_ALIGMENT_RINGSIZE);
pHTTXContext->ENextBulkOutPosition = 0;
}
else
{
CUR_WRITE_IDX_INC(pHTTXContext->NextBulkIdx, BUF_ALIGMENT_RINGSIZE);
pHTTXContext->ENextBulkOutPosition = 0;
CUR_WRITE_IDX_INC(pHTTXContext->CurWriteIdx, BUF_ALIGMENT_RINGSIZE);
pHTTXContext->CurWritePosition = 0;
}
#endif /* USB_BULK_BUF_ALIGMENT */
pAd->watchDogWmm1TxPendingCnt[BulkOutPipeId] = 1;
BULK_OUT_UNLOCK(&pAd->TxContextQueueWmm1Lock[BulkOutPipeId], IrqFlags2);
/* Init Tx context descriptor*/
RTUSBInitHTTxWmm1Desc(pAd, pHTTXContext, EDCA_WMM1_AC0_PIPE+BulkOutPipeId, ThisBulkSize, (usb_complete_t)RtmpUsbBulkOutDataPacketComplete);
#ifdef USB_BULK_BUF_ALIGMENT
pUrb = pHTTXContext->pUrb[pHTTXContext->CurtBulkIdx];
#else
pUrb = pHTTXContext->pUrb;
#endif /* USB_BULK_BUF_ALIGMENT */
#ifdef USB_IOT_WORKAROUND2
if (pUrb->transfer_buffer_length <= W2_MAX_HTTX_SIZE)
usb_iot_add_padding(pUrb, pHTTXContext->usb_iot_w2_buf, pHTTXContext->usb_iot_w2_data_dma);
else{
DBGPRINT(RT_DEBUG_ERROR, ("[%s]USB_IOT_WORKAROUND2: transfer length=%d > %d, skip padding\n", __func__, pUrb->transfer_buffer_length, W2_MAX_HTTX_SIZE));
}
#endif
if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
{
#ifdef RELEASE_EXCLUDE
/*
Bug history:
1. Webcom
When submit non-BE packet, the function will fail here.
After EEPROM content is updated, everything is ok.
*/
#endif /* RELEASE_EXCLUDE */
DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
BULK_OUT_LOCK(&pAd->BulkOutWmm1Lock[BulkOutPipeId], IrqFlags);
pAd->BulkOutWmm1Pending[BulkOutPipeId] = FALSE;
pAd->watchDogWmm1TxPendingCnt[BulkOutPipeId] = 0;
BULK_OUT_UNLOCK(&pAd->BulkOutWmm1Lock[BulkOutPipeId], IrqFlags);
return;
}
BULK_OUT_LOCK(&pAd->BulkOutWmm1Lock[BulkOutPipeId], IrqFlags);
pHTTXContext->IRPPending = TRUE;
BULK_OUT_UNLOCK(&pAd->BulkOutWmm1Lock[BulkOutPipeId], IrqFlags);
pAd->BulkOutReq++;
}
#endif /* MULTI_WMM_SUPPORT */
VOID RTUSBBulkOutDataPacket(RTMP_ADAPTER *pAd, UCHAR BulkOutPipeId, UCHAR Index)
{
PHT_TX_CONTEXT pHTTXContext;
PURB pUrb;
int ret = 0;
#ifndef MT_MAC
TXINFO_STRUC *pLastTxInfo = NULL;
#endif
#if !defined(MT_MAC) || defined(RT_BIG_ENDIAN)
TXINFO_STRUC *pTxInfo;
#endif
#if defined(RLT_MAC) || defined(RTMP_MAC) || !defined(MT_MAC) || defined(RT_BIG_ENDIAN)
TXWI_STRUC *pTxWI;
#endif /* defined(RLT_MAC) || defined(RTMP_MAC) || !defined(MT_MAC) || defined(RT_BIG_ENDIAN) */
UCHAR ampdu = 0;
#if defined(RLT_MAC) || defined(RTMP_MAC)
UCHAR pid;
#endif /* defined(RLT_MAC) || defined(RTMP_MAC) */
#if defined(RLT_MAC) || defined(RTMP_MAC) || !defined(MT_MAC)
USHORT txwi_pkt_len = 0;
UCHAR phy_mode = 0;
#endif /* defined(RLT_MAC) || defined(RTMP_MAC) || !defined(MT_MAC) */
ULONG TmpBulkEndPos, ThisBulkSize;
unsigned long IrqFlags = 0, IrqFlags2 = 0;
UCHAR *pWirelessPkt, *pAppendant;
UINT32 aggregation_num = 0, padding = 0;
#ifdef USB_BULK_BUF_ALIGMENT
INT idx;
BOOLEAN bLasAlignmentsectiontRound = FALSE;
#else
BOOLEAN bTxQLastRound = FALSE;
UCHAR allzero[4]= {0x0,0x0,0x0,0x0};
#endif /* USB_BULK_BUF_ALIGMENT */
BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
{
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
#ifdef CONFIG_DVT_MODE
DBGPRINT(RT_DEBUG_TRACE, ("%s::BulkOutPending[%d]=%d, NEED_STOP_TX(%d)\n", __FUNCTION__, BulkOutPipeId, pAd->BulkOutPending[BulkOutPipeId], RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)));
#endif /* CONFIG_DVT_MODE */
return;
}
pAd->BulkOutPending[BulkOutPipeId] = TRUE;
if (((!OPSTATUS_TEST_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED)) &&
( !OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)))
#ifdef MESH_SUPPORT
&& !MESH_ON(pAd)
#endif /* MESH_SUPPORT */
#ifdef P2P_SUPPORT
&& !(P2P_GO_ON(pAd) || P2P_CLI_ON(pAd))
#endif /* P2P_SUPPORT */
#ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE
&& !(RTMP_CFG80211_VIF_P2P_GO_ON(pAd) || RTMP_CFG80211_VIF_P2P_CLI_ON(pAd))
#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */
)
{
pAd->BulkOutPending[BulkOutPipeId] = FALSE;
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
return;
}
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
#ifdef USB_BULK_BUF_ALIGMENT
if ( (pHTTXContext->NextBulkIdx != pHTTXContext->CurtBulkIdx)
|| ((pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition) &&(pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx) )
|| ((pHTTXContext->CurWriteRealPos == 0) && (pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx))
)
#else
if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
|| ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
#endif /* USB_BULK_BUF_ALIGMENT */
/* druing writing. */
{
BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
pAd->BulkOutPending[BulkOutPipeId] = FALSE;
/* Clear Data flag*/
RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
return;
}
/* Clear Data flag*/
RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
/*
DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n",
in_interrupt(),
pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition,
pHTTXContext->bCopySavePad));
*/
pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
ThisBulkSize = 0;
TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
#ifdef USB_BULK_BUF_ALIGMENT
idx = pHTTXContext->NextBulkIdx;
pWirelessPkt = &pHTTXContext->TransferBuffer[idx]->field.WirelessPacket[0];
#else
pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
#endif /* USB_BULK_BUF_ALIGMENT */
#ifndef USB_BULK_BUF_ALIGMENT
if ((pHTTXContext->bCopySavePad == TRUE))
{
if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
{
DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n",
pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
}
NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
pHTTXContext->bCopySavePad = FALSE;
if (pAd->bForcePrintTX == TRUE)
DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n",
pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
}
#endif /* USB_BULK_BUF_ALIGMENT */
#ifdef RELEASE_EXCLUDE
#ifdef RTMP_MAC_USB
#ifdef DOT11_N_SUPPORT
#ifdef PLATFORM_RALINK_3052
{
/*
Do not use WLAN USB in RT3052 board due to Synopsys host controller
problem.
This is for WMM test when any WLAN USB is pluged into RT3052 board to
do AT/STA device.
1. One dnlink BK (18Mbps), Two uplinks BE (18Mbps) and BK (22Mbps)
When we do aggregation for BK traffic, there will have many NAKs
from USB device, only one pipe for Synopsys host controller,
these NAKs will cause we can not receive all packets from uplinks.
And the throughput of uplink BE will be smaller than dnlink BK.
Solution: No aggregation for dnlink in the case.
2. Two dnlink BE (18Mbps) and BK (22Mbps), one uplink BK (18Mbps)
We need to use aggregation function to get higher throughput for
BE traffic.
So some cases need aggregation and some cases do not need it.
==> Final solution:
1. Only for 20MHz and no BLOCK ACK mechanism in RT3052 platform.
2. Check how many ACs are used before aggregation.
If only one AC is used, aggregation function is disabled.
If more than one AC are used, aggregation function is enabled.
*/
}
#endif /* PLATFORM_RALINK_3052 */
#endif /* DOT11_N_SUPPORT */
#endif /* RTMP_MAC_USB */
#endif /* RELEASE_EXCLUDE */
do
{
#ifdef MT_MAC
TMAC_TXD_L *txd_l = (TMAC_TXD_L *)&pWirelessPkt[TmpBulkEndPos];
TMAC_TXD_S *txd_s = (TMAC_TXD_S *)&pWirelessPkt[TmpBulkEndPos];
TMAC_TXD_0 *txd_0 = &txd_s->txd_0;
TMAC_TXD_1 *txd_1 = &txd_s->txd_1;
TMAC_TXD_7 *txd_7;
if (txd_1->ft == TMI_FT_SHORT)
txd_7 = &txd_s->txd_7;
else
txd_7 = &txd_l->txd_7;
#else
pTxInfo = (TXINFO_STRUC *)&pWirelessPkt[TmpBulkEndPos];
pTxWI = (TXWI_STRUC *)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
#endif /* MT_MAC */
#ifdef RLT_MAC
if (pAd->chipCap.hif_type == HIF_RLT) {
#ifdef MT7601
if (IS_MT7601(pAd)) {
ampdu = pTxWI->TXWI_X.AMPDU;
phy_mode = pTxWI->TXWI_X.PHYMODE;
pid = pTxWI->TXWI_X.PacketId;
txwi_pkt_len = pTxWI->TXWI_X.MPDUtotalByteCnt;
}
else
#endif /* MT7601 */
{
ampdu = pTxWI->TXWI_N.AMPDU;
phy_mode = pTxWI->TXWI_N.PHYMODE;
pid = pTxWI->TXWI_N.TxPktId;
txwi_pkt_len = pTxWI->TXWI_N.MPDUtotalByteCnt;
}
}
#endif /* RLT_MAC */
#ifdef RTMP_MAC
if (pAd->chipCap.hif_type == HIF_RTMP) {
ampdu = pTxWI->TXWI_O.AMPDU;
phy_mode = pTxWI->TXWI_O.PHYMODE;
pid = pTxWI->TXWI_O.PacketId;
txwi_pkt_len = pTxWI->TXWI_O.MPDUtotalByteCnt;
}
#endif /* RTMP_MAC */
if (pAd->bForcePrintTX == TRUE)
DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", ampdu));
/* add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items*/
/*if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/
#ifndef MT_MAC
if ((ThisBulkSize != 0) && (phy_mode == MODE_CCK))
{
#ifndef USB_BULK_BUF_ALIGMENT
if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
{
/* Limit BulkOut size to about 4k bytes.*/
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
break;
}
#else
if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE))
{
/* Limit BulkOut size to about 24k bytes.*/
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
/*
when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section.
*/
bLasAlignmentsectiontRound = TRUE;
break;
}
#endif /* USB_BULK_BUF_ALIGMENT */
#ifndef USB_BULK_BUF_ALIGMENT
else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
{
/* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */
/* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.*/
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
break;
}
#else
else if (((pAd->BulkOutMaxPacketSize < 512) && (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE)) ))
{
/* Limit BulkOut size to about 24k bytes.*/
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
/*
when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section.
*/
bLasAlignmentsectiontRound = TRUE;
break;
}
#endif /* USB_BULK_BUF_ALIGMENT */
}
/* end Iverson*/
else
#endif /* MT_MAC */
{
#ifdef USB_BULK_BUF_ALIGMENT
if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE))
#else
if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
#endif /* USB_BULK_BUF_ALIGMENT */
{ /* Limit BulkOut size to about 24k bytes.*/
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
#ifdef USB_BULK_BUF_ALIGMENT
/*
when bulk size is > 0x6000, it mean that this is the lasttround at this alignmnet section.
*/
bLasAlignmentsectiontRound = TRUE;
/* printk("data bulk out bLasAlignmentsectiontRound \n");*/
#endif /* USB_BULK_BUF_ALIGMENT */
break;
}
#ifdef INF_AMAZON_SE
else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&pAd->BulkOutDataSizeLimit[BulkOutPipeId]) == pAd->BulkOutDataSizeLimit[BulkOutPipeId]))
{
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
break;
}
#endif /* INF_AMAZON_SE */
#ifndef USB_BULK_BUF_ALIGMENT
else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
{ /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */
/* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.*/
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
break;
}
#else
else if (((pAd->BulkOutMaxPacketSize < 512) && (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE)) ))
{
/* Limit BulkOut size to about 24k bytes. */
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
/*
when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section.
*/
bLasAlignmentsectiontRound = TRUE;
break;
}
#endif /* USB_BULK_BUF_ALIGMENT */
}
#ifdef USB_BULK_BUF_ALIGMENT
if ((TmpBulkEndPos == pHTTXContext->CurWritePosition) && (pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx))
#else
if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
#endif /* USB_BULK_BUF_ALIGMENT */
{
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
break;
}
#ifndef MT_MAC
if (pTxInfo->TxInfoQSEL != FIFO_EDCA)
{
DBGPRINT(RT_DEBUG_ERROR, ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n",
__FUNCTION__, pTxInfo->TxInfoQSEL));
DBGPRINT(RT_DEBUG_ERROR, ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n",
pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
}
if (pTxInfo->TxInfoPktLen <= 8)
{
BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, TxInfoPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
{
DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n",
pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
}
pAd->bForcePrintTX = TRUE;
BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
pAd->BulkOutPending[BulkOutPipeId] = FALSE;
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
/*DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->TxInfoPktLen=%d!\n", pTxInfo->TxInfoPktLen));*/
return;
}
/* Increase Total transmit byte counter*/
pAd->RalinkCounters.OneSecTransmittedByteCount += txwi_pkt_len;
pAd->RalinkCounters.TransmittedByteCount += txwi_pkt_len;
pLastTxInfo = pTxInfo;
/* Make sure we use EDCA QUEUE. */
pTxInfo->TxInfoQSEL = FIFO_EDCA;
ThisBulkSize += (pTxInfo->TxInfoPktLen+4);
TmpBulkEndPos += (pTxInfo->TxInfoPktLen+4);
if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
pTxInfo->TxInfoUDMANextVld = 1;
#else
padding = (4 - (txd_0->tx_byte_cnt % 4)) & 0x03;
ThisBulkSize += txd_0->tx_byte_cnt+padding;
pAd->RalinkCounters.OneSecTransmittedByteCount += (txd_0->tx_byte_cnt+padding);
TmpBulkEndPos += txd_0->tx_byte_cnt+padding;
#endif /* MT_MAC */
#ifndef USB_BULK_BUF_ALIGMENT
#ifndef MT_MAC
if (pTxInfo->TxInfoSwLstRnd == 1)
{
if (pHTTXContext->CurWritePosition == 8)
pTxInfo->TxInfoUDMANextVld = 0;
pTxInfo->TxInfoSwLstRnd = 0;
bTxQLastRound = TRUE;
pHTTXContext->ENextBulkOutPosition = 8;
#ifdef RT_BIG_ENDIAN
RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI);
#endif /* RT_BIG_ENDIAN */
break;
}
#else
if (txd_7->sw_field == 1)
{
txd_7->sw_field = 0;
bTxQLastRound = TRUE;
pHTTXContext->ENextBulkOutPosition = 8;
break;
}
#endif /* MT_MAC */
#endif /* USB_BULK_BUF_ALIGMENT */
#ifdef RT_BIG_ENDIAN
RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI);
#endif /* RT_BIG_ENDIAN */
aggregation_num++;
if ((aggregation_num == 1) && (!pAd->usb_ctl.usb_aggregation)) {
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
break;
}
}while (TRUE);
#ifdef CONFIG_DVT_MODE
DBGPRINT(RT_DEBUG_TRACE, ("%s::aggregation_num(%d), usb_aggregation(%d)\n", __FUNCTION__, aggregation_num, pAd->usb_ctl.usb_aggregation));
#endif /* CONFIG_DVT_MODE */
#ifndef MT_MAC
/* adjust the pTxInfo->TxInfoUDMANextVld value of last pTxInfo.*/
if (pLastTxInfo)
{
#ifdef RT_BIG_ENDIAN
RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
#endif /* RT_BIG_ENDIAN */
pLastTxInfo->TxInfoUDMANextVld = 0;
#ifdef RT_BIG_ENDIAN
RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
#endif /* RT_BIG_ENDIAN */
}
#endif /* MT_MAC */
/*
We need to copy SavedPad when following condition matched!
1. Not the last round of the TxQueue and
2. any match of following cases:
(1). The End Position of this bulk out is reach to the Currenct Write position and
the TxInfo and related header already write to the CurWritePosition.
=>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
(2). The EndPosition of the bulk out is not reach to the Current Write Position.
=>(ENextBulkOutPosition != CurWritePosition)
*/
#ifndef USB_BULK_BUF_ALIGMENT
if ((bTxQLastRound == FALSE) &&
(((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
(pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
)
{
NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
pHTTXContext->bCopySavePad = TRUE;
if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
{
PUCHAR pBuf = &pHTTXContext->SavedPad[0];
DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7]));
}
/*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));*/
}
#endif /* USB_BULK_BUF_ALIGMENT */
if (pAd->bForcePrintTX == TRUE)
DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
/*DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));*/
/* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.*/
pAppendant = &pWirelessPkt[TmpBulkEndPos];
NdisZeroMemory(pAppendant, 8);
ThisBulkSize += 4;
pHTTXContext->LastOne = TRUE;
pHTTXContext->BulkOutSize = ThisBulkSize;
#ifdef USB_BULK_BUF_ALIGMENT
/*
if it is the last alignment section round,that we just need to add nextbulkindex,
otherwise we both need to add nextbulkindex and CurWriteIdx
(because when alignment section round happened, the CurWriteIdx is added at function writing resource.)
*/
if(bLasAlignmentsectiontRound == TRUE)
{
CUR_WRITE_IDX_INC(pHTTXContext->NextBulkIdx, BUF_ALIGMENT_RINGSIZE);
pHTTXContext->ENextBulkOutPosition = 0;
}
else
{
CUR_WRITE_IDX_INC(pHTTXContext->NextBulkIdx, BUF_ALIGMENT_RINGSIZE);
pHTTXContext->ENextBulkOutPosition = 0;
CUR_WRITE_IDX_INC(pHTTXContext->CurWriteIdx, BUF_ALIGMENT_RINGSIZE);
pHTTXContext->CurWritePosition = 0;
}
#endif /* USB_BULK_BUF_ALIGMENT */
pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
/* Init Tx context descriptor*/
RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RtmpUsbBulkOutDataPacketComplete);
#ifdef USB_BULK_BUF_ALIGMENT
pUrb = pHTTXContext->pUrb[pHTTXContext->CurtBulkIdx];
#else
pUrb = pHTTXContext->pUrb;
#endif /* USB_BULK_BUF_ALIGMENT */
#ifdef USB_IOT_WORKAROUND2
if (pUrb->transfer_buffer_length <= W2_MAX_HTTX_SIZE)
usb_iot_add_padding(pUrb, pHTTXContext->usb_iot_w2_buf, pHTTXContext->usb_iot_w2_data_dma);
else{
DBGPRINT(RT_DEBUG_ERROR, ("[%s]USB_IOT_WORKAROUND2: transfer length=%d > %d, skip padding\n", __func__, pUrb->transfer_buffer_length, W2_MAX_HTTX_SIZE));
}
#endif
if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
{
#ifdef RELEASE_EXCLUDE
/*
Bug history:
1. Webcom
When submit non-BE packet, the function will fail here.
After EEPROM content is updated, everything is ok.
*/
#endif /* RELEASE_EXCLUDE */
DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
pAd->BulkOutPending[BulkOutPipeId] = FALSE;
pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
return;
}
BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
pHTTXContext->IRPPending = TRUE;
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
pAd->BulkOutReq++;
}
USBHST_STATUS RTUSBBulkOutDataPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs)
{
PHT_TX_CONTEXT pHTTXContext;
PRTMP_ADAPTER pAd;
POS_COOKIE pObj;
UCHAR BulkOutPipeId;
pHTTXContext = (PHT_TX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB);
pAd = pHTTXContext->pAd;
pObj = (POS_COOKIE) pAd->OS_Cookie;
/* Store BulkOut PipeId*/
BulkOutPipeId = pHTTXContext->BulkOutPipeId;
pAd->BulkOutDataOneSecCount++;
switch (BulkOutPipeId)
{
case EDCA_AC0_PIPE:
#ifdef CONFIG_ATE
if (!ATE_ON(pAd))
{
#endif /* CONFIG_ATE */
RTMP_NET_TASK_DATA_ASSIGN(&pObj->ac0_dma_done_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->ac0_dma_done_task);
#ifdef CONFIG_ATE
}
else
{
RTMP_NET_TASK_DATA_ASSIGN(&pObj->ate_ac0_dma_done_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->ate_ac0_dma_done_task);
}
#endif /* CONFIG_ATE */
break;
case EDCA_AC1_PIPE:
RTMP_NET_TASK_DATA_ASSIGN(&pObj->ac1_dma_done_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->ac1_dma_done_task);
break;
case EDCA_AC2_PIPE:
RTMP_NET_TASK_DATA_ASSIGN(&pObj->ac2_dma_done_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->ac2_dma_done_task);
break;
case EDCA_AC3_PIPE:
RTMP_NET_TASK_DATA_ASSIGN(&pObj->ac3_dma_done_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->ac3_dma_done_task);
break;
#ifdef USE_BMC
case EDCA_BMC_PIPE:
DBGPRINT_RAW(RT_DEBUG_INFO,("%s, EDCA_BMC_PIPE\n", __func__));
RTMP_NET_TASK_DATA_ASSIGN(&pObj->bmc_dma_done_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->bmc_dma_done_task);
break;
#endif /*USE_BMC*/
#ifndef MT_MAC
case HCCA_PIPE:
RTMP_NET_TASK_DATA_ASSIGN(&pObj->hcca_dma_done_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->hcca_dma_done_task);
break;
#endif /*not def MT_MAC */
#ifdef MULTI_WMM_SUPPORT
case EDCA_WMM1_AC0_PIPE:
RTMP_NET_TASK_DATA_ASSIGN(&pObj->wmm1_ac0_dma_done_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->wmm1_ac0_dma_done_task);
break;
#endif /* MULTI_WMM_SUPPORT */
}
#ifdef RELEASE_EXCLUDE
DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutDataPacketComplete\n"));
#endif /* RELEASE_EXCLUDE */
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note: NULL frame use BulkOutPipeId = 0
========================================================================
*/
VOID RTUSBBulkOutNullFrame(
IN PRTMP_ADAPTER pAd)
{
PTX_CONTEXT pNullContext = &(pAd->NullContext);
PURB pUrb;
int ret = 0;
unsigned long IrqFlags = 0;
RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
{
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
return;
}
pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
//pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
pNullContext->IRPPending = TRUE;
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
/* Increase Total transmit byte counter*/
pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
/* Clear Null frame bulk flag*/
RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
#ifdef RT_BIG_ENDIAN
RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO);
#endif /* RT_BIG_ENDIAN */
/* Init Tx context descriptor*/
RTUSBInitTxDesc(pAd, pNullContext, EDCA_BMC_PIPE, (usb_complete_t)RtmpUsbBulkOutNullFrameComplete);
pUrb = pNullContext->pUrb;
#ifdef USB_IOT_WORKAROUND2
if (pUrb->transfer_buffer_length <= W2_MAX_TX_SIZE)
usb_iot_add_padding(pUrb, pNullContext->usb_iot_w2_buf, pNullContext->usb_iot_w2_data_dma);
else{
DBGPRINT(RT_DEBUG_ERROR, ("[%s]USB_IOT_WORKAROUND2: transfer length=%d > %d, skip padding\n", __func__, pUrb->transfer_buffer_length, W2_MAX_TX_SIZE));
}
#endif
if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
{
RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
//pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
pNullContext->IRPPending = FALSE;
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
return;
}
}
/* NULL frame use BulkOutPipeId = 0*/
USBHST_STATUS RTUSBBulkOutNullFrameComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs)
{
PRTMP_ADAPTER pAd;
PTX_CONTEXT pNullContext;
//NTSTATUS Status;
POS_COOKIE pObj;
#ifdef RELEASE_EXCLUDE
DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutNullFrameComplete\n"));
#endif /* RELEASE_EXCLUDE */
pNullContext = (PTX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB);
pAd = pNullContext->pAd;
//Status = RTMP_OS_USB_STATUS_GET(pURB); /*->rtusb_urb_status;*/
pObj = (POS_COOKIE) pAd->OS_Cookie;
RTMP_NET_TASK_DATA_ASSIGN(&pObj->null_frame_complete_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->null_frame_complete_task);
#ifdef RELEASE_EXCLUDE
DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutNullFrameComplete\n"));
#endif /* RELEASE_EXCLUDE */
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note: MLME use BulkOutPipeId = 0
========================================================================
*/
VOID RTUSBBulkOutMLMEPacket(
IN PRTMP_ADAPTER pAd,
IN UCHAR Index)
{
PTX_CONTEXT pMLMEContext;
PURB pUrb;
int ret = 0;
unsigned long IrqFlags = 0;
pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
pUrb = pMLMEContext->pUrb;
if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
(pMLMEContext->InUse == FALSE) ||
(pMLMEContext->bWaitingBulkOut == FALSE))
{
#ifdef RELEASE_EXCLUDE
DBGPRINT(RT_DEBUG_INFO, ("Try to BulkOut coherent MgmtPkt(D=%d, C=%d, F=%d, InUse=%d, bWaitingBulkOut=%d)!\n",
pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxSwFreeIdx,
pMLMEContext->InUse, pMLMEContext->bWaitingBulkOut));
#endif /* RELEASE_EXCLUDE */
#ifdef CONFIG_DVT_MODE
DBGPRINT(RT_DEBUG_TRACE, ("%s::TxSwFreeIdx(%d,%d), InUse(%d), bWaitingBulkOut(%d)\n",
__FUNCTION__,
pAd->MgmtRing.TxSwFreeIdx,
MGMT_RING_SIZE,
pMLMEContext->InUse,
pMLMEContext->bWaitingBulkOut));
#endif /* CONFIG_DVT_MODE */
/* Clear MLME bulk flag*/
RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
return;
}
RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
{
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
return;
}
pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
//pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
pMLMEContext->IRPPending = TRUE;
pMLMEContext->bWaitingBulkOut = FALSE;
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
/* Increase Total transmit byte counter*/
pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
/* Clear MLME bulk flag*/
RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
#ifdef RT_BIG_ENDIAN
RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO);
#endif /* RT_BIG_ENDIAN */
/* Init Tx context descriptor*/
RTUSBInitTxDesc(pAd, pMLMEContext, EDCA_BMC_PIPE, (usb_complete_t)RtmpUsbBulkOutMLMEPacketComplete);
RTUSB_URB_DMA_MAPPING(pUrb);
pUrb = pMLMEContext->pUrb;
#ifdef USB_IOT_WORKAROUND2
if (pUrb->transfer_buffer_length <= W2_MAX_TX_SIZE)
usb_iot_add_padding(pUrb, pMLMEContext->usb_iot_w2_buf, pMLMEContext->usb_iot_w2_data_dma);
else{
DBGPRINT(RT_DEBUG_ERROR, ("[%s]USB_IOT_WORKAROUND2: transfer length=%d > %d, skip padding\n", __func__, pUrb->transfer_buffer_length, W2_MAX_TX_SIZE));
}
#endif
if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
{
DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
//pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
pMLMEContext->IRPPending = FALSE;
pMLMEContext->bWaitingBulkOut = TRUE;
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
return;
}
}
USBHST_STATUS RTUSBBulkOutMLMEPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs)
{
PTX_CONTEXT pMLMEContext;
PRTMP_ADAPTER pAd;
//NTSTATUS Status;
POS_COOKIE pObj;
//int index;
pMLMEContext = (PTX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB);
pAd = pMLMEContext->pAd;
pObj = (POS_COOKIE)pAd->OS_Cookie;
//Status = RTMP_OS_USB_STATUS_GET(pURB);
//index = pMLMEContext->SelfIdx;
RTMP_NET_TASK_DATA_ASSIGN(&pObj->mgmt_dma_done_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->mgmt_dma_done_task);
}
#ifdef MT_MAC
VOID RTUSBBulkOutBCNPacket(
IN PRTMP_ADAPTER pAd,
IN UCHAR Index)
{
PTX_CONTEXT pBcnContext;
PURB pUrb;
int ret = 0;
unsigned long IrqFlags = 0;
pBcnContext = (PTX_CONTEXT)pAd->BcnRing.Cell[pAd->BcnRing.TxDmaIdx].AllocVa;
pUrb = pBcnContext->pUrb;
if ((pAd->BcnRing.TxSwFreeIdx >= BCN_RING_SIZE) ||
(pBcnContext->InUse == FALSE) ||
(pBcnContext->bWaitingBulkOut == FALSE))
{
#ifdef RELEASE_EXCLUDE
DBGPRINT(RT_DEBUG_INFO, ("Try to BulkOut coherent BcnPkt(D=%d, C=%d, F=%d, InUse=%d, bWaitingBulkOut=%d)!\n",
pAd->BcnRing.TxDmaIdx, pAd->BcnRing.TxCpuIdx, pAd->BcnRing.TxSwFreeIdx,
pBcnContext->InUse, pBcnContext->bWaitingBulkOut));
#endif /* RELEASE_EXCLUDE */
/* Clear BCN bulk flag*/
RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_BCN);
return;
}
RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
{
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
return;
}
pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
//pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
pBcnContext->IRPPending = TRUE;
pBcnContext->bWaitingBulkOut = FALSE;
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
/* Increase Total transmit byte counter*/
pAd->RalinkCounters.TransmittedByteCount += pBcnContext->BulkOutSize;
/* Clear MLME bulk flag*/
RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_BCN);
#ifdef RT_BIG_ENDIAN
RTMPDescriptorEndianChange((PUCHAR)pBcnContext->TransferBuffer, TYPE_TXINFO);
#endif /* RT_BIG_ENDIAN */
/* Init Tx context descriptor*/
RTUSBInitTxDesc(pAd, pBcnContext, EDCA_BMC_PIPE, (usb_complete_t)RTUSBBulkOutBCNPacketComplete);
RTUSB_URB_DMA_MAPPING(pUrb);
pUrb = pBcnContext->pUrb;
#ifdef USB_IOT_WORKAROUND2
if (pUrb->transfer_buffer_length <= W2_MAX_TX_SIZE)
usb_iot_add_padding(pUrb, pBcnContext->usb_iot_w2_buf, pBcnContext->usb_iot_w2_data_dma);
else{
DBGPRINT(RT_DEBUG_ERROR, ("[%s]USB_IOT_WORKAROUND2: transfer length=%d > %d, skip padding\n", __func__, pUrb->transfer_buffer_length, W2_MAX_TX_SIZE));
}
#endif
if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
{
DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutBCNPacket: Submit BCN URB failed %d\n", ret));
RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
//pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
pBcnContext->IRPPending = FALSE;
pBcnContext->bWaitingBulkOut = TRUE;
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
return;
}
}
USBHST_STATUS RTUSBBulkOutBCNPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs)
{
PTX_CONTEXT pBcnContext;
PRTMP_ADAPTER pAd;
//NTSTATUS Status;
POS_COOKIE pObj;
//int index;
pBcnContext = (PTX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB);
pAd = pBcnContext->pAd;
pObj = (POS_COOKIE)pAd->OS_Cookie;
//Status = RTMP_OS_USB_STATUS_GET(pURB);
//index = pBcnContext->SelfIdx;
RTMP_NET_TASK_DATA_ASSIGN(&pObj->bcn_dma_done_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->bcn_dma_done_task);
}
#endif /* MT_MAC */
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note: PsPoll use BulkOutPipeId = 0
========================================================================
*/
VOID RTUSBBulkOutPsPoll(
IN PRTMP_ADAPTER pAd)
{
PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
PURB pUrb;
int ret = 0;
unsigned long IrqFlags = 0;
RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
{
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
return;
}
pAd->BulkOutPending[0] = TRUE;
pAd->watchDogTxPendingCnt[0] = 1;
pPsPollContext->IRPPending = TRUE;
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
/* Clear PS-Poll bulk flag*/
RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
#ifdef RT_BIG_ENDIAN
RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO);
#endif /* RT_BIG_ENDIAN */
/* Init Tx context descriptor*/
RTUSBInitTxDesc(pAd, pPsPollContext, EDCA_BMC_PIPE, (usb_complete_t)RtmpUsbBulkOutPsPollComplete);
pUrb = pPsPollContext->pUrb;
#ifdef USB_IOT_WORKAROUND2
if (pUrb->transfer_buffer_length <= W2_MAX_TX_SIZE)
usb_iot_add_padding(pUrb, pPsPollContext->usb_iot_w2_buf, pPsPollContext->usb_iot_w2_data_dma);
else{
DBGPRINT(RT_DEBUG_ERROR, ("[%s]USB_IOT_WORKAROUND2: transfer length=%d > %d, skip padding\n", __func__, pUrb->transfer_buffer_length, W2_MAX_TX_SIZE));
}
#endif
if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
{
RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
pAd->BulkOutPending[0] = FALSE;
pAd->watchDogTxPendingCnt[0] = 0;
pPsPollContext->IRPPending = FALSE;
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
return;
}
}
/* PS-Poll frame use BulkOutPipeId = 0*/
USBHST_STATUS RTUSBBulkOutPsPollComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs)
{
PRTMP_ADAPTER pAd;
PTX_CONTEXT pPsPollContext;
//NTSTATUS Status;
POS_COOKIE pObj;
#ifdef RELEASE_EXCLUDE
DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutPsPollComplete\n"));
#endif /* RELEASE_EXCLUDE */
pPsPollContext= (PTX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB);
pAd = pPsPollContext->pAd;
//Status = RTMP_OS_USB_STATUS_GET(pURB);
pObj = (POS_COOKIE) pAd->OS_Cookie;
RTMP_NET_TASK_DATA_ASSIGN(&pObj->pspoll_frame_complete_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->pspoll_frame_complete_task);
#ifdef RELEASE_EXCLUDE
DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutPsPollComplete\n"));
#endif /* RELEASE_EXCLUDE */
}
NDIS_SPIN_LOCK *RTUSBGetSpinLock(PRTMP_ADAPTER pAd, DL_LIST *list)
{
NDIS_SPIN_LOCK *Lock = NULL;
if (list == &pAd->RxFreeQ)
Lock = &pAd->RxFreeQLock;
else if (list == &pAd->RxProcessingQ)
Lock = &pAd->RxProcessingQLock;
else if (list == &pAd->RxBulkInQ)
Lock = &pAd->RxBulkInQLock;
else
DBGPRINT(RT_DEBUG_ERROR, ("%s:illegal list\n", __FUNCTION__));
return Lock;
}
VOID _RTUSBUnlinkRxContext(PRX_CONTEXT pRxContext, DL_LIST *list)
{
if (!pRxContext)
return;
DlListDel(&pRxContext->list);
}
VOID RTUSBUnlinkRxContext(PRTMP_ADAPTER pAd, PRX_CONTEXT pRxContext, DL_LIST *list)
{
unsigned long flags;
NDIS_SPIN_LOCK *Lock;
Lock = RTUSBGetSpinLock(pAd, list);
RTMP_SPIN_LOCK_IRQSAVE(Lock, &flags);
_RTUSBUnlinkRxContext(pRxContext, list);
RTMP_SPIN_UNLOCK_IRQRESTORE(Lock, &flags);
}
PRX_CONTEXT _RTUSBDequeueRxContext(DL_LIST *list)
{
PRX_CONTEXT pRxContext;
pRxContext = DlListFirst(list, RX_CONTEXT, list);
_RTUSBUnlinkRxContext(pRxContext, list);
return pRxContext;
}
PRX_CONTEXT RTUSBDequeueRxContext(PRTMP_ADAPTER pAd, DL_LIST *list)
{
unsigned long flags;
PRX_CONTEXT RxContext;
NDIS_SPIN_LOCK *Lock;
Lock = RTUSBGetSpinLock(pAd, list);
RTMP_SPIN_LOCK_IRQSAVE(Lock, &flags);
RxContext = _RTUSBDequeueRxContext(list);
RTMP_SPIN_UNLOCK_IRQRESTORE(Lock, &flags);
return RxContext;
}
VOID _RTUSBQueueTailRxContext(DL_LIST *list, PRX_CONTEXT pRxContext)
{
DlListAddTail(list, &pRxContext->list);
}
VOID RTUSBQueueTailRxContext(PRTMP_ADAPTER pAd, DL_LIST *list, PRX_CONTEXT pRxContext)
{
unsigned long flags;
NDIS_SPIN_LOCK *Lock;
Lock = RTUSBGetSpinLock(pAd, list);
RTMP_SPIN_LOCK_IRQSAVE(Lock, &flags);
_RTUSBQueueTailRxContext(list, pRxContext);
RTMP_SPIN_UNLOCK_IRQRESTORE(Lock, &flags);
}
UINT32 RTUSBQueueLen(PRTMP_ADAPTER pAd, DL_LIST *list)
{
UINT32 qlen;
unsigned long flags;
NDIS_SPIN_LOCK *Lock;
Lock = RTUSBGetSpinLock(pAd, list);
RTMP_SPIN_LOCK_IRQSAVE(Lock, &flags);
qlen = DlListLen(list);
RTMP_SPIN_UNLOCK_IRQRESTORE(Lock, &flags);
return qlen;
}
/*Nobody uses it curretly*/
#if 0
static INT32 RTUSBQueueEmpty(PRTMP_ADAPTER pAd, DL_LIST *list)
{
unsigned long flags;
int is_empty;
NDIS_SPIN_LOCK *Lock;
Lock = RTUSBGetSpinLock(pAd, list);
RTMP_SPIN_LOCK_IRQSAVE(Lock, &flags);
is_empty = DlListEmpty(list);
RTMP_SPIN_UNLOCK_IRQRESTORE(Lock, &flags);
return is_empty;
}
#endif
VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
{
PRX_CONTEXT pRxContext;
PURB pUrb;
int ret = 0;
while ((RTUSBQueueLen(pAd, &pAd->RxBulkInQ) < 2) &&
(pRxContext = RTUSBDequeueRxContext(pAd, &pAd->RxFreeQ)))
{
RTUSBInitRxDesc(pAd, pRxContext);
pUrb = pRxContext->pUrb;
RTUSBQueueTailRxContext(pAd, &pAd->RxBulkInQ, pRxContext);
if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0)
{
//RTUSBQueueTailRxContext(pAd, &pAd->RxFreeQ, pRxContext);
DBGPRINT(RT_DEBUG_OFF, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
RTUSBUnlinkRxContext(pAd, pRxContext, &pAd->RxBulkInQ);
}
else
{
}
#ifdef CONFIG_TRACE_SUPPORT
TRACE_USB_BULK_IN_INFO(pAd, __FUNCTION__, pRxContext, ret);
#endif
}
}
#define fRTMP_ADAPTER_NEED_STOP_RX \
(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
#define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
VOID RTUSBBulkReceive(RTMP_ADAPTER *pAd)
{
PRX_CONTEXT pRxContext;
unsigned long IrqFlags = 0;
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX)
&& !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_POLL_IDLE))
return;
#ifdef CONFIG_TRACE_SUPPORT
TRACE_USB_BULK_QLEN(pAd, __FUNCTION__, RX_FREEQ, &pAd->RxFreeQ);
TRACE_USB_BULK_QLEN(pAd, __FUNCTION__, RX_BULKINQ, &pAd->RxBulkInQ);
TRACE_USB_BULK_QLEN(pAd, __FUNCTION__, RX_PROCESSINGQ, &pAd->RxProcessingQ);
#endif
if (!((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)
&& (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_POLL_IDLE)))))
{
#ifdef CONFIG_STA_SUPPORT
if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
return;
#endif /* CONFIG_STA_SUPPORT */
DoBulkIn(pAd);
}
while ((pRxContext = RTUSBDequeueRxContext(pAd, &pAd->RxProcessingQ)))
{
#ifdef CONFIG_TRACE_SUPPORT
TRACE_USB_BULK_IN_RECEIVE(pAd, __FUNCTION__, 0, pRxContext);
#endif
RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
pAd->RxBulkInReadIndex = pRxContext->Id;
RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
rtmp_rx_done_handle(pAd);
pRxContext->BulkInOffset = 0;
pRxContext->ReadPosition = 0;
#ifdef CONFIG_TRACE_SUPPORT
TRACE_USB_BULK_IN_RECEIVE(pAd, __FUNCTION__, 1, pRxContext);
#endif
RTUSBQueueTailRxContext(pAd, &pAd->RxFreeQ, pRxContext);
}
if (!((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)
&& (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_POLL_IDLE)))))
{
DoBulkIn(pAd);
}
}
USBHST_STATUS RTUSBBulkRxComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs)
{
PRX_CONTEXT pRxContext;
PRTMP_ADAPTER pAd;
POS_COOKIE pObj;
NTSTATUS Status;
Status = RTMP_USB_URB_STATUS_GET(pURB);
pRxContext = (PRX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB);
pAd = pRxContext->pAd;
pObj = (POS_COOKIE)pAd->OS_Cookie;
RTUSBUnlinkRxContext(pAd, pRxContext, &pAd->RxBulkInQ);
pRxContext->BulkInOffset = RTMP_USB_URB_LEN_GET(pURB);
#ifdef CONFIG_TRACE_SUPPORT
TRACE_USB_BULK_IN_RX_COMPLETE(__FUNCTION__, RTMP_OS_USB_STATUS_GET(pURB),
RTMP_OS_USB_TRANSFER_LEN_GET(pURB),
RTMP_OS_USB_ACTUAL_LEN_GET(pURB));
#endif
if ((Status == 0) && (pRxContext->BulkInOffset != 0))
{
RTUSBQueueTailRxContext(pAd, &pAd->RxProcessingQ, pRxContext);
}
else
{
RTUSBQueueTailRxContext(pAd, &pAd->RxFreeQ, pRxContext);
}
#ifdef CONFIG_TRACE_SUPPORT
TRACE_USB_BULK_QLEN(pAd, __FUNCTION__, RX_FREEQ, &pAd->RxFreeQ);
TRACE_USB_BULK_QLEN(pAd, __FUNCTION__, RX_BULKINQ, &pAd->RxBulkInQ);
TRACE_USB_BULK_QLEN(pAd, __FUNCTION__, RX_PROCESSINGQ, &pAd->RxProcessingQ);
#endif
if (!((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)
&& (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_POLL_IDLE)))))
{
#ifdef CONFIG_STA_SUPPORT
if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
return;
#endif /* CONFIG_STA_SUPPORT */
if (!pAd->PM_FlgSuspend)
DoBulkIn(pAd);
}
RTMP_NET_TASK_DATA_ASSIGN(&pObj->rx_done_task, (unsigned long)pURB);
RTMP_OS_TASKLET_SCHE(&pObj->rx_done_task);
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
VOID RTUSBKickBulkOut(
IN PRTMP_ADAPTER pAd)
{
#ifdef RELEASE_EXCLUDE
DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBKickBulkOut\n"));
#endif /* RELEASE_EXCLUDE */
/* BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.*/
if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
#if defined(STA_LP_PHASE_1_SUPPORT) || defined(STA_LP_PHASE_2_SUPPORT)
&& (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
#endif /* STA_LP_PHASE_1_SUPPORT || STA_LP_PHASE_2_SUPPORT */
#ifdef CONFIG_ATE
&& !(ATE_ON(pAd))
#endif /* CONFIG_ATE */
)
{
/* 2. PS-Poll frame is next*/
if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
{
RTUSBBulkOutPsPoll(pAd);
}
/* 5. Mlme frame is next*/
else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) ||
(pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
{
RTUSBBulkOutMLMEPacket(pAd, (UCHAR)pAd->MgmtRing.TxDmaIdx);
}
#ifdef MT_MAC
/* 6. BCN frame is next*/
else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_BCN)) ||
(pAd->BcnRing.TxSwFreeIdx < BCN_RING_SIZE))
{
RTUSBBulkOutBCNPacket(pAd, (UCHAR)pAd->BcnRing.TxDmaIdx);
}
#endif
#ifdef USE_BMC
if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5))
{
if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
))
{
RTUSBBulkOutDataPacket(pAd, EDCA_BMC_PIPE, pAd->NextBulkOutIndex[EDCA_BMC_PIPE]);
}
}
#endif /* USE_BMC */
/* 7. Data frame normal is next*/
if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
{
if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
#ifdef MESH_SUPPORT
|| MESH_ON(pAd)
#endif /* MESH_SUPPORT */
#ifdef P2P_SUPPORT
|| P2P_GO_ON(pAd) || P2P_CLI_ON(pAd)
#endif /* P2P_SUPPORT */
#ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE
|| RTMP_CFG80211_VIF_P2P_GO_ON(pAd) || RTMP_CFG80211_VIF_P2P_CLI_ON(pAd)
#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */
))
{
RTUSBBulkOutDataPacket(pAd, EDCA_AC0_PIPE, pAd->NextBulkOutIndex[EDCA_AC0_PIPE]);
}
}
if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
{
if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
#ifdef MESH_SUPPORT
|| MESH_ON(pAd)
#endif /* MESH_SUPPORT */
#ifdef P2P_SUPPORT
|| P2P_GO_ON(pAd) || P2P_CLI_ON(pAd)
#endif /* P2P_SUPPORT */
#ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE
|| RTMP_CFG80211_VIF_P2P_GO_ON(pAd) || RTMP_CFG80211_VIF_P2P_CLI_ON(pAd)
#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */
))
{
RTUSBBulkOutDataPacket(pAd, EDCA_AC1_PIPE, pAd->NextBulkOutIndex[EDCA_AC1_PIPE]);
}
}
if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
{
if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
#ifdef MESH_SUPPORT
|| MESH_ON(pAd)
#endif /* MESH_SUPPORT */
#ifdef P2P_SUPPORT
|| P2P_GO_ON(pAd) || P2P_CLI_ON(pAd)
#endif /* P2P_SUPPORT */
#ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE
|| RTMP_CFG80211_VIF_P2P_GO_ON(pAd) || RTMP_CFG80211_VIF_P2P_CLI_ON(pAd)
#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */
))
{
RTUSBBulkOutDataPacket(pAd, EDCA_AC2_PIPE, pAd->NextBulkOutIndex[EDCA_AC2_PIPE]);
}
}
if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
{
if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
#ifdef MESH_SUPPORT
|| MESH_ON(pAd)
#endif /* MESH_SUPPORT */
))
{
RTUSBBulkOutDataPacket(pAd, EDCA_AC3_PIPE, pAd->NextBulkOutIndex[EDCA_AC3_PIPE]);
}
}
#ifdef MULTI_WMM_SUPPORT
if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_WMM1_NORMAL))
{
if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
#ifdef MESH_SUPPORT
|| MESH_ON(pAd)
#endif /* MESH_SUPPORT */
))
{
RTUSBBulkOutWmm1DataPacket(pAd, EDCA_AC0_PIPE, pAd->NextBulkOutWmm1Index[EDCA_AC0_PIPE]);
}
}
#endif /* MULTI_WMM_SUPPORT */
/* 8. Null frame is the last*/
else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
{
#if 0 //need to remove this to let null frame can be sent
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
#endif
{
RTUSBBulkOutNullFrame(pAd);
}
}
/* 8. No data avaliable*/
else
{
}
}
#ifdef CONFIG_ATE
else if((ATE_ON(pAd)) &&
!RTMP_TEST_FLAG(pAd , fRTMP_ADAPTER_NEED_STOP_TX))
{
if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE))
{
ATE_RTUSBBulkOutDataPacket(pAd, EDCA_AC0_PIPE);
}
}
#endif /* CONFIG_ATE */
#if defined(STA_LP_PHASE_1_SUPPORT) || defined(STA_LP_PHASE_2_SUPPORT)
else if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
{
DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s:: Bypass since H/W is in DOZE\n", __FUNCTION__));
}
#endif /* STA_LP_PHASE_1_SUPPORT || STA_LP_PHASE_2_SUPPORT */
#ifdef RELEASE_EXCLUDE
DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBKickBulkOut\n"));
#endif /* RELEASE_EXCLUDE */
}
/*
========================================================================
Routine Description:
Call from Reset action after BulkOut failed.
Arguments:
Return Value:
Note:
========================================================================
*/
VOID RTUSBCleanUpDataBulkOutQueue(
IN PRTMP_ADAPTER pAd)
{
UCHAR Idx;
PHT_TX_CONTEXT pTxContext;
DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
for (Idx = 0; Idx < 4; Idx++)
{
pTxContext = &pAd->TxContext[Idx];
pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
pTxContext->LastOne = FALSE;
NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
pAd->BulkOutPending[Idx] = FALSE;
NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
}
DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
VOID RTUSBCleanUpMLMEBulkOutQueue(
IN PRTMP_ADAPTER pAd)
{
DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
#if 0 /* Do nothing!*/
NdisAcquireSpinLock(&pAd->MLMEBulkOutLock);
while (pAd->PrioRingTxCnt > 0)
{
pAd->MLMEContext[pAd->PrioRingFirstIndex].InUse = FALSE;
pAd->PrioRingFirstIndex++;
if (pAd->PrioRingFirstIndex >= MGMT_RING_SIZE)
{
pAd->PrioRingFirstIndex = 0;
}
pAd->PrioRingTxCnt--;
}
NdisReleaseSpinLock(&pAd->MLMEBulkOutLock);
#endif
DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
VOID RTUSBCancelPendingIRPs(
IN PRTMP_ADAPTER pAd)
{
RTUSBCancelPendingBulkInIRP(pAd);
RTUSBCancelPendingBulkOutIRP(pAd);
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
VOID RTUSBCancelPendingBulkInIRP(RTMP_ADAPTER *pAd)
{
PRX_CONTEXT pRxContext;
UINT32 i;
DBGPRINT(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
for (i=0; i < RX_RING_SIZE; i++)
{
pRxContext = &(pAd->RxContext[i]);
RTUSB_UNLINK_URB(pRxContext->pUrb);
}
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
VOID RTUSBCancelPendingBulkOutIRP(
IN PRTMP_ADAPTER pAd)
{
PHT_TX_CONTEXT pHTTXContext;
PTX_CONTEXT pMLMEContext;
PTX_CONTEXT pNullContext;
PTX_CONTEXT pPsPollContext;
UINT i, Idx;
/* unsigned int IrqFlags;*/
/* NDIS_SPIN_LOCK *pLock;*/
/* BOOLEAN *pPending;*/
/* pLock = &pAd->BulkOutLock[MGMTPIPEIDX];*/
/* pPending = &pAd->BulkOutPending[MGMTPIPEIDX];*/
for (Idx = 0; Idx < 4; Idx++)
{
pHTTXContext = &(pAd->TxContext[Idx]);
if (pHTTXContext->IRPPending == TRUE)
{
/* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself*/
/* remove it from the HeadPendingSendList and NULL out HeadPendingSendList*/
/* when the last IRP on the list has been cancelled; that's how we exit this loop*/
#ifdef USB_BULK_BUF_ALIGMENT
INT ringidx;;
for(ringidx=0;ringidx < BUF_ALIGMENT_RINGSIZE ;ringidx++)
RTUSB_UNLINK_URB(pHTTXContext->pUrb[ringidx]);
#else
RTUSB_UNLINK_URB(pHTTXContext->pUrb);
#endif /* USB_BULK_BUF_ALIGMENT */
/* Sleep 200 microseconds to give cancellation time to work*/
RtmpusecDelay(200);
}
#ifdef CONFIG_ATE
pHTTXContext->bCopySavePad = 0;
pHTTXContext->CurWritePosition = 0;
pHTTXContext->CurWriteRealPos = 0;
pHTTXContext->bCurWriting = FALSE;
pHTTXContext->NextBulkOutPosition = 0;
pHTTXContext->ENextBulkOutPosition = 0;
#endif /* CONFIG_ATE */
pAd->BulkOutPending[Idx] = FALSE;
}
/*RTMP_IRQ_LOCK(pLock, IrqFlags);*/
for (i = 0; i < MGMT_RING_SIZE; i++)
{
pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
{
/* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself*/
/* remove it from the HeadPendingSendList and NULL out HeadPendingSendList*/
/* when the last IRP on the list has been cancelled; that's how we exit this loop*/
RTUSB_UNLINK_URB(pMLMEContext->pUrb);
pMLMEContext->IRPPending = FALSE;
/* Sleep 200 microsecs to give cancellation time to work*/
RtmpusecDelay(200);
}
}
pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
/*RTMP_IRQ_UNLOCK(pLock, IrqFlags);*/
pNullContext = &(pAd->NullContext);
if (pNullContext->IRPPending == TRUE)
RTUSB_UNLINK_URB(pNullContext->pUrb);
pPsPollContext = &(pAd->PsPollContext);
if (pPsPollContext->IRPPending == TRUE)
RTUSB_UNLINK_URB(pPsPollContext->pUrb);
for (Idx = 0; Idx < 4; Idx++)
{
NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
pAd->BulkOutPending[Idx] = FALSE;
NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
}
}
#endif /* RTMP_MAC_USB */