📄 nicinterrupt.c
字号:
/*******************************************************************************
*** 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 + -