⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lan91c111_intr.c

📁 PXA255/270平台的 LAN91C111网卡驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*
*    Copyright (c) Standard MicroSystems Corporation.  All Rights Reserved.
*
*				    LAN91C111 Driver for Windows CE .NET
*
*							 Revision History
*_______________________________________________________________________________
*     Author		  Date		Version		Description
*_______________________________________________________________________________
* Pramod Bhardwaj  6/18/2002	  0.1		Beta Release
*					7/15/2002	  1.0       Release 
*					1/22/2003     1.1		Removed some platform dependencies
*					3/27/2003     1.2       Used alloc interrupt
* TScho				2/15/2004	  1.2.0		Performance changes (Beta)
* TScho				2/20/2004	  1.2.1		Multi-packet indication (Beta)
* TScho				2/25/2004	  1.2.2		Multicast fixed (Beta)
* TScho				2/26/2004	  2.1		Release for CE 5.0
*_______________________________________________________________________________
*
* Description:
*              Interrupt Service routines and other required functions for 
*  processing the interrupts.
*
*
*/

#include <Ndis.h>
#include "LAN91C111_Adapter.h"
#include "LAN91C111_Proto.h"

#define SMSC_32BIT_RW	1
#undef SMSC_32BIT_RW
static char _LAN91C111_Intr_C_Date_Code_[] = "082304";

__inline void nCtrlPulse(MINIPORT_ADAPTER *Adapter) 
{
	USHORT temp;
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, (USHORT)1);
	NdisRawReadPortUshort(Adapter->IOBase + BANK1_CONFIG, &temp);
	temp |= CFG_GPCNTRL;
	NdisRawWritePortUshort(Adapter->IOBase + BANK1_CONFIG, temp);
	temp &= ~CFG_GPCNTRL;
	NdisRawWritePortUshort(Adapter->IOBase + BANK1_CONFIG, temp);
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, (USHORT)2);
};

__inline void nCtrlLow(MINIPORT_ADAPTER *Adapter) 
{
	USHORT temp;
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, (USHORT)1);
	NdisRawReadPortUshort(Adapter->IOBase + BANK1_CONFIG, &temp);
	temp |= CFG_GPCNTRL;
	NdisRawWritePortUshort(Adapter->IOBase + BANK1_CONFIG, temp);
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, (USHORT)2);
};

__inline void nCtrlHigh(MINIPORT_ADAPTER *Adapter) 
{
	USHORT temp;
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, (USHORT)1);
	NdisRawReadPortUshort(Adapter->IOBase + BANK1_CONFIG, &temp);
	temp &= ~CFG_GPCNTRL;
	NdisRawWritePortUshort(Adapter->IOBase + BANK1_CONFIG, temp);
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, (USHORT)2);
};


/*
Function Name : 	LAN91C111_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.
Parameters    :
OUT PBOOLEAN     InterruptRecognized            Is it ours?
OUT PBOOLEAN     QueueMiniportHandleInterrupt   Run the DPC?
IN  NDIS_HANDLE  AdapterContext                 The Adapter structure.

  Return Value  :
  VOID
*/
VOID LAN91C111_MiniportISR (
							PBOOLEAN    InterruptRecognized,
							PBOOLEAN    QueueMiniportHandleInterrupt,
							NDIS_HANDLE MiniportAdapterContext
							)
{
	MINIPORT_ADAPTER *Adapter = (MINIPORT_ADAPTER *) MiniportAdapterContext;
	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111:<==> Miniport ISR\r\n")));
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
	NdisRawWritePortUshort(Adapter->IOBase + BANK2_INT_STS,0);
	*InterruptRecognized			  =
		*QueueMiniportHandleInterrupt = TRUE;
	return;
}


/*
Function Name : 	LAN91C111_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 LAN91C111_MiniPortHandleInterrupt (IN NDIS_HANDLE  AdapterContext)
{
	MINIPORT_ADAPTER *Adapter = (MINIPORT_ADAPTER *) AdapterContext;
	USHORT		SavedBSel, SavedPNR, SavedPTR, temp;
	ULONG		IOBase, IntrPort;
	UCHAR		IntrSts;

	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111:==> Miniport Handler\r\n")));
	IOBase		= Adapter->IOBase;
	IntrPort	= IOBase + BANK2_INT_STS;

	//Save the Bank Select..
	NdisRawReadPortUshort(IOBase + BANK_SELECT, &SavedBSel);
	NdisRawWritePortUshort(IOBase + BANK_SELECT, (USHORT) 2);
	NdisRawReadPortUshort(IOBase + BANK2_PNR, &SavedPNR);
	NdisRawReadPortUshort(IOBase + BANK2_PTR, &SavedPTR);

	while (1)
	{
		NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
		NdisRawReadPortUshort (IntrPort, &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_RX_OVRN)
			RX_OVRN_Interrupt_Handler(Adapter);

		if (IntrSts & INT_EPH_INT)
			EPH_Interrupt_Handler(Adapter);
		
		if (IntrSts & INT_ALLOC)
			ALLOC_Interrupt_Handler(Adapter);

		if (IntrSts & INT_MDINT)
			MD_Interrupt_Handler(Adapter);
	}

	// re-enable NIC Interrupts
	//NdisRawWritePortUshort(IOBase + BANK_SELECT, 2);
	//NdisRawWritePortUshort(IOBase + BANK2_INT_STS,(ENABLED_INTS << 8));

	//Restore the registers
	NdisRawWritePortUshort(IOBase + BANK_SELECT, 2);
	NdisRawWritePortUshort(IOBase + BANK2_PNR, SavedPNR);
	NdisRawWritePortUshort(IOBase + BANK2_PTR, SavedPTR);
	NdisRawWritePortUshort(IOBase + BANK_SELECT, SavedBSel);
	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111:<== Miniport Handler\r\n")));
	return;
}



VOID LAN91C111_MiniportEnableInterrupt (NDIS_HANDLE MiniportAdapterContext)
{
	USHORT SavedBS;
	MINIPORT_ADAPTER    *Adapter = (MINIPORT_ADAPTER *) MiniportAdapterContext;

	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111: ==> MiniPort ENABLE Interrupt\r\n")));
	
	NdisRawReadPortUshort(Adapter->IOBase + BANK_SELECT, &SavedBS);
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
	NdisRawWritePortUshort(Adapter->IOBase + BANK2_INT_STS,(ENABLED_INTS << 8));
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, SavedBS);
	
	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111: <== MiniPort ENABLE Interrupt\r\n")));
	return;
}



VOID LAN91C111_MiniportDisableInterrupt (NDIS_HANDLE MiniportAdapterContext)
{
	MINIPORT_ADAPTER    *Adapter = (MINIPORT_ADAPTER *) MiniportAdapterContext;
	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111: ==> MiniPort DISABLE Interrupt\r\n")));
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
	NdisRawWritePortUshort(Adapter->IOBase + BANK2_INT_STS,0);
	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111: <== MiniPort DISABLE Interrupt\r\n")));
	return;
}


VOID MD_Interrupt_Handler (MINIPORT_ADAPTER *Adapter)
{
	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111: ==> MDINT Interrupt Handler\r\n")));
	
	//Acknowledge the interrupt
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT,2);
	NdisRawWritePortUshort(Adapter->IOBase + BANK2_INT_STS,INT_MDINT);

	//Acknowledge the PHY interrupt
	ReadPhyRegister(Adapter->IOBase, 18);

	//Indicate to the change to the higher layer.
	if (Adapter->LinkStatus == MEDIA_CONNECTED)
	{
		NdisMIndicateStatus(Adapter->AdapterHandle, NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0);
		Adapter->LinkStatus = MEDIA_DISCONNECTED;
	}
	else
	{
		//Re-Negotiate the Link..
		EstablishLink(Adapter);
		//Setup Transmit Control Register
		Adapter->TCR = (USHORT)(TCR_TX_ENA | TCR_PAD_EN | TCR_MON_CSN);
		if (Adapter->Duplex == FULL_DUPLEX)
			Adapter->TCR |= TCR_SWFDUP;
		else
			Adapter->TCR &= (~TCR_SWFDUP);
		NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, (USHORT) 0);
		NdisRawWritePortUshort(Adapter->IOBase + BANK0_TCR, Adapter->TCR);
		NdisMIndicateStatus(Adapter->AdapterHandle, NDIS_STATUS_MEDIA_CONNECT, NULL, 0);
		Adapter->LinkStatus = MEDIA_CONNECTED;
	}
	NdisMIndicateStatusComplete(Adapter->AdapterHandle);

	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111<== MDINT Interrupt\r\n")));
	return;
}


VOID EPH_Interrupt_Handler (MINIPORT_ADAPTER *Adapter)
{
	USHORT EPHStatus;
	USHORT temp;
	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111: ==> EPH Interrupt Handler\r\n")));
	
	//Read the EPH Status register
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, (USHORT) 0);
	NdisRawReadPortUshort(Adapter->IOBase + BANK0_STS, &EPHStatus);
	
	//Check for errors
	if (EPHStatus & TFS_LINKERROR)
	{
		//Acked by clearing the LE_ENABLE bit in the Control Register
		PrintDebugMsg(ZONE_INIT, (TEXT("LAN91C111: LINK_OK\r\n")));
	}
	if (EPHStatus & TFS_COUNTER)
	{
		//This is cleared by reading the ECR
		NdisRawReadPortUshort(Adapter->IOBase + BANK0_CTR, &temp);
	}
	
	//Renable the Transmitter..
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, (USHORT) 0);
	NdisRawWritePortUshort(Adapter->IOBase + BANK0_TCR, Adapter->TCR);
	
	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111: <== EPH Interrupt Handler\r\n")));
}


VOID RX_OVRN_Interrupt_Handler (MINIPORT_ADAPTER *Adapter)
{
	USHORT	FIFO, MIR;

	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111: ==> RX OVRN Interrupt Handler\r\n")));

	//Ack the interrupt
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, 2);
	NdisRawWritePortUshort(Adapter->IOBase + BANK2_INT_STS, INT_RX_OVRN);

	//Update the counter
	Adapter->Stat_RxOvrn++;
	NdisRawReadPortUshort(Adapter->IOBase + BANK2_FIFOS, &FIFO);
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, 0);
	NdisRawReadPortUshort(Adapter->IOBase + BANK0_MIR, &MIR);
	PrintDebugMsg(ZONE_RX_OVRN, (TEXT("LAN91C111: MIR=%04X, FIFO=%04X\r\n"), MIR, FIFO));

	//Make sure the RCR is ok.
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, 0);
	NdisRawWritePortUshort(Adapter->IOBase + BANK0_RCR, Adapter->RCR);

	PrintDebugMsg(ZONE_INTR, (TEXT("LAN91C111: <== RX OVRN Interrupt Handler\r\n")));
	return;
}


VOID ALLOC_Interrupt_Handler (MINIPORT_ADAPTER *Adapter)
{
	USHORT			PacketNumber;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -