コード例 #1
0
ファイル: protocol.c プロジェクト: layerfsd/natflt
VOID
	natpReceiveComplete(
		IN NDIS_HANDLE	ProtocolBindingContext
		)
{
	PFILTER_ADAPTER	pAdapt;
	pAdapt = (PFILTER_ADAPTER)ProtocolBindingContext;

	if(1 == InterlockedIncrement(&pAdapt->RcvCompleteProcessing))	
		natpFlushReceiveQueue(pAdapt);

	if ( (pAdapt->MiniportHandle != NULL) 
		&& (pAdapt->IndicateRcvComplete)){
		switch (pAdapt->Medium){
		case NdisMedium802_3:
			NdisMEthIndicateReceiveComplete(pAdapt->MiniportHandle);
			break;

		default:
			break;
		}
	}

	pAdapt->IndicateRcvComplete = FALSE;
	InterlockedDecrement(&pAdapt->RcvCompleteProcessing);
}
コード例 #2
0
VOID
PtReceiveComplete(
	IN	NDIS_HANDLE		ProtocolBindingContext
	)
/*++

Routine Description:

	Called by the adapter below us when it is done indicating a batch of
	received packets.

Arguments:

	ProtocolBindingContext	Pointer to our adapter structure.

Return Value:

	None

--*/
{
	PADAPT		pAdapt =(PADAPT)ProtocolBindingContext;

	if ((pAdapt->MiniportHandle != NULL) && pAdapt->IndicateRcvComplete)
	{
		switch (pAdapt->Medium)
		{
		  case NdisMedium802_3:
		  case NdisMediumWan:
			NdisMEthIndicateReceiveComplete(pAdapt->MiniportHandle);
			break;

		  case NdisMedium802_5:
			NdisMTrIndicateReceiveComplete(pAdapt->MiniportHandle);
			break;

		  case NdisMediumFddi:
			//NdisMFddiIndicateReceiveComplete(pAdapt->MiniportHandle);
			break;

		  default:
			ASSERT(FALSE);
			break;
		}
	}

	pAdapt->IndicateRcvComplete = FALSE;
}
コード例 #3
0
ファイル: driver.cpp プロジェクト: HITEG/TenByTen6410_SLC
void NIC_DRIVER_OBJECT::DriverReceiveIndication(
    int nCurr,
    PVOID pVoid,
    int nLength)
{
    NdisMEthIndicateReceive(
        m_NdisHandle,
        (PNDIS_HANDLE)nCurr,
        (char*)pVoid,
        ETH_HEADER_SIZE,
        ((char*)pVoid + ETH_HEADER_SIZE),
        nLength - ETH_HEADER_SIZE,
        nLength - ETH_HEADER_SIZE);
        
    NdisMEthIndicateReceiveComplete(m_NdisHandle);
    return;
}
コード例 #4
0
ファイル: Neo.c プロジェクト: alex-docker/CE-dockerfiles
// Process the received packet
void NeoWrite(void *buf)
{
	UINT num, i, size;
	void *packet_buf;
	// Validate arguments
	if (buf == NULL)
	{
		return;
	}

	// Number of packets
	num = NEO_NUM_PACKET(buf);
	if (num > NEO_MAX_PACKET_EXCHANGE)
	{
		// Number of packets is too many
		return;
	}
	if (num == 0)
	{
		// No packet
		return;
	}

	if (ctx->Halting != FALSE)
	{
		// Halting
		return;
	}

	if (ctx->Opened == FALSE)
	{
		// Not connected
		return;
	}

	for (i = 0;i < num;i++)
	{
		PACKET_BUFFER *p = ctx->PacketBuffer[i];

		size = NEO_SIZE_OF_PACKET(buf, i);
		if (size > NEO_MAX_PACKET_SIZE)
		{
			size = NEO_MAX_PACKET_SIZE;
		}
		if (size < NEO_PACKET_HEADER_SIZE)
		{
			size = NEO_PACKET_HEADER_SIZE;
		}

		packet_buf = NEO_ADDR_OF_PACKET(buf, i);

		// Buffer copy
		NeoCopy(p->Buf, packet_buf, size);

		if (g_is_win8 == false)
		{
			// Adjust the buffer size
			NdisAdjustBufferLength(p->NdisBuffer, size);
			// Set the packet information
			NDIS_SET_PACKET_STATUS(p->NdisPacket, NDIS_STATUS_RESOURCES);
			NDIS_SET_PACKET_HEADER_SIZE(p->NdisPacket, NEO_PACKET_HEADER_SIZE);
		}
		else
		{
			NdisMEthIndicateReceive(ctx->NdisMiniport, ctx, 
				p->Buf, NEO_PACKET_HEADER_SIZE,
				((UCHAR *)p->Buf) + NEO_PACKET_HEADER_SIZE, size - NEO_PACKET_HEADER_SIZE,
				size - NEO_PACKET_HEADER_SIZE);
			NdisMEthIndicateReceiveComplete(ctx->NdisMiniport);
		}
	}

	// Notify that packets have received
	ctx->Status.NumPacketRecv += num;

	if (g_is_win8 == false)
	{
		NdisMIndicateReceivePacket(ctx->NdisMiniport, ctx->PacketBufferArray, num);
	}
}
コード例 #5
0
/***************************************************************************
Routine Description:

    This is the real interrupt handler for receive/overflow interrupt.

    Called when a receive interrupt is received. It first indicates
    all packets on the card and finally indicates ReceiveComplete().

Arguments:

    Adapter - Pointer to the adapter block.

Return Value:

    TRUE if done with all receives, else FALSE.
*****************************************************************************/
BOOLEAN R6040RcvDpc(IN PR6040_ADAPTER Adapter)
{
    // Status of a received packet.
    INDICATE_STATUS IndicateStatus = INDICATE_OK;

    // Guess at where the packet is located
    PUCHAR PacketLoc;

    // Flag to tell when the receive process is complete
    BOOLEAN Done = TRUE;

    PUCHAR rxd;
    USHORT rxstatus;
    int total_len;

    do
    {
        // Code to fix a loop we got into where the card had been removed,
        // Now, the NDIS unbind routine calls our shutdown
        // handler which sets a flag
        if (Adapter->ShuttingDown)
        {
            RETAILMSG(R6040DBG, (TEXT("R6040RcvDpc(): Shutdown detected\r\n")));
            break;
        }

        // Default to not indicating NdisMEthIndicateReceiveComplete
        Adapter->IndicateReceiveDone = FALSE;

        // A packet was found on the card, indicate it.
        Adapter->ReceivePacketCount++;

        rxd = Adapter->Rx_ring[Adapter->Rx_desc_add].VirtualAddr;

        READMEM16(rxd + DS_STATUS, rxstatus);
        READMEM16(rxd + DS_LEN, total_len);
        total_len -= 4;  /* Skip CRC 4 byte */

        /* OWN bit=1, no packet coming */
        if (rxstatus & 0x8000)
        {
            IndicateStatus = SKIPPED;
            //RETAILMSG(R6040DBG, (TEXT("R6040RcvDpc(): no packet coming \r\n")));
            break;
        }

        //RETAILMSG(R6040DBG, (TEXT("R6040RcvDpc(): total_len = %d\r\n"), total_len));

        Adapter->Rx_desc_add++;
        // Adapter->Rx_free_cnt++;

        // Copy the data to the network stack
        PacketLoc = rxd + BUF_START;
        Adapter->PacketHeaderLoc =  PacketLoc;

        // Indicate the packet to the wrapper
        IndicateStatus = R6040IndicatePacket(Adapter , total_len);
        if (IndicateStatus != CARD_BAD)
        {
            Adapter->FramesRcvGood++;
        }

        // Handle when the card is unable to indicate good packets
        if (IndicateStatus == CARD_BAD)
        {
            RETAILMSG(R6040DBG,
                (TEXT("R6040RcvDpc(): CARD_BAD: R: <%x %x %x %x> \r\n"),
                Adapter->PacketHeader[0],
                Adapter->PacketHeader[1],
                Adapter->PacketHeader[2],
                Adapter->PacketHeader[3]));

            // Start off with receive interrupts disabled.
            Adapter->NicInterruptMask = MIER_RXENDE | MIER_TXENDE;

            // Reset the adapter
            CardReset(Adapter);
            // Since the adapter was just reset, stop indicating packets.
            break;
        }

        /* Rx data already copy to the upper buffer, now can reuse RX descriptor */
        WRITEMEM16(rxd + DS_STATUS, 0x8000); /* Reuse RX descriptor */

        /* Signal RX ready */
        // NdisRawWritePortUshort( Adapter->IoPAddr + NIC_CONTROL0,Adapter->MacControl);

        /* Move to next RX descriptor */
        if (Adapter->Rx_desc_add >= MAX_RX_DESCRIPTORS)
        {
            Adapter->Rx_desc_add = 0;
            Done = FALSE;
            Adapter->ReceivePacketCount = 0;
            // break;
        }

        // Finally, indicate ReceiveComplete to all protocols which received packets
        if (Adapter->IndicateReceiveDone)
        {
            NdisDprReleaseSpinLock(&Adapter->RcvLock);
            NdisMEthIndicateReceiveComplete(Adapter->MiniportAdapterHandle);
            NdisDprAcquireSpinLock(&Adapter->RcvLock);
            Adapter->IndicateReceiveDone = FALSE;
        }
    }while (TRUE);

    return (Done);
}
コード例 #6
0
ファイル: interrupt.c プロジェクト: hoangduit/reactos
VOID
NTAPI
MiniportHandleInterrupt (
    IN NDIS_HANDLE MiniportAdapterContext
    )
{
    PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext;
    ULONG txStatus;
    UCHAR command;
    PPACKET_HEADER nicHeader;
    PETH_HEADER ethHeader;
        
    NdisDprAcquireSpinLock(&adapter->Lock);
    
    NDIS_DbgPrint(MAX_TRACE, ("Interrupts pending: 0x%x\n", adapter->InterruptPending));
    
    //
    // Handle a link change
    //
    if (adapter->LinkChange)
    {
        NdisDprReleaseSpinLock(&adapter->Lock);
        NdisMIndicateStatus(adapter->MiniportAdapterHandle,
                            adapter->MediaState == NdisMediaStateConnected ?
                                NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT,
                            NULL,
                            0);
        NdisMIndicateStatusComplete(adapter->MiniportAdapterHandle);
        NdisDprAcquireSpinLock(&adapter->Lock);
        adapter->LinkChange = FALSE;
    }                            
    
    //
    // Handle a TX interrupt
    //
    if (adapter->InterruptPending & (R_I_TXOK | R_I_TXERR))
    {
        while (adapter->TxFull || adapter->DirtyTxDesc != adapter->CurrentTxDesc)
        {
            NdisRawReadPortUlong(adapter->IoBase + R_TXSTS0 +
                                 (adapter->DirtyTxDesc * sizeof(ULONG)), &txStatus);
            
            if (!(txStatus & (R_TXS_STATOK | R_TXS_UNDERRUN | R_TXS_ABORTED)))
            {
                //
                // Not sent yet
                //
                break;
            }
            
            NDIS_DbgPrint(MAX_TRACE, ("Transmission for desc %d complete: 0x%x\n",
                                      adapter->DirtyTxDesc, txStatus));
            
            if (txStatus & R_TXS_STATOK)
            {
                adapter->TransmitOk++;
            }
            else
            {
                adapter->TransmitError++;
            }

            adapter->DirtyTxDesc++;
            adapter->DirtyTxDesc %= TX_DESC_COUNT;
            adapter->InterruptPending &= ~(R_I_TXOK | R_I_TXERR);
            adapter->TxFull = FALSE;
        }
    }
    
    //
    // Handle a good RX interrupt
    //
    if (adapter->InterruptPending & (R_I_RXOK | R_I_RXERR))
    {
        for (;;)
        {
            NdisRawReadPortUchar(adapter->IoBase + R_CMD, &command);
            if (command & R_CMD_RXEMPTY)
            {
                //
                // The buffer is empty
                //
                adapter->InterruptPending &= ~(R_I_RXOK | R_I_RXERR);
                break;
            }
            
            adapter->ReceiveOffset %= RECEIVE_BUFFER_SIZE;
            
            NDIS_DbgPrint(MAX_TRACE, ("Looking for a packet at offset 0x%x\n",
                            adapter->ReceiveOffset));
            nicHeader = (PPACKET_HEADER)(adapter->ReceiveBuffer + adapter->ReceiveOffset);
            if (!(nicHeader->Status & RSR_ROK))
            {
                //
                // Receive failed
                //
                NDIS_DbgPrint(MIN_TRACE, ("Receive failed: 0x%x\n", nicHeader->Status));
                
                if (nicHeader->Status & RSR_FAE)
                {
                    adapter->ReceiveAlignmentError++;
                }
                else if (nicHeader->Status & RSR_CRC)
                {
                    adapter->ReceiveCrcError++;
                }
                adapter->ReceiveError++;
                
                goto NextPacket;
            }
            
            NDIS_DbgPrint(MAX_TRACE, ("Indicating %d byte packet to NDIS\n",
                           nicHeader->PacketLength - RECV_CRC_LENGTH));
   
            ethHeader = (PETH_HEADER)(nicHeader + 1);
            NdisMEthIndicateReceive(adapter->MiniportAdapterHandle,
                                    NULL,
                                    (PVOID)(ethHeader),
                                    sizeof(ETH_HEADER),
                                    (PVOID)(ethHeader + 1),
                                    nicHeader->PacketLength - sizeof(ETH_HEADER) - RECV_CRC_LENGTH,
                                    nicHeader->PacketLength - sizeof(ETH_HEADER) - RECV_CRC_LENGTH);
            adapter->ReceiveOk++;
            
        NextPacket:
            adapter->ReceiveOffset += nicHeader->PacketLength + sizeof(PACKET_HEADER);
            adapter->ReceiveOffset = (adapter->ReceiveOffset + 3) & ~3;
            NdisRawWritePortUshort(adapter->IoBase + R_CAPR, adapter->ReceiveOffset - 0x10);
            
            if (adapter->InterruptPending & (R_I_RXOVRFLW | R_I_FIFOOVR))
            {
                //
                // We can only clear these interrupts once CAPR has been reset
                //
                NdisRawWritePortUshort(adapter->IoBase + R_IS, R_I_RXOVRFLW | R_I_FIFOOVR);
                adapter->InterruptPending &= ~(R_I_RXOVRFLW | R_I_FIFOOVR);
            }
        }
        
        NdisMEthIndicateReceiveComplete(adapter->MiniportAdapterHandle);
    }
    
    NdisDprReleaseSpinLock(&adapter->Lock);
}
コード例 #7
0
ファイル: int.c プロジェクト: BillTheBest/WinNT4
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//  Routine Name:   NetFlexHandleInterrupt
//
//  Description:
//      This routine is the deferred processing
//      routine for all adapter interrupts.
//
//  Input:
//      acb - Our Driver Context for this adapter or head.
//
//  Output:
//      None
//
//  Called By:
//      Miniport Wrapper
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VOID
NetFlexHandleInterrupt(
    IN NDIS_HANDLE MiniportAdapterContext
    )
{
    USHORT  sifint_reg;
    USHORT  tmp_reg;
    USHORT  ReceivesProcessed = 0;

    PACB acb = (PACB) MiniportAdapterContext;

    //
    // Read the SifInt
    //
    NdisRawReadPortUshort( acb->SifIntPort, &sifint_reg);

    while (sifint_reg & SIFINT_SYSINT)
    {
        //
        // Ack the interrupt
        //
        sifint_reg &= ~SIFINT_SYSINT;
        NdisRawWritePortUshort( acb->SifIntPort, sifint_reg);

        //
        // mask off the int code
        //
        sifint_reg &= INT_CODES;

        //
        // See if there are any recieves to do...
        //
        if (acb->acb_rcv_head->RCV_CSTAT & RCSTAT_COMPLETE)
        {
			//
			//	Increment the interrupt count.
			//
			acb->acb_int_count++;

            //
            // yes, do them...
            //
            acb->handled_interrupts++;
            ReceivesProcessed += acb->ProcessReceiveHandler(acb);
        }

        //
        // See if there are any transmits to do...
        //
		NetFlexProcessXmit(acb);

        switch (sifint_reg)
        {
            case INT_SCBCLEAR:
                acb->acb_scbclearout = FALSE;
                //
                // Is the SCB really clear?
                //
                // If the SCB is clear, send a SCB command off now.
                // Otherwise, if we are not currently waiting for an SCB clear
                // interrupt, signal the adapter to send us a SCB clear interrupt
                // when it is done with the SCB.
                //
                if (acb->acb_scb_virtptr->SCB_Cmd == 0)
                {
                    NetFlexSendNextSCB(acb);
                }
                else if ((acb->acb_xmit_whead) ||
						 (acb->acb_rcv_whead) ||
						 (acb->acb_scbreq_next))
                {
                    acb->acb_scbclearout = TRUE;
                    NdisRawWritePortUshort(
                        acb->SifIntPort,
                        (USHORT)SIFINT_SCBREQST);
                }
                break;

            case INT_COMMAND:
                NetFlexCommand(acb);

                //
                // Do we have any commands to complete?
                //
                if (acb->acb_confirm_qhead != NULL)
                {
                    NetFlexProcessMacReq(acb);
                }
                break;

            case INT_ADPCHECK:
                //
                // Read the Adapter Check Status @ 1.05e0
                //
                NdisRawWritePortUshort(acb->SifAddrxPort, (USHORT) 1);
                NdisRawWritePortUshort(acb->SifAddrPort, (USHORT) 0x5e0);
                NdisRawReadPortUshort( acb->SifDIncPort, &tmp_reg);

                DebugPrint(1,("NF(%d): Adapter Check - 0x%x\n",acb->anum,tmp_reg));

                //
                // Reset has failed, errorlog an entry.
                //

                NdisWriteErrorLogEntry( acb->acb_handle,
                                        EVENT_NDIS_ADAPTER_CHECK_ERROR,
                                        2,
                                        NETFLEX_ADAPTERCHECK_ERROR_CODE,
                                        tmp_reg );

                //
                // Set the variables up showing that the hardware has an unrecoverable
                // error.
                //
                acb->acb_state = AS_HARDERROR;
                break;

            case INT_RINGSTAT:
                NetFlexRingStatus(acb);
                break;

            case INT_RECEIVE:
                break;

            case INT_TRANSMIT:
                //
                //  If we reached the end of the xmit lists,
                //  then the xmit status will indicate COMMAND_COMPLETE.
                //  The transmiter will be stalled until another transmit
                //  command is issued with a valid list.
                //
                if (acb->acb_ssb_virtptr->SSB_Status & XSTAT_LERROR)
                {
					//
					// We have a list error...
					//
					NetFlexTransmitStatus(acb);
                }

            default:
                break;
        }

        //
        // Issue a ssb clear.  After this we may see SIFCMD interrupts.
        //
        NdisRawWritePortUshort(acb->SifIntPort, SIFINT_SSBCLEAR);

        //
        // Read the SifInt
        //
        NdisRawReadPortUshort(acb->SifIntPort, &sifint_reg);
    }

    //
    // Processed any receives which need IndicateReceiveComplete?
    //
    if (ReceivesProcessed)
    {
        if (acb->acb_gen_objs.media_type_in_use == NdisMedium802_5)
        {
            // Token Ring
            //
            NdisMTrIndicateReceiveComplete(acb->acb_handle);
        }
        else
        {
            // Ethernet
            //
            NdisMEthIndicateReceiveComplete(acb->acb_handle);
        }
    }
}
コード例 #8
0
ファイル: int.c プロジェクト: BillTheBest/WinNT4
VOID NetFlexDeferredTimer(
    IN PVOID SystemSpecific1,
    IN PACB  acb,
    IN PVOID SystemSpecific2,
    IN PVOID SystemSpecific3
)
{
    USHORT ReceivesProcessed = 0;
    USHORT sifint_reg;
    UINT   IntAve;

    //
    // Indicate that a timer has expired.
    //
    DebugPrint(3,("NF(%d) - Defered Timer Expired!\n",acb->anum));

    //
    // If we are resetting, get out...
    //
    if (acb->acb_state == AS_RESETTING)
    {
        return;
    }

    //
    // See if there are any recieves to do...
    //

    if (acb->acb_rcv_head->RCV_CSTAT & RCSTAT_COMPLETE)
    {
		//
		//	Increment the interrupt count.
		//
		acb->acb_int_count++;

        // yes, do them...
        //
        ReceivesProcessed = acb->ProcessReceiveHandler(acb);
    }

	//
	//	See if there are any transmits to do...
	//
	NetFlexProcessXmit(acb);

    //
    // Processed any receives which need IndicateReceiveComplete?
    //
    if (ReceivesProcessed)
    {
        if (acb->acb_gen_objs.media_type_in_use == NdisMedium802_5)
        {
            // Token Ring
            //
            NdisMTrIndicateReceiveComplete(acb->acb_handle);
        }
        else
        {
            // Ethernet
            //
            NdisMEthIndicateReceiveComplete(acb->acb_handle);
        }
    }


    if ( ++acb->timer_run_count >= RatioCheckCount )
    {
        acb->timer_run_count = 0;

#ifdef ALLOW_DISABLE_DYNAMIC_RATIO
        if ( EnableDynamicRatio )
        {
#endif

#ifdef NEW_DYNAMIC_RATIO

            //
            // Should we increase the ratio?
            //
            if ( acb->handled_interrupts > RaiseIntThreshold)
            {
                acb->current_run_down = 0;
                if (acb->XmitIntRatio == 1)
                {
                    if ( ++acb->current_run_up > RunThreshold )
                    {
#ifdef XMIT_INTS
                        acb->XmitIntRatio = acb->acb_maxtrans;
#endif
                        acb->acb_gen_objs.interrupt_ratio_changes++;
                        acb->current_run_up = 0;
                        DebugPrint(1,("NF(%d) - RcvIntRatio = %d\n",acb->anum,acb->RcvIntRatio));
                    }
                }
            }
            //
            // Or, should we decrease it?
            //
            else //if ( acb->handled_interrupts < LowerIntThreshold )
            {
                acb->current_run_up = 0;
                if (acb->XmitIntRatio != 1)

                {
                    if ( ++acb->current_run_down > RunThreshold )
                    {

#ifdef XMIT_INTS
                        acb->XmitIntRatio = 1;
#endif
                        acb->acb_gen_objs.interrupt_ratio_changes++;
                        acb->current_run_down = 0;
                        DebugPrint(1,("NF(%d) - RcvIntRatio = %d\n",acb->anum,acb->RcvIntRatio));
                    }
                }
            }

#else   //  !defined(NEW_DYNAMIC_RATIO)

            if ( acb->XmitIntRatio != 1 )
            {
                if ( acb->handled_interrupts < sw21 )
                {
                    if ( ++acb->current_run > RunThreshold )
                    {

#ifdef XMIT_INTS
                        acb->XmitIntRatio = 1;
#endif
                        acb->RcvIntRatio = 1;
                        acb->acb_gen_objs.interrupt_ratio_changes++;
                        acb->current_run = 0;
                        acb->sw24 += 3;

                        acb->cleartime = 0;
                    }
                }
                else
                {
                    acb->current_run = 0;
                }
            }
            else
            {
                if ( acb->handled_interrupts > sw24 )
                {
                    if ( ++acb->current_run > RunThreshold )
                    {

#ifdef XMIT_INTS
                        acb->XmitIntRatio = ratio;
#endif
                        acb->RcvIntRatio = ratio;
                        acb->acb_gen_objs.interrupt_ratio_changes++;
                        acb->current_run = 0;
                    }
                }
                else
                {
                    acb->current_run = 0;
                }
            }

#ifdef DYNAMIC_RATIO_HISTORY
            acb->IntHistory[acb->Hndx] = acb->handled_interrupts;
            acb->RatioHistory[acb->Hndx] = (UCHAR)acb->RcvIntRatio;

            if ( ++acb->Hndx >= 1024 )
            {
                acb->Hndx = 0;
            }
#endif
            //
            // The switchover value to turbo gets incremented each time
            // we drop to normal mode.  We reset this value every x seconds.
            // This will prevent the driver from toggling rapidly between
            // turbo <-> normal mode.
            //
            if ( ++acb->cleartime > 50 )
            {
                acb->sw24 = sw24;
                acb->cleartime = 0;
            }

#endif // !NEW_DYNAMIC_RATIO

#ifdef ALLOW_DISABLE_DYNAMIC_RATIO
        }
        else
        {

#ifdef XMIT_INTS
            acb->XmitIntRatio = ratio;
#endif
            acb->RcvIntRatio = ratio;
        }
#endif // ALLOW_DISABLE_DYNAMIC_RATIO

        acb->acb_gen_objs.interrupt_count = acb->handled_interrupts;
        acb->handled_interrupts = 0;
    }

    //
    // Set the timer...
    //
    NdisMSetTimer(&acb->DpcTimer, 10);

} // NetFlexDeferredTimer