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

📄 nicinterrupt.c

📁 3com3c905网卡驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************
*** Note: Copy rights resevered to Beijing Pacific Linkair Communications Co. 
***
*** File Name: Interrupt.cc
*** Purpose  : Interrupt Handlers dealing all kinds of interrup from NIC Cards
***
*** Author   : Guangzhao Tian
*** Modified : By Guangzhao Tian at 2000/9/7
***
**/

#include "NICMacro.h"
#include "NICWinReg.h"
#include "NICCommand.h"
#include "NICEeprom.h"
#include "NICData.h"
#include "NICHelper.h"
#include "NICExport.h"

#ifndef  IVEC_TO_INUM
#define IVEC_TO_INUM(intVec)    ((int) (intVec))
#endif
 
#ifndef  INUM_TO_IVEC
#define INUM_TO_IVEC(intNum)    ((VOIDFUNCPTR *) (intNum))
#endif

/**********Extern variables***********************/
extern NIC_INFORMATION  * pNic_Information;

/********************************************************
***  Just for test
**/
void Drv_ShowIntInfo(IN PNIC_INFORMATION pAdapter) 
{  

   DebugMsg("***************\n");

   DebugMsg(" Inttrupt Status Register Value : 0x%08X. \n",
                        NIC_READ_PORT_USHORT(pAdapter->IoBaseAddress,INTSTATUS_COMMAND_REGISTER) ); 
   
   NIC_COMMAND( (pAdapter->IoBaseAddress),
                   (USHORT)(COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_5) );

   DebugMsg(" Indication Enable Register Value : 0x%08X. \n",
                        NIC_READ_PORT_USHORT(pAdapter->IoBaseAddress,INDICATION_ENABLE_REGISTER) ); 

   DebugMsg(" Inttrupt Enable Register Value : 0x%08X. \n",
                        NIC_READ_PORT_USHORT(pAdapter->IoBaseAddress,INTERRUPT_ENABLE_REGISTER) ); 

   DebugMsg("***************\n");

}

/*************************************************************************
*** Hook the Interruptor Vector and Enable Interruptor
**/
NIC_STATUS Drv_InterruptHook(IN PNIC_INFORMATION pAdapter) 
{
   DebugMsg("\n************\nNow Hook the Interrupt Handler to Interruptor Vector...");

   NIC_MASK_ALL_INTERRUPT(pAdapter->IoBaseAddress) ;

   if(ERROR == NIC_INTTRUPT_Hook(pAdapter->InterruptVector, NIC_InterruptHandler,NULL) )
   {
     DebugMsg("\n Failure to Hook the Interrupt Hander to the INT Vector ! \n"); 
     return NIC_STATUS_FAILURE;
   }
   
   NIC_ENABLE_ALL_INTERRUPT_INDICATION(pAdapter->IoBaseAddress);

   NIC_UNMASK_ALL_INTERRUPT(pAdapter->IoBaseAddress);

   DebugMsg(" Done ! \n******\n");

   Drv_ShowIntInfo(pAdapter);

   NIC_INTTRUPT_ENABLE( pAdapter->InterruptVector);
 
   return NIC_STATUS_SUCCESS;
}

/****************************************************
***	This routine handles the interrupt, check each possible 
*** interrupt source to find who is calling, and switch to
*** the rountines.
**/

VOID NIC_InterruptHandler ()
{		
	USHORT intStatus = 0;
	UCHAR  nloopCount = 2;
	BOOLEAN countDownTimerEventCalled = FALSE; 
    int x;

   /* First of all disable the intrrupt, and Mask all the interrupts , 
           avoiding any interrupt to bore me

    NIC_INTTRUPT_DISABLE( pNic_Information->InterruptVector);  */

    NIC_MASK_ALL_INTERRUPT(pNic_Information->IoBaseAddress );

    DebugMsg("\n********\nWe get an Interruptor, let's do it ....\n");

	/* reading the IntStatus Registers to find who is boring*/
 	intStatus = NIC_READ_PORT_UCHAR( pNic_Information->IoBaseAddress,INTSTATUS_COMMAND_REGISTER);

	if (! (intStatus & INTSTATUS_INTERRUPT_LATCH) )
	{			
        DebugMsg("An Spurious Intterrupt occurs, Let's go sleep! \n");

        NIC_ACKNOWLEDGE_ALL_INTERRUPT(pNic_Information->IoBaseAddress);
       	NIC_UNMASK_ALL_INTERRUPT(pNic_Information->IoBaseAddress );

    /*    NIC_INTTRUPT_ENABLE( pNic_Information->InterruptVector); */
		return;
	}
	else 
	{
        DebugMsg(" Mask all Interrupts, and clear Interrrupt Bits ! \n");
        /*Clear the Interrpt Latch bits*/
        NIC_COMMAND(pNic_Information->IoBaseAddress, COMMAND_ACKNOWLEDGE_INTERRUPT | 
										            ACKNOWLEDGE_INTERRUPT_LATCH);
	}

	/* Read the interrupt status register. */
	intStatus=NIC_READ_PORT_USHORT(pNic_Information->IoBaseAddress,INTSTATUS_COMMAND_REGISTER);

    intStatus &= INTSTATUS_INTERRUPT_MASK;  /*to carve out the intrrupt relevant*/

	if (!intStatus)  /*Unkown case, maybe some thing wrong,let's go home*/
    {
        NIC_ACKNOWLEDGE_ALL_INTERRUPT(pNic_Information->IoBaseAddress);
        NIC_UNMASK_ALL_INTERRUPT(pNic_Information->IoBaseAddress );
    /*    NIC_INTTRUPT_ENABLE( pNic_Information->InterruptVector); */
		return;
    }  

    if (intStatus & INTSTATUS_HOST_ERROR)
	{	
       /*     NIC_IntHostError(pNic_Information);   */

          NIC_COMMAND_WAIT(pNic_Information,
			COMMAND_GLOBAL_RESET           | GLOBAL_RESET_MASK_NETWORK_RESET |
			GLOBAL_RESET_MASK_TP_AUI_RESET | GLOBAL_RESET_MASK_ENDEC_RESET   |
			GLOBAL_RESET_MASK_AISM_RESET   | GLOBAL_RESET_MASK_SMB_RESET     |
			GLOBAL_RESET_MASK_VCO_RESET    );
    
           Drv_ShowIntInfo(pNic_Information); 

          NIC_ENABLE_ALL_INTERRUPT_INDICATION(pNic_Information->IoBaseAddress);

    }

    if (intStatus & INTSTATUS_UPDATE_STATISTICS)	/* interrupt is cleared by reading  statistics.*/
	{	
	    NIC_IntUpdateStatistic(pNic_Information);
    }

	if (intStatus & INTSTATUS_UP_COMPLETE)
	{ 
		NIC_COMMAND( pNic_Information->IoBaseAddress ,COMMAND_ACKNOWLEDGE_INTERRUPT |
	                   	                    ACKNOWLEDGE_UP_COMPLETE);
    	NIC_IntUpComplete(pNic_Information);
    }

	if (intStatus & INTSTATUS_INTERRUPT_REQUESTED)
	{	
		NIC_COMMAND(pNic_Information->IoBaseAddress,COMMAND_ACKNOWLEDGE_INTERRUPT | 
				                 ACKNOWLEDGE_INTERRUPT_REQUESTED);

		NIC_IntCountDownTimer(pNic_Information);
			countDownTimerEventCalled = TRUE;
    }

	if (intStatus & INTSTATUS_TX_COMPLETE) 
	{	
		NIC_IntTxComplete(pNic_Information);
    }

    if ( intStatus & INTSTATUS_RX_COMPLETE )
    {
       DebugMsg(" I know that someone gives data to my Rx FIFO ! \n ");   
    }

    if (  (intStatus & INTSTATUS_LINK_EVENT) ||  (intStatus & INTSTATUS_DOWN_COMPLETE) )
	{	
		DebugMsg(" Other Interrupt we don't care.\n");
    }

    if (FALSE == countDownTimerEventCalled) 
	{	
		NIC_IntCountDownTimer(pNic_Information);
    		countDownTimerEventCalled = TRUE;
     }

    DebugMsg(" Now UnMask all interrupt! \n");

    NIC_ACKNOWLEDGE_ALL_INTERRUPT(pNic_Information->IoBaseAddress);
	NIC_UNMASK_ALL_INTERRUPT(pNic_Information->IoBaseAddress );

  /*  NIC_INTTRUPT_ENABLE( pNic_Information->InterruptVector); */
  
    DebugMsg("Interrupt be done ! \n *******************\n");

	return;
}

/*****************************************************************
***	This routine handles the host error,called by Interrupt Handler
*** to dealing the Host Error Event interrupt
**/
VOID NIC_IntHostError(IN PNIC_INFORMATION pAdapter)
{

/*	TASKQ	HostErrTask;
	HostErrTask = pAdapter->Resources.hostErr_task;

	Read the internal config. 
	NIC_COMMAND(pAdapter,COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_3);

	pAdapter->keepForGlobalReset = NIC_READ_PORT_ULONG(
								pAdapter, 
								INTERNAL_CONFIG_REGISTER); */

	DebugMsg(" \n PCI exeception,Adapter has to be globally resetted and restarted\n");

	/* Issue Global reset. I will mask the updown reset so that  I don't have to 
	   set the UpPoll, DownPoll, UpListPointer and DownListPointer. */

	NIC_COMMAND_WAIT(pAdapter,
			COMMAND_GLOBAL_RESET           | GLOBAL_RESET_MASK_NETWORK_RESET |
			GLOBAL_RESET_MASK_TP_AUI_RESET | GLOBAL_RESET_MASK_ENDEC_RESET   |
			GLOBAL_RESET_MASK_AISM_RESET   | GLOBAL_RESET_MASK_SMB_RESET     |
			GLOBAL_RESET_MASK_VCO_RESET    ); /* | GLOBAL_RESET_MASK_UP_DOWN_RESET ); */
    
    DebugMsg(" Now Card Resetting -- Done !\n");

	return;
}	


/***********************************************************
*** This routine handles the update statistics interrupt.
*** called by Interrupt handler.
**/
VOID NIC_IntUpdateStatistic(IN  NIC_INFORMATION * pAdapter)
{

	PNIC_STATISTICS pStatistics = &pAdapter->Statistics;

	USHORT retValueWord=0;
	UINT   retValueByte=0;

	USHORT rxPackets, txPackets, highPackets;
	USHORT rxBytes, txBytes, highBytes;

	/* Change the window. */
    DebugMsg(" Now Update Statistic Interuptor!\n");
	NIC_COMMAND (pAdapter->IoBaseAddress ,
		                   COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_6);

	retValueByte=NIC_READ_PORT_UCHAR(pAdapter->IoBaseAddress, CARRIER_LOST_REGISTER);
		pStatistics->TxCarrierLost += retValueByte;

	retValueByte=NIC_READ_PORT_UCHAR(pAdapter->IoBaseAddress , SQE_ERRORS_REGISTER);
		pStatistics->TxSQEErrors += retValueByte;

	retValueByte=NIC_READ_PORT_UCHAR(pAdapter->IoBaseAddress, MULTIPLE_COLLISIONS_REGISTER);
		pStatistics->TxMultipleCollisions += retValueByte;

	retValueByte=NIC_READ_PORT_UCHAR(pAdapter->IoBaseAddress, SINGLE_COLLISIONS_REGISTER);
		pStatistics->TxSingleCollisions += retValueByte;

	retValueByte=NIC_READ_PORT_UCHAR(pAdapter->IoBaseAddress, LATE_COLLISIONS_REGISTER);
		pStatistics->TxLateCollisions += retValueByte;

	retValueByte=NIC_READ_PORT_UCHAR(pAdapter->IoBaseAddress, RX_OVERRUNS_REGISTER);
		pStatistics->RxOverruns += retValueByte;

	retValueByte=NIC_READ_PORT_UCHAR(pAdapter->IoBaseAddress, FRAMES_DEFERRED_REGISTER);
		pStatistics->TxFramesDeferred += retValueByte;

⌨️ 快捷键说明

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