?? txproc.c
字號:
/******************* ?Marvell Semiconductor, Inc., 2001-2004 *****************
*
* Purpose: This module has the implementation of TX functions
*
* $Author: cuizt $
*
* $Date: 2007/07/02 09:10:17 $
*
* $Revision: 1.9.2.2 $
*
*****************************************************************************/
#include "precomp.h"
// compilation error if this file is not included
#ifdef UNDER_CE
#include "pkfuncs.h"
#endif
#ifdef SDIO
#include "SDCardDDK.h"
#endif // SDIO
//////////////added by zhangb////////////////
#include "ParaRoamingProc.h"
//////////////added by zhangb////////////////
#ifdef DEBUG_PARA_ROAMING
extern PRIVATE_PARAROAMING_ADAPTER priv;
#endif
/******************************************************************************
*
* Name: MrvDrvSend()
*
* Description: NDIS miniport serialized send packet routine
*
* Conditions for Use: Protocol driver will call this routine to pass Tx NDIS_PACKET
*
* Arguments:
* IN NDIS_HANDLE MiniportAdapterContext
* IN PPNDIS_PACKET Packet
* IN UINT Flags
*
* Return Value: NDIS_STATUS_RESOURCES or NDIS_STATUS_PENDING
*
* Notes:
*
*****************************************************************************/
NDIS_STATUS
MrvDrvSend(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT Flags)
{
PMRVDRV_ADAPTER Adapter;
NDIS_STATUS Status;
#if 0
NDIS_STATUS iStatus;
#endif ///0
PNDIS_PACKET pPacket;
//DWORD waitStatus; // wait status
PTXQ_KEEPER pTxQKeeper;
PTXQ_NODE pTQNode;
//int pri;
#ifdef RETQ_TIMER
BOOLEAN timerStatus;
#endif
#ifdef PARA_WPA_1X
UINT BufferCount;
UINT TotalPacketLength=0;
UINT TotalBufferLength=0;
UINT BytesCopied=0;
UINT Length, AccumLength;
PNDIS_BUFFER pBuffer, pNextBuffer;
ULONG i;
PVOID pVirtualAddr;
PTxCtrlNode pTxNode;
// due to fix for odd sized buffers, WepBuffer is used in both
// WEP and no-WEP scenarios
//UCHAR WepBuffer[MRVDRV_ETH_TX_PACKET_BUFFER_SIZE];
//BOOLEAN doWep = FALSE;
//BOOLEAN NotEncryption4EAPOL = FALSE;
UCHAR Buffer[MRVDRV_ETH_TX_PACKET_BUFFER_SIZE];
BOOLEAN bIsEtherPacket = TRUE;
PUCHAR pDest = Buffer;
PUCHAR pHeader = NULL;
BOOLEAN useBuffer = FALSE;
ULONG coBufferLength = 0;
#endif
// return NDIS_STATUS_SUCCESS;
Status = NDIS_STATUS_SUCCESS;
Adapter = (PMRVDRV_ADAPTER)MiniportAdapterContext;
DBGPRINT(DBG_TXDATA, ("+MrvDrvSend()\n"));
#if 0
EnterCriticalSection(&Adapter->TxCriticalSection);
#if 0
while(1)
{
pTxQKeeper = (PTXQ_KEEPER)&Adapter->TXRETQ;
pTQNode = PopFirstTxQNode(pTxQKeeper);
if(pTQNode)
{
pPacket = pTQNode -> pPacket;
//tt ++ ra fail
if ( pPacket == NULL )
V5DbgMsg( (L" ??? nul pkt 2\n") );
if ( pPacket )
{
//tt --
iStatus = NDIS_STATUS_SUCCESS;
NDIS_SET_PACKET_STATUS(pPacket, iStatus);
NdisMSendComplete(
Adapter->MrvDrvAdapterHdl,
pPacket,
iStatus);
} //tt ra fail
PushFreeTxQNode(Adapter->TxFreeQ,pTQNode);
}
else
break;
}
#else
BatchIndicateRetQPkts(Adapter);
#endif
#ifdef RETQ_TIMER
//if( Adapter->RetQTimerIsSet == TRUE )
if( Adapter->RetQTimerIsSet)
{
Adapter->RetQTimerIsSet = 0;
NdisMCancelTimer(&Adapter->MrvRetQTimer, &timerStatus);
}
#endif
LeaveCriticalSection(&Adapter->TxCriticalSection);
#endif
#ifdef DEEP_SLEEP
// In Deep Sleep Mode no packet can be sent out
if (Adapter->IsDeepSleep)
{
Status = NDIS_STATUS_NO_CABLE;
}
#endif
// Check device removal status
if( Adapter->SurpriseRemoved == TRUE )
{
RETAILMSG(1,(TEXT("\n\r[MrvSend]: NDIS_STATUS_FAILURE")));
return NDIS_STATUS_FAILURE;
}
if ( Adapter->bIsPendingReset == TRUE )
{
RETAILMSG(1,(TEXT("\n\r[MrvSend]: NDIS_STATUS_FAILURE")));
return NDIS_STATUS_FAILURE;
}
if ( Adapter->MediaConnectStatus == NdisMediaStateDisconnected )
{
DBGPRINT(DBG_WARNING, ("***WARNING: OS attempted to send packet while disconnected!\n"));
RETAILMSG(1,(TEXT("[Marvell]MrvDrvSend:***1WARNING: OS attempted to send packet while disconnected!")));
DraleeMsg((L"[MrvSend]:disconnected"));
#ifdef DEBUG_PARA_ROAMING
if ( (!priv.bAutoRoamingInProcess) && (!priv.bManualRoamingInProcess))
{
#else
#endif
NdisMIndicateStatus(
Adapter->MrvDrvAdapterHdl,
NDIS_STATUS_MEDIA_DISCONNECT,
(PVOID)NULL,
0);
NdisMIndicateStatusComplete(Adapter->MrvDrvAdapterHdl);
#ifdef DEBUG_PARA_ROAMING
}
#else
#endif
//RETAILMSG(1,(TEXT("[Marvell]MrvDrvSend:***2WARNING: OS attempted to send packet while disconnected!")));
V5DbgMsg( (L" * disconn\n") );
#if 1 //dralee_20051128
CleanUpSingleTxBuffer(Adapter);
ResetRxPDQ(Adapter);
#endif
return NDIS_STATUS_FAILURE;
}
#if 0
// check if the current command is scan, if so, ask NDIS to hold the packet
if ( (Adapter->CurCmd != NULL) &&
(Adapter->CurCmd->ExpectedRetCode == HostCmd_RET_802_11_SCAN) )
{
RETAILMSG(1,(TEXT("\r\nTX: Scan in progress, return NDIS_STATUS_RESOURCES")));
Adapter->ResourcesEvts |= RSC_SCANNING;
return NDIS_STATUS_RESOURCES;
}
#endif
#if 1 //dralee_20051128
//Plus
if( Adapter->bIsScanInProgress == TRUE )
return NDIS_STATUS_SUCCESS;
#endif
#ifdef PARA_WPA_1X
//#ifdef MRVL_CHECK_TXPACKET
// check if in key absent state, if so, block all packet other than
// 802.1x
if ( (Adapter->EncryptionStatus == Ndis802_11Encryption2KeyAbsent )|| (Adapter->EncryptionStatus == Ndis802_11Encryption3KeyAbsent ) )
{
//pTxNode = &Adapter->TxNode;
NdisQueryPacket(
Packet,
NULL,
&BufferCount,
&pBuffer,
&TotalPacketLength );
if (!pBuffer || !BufferCount || !TotalPacketLength)
{
#ifdef MRVL_PRINT_FILE_MSG
MrvPrintFileMSG("[Marvell]MrvDrvSend:NdisQueryPacket Fail!! Return NDIS_STATUS_FAILURE!!\n");
#endif
return NDIS_STATUS_FAILURE;
}
NdisQueryBufferSafe(pBuffer, &pVirtualAddr, &Length, HighPagePriority);
////NKDbgPrintfW(TEXT("WLAN: [2] pBuffer is %x \n"),pBuffer);
// if(pVirtualAddr == NULL)
// {
// NdisMSleep(20);
// NdisQueryBufferSafe(pBuffer, &pVirtualAddr, &Length, NormalPagePriority);
////NKDbgPrintfW(TEXT("WLAN: [3] pBuffer is %x \n"),pBuffer);
////NKDbgPrintfW(TEXT("WLAN: [3] pRxBufVM is %x \n"),pRxBufVM);
// }
if(pVirtualAddr == NULL)
return NDIS_STATUS_FAILURE;
pHeader = (PUCHAR)pVirtualAddr;
if ( TotalPacketLength < 14 )
{
// malformed packet, blocked!
DBGPRINT(DBG_TXDATA|DBG_WARNING,("Got packet with size less than 14 bytes, reject!\n"));
#ifdef MRVL_PRINT_FILE_MSG
MrvPrintFileMSG("[Marvell]MrvDrvSend:Got packet with size less than 14 bytes, reject!!\n");
#endif
return NDIS_STATUS_FAILURE;
}
if ( (pHeader[12] != 0x88) || (pHeader[13] != 0x8E) )
{
DBGPRINT(DBG_TXDATA|DBG_WARNING,("Still no key and packet type(0x%x 0x%x)is not 802.1x , drop!\n",
pHeader[12],
pHeader[13]));
#ifdef MRVL_PRINT_FILE_MSG
MrvPrintFileMSG("[Marvell]MrvDrvSend:pHeader[6]=0x%x\n,pHeader[7]=0x%x\n,pHeader[8]=0x%x\n,pHeader[9]=0x%x\n,pHeader[10]=0x%x\n,pHeader[11]=0x%x\n,pHeader[12]=0x%x\n,pHeader[13]=0x%x\n,pHeader[14]=0x%x\n,pHeader[15]=0x%x\n,Adapter->TxPacketCount =%d\n",pHeader[6],pHeader[7],pHeader[8],pHeader[9],pHeader[10],pHeader[11],pHeader[12],pHeader[13],pHeader[14],pHeader[15],Adapter->TxPacketCount);
#endif
return NDIS_STATUS_FAILURE;
}
}// if ( (Adapter->EncryptionStatus == Ndis802_11Encryption2KeyAbsent )|| (Adapter->EncryptionStatus == Ndis802_11Encryption3KeyAbsent ) )
//#endif //MRVL_PRINT_FILE_MSG
#endif
/* dralee
if( ( Adapter->psState != PS_STATE_SLEEP ) &&
(Adapter->RoamingNeedToRoam == FALSE ) )
{
*/
if(Adapter->TxPacketCount > 6) //flow control
NdisMSleep(20000);
#ifdef CONFIG_WLAN_PMU
wlan_PMUTxPkt();
#endif
EnterCriticalSection(&Adapter->TxCriticalSection);
if(Adapter->TxPacketCount >= (MAX_TX_PACKETS-1) )
{
RETAILMSG(1,(L"Enter Waiting ..:%d\n\r",Adapter->TxPacketCount));
V5DbgMsg( (L"=== MrvDrvSend, TxPacketCount=%d\n", Adapter->TxPacketCount) ); //tt ra fail
//Adapter->PendingTxCnt = 1;
#if 1
if( Adapter->RetQTimerIsSet)
{
Adapter->RetQTimerIsSet = 0;
NdisMCancelTimer(&Adapter->MrvRetQTimer, &timerStatus);
BatchIndicateRetQPkts(Adapter);
}
#endif
LeaveCriticalSection(&Adapter->TxCriticalSection);
V5DbgMsg( (L"- return resources\n") );
//return NDIS_STATUS_RESOURCES; //dralee_1209, resource hang system,
return NDIS_STATUS_FAILURE; //so, return fail is a little better...
}
//record how many tx pkt is sent.
Adapter->TxPacketSend++;
DBGPRINT(DBG_TXDATADUMP,("[Marvell:MrvDrvSend] Adapter->TxPacketSend=%d\n", Adapter->TxPacketSend));
//if((Adapter->TxPacketGet != Adapter->TxPacketComplete) || (Adapter->CurCmd != NULL))
if( Adapter->SentPacket || (Adapter->CurCmd != NULL))
{
TxPacketEnQueue(Adapter, Packet);
Adapter->TxPacketCount++;
#if 1
if( Adapter->RetQTimerIsSet)
{
Adapter->RetQTimerIsSet = 0;
NdisMCancelTimer(&Adapter->MrvRetQTimer, &timerStatus);
BatchIndicateRetQPkts(Adapter);
}
#endif
LeaveCriticalSection(&Adapter->TxCriticalSection);
return NDIS_STATUS_PENDING;
}
if( Adapter->TxPacketCount )
{
TxPacketEnQueue(Adapter, Packet);
TxPacketDeQueue(Adapter, &pTxQKeeper, &pTQNode);
// tt ++ ps check
if ( pTQNode == NULL )
DBGPRINT(DBG_TXDATA, ("pq: 2\n") );
// tt --
pPacket = pTQNode -> pPacket;
//RETAILMSG(1,(L"Dequeue:%x, %x\n\r",(ULONG)pTQNode,(ULONG)(pTQNode->pPacket)));
Status = SendSinglePacket(Adapter,pPacket);
if(Status == NDIS_STATUS_SUCCESS)
{
PushFreeTxQNode(Adapter->TxFreeQ,pTQNode);
}
else
{
InsertTxQNodeFromHead(pTxQKeeper,pTQNode);
Adapter->TxPacketCount++;
}
Status = NDIS_STATUS_PENDING;
}
else
{
pPacket = Packet;
Status = SendSinglePacket(Adapter,pPacket);
if(Status == NDIS_STATUS_SUCCESS)
{
Adapter->bSentPacketReturned = 1;
}
else
{
//RETAILMSG(1,(TEXT("[MrvSend] Send packet fail\r\n")));
TxPacketEnQueue(Adapter, Packet);
//Error handling , push back this node
//InsertTxQNodeFromHead(pTxQKeeper,pTQNode);
Adapter->TxPacketCount++;
Status = NDIS_STATUS_PENDING;
}
}
#if 1
if( Adapter->RetQTimerIsSet)
{
Adapter->RetQTimerIsSet = 0;
NdisMCancelTimer(&Adapter->MrvRetQTimer, &timerStatus);
BatchIndicateRetQPkts(Adapter);
}
#endif
LeaveCriticalSection(&Adapter->TxCriticalSection);
return Status;
}
//////////////////////////////////////////////////////////////
/******************************************************************************
*
* Name: SendSinglePacket()
*
* Description: TX packet handler
*
* Arguments: PMRVDRV_ADAPTER Adapter
*
* Return Value:
*
* Notes:
*
*****************************************************************************/
NDIS_STATUS
SendSinglePacket(
IN PMRVDRV_ADAPTER Adapter,
IN PNDIS_PACKET Packet
)
{
//int ii;
ULONG bigTimeout = 250000; // about 500ms drop dead timeout timing on BUS IO.
BOOLEAN timerStatus;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
UINT BufferCount;
UINT TotalPacketLength=0;
UINT TotalBufferLength=0;
UINT BytesCopied=0;
UINT Length, AccumLength;
PNDIS_BUFFER pBuffer, pNextBuffer;
ULONG i;
PVOID pVirtualAddr;
PTxCtrlNode pTxNode;
// due to fix for odd sized buffers, WepBuffer is used in both
// WEP and no-WEP scenarios
//UCHAR WepBuffer[MRVDRV_ETH_TX_PACKET_BUFFER_SIZE];
//BOOLEAN doWep = FALSE;
//BOOLEAN NotEncryption4EAPOL = FALSE;
UCHAR Buffer[MRVDRV_ETH_TX_PACKET_BUFFER_SIZE];
BOOLEAN bIsEtherPacket = TRUE;
PUCHAR pDest = Buffer;
PUCHAR pHeader = NULL;
BOOLEAN useBuffer = FALSE;
ULONG coBufferLength = 0;
//#ifdef SDIO
SD_API_STATUS sdstatus; // intermediate status
SDIO_TX_PKT downloadPkt;
UCHAR *pCurPtr = (UCHAR *)downloadPkt.Buf.CmdBuf;
//#endif // SDIO
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -