📄 interrupt.c
字号:
pCs8900_t pEthernet = ((pCs8900_t)(MiniportAdapterContext));
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aEnableInterrupt\r\n")));
if(pEthernet->CurrentState != NdisHardwareStatusReady)
{
return;
}
InterruptChip(pEthernet, TRUE);
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -Cs8900aEnableInterrupt\r\n")));
return;
}
//------------------------------------------------------------------------------
//
// Function: ProcessBufferInterrupts
//
// This function process interrupts from buffer-related events.
//
// Parameters:
// pEthernet
// [in] pointer to CS8900 structure.
//
// InterruptEvent
// [in] Interrupt value from the ISQ register.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void ProcessBufferInterrupts( pCs8900_t pEthernet, WORD InterruptEvent )
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +ProcessBufferInterrupts\r\n")));
// check for ready for transmit
if(InterruptEvent & BUF_EVENT_RDY4TX)
{
if(pEthernet->HeadPacket != NULL)
{
pEthernet->TransmitBidPending = FALSE;
pEthernet->StartTX = FALSE;
TransferPacketToChip(pEthernet);
}
}
// check for transmit underrun bit
if(InterruptEvent & BUF_EVENT_TX_UNDR)
{
if(pEthernet->HeadPacket != NULL)
{
pEthernet->XmitUnderrun++;
pEthernet->StartTX = TRUE;
}
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -ProcessBufferInterrupts\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: ProcessReceiveInterrupts
//
// This function process interrupts from receive-related events.
//
// Parameters:
// pEthernet
// [in] pointer to CS8900 structure.
//
// InterruptEvent
// [in] Interrupt value from the ISQ register.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void ProcessReceiveInterrupts( pCs8900_t pEthernet, WORD InterruptEvent )
{
WORD PacketSize, i, ReceivePtr;
PUCHAR pReceiveBuffer;
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +ProcessReceiveInterrupts\r\n")));
if ( InterruptEvent & RX_EVENT_RX_OK)
{
// receive packet
// Get packet size of the receive packet
PacketSize = ReadCs8900Register(PKTPG_RX_LENGTH);
PacketSize -= 4; // remove the CRC32 bytes
// Intialise the receive frame ptr in CS8900A to be auto increment and put in the
// PacketPage pointer
ReceivePtr = PKTPG_RX_FRAME|AUTO_INCREMENT_EN;
// Assign a pointer to the receive buffer
pReceiveBuffer = pEthernet->ReceiveBuffer;
pEthernet->ReceivePacketSize = PacketSize;
EnterCriticalSection (&gCS8900RegCs);
NdisRawWritePortUshort( (unsigned long)&(g_pCS8900Reg->CS8900_PAGE_POINTER), ReceivePtr );
for(i=0; i<(PacketSize/2); i++)
{
NdisRawReadPortUshort( (unsigned long)&(g_pCS8900Reg->CS8900_PAGE_DATA_0), ((PWORD)pReceiveBuffer)++);
}
if(PacketSize % 2)
{
NdisRawReadPortUshort( (unsigned long)&(g_pCS8900Reg->CS8900_PAGE_DATA_0), ((PWORD)pReceiveBuffer));
}
LeaveCriticalSection (&gCS8900RegCs);
pEthernet->FramesRcvGood++;
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;
}
else
{
pEthernet->RcvErrors++;
if (InterruptEvent & RX_EVENT_CRC_ERR)
{
pEthernet->RcvCRCErrors++;
}
if(InterruptEvent & RX_EVENT_DRIBBLE)
{
pEthernet->FrameAlignmentErrors++;
}
if (InterruptEvent & RX_EVENT_X_DATA)
{
pEthernet->RcvExtraDataErrors++;
}
if (InterruptEvent & RX_EVENT_RUNT)
{
pEthernet->RcvShortDataErrors++;
}
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -ProcessReceiveInterrupts\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: ProcessTransmitInterrupts
//
// This function process interrupts from transmit-related events.
//
// Parameters:
// pEthernet
// [in] pointer to CS8900 structure.
//
// InterruptEvent
// [in] Interrupt value from the ISQ register.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void ProcessTransmitInterrupts( pCs8900_t pEthernet, WORD InterruptEvent )
{
PNDIS_PACKET pNdisPacket;
WORD Collisions;
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +ProcessTransmitInterrupts\r\n")));
if (InterruptEvent & TX_EVENT_TX_OK) // Tx ok?
{
pEthernet->FramesXmitGood++;
//
// Remove the packet from the queue.
//
EnterCriticalSection (&gCS8900BufCs);
pNdisPacket = pEthernet->HeadPacket;
pEthernet->HeadPacket = RESERVED(pNdisPacket)->Next;
if (pNdisPacket == pEthernet->TailPacket)
{
pEthernet->TailPacket = NULL;
}
LeaveCriticalSection (&gCS8900BufCs);
NdisMSendComplete(pEthernet->ndisAdapterHandle, pNdisPacket, NDIS_STATUS_SUCCESS);
}
else
{
pEthernet->FramesXmitBad++;
if(InterruptEvent & TX_EVENT_JABBER)
{
// update member?
// currently do nothing
}
if(InterruptEvent & TX_EVENT_OUT_WIN)
{
// update member?
// currently do nothing
}
if(InterruptEvent & TX_EVENT_16_COLL)
{
// update member?
// currently do nothing
}
if(InterruptEvent & TX_EVENT_JABBER)
{
// update member?
// currently do nothing
}
}
// Process number of collisions
Collisions = (InterruptEvent & TX_EVENT_COLL_MASK) >> TX_EVENT_COLL_SHIFT;
if(Collisions == 1)
{
pEthernet->FramesXmitOneCollision++;
}
else
{
pEthernet->FramesXmitManyCollisions++;
}
//
// If there is a packet in the transmit queue then try
// transmitting it at the end of the ISR
//
if (pEthernet->HeadPacket != NULL )
{
pEthernet->StartTX = TRUE;
}
else
{
pEthernet->TransmitInProgress = FALSE;
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -ProcessTransmitInterrupts\r\n")));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -