📄 cmdproc.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/** @file cmdproc.c
* @This module provides implementaion of host command
* processing routines
*
* Copyright (c) Marvell Semiconductor, Inc.
*/
#include "precomp.h"
/******************************************************************************
*
* 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;
// return Status;
// initialize free queue
NdisAcquireSpinLock(&Adapter->FreeQSpinLock);
InitializeQKeeper(&Adapter->CmdFreeQ);
NdisReleaseSpinLock(&Adapter->FreeQSpinLock);
// initialize priority queue
NdisAcquireSpinLock(&Adapter->PriorityQSpinLock);
InitializeQKeeper(&Adapter->CmdPendQ);
NdisReleaseSpinLock(&Adapter->PriorityQSpinLock);
// 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);
//DBGPRINT(DBG_LOAD, ("CmdArray = 0x%x \n", Adapter->CmdArray));
//DBGPRINT(DBG_LOAD, ("CmdBufferArray = 0x%x \n", &(Adapter->CmdBufferArray[0][0])));
// Allocate shared memory buffers
for ( i=0; i<MRVDRV_NUM_OF_CMD_BUFFER; i++ )
{
TempCmdArray = (CmdCtrlNode *)(&(Adapter->CmdArray[i]));
//DBGPRINT(DBG_LOAD, ("CmdArray[%d] = 0x%x \n", i, TempCmdArray));
//DBGPRINT(DBG_NEWCMD,("TempCmdArray %d 0x%x ****\n",
// i, TempCmdArray));
//NdisAllocateMemoryWithTag(&pTempVirtualAddr, MRVDRV_SIZE_OF_CMD_BUFFER, 'LVRM');
//if ( !pTempVirtualAddr )
//{
// DBGPRINT(DBG_NEWCMD, ("return NDIS_STATUS_RESOURCES\n"));
// return NDIS_STATUS_RESOURCES;
//}
pTempVirtualAddr = &(Adapter->CmdBufferArray[i][0]);
//DBGPRINT(DBG_LOAD, ("CmdBufferArray[%d] = 0x%x \n", i, pTempVirtualAddr));
NdisZeroMemory(pTempVirtualAddr, MRVDRV_SIZE_OF_CMD_BUFFER);
//DBGPRINT(DBG_LOAD, ("CmdBufferArray- 1 \n"));
TempCmdArray->BufVirtualAddr = pTempVirtualAddr;
TempCmdArray->BufPhyAddr.LowPart = 0xffffffff;
TempCmdArray->BufPhyAddr.HighPart = 0xffffffff;
//DBGPRINT(DBG_LOAD, ("CmdBufferArray- 2 \n"));
// insert command to free queue
NdisAcquireSpinLock(&Adapter->FreeQSpinLock);
CleanUpCmdCtrlNode(TempCmdArray);
InsertQNodeAtTail(&Adapter->CmdFreeQ,(PQ_NODE) TempCmdArray);
NdisReleaseSpinLock(&Adapter->FreeQSpinLock);
//DBGPRINT(DBG_LOAD, ("CmdBufferArray- 3 \n"));
}
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;
// 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, ("Reset CMD Buffer\n"));
EnterCriticalSection(&Adapter->CmdQueueExeSection);
NdisAcquireSpinLock(&Adapter->FreeQSpinLock);
// 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);
for(i=0; i<MRVDRV_NUM_OF_CMD_BUFFER; i++)
{
TempCmdArray = (CmdCtrlNode*)(&(Adapter->CmdArray[i]));
if (Adapter->bIsFreeNow == FALSE)
{
// If this is a pending command, return failure
if ( TempCmdArray->PendingInfo == HostCmd_PENDING_ON_SET_OID )
{
NdisMSetInformationComplete(
Adapter->MrvDrvAdapterHdl,
NDIS_STATUS_SUCCESS);
}
else if ( TempCmdArray->PendingInfo == HostCmd_PENDING_ON_GET_OID )
{
NdisMQueryInformationComplete(
Adapter->MrvDrvAdapterHdl,
NDIS_STATUS_SUCCESS);
}
}
// 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;
if (Adapter->bIsFreeNow == FALSE)
{
// return pending OIDs
pPending = &(Adapter->PendingSetSssidOid);
if (pPending->bIsPendingOID)
{
pPending->bIsPendingOID = FALSE;
*(pPending->BytesReadWrite) = 0;
NdisMSetInformationComplete(
Adapter->MrvDrvAdapterHdl,
NDIS_STATUS_SUCCESS);
}
}
NdisReleaseSpinLock(&Adapter->FreeQSpinLock);
LeaveCriticalSection(&Adapter->CmdQueueExeSection);
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);
CleanUpCmdCtrlNode(TempNode);
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;
}
VOID
InsertCmdToQueue(
IN PMRVDRV_ADAPTER Adapter,
IN CmdCtrlNode *pTempCmd
)
{
USHORT Command;
USHORT PsSubCommand;
USHORT AddToQueue = 0xFFFF;
DBGPRINT(DBG_NEWCMD, ("InsertCmdToQueue() \n"));
//RETAILMSG(1, (TEXT("InsertCmdToQueue \r\n")));
if (!pTempCmd)
return;
EnterCriticalSection(&Adapter->CmdQueueExeSection);
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;
switch (Adapter->psState)
{
case PS_STATE_FULL_POWER:
if ((PsSubCommand == HostCmd_SubCmd_Enter_PS) ||
(PsSubCommand == 0))
AddToQueue = 0;
break;
case PS_STATE_WAKEUP:
case PS_STATE_SLEEP:
if (PsSubCommand == HostCmd_SubCmd_Exit_PS)
AddToQueue = 1;
else if (PsSubCommand == 0)
AddToQueue = 0;
break;
case PS_STATE_SLEEP_PENDING:
if ((PsSubCommand == HostCmd_SubCmd_Sleep_Confirmed) ||
(PsSubCommand == HostCmd_SubCmd_Exit_PS))
AddToQueue = 1;
else if (PsSubCommand == 0)
AddToQueue = 0;
break;
}
if (Command == HostCmd_CMD_802_11_HOST_SLEEP_AWAKE_CONFIRM)
{
AddToQueue = 1;
}
switch(AddToQueue)
{
case 0:
NdisAcquireSpinLock(&Adapter->PriorityQSpinLock);
InsertQNodeAtTail(&(Adapter->CmdPendQ),(PQ_NODE)pTempCmd);
NdisReleaseSpinLock(&Adapter->PriorityQSpinLock);
break;
case 1:
NdisAcquireSpinLock(&Adapter->PriorityQSpinLock);
InsertQNodeFromHead(&(Adapter->CmdPendQ),(PQ_NODE)pTempCmd);
NdisReleaseSpinLock(&Adapter->PriorityQSpinLock);
break;
default:
ReturnCmdNode(Adapter, pTempCmd);
break;
}
LeaveCriticalSection(&Adapter->CmdQueueExeSection);
return;
}
VOID
GetCmdFromQueueToExecute(
IN PMRVDRV_ADAPTER Adapter
)
{
CmdCtrlNode *pTempNode=NULL;
CmdCtrlNode *pPsEnterCmd;
CmdCtrlNode *pPsExitCmd;
NDIS_STATUS status;
USHORT Command;
USHORT PsSubCommand;
USHORT IsDownloadCmdToFW;
DBGPRINT(DBG_NEWCMD, ("GetCmdFromQueueToExecute() \n"));
//RETAILMSG(1, (TEXT("GetCmdFromQueueToExecute \r\n")));
if (Adapter->CurCmd)
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -