Example #1
0
/******************************************************************************
 * SteMiniportReset()
 *
 *    NDIS Miniport エントリポイント
 *    以下の条件のとき NIC がハングしていると判断しドライバーのソフトステート
 *    をリセットするために呼ばれる。
 *
 *     1) SteMiniportCheckForHang() が TRUE を返してきた
 *     2) 未処理の送信パケットを検出した(シリアライズドドライバのみ)
 *     3) 一定時間内に完了することができなかった未処理の要求があった
 *
 *   この関数の中では以下を行う
 *   
 *     1) キューイングされている送信パケットの処理をやめ、NDIS_STATUS_REQUEST_ABORTED を返す。
 *     2) 上位に通知した全てのパケットがリターンしてきたか確認する。
 *     3) 上記2つに問題がありリセット処理をただちに完了できない場合、ResetTimer をセットし、
 *        NDIS_STATUS_PENDING を返す。

 * 
 * 引数:
 * 
 *    AddressingReset        : マルチキャストや、MAC アドレス、lookahead サイズ
 *                             に変更があった場合にはここを TRUE にしなければならない。
 *                             
 *    MiniportAdapterContext : STE_ADAPTER 構造体のポインタ                  
 * 
 * 
 *   返り値:
 * 
 *     NDIS_STATUS
 * 
 **************************************************************************/
NDIS_STATUS
SteMiniportReset(
    OUT PBOOLEAN     AddressingReset,
    IN  NDIS_HANDLE  MiniportAdapterContext
    )
{
    NDIS_STATUS        Status;
    STE_ADAPTER       *Adapter;
    NDIS_PACKET       *Packet = NULL;

    DEBUG_PRINT0(3, "SteMiniportReset called\n");

    Adapter = (STE_ADAPTER *)MiniportAdapterContext;

    // MAC アドレス、マルチキャストアドレスの変更はない!?ときめつけて FALSE を返す
    *AddressingReset = FALSE;    

    Status = NDIS_STATUS_REQUEST_ABORTED;

    // 送信キューに入っているパケットを処理する
    while (SteGetQueue(&Adapter->SendQueue, &Packet) == NDIS_STATUS_SUCCESS) {
        NdisMSendComplete(
            Adapter->MiniportAdapterHandle,  //IN NDIS_HANDLE   
            Packet,                          //IN PNDIS_PACKET  
            Status                           //IN NDIS_STATUS   
            );
    }

    // 受信キューに入っているパケットを処理する
    while (SteGetQueue(&Adapter->RecvQueue, &Packet) == NDIS_STATUS_SUCCESS) {
        SteFreeRecvPacket(Adapter, Packet);
    }
    // これが終われば、全ての受信パケットがフリーされているはず。
    // 後は上位プロトコルに通知済みでまだ戻ってきていないパケットがあるかどうかを
    // 確認する。

    if (Adapter->RecvIndicatedPackets > 0) {
        // まだ戻ってきてないパケットがあるようだ。
        // リセットタイマーをセットして、後ほど SteResetTimerFunc() から
        // NdisMResetComplete() を呼んでリセットを完了することにする。
        NdisSetTimer(&Adapter->ResetTimer, 300);
        Status = NDIS_STATUS_PENDING;
    } else {
        // リセット操作完了!
        Status = NDIS_STATUS_SUCCESS;
    }

    return(Status);
}
/******************************************************
Required NDIS procedure
Allocates and initializes adapter context
Finally sets send and receive to Enabled state and reports connect
Returns:
NDIS_STATUS	SUCCESS or some error code
*******************************************************/
static NDIS_STATUS ParaNdis5_Initialize(OUT PNDIS_STATUS OpenErrorStatus,
									OUT PUINT SelectedMediumIndex,
									IN PNDIS_MEDIUM MediumArray,
									IN UINT MediumArraySize,
									IN NDIS_HANDLE MiniportAdapterHandle,
									IN NDIS_HANDLE WrapperConfigurationContext)
{
	NDIS_STATUS  status = NDIS_STATUS_UNSUPPORTED_MEDIA;
	PARANDIS_ADAPTER *pContext = NULL;
	UINT i;
	for(i = 0; i < MediumArraySize; ++i)
	{
		if(MediumArray[i] == NdisMedium802_3)
		{
			*SelectedMediumIndex = i;
			status = NDIS_STATUS_SUCCESS;
			break;
		}
	}

	if (status == NDIS_STATUS_SUCCESS)
	{
		pContext =
			(PARANDIS_ADAPTER *)ParaNdis_AllocateMemory(NULL, sizeof(PARANDIS_ADAPTER));
		if (!pContext)
		{
			status = NDIS_STATUS_RESOURCES;
		}
	}

	if (status == NDIS_STATUS_SUCCESS)
	{
		PVOID pResourceList = &status;
		UINT  uSize = 0;
		NdisZeroMemory(pContext, sizeof(PARANDIS_ADAPTER));
		pContext->ulUniqueID = InterlockedIncrement(&gID);
		pContext->DriverHandle = DriverHandle;
		pContext->MiniportHandle = MiniportAdapterHandle;
		pContext->WrapperConfigurationHandle = WrapperConfigurationContext;
		NdisMQueryAdapterResources(&status, WrapperConfigurationContext, pResourceList, &uSize);
		if (uSize > 0)
			pResourceList = ParaNdis_AllocateMemory(MiniportAdapterHandle, uSize);
		else
			pResourceList = NULL;
		if (!pResourceList)
			status = uSize > 0 ? NDIS_STATUS_RESOURCES : NDIS_STATUS_FAILURE;
		else
		{
			ULONG attributes;
			attributes = NDIS_ATTRIBUTE_DESERIALIZE | NDIS_ATTRIBUTE_BUS_MASTER;
			// in XP SP2, if this flag is NOT set, the NDIS halts miniport
			// upon transition to S1..S4.
			// it seems that XP SP3 ignores it and always sends SET_POWER to D3
#ifndef NO_XP_POWER_MANAGEMENT
			attributes |= NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND;
#endif
#ifdef NDIS50_MINIPORT
			//TODO: this is wrong, I think
			// this API is for XP and
			// it should be used only if you never need virtual addresses of sent buffers
			// so I comment it out
			//attributes |= NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS;
#endif
			NdisMSetAttributesEx(
				MiniportAdapterHandle,
				pContext,
				0,
				attributes,
				NdisInterfacePci);
			NdisMQueryAdapterResources(&status, WrapperConfigurationContext, pResourceList, &uSize);
			status = ParaNdis_InitializeContext(pContext, (PNDIS_RESOURCE_LIST)pResourceList);
			NdisFreeMemory(pResourceList, 0, 0);
		}
	}

	if (status == NDIS_STATUS_SUCCESS)
	{
		status = ParaNdis_FinishInitialization(pContext);
		if (status == NDIS_STATUS_SUCCESS)
		{
#ifdef NDIS50_MINIPORT
			NdisMRegisterAdapterShutdownHandler(
				MiniportAdapterHandle,
				pContext,
				(ADAPTER_SHUTDOWN_HANDLER)ParaNdis5_Shutdown);
#endif //NDIS50_MINIPORT
			ParaNdis_DebugRegisterMiniport(pContext, TRUE);
			ParaNdis_IndicateConnect(pContext, FALSE, TRUE);
			ParaNdis5_StopSend(pContext, FALSE, NULL);
			ParaNdis5_StopReceive(pContext, FALSE, NULL);
			if (!pContext->ulMilliesToConnect)
			{
				ParaNdis_ReportLinkStatus(pContext, FALSE);
			}
			else
			{
				NdisSetTimer(&pContext->ConnectTimer, pContext->ulMilliesToConnect);
			}
		}
		else
		{
			ParaNdis_CleanupContext(pContext);
		}
	}

	if (status != NDIS_STATUS_SUCCESS && pContext)
	{
		NdisFreeMemory(pContext, 0, 0);
	}

	DEBUG_EXIT_STATUS(0, status);
	return status;
}
Example #3
0
NDIS_STATUS
LoopSend(
    IN NDIS_HANDLE MacBindingHandle,
    IN PNDIS_PACKET Packet
    )
{
    PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
    PLOOP_OPEN Open = PLOOP_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
    UINT PacketLength;
    NDIS_STATUS StatusToReturn;

    DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, (" --> LoopSend\n"));

    //
    // Verify that the packet is correctly sized for the medium
    //

    NdisQueryPacket(
        Packet,
        NULL,
        NULL,
        NULL,
        &PacketLength
        );

    if ((PacketLength < Adapter->MediumMinPacketLen) ||
        (PacketLength > Adapter->MediumMaxPacketLen))   {

        return NDIS_STATUS_INVALID_PACKET;

        }

    NdisAcquireSpinLock(&Adapter->Lock);
    Adapter->References++;

    if (!Adapter->ResetInProgress)  {

        if (!Open->BindingClosing)  {

            PLOOP_PACKET_RESERVED Reserved = PLOOP_RESERVED_FROM_PACKET(Packet);
            BOOLEAN LoopIt=FALSE;
            PNDIS_BUFFER FirstBuffer;
            PVOID BufferVirtualAddress;
            UINT BufferLength;

            Open->References++;

            Reserved->Next = NULL;
            Reserved->MacBindingHandle = MacBindingHandle;
            Reserved->PacketLength = PacketLength;
            Reserved->HeaderLength = Adapter->MediumMacHeaderLen;

            NdisReleaseSpinLock(&Adapter->Lock);

            NdisQueryPacket(
                Packet,
                NULL,
                NULL,
                &FirstBuffer,
                NULL
                );

            NdisQueryBuffer(
                FirstBuffer,
                &BufferVirtualAddress,
                &BufferLength
                );

            NdisAcquireSpinLock(&Adapter->Lock);

            switch (Adapter->Medium)  {
                case NdisMedium802_3:
                case NdisMediumDix:

                    DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
                        ("Ethernet Dest Addr: %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n",
                        *((PUCHAR)BufferVirtualAddress),*((PUCHAR)BufferVirtualAddress+1),
                        *((PUCHAR)BufferVirtualAddress+2),*((PUCHAR)BufferVirtualAddress+3),
                        *((PUCHAR)BufferVirtualAddress+4),*((PUCHAR)BufferVirtualAddress+5)));

                    LoopIt = EthShouldAddressLoopBack(
                                 Adapter->Filter.Eth,
                                 BufferVirtualAddress
                                 );
                    break;
                case NdisMedium802_5:

                    // check for source routing info and adjust header

                    if (*((PUCHAR)BufferVirtualAddress+8) & 0x80)
                        Reserved->HeaderLength += (*((PUCHAR)BufferVirtualAddress+14) & 0x1f);

                    DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
                        ("TokenRing Dest Addr: %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n",
                        *((PUCHAR)BufferVirtualAddress+2),*((PUCHAR)BufferVirtualAddress+3),
                        *((PUCHAR)BufferVirtualAddress+4),*((PUCHAR)BufferVirtualAddress+5),
                        *((PUCHAR)BufferVirtualAddress+6),*((PUCHAR)BufferVirtualAddress+7)));

                    LoopIt = TrShouldAddressLoopBack(
                                 Adapter->Filter.Tr,
                                 (PCHAR)BufferVirtualAddress+2,
                                 Adapter->CurrentAddress
                                 );

                    if (!LoopIt)  {

                        // check if it's directed at ourselves

                        TR_COMPARE_NETWORK_ADDRESSES_EQ(
                            (PUCHAR)BufferVirtualAddress+2,
                            (PUCHAR)(Adapter->Filter.Tr)->AdapterAddress,
                            &BufferLength
                            );
                        if (!BufferLength)
                            LoopIt = TRUE;
                        }

                    break;
                case NdisMediumFddi:

                    // check the address length bit and adjust the header length
                    //  if it is short.  by default we assume a long address

                    if (!(*((PUCHAR)BufferVirtualAddress) & 0x40))  {
                        Reserved->HeaderLength = 2*FDDI_LENGTH_OF_SHORT_ADDRESS+1;
                        BufferLength = FDDI_LENGTH_OF_SHORT_ADDRESS;
                        }
                    else
                        BufferLength = FDDI_LENGTH_OF_LONG_ADDRESS;

                    // hmmm... the DBGPRINT macro doesn't work too well to
                    //  dump out dest addr of varying lengths

                    DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
                        ("Fddi Dest Addr: L(%d) %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n",BufferLength,
                        *((PUCHAR)BufferVirtualAddress+1),*((PUCHAR)BufferVirtualAddress+2),
                        *((PUCHAR)BufferVirtualAddress+3),*((PUCHAR)BufferVirtualAddress+4),
                        *((PUCHAR)BufferVirtualAddress+5),*((PUCHAR)BufferVirtualAddress+6)));

                    LoopIt = FddiShouldAddressLoopBack(
                                 Adapter->Filter.Fddi,
                                 (PCHAR)BufferVirtualAddress+1,
                                 BufferLength
                                 );
                    break;
                case NdisMediumWan:
                case NdisMediumLocalTalk:
                    DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
                        ("LocalTalk Dest Addr: %.2x\n",((PUCHAR)BufferVirtualAddress)[0]));

                    if ((((PUCHAR)BufferVirtualAddress)[1] == Adapter->CurrentAddress[0]) ||
                         LOOP_LT_IS_BROADCAST(((PUCHAR)BufferVirtualAddress)[0]))
                        LoopIt = TRUE;
                    else
                        LoopIt = FALSE;

                    break;
                case NdisMediumArcnet878_2:

                    DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
                        ("Arcnet Dest Addr: %.2x\n",((PUCHAR)BufferVirtualAddress)[1]));

                    if ((((PUCHAR)BufferVirtualAddress)[1] == Adapter->CurrentAddress[0]) ||
                         LOOP_ARC_IS_BROADCAST(((PUCHAR)BufferVirtualAddress)[1]))
                        LoopIt = TRUE;
                    else
                        LoopIt = FALSE;

                    break;
                default:
                    // we should never get here...
                    ASSERT(FALSE);
                    break;
                }

            DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, ("LoopIt = %c\n",(LoopIt)?'Y':'N'));

            if (LoopIt)  {

                DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
                    ("Queueing packet %lx for loopback\n",Packet));

                if (Adapter->LastLoopback == NULL)
                    Adapter->Loopback = Packet;
                else
                    PLOOP_RESERVED_FROM_PACKET(Adapter->LastLoopback)->Next = Packet;
                Adapter->LastLoopback = Packet;

                StatusToReturn = NDIS_STATUS_PENDING;

                }
            else  {
                //
                // Since we're not looping this packet back, there's
                // nothing for us to do.  just return success and make
                // like the packet was successfully sent out
                //

                Adapter->GeneralMandatory[GM_TRANSMIT_GOOD]++;
                Open->References--;
                StatusToReturn = NDIS_STATUS_SUCCESS;
                }
            }
        else
            StatusToReturn = NDIS_STATUS_CLOSING;

        }
    else
        StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;

    Adapter->References--;

    // might not queue a packet, but setting the timer anyway ensures
    // we don't miss any packets sitting in the queue

    if (!Adapter->TimerSet)  {
        Adapter->TimerSet = TRUE;
        NdisReleaseSpinLock(&Adapter->Lock);
        NdisSetTimer(
            &Adapter->LoopTimer,
            25
            );
        }
    else
        NdisReleaseSpinLock(&Adapter->Lock);

    return StatusToReturn;
}
Example #4
0
STATIC
VOID
LoopProcessLoopback(
    PLOOP_ADAPTER Adapter
    )
{
    PNDIS_PACKET LoopPacket;
    PLOOP_PACKET_RESERVED Reserved;
    PLOOP_OPEN Open;
    UINT BufferLength;
    UINT IndicateLen;
    UINT AddressType;
    UCHAR DestAddress[FDDI_LENGTH_OF_LONG_ADDRESS];

    DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO, (" --> LoopProcessLoopback\n"));

    while ((Adapter->Loopback != NULL) && !Adapter->ResetInProgress)  {

        // dequeue the packet at the head of the loopback queue

        LoopPacket = Adapter->Loopback;
        Adapter->CurrentLoopback = LoopPacket;
        Reserved = PLOOP_RESERVED_FROM_PACKET(LoopPacket);
        Adapter->Loopback = Reserved->Next;
        if (Adapter->Loopback == NULL)
            Adapter->LastLoopback = NULL;

        DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO, ("Dequeued packet %lx\n",LoopPacket));

        IndicateLen = (Reserved->PacketLength > Adapter->MaxLookAhead) ?
                       Adapter->MaxLookAhead : Reserved->PacketLength;

        Adapter->GeneralMandatory[GM_RECEIVE_GOOD]++;
        NdisDprReleaseSpinLock(&Adapter->Lock);

        LoopCopyFromPacketToBuffer(
            LoopPacket,
            0,
            IndicateLen,
            Adapter->LoopBuffer,
            &BufferLength
            );

        // indicate the packet as appropriate

        switch (Adapter->Medium)  {
            case NdisMedium802_3:
            case NdisMediumDix:
                EthFilterIndicateReceive(
                    Adapter->Filter.Eth,
                    (NDIS_HANDLE)NULL,
                    (PCHAR)Adapter->LoopBuffer,
                    Adapter->LoopBuffer,
                    Reserved->HeaderLength,
                    (Adapter->LoopBuffer)+(Reserved->HeaderLength),
                    IndicateLen-(Reserved->HeaderLength),
                    (Reserved->PacketLength)-(Reserved->HeaderLength)
                    );
                break;
            case NdisMedium802_5:
                TrFilterIndicateReceive(
                    Adapter->Filter.Tr,
                    (NDIS_HANDLE)NULL,
                    Adapter->LoopBuffer,
                    Reserved->HeaderLength,
                    (Adapter->LoopBuffer)+(Reserved->HeaderLength),
                    IndicateLen-(Reserved->HeaderLength),
                    (Reserved->PacketLength)-(Reserved->HeaderLength)
                    );
                break;
            case NdisMediumFddi:

                // just copy over the long address size, even though it may
                // be a short address

                NdisMoveMemory(
                    DestAddress,
                    Adapter->LoopBuffer+1,
                    FDDI_LENGTH_OF_LONG_ADDRESS
                    );

                FddiFilterIndicateReceive(
                    Adapter->Filter.Fddi,
                    (NDIS_HANDLE)NULL,
                    (PCHAR)DestAddress,
                    ((*(Adapter->LoopBuffer) & 0x40) ? FDDI_LENGTH_OF_LONG_ADDRESS :
                                                       FDDI_LENGTH_OF_SHORT_ADDRESS),
                    Adapter->LoopBuffer,
                    Reserved->HeaderLength,
                    (Adapter->LoopBuffer)+(Reserved->HeaderLength),
                    IndicateLen-(Reserved->HeaderLength),
                    (Reserved->PacketLength)-(Reserved->HeaderLength)
                    );
                break;
            case NdisMediumLocalTalk:
                if (LOOP_LT_IS_BROADCAST(Adapter->LoopBuffer[0]))
                    AddressType = NDIS_PACKET_TYPE_BROADCAST;
                else
                    AddressType = NDIS_PACKET_TYPE_DIRECTED;

                LtIndicateReceive(
                    Adapter,
                    AddressType,
                    Adapter->LoopBuffer,
                    Reserved->HeaderLength,
                    (Adapter->LoopBuffer)+(Reserved->HeaderLength),
                    IndicateLen-(Reserved->HeaderLength),
                    (Reserved->PacketLength)-(Reserved->HeaderLength)
                    );
                break;
            case NdisMediumArcnet878_2:
                if (LOOP_ARC_IS_BROADCAST(Adapter->LoopBuffer[1]))
                    AddressType = NDIS_PACKET_TYPE_BROADCAST;
                else
                    AddressType = NDIS_PACKET_TYPE_DIRECTED;

                LtIndicateReceive(
                    Adapter,
                    AddressType,
                    Adapter->LoopBuffer,
                    Reserved->HeaderLength,
                    (Adapter->LoopBuffer)+(Reserved->HeaderLength),
                    IndicateLen-(Reserved->HeaderLength),
                    (Reserved->PacketLength)-(Reserved->HeaderLength)
                    );
                break;
            default:
                ASSERT(FALSE);    // should never get here
                break;
            }

        // complete the send

        Open = PLOOP_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO,
            ("Completing Send for binding %lx\n",Open));
        NdisCompleteSend(
            Open->NdisBindingContext,
            LoopPacket,
            NDIS_STATUS_SUCCESS
            );
        NdisDprAcquireSpinLock(&Adapter->Lock);
        Adapter->GeneralMandatory[GM_TRANSMIT_GOOD]++;
        // remove reference for send just completed
        Open->References--;
        }

    // rearm timer if there are still packets to loop back and the timer is
    //  not already ticking away

    if (Adapter->Loopback != NULL && !Adapter->TimerSet)  {
        DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO, ("More packets to loopback\n"));
        Adapter->TimerSet = TRUE;
        NdisDprReleaseSpinLock(&Adapter->Lock);
        NdisSetTimer(
            &Adapter->LoopTimer,
            25
            );
        NdisDprAcquireSpinLock(&Adapter->Lock);
        }

    // issue indicate receive completes as necessary

    switch (Adapter->Medium)  {
        case NdisMedium802_3:
        case NdisMediumDix:
            NdisDprReleaseSpinLock(&Adapter->Lock);
            EthFilterIndicateReceiveComplete(Adapter->Filter.Eth);
            NdisDprAcquireSpinLock(&Adapter->Lock);
            break;
        case NdisMedium802_5:
            NdisDprReleaseSpinLock(&Adapter->Lock);
            TrFilterIndicateReceiveComplete(Adapter->Filter.Tr);
            NdisDprAcquireSpinLock(&Adapter->Lock);
            break;
        case NdisMediumFddi:
            NdisDprReleaseSpinLock(&Adapter->Lock);
            FddiFilterIndicateReceiveComplete(Adapter->Filter.Fddi);
            NdisDprAcquireSpinLock(&Adapter->Lock);
            break;
        case NdisMediumLocalTalk:
        case NdisMediumArcnet878_2:
            NdisDprReleaseSpinLock(&Adapter->Lock);
            LtIndicateReceiveComplete(Adapter);
            NdisDprAcquireSpinLock(&Adapter->Lock);
            break;
        default:
            ASSERT(FALSE);
            break;
        }
}
Example #5
0
NDIS_STATUS
LtInitRegisterAdapter(
	IN NDIS_HANDLE 			LtMacHandle,
	IN NDIS_HANDLE 			WrapperConfigurationContext,
	IN PNDIS_STRING 		AdapterName,
	IN NDIS_INTERFACE_TYPE 	BusType,
	IN UCHAR				SuggestedNodeId,
	IN UINT 				IoBaseAddress,
	IN UINT 				MaxAdapters,
	IN NDIS_STATUS			ConfigError
	)
/*++

Routine Description:

	This routine (and its interface) are not portable.  They are
	defined by the OS, the architecture, and the particular Lt
	implementation.

	This routine is responsible for the allocation of the datastructures
	for the driver as well as any hardware specific details necessary
	to talk with the device.

Arguments:

	LtMacHandle		:	The handle given back to the mac from ndis when
						the mac registered itself.

	WrapperConfigurationContext
					:	configuration context passed in by NDIS in the AddAdapter
						call.

	AdapterName		:	The string containing the name to give to the device adapter.
	BusType 		:	The type of bus in use. (MCA, ISA, EISA ...)
	IoBaseAddress 	:	The base IO address of the card.
	MaxAdapters 	:	The maximum number of opens at any one time.
	ConfigError		:	Error with the Config parameters if any.

Return Value:

	NDIS_STATUS_SUCCESS	: 	If successful, error otherwise.

--*/
{
	// Pointer for the adapter root.
	PLT_ADAPTER 	Adapter;
	NDIS_STATUS 	Status, RefStatus;
	NDIS_ERROR_CODE	LogErrorCode;

	// Holds information needed when registering the adapter.
	NDIS_ADAPTER_INFORMATION AdapterInformation;

	// Allocate the Adapter block.
	NdisAllocateMemory(
		(PVOID)&Adapter,
		sizeof(LT_ADAPTER),
		0,
		LtNdisPhyAddr);

	if (Adapter == NULL)
	{
		return(NDIS_STATUS_RESOURCES);
	}

	NdisZeroMemory(
		Adapter,
		sizeof(LT_ADAPTER));

	Adapter->NdisMacHandle = LtMacHandle;

	// Set up the AdapterInformation structure.
	NdisZeroMemory (&AdapterInformation, sizeof(NDIS_ADAPTER_INFORMATION));

	AdapterInformation.DmaChannel 						= 0;
	AdapterInformation.Master 							= FALSE ;
	AdapterInformation.Dma32BitAddresses 				= FALSE ;
	AdapterInformation.AdapterType 						= BusType ;
	AdapterInformation.PhysicalMapRegistersNeeded 		= 0;
	AdapterInformation.MaximumPhysicalMapping 			= 0;
	AdapterInformation.NumberOfPortDescriptors 			= 1 ;
	AdapterInformation.PortDescriptors[0].InitialPort 	= IoBaseAddress;
	AdapterInformation.PortDescriptors[0].NumberOfPorts	= 4;
	AdapterInformation.PortDescriptors[0].PortOffset	= (PVOID *)(&(Adapter->MappedIoBaseAddr));

	DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
			("LtInitRegisterAdapter: IoBaseAddr %lx\n", IoBaseAddress));

	// Register the adapter with NDIS.
	if ((Status = NdisRegisterAdapter(
						&Adapter->NdisAdapterHandle,
						Adapter->NdisMacHandle,
						Adapter,
						WrapperConfigurationContext,
						AdapterName,
						&AdapterInformation)) != NDIS_STATUS_SUCCESS)
	{
		//	Could not register the adapter, so we cannot log any errors
		//	either.
		DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_FATAL,
				("LtInitRegisterAdapter: Failed %lx\n", Status));

		//	Free up the memory allocated.
		NdisFreeMemory(
			Adapter,
			sizeof(LT_ADAPTER),
			0);

		return(Status);
	}

	DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
			("LtInitRegisterAdapter: MappedIoBaseAddr %lx\n", Adapter->MappedIoBaseAddr));

	do
	{
		//	Ok. We are all set.
		Adapter->BusType 		= BusType;

		InitializeListHead(&Adapter->Request);
		InitializeListHead(&Adapter->OpenBindings);

		InitializeListHead(&Adapter->LoopBack);
		InitializeListHead(&Adapter->Transmit);
		InitializeListHead(&Adapter->Receive);

		NdisAllocateSpinLock(&Adapter->Lock);

		Adapter->OpenCount 	= 0;

		//	Set refcount to 1 - creation
		Adapter->RefCount	= 1;	

		NdisInitializeTimer(
			&Adapter->PollingTimer,
			LtTimerPoll,
			(PVOID)Adapter);

		//	If there were no configuration errors, then go ahead with the
		//	initialize.

		if (ConfigError == NDIS_STATUS_SUCCESS)
		{
			// Start the card up. This writes an error
			// log entry if it fails.
			if (LtFirmInitialize(Adapter, SuggestedNodeId))
			{
				//	Ok, the firmware code has been downloaded to the card.
				//	Start the poll timer. We should do this before we call
				//	GetAddress. Add a reference for the timer.
				NdisAcquireSpinLock(&Adapter->Lock);
				LtReferenceAdapterNonInterlock(Adapter, &RefStatus);

				ASSERTMSG("LtInitRegisterAdapter: RefAdater Failed!\n",
						 (RefStatus == NDIS_STATUS_SUCCESS));

				Adapter->Flags |= ADAPTER_TIMER_QUEUED;
				NdisSetTimer(&Adapter->PollingTimer, LT_POLLING_TIME);
				NdisReleaseSpinLock(&Adapter->Lock);
				break;
			}

			LogErrorCode = NDIS_ERROR_CODE_HARDWARE_FAILURE;

		}
		else
		{
			LogErrorCode = NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER;
		}


		//	We either could not initialize the hardware or get the node
		//	address. OR there was a config error. Log it and deregister
		//	the adapter.
		LOGERROR(Adapter->NdisAdapterHandle, LogErrorCode);

		//	Deregister the adapter. This calls LtInitRemoveAdapter which
		//	will do all necessary cleanup.
		NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
				
		Status = NDIS_STATUS_FAILURE;
		break;

	} while (FALSE);

	return(Status);
}
Example #6
0
VOID
NdisMlidStatisticTimer(
    IN PVOID SystemSpecific1,
    IN PVOID Context,
    IN PVOID SystemSpecific2,
    IN PVOID SystemSpecific3
    )

