📄 cmdproc.c
字号:
/******************* ?Marvell Semiconductor, Inc., 2001-2004 *****************
*
*
* Purpose: This module provides implementaion of host command
* processing routines
*
* $Author: schiu $
*
* $Date: 2004/11/11 $
*
* $Revision: #8 $
*
*****************************************************************************/
/*
===============================================================================
INCLUDE FILES
===============================================================================
*/
#include "precomp.h"
#include "If.h"
NDIS_STATUS
DownloadCommand(
IN PMRVDRV_ADAPTER Adapter,
IN CmdCtrlNode *pTempNode
);
/******************************************************************************
*
* Name: AllocateCmdBuffer()
*
* Description: Allocate command buffer
*
* Arguments: PMRVDRV_ADAPTER Adapter
*
* Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_RESOURCES
*
* Notes:
*
*****************************************************************************/
NDIS_STATUS AllocateCmdBuffer(
IN PMRVDRV_ADAPTER Adapter
)
{
NDIS_STATUS Status;
ULONG ulBufSize;
CmdCtrlNode *TempCmdArray;
PUCHAR pTempVirtualAddr;
UINT i;
Status = NDIS_STATUS_SUCCESS;
// initialize free queue
NdisAcquireSpinLock(&Adapter->FreeQSpinLock);
InitializeQKeeper(&Adapter->CmdFreeQ);
NdisReleaseSpinLock(&Adapter->FreeQSpinLock);
// initialize priority queue
InitializeQKeeper(&Adapter->CmdPendQ); // plus All pending Command
// allocate the command array space
ulBufSize = sizeof(CmdCtrlNode) * MRVDRV_NUM_OF_CMD_BUFFER;
Status = MRVDRV_ALLOC_MEM((PVOID *)(&(Adapter->CmdArray)), ulBufSize);
if( Status != NDIS_STATUS_SUCCESS )
return Status;
NdisZeroMemory(Adapter->CmdArray, ulBufSize);
// Allocate shared memory buffers
for ( i=0; i<MRVDRV_NUM_OF_CMD_BUFFER; i++ )
{
TempCmdArray = ((CmdCtrlNode *)(Adapter->CmdArray) + i);
DBGPRINT(DBG_NEWCMD,("TempCmdArray %d 0x%x ****\n",
i, TempCmdArray));
NdisAllocateMemoryWithTag(&pTempVirtualAddr, MRVDRV_SIZE_OF_CMD_BUFFER, 'LVRM');
if ( !pTempVirtualAddr )
return NDIS_STATUS_RESOURCES;
NdisZeroMemory(pTempVirtualAddr, MRVDRV_SIZE_OF_CMD_BUFFER);
TempCmdArray->BufVirtualAddr = pTempVirtualAddr;
TempCmdArray->BufPhyAddr.LowPart = 0xffffffff;
TempCmdArray->BufPhyAddr.HighPart = 0xffffffff;
// insert command to free queue
NdisAcquireSpinLock(&Adapter->FreeQSpinLock);
CleanUpCmdCtrlNode(TempCmdArray);
InsertQNodeAtTail(&Adapter->CmdFreeQ,(PQ_NODE) TempCmdArray);
NdisReleaseSpinLock(&Adapter->FreeQSpinLock);
}
return Status;
}
/******************************************************************************
*
* Name: FreeCmdBuffer()
*
* Description: Free command buffer
*
* Arguments: PMRVDRV_ADAPTER Adapter
*
* Return Value: NDIS_STATUS_SUCCESS
*
* Notes:
*
*****************************************************************************/
NDIS_STATUS FreeCmdBuffer(
IN PMRVDRV_ADAPTER Adapter
)
{
CmdCtrlNode *TempCmdArray;
ULONG ulBufSize;
UINT i;
// Need to check if cmd array is allocated or not
if ( Adapter->CmdArray == NULL )
return NDIS_STATUS_SUCCESS;
//RETAILMSG(1,(TEXT("Free Cmd Buf \r\n")));
// Release shared memory buffers
for(i=0; i<MRVDRV_NUM_OF_CMD_BUFFER; i++)
{
TempCmdArray = ((CmdCtrlNode*)(Adapter->CmdArray) + i);
if ( TempCmdArray->BufVirtualAddr )
NdisFreeMemory ((PVOID)TempCmdArray->BufVirtualAddr,
MRVDRV_SIZE_OF_CMD_BUFFER,
0);
}
// Release CmdCtrlNode
if ( Adapter->CmdArray )
{
ulBufSize = sizeof(CmdCtrlNode) * MRVDRV_NUM_OF_CMD_BUFFER;
NdisFreeMemory((PVOID *)Adapter->CmdArray, ulBufSize, 0);
}
return NDIS_STATUS_SUCCESS;
}
/******************************************************************************
*
* Name: ResetCmdBuffer()
*
* Description: Reset command buffers
*
* Arguments: PMRVDRV_ADAPTER Adapter
*
* Return Value: NDIS_STATUS_SUCCESS
*
* Notes:
*
*****************************************************************************/
NDIS_STATUS ResetCmdBuffer(
IN PMRVDRV_ADAPTER Adapter
)
{
CmdCtrlNode *TempCmdArray;
UINT i;
BOOLEAN timerStatus;
PPENDING_OID pPending;
DBGPRINT(DBG_CMDRESP, ("ResetCmdBuffer\n"));
// Cancel command timer
if (Adapter->CommandTimerSet)
{
NdisMCancelTimer(&Adapter->MrvDrvCommandTimer, &timerStatus);
Adapter->CommandTimerSet = FALSE;
Adapter->isCommandTimerExpired = FALSE;
}
// Reset CmdFreeQ and CmdPendingQ
InitializeQKeeper(&Adapter->CmdFreeQ);
InitializeQKeeper(&Adapter->CmdPendQ); // plus
for(i=0; i<MRVDRV_NUM_OF_CMD_BUFFER; i++)
{
TempCmdArray = ((CmdCtrlNode*)(Adapter->CmdArray) + i);
#if 0 // marked at 36.p4
// If this is a pending command, return failure
if ( TempCmdArray->PendingInfo == HostCmd_PENDING_ON_SET_OID )
{
NdisMSetInformationComplete(
Adapter->MrvDrvAdapterHdl,
NDIS_STATUS_FAILURE);
DBGPRINT(DBG_CMDRESP, ("call NdisMSetInformationComplete\n"));
}
if ( TempCmdArray->PendingInfo == HostCmd_PENDING_ON_GET_OID )
{
NdisMQueryInformationComplete(
Adapter->MrvDrvAdapterHdl,
NDIS_STATUS_FAILURE);
DBGPRINT(DBG_CMDRESP, ("call NdisMGetInformationComplete\n"));
}
#endif // marked at 36.p4
// Clean up node content
TempCmdArray->Next = NULL;
CleanUpCmdCtrlNode(TempCmdArray);
// Append node to the end of CmdFreeQ
InsertQNodeAtTail(&Adapter->CmdFreeQ, (PQ_NODE)(TempCmdArray));
}
Adapter->CurCmd = NULL;
Adapter->SeqNum = 0;
// return pending OIDs
pPending = &(Adapter->PendingSetSssidOid);
if (pPending->bIsPendingOID)
{
pPending->bIsPendingOID = FALSE;
///crlo:cetk-ltk_D0D3_dataabort ++
///Problem: CETK one-card failed in D0->D3 (data abort) if we complete this
/// Because will not not pending this ESSID, it's not needed to complete
/*
RETAILMSG(1,(L"completing PendingSetSssidOid\n\r"));
NdisMSetInformationComplete(
Adapter->MrvDrvAdapterHdl,
NDIS_STATUS_SUCCESS);
*/
///crlo:cetk-ltk_D0D3_dataabort --
}
pPending = &(Adapter->PendingGetBssidOid);
if (pPending->bIsPendingOID)
{
pPending->bIsPendingOID = FALSE;
RETAILMSG(1,(L"DRV_WARNING: This fragment should not be touch....\n\r"));
NdisMSetInformationComplete(
Adapter->MrvDrvAdapterHdl,
NDIS_STATUS_SUCCESS);
}
return NDIS_STATUS_SUCCESS;
}
/******************************************************************************
*
* Name: GetFreeCmdCtrlNode()
*
* Description: to get next available CmdCtrlNode
*
* Arguments: PMRVDRV_ADAPTER Adapter,
* ULONG CurrentPacketFilter
*
* Return Value:
*
* Notes:
*
*****************************************************************************/
CmdCtrlNode *
GetFreeCmdCtrlNode(
IN PMRVDRV_ADAPTER Adapter
)
{
CmdCtrlNode *TempNode;
if ( !Adapter )
return NULL;
NdisAcquireSpinLock(&Adapter->FreeQSpinLock);
TempNode = (CmdCtrlNode *)PopFirstQNode(&Adapter->CmdFreeQ);
CleanUpCmdCtrlNode(TempNode);
NdisReleaseSpinLock(&Adapter->FreeQSpinLock);
return TempNode;
}
VOID
ReturnCmdNode(
IN PMRVDRV_ADAPTER Adapter,
CmdCtrlNode *TempNode
)
{
if ( !TempNode )
return;
NdisAcquireSpinLock(&Adapter->FreeQSpinLock);
InsertQNodeAtTail(&Adapter->CmdFreeQ, (PQ_NODE)TempNode);
NdisReleaseSpinLock(&Adapter->FreeQSpinLock);
return;
}
/******************************************************************************
*
* Name: SetCmdCtrlNode()
*
* Description: to set up CmdCtrlNode
*
* Arguments: CmdCtrlNode *pTempNode
* NDIS_OID PendingOID
* USHORT PendingInfo
* USHORT INTOption
* USHORT BatchQNum
* BOOLEAN IsLastBatchCmd
* PULONG BytesWritten
* PULONG BytesRead
* PULONG BytesNeeded
* PVOID InformationBuffer
*
* Return Value:
*
* Notes:
*
*****************************************************************************/
VOID SetCmdCtrlNode(
IN PMRVDRV_ADAPTER Adapter,
IN CmdCtrlNode *pTempNode,
IN NDIS_OID PendingOID,
IN USHORT PendingInfo,
IN USHORT INTOption,
IN USHORT BatchQNum,
IN BOOLEAN IsLastBatchCmd,
IN PULONG BytesWritten,
IN PULONG BytesRead,
IN PULONG BytesNeeded,
IN PVOID InformationBuffer
)
{
if( !pTempNode )
return;
pTempNode->PendingOID = PendingOID;
pTempNode->PendingInfo = PendingInfo;
pTempNode->INTOption = INTOption;
pTempNode->BatchQNum = BatchQNum;
pTempNode->IsLastBatchCmd = IsLastBatchCmd;
pTempNode->BytesWritten = BytesWritten;
pTempNode->BytesRead = BytesRead;
pTempNode->BytesNeeded = BytesNeeded;
pTempNode->InformationBuffer = InformationBuffer;
return;
}
/******************************************************************************
*
* Name: GetExpectedRetCode()
*
* Description:
*
* Arguments:
*
* Return Value:
*
* Notes:
*
*****************************************************************************/
USHORT
GetExpectedRetCode(USHORT Cmd)
{
USHORT RetCode;
if (Cmd==HostCmd_CMD_802_11_ASSOCIATE_EXT)
RetCode = HostCmd_RET_802_11_ASSOCIATE;
else
RetCode = (Cmd | 0x8000);
return RetCode;
}
/******************************************************************************
*
* Name: CleanUpCmdCtrlNode()
*
* Description: to clean up CmdCtrlNode
*
* Arguments: CmdCtrlNode *pTempNode
*
* Return Value:
*
* Notes:
*
*****************************************************************************/
VOID CleanUpCmdCtrlNode(
IN CmdCtrlNode *pTempNode
)
{
if( !pTempNode )
return;
pTempNode->Status = HostCmd_STATE_IDLE;
pTempNode->PendingOID = (NDIS_OID)0;
pTempNode->ExpectedRetCode = HostCmd_CMD_NONE;
pTempNode->PendingInfo = HostCmd_PENDING_ON_NONE;
pTempNode->INTOption = HostCmd_OPTION_USE_INT; // Default
pTempNode->BatchQNum = 0;
pTempNode->IsLastBatchCmd = FALSE;
pTempNode->BytesWritten = NULL;
pTempNode->BytesRead = NULL;
pTempNode->BytesNeeded = NULL;
pTempNode->InformationBuffer = NULL;
pTempNode->Pad[0] = 0;
pTempNode->Pad[1] = 0;
pTempNode->Pad[2] = 0;
pTempNode->PadExt[0] = 0;
pTempNode->PadExt[0] = 0;
pTempNode->PadExt[0] = 0;
pTempNode->PadExt[0] = 0;
if( pTempNode->BufVirtualAddr != NULL )
NdisZeroMemory(pTempNode->BufVirtualAddr, MRVDRV_SIZE_OF_CMD_BUFFER);
return;
}
// plus ++
VOID
InsertCmdToQueue(
IN PMRVDRV_ADAPTER Adapter,
IN CmdCtrlNode *pTempCmd
)
{
USHORT Command;
USHORT PsSubCommand;
USHORT AddToQueue = 0xFFFF;
if (!pTempCmd)
return;
Command = ((PHostCmd_DS_GEN)(pTempCmd->BufVirtualAddr))->Command;
if ((Command == HostCmd_CMD_802_11_PS_MODE))
PsSubCommand = ((PHostCmd_DS_802_11_PS_MODE)pTempCmd->BufVirtualAddr)->SubCommand;
else
PsSubCommand = 0;
// if(PsSubCommand != HostCmd_SubCmd_Sleep_Confirmed)
// DraleeMsg((L"InsertCmdToQueue: Cmd %x PsSubCmd %x PSSTATE %x \n", Command, PsSubCommand, Adapter->psState));
switch(Adapter->psState)
{
case PS_STATE_FULL_POWER:
if((PsSubCommand == HostCmd_SubCmd_Enter_PS) ||
(PsSubCommand == 0))
AddToQueue = 0;
break;
case PS_STATE_WAKEUP:
if(PsSubCommand == HostCmd_SubCmd_Exit_PS)
AddToQueue = 1;
else if (PsSubCommand == 0)
AddToQueue = 0;
break;
case PS_STATE_SLEEP: //dralee_20051128
if (PsSubCommand == HostCmd_SubCmd_Sleep_Confirmed|| PsSubCommand == HostCmd_SubCmd_Exit_PS)
AddToQueue = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -