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

📄 rtl8029.c

📁 自编的RTL8029驱动程序,用DS3.1开发
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (ConfigError)
    {
        //
        // Log Error and exit.
        //
        NdisWriteErrorLogEntry(
            Adapter->MiniportAdapterHandle,
            NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
            1,
            ConfigErrorValue
            );

        return(NDIS_STATUS_FAILURE);
    }

    //
    // Inform the wrapper of the physical attributes of this adapter.
   
    //
    // Register the port addresses.
    //
    status = NdisMRegisterIoPortRange(
                 (PVOID *)&Adapter->IoAddr,
                 Adapter->MiniportAdapterHandle,
                 Adapter->IoBaseAddr,
                 0x20
             );
    if(status==NDIS_STATUS_RESOURCE_CONFLICT )
    	IF_LOUD(DbgPrint("NDIS_STATUS_RESOURCE_CONFLICT ");)
    if(status==NDIS_STATUS_RESOURCES )
    	IF_LOUD(DbgPrint("NDIS_STATUS_RESOURCES");)
    if(status==NDIS_STATUS_FAILURE  )
    	IF_LOUD(DbgPrint("NDIS_STATUS_FAILURE ");)

    if (status != NDIS_STATUS_SUCCESS)
        return(status);

    
        //
        // Check that the IoBaseAddress seems to be correct.
        //
  

        if (!CardCheckParameters(Adapter))
        {
            //
            // The card does not seem to be there, fail silently.
            //


            NdisWriteErrorLogEntry(
                Adapter->MiniportAdapterHandle,
                NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
                0
            );

            status = NDIS_STATUS_ADAPTER_NOT_FOUND;

            goto fail2;
        }

        IF_VERY_LOUD( DbgPrint("  -- Success\n"); )
 

    //
    // Initialize the card.
    //
    IF_VERY_LOUD( DbgPrint("CardInitialize\n"); )

    if (!CardInitialize(Adapter))
    {
        //
        // Card seems to have failed.
        //

        IF_VERY_LOUD( DbgPrint("  -- Failed\n"); )

        NdisWriteErrorLogEntry(
            Adapter->MiniportAdapterHandle,
            NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
            0
        );

        status = NDIS_STATUS_ADAPTER_NOT_FOUND;

        goto fail2;
    }

    IF_VERY_LOUD( DbgPrint("  -- Success\n"); )

    //
    //
    // For programmed I/O, we will refer to transmit/receive memory in
    // terms of offsets in the card's 64K address space.
    //
    Adapter->XmitStart = Adapter->RamBase;

    //
    // For the NicXXX fields, always use the addressing system
    // containing the MSB only).
    //
    Adapter->NicXmitStart = (UCHAR)((PtrToUlong(Adapter->XmitStart)) >> 8);

    //
    // The start of the receive space.
    //
    Adapter->PageStart = Adapter->XmitStart +
            (Adapter->NumBuffers * TX_BUF_SIZE);

    Adapter->NicPageStart = Adapter->NicXmitStart +
            (UCHAR)(Adapter->NumBuffers * BUFS_PER_TX);

    ASSERT(Adapter->PageStart < (Adapter->RamBase + Adapter->RamSize));

    //
    // The end of the receive space.
    //
    Adapter->PageStop = Adapter->XmitStart + Adapter->RamSize;
    Adapter->NicPageStop = Adapter->NicXmitStart + (UCHAR)(Adapter->RamSize >> 8);

    ASSERT(Adapter->PageStop <= (Adapter->RamBase + Adapter->RamSize));

    IF_LOUD( DbgPrint("Xmit Start (0x%x, 0x%x) : Rcv Start (0x%x, 0x%x) : Rcv End (0x%x, 0x%x)\n",
              Adapter->XmitStart,
              Adapter->NicXmitStart,
              Adapter->PageStart,
              Adapter->NicPageStart,
              (ULONG_PTR)Adapter->PageStop,
              Adapter->NicPageStop
             );
       )


    //
    // Initialize the receive variables.
    //
    Adapter->NicReceiveConfig = RCR_REJECT_ERR;

    //
    // Initialize the transmit buffer control.
    //
    Adapter->CurBufXmitting = (XMIT_BUF)-1;

    //
    // Initialize the transmit buffer states.
    //
    for (i = 0; i < Adapter->NumBuffers; i++)
        Adapter->BufferStatus[i] = EMPTY;

    //
    // Read the Ethernet address off of the PROM.
    //
    if (!CardReadEthernetAddress(Adapter))
    {
        IF_LOUD(DbgPrint("Could not read the ethernet address\n");)

        NdisWriteErrorLogEntry(
            Adapter->MiniportAdapterHandle,
            NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
            0
            );

        status = NDIS_STATUS_ADAPTER_NOT_FOUND;

        goto fail2;
    }

    //
    // Now initialize the NIC and Gate Array registers.
    //
    Adapter->NicInterruptMask = IMR_RCV | IMR_XMIT | IMR_XMIT_ERR | IMR_OVERFLOW;

    //
    // Link us on to the chain of adapters for this driver.
    //
    Adapter->NextAdapter = RTL8029MiniportBlock.AdapterQueue;
    RTL8029MiniportBlock.AdapterQueue = Adapter;


    //
    // Setup the card based on the initialization information
    //

    IF_VERY_LOUD( DbgPrint("Setup\n"); )

    if (!CardSetup(Adapter))
    {
        //
        // The NIC could not be written to.
        //

        NdisWriteErrorLogEntry(
            Adapter->MiniportAdapterHandle,
            NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
            0
        );

        IF_VERY_LOUD( DbgPrint("  -- Failed\n"); )

        status = NDIS_STATUS_ADAPTER_NOT_FOUND;

        goto fail3;
    }

    IF_VERY_LOUD( DbgPrint("  -- Success\n"); )

    //
    // Initialize the interrupt.
    //
    status = NdisMRegisterInterrupt(
                 &Adapter->Interrupt,
                 Adapter->MiniportAdapterHandle,
                 Adapter->InterruptVector,
                 Adapter->InterruptLevel,
                 TRUE,
      			 TRUE,
                 NdisInterruptLatched
             );
    if(status==NDIS_STATUS_FAILURE )
    	IF_LOUD(DbgPrint("NDIS_STATUS_FAILURE ");)
    if(status==NDIS_STATUS_RESOURCE_CONFLICT  )
   		 IF_LOUD(DbgPrint("NDIS_STATUS_RESOURCE_CONFLICT  ");)
    if(status==NDIS_STATUS_RESOURCES  )
    	IF_LOUD(DbgPrint("NDIS_STATUS_RESOURCES  ");)

    if (status != NDIS_STATUS_SUCCESS)
    {
        NdisWriteErrorLogEntry(
            Adapter->MiniportAdapterHandle,
            NDIS_ERROR_CODE_INTERRUPT_CONNECT,
            0
        );

        goto fail3;
    }

    IF_LOUD( DbgPrint("Interrupt Connected\n");)

    //
    // Start up the adapter.
    //
    CardStart(Adapter);

    //
    // Initialization completed successfully.
    //
    IF_LOUD( DbgPrint(" [ RTL8029 ] : OK\n");)

    return(NDIS_STATUS_SUCCESS);

    //
    // Code to unwind what has already been set up when a part of
    // initialization fails, which is jumped into at various
    // points based on where the failure occured. Jumping to
    // a higher-numbered failure point will execute the code
    // for that block and all lower-numbered ones.
    //

fail3:

    //
    // Take us out of the AdapterQueue.
    //

    if (RTL8029MiniportBlock.AdapterQueue == Adapter)
    {
        RTL8029MiniportBlock.AdapterQueue = Adapter->NextAdapter;
    }
    else
    {
        PRTL8029_ADAPTER TmpAdapter = RTL8029MiniportBlock.AdapterQueue;

        while (TmpAdapter->NextAdapter != Adapter)
        {
            TmpAdapter = TmpAdapter->NextAdapter;
        }

        TmpAdapter->NextAdapter = TmpAdapter->NextAdapter->NextAdapter;
    }

    //
    // We already enabled the interrupt on the card, so
    // turn it off.
    //
    NdisRawWritePortUchar(Adapter->IoAddr+NIC_COMMAND, CR_STOP);

fail2:

    NdisMDeregisterIoPortRange(
        Adapter->MiniportAdapterHandle,
        PtrToUint(Adapter->IoBaseAddr),
        0x20,
        (PVOID)&Adapter->IoAddr
    );

    return(status);
}


extern
VOID
RTL8029Halt(
    IN NDIS_HANDLE MiniportAdapterContext
    )

/*++

Routine Description:

    RTL8029Halt removes an adapter that was previously initialized.

Arguments:

    MiniportAdapterContext - The context value that the Miniport returned
        from RTL8029Initialize; actually as pointer to an RTL8029_ADAPTER.

Return Value:

    None.

--*/

{
    PRTL8029_ADAPTER Adapter;

    Adapter = PRTL8029_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);

    //
    // Shut down the chip.
    //
    CardStop(Adapter);

    //
    // Disconnect the interrupt line.
    //
    NdisMDeregisterInterrupt(&Adapter->Interrupt);

    //
    // Pause, waiting for any DPC stuff to clear.
    //
    NdisStallExecution(250000);

    NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle,
                               PtrToUint(Adapter->IoBaseAddr),
                               0x20,
                               (PVOID)&Adapter->IoAddr
                               );

    //
    // Remove the adapter from the global queue of adapters.
    //
    if (RTL8029MiniportBlock.AdapterQueue == Adapter) {

        RTL8029MiniportBlock.AdapterQueue = Adapter->NextAdapter;

    } else {

        PRTL8029_ADAPTER TmpAdapter = RTL8029MiniportBlock.AdapterQueue;

        while (TmpAdapter->NextAdapter != Adapter) {

            TmpAdapter = TmpAdapter->NextAdapter;

        }

        TmpAdapter->NextAdapter = TmpAdapter->NextAdapter->NextAdapter;
    }

    //
    // Free up the memory
    //
    NdisFreeMemory(Adapter, sizeof(RTL8029_ADAPTER), 0);

    return;

}



NDIS_STATUS
RTL8029Reset(
    OUT PBOOLEAN AddressingReset,
    IN NDIS_HANDLE MiniportAdapterContext
    )
/*++

Routine Description:

    The RTL8029Reset request instructs the Miniport to issue a hardware reset
    to the network adapter.  The driver also resets its software state.  See
    the description of NdisMReset for a detailed description of this request.

Arguments:

    AddressingReset - Does the adapter need the addressing information reloaded.

    MiniportAdapterContext - Pointer to the adapter structure.

Return Value:

    The function value is the status of the operation.

--*/

{

    //
    // Pointer to the adapter structure.
    //
    PRTL8029_ADAPTER Adapter = (PRTL8029_ADAPTER)MiniportAdapterContext;

    //
    // Temporary looping variable
    //
    UINT i;

    //
    // Clear the values for transmits, they will be reset these for after
    // the reset is completed.
    //
    Adapter->NextBufToFill = 0;
    Adapter->NextBufToXmit = 0;
    Adapter->CurBufXmitting = (XMIT_BUF)-1;

    Adapter->FirstPacket = NULL;
    Adapter->LastPacket = NULL;

    for (i=0; i<Adapter->NumBuffers; i++) {
            Adapter->BufferStatus[i] = EMPTY;
    }

    //
    // Physically reset the card.
    //
    Adapter->NicInterruptMask = IMR_RCV | IMR_XMIT | IMR_XMIT_ERR | IMR_OVERFLOW;

    return (CardReset(Adapter) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
}


NDIS_STATUS
RTL8029QueryInformation(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN NDIS_OID Oid,
    IN PVOID InformationBuffer,
    IN ULONG InformationBufferLength,
    OUT PULONG BytesWritten,
    OUT PULONG BytesNeeded
)

/*++

Routine Description:

    The RTL8029QueryInformation process a Query request for
    NDIS_OIDs that are specific about the Driver.

Arguments:

    MiniportAdapterContext - a pointer to the adapter.

    Oid - the NDIS_OID to process.

    InformationBuffer -  a pointer into the
    NdisRequest->InformationBuffer into which store the result of the query.

    InformationBufferLength - a pointer to the number of bytes left in the
    InformationBuffer.

    BytesWritten - a pointer to the number of bytes written into the
    InformationBuffer.

    BytesNeeded - If there is not enough room in the information buffer
    then this will contain the number of bytes needed to complete the
    request.

Return Value:

    The function value is the status of the operation.

--*/
{

    //
    // Pointer to the adapter structure.
    //
    PRTL8029_ADAPTER Adapter = (PRTL8029_ADAPTER)MiniportAdapterContext;

    //
    //   General Algorithm:
    //
    //      Switch(Request)
    //         Get requested information
    //         Store results in a common variable.
    //      default:
    //         Try protocol query information
    //         If that fails, fail query.
    //
    //      Copy result in common variable to result buffer.
    //   Finish processing

    UINT BytesLeft = InformationBufferLength;
    PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);
    NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
    NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
    NDIS_MEDIUM Medium = NdisMedium802_3;

    //
    // This variable holds result of query
    //
    ULONG GenericULong;
    USHORT GenericUShort;
    UCHAR GenericArray[6];
    UINT MoveBytes = sizeof(ULONG);
    PVOID MoveSource = (PVOID)(&GenericULong);

    //
    // Make sure that int is 4 bytes.  Else GenericULong must change
    // to something of size 4.
    //
    ASSERT(sizeof(ULONG) == 4);

    //
    // Switch on request type
    //

    switch (Oid) {

    case OID_GEN_MAC_OPTIONS:

        GenericULong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND  |
                               NDIS_MAC_OPTION_RECEIVE_SERIALIZED  |
                               NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
                               NDIS_MAC_OPTION_NO_LOOPBACK
                               );

        break;

    case OID_GEN_SUPPORTED_LIST:

        MoveSource = (PVOID)(RTL8029SupportedOids);
        MoveBytes = sizeof(RTL8029SupportedOids);
        break;

    case OID_GEN_HARDWARE_STATUS:

        HardwareStatus = NdisHardwareStatusReady;
        MoveSource = (PVOID)(&HardwareStatus);
        MoveBytes = sizeof(NDIS_HARDWARE_STATUS);

        break;

    case OID_GEN_MEDIA_SUPPORTED:
    case OID_GEN_MEDIA_IN_USE:

        MoveSource = (PVOID) (&Medium);
        MoveBytes = sizeof(NDIS_MEDIUM);
        break;

    case OID_GEN_MAXIMUM_LOOKAHEAD:

        GenericULong = RTL8029_MAX_LOOKAHEAD;

        break;


    case OID_GEN_MAXIMUM_FRAME_SIZE:

        GenericULong = (ULONG)(1514 - RTL8029_HEADER_SIZE);

        break;


    case OID_GEN_MAXIMUM_TOTAL_SIZE:

        GenericULong = (ULONG)(1514);

        break;


    case OID_GEN_LINK_SPEED:

        GenericULong = (ULONG)(100000);

        break;

⌨️ 快捷键说明

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