/*++

Routine Description:

    This DPC routine is queued to gather statistics from then
    NDIS MAC.

Arguments:

    Context - Really a pointer to the MLID.

Return Value:

    None.

--*/
{
    PMLID_STRUCT Mlid = (PMLID_STRUCT)Context;
    PNDIS_REQUEST NdisMlidRequest = &(Mlid->StatsTable->NdisRequest);
    NDIS_STATUS NdisStatus;

    NdisAcquireSpinLock(&(Mlid->MlidSpinLock));

    //
    // Loop
    //
    while (TRUE) {

        //
        // Set up NdisRequest
        //
        NdisMlidRequest->RequestType = NdisRequestQueryInformation;

        switch (Mlid->NdisMlidMedium) {

            case NdisMedium802_3:

                switch (Mlid->StatsTable->StatisticNumber) {

                    case 0:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_3_XMIT_ONE_COLLISION;
                        break;

                    case 1:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_3_XMIT_MORE_COLLISIONS;
                        break;

                    case 2:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_3_XMIT_DEFERRED;
                        break;

                    case 3:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_3_XMIT_LATE_COLLISIONS;
                        break;

                    case 4:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_3_XMIT_MAX_COLLISIONS;
                        break;

                    case 5:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_3_XMIT_TIMES_CRS_LOST;
                        break;

                    case 6:
                        goto DoNextStatistic;

                    case 7:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_3_RCV_ERROR_ALIGNMENT;
                        break;

                }

                break;

            case NdisMedium802_5:
                switch (Mlid->StatsTable->StatisticNumber) {

                    case 0:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_5_AC_ERRORS;
                        break;

                    case 1:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_5_ABORT_DELIMETERS;
                        break;

                    case 2:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_5_BURST_ERRORS;
                        break;

                    case 3:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_5_FRAME_COPIED_ERRORS;
                        break;

                    case 4:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_5_FREQUENCY_ERRORS;
                        break;

                    case 5:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_5_INTERNAL_ERRORS;
                        break;

                    case 6:

                        goto DoNextStatistic;

                    case 7:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_5_LINE_ERRORS;
                        break;

                    case 8:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_5_LOST_FRAMES;
                        break;

                    case 9:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                                 OID_802_5_TOKEN_ERRORS;
                        break;

                    case 10:
                    case 11:
                    case 12:

                        goto DoNextStatistic;

                }

                break;

            case NdisMediumFddi:

                switch (Mlid->StatsTable->StatisticNumber) {

                    case 0:
                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                            OID_FDDI_ATTACHMENT_TYPE;

                        break;

                    case 1:
                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                            OID_FDDI_UPSTREAM_NODE_LONG;

                        break;

                    case 2:
                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                            OID_FDDI_DOWNSTREAM_NODE_LONG;

                        break;

                    case 3:
                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                            OID_FDDI_FRAME_ERRORS;

                        break;

                    case 4:
                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                            OID_FDDI_FRAMES_LOST;

                        break;

                    case 5:
                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                            OID_FDDI_RING_MGT_STATE;

                        break;

                    case 6:
                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                            OID_FDDI_LCT_FAILURES;

                        break;

                    case 7:
                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                            OID_FDDI_LEM_REJECTS;

                        break;

                    case 8: // LemCount

                        goto DoNextStatistic;

                    case 9:

                        NdisMlidRequest->DATA.QUERY_INFORMATION.Oid =
                            OID_FDDI_LCONNECTION_STATE;

                        break;

                    default:

                        goto DoNextStatistic;
                }

                break;

        }

        NdisMlidRequest->DATA.QUERY_INFORMATION.InformationBuffer =
               (PVOID)&(Mlid->StatsTable->StatisticValue);
        NdisMlidRequest->DATA.QUERY_INFORMATION.InformationBufferLength =
               sizeof(Mlid->StatsTable->StatisticValue);
        NdisMlidRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
        NdisMlidRequest->DATA.QUERY_INFORMATION.BytesNeeded = 0;

        NdisReleaseSpinLock(&(Mlid->MlidSpinLock));

        NdisRequest(
            &NdisStatus,
            Mlid->NdisBindingHandle,
            NdisMlidRequest
            );

        //
        // if (pending), exit.
        //

        if (NdisStatus == NDIS_STATUS_PENDING) {

            return;

        }

        NdisAcquireSpinLock(&(Mlid->MlidSpinLock));

        if (NdisStatus == NDIS_STATUS_SUCCESS) {

            //
            // Store Statistic
            //
            (*((PUINT32)((*(Mlid->StatsTable->StatsTable.MMediaCountsPtr))
                [
                Mlid->StatsTable->StatisticNumber
                ].StatCounter))) =
                Mlid->StatsTable->StatisticValue;

        }

DoNextStatistic:

        Mlid->StatsTable->StatisticNumber++;


        switch (Mlid->NdisMlidMedium) {

            case NdisMedium802_3:

                if (Mlid->StatsTable->StatisticNumber >= NUM_ETHERNET_COUNTS) {
                    Mlid->StatsTable->StatisticNumber = 0;
                }

                break;

            case NdisMedium802_5:

                if (Mlid->StatsTable->StatisticNumber >= NUM_TOKEN_RING_COUNTS) {
                    Mlid->StatsTable->StatisticNumber = 0;
                }

                break;

            case NdisMediumFddi:

                if (Mlid->StatsTable->StatisticNumber >= NUM_FDDI_COUNTS) {
                    Mlid->StatsTable->StatisticNumber = 0;
                }

                break;

        }

        if (Mlid->StatsTable->StatisticNumber == 0) {

            //
            // Set timer for 30 seconds from now.
            //
            NdisReleaseSpinLock(&(Mlid->MlidSpinLock));

            NdisSetTimer(&(Mlid->StatsTable->StatisticTimer), 30000);

            return;

        }

    }

}