📄 lan91c96_intr.c
字号:
/*
*
*
* LAN91C96 Driver for Windows CE .NET
*
* Description:
* Interrupt Service routines and other required functions for
* processing the interrupts.
*
*
*/
#include <Ndis.h>
#include "LAN91C96_Adapter.h"
#include "LAN91C96_Proto.h"
#include "platform.h"
#define ZQ 0
BOOLEAN CheckMultiCastAddress(UCHAR *ReadBuffer, MINIPORT_ADAPTER *Adapter);
/*
Function Name : LAN91C96_MiniportISR
Description :
This routine is invoked when an interrupt occurs. If the
interrupting device is identified as ours, then the DPC
is scheduled to complete the processing.
If the interrupt is shared, then check for the LAN91C96 interrupt,
else return TRUE always.
Parameters :
OUT PBOOLEAN InterruptRecognized Is it ours?
OUT PBOOLEAN QueueMiniportHandleInterrupt Run the DPC?
IN NDIS_HANDLE AdapterContext The Adapter structure.
Return Value :
VOID
*/
VOID LAN91C96_MiniportISR (
PBOOLEAN InterruptRecognized,
PBOOLEAN QueueMiniportHandleInterrupt,
NDIS_HANDLE MiniportAdapterContext
)
{
// USHORT SavedBS;
MINIPORT_ADAPTER *Adapter = (MINIPORT_ADAPTER *) MiniportAdapterContext;
//If the interrupt is shared, verify the interrupt with the interrupt status register
//***************
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96==> Miniport ISR\r\n")));
/*
LAN91C96_Read(Adapter->IOBase + BANK_SELECT, &SavedBS);
LAN91C96_Write(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
LAN91C96_Write(Adapter->IOBase + BANK2_INT_STS,0);
LAN91C96_Write(Adapter->IOBase + BANK_SELECT, SavedBS);
*/
*InterruptRecognized =
*QueueMiniportHandleInterrupt = TRUE;
return;
}
/*
Function Name : LAN91C96_MiniPortHandleInterrupt
Description :
This routine performs deferred processing for adapter
interrupts. All pending interrupt conditions are
handled before exit.
Parameters :
NDIS_HANDLE AdapterContext - Handle to the adapter structure
Return Value :
VOID
*/
VOID LAN91C96_MiniPortHandleInterrupt (IN NDIS_HANDLE AdapterContext)
{
MINIPORT_ADAPTER *Adapter = (MINIPORT_ADAPTER *) AdapterContext;
USHORT SavedBSel,
SavedPNR,
SavedPTR,
temp;
ULONG IOBase,
IntrPort;
UCHAR IntrSts;
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: ==> Miniport Intr Handler\r\n")));
IOBase = Adapter->IOBase;
IntrPort = IOBase + BANK2_INT_STS;
//Save the registers..
LAN91C96_Read(IOBase + BANK_SELECT, &SavedBSel);
LAN91C96_Write(IOBase + BANK_SELECT, (USHORT) 2);
LAN91C96_Read(IOBase + BANK2_PNR, &SavedPNR);
LAN91C96_Read(IOBase + BANK2_PTR, &SavedPTR);
while(1)
{
LAN91C96_Write(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
LAN91C96_Read (IntrPort, &temp);
RETAILMSG(ZONE_INTR, (TEXT("IntrPort = 0x%x\r\n"),temp));
IntrSts = LOBYTE(temp);
if (Adapter->AllocIntPending)
IntrSts &= (ENABLED_INTS | INT_ALLOC);
else
IntrSts &= ENABLED_INTS;
if(!IntrSts) break;
if (IntrSts & INT_RX_CMP)
RCV_Interrupt_Handler(Adapter);
if (IntrSts & INT_TX_CMP)
TX_Interrupt_Handler(Adapter);
if (IntrSts & INT_EPH_INT)
EPH_Interrupt_Handler(Adapter);
if (IntrSts & INT_RX_OVRN)
RX_OVRN_Interrupt_Handler(Adapter);
if (IntrSts & INT_ALLOC)
ALLOC_Interrupt_Handler(Adapter);
}
//Restore the registers
LAN91C96_Write(IOBase + BANK_SELECT, 2);
LAN91C96_Write(IOBase + BANK2_PNR, SavedPNR);
LAN91C96_Write(IOBase + BANK2_PTR, SavedPTR);
LAN91C96_Write(IOBase + BANK_SELECT, SavedBSel);
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: <== Miniport Intr Handler\r\n")));
return;
}
VOID LAN91C96_MiniportEnableInterrupt (NDIS_HANDLE MiniportAdapterContext)
{//USHORT SavedBS;
MINIPORT_ADAPTER *Adapter = (MINIPORT_ADAPTER *) MiniportAdapterContext;
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: <==> MiniPort ENABLE Interrupt\r\n")));
// LAN91C96_Read(Adapter->IOBase + BANK_SELECT, &SavedBS);
LAN91C96_Write(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
LAN91C96_Write(Adapter->IOBase + BANK2_INT_STS,(USHORT)(ENABLED_INTS << 8));
// LAN91C96_Write(Adapter->IOBase + BANK_SELECT, SavedBS);
return;
}
VOID LAN91C96_MiniportDisableInterrupt (NDIS_HANDLE MiniportAdapterContext)
{//USHORT SavedBS;
MINIPORT_ADAPTER *Adapter = (MINIPORT_ADAPTER *) MiniportAdapterContext;
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: <==> MiniPort DISABLE Interrupt\r\n")));
// LAN91C96_Read(Adapter->IOBase + BANK_SELECT, &SavedBS);
LAN91C96_Write(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
LAN91C96_Write(Adapter->IOBase + BANK2_INT_STS,0);
// LAN91C96_Write(Adapter->IOBase + BANK_SELECT, SavedBS);
return;
}
VOID EPH_Interrupt_Handler (MINIPORT_ADAPTER *Adapter)
{
USHORT EPHStatus;
USHORT temp;
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: <==> EPH Interrupt Handler\r\n")));
//Read the EPH Status register
LAN91C96_Write(Adapter->IOBase + BANK_SELECT, (USHORT) 0);
LAN91C96_Read(Adapter->IOBase + BANK0_STS, &EPHStatus);
//Check for errors
if (EPHStatus & TFS_LINKERROR)
{
//Acked by clearing the LE_ENABLE bit in the Control Register
LAN91C96_Write(Adapter->IOBase + BANK_SELECT, (USHORT) 1);
LAN91C96_Read(Adapter->IOBase + BANK1_CTL, (PUSHORT) &temp);
temp |= CTL_LE_EN;
LAN91C96_Write(Adapter->IOBase + BANK1_CTL, temp);
}
if (EPHStatus & TFS_COUNTER)
{
//This is cleared by reading the ECR
LAN91C96_Write(Adapter->IOBase + BANK_SELECT, (USHORT) 0);
LAN91C96_Read(Adapter->IOBase + BANK0_CTR, &temp);
}
//Renable the Transmitter..
LAN91C96_Write(Adapter->IOBase + BANK_SELECT, (USHORT) 0);
LAN91C96_Write(Adapter->IOBase + BANK0_TCR, Adapter->TCR | TCR_TX_ENA);
return;
}
VOID ALLOC_Interrupt_Handler (MINIPORT_ADAPTER *Adapter)
{
USHORT PacketNumber;
MINIPORT_PACKET *Packet;
PNDIS_PACKET pNDISPacket;
ULONG IOBase;
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: ==> Alloc Interrupt Handler\r\n")));
IOBase = Adapter->IOBase;
Adapter->AllocIntPending = FALSE;
//Get the allocated packet
LAN91C96_Read(IOBase + BANK2_PNR, (PUSHORT)&PacketNumber);
PacketNumber = PacketNumber >> 8; //allocated packet number in higher byte
//Write the allocated packet no. to PNR
LAN91C96_Write(IOBase + BANK2_PNR, PacketNumber);
NdisStallExecution(1);
if (Adapter->AllocPending.First)
DequePacket(Adapter->AllocPending, Packet);
if(Packet)
{
pNDISPacket = CONTAINING_RECORD(Packet,NDIS_PACKET,MiniportReserved[0]);
//Make sure that the packet size is in legal limits.
AdapterWriteData(Adapter, pNDISPacket, PacketNumber);
}
else
{
LAN91C96_Write(IOBase + BANK2_PNR, PacketNumber);
LAN91C96_Write(IOBase + BANK2_MMUCMD,(USHORT) CMD_REL_SPEC);
}
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: <== Alloc Interrupt Handler\r\n")));
return;
}
VOID RX_OVRN_Interrupt_Handler (MINIPORT_ADAPTER *Adapter)
{
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: ==> RX OVRN Interrupt Handler\r\n")));
//Ack the interrupt
LAN91C96_Write(Adapter->IOBase + BANK_SELECT,2);
LAN91C96_Write(Adapter->IOBase + BANK2_INT_STS,INT_RX_OVRN);
//Update the counter
Adapter->Stat_RxOvrn++;
//Make sure the RCR is ok.
LAN91C96_Write(Adapter->IOBase + BANK_SELECT,(USHORT) 0);
LAN91C96_Write(Adapter->IOBase + BANK0_RCR, Adapter->RCR);
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: <== RX OVRN Interrupt Handler\r\n")));
return;
}
VOID TX_Interrupt_Handler (MINIPORT_ADAPTER *Adapter)
{
ULONG IOBase;
USHORT PacketNumber;
USHORT TempWord;
NDIS_STATUS RetStatus;
MINIPORT_PACKET *LocalPkt;
NDIS_PACKET *NdisPacket;
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: ==> TX Interrupt Handler\r\n")));
IOBase = Adapter->IOBase;
LAN91C96_Write(IOBase + BANK_SELECT,(USHORT)2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -