📄 txproc.c
字号:
ixStatus = cf_TxStartPacket( pCf, (USHORT)AccumLength);
if ( !IX_SUCCESS(ixStatus) )
{
DBGPRINT(DBG_ERROR | DBG_MACEVENT ,("Frame not accepted: interface still busy after waiting"));
Status = NDIS_STATUS_FAILURE;
goto end;
}
/// AllenDBGPRINT(DBG_TXDATA, ("-really send a packet\n"));
cf_TxBlock( pCf,(PUCHAR)(&(Packet->Wcb)), sizeof(WCB));
cf_TxBlock ( pCf, (PUCHAR)(Packet->PktBuf), Packet->PktLen);
// finish up the packet
cf_TxUpdateSeq( pCf, Adapter->SeqNum);
cf_TxEndPacket(pCf);
// remember the current packet being sent
Adapter->TxRetryCount = 0;
Adapter->ulTxByteInLastPeriod += Packet->PktLen;
// Start Tx timer
NdisMSetTimer(&Adapter->MrvDrvTxPktTimer,
MRVDRV_DEFAULT_TX_PKT_TIME_OUT);
Adapter->TxPktTimerIsSet=TRUE;
// Update sequence number
Adapter->SeqNum++;
Adapter->SentPacket = Packet;
end:
NdisReleaseSpinLock(&Adapter->lCFInterfaceLock);
return Status;
}
/******************************************************************************
*
* Name: FreeSingleTxBuffer()
*
* Description: Free single Tx Bbuffer
*
* Arguments: PMRVDRV_ADAPTER Adapter
*
* Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE
*
* Notes:
* TODO: Verify what should be in here.
*****************************************************************************/
/*
NDIS_STATUS FreeSingleTxBuffer(
IN PMRVDRV_ADAPTER Adapter
)
{
// if( Adapter->TxNode.BufVirtualAddr ){
// NdisMFreeSharedMemory(Adapter->MrvDrvAdapterHdl,
// MRVDRV_ETH_PACKET_BUFFER_SIZE,
// TRUE,
// (PVOID)Adapter->TxNode.BufVirtualAddr,
// Adapter->TxNode.BufPhyAddr
// );
// }
return NDIS_STATUS_SUCCESS;
}
*/
/******************************************************************************
*
* Name: HandleTxSingleDoneEvent()
*
* Description: TX done event handler
*
* Arguments: PMRVDRV_ADAPTER Adapter
*
* Return Value:
*
* Notes:
*
*****************************************************************************/
NDIS_STATUS
HandleTxSingleDoneEvent(
PMRVDRV_ADAPTER Adapter
)
{
PTX_PKT_T pPacket;
NDIS_STATUS Status;
USHORT usTxFrmSeqNum = 0, usTxFrmStatus = 0, usTCNSeqNum = 0;
USHORT usTxCurrentRate = 0;
TxCtrlNode *pTCN;
BOOLEAN timerStatus;
DBGSTROBE_LINE_OFF(DBLINE2);
DBGPRINT(DBG_TXDATA | DBG_CRLF ,("+HandleTxSingleDoneEvent()\n"));
if ( Adapter->TxPktTimerIsSet==TRUE )
{
NdisMCancelTimer(&Adapter->MrvDrvTxPktTimer, &timerStatus);
Adapter->TxPktTimerIsSet=FALSE;
}
if ( Adapter->SentPacket == NULL )
{
DBGPRINT(DBG_TXDATA | DBG_WARNING,
("TXDone event received eventhough there is no outstanding TX pkt!\n"));
Adapter->bIsDoingTx = FALSE;
return NDIS_STATUS_FAILURE;
}
// Check Tx frame seq num and Tx frame status
NdisRawReadPortUshort(
Adapter->ulMrvDrvVirtualIoBase + CFMACREG_CCR_TX_FRAME_SEQ_NUM,
&usTxFrmSeqNum);
// If Tx frame sequence number is out of sync, ignore it
NdisRawReadPortUshort(
Adapter->ulMrvDrvVirtualIoBase + CFMACREG_CCR_TX_FRAME_STATUS,
&usTxFrmStatus);
DBGPRINT(DBG_DATARATE,("TX Status = 0x%x", usTxFrmStatus));
usTxCurrentRate = usTxFrmStatus >> 4;
usTxFrmStatus &= CFMACREG_CCR_TFS_MASK; // mask unwanted bits.
DBGPRINT(DBG_DATARATE,("Rate value reported by FW %d\n", (ULONG)usTxCurrentRate ));
// Locate the packet
pTCN = &(Adapter->TxNode);
// Clear the data structure
pTCN->Status = MRVDRV_TX_CTRL_NODE_STATUS_IDLE;
pTCN->NPTxPacket = NULL;
pTCN->LocalWCB->PktPtr = (ULONG)0;
Status = NDIS_STATUS_FAILURE;
// Check and update statistics
if ( usTxFrmStatus & CFMACREG_CCR_TFS_TxFrmSent )
{
DBGPRINT(DBG_TXDATA,("HandleTxSingleDoneEvent() - TX frame (0x%x) marked GOOD\n",
Adapter->SentPacket));
Adapter->XmitOK++;
Status = NDIS_STATUS_SUCCESS;
}
else if ( usTxFrmStatus & CFMACREG_CCR_TFS_RtyLmtExcd )
{
DBGPRINT(DBG_TXDATA | DBG_WARNING, ("HandleTxSingleDoneEvent() - TX frame (0x%x) marked BAD\n",
Adapter->SentPacket));
Adapter->XmitError++;
Status = NDIS_STATUS_FAILURE;
}
else if ( usTxFrmStatus & CFMACREG_CCR_TFS_TimeOut )
{
DBGPRINT(DBG_TXDATA | DBG_WARNING,("HandleTxSingleDoneEvent() - TX frame (0x%x) marked TIMEOUT\n",
Adapter->SentPacket));
Adapter->XmitError++;
Status = NDIS_STATUS_FAILURE;
}
else
{
DBGPRINT(DBG_TXDATA | DBG_WARNING,("HandleTxSingleDoneEvent() - TX frame (0x%x) marked no\n",
Adapter->SentPacket));
Adapter->XmitError++;
Status = NDIS_STATUS_FAILURE;
}
EnterCriticalSection(&Adapter->TxCriticalSection);
if ( Adapter->SentPacket != NULL )
{
Adapter->SendPackets[Adapter->TxPacketComplete].PktLen = 0;
Adapter->TxPacketComplete++;
Adapter->TxPacketCount--;
Adapter->TxPacketComplete %= MAX_TX_PACKETS;
Adapter->SentPacket = NULL;
Adapter->TxPacketSendComplete++;
if ( Adapter->TxPacketCount && Adapter->psState != PS_STATE_SLEEP )
{
pPacket = &(Adapter->SendPackets[Adapter->TxPacketGet]);
if (pPacket != NULL)
{
Status = SendSinglePacket(Adapter,pPacket);
if (Status == NDIS_STATUS_SUCCESS)
{
Adapter->TxPacketGet++;
Adapter->TxPacketGet %= MAX_TX_PACKETS;
}
else
{
DBGPRINT(DBG_DRALEE,("Handle Tx single Done error\n\r"));
}
}
}
}
LeaveCriticalSection(&Adapter->TxCriticalSection);
Adapter->bIsDoingTx = FALSE;
return NDIS_STATUS_SUCCESS;
}
/******************************************************************************
*
* Name: AllocateSingleTx()
*
* Description: Allocate single Tx
*
* Arguments: PMRVDRV_ADAPTER Adapter
*
* Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE
*
* Notes:
*
*****************************************************************************/
NDIS_STATUS AllocateSingleTx(
IN PMRVDRV_ADAPTER Adapter
)
{
ULONG i;
Adapter->TxNode.BufVirtualAddr = NULL;
Adapter->TxNode.BufPhyAddr.LowPart = 0xffffffff;
Adapter->TxNode.BufPhyAddr.HighPart = 0xffffffff;
Adapter->TxNode.LocalWCB = &Adapter->Wcb;
Adapter->TxNode.Status = MRVDRV_TX_CTRL_NODE_STATUS_IDLE;
Adapter->Wcb.PktPtr = 0xffffffff;
for (i =0; i<MAX_TX_PACKETS; i++)
{
Adapter->SendPackets[i].PktLen= 0;
}
Adapter->TxPacketCount = 0;
Adapter->TxPacketPut = 0;
Adapter->TxPacketGet = 0;
Adapter->TxPacketComplete = 0;
Adapter->TxPacketSend = 0;
Adapter->TxPacketSendComplete = 0;
return NDIS_STATUS_SUCCESS;
}
VOID FreeSingleTx(
IN PMRVDRV_ADAPTER Adapter
)
{
CleanUpSingleTxBuffer(Adapter);
return;
}
/******************************************************************************
*
* Name: CleanUpSingleTxBuffer()
*
* Description: Clean up single Tx Bbuffer
*
* Arguments: PMRVDRV_ADAPTER Adapter
*
* Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE
*
* Notes:
*
*****************************************************************************/
NDIS_STATUS
CleanUpSingleTxBuffer(
IN PMRVDRV_ADAPTER Adapter
)
{
BOOLEAN timerStatus;
ULONG i;
//RETAILMSG(1, (TEXT("CleanUpSingleTxBuffer TxPacketCount= 0x%x>>> "), Adapter->TxPacketCount));
EnterCriticalSection(&Adapter->TxCriticalSection);
if (Adapter->bIsFreeNow == FALSE)
{
for (i = 0; i< MAX_TX_PACKETS; i++)
{
Adapter->SendPackets[i].PktLen = 0;
}
}
Adapter->TxPacketCount = 0;
Adapter->TxPacketPut = 0;
Adapter->TxPacketGet = 0;
Adapter->TxPacketComplete = 0;
Adapter->TxPacketSend = 0;
Adapter->TxPacketSendComplete = 0;
if (Adapter->TxPktTimerIsSet==TRUE)
{
NdisMCancelTimer(&Adapter->MrvDrvTxPktTimer, &timerStatus);
Adapter->TxPktTimerIsSet=FALSE;
}
Adapter->SentPacket = NULL;
LeaveCriticalSection(&Adapter->TxCriticalSection);
return NDIS_STATUS_SUCCESS;
}
/******************************************************************************
*
* Name: MrvDrvCancelSendPacket()
*
* Description: Miniport Tx pakcet cancellation routine
*
* Conditions for Use:
*
* Arguments:
* IN NDIS_HANDLE MiniportAdapterContext,
* IN PVOID GroupCancelId
*
* Return Value: None
*
* Notes:
*
*****************************************************************************/
#ifdef MRVL_WINXP_NDIS51
VOID
MrvDrvCancelSendPackets(
IN NDIS_HANDLE MiniportAdapterContext,
IN PVOID GroupCancelId
)
{
return;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -