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;
}
Ejemplo n.º 2
0
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//  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);
        }
    }
}
Ejemplo n.º 3
0
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