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

📄 ne2000.c

📁 自制PDA系列之PCMCIA接口驱动(处理器PXA270)
💻 C
📖 第 1 页 / 共 4 页
字号:
    //
    // 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))
    {
        DEBUGMSG(1,
            (TEXT("NE2000:RegisterAdapter 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 = Ne2000MiniportBlock.AdapterQueue;
    Ne2000MiniportBlock.AdapterQueue = Adapter;


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

    DEBUGMSG(1, (TEXT("NE2000:RegisterAdapter CardSetup\n")));

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

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

        DEBUGMSG(1,
            (TEXT("NE2000:RegisterAdapter CardSetup -- Failed\n")));

        status = NDIS_STATUS_ADAPTER_NOT_FOUND;

        goto fail3;
    }

    DEBUGMSG(1,
        (TEXT("NE2000:RegisterAdapter CardSetup -- Success\n")));

    //
    // Initialize the interrupt.
    //
    status = NdisMRegisterInterrupt(
                 &Adapter->Interrupt,
                 Adapter->MiniportAdapterHandle,
                 Adapter->InterruptNumber,
                 Adapter->InterruptNumber,
                 FALSE,
                 FALSE,
                 NdisInterruptLatched
             );

    if (status != NDIS_STATUS_SUCCESS)
    {
        DEBUGMSG(1,
            (TEXT("NE2000:RegisterAdapter NdisMRegisterInterrupt failed 0x%x\n"), status));
        NdisWriteErrorLogEntry(
            Adapter->MiniportAdapterHandle,
            NDIS_ERROR_CODE_INTERRUPT_CONNECT,
            0
        );

        goto fail3;
    }

    DEBUGMSG(1,
        (TEXT("NE2000:RegisterAdapter Interrupt Connected\n")));

    // register a shutdown handler for this card
	NdisMRegisterAdapterShutdownHandler(
		Adapter->MiniportAdapterHandle,		// miniport handle.
		Adapter,							// shutdown context.
		Ne2000Shutdown						// shutdown handler.
		);
    
    //
    // Start up the adapter.
    //
    CardStart(Adapter);

    //
    // Initialization completed successfully.
    //
    DEBUGMSG(1, (TEXT("NE2000:RegisterAdapter 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 (Ne2000MiniportBlock.AdapterQueue == Adapter)
    {
        Ne2000MiniportBlock.AdapterQueue = Adapter->NextAdapter;
    }
    else
    {
        PNE2000_ADAPTER TmpAdapter = Ne2000MiniportBlock.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->IoPAddr+NIC_COMMAND, CR_STOP);

fail2:

    NdisMDeregisterIoPortRange(
        Adapter->MiniportAdapterHandle,
        (ULONG)Adapter->IoBaseAddr,
        0x20,
        (PVOID)Adapter->IoPAddr
    );

    return(status);
}



extern
VOID
Ne2000Shutdown(
    IN NDIS_HANDLE MiniportAdapterContext
    )
/*++

Routine Description:

    NE2000Shutdown is called to shut down the adapter. We need to unblock any
    threads which may be called in, and terminate any loops.  This function is
    called by NDIS.DLL when a PCMCIA card removal is detected.  At that
    point, any access to the NE2000 registers may return random data, as the bus
    is floating.

Arguments:

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

Return Value:

    None.

--*/    
{
    PNE2000_ADAPTER Adapter;

    Adapter = PNE2000_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);

    Adapter->ShuttingDown = TRUE;
    //
    // Shut down the chip.  Note that the card may not be present, so this
    // routine should not do anything that might hang.
    //
    CardStop(Adapter);
}


extern
VOID
Ne2000Halt(
    IN NDIS_HANDLE MiniportAdapterContext
    )

/*++

Routine Description:

    NE2000Halt removes an adapter that was previously initialized.

Arguments:

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

Return Value:

    None.

--*/

{
    PNE2000_ADAPTER Adapter;

    Adapter = PNE2000_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,
                               (ULONG)Adapter->IoBaseAddr,
                               0x20,
                               (PVOID)Adapter->IoPAddr
                               );

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

        Ne2000MiniportBlock.AdapterQueue = Adapter->NextAdapter;

    } else {

        PNE2000_ADAPTER TmpAdapter = Ne2000MiniportBlock.AdapterQueue;

        while (TmpAdapter->NextAdapter != Adapter) {

            TmpAdapter = TmpAdapter->NextAdapter;

        }

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

	// was this the last NIC?
	if ((Ne2000MiniportBlock.AdapterQueue == NULL) &&
		(Ne2000MiniportBlock.NdisWrapperHandle)) {
		NdisTerminateWrapper (Ne2000MiniportBlock.NdisWrapperHandle, NULL);
		Ne2000MiniportBlock.NdisWrapperHandle = NULL;
	}

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

    return;

}



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

Routine Description:

    The NE2000Reset 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.
    //
    PNE2000_ADAPTER Adapter = (PNE2000_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
Ne2000QueryInformation(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN NDIS_OID Oid,
    IN PVOID InformationBuffer,
    IN ULONG InformationBufferLength,
    OUT PULONG BytesWritten,
    OUT PULONG BytesNeeded
)

/*++

Routine Description:

    The NE2000QueryInformation 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.
    //
    PNE2000_ADAPTER Adapter = (PNE2000_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)(Ne2000SupportedOids);
        MoveBytes = sizeof(Ne2000SupportedOids);
        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 = NE2000_MAX_LOOKAHEAD;

        break;


    case OID_GEN_MAXIMUM_FRAME_SIZE:

        GenericULong = (ULONG)(1514 - NE2000_HEADER_SIZE);

        break;


    case OID_GEN_MAXIMUM_TOTAL_SIZE:

        GenericULong = (ULONG)(1514);

        break;


    case OID_GEN_LINK_SPEED:

        GenericULong = (ULONG)(100000);

        break;


    case OID_GEN_TRANSMIT_BUFFER_SPACE:

        GenericULong = (ULONG)(Adapter->NumBuffers * TX_BUF_SIZE);

        break;

    case OID_GEN_RECEIVE_BUFFER_SPACE:

        GenericULong = (ULONG)(0x2000 - (Adapter->NumBuffers * TX_BUF_SIZE));

        break;

    case OID_GEN_TRANSMIT_BLOCK_SIZE:

        GenericULong = (ULONG)(TX_BUF_SIZE);

        break;

    case OID_GEN_RECEIVE_BLOCK_SIZE:

        GenericULong = (ULONG)(256);

        break;

#ifdef NE2000

    case OID_GEN_VENDOR_ID:

        NdisMoveMemory(
            (PVOID)&GenericULong,
            Adapter->PermanentAddress,
            3
            );
        GenericULong &= 0xFFFFFF00;
        MoveSource = (PVOID)(&GenericULong);
        MoveBytes = sizeof(GenericULong);

⌨️ 快捷键说明

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