📄 interrupt.c
字号:
// which the driver maintains FEC adapter state, set up by
// FECInitialize
//
// Return Value:
// None
//------------------------------------------------------------------------------
void ProcessReceiveInterrupts(
IN pFEC_t pEthernet)
{
volatile PBUFFER_DESC BufferDescPointer;
USHORT PacketSize;
PUCHAR pReceiveBuffer, pData;
PFEC_ENET_PRIVATE pFEC = &(pEthernet->FECPrivateInfo);
DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +ProcessReceiveInterrupts\r\n")));
BufferDescPointer = pFEC->CurrentRx;
DEBUGMSG(1, (TEXT("The value of ControlStatus is = %Xh\r\n"), BufferDescPointer->ControlStatus));
while(!(BufferDescPointer->ControlStatus & BD_ENET_RX_EMPTY))
{
// Since we have allocated space to hold a complete
// frame, the last indicator should be set
if((BufferDescPointer->ControlStatus & BD_ENET_RX_LAST) == 0)
DEBUGMSG(ZONE_INFO, (TEXT("RCV is not the last\r\n")));
// Check for errors
if(BufferDescPointer->ControlStatus & (BD_ENET_RX_LG | BD_ENET_RX_SH |
BD_ENET_RX_NO | BD_ENET_RX_CR |
BD_ENET_RX_OV | BD_ENET_RX_CL ))
{
pEthernet->RcvStatus.FrameRcvErrors++;
if(BufferDescPointer->ControlStatus & BD_ENET_RX_LG) // too long frame
pEthernet->RcvStatus.FrameRcvExtraDataErrors++;
if(BufferDescPointer->ControlStatus & BD_ENET_RX_SH) // too short frame
pEthernet->RcvStatus.FrameRcvShortDataErrors++;
if(BufferDescPointer->ControlStatus & BD_ENET_RX_NO) // no-octet aligned frame
pEthernet->RcvStatus.FrameRcvAllignmentErrors++;
if(BufferDescPointer->ControlStatus & BD_ENET_RX_CR) // CRC error
pEthernet->RcvStatus.FrameRcvCRCErrors++;
if(BufferDescPointer->ControlStatus & BD_ENET_RX_OV) // receive FIFO overrun
pEthernet->RcvStatus.FrameRcvOverrunErrors;
if(BufferDescPointer->ControlStatus & BD_ENET_RX_CL) // late collisions error
pEthernet->RcvStatus.FrameRcvLCErrors++;
}
else
{
// Process the successfully received frame
pEthernet->RcvStatus.FrameRcvGood++;
// Get frame size of the received frame
PacketSize = BufferDescPointer->DataLen;
PacketSize -= 4;
// Assign a pointer to the receive buffer
pReceiveBuffer = pEthernet->ReceiveBuffer;
pEthernet->ReceivePacketSize = PacketSize;
pData = pFEC->RxBuffAddr[BufferDescPointer - pFEC->RxBufferDescBase];
memcpy(pReceiveBuffer, pData, PacketSize);
NdisMEthIndicateReceive( pEthernet->ndisAdapterHandle,
(NDIS_HANDLE)pEthernet,
pEthernet->ReceiveBuffer,
ETHER_HDR_SIZE,
pEthernet->ReceiveBuffer +ETHER_HDR_SIZE,
PacketSize-ETHER_HDR_SIZE,
PacketSize-ETHER_HDR_SIZE
);
pEthernet->ReceiveCompleteNotifyFlag = TRUE;
}
// Clear the status flags for this BD
BufferDescPointer->ControlStatus &= ~BD_ENET_RX_STATS;
// Mark the buffer as empty
BufferDescPointer->ControlStatus |= BD_ENET_RX_EMPTY;
// Update BD pointer to next entry
if(BufferDescPointer->ControlStatus & BD_ENET_RX_WRAP)
BufferDescPointer = pFEC->RxBufferDescBase;
else
BufferDescPointer++;
INSREG32BF(&gpFECReg->RDAR, FEC_RDAR_ACTIVE, FEC_RDAR_ACTIVE_ACTIVE);
}
pFEC->CurrentRx = (PBUFFER_DESC)BufferDescPointer;
DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -ProcessReceiveInterrupts\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: ProcessTransmitInterrupts
//
// This function is the interrupt handler when a ethernet packet had been
// transmitted by the FEC hardware.
//
// Parameters:
// pEthernet
// [in] Specifies the pointer to the driver allocated context area in
// which the driver maintains FEC adapter state, set up by
// FECInitialize.
//
// Return Value:
// None.
//
//------------------------------------------------------------------------------
void ProcessTransmitInterrupts(
IN pFEC_t pEthernet)
{
volatile PBUFFER_DESC BufferDescPointer;
PNDIS_PACKET pNdisPacket;
PFEC_ENET_PRIVATE pFEC = &(pEthernet->FECPrivateInfo);
DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +ProcessTransmitInterrupts\r\n")));
BufferDescPointer = pFEC->DirtyTx;
DEBUGMSG(1, (TEXT("The value of ControlStatus is = %Xh\r\n"), BufferDescPointer->ControlStatus));
while((BufferDescPointer->ControlStatus & BD_ENET_TX_READY) == 0)
{
if((BufferDescPointer == pFEC->CurrentTx) && (pFEC->TxFull == FALSE) )
break;
if(BufferDescPointer->ControlStatus & (BD_ENET_TX_HB | BD_ENET_TX_LC |
BD_ENET_TX_RL | BD_ENET_TX_UN |
BD_ENET_TX_CSL))
{
pEthernet->TxdStatus.FramesXmitBad++;
if(BufferDescPointer->ControlStatus & BD_ENET_TX_HB) // No heartbeat
pEthernet->TxdStatus.FramesXmitHBErrors++;
if(BufferDescPointer->ControlStatus & BD_ENET_TX_LC) // Late collision
pEthernet->TxdStatus.FramesXmitCollisionErrors++;
if(BufferDescPointer->ControlStatus & BD_ENET_TX_RL) // Retrans limit
pEthernet->TxdStatus.FramesXmitAbortedErrors++;
if(BufferDescPointer->ControlStatus & BD_ENET_TX_UN) // Underrun
pEthernet->TxdStatus.FramesXmitUnderrunErrors++;
if(BufferDescPointer->ControlStatus & BD_ENET_TX_CSL) // Carrier lost
pEthernet->TxdStatus.FramsXmitCarrierErrors++;
}
else
{
pEthernet->TxdStatus.FramesXmitGood++;
// Remove the successfully transmitted packet from the
// packet queue
EnterCriticalSection (&gFECBufCs);
pNdisPacket = pEthernet->HeadPacket;
pEthernet->HeadPacket = RESERVED(pNdisPacket)->Next;
if (pNdisPacket == pEthernet->TailPacket)
{
pEthernet->TailPacket = NULL;
}
LeaveCriticalSection (&gFECBufCs);
NdisMSendComplete(pEthernet->ndisAdapterHandle, pNdisPacket, NDIS_STATUS_SUCCESS);
}
// Update pointer to next buffer descriptor to be transmitted
if(BufferDescPointer->ControlStatus & BD_ENET_TX_WRAP)
BufferDescPointer = pFEC->TxBufferDescBase;
else
BufferDescPointer++;
// Since we have freed up a buffer, the ring is no longer full
if(pFEC->TxFull == TRUE)
{
pFEC->TxFull = FALSE;
// NdisMSendComplete(pEthernet->ndisAdapterHandle, pNdisPacket, NDIS_STATUS_SUCCESS);
}
}
pFEC->DirtyTx = BufferDescPointer;
if (pEthernet->HeadPacket != NULL )
{
pEthernet->StartTx = TRUE;
}
else
{
pEthernet->TransmitInProgress = FALSE;
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -ProcessTransmitInterrupts\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: ProcessMIIInterrupts
//
// This function is the interrupt handler for the MII interrupt
//
// Parameters:
// pEthernet
// [in] Specifies the pointer to the driver allocated context area in
// which the driver maintains FEC adapter state, set up by
// FECInitialize
//
// Return Value:
// None
//
//------------------------------------------------------------------------------
void ProcessMIIInterrupts(IN pFEC_t pEthernet)
{
PFEC_MII_LIST MIIPoint;
UINT MIIReg;
DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +ProcessMIIInterrupts\r\n")));
// Get the MII frame value from MMFR register
MIIReg = INREG32( &gpFECReg->MMFR );
if( (MIIPoint = gMIIHead) == NULL )
{
DEBUGMSG(ZONE_INFO,
(TEXT("%s: MII head is null\r\n"), __WFUNCTION__));
return;
}
if( MIIPoint->MIIFunction != NULL )
(*(MIIPoint->MIIFunction))(MIIReg, (NDIS_HANDLE)pEthernet);
gMIIHead = MIIPoint->MIINext;
MIIPoint->MIINext = gMIIFree;
gMIIFree = MIIPoint;
// Send the next MMI management frame to the external
// PHY if any
if( (MIIPoint = gMIIHead) != NULL )
OUTREG32( &gpFECReg->MMFR, MIIPoint->MIIRegVal );
DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -ProcessMIIInterrupts\r\n")));
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -