📄 int.c
字号:
BOOLEAN fReceived = FALSE;
BOOLEAN fTmpReceived = FALSE;
INTR_HLDOFF_REG regIntrHldoff;
//
// If the adapter is currently resetting then we need to bail.
//
NdisDprAcquireSpinLock(&pAdapter->lock);
if (ADAPTER_TEST_FLAG(pAdapter, fADAPTER_RESET_IN_PROGRESS) ||
ADAPTER_TEST_FLAG(pAdapter, fADAPTER_HARDWARE_FAILURE))
{
NdisDprReleaseSpinLock(&pAdapter->lock);
DBGPRINT(DBG_COMP_INT, DBG_LEVEL_INFO,
("<==TbAtm155HandleInterrupt_1\n"));
return;
}
ASSERT(!ADAPTER_TEST_FLAG(pAdapter, fADAPTER_RESET_REQUESTED));
//
// Mark the adapter as processing interrupts.
//
ADAPTER_SET_FLAG(pAdapter, fADAPTER_PROCESSING_INTERRUPTS);
NdisDprReleaseSpinLock(&pAdapter->lock);
//
// Read the interrupt status.
//
TBATM155_READ_PORT(
&pHwInfo->TbAtm155_SAR->Intr_Status,
&InterruptStatus);
InterruptStatus &= TBATM155_REG_INT_VALID;
//
// Clear the interrupt status register
//
TBATM155_WRITE_PORT(
&pHwInfo->TbAtm155_SAR->Intr_Status,
InterruptStatus);
InterruptCount = 0;
while (0 != InterruptStatus)
{
if (InterruptStatus & (TBATM155_INT_TX_IOC | TBATM155_INT_RX_IOC))
{
//
// Reload the holdoff count and timer.
//
regIntrHldoff.reg = 0;
if (InterruptStatus & TBATM155_INT_TX_IOC)
{
//
// Set HoldOff count and timer of TxIOC interrupt.
//
regIntrHldoff.Tx_IOC_Hldoff_Wr = 1;
regIntrHldoff.Tx_IOC_Hldoff_Cnt = TX_IOC_HLDOFF_CNT;
regIntrHldoff.Tx_IOC_Hldoff_Time = TX_IOC_HLDOFF_TIME;
}
if (InterruptStatus & TBATM155_INT_RX_IOC)
{
//
// Set HoldOff count and timer of RxIOC interrupt.
//
regIntrHldoff.Rx_IOC_Hldoff_Wr = 1;
regIntrHldoff.Rx_IOC_Hldoff_Cnt = RX_IOC_HLDOFF_CNT;
regIntrHldoff.Rx_IOC_Hldoff_Time = RX_IOC_HLDOFF_TIME;
}
TBATM155_WRITE_PORT(
&pHwInfo->TbAtm155_SAR->Intr_Hldoff,
regIntrHldoff.reg);
//
// Disable modifying holdoff count and timer fields.
//
regIntrHldoff.reg = 0;
TBATM155_WRITE_PORT(
&pHwInfo->TbAtm155_SAR->Intr_Hldoff,
regIntrHldoff.reg);
}
//
// Was there any error interrupts?
//
if ((InterruptStatus & TBATM155_REG_INT_ERROR) != 0)
{
//
// Save the interrupt status with the adapter block's
// hardware information to process when we are synchronized with
// the interrupt.
//
pHwInfo->InterruptStatus = InterruptStatus;
//
// Process the error interrupts.
//
tbAtm155ErrorInterrupt(pAdapter);
break;
}
//
// Was there a interrupt from the PHY chip?
//
if (InterruptStatus & TBATM155_INT_PHY_INTR)
{
if (pHwInfo->fAdapterHw & TBATM155_PHY_SUNI_LITE)
{
tbAtm155SuniInterrupt(pAdapter);
}
else
{
tbAtm155PLC2Interrupt(pAdapter);
}
InterruptStatus &= ~TBATM155_INT_PHY_INTR;
}
//
// If Invalid VC interrupts
//
if (InterruptStatus & (TBATM155_INT_RX_UNOPENED_VC | TBATM155_INT_RX_UNKNOWN_VC))
{
DBGPRINT(DBG_COMP_INT, DBG_LEVEL_INFO,
("Detected packets for unknown VC.\n"));
NdisInterlockedIncrement((PLONG)&pAdapter->StatInfo.RecvInvalidVpiVci);
InterruptStatus &= ~(TBATM155_INT_RX_UNOPENED_VC | TBATM155_INT_RX_UNKNOWN_VC);
}
//
// If receive Host Access Error interrupt
//
if (InterruptStatus & TBATM155_INT_HOST_ACCESS_ERR)
{
DBGPRINT(DBG_COMP_INT, DBG_LEVEL_INFO,
("InterruptStatus & TBATM155_INT_HOST_ACCESS_ERR\n"));
InterruptStatus &= ~TBATM155_INT_HOST_ACCESS_ERR;
}
//
// If receive data FIFO overflow.
//
if (InterruptStatus & TBATM155_INT_RX_DATA_FIFO_OVFL)
{
DBGPRINT(DBG_COMP_INT, DBG_LEVEL_INFO,
("Detected receive data FIFO overflow.\n"));
NdisInterlockedIncrement((PLONG)&pAdapter->StatInfo.RecvCellsDropped);
InterruptStatus &= ~TBATM155_INT_RX_DATA_FIFO_OVFL;
}
//
// If "Big" receive slots are running low.
//
if (InterruptStatus &
(TBATM155_INT_RX_NO_BIG_SLOTS | TBATM155_INT_RX_BIG_SLOTS_LOW))
{
DBGPRINT(DBG_COMP_INT, DBG_LEVEL_ERR,
("Detected 'BIG' receive slots running low or no slots.\n"));
DBGPRINT(DBG_COMP_INT, DBG_LEVEL_ERR,
("RemainingReceiveBigSlots: %ld\n",
pSar->RecvDmaQ.RemainingReceiveBigSlots));
tbAtm155QueueRecvBuffersToReceiveSlots(
pAdapter,
RECV_BIG_BUFFER);
pSar->fBigllSlotsLowOrNone = TRUE;
InterruptStatus &= ~(TBATM155_INT_RX_NO_BIG_SLOTS | TBATM155_INT_RX_BIG_SLOTS_LOW);
}
//
// If "Small" receive slots are running low.
//
if (InterruptStatus &
(TBATM155_INT_RX_NO_SMALL_SLOTS | TBATM155_INT_RX_SMALL_SLOTS_LOW))
{
DBGPRINT(DBG_COMP_INT, DBG_LEVEL_ERR,
("Detected 'SMALL' receive slots running low or no slots.\n"));
DBGPRINT(DBG_COMP_INT, DBG_LEVEL_ERR,
("RemainingReceiveSmallSlots: %ld\n",
pSar->RecvDmaQ.RemainingReceiveSmallSlots));
tbAtm155QueueRecvBuffersToReceiveSlots(
pAdapter,
RECV_SMALL_BUFFER);
pSar->fSmallSlotsLowOrNone = TRUE;
InterruptStatus &= ~(TBATM155_INT_RX_NO_SMALL_SLOTS | TBATM155_INT_RX_SMALL_SLOTS_LOW);
}
//
// Check for receiving any packets.
//
if (InterruptStatus & TBATM155_INT_RX_IOC)
{
fTmpReceived = tbAtm155RxInterruptOnCompletion(pAdapter);
//
// Should not overwrite if fReceived has been set to TRUE.
//
if (fReceived == FALSE)
fReceived = fTmpReceived;
// Clear these flags regardless.
pSar->fSmallSlotsLowOrNone = FALSE;
pSar->fBigllSlotsLowOrNone = FALSE;
InterruptStatus &= ~TBATM155_INT_RX_IOC;
}
//
// Check to see if packets have been transmitted.
//
if (InterruptStatus & TBATM155_INT_TX_IOC)
{
tbAtm155TxInterruptOnCompletion(pAdapter);
InterruptStatus &= ~TBATM155_INT_TX_IOC;
}
//
// Increment the number of interrupts that we have processed.
//
InterruptCount++;
if (MAXIMUM_INTERRUPTS == InterruptCount)
{
//
// Break out so we don't ack more interrupts
// (and miss them later).
//
break;
}
//
// Read the interrupt status register and see if there is anything
// new.
//
TBATM155_READ_PORT(
&pHwInfo->TbAtm155_SAR->Intr_Status,
&InterruptStatus);
InterruptStatus &= TBATM155_REG_INT_VALID;
//
// Clear the interrupt status register
//
TBATM155_WRITE_PORT(
&pHwInfo->TbAtm155_SAR->Intr_Status,
InterruptStatus);
}
//
// Has the adapter received any packets?
//
if (fReceived == TRUE)
{
//
// Issue a receive complete to the transports.
//
NdisMCoReceiveComplete(pAdapter->MiniportAdapterHandle);
}
//
// Was a reset requested?
//
NdisDprAcquireSpinLock(&pAdapter->lock);
ADAPTER_CLEAR_FLAG(pAdapter, fADAPTER_PROCESSING_INTERRUPTS);
if (ADAPTER_TEST_FLAG(pAdapter, fADAPTER_RESET_REQUESTED))
{
if (!ADAPTER_TEST_FLAG(pAdapter, fADAPTER_PROCESSING_SENDPACKETS))
{
ADAPTER_SET_FLAG(pAdapter, fADAPTER_RESET_IN_PROGRESS);
ADAPTER_CLEAR_FLAG(pAdapter, fADAPTER_RESET_REQUESTED);
NdisDprReleaseSpinLock(&pAdapter->lock);
DBGPRINT(DBG_COMP_INT, DBG_LEVEL_ERR,
("Calling tbAtm155ProcessReset in TbAtm155HandleInterrupt\n"));
tbAtm155ProcessReset(pAdapter);
NdisMResetComplete(pAdapter->MiniportAdapterHandle, NDIS_STATUS_SUCCESS, FALSE);
}
else
{
//
// We are in Tbatm155SendPackets().
// The tbatm155ProcessReset() will be called in sendpackets handler,
// so don't enable interrupts now.
//
NdisDprReleaseSpinLock(&pAdapter->lock);
}
}
else
{
NdisDprReleaseSpinLock(&pAdapter->lock);
//
// Re-enable interrupts.
//
NdisMSynchronizeWithInterrupt(
&pHwInfo->Interrupt,
(PVOID)TbAtm155EnableInterrupt,
pAdapter);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -