⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ne2000.c

📁 自制PDA系列之PCMCIA接口驱动(处理器PXA270)
💻 C
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:

    ne2000.c

Abstract:

    This is the main file for the Novel 2000 Ethernet controller.
    This driver conforms to the NDIS 3.0 miniport interface.

--*/

#include "precomp.h"


//
// On debug builds tell the compiler to keep the symbols for
// internal functions, otw throw them out.
//
#if DBG
#define STATIC
#else
#define STATIC static
#endif

//
// Debugging definitions
//
#if DBG

//
// Default debug mode
//
ULONG Ne2000DebugFlag = 
                       NE2000_DEBUG_LOUD
                       | NE2000_DEBUG_VERY_LOUD
                       // | NE2000_DEBUG_LOG
                       // | NE2000_DEBUG_CHECK_DUP_SENDS
                       // | NE2000_DEBUG_TRACK_PACKET_LENS
                       // | NE2000_DEBUG_WORKAROUND1
                       // | NE2000_DEBUG_CARD_BAD
                       // | NE2000_DEBUG_CARD_TESTS 
                       ;

//
// Debug tracing defintions
//
#define NE2000_LOG_SIZE 256
UCHAR Ne2000LogBuffer[NE2000_LOG_SIZE]={0};
UINT Ne2000LogLoc = 0;

extern
VOID
Ne2000Log(UCHAR c) {

    Ne2000LogBuffer[Ne2000LogLoc++] = c;

	Ne2000LogBuffer[(Ne2000LogLoc + 4) % NE2000_LOG_SIZE] = '\0';

	if (Ne2000LogLoc >= NE2000_LOG_SIZE)
		Ne2000LogLoc = 0;
}

#endif



//
// This constant is used for places where NdisAllocateMemory
// needs to be called and the HighestAcceptableAddress does
// not matter.
//
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
    NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);

//
// The global Miniport driver block.
//

DRIVER_BLOCK Ne2000MiniportBlock={0};

//
// List of supported OID for this driver.
//
STATIC UINT Ne2000SupportedOids[] = {
    OID_GEN_SUPPORTED_LIST,
    OID_GEN_HARDWARE_STATUS,
    OID_GEN_MEDIA_SUPPORTED,
    OID_GEN_MEDIA_IN_USE,
    OID_GEN_MAXIMUM_LOOKAHEAD,
    OID_GEN_MAXIMUM_FRAME_SIZE,
    OID_GEN_MAXIMUM_TOTAL_SIZE,
    OID_GEN_MAC_OPTIONS,
    OID_GEN_PROTOCOL_OPTIONS,
    OID_GEN_LINK_SPEED,
    OID_GEN_TRANSMIT_BUFFER_SPACE,
    OID_GEN_RECEIVE_BUFFER_SPACE,
    OID_GEN_TRANSMIT_BLOCK_SIZE,
    OID_GEN_RECEIVE_BLOCK_SIZE,
    OID_GEN_VENDOR_DESCRIPTION,
    OID_GEN_VENDOR_ID,
    OID_GEN_DRIVER_VERSION,
    OID_GEN_CURRENT_PACKET_FILTER,
    OID_GEN_CURRENT_LOOKAHEAD,
    OID_GEN_XMIT_OK,
    OID_GEN_RCV_OK,
    OID_GEN_XMIT_ERROR,
    OID_GEN_RCV_ERROR,
    OID_GEN_RCV_NO_BUFFER,
    OID_802_3_PERMANENT_ADDRESS,
    OID_802_3_CURRENT_ADDRESS,
    OID_802_3_MULTICAST_LIST,
    OID_802_3_MAXIMUM_LIST_SIZE,
    OID_802_3_RCV_ERROR_ALIGNMENT,
    OID_802_3_XMIT_ONE_COLLISION,
    OID_802_3_XMIT_MORE_COLLISIONS
    };

//
// Determines whether failing the initial card test will prevent
// the adapter from being registered.
//
#ifdef CARD_TEST

BOOLEAN InitialCardTest = TRUE;

#else  // CARD_TEST

BOOLEAN InitialCardTest = FALSE;

#endif // CARD_TEST

NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    );

BOOL SearchPCIConfig (DWORD *pIoBaseAddr, PCHAR pIRQNum,
                      DWORD PCIBaseClass, DWORD PCISubClass);


#pragma NDIS_INIT_FUNCTION(DriverEntry)


NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This is the primary initialization routine for the NE2000 driver.
    It is simply responsible for the intializing the wrapper and registering
    the Miniport driver.  It then calls a system and architecture specific
    routine that will initialize and register each adapter.

Arguments:

    DriverObject - Pointer to driver object created by the system.

    RegistryPath - Path to the parameters for this driver in the registry.

Return Value:

    The status of the operation.

--*/

{


    //
    // Receives the status of the NdisMRegisterMiniport operation.
    //
    NDIS_STATUS Status;

    //
    // Characteristics table for this driver.
    //
    NDIS_MINIPORT_CHARACTERISTICS NE2000Char;

    //
    // Pointer to the global information for this driver
    //
    PDRIVER_BLOCK NewDriver = &Ne2000MiniportBlock;

    //
    // Handle for referring to the wrapper about this driver.
    //
    NDIS_HANDLE NdisWrapperHandle;
	return STATUS_SUCCESS;

#if NDIS_WIN
    UCHAR pIds[sizeof (EISA_MCA_ADAPTER_IDS) + 3 * sizeof (USHORT)];
    ((PEISA_MCA_ADAPTER_IDS)pIds)->nEisaAdapters=0;
    ((PEISA_MCA_ADAPTER_IDS)pIds)->nMcaAdapters=3;
    *((PUSHORT)(((PEISA_MCA_ADAPTER_IDS)pIds)->IdArray) + 0)=AE2_ADAPTER_ID;
    *((PUSHORT)(((PEISA_MCA_ADAPTER_IDS)pIds)->IdArray) + 1)=UB_ADAPTER_ID;
    *((PUSHORT)(((PEISA_MCA_ADAPTER_IDS)pIds)->IdArray) + 2)=NE2_ADAPTER_ID;
    (PVOID) DriverObject = (PVOID) pIds;

#endif

    DEBUGMSG(1,
        (TEXT("+NE2000:DriverEntry YI\n")));
	

    //
    // Initialize the wrapper.
    //
    NdisMInitializeWrapper(
                &NdisWrapperHandle,
                DriverObject,
                RegistryPath,
                NULL
                );

    //
    // Save the global information about this driver.
    //
    NewDriver->NdisWrapperHandle = NdisWrapperHandle;
    NewDriver->AdapterQueue = (PNE2000_ADAPTER)NULL;

    //
    // Initialize the Miniport characteristics for the call to
    // NdisMRegisterMiniport.
    //
    memset(&NE2000Char,0,sizeof(NE2000Char));
    NE2000Char.MajorNdisVersion = NE2000_NDIS_MAJOR_VERSION;
    NE2000Char.MinorNdisVersion = NE2000_NDIS_MINOR_VERSION;
    NE2000Char.CheckForHangHandler = NULL;
    NE2000Char.DisableInterruptHandler = Ne2000DisableInterrupt;
    NE2000Char.EnableInterruptHandler = Ne2000EnableInterrupt;
    NE2000Char.HaltHandler = Ne2000Halt;
    NE2000Char.HandleInterruptHandler = Ne2000HandleInterrupt;
    NE2000Char.InitializeHandler = Ne2000Initialize;
    NE2000Char.ISRHandler = Ne2000Isr;
    NE2000Char.QueryInformationHandler = Ne2000QueryInformation;
    NE2000Char.ReconfigureHandler = NULL;
    NE2000Char.ResetHandler = Ne2000Reset;
    NE2000Char.SendHandler = Ne2000Send;
    NE2000Char.SetInformationHandler = Ne2000SetInformation;
    NE2000Char.TransferDataHandler = Ne2000TransferData;

    Status = NdisMRegisterMiniport(
                 NdisWrapperHandle,
                 &NE2000Char,
                 sizeof(NE2000Char)
                 );

    if (Status == NDIS_STATUS_SUCCESS) {
		DEBUGMSG(1,
				 (TEXT("-NE2000:DriverEntry: Success\n")));
        return STATUS_SUCCESS;

    }

	// Terminate the wrapper.
	NdisTerminateWrapper (Ne2000MiniportBlock.NdisWrapperHandle, NULL);
	Ne2000MiniportBlock.NdisWrapperHandle = NULL;

    DEBUGMSG(1,
        (TEXT("-NE2000:DriverEntry: Unsuccessful\n")));
    return STATUS_UNSUCCESSFUL;

}


#pragma NDIS_PAGEABLE_FUNCTION(Ne2000Initialize)
extern
NDIS_STATUS
Ne2000Initialize(
    OUT PNDIS_STATUS OpenErrorStatus,
    OUT PUINT SelectedMediumIndex,
    IN PNDIS_MEDIUM MediumArray,
    IN UINT MediumArraySize,
    IN NDIS_HANDLE MiniportAdapterHandle,
    IN NDIS_HANDLE ConfigurationHandle
    )

/*++

Routine Description:

    Ne2000Initialize starts an adapter and registers resources with the
    wrapper.

Arguments:

    OpenErrorStatus - Extra status bytes for opening token ring adapters.

    SelectedMediumIndex - Index of the media type chosen by the driver.

    MediumArray - Array of media types for the driver to chose from.

    MediumArraySize - Number of entries in the array.

    MiniportAdapterHandle - Handle for passing to the wrapper when
       referring to this adapter.

    ConfigurationHandle - A handle to pass to NdisOpenConfiguration.

Return Value:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_PENDING

--*/

{
    //
    // Pointer to our newly allocated adapter.
    //
    PNE2000_ADAPTER Adapter;

    //
    // The handle for reading from the registry.
    //
    NDIS_HANDLE ConfigHandle;

    //
    // The value read from the registry.
    //
    PNDIS_CONFIGURATION_PARAMETER ReturnedValue;

    //
    // String names of all the parameters that will be read.
    //
    NDIS_STRING IOAddressStr = IOADDRESS;
    NDIS_STRING InterruptStr = INTERRUPT;
    NDIS_STRING MaxMulticastListStr = MAX_MULTICAST_LIST;
    NDIS_STRING NetworkAddressStr = NETWORK_ADDRESS;
    NDIS_STRING BusTypeStr = NDIS_STRING_CONST("BusType");

    //
    // TRUE if there is a configuration error.
    //
    BOOLEAN ConfigError = FALSE;

    //
    // A special value to log concerning the error.
    //
    ULONG ConfigErrorValue = 0;

    //
    // The slot number the adapter is located in, used for
    // Microchannel adapters.
    //
    UINT SlotNumber = 0;

    //
    // TRUE if it is unnecessary to read the Io Base Address
    // and Interrupt from the registry.  Used for Microchannel
    // adapters, which get this information from the slot
    // information.
    //
    BOOLEAN SkipIobaseAndInterrupt = FALSE;

    //
    // The network address the adapter should use instead of the
    // the default burned in address.
    //
    PVOID NetAddress;

    //
    // The number of bytes in the address.  It should be
    // NE2000_LENGTH_OF_ADDRESS
    //
    ULONG Length;

    //
    // These are used when calling Ne2000RegisterAdapter.
    //

    //
    // The physical address of the base I/O port.
    //
    PVOID IoBaseAddr;

    //
    // The interrupt number to use.
    //
    CCHAR InterruptNumber;

    //
    // The number of multicast address to be supported.
    //
    UINT MaxMulticastList;

    //
    // Temporary looping variable.
    //
    ULONG i;

    //
    // Status of Ndis calls.
    //
    NDIS_STATUS Status;

//    NDIS_MCA_POS_DATA McaData;
    return NDIS_STATUS_SUCCESS;
    //
    // Search for the medium type (802.3) in the given array.
    //
    for (i = 0; i < MediumArraySize; i++){

        if (MediumArray[i] == NdisMedium802_3){

            break;

        }

    }

    if (i == MediumArraySize){
        DEBUGMSG(1,
            (TEXT("NE2000:Initialize: No supported media\n")));
        return( NDIS_STATUS_UNSUPPORTED_MEDIA );

    }

    *SelectedMediumIndex = i;


    //
    // Set default values.
    //
    IoBaseAddr = DEFAULT_IOBASEADDR;
    InterruptNumber = DEFAULT_INTERRUPTNUMBER;
    MaxMulticastList = DEFAULT_MULTICASTLISTMAX;

    //
    // Allocate memory for the adapter block now.
    //
    Status = NdisAllocateMemory( (PVOID *)&Adapter,
                   sizeof(NE2000_ADAPTER),
                   0,
                   HighestAcceptableMax
                   );

    if (Status != NDIS_STATUS_SUCCESS) {

        DEBUGMSG(1,
            (TEXT("NE2000:Initialize: NdisAllocateMemory(NE2000_ADAPTER) failed\n")));
        return Status;

    }

    //
    // Clear out the adapter block, which sets all default values to FALSE,
    // or NULL.
    //
    NdisZeroMemory (Adapter, sizeof(NE2000_ADAPTER));

    //
    // Open the configuration space.
    //
    NdisOpenConfiguration(
            &Status,
            &ConfigHandle,
            ConfigurationHandle
            );

    if (Status != NDIS_STATUS_SUCCESS) {

        NdisFreeMemory(Adapter, sizeof(NE2000_ADAPTER), 0);

        DEBUGMSG(1,
            (TEXT("NE2000:Initialize: NdisOpenconfiguration failed 0x%x\n"),
            Status));
        return Status;

    }

    //
    // Read net address
    //
    NdisReadNetworkAddress(
                    &Status,
                    &NetAddress,
                    &Length,
                    ConfigHandle
                    );

    if ((Length == NE2000_LENGTH_OF_ADDRESS) &&
        (Status == NDIS_STATUS_SUCCESS)) {

        //
        // Save the address that should be used.
        //
        NdisMoveMemory(
                Adapter->StationAddress,
                NetAddress,
                NE2000_LENGTH_OF_ADDRESS
                );

    }

#if NDIS_NT
    //
    // Disallow multiple adapters in the same MP machine because of hardware
    // problems this results in random packet corruption.
    //
    if ((NdisSystemProcessorCount() > 1) &&
        (Ne2000MiniportBlock.AdapterQueue != NULL)) {

        ConfigError = TRUE;
        ConfigErrorValue = (ULONG)NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION;
        DEBUGMSG(1,
            (TEXT("NE2000:Initialize: Invalid MP config\n")));
        goto RegisterAdapter;
    }
#endif


    //
    // Read Bus Type (for NE2/AE2 support)
    //

    NdisReadConfiguration(
            &Status,
            &ReturnedValue,
            ConfigHandle,
            &BusTypeStr,
            NdisParameterHexInteger

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -