Exemplo n.º 1
0
/* create a new cm object */
cm_create(VOID **ret_cm, NDIS_HANDLE AdapterHandle)
{
    NDIS_PHYSICAL_ADDRESS   pa = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
    INT     n;

    D_LOG(D_ENTRY, ("cm_create: entry, ret_cm: 0x%p", ret_cm));

	/* allocate memory object */
    NdisAllocateMemory((PVOID*)ret_cm, sizeof(CM), 0, pa);
    if ( *ret_cm == NULL )
    {
        D_LOG(D_ALWAYS, ("cm_create: memory allocate failed!"));
		NdisWriteErrorLogEntry (AdapterHandle,
		                        NDIS_ERROR_CODE_OUT_OF_RESOURCES,
								0);
        return(CM_E_NOMEM);
    }
    D_LOG(D_ALWAYS, ("cm_create: cm: 0x%x", *ret_cm));
	NdisZeroMemory(*ret_cm, sizeof(CM));

    /* allocate connection out of local table */
    for ( n = 0 ; n < MAX_CM_IN_SYSTEM ; n++ )
        if ( !cm_used[n] )
            break;
    if ( n >= MAX_CM_IN_SYSTEM )
	{
		/* free memory */
		NdisFreeMemory(*ret_cm, sizeof(CM), 0);
        return(CM_E_NOSLOT);
	}


    /* initialize */
    cm_used[n] = 1;
	cm_tbl[n] = *ret_cm;
	((CM*)*ret_cm)->local_conn_index = n;

    /* return */
    return(CM_E_SUCC);
}
Exemplo n.º 2
0
NDIS_STATUS
MPReset(
    NDIS_HANDLE             MiniportAdapterContext,
    PBOOLEAN                AddressingReset
    )
{
    PADAPTER                    adapter = (PADAPTER)MiniportAdapterContext;
    NDIS_STATUS                 ndisStatus = NDIS_STATUS_PENDING;
    NDIS_HANDLE                 workitemHandle;

    *AddressingReset = TRUE;
    
#if DBG
    if (adapter->Debug_BreakOnReset)
    {
        DbgPrint("Received NdisReset\n");
        DbgBreakPoint();
    }
#endif

    do
    {
        //
        // Set the flag so that other routines stop proceeding
        //
        MP_SET_ADAPTER_STATUS(adapter, MP_ADAPTER_IN_RESET);
        
        //
        // If our halt handler has been called, we should not reset
        //
        if (MP_TEST_ADAPTER_STATUS(adapter, MP_ADAPTER_HALTING))
        {
            MPASSERT(FALSE);    // Would be an interesting scenario to investigate
            ndisStatus = NDIS_STATUS_SUCCESS;
            break;
        }

        //
        // Handle the reset asynchronously since we can be called at either dispatch
        // or passive IRQL
        //
        workitemHandle = NdisAllocateIoWorkItem(adapter->MiniportAdapterHandle);
        if(workitemHandle == NULL)
        {
            MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to allocate Reset workitem\n"));
            NdisWriteErrorLogEntry(adapter->MiniportAdapterHandle,
                NDIS_ERROR_CODE_OUT_OF_RESOURCES,
                0
                );
            ndisStatus = NDIS_STATUS_RESOURCES;
            break;
        }

        // Queue the workitem
        NdisQueueIoWorkItem(workitemHandle, 
            MpResetWorkItem,
            adapter
            );

    } while (FALSE);   

    if (ndisStatus != NDIS_STATUS_PENDING)
    {
        // Something failed, clear the in reset flag
        MP_CLEAR_ADAPTER_STATUS(adapter, MP_ADAPTER_IN_RESET);
    }
    return ndisStatus;
}
Exemplo n.º 3
0
NDIS_STATUS
CardIdentify(
    IN PHTDSU_ADAPTER       Adapter
    )

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Functional Description:

    This routine will attempt to verify that the controller is located in
    memory where the driver has been configured to expect it.

Parameters:

    Adapter _ A pointer ot our adapter information structure.

Return Values:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_ADAPTER_NOT_FOUND

---------------------------------------------------------------------------*/

{
    DBG_FUNC("CardIdentify")

    NDIS_STATUS Status;

    /*
    // These values are read from the adapter to make sure this driver will
    // work with the firmware on the adapter.
    */
    USHORT CoProcessorId;
    USHORT CoProcessorVersion;
    USHORT DsuId;
    USHORT DsuVersion;

    DBG_ENTER(Adapter);

    /*
    // Read the configuration values from the card.
    */
    CoProcessorId      = READ_REGISTER_USHORT(&Adapter->AdapterRam->CoProcessorId);
    CoProcessorVersion = READ_REGISTER_USHORT(&Adapter->AdapterRam->CoProcessorVersion);
    DsuId              = READ_REGISTER_USHORT(&Adapter->AdapterRam->DsuId);
    DsuVersion         = READ_REGISTER_USHORT(&Adapter->AdapterRam->DsuVersion);

    /*
    // Make sure these values are what we expect.
    */
    if ((CoProcessorId      == HTDSU_COPROCESSOR_ID) &&
        (CoProcessorVersion >= HTDSU_COPROCESSOR_VERSION) &&
        ((DsuId & 0x00FF)   == HTDSU_DSU_ID) &&
        (DsuVersion         >= HTDSU_DSU_VERSION))
    {
        /*
        // Record the number of lines on this adapter.
        */
        Adapter->NumLineDevs = HTDSU_NUM_LINKS;
        if ((DsuId & 0xFF00) == 0)
        {
            --Adapter->NumLineDevs;
        }
        DBG_NOTICE(Adapter,("NumLineDevs=%d\n",Adapter->NumLineDevs));

        Status = NDIS_STATUS_SUCCESS;
    }
    else
    {
        DBG_ERROR(Adapter,("Adapter not found or invalid firmware:\n"
                  "CoProcessorId      = %Xh\n"
                  "CoProcessorVersion = %Xh\n"
                  "DsuId              = %Xh\n"
                  "DsuVersion         = %Xh\n",
                  CoProcessorId,
                  CoProcessorVersion,
                  DsuId,
                  DsuVersion
                  ));

        Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
        /*
        // Log error message and return.
        */
        NdisWriteErrorLogEntry(
                Adapter->MiniportAdapterHandle,
                NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
                7,
                CoProcessorId,
                CoProcessorVersion,
                DsuId,
                DsuVersion,
                Status,
                __FILEID__,
                __LINE__
                );
    }

    DBG_LEAVE(Adapter);

    return (Status);
}
Exemplo n.º 4
0
NDIS_STATUS
CardInitialize(
    IN PHTDSU_ADAPTER       Adapter,
    IN BOOLEAN              PerformSelfTest
    )

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Functional Description:

    This routine will attempt to initialize the controller, but will not
    enable transmits or receives.

Parameters:

    Adapter _ A pointer ot our adapter information structure.

    PerformSelfTest _ TRUE if caller wants to run selftest diagnostics.
                      This normally takes about 4 seconds to complete, so you
                      wouldn't want to do it every time you start up.

Return Values:

    NDIS_STATUS_HARD_ERRORS
    NDIS_STATUS_SUCCESS

---------------------------------------------------------------------------*/

{
    DBG_FUNC("CardInitialize")

    NDIS_STATUS Status;

    USHORT      SelfTestStatus;

    UINT        TimeOut;

    DBG_ENTER(Adapter);

    /*
    // First we make sure the adapter is where we think it is.
    */
    Status = CardIdentify(Adapter);
    if (Status != NDIS_STATUS_SUCCESS)
    {
        return (Status);
    }

    /*
    // Reset the hardware to make sure we're in a known state.
    */
    Status = CardDoCommand(Adapter, 0, HTDSU_CMD_RESET);
    
    if (PerformSelfTest)
    {
        /*
        // Wait for the reset to complete before starting the self-test.
        // Then issue the self-test command to see if the adapter firmware
        // is happy with the situation.
        */
        Status = CardDoCommand(Adapter, 0, HTDSU_CMD_SELFTEST);
        if (Status != NDIS_STATUS_SUCCESS)
        {
            DBG_ERROR(Adapter,("Failed HTDSU_CMD_RESET\n"));
            /*
            // Log error message and return.
            */
            NdisWriteErrorLogEntry(
                    Adapter->MiniportAdapterHandle,
                    NDIS_ERROR_CODE_HARDWARE_FAILURE,
                    3,
                    Status,
                    __FILEID__,
                    __LINE__
                    );
            return (Status);
        }
        
        /*
        // Wait for the self test to complete, but don't wait forever.
        */
        TimeOut = 0;
        while (Status == NDIS_STATUS_SUCCESS &&
               READ_REGISTER_USHORT(&Adapter->AdapterRam->Command) !=
                        HTDSU_CMD_NOP)
        {
            if (TimeOut++ > HTDSU_SELFTEST_TIMEOUT)
            {
                DBG_ERROR(Adapter,("Timeout waiting for SELFTEST to complete\n"));
                Status = NDIS_STATUS_HARD_ERRORS;
            }
            else
            {
                NdisStallExecution(_100_MICROSECONDS);
            }
        }
        if (Status != NDIS_STATUS_SUCCESS)
        {
            DBG_ERROR(Adapter,("Failed HTDSU_CMD_SELFTEST\n"));
            /*
            // Log error message and return.
            */
            NdisWriteErrorLogEntry(
                    Adapter->MiniportAdapterHandle,
                    NDIS_ERROR_CODE_HARDWARE_FAILURE,
                    3,
                    Status,
                    __FILEID__,
                    __LINE__
                    );
            return (Status);
        }

        /*
        // Verify that self test was successful.
        */
        SelfTestStatus = READ_REGISTER_USHORT(&Adapter->AdapterRam->SelfTestStatus);
        if (SelfTestStatus != 0 && SelfTestStatus != HTDSU_SELFTEST_OK)
        {
            DBG_ERROR(Adapter,("Failed HTDSU_CMD_SELFTEST (Status=%X)\n",
                      SelfTestStatus));
            /*
            // Log error message and return.
            */
            NdisWriteErrorLogEntry(
                    Adapter->MiniportAdapterHandle,
                    NDIS_ERROR_CODE_HARDWARE_FAILURE,
                    3,
                    SelfTestStatus,
                    __FILEID__,
                    __LINE__
                    );
            return (NDIS_STATUS_HARD_ERRORS);
        }
    }

    DBG_LEAVE(Adapter);

    return (NDIS_STATUS_SUCCESS);
}
Exemplo n.º 5
0
extern
NDIS_STATUS
IbmtokTransferData(
    IN NDIS_HANDLE MacBindingHandle,
    IN NDIS_HANDLE MacReceiveContext,
    IN UINT ByteOffset,
    IN UINT BytesToTransfer,
    OUT PNDIS_PACKET Packet,
    OUT PUINT BytesTransferred
    )

/*++

Routine Description:

    A protocol calls the IbmtokTransferData request (indirectly via
    NdisTransferData) from within its Receive event handler
    to instruct the MAC to copy the contents of the received packet
    a specified packet buffer.

Arguments:

    MacBindingHandle - The context value returned by the MAC when the
    adapter was opened.  In reality this is a pointer to IBMTOK.

    MacReceiveContext - The context value passed by the MAC on its call
    to NdisIndicateReceive.  The MAC can use this value to determine
    which packet, on which adapter, is being received.

    ByteOffset - An unsigned integer specifying the offset within the
    received packet at which the copy is to begin.  If the entire packet
    is to be copied, ByteOffset must be zero.

    BytesToTransfer - An unsigned integer specifying the number of bytes
    to copy.  It is legal to transfer zero bytes; this has no effect.  If
    the sum of ByteOffset and BytesToTransfer is greater than the size
    of the received packet, then the remainder of the packet (starting from
    ByteOffset) is transferred, and the trailing portion of the receive
    buffer is not modified.

    Packet - A pointer to a descriptor for the packet storage into which
    the MAC is to copy the received packet.

    BytesTransfered - A pointer to an unsigned integer.  The MAC writes
    the actual number of bytes transferred into this location.  This value
    is not valid if the return status is STATUS_PENDING.

Return Value:

    The function value is the status of the operation.


--*/

{

    PIBMTOK_ADAPTER Adapter;

    NDIS_STATUS StatusToReturn;

    Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);

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

    if (!Adapter->NotAcceptingRequests) {

        PIBMTOK_OPEN Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);

        if (!Open->BindingShuttingDown) {

            //
            // The code in this section is quite similar to the
            // code in CopyFromPacketToPacket.  It could easily go
            // into its own routine, except that it is not likely
            // to be used in any other implementation.
            //
            SRAM_PTR SourceReceiveBuffer =
                Adapter->IndicatedReceiveBuffer;

            //
            // Holds the count of the number of ndis buffers comprising
            // the destination packet.
            //
            UINT DestinationBufferCount;

            //
            // Points to the buffer into which we are putting data.
            //
            PNDIS_BUFFER DestinationCurrentBuffer;

            //
            // Holds the virtual address of the current destination
            // buffer.
            //
            PVOID DestinationVirtualAddress;

            //
            // Holds the virtual address of the current source buffer.
            //
            PRECEIVE_BUFFER SourceBufferAddress;

            //
            // Holds the address of the data in the current source buffer.
            //
            PVOID SourceVirtualAddress;

            //
            // Holds the length of the current destination buffer.
            //
            UINT DestinationCurrentLength;

            //
            // Holds the length of the current source buffer.
            //
            UINT SourceCurrentLength;

            //
            // Keep a local variable of BytesTransferred so we aren't
            // referencing through a pointer.
            //
            UINT LocalBytesTransferred = 0;

            USHORT PortValue;

            Open->References++;

            NdisReleaseSpinLock(&Adapter->Lock);

            *BytesTransferred = 0;

            ASSERT(sizeof(UINT) >= 2);
            ASSERT(sizeof(UINT) == sizeof(NDIS_HANDLE));

            //
            // Get the first buffer of the destination.
            //

            NdisQueryPacket(
                Packet,
                NULL,
                &DestinationBufferCount,
                &DestinationCurrentBuffer,
                NULL
                );

            //
            // Could have a null packet.
            //

            if (DestinationBufferCount != 0) {

                NdisQueryBuffer(
                    DestinationCurrentBuffer,
                    &DestinationVirtualAddress,
                    &DestinationCurrentLength
                    );

                //
                // Get the information for the first buffer of the source.
                //

                SourceBufferAddress = (PRECEIVE_BUFFER)
                    ((PUCHAR)SRAM_PTR_TO_PVOID(Adapter,
                            SourceReceiveBuffer) + 2);

                //
                // Adjust the address and length to account for the
                // header for this frame.
                //

                SourceVirtualAddress =
                    SourceBufferAddress->FrameData +
                    Adapter->IndicatedHeaderLength;

                NdisReadRegisterUshort(&SourceBufferAddress->BufferLength,
                                       &PortValue
                                      );

                SourceCurrentLength = IBMSHORT_TO_USHORT(PortValue) -
                                      Adapter->IndicatedHeaderLength;



                //
                // Take care of boundary condition of zero length copy.
                //

                while (LocalBytesTransferred < BytesToTransfer) {

                    //
                    // Check to see whether we've exhausted the current
                    // destination buffer.  If so, move onto the next one.
                    //

                    if (!DestinationCurrentLength) {

                        NdisGetNextBuffer(
                            DestinationCurrentBuffer,
                            &DestinationCurrentBuffer
                            );

                        if (!DestinationCurrentBuffer) {

                            //
                            // We've reached the end of the packet.  We
                            // return with what we've done so far. (Which
                            // must be shorter than requested.)
                            //

                            break;

                        }

                        NdisQueryBuffer(
                            DestinationCurrentBuffer,
                            &DestinationVirtualAddress,
                            &DestinationCurrentLength
                            );
                        continue;

                    }


                    //
                    // Check to see whether we've exhausted the current
                    // source buffer.  If so, move onto the next one.
                    //

                    if (!SourceCurrentLength) {

                        NdisReadRegisterUshort(
                                     &SourceBufferAddress->NextBuffer,
                                     &SourceReceiveBuffer
                                     );

                        if (SourceReceiveBuffer == NULL_SRAM_PTR) {

                            //
                            // We've reached the end of the frame.  We
                            // return with what we've done so far. (Which
                            // must be shorter than requested.)
                            //

                            break;

                        }

                        SourceBufferAddress = (PRECEIVE_BUFFER)
                          SRAM_PTR_TO_PVOID(Adapter, SourceReceiveBuffer);

                        SourceVirtualAddress =
                            (PVOID)SourceBufferAddress->FrameData;

                        NdisReadRegisterUshort(
                                &SourceBufferAddress->BufferLength,
                                &SourceCurrentLength
                                );

                        SourceCurrentLength = IBMSHORT_TO_USHORT(
                                                SourceCurrentLength
                                                );

                        continue;

                    }

                    //
                    // Try to get us up to the point to start the copy.
                    //

                    if (ByteOffset) {

                        if (ByteOffset > SourceCurrentLength) {

                            //
                            // What we want isn't in this buffer.
                            //

                            ByteOffset -= SourceCurrentLength;
                            SourceCurrentLength = 0;
                            continue;

                        } else {

                            SourceVirtualAddress =
                                (PCHAR)SourceVirtualAddress + ByteOffset;
                            SourceCurrentLength -= ByteOffset;
                            ByteOffset = 0;

                        }

                    }

                    //
                    // Copy the data.
                    //

                    {

                        //
                        // Holds the amount of data to move.
                        //
                        UINT AmountToMove;

                        //
                        // Holds the amount desired remaining.
                        //
                        UINT Remaining = BytesToTransfer
                                         - LocalBytesTransferred;

                        AmountToMove =
                      ((SourceCurrentLength <= DestinationCurrentLength)?
                       (SourceCurrentLength):(DestinationCurrentLength));

                        AmountToMove = ((Remaining < AmountToMove)?
                                        (Remaining):(AmountToMove));

                        IBMTOK_MOVE_FROM_MAPPED_MEMORY(
                            DestinationVirtualAddress,
                            SourceVirtualAddress,
                            AmountToMove
                            );

                        DestinationVirtualAddress =
                          (PCHAR)DestinationVirtualAddress + AmountToMove;
                        SourceVirtualAddress =
                            (PCHAR)SourceVirtualAddress + AmountToMove;

                        LocalBytesTransferred += AmountToMove;
                        SourceCurrentLength -= AmountToMove;
                        DestinationCurrentLength -= AmountToMove;

                    }

                }

                *BytesTransferred = LocalBytesTransferred;

            }

            NdisAcquireSpinLock(&Adapter->Lock);
            Open->References--;
            StatusToReturn = NDIS_STATUS_SUCCESS;

        } else {

            StatusToReturn = NDIS_STATUS_REQUEST_ABORTED;

        }

    } else {

        if (Adapter->ResetInProgress) {

            StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;

        } else if (Adapter->OpenInProgress) {

            StatusToReturn = NDIS_STATUS_FAILURE;

        } else {

            NdisWriteErrorLogEntry(
                Adapter->NdisAdapterHandle,
                NDIS_ERROR_CODE_DRIVER_FAILURE,
                2,
                IBMTOK_ERRMSG_INVALID_STATE,
                1
                );

        }

    }

    IBMTOK_DO_DEFERRED(Adapter);
    return StatusToReturn;
}
Exemplo n.º 6
0
VOID
NE3200ResetHandler(
    IN PVOID SystemSpecific1,
    IN PNE3200_ADAPTER Adapter,
    IN PVOID SystemSpecific2,
    IN PVOID SystemSpecific3
    )

/*++

Routine Description:

    This manages the reset/download process.  It is
    responsible for resetting the adapter, waiting for proper
    status, downloading MAC.BIN, waiting for MAC.BIN initialization,
    and optionally sending indications to the appropriate protocol.

    Since the NE3200's status registers must be polled during the
    reset/download process, this is implemented as a state machine.

Arguments:

    Adapter - The adapter whose hardware is to be initialized.

Return Value:

    None.

--*/
{

    //
    // Physical address of the MAC.BIN buffer.
    //
    NDIS_PHYSICAL_ADDRESS MacBinPhysicalAddress;

    //
    // Status from the adapter.
    //
    UCHAR Status;

    //
    // Simple iteration counter.
    //
    UINT i;

    //
    // Loop until the reset has completed.
    //
    while (Adapter->ResetState != NE3200ResetStateComplete) {

        switch (Adapter->ResetState) {

            //
            // The first stage of resetting an NE3200
            //
            case NE3200ResetStateStarting :

                //
                // Unfortunately, a hardware reset to the NE3200 does *not*
                // reset the BMIC chip.  To ensure that we read a proper status,
                // we'll clear all of the BMIC's registers.
                //
                NE3200_WRITE_SYSTEM_INTERRUPT(
                    Adapter,
                    0
                    );

                //
                // I changed this to ff since the original 0 didn't work for
                // some cases. since we don't have the specs....
                //
                NE3200_WRITE_LOCAL_DOORBELL_INTERRUPT(
                    Adapter,
                    0xff
                    );

                NE3200_WRITE_SYSTEM_DOORBELL_MASK(
                    Adapter,
                    0
                    );

                NE3200_SYNC_CLEAR_SYSTEM_DOORBELL_INTERRUPT(
                    Adapter
                    );

                for (i = 0 ; i < 16 ; i += 4 ) {

                    NE3200_WRITE_MAILBOX_ULONG(
                        Adapter,
                        i,
                        0L
                        );

                }

                //
                // Toggle the NE3200's reset line.
                //
                NE3200_WRITE_RESET(
                    Adapter,
                    NE3200_RESET_BIT_ON
                    );

                NE3200_WRITE_RESET(
                    Adapter,
                    NE3200_RESET_BIT_OFF
                    );

                //
                // Switch to the next state.
                //
                Adapter->ResetState = NE3200ResetStateResetting;
                Adapter->ResetTimeoutCounter = NE3200_TIMEOUT_RESET;

                //
                // Loop to the next processing
                //
                break;

            //
            // Part Deux.  The actual downloading of the software.
            //
            case NE3200ResetStateResetting :

                //
                // Read the status mailbox.
                //
                NE3200_READ_MAILBOX_UCHAR(Adapter, NE3200_MAILBOX_RESET_STATUS, &Status);

                if (Status == NE3200_RESET_PASSED) {

                    //
                    // We have good reset.  Initiate the MAC.BIN download.
                    //

                    //
                    // The station address for this adapter can be forced to
                    // a specific value at initialization time.  When MAC.BIN
                    // first gets control, it reads mailbox 10.  If this mailbox
                    // contains a 0xFF, then the burned-in PROM station address
                    // is used.  If this mailbox contains any value other than
                    // 0xFF, then mailboxes 10-15 are read.  The six bytes
                    // stored in these mailboxes then become the station address.
                    //
                    // Since we have no need for this feature, we will always
                    // initialize mailbox 10 with a 0xFF.
                    //
                    NE3200_WRITE_MAILBOX_UCHAR(
                        Adapter,
                        NE3200_MAILBOX_STATION_ID,
                        0xFF
                        );


                    //
                    // Get the MAC.BIN buffer.
                    //
                    MacBinPhysicalAddress = NE3200Globals.MacBinPhysicalAddress;

                    //
                    // Download MAC.BIN to the card.
                    //
                    NE3200_WRITE_MAILBOX_USHORT(
                        Adapter,
                        NE3200_MAILBOX_MACBIN_LENGTH,
                        NE3200Globals.MacBinLength
                        );

                    NE3200_WRITE_MAILBOX_UCHAR(
                        Adapter,
                        NE3200_MAILBOX_MACBIN_DOWNLOAD_MODE,
                        NE3200_MACBIN_DIRECT
                        );

                    NE3200_WRITE_MAILBOX_ULONG(
                        Adapter,
                        NE3200_MAILBOX_MACBIN_POINTER,
                        NdisGetPhysicalAddressLow(MacBinPhysicalAddress)
                        );

                    NE3200_WRITE_MAILBOX_USHORT(
                        Adapter,
                        NE3200_MAILBOX_MACBIN_TARGET,
                        NE3200_MACBIN_TARGET_ADDRESS >> 1
                        );

                    //
                    // This next OUT "kicks" the loader into action.
                    //
                    NE3200_WRITE_MAILBOX_UCHAR(
                        Adapter,
                        NE3200_MAILBOX_RESET_STATUS,
                        0
                        );

                    //
                    // Switch to the next state.
                    //
                    Adapter->ResetState = NE3200ResetStateDownloading;
                    Adapter->ResetTimeoutCounter = NE3200_TIMEOUT_DOWNLOAD;

                    //
                    // Loop to the next state.
                    //

                } else if (Status == NE3200_RESET_FAILED) {

                    //
                    // Reset failure.  Notify the authorities and
                    // next of kin.
                    //
                    Adapter->ResetResult = NE3200ResetResultResetFailure;
                    Adapter->ResetState = NE3200ResetStateComplete;

                    NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                } else {

                    //
                    // Still waiting for results, check if we have
                    // timed out waiting.
                    //
                    Adapter->ResetTimeoutCounter--;

                    if (Adapter->ResetTimeoutCounter == 0) {

                        //
                        // We've timed-out.  Bad news.  Notify the death.
                        //
                        Adapter->ResetResult = NE3200ResetResultResetTimeout;
                        Adapter->ResetState = NE3200ResetStateComplete;

                        NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                    } else {

                        //
                        // For Synchronous resets, we stall.  For async,
                        // we set a timer to check later.
                        //
                        if (!Adapter->ResetAsynchronous) {

                            //
                            // Otherwise, wait and try again.
                            //
                            NdisStallExecution(10000);

                        } else{

                            //
                            // Try again later.
                            //
                            NdisMSetTimer(&Adapter->ResetTimer, 100);

                            return;

                        }

                    }

                }

                break;

            //
            // Part Three: The download was started.  Check for completion,
            // and reload the current station address.
            //
            case NE3200ResetStateDownloading :

                //
                // Read the download status.
                //
                NE3200_READ_MAILBOX_UCHAR(Adapter, NE3200_MAILBOX_STATUS, &Status);

                if (Status == NE3200_INITIALIZATION_PASSED) {

                    //
                    // According to documentation from Compaq, this next port
                    // write will (in a future MAC.BIN) tell MAC.BIN whether or
                    // not to handle loopback internally.  This value is currently
                    // not used, but must still be written to the port.
                    //
                    NE3200_WRITE_MAILBOX_UCHAR(
                        Adapter,
                        NE3200_MAILBOX_STATUS,
                        1
                        );

                    //
                    // Initialization is good, the card is ready.
                    //
                    NE3200StartChipAndDisableInterrupts(Adapter,
                                                        Adapter->ReceiveQueueHead
                                                       );

                    {

                        //
                        // Do the work for updating the current address
                        //

                        //
                        // This points to the public Command Block.
                        //
                        PNE3200_SUPER_COMMAND_BLOCK CommandBlock;

                        //
                        // This points to the adapter's configuration block.
                        //
                        PNE3200_CONFIGURATION_BLOCK ConfigurationBlock =
                            Adapter->ConfigurationBlock;

                        //
                        // Get a public command block.
                        //
                        NE3200AcquirePublicCommandBlock(Adapter,
                                                        &CommandBlock
                                                       );

                        Adapter->ResetHandlerCommandBlock = CommandBlock;

                        //
                        // Setup the command block.
                        //

                        CommandBlock->NextCommand = NULL;

                        CommandBlock->Hardware.State = NE3200_STATE_WAIT_FOR_ADAPTER;
                        CommandBlock->Hardware.Status = 0;
                        CommandBlock->Hardware.NextPending = NE3200_NULL;
                        CommandBlock->Hardware.CommandCode =
                            NE3200_COMMAND_CONFIGURE_82586;
                        CommandBlock->Hardware.PARAMETERS.CONFIGURE.ConfigurationBlock =
                            NdisGetPhysicalAddressLow(Adapter->ConfigurationBlockPhysical);

                        //
                        // Now that we've got the command block built,
                        // let's do it!
                        //
                        NE3200SubmitCommandBlock(Adapter, CommandBlock);

                        Adapter->ResetState = NE3200ResetStateReloadAddress;
                        Adapter->ResetTimeoutCounter = NE3200_TIMEOUT_DOWNLOAD;

                    }

                } else if (Status == NE3200_INITIALIZATION_FAILED) {

                    //
                    // Initialization failed.  Notify the wrapper.
                    //
                    Adapter->ResetResult = NE3200ResetResultInitializationFailure;
                    Adapter->ResetState = NE3200ResetStateComplete;

                    NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                } else {

                    //
                    // See if we've timed-out waiting for the download to
                    // complete.
                    //
                    Adapter->ResetTimeoutCounter--;

                    if (Adapter->ResetTimeoutCounter == 0) {

                        //
                        // We've timed-out.  Bad news.
                        //
                        Adapter->ResetResult = NE3200ResetResultInitializationTimeout;
                        Adapter->ResetState = NE3200ResetStateComplete;

                        NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                    } else {

                        //
                        // For Synchronous resets, we stall.  For async,
                        // we set a timer to check later.
                        //
                        if (!Adapter->ResetAsynchronous) {

                            //
                            // Otherwise, wait and try again.
                            //
                            NdisStallExecution(10000);

                        } else{

                            //
                            // Try again later.
                            //
                            NdisMSetTimer(&Adapter->ResetTimer, 100);
                            return;

                        }

                    }

                }

                break;

            //
            // Part Last: Waiting for the configuring of the adapter
            // to complete
            //
            case NE3200ResetStateReloadAddress :

                //
                // Read the command block status.
                //
                if (Adapter->ResetHandlerCommandBlock->Hardware.State ==
                    NE3200_STATE_EXECUTION_COMPLETE) {

                    //
                    // return this command block
                    //
                    NE3200RelinquishCommandBlock(Adapter,
                                                 Adapter->ResetHandlerCommandBlock
                                                );

                    //
                    // Reset is complete.  Do those indications.
                    //
                    Adapter->ResetResult = NE3200ResetResultSuccessful;
                    Adapter->ResetState = NE3200ResetStateComplete;

                    NE3200DoResetIndications(Adapter, NDIS_STATUS_SUCCESS);

                } else {

                    //
                    // See if we've timed-out.
                    //
                    Adapter->ResetTimeoutCounter--;

                    if (Adapter->ResetTimeoutCounter == 0) {

                        //
                        // We've timed-out.  Bad news.
                        //

                        //
                        // return this command block
                        //
                        NE3200RelinquishCommandBlock(Adapter,
                                                     Adapter->ResetHandlerCommandBlock
                                                    );

                        Adapter->ResetResult = NE3200ResetResultInitializationTimeout;
                        Adapter->ResetState = NE3200ResetStateComplete;

                        NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                    } else {

                        if ( Adapter->ResetTimeoutCounter ==
                                (NE3200_TIMEOUT_DOWNLOAD/2) ) {

                            //
                            // The command may have stalled, try again.
                            //
                            NE3200_WRITE_LOCAL_DOORBELL_INTERRUPT(
                                Adapter,
                                NE3200_LOCAL_DOORBELL_NEW_COMMAND
                                );

                        }

                        //
                        // For Synchronous resets, we stall.  For async,
                        // we set a timer to check later.
                        //
                        if (!Adapter->ResetAsynchronous) {

                            //
                            // Otherwise, wait and try again.
                            //
                            NdisStallExecution(10000);

                        } else{

                            //
                            // Check again later
                            //
                            NdisMSetTimer(&Adapter->ResetTimer, 100);
                            return;

                        }

                    }

                }

                break;

            default :

                //
                // Somehow, we reached an invalid state.
                //

                //
                // We'll try to salvage our way out of this.
                //
                Adapter->ResetResult = NE3200ResetResultInvalidState;
                Adapter->ResetState = NE3200ResetStateComplete;

                NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                NdisWriteErrorLogEntry(
                    Adapter->MiniportAdapterHandle,
                    NDIS_ERROR_CODE_HARDWARE_FAILURE,
                    3,
                    resetDpc,
                    NE3200_ERRMSG_BAD_STATE,
                    (ULONG)(Adapter->ResetState)
                    );

                break;
        }
Exemplo n.º 7
0
NDIS_STATUS	RTMPAllocTxRxRingMemory(
	IN	PRTMP_ADAPTER	pAd)
{
	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
	ULONG			RingBasePaHigh;
	ULONG			RingBasePaLow;
	PVOID			RingBaseVa;
	INT				index, num;
	PTXD_STRUC		pTxD;
	PRXD_STRUC		pRxD;
	ULONG			ErrorValue = 0;
	PRTMP_TX_RING	pTxRing;
	PRTMP_DMABUF	pDmaBuf;
	PNDIS_PACKET	pPacket;

	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
	do
	{
		
		
		
		
		
		for (num=0; num<NUM_OF_TX_RING; num++)
		{
			ULONG  BufBasePaHigh;
			ULONG  BufBasePaLow;
			PVOID  BufBaseVa;

			
			
			
			pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE;
			RTMP_AllocateTxDescMemory(
				pAd,
				num,
				pAd->TxDescRing[num].AllocSize,
				FALSE,
				&pAd->TxDescRing[num].AllocVa,
				&pAd->TxDescRing[num].AllocPa);

			if (pAd->TxDescRing[num].AllocVa == NULL)
			{
				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
				Status = NDIS_STATUS_RESOURCES;
				break;
			}

			
			NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize);

			
			RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa);
			RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa);
			RingBaseVa     = pAd->TxDescRing[num].AllocVa;

			
			
			
			pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
			RTMP_AllocateFirstTxBuffer(
				pAd,
				num,
				pAd->TxBufSpace[num].AllocSize,
				FALSE,
				&pAd->TxBufSpace[num].AllocVa,
				&pAd->TxBufSpace[num].AllocPa);

			if (pAd->TxBufSpace[num].AllocVa == NULL)
			{
				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
				Status = NDIS_STATUS_RESOURCES;
				break;
			}

			
			NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize);

			
			BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa);
			BufBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa);
			BufBaseVa     = pAd->TxBufSpace[num].AllocVa;

			
			
			
			pTxRing = &pAd->TxRing[num];
			for (index = 0; index < TX_RING_SIZE; index++)
			{
				pTxRing->Cell[index].pNdisPacket = NULL;
				pTxRing->Cell[index].pNextNdisPacket = NULL;
				
				pTxRing->Cell[index].AllocSize = TXD_SIZE;
				pTxRing->Cell[index].AllocVa = RingBaseVa;
				RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh);
				RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow);

				
				pDmaBuf = &pTxRing->Cell[index].DmaBuf;
				pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
				pDmaBuf->AllocVa = BufBaseVa;
				RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh);
				RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow);

				
				pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa;
				pTxD->SDPtr0 = BufBasePaLow;
				
				pTxD->DMADONE = 1;
				RingBasePaLow += TXD_SIZE;
				RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;

				
				BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
				BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
			}
			DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index));
		}
		if (Status == NDIS_STATUS_RESOURCES)
			break;

		
		
		
		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
		RTMP_AllocateMgmtDescMemory(
			pAd,
			pAd->MgmtDescRing.AllocSize,
			FALSE,
			&pAd->MgmtDescRing.AllocVa,
			&pAd->MgmtDescRing.AllocPa);

		if (pAd->MgmtDescRing.AllocVa == NULL)
		{
			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
			Status = NDIS_STATUS_RESOURCES;
			break;
		}

		
		NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);

		
		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa);
		RingBaseVa     = pAd->MgmtDescRing.AllocVa;

		
		
		
		for (index = 0; index < MGMT_RING_SIZE; index++)
		{
			pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
			pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
			
			pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
			pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
			RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh);
			RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow);

			
			RingBasePaLow += TXD_SIZE;
			RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;

			
			pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa;
			pTxD->DMADONE = 1;

			
		}
		DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index));

		
		
		
		pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
		RTMP_AllocateRxDescMemory(
			pAd,
			pAd->RxDescRing.AllocSize,
			FALSE,
			&pAd->RxDescRing.AllocVa,
			&pAd->RxDescRing.AllocPa);

		if (pAd->RxDescRing.AllocVa == NULL)
		{
			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
			Status = NDIS_STATUS_RESOURCES;
			break;
		}

		
		NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize);


		printk("RX DESC %p  size = %ld\n", pAd->RxDescRing.AllocVa,
					pAd->RxDescRing.AllocSize);

		
		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa);
		RingBaseVa     = pAd->RxDescRing.AllocVa;

		
		
		
		for (index = 0; index < RX_RING_SIZE; index++)
		{
			
			pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
			pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
			RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh);
			RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow);

			
			RingBasePaLow += RXD_SIZE;
			RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE;

			
			pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
			pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
			pPacket = RTMP_AllocateRxPacketBuffer(
				pAd,
				pDmaBuf->AllocSize,
				FALSE,
				&pDmaBuf->AllocVa,
				&pDmaBuf->AllocPa);

			
			pAd->RxRing.Cell[index].pNdisPacket = pPacket;

			
			if (pDmaBuf->AllocVa == NULL)
			{
				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
				DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
				Status = NDIS_STATUS_RESOURCES;
				break;
			}

			
			NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);

			
			pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
			pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
			pRxD->DDONE = 0;
		}

		DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index));

	}	while (FALSE);


	NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
	pAd->FragFrame.pFragPacket =  RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);

	if (pAd->FragFrame.pFragPacket == NULL)
	{
		Status = NDIS_STATUS_RESOURCES;
	}

	if (Status != NDIS_STATUS_SUCCESS)
	{
		
		NdisWriteErrorLogEntry(
			pAd->AdapterHandle,
			NDIS_ERROR_CODE_OUT_OF_RESOURCES,
			1,
			ErrorValue);
	}

	DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
	return Status;
}
Exemplo n.º 8
0
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//  Routine Name:   NetFlexRingStatus
//
//  Description:
//      This routine does the clean up work necessary
//      when a ring status occurs.
//
//  Input:
//      acb - Our Driver Context for this adapter or head.
//
//  Output:
//      None
//
//  Called By:
//      NetFlexHandleInterrupt
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VOID
NetFlexRingStatus(
    PACB acb
    )
{
    USHORT value;
    ULONG  RingStatus = 0;

    value = acb->acb_ssb_virtptr->SSB_Status;

    DebugPrint(1,("NF(%d): RingStatus value = %x\n",acb->anum, value));

    //
    // Determine the reason for the ring interrupt.
    //
    if (value & RING_STATUS_SIGNAL_LOSS)
    {
        RingStatus |= NDIS_RING_SIGNAL_LOSS;
        DebugPrint(1,("NF(%d): RING_STATUS_SIGNAL_LOSS\n",acb->anum));

        //
        // Have we already reported the error?
        //
        if (!acb->SentRingStatusLog &&
            ((acb->acb_lastringstatus & RING_STATUS_SIGNAL_LOSS) == 0))
        {
            // no, so send one.
            NdisWriteErrorLogEntry( acb->acb_handle,
                                    EVENT_NDIS_SIGNAL_LOSS_ERROR,
                                    3,
                                    NETFLEX_RINGSTATUS_ERROR_CODE,
                                    (ULONG) acb->acb_baseaddr,
                                    (ULONG) value
                                    );
            acb->SentRingStatusLog = TRUE;
        }
    }

    if (value & RING_STATUS_HARD_ERROR)
    {
        RingStatus |= NDIS_RING_HARD_ERROR;
        DebugPrint(1,("NF(%d): RING_STATUS_HARD_ERROR\n",acb->anum));
    }
    if (value & RING_STATUS_SOFT_ERROR)
    {
        RingStatus |= NDIS_RING_SOFT_ERROR;
        DebugPrint(1,("NF(%d): RING_STATUS_SOFT_ERROR\n",acb->anum));
    }
    if (value & RING_STATUS_XMIT_BEACON)
    {
        RingStatus |= NDIS_RING_TRANSMIT_BEACON;
        DebugPrint(1,("NF(%d): RING_STATUS_XMIT_BEACON\n",acb->anum));
    }
    if (value & RING_STATUS_LOBE_WIRE_FAULT)
    {
        RingStatus |= NDIS_RING_LOBE_WIRE_FAULT;
        DebugPrint(1,("NF(%d): RING_STATUS_LOBE_WIRE_FAULT\n",acb->anum));
        //
        // Have we already reported the error?
        //
        if (!acb->SentRingStatusLog &&
            ((acb->acb_lastringstatus & NDIS_RING_LOBE_WIRE_FAULT) == 0))
        {
            // no, so send one.
            NdisWriteErrorLogEntry( acb->acb_handle,
                                    EVENT_NDIS_LOBE_FAILUE_ERROR,
                                    3,
                                    NETFLEX_RINGSTATUS_ERROR_CODE,
                                    (ULONG) acb->acb_baseaddr,
                                    (ULONG) value
                                    );

            acb->SentRingStatusLog = TRUE;
        }
    }

    if (value & (RING_STATUS_AUTO_REMOVE_1 | RING_STATUS_REMOVE_RECEIVED))
    {
        if (value & RING_STATUS_AUTO_REMOVE_1)
        {
            RingStatus |= NDIS_RING_AUTO_REMOVAL_ERROR;
            DebugPrint(1,("NF(%d): RING_STATUS_AUTO_REMOVE_1\n",acb->anum));
        }
        if (value & RING_STATUS_REMOVE_RECEIVED)
        {
            RingStatus |= NDIS_RING_REMOVE_RECEIVED;
            DebugPrint(1,("NF(%d): RING_STATUS_REMOVE_RECEIVED\n",acb->anum));
        }
        //
        // Have we already reported the error?
        //
        if ((acb->acb_lastringstatus &
                (RING_STATUS_AUTO_REMOVE_1 | RING_STATUS_REMOVE_RECEIVED )) == 0)
        {
            // no, so send one.
            NdisWriteErrorLogEntry( acb->acb_handle,
                                    EVENT_NDIS_REMOVE_RECEIVED_ERROR,
                                    3,
                                    NETFLEX_RINGSTATUS_ERROR_CODE,
                                    (ULONG) acb->acb_baseaddr,
                                    (ULONG) value
                                    );
        }
    }

    if (value & RING_STATUS_OVERFLOW)
    {
         RingStatus |= NDIS_RING_COUNTER_OVERFLOW;
         DebugPrint(1,("NF(%d): RING_STATUS_OVERFLOW\n",acb->anum));
    }

    if (value & RING_STATUS_SINGLESTATION)
    {
        RingStatus |= NDIS_RING_SINGLE_STATION;
        DebugPrint(1,("NF(%d): RING_STATUS_SINGLESTATION\n",acb->anum));
    }

    if (value & RING_STATUS_RINGRECOVERY)
    {
        RingStatus |= NDIS_RING_RING_RECOVERY;
        DebugPrint(1,("NF(%d): RING_STATUS_RINGRECOVERY\n",acb->anum));
    }

    //
    // Save the Ring Status
    //
    acb->acb_lastringstatus = RingStatus;


    //
    // Indicate to the filter the ring status.
    //
    NdisMIndicateStatus(
        acb->acb_handle,
        NDIS_STATUS_RING_STATUS,
        &RingStatus,
        sizeof(ULONG)
        );

    //
    // Tell the filter that we have completed the ring status.
    //
    NdisMIndicateStatusComplete(acb->acb_handle);
}
Exemplo n.º 9
0
BOOLEAN
NE3200InitialInit(
    IN PNE3200_ADAPTER Adapter,
    IN UINT NE3200InterruptVector,
    IN NDIS_INTERRUPT_MODE NE3200InterruptMode
    )

/*++

Routine Description:

    This routine sets up the initial init of the driver, by
    stopping the adapter, connecting the interrupt and initializing
    the adapter.

Arguments:

    Adapter - The adapter for the hardware.

Return Value:

    TRUE if the initialization succeeds, else FALSE.

--*/

{
    //
    // Status of NDIS calls
    //
    NDIS_STATUS Status;

    //
    // First we make sure that the device is stopped.
    //
    NE3200StopChip(Adapter);

    //
    // The ISR will set this to FALSE if we get an interrupt
    //
    Adapter->InitialInit = TRUE;

    //
    // Initialize the interrupt.
    //
    Status = NdisMRegisterInterrupt(
                 &Adapter->Interrupt,
                 Adapter->MiniportAdapterHandle,
                 NE3200InterruptVector,
                 NE3200InterruptVector,
                 FALSE,
                 FALSE,
                 NE3200InterruptMode
                 );

    //
    // So far so good
    //
    if (Status == NDIS_STATUS_SUCCESS) {

        //
        // Now try to initialize the adapter
        //
        if (!NE3200SetConfigurationBlockAndInit(Adapter)) {

            //
            // Failed. Write out an error log entry.
            //
            NdisWriteErrorLogEntry(
                Adapter->MiniportAdapterHandle,
                NDIS_ERROR_CODE_TIMEOUT,
                2,
                initialInit,
                NE3200_ERRMSG_NO_DELAY
                );

            //
            // Unhook the interrupt
            //
            NdisMDeregisterInterrupt(&Adapter->Interrupt);

            Adapter->InitialInit = FALSE;

            return FALSE;

        }

        //
        // Get hardware assigned network address.
        //
        NE3200GetStationAddress(
            Adapter
            );

        //
        // We can start the chip.  We may not
        // have any bindings to indicate to but this
        // is unimportant.
        //
        Status = NE3200ChangeCurrentAddress(Adapter);

        Adapter->InitialInit = FALSE;

        return(Status == NDIS_STATUS_SUCCESS);

    } else {

        //
        // Interrupt line appears to be taken.  Notify user.
        //
        NdisWriteErrorLogEntry(
            Adapter->MiniportAdapterHandle,
            NDIS_ERROR_CODE_INTERRUPT_CONNECT,
            2,
            initialInit,
            NE3200_ERRMSG_INIT_INTERRUPT
            );

        Adapter->InitialInit = FALSE;

        return(FALSE);
    }

}
Exemplo n.º 10
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);
        }
    }
}
Exemplo n.º 11
0
NDIS_STATUS 
MPInitializeEx(
    __in  NDIS_HANDLE             AdapterHandle,
    __in  NDIS_HANDLE             MiniportDriverContext,
    __in  PNDIS_MINIPORT_INIT_PARAMETERS     MiniportInitParameters
    )
{
    PHWT_ADAPTER    newAdapter = NULL;
    NDIS_STATUS     ndisStatus;
    UNREFERENCED_PARAMETER(MiniportDriverContext);

    DbgPrint("[HWTest]: MPInitializeEx -->\n");
    do
    {
        
        ndisStatus = MpAllocateAdapter(AdapterHandle, &newAdapter);
        if (ndisStatus != NDIS_STATUS_SUCCESS)
        {
            DbgPrint("[HWTest]: MpAllocateAdapter return %08x\n", ndisStatus);
            break;
        }
        
        ndisStatus = NICInitializeAdapter(newAdapter, AdapterHandle);
        if (ndisStatus != NDIS_STATUS_SUCCESS)
        {
            DbgPrint("[HWTest]: NICInitializeAdapter return %08x\n", ndisStatus);
            ndisStatus = NDIS_STATUS_FAILURE;
            break;
        }

        ndisStatus = MpSetRegistrationAttributes(newAdapter);
        if (ndisStatus != NDIS_STATUS_SUCCESS)
        {
            DbgPrint("[HWTest]: MpSetRegistrationAttributes return %08x\n", ndisStatus);
            break;
        }

        ndisStatus = MpSetMiniportAttributes(newAdapter);
        if (ndisStatus != NDIS_STATUS_SUCCESS)
        {
            DbgPrint("[HWTest]: MpSetMiniportAttributes return %08x\n", ndisStatus);
            break;
        }

        ndisStatus = VNicAllocateNdisPort(AdapterHandle, &newAdapter->PortNumber);
        if (ndisStatus != NDIS_STATUS_SUCCESS)
        {
            DbgPrint("[HWTest]: VNicAllocateNdisPort return %08x\n", ndisStatus);
            break;
        }

    } while (FALSE);
    
    if (ndisStatus != NDIS_STATUS_SUCCESS)
    {
        if (newAdapter != NULL)
        {
            VNicFreeNdisPort(newAdapter);
            NICCleanAdapter(newAdapter);
            MpFreeAdapter(newAdapter);
            NdisWriteErrorLogEntry(AdapterHandle, NDIS_ERROR_CODE_HARDWARE_FAILURE, 0);
        }
    }
    else
    {
        NICAttachAdapter(newAdapter);
        NICRegisterDevice();
    }

    DbgPrint("[HWTest]: MPInitializeEx return %08x\n", ndisStatus);
    return ndisStatus;
}
Exemplo n.º 12
0
/*
	========================================================================

	Routine Description:
		Allocate DMA memory blocks for send, receive

	Arguments:
		Adapter		Pointer to our adapter

	Return Value:
		NDIS_STATUS_SUCCESS
		NDIS_STATUS_FAILURE
		NDIS_STATUS_RESOURCES

	IRQL = PASSIVE_LEVEL

	Note:

	========================================================================
*/
NDIS_STATUS	RTMPAllocTxRxRingMemory(
	IN	PRTMP_ADAPTER	pAd)
{
	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
	ULONG			RingBasePaHigh;
	ULONG			RingBasePaLow;
	PVOID			RingBaseVa;
	INT				index, num;
	PTXD_STRUC		pTxD;
	PRXD_STRUC		pRxD;
	ULONG			ErrorValue = 0;
	PRTMP_TX_RING	pTxRing;
	PRTMP_DMABUF	pDmaBuf;
	PNDIS_PACKET	pPacket;

	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
	do
	{
		//
		// Allocate all ring descriptors, include TxD, RxD, MgmtD.
		// Although each size is different, to prevent cacheline and alignment
		// issue, I intentional set them all to 64 bytes.
		//
		for (num=0; num<NUM_OF_TX_RING; num++)
		{
			ULONG  BufBasePaHigh;
			ULONG  BufBasePaLow;
			PVOID  BufBaseVa;

			//
			// Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA)
			//
			pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE;
			RTMP_AllocateTxDescMemory(
				pAd,
				num,
				pAd->TxDescRing[num].AllocSize,
				FALSE,
				&pAd->TxDescRing[num].AllocVa,
				&pAd->TxDescRing[num].AllocPa);

			if (pAd->TxDescRing[num].AllocVa == NULL)
			{
				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
				Status = NDIS_STATUS_RESOURCES;
				break;
			}

			// Zero init this memory block
			NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize);

			// Save PA & VA for further operation
			RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa);
			RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa);
			RingBaseVa     = pAd->TxDescRing[num].AllocVa;

			//
			// Allocate all 1st TXBuf's memory for this TxRing
			//
			pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
			RTMP_AllocateFirstTxBuffer(
				pAd,
				num,
				pAd->TxBufSpace[num].AllocSize,
				FALSE,
				&pAd->TxBufSpace[num].AllocVa,
				&pAd->TxBufSpace[num].AllocPa);

			if (pAd->TxBufSpace[num].AllocVa == NULL)
			{
				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
				Status = NDIS_STATUS_RESOURCES;
				break;
			}

			// Zero init this memory block
			NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize);

			// Save PA & VA for further operation
			BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa);
			BufBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa);
			BufBaseVa     = pAd->TxBufSpace[num].AllocVa;

			//
			// Initialize Tx Ring Descriptor and associated buffer memory
			//
			pTxRing = &pAd->TxRing[num];
			for (index = 0; index < TX_RING_SIZE; index++)
			{
				pTxRing->Cell[index].pNdisPacket = NULL;
				pTxRing->Cell[index].pNextNdisPacket = NULL;
				// Init Tx Ring Size, Va, Pa variables
				pTxRing->Cell[index].AllocSize = TXD_SIZE;
				pTxRing->Cell[index].AllocVa = RingBaseVa;
				RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh);
				RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow);

				// Setup Tx Buffer size & address. only 802.11 header will store in this space
				pDmaBuf = &pTxRing->Cell[index].DmaBuf;
				pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
				pDmaBuf->AllocVa = BufBaseVa;
				RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh);
				RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow);

				// link the pre-allocated TxBuf to TXD
				pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa;
				pTxD->SDPtr0 = BufBasePaLow;
				// advance to next ring descriptor address
				pTxD->DMADONE = 1;
				RingBasePaLow += TXD_SIZE;
				RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;

				// advance to next TxBuf address
				BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
				BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
			}
			DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index));
		}
		if (Status == NDIS_STATUS_RESOURCES)
			break;

		//
		// Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler
		//
		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
		RTMP_AllocateMgmtDescMemory(
			pAd,
			pAd->MgmtDescRing.AllocSize,
			FALSE,
			&pAd->MgmtDescRing.AllocVa,
			&pAd->MgmtDescRing.AllocPa);

		if (pAd->MgmtDescRing.AllocVa == NULL)
		{
			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
			Status = NDIS_STATUS_RESOURCES;
			break;
		}

		// Zero init this memory block
		NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);

		// Save PA & VA for further operation
		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa);
		RingBaseVa     = pAd->MgmtDescRing.AllocVa;

		//
		// Initialize MGMT Ring and associated buffer memory
		//
		for (index = 0; index < MGMT_RING_SIZE; index++)
		{
			pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
			pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
			// Init MGMT Ring Size, Va, Pa variables
			pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
			pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
			RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh);
			RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow);

			// Offset to next ring descriptor address
			RingBasePaLow += TXD_SIZE;
			RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;

			// link the pre-allocated TxBuf to TXD
			pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa;
			pTxD->DMADONE = 1;

			// no pre-allocated buffer required in MgmtRing for scatter-gather case
		}
		DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index));

		//
		// Allocate RX ring descriptor's memory except Tx ring which allocated eariler
		//
		pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
		RTMP_AllocateRxDescMemory(
			pAd,
			pAd->RxDescRing.AllocSize,
			FALSE,
			&pAd->RxDescRing.AllocVa,
			&pAd->RxDescRing.AllocPa);

		if (pAd->RxDescRing.AllocVa == NULL)
		{
			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
			Status = NDIS_STATUS_RESOURCES;
			break;
		}

		// Zero init this memory block
		NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize);


		printk("RX DESC %p  size = %ld\n", pAd->RxDescRing.AllocVa,
					pAd->RxDescRing.AllocSize);

		// Save PA & VA for further operation
		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa);
		RingBaseVa     = pAd->RxDescRing.AllocVa;

		//
		// Initialize Rx Ring and associated buffer memory
		//
		for (index = 0; index < RX_RING_SIZE; index++)
		{
			// Init RX Ring Size, Va, Pa variables
			pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
			pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
			RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh);
			RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow);

			// Offset to next ring descriptor address
			RingBasePaLow += RXD_SIZE;
			RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE;

			// Setup Rx associated Buffer size & allocate share memory
			pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
			pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
			pPacket = RTMP_AllocateRxPacketBuffer(
				pAd,
				pDmaBuf->AllocSize,
				FALSE,
				&pDmaBuf->AllocVa,
				&pDmaBuf->AllocPa);

			/* keep allocated rx packet */
			pAd->RxRing.Cell[index].pNdisPacket = pPacket;

			// Error handling
			if (pDmaBuf->AllocVa == NULL)
			{
				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
				DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
				Status = NDIS_STATUS_RESOURCES;
				break;
			}

			// Zero init this memory block
			NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);

			// Write RxD buffer address & allocated buffer length
			pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
			pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
			pRxD->DDONE = 0;
		}

		DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index));

	}	while (FALSE);


	NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
	pAd->FragFrame.pFragPacket =  RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);

	if (pAd->FragFrame.pFragPacket == NULL)
	{
		Status = NDIS_STATUS_RESOURCES;
	}

	if (Status != NDIS_STATUS_SUCCESS)
	{
		// Log error inforamtion
		NdisWriteErrorLogEntry(
			pAd->AdapterHandle,
			NDIS_ERROR_CODE_OUT_OF_RESOURCES,
			1,
			ErrorValue);
	}

	DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
	return Status;
}
Exemplo n.º 13
0
NDIS_STATUS
NdisMAllocateMapRegisters(
	IN	NDIS_HANDLE				MiniportAdapterHandle,
	IN	UINT					DmaChannel,
	IN	BOOLEAN					Dma32BitAddresses,
	IN	ULONG					PhysicalMapRegistersNeeded,
	IN	ULONG					MaximumPhysicalMapping
	)

/*++

Routine Description:

	Allocates map registers for bus mastering devices.

Arguments:

	MiniportAdapterHandle - Handle passed to MiniportInitialize.

	PhysicalMapRegistersNeeded - The maximum number of map registers needed
		by the Miniport at any one time.

	MaximumPhysicalMapping - Maximum length of a buffer that will have to be mapped.

Return Value:

	None.

--*/

{
	//
	// Convert the handle to our internal structure.
	//
	PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK) MiniportAdapterHandle;

	//
	// This is needed by HalGetAdapter.
	//
	DEVICE_DESCRIPTION DeviceDescription;

	//
	// Returned by HalGetAdapter.
	//
	ULONG MapRegistersAllowed;

	//
	// Returned by HalGetAdapter.
	//
	PADAPTER_OBJECT AdapterObject;

	//
	// Map registers needed per channel.
	//
	ULONG MapRegistersPerChannel;

	NTSTATUS NtStatus;

	KIRQL OldIrql;

	UINT i;

	LARGE_INTEGER TimeoutValue;

	//
	// If the device is a busmaster, we get an adapter
	// object for it.
	// If map registers are needed, we loop, allocating an
	// adapter channel for each map register needed.
	//

	if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_BUS_MASTER) &&
		(Miniport->BusType != (NDIS_INTERFACE_TYPE)-1) &&
		(Miniport->BusNumber != (ULONG)-1))
	{
		TimeoutValue.QuadPart = Int32x32To64(2 * 1000, -10000);

		Miniport->PhysicalMapRegistersNeeded = PhysicalMapRegistersNeeded;
		Miniport->MaximumPhysicalMapping = MaximumPhysicalMapping;

		//
		// Allocate storage for holding the appropriate
		// information for each map register.
		//

		Miniport->MapRegisters = (PMAP_REGISTER_ENTRY)
		ALLOC_FROM_POOL(sizeof(MAP_REGISTER_ENTRY) * PhysicalMapRegistersNeeded,
						NDIS_TAG_DEFAULT);

		if (Miniport->MapRegisters == (PMAP_REGISTER_ENTRY)NULL)
		{
			//
			// Error out
			//

			NdisWriteErrorLogEntry((NDIS_HANDLE)Miniport,
								   NDIS_ERROR_CODE_OUT_OF_RESOURCES,
								   1,
								   0xFFFFFFFF);

			return NDIS_STATUS_RESOURCES;
		}

		//
		// Use this event to tell us when ndisAllocationExecutionRoutine
		// has been called.
		//

		INITIALIZE_EVENT(&Miniport->AllocationEvent);

		//
		// Set up the device description; zero it out in case its
		// size changes.
		//

		ZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION));

		DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
		DeviceDescription.Master = TRUE;
		DeviceDescription.ScatterGather = TRUE;

		DeviceDescription.BusNumber = Miniport->BusNumber;
		DeviceDescription.DmaChannel = DmaChannel;
		DeviceDescription.InterfaceType = Miniport->AdapterType;

		if (DeviceDescription.InterfaceType == NdisInterfaceIsa)
		{
			//
			// For ISA devices, the width is based on the DMA channel:
			// 0-3 == 8 bits, 5-7 == 16 bits. Timing is compatibility
			// mode.
			//

			if (DmaChannel > 4)
			{
				DeviceDescription.DmaWidth = Width16Bits;
			}
			else
			{
				DeviceDescription.DmaWidth = Width8Bits;
			}
			DeviceDescription.DmaSpeed = Compatible;

		}
		else if ((DeviceDescription.InterfaceType == NdisInterfaceEisa)	||
				 (DeviceDescription.InterfaceType == NdisInterfacePci)	||
				 (DeviceDescription.InterfaceType == NdisInterfaceMca))
		{
			DeviceDescription.Dma32BitAddresses = Dma32BitAddresses;
		}

		DeviceDescription.MaximumLength = MaximumPhysicalMapping;

		//
		// Get the adapter object.
		//

		AdapterObject = HalGetAdapter (&DeviceDescription, &MapRegistersAllowed);

		if (AdapterObject == NULL)
		{
			NdisWriteErrorLogEntry((NDIS_HANDLE)Miniport,
								   NDIS_ERROR_CODE_OUT_OF_RESOURCES,
								   1,
								   0xFFFFFFFF);

			FREE_POOL(Miniport->MapRegisters);
			Miniport->MapRegisters = NULL;
			DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
					("<==NdisRegisterAdapter\n"));
			return NDIS_STATUS_RESOURCES;
		}

		//
		// We save this to call IoFreeMapRegisters later.
		//

		Miniport->SystemAdapterObject = AdapterObject;

		//
		// Determine how many map registers we need per channel.
		//

		MapRegistersPerChannel = ((MaximumPhysicalMapping - 2) / PAGE_SIZE) + 2;

		ASSERT (MapRegistersAllowed >= MapRegistersPerChannel);

		//
		// Now loop, allocating an adapter channel each time, then
		// freeing everything but the map registers.
		//

		for (i=0; i<Miniport->PhysicalMapRegistersNeeded; i++)
		{
			Miniport->CurrentMapRegister = i;

			RAISE_IRQL_TO_DISPATCH(&OldIrql);

			NtStatus = IoAllocateAdapterChannel(AdapterObject,
												Miniport->DeviceObject,
												MapRegistersPerChannel,
												ndisAllocationExecutionRoutine,
												Miniport);

			if (!NT_SUCCESS(NtStatus))
			{
				DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
						("AllocateAdapterChannel: %lx\n", NtStatus));

				for (; i != 0; i--)
				{
					IoFreeMapRegisters(Miniport->SystemAdapterObject,
									   Miniport->MapRegisters[i-1].MapRegister,
									   MapRegistersPerChannel);
				}

				LOWER_IRQL(OldIrql);

				NdisWriteErrorLogEntry((NDIS_HANDLE)Miniport,
									   NDIS_ERROR_CODE_OUT_OF_RESOURCES,
									   1,
									   0xFFFFFFFF);

				FREE_POOL(Miniport->MapRegisters);
				Miniport->MapRegisters = NULL;
				return NDIS_STATUS_RESOURCES;
			}

			LOWER_IRQL(OldIrql);

			TimeoutValue.QuadPart = Int32x32To64(2 * 1000, -10000);

			//
			// ndisAllocationExecutionRoutine will set this event
			// when it has gotten FirstTranslationEntry.
			//

			NtStatus = WAIT_FOR_OBJECT(&Miniport->AllocationEvent, &TimeoutValue);

			if (NtStatus != STATUS_SUCCESS)
			{
				DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
						("NDIS DMA AllocateAdapterChannel: %lx\n", NtStatus));

				RAISE_IRQL_TO_DISPATCH(&OldIrql);

				for (; i != 0; i--)
				{
					IoFreeMapRegisters(Miniport->SystemAdapterObject,
									   Miniport->MapRegisters[i-1].MapRegister,
									   MapRegistersPerChannel);
				}

				LOWER_IRQL(OldIrql);

				NdisWriteErrorLogEntry((NDIS_HANDLE)Miniport,
										NDIS_ERROR_CODE_OUT_OF_RESOURCES,
										1,
										0xFFFFFFFF);

				FREE_POOL(Miniport->MapRegisters);
				Miniport->MapRegisters = NULL;
				return  NDIS_STATUS_RESOURCES;
			}

			RESET_EVENT(&Miniport->AllocationEvent);
		}
	}

	return NDIS_STATUS_SUCCESS;
}
Exemplo n.º 14
0
/*----------------------------------------------------------------------------*/
NDIS_STATUS
windowsRegisterIsrt (
    IN P_GLUE_INFO_T prGlueInfo
    )
{
    NDIS_STATUS rStatus;
    P_GL_HIF_INFO_T   prHifInfo;

    DEBUGFUNC("windowsRegisterIsrt");

    ASSERT(prGlueInfo);
    prHifInfo = &prGlueInfo->rHifInfo;

    /* Next we'll register our interrupt with the NDIS wrapper. */
    /* Hook our interrupt vector.  We used level-triggered, shared
       interrupts with our PCI adapters. */
    INITLOG(("Register IRQ: handle=0x%x, irq=0x%x, level-triggered\n",
        prGlueInfo->rMiniportAdapterHandle, prHifInfo->u4InterruptLevel));

    rStatus = NdisMRegisterInterrupt(&prHifInfo->rInterrupt,
                                    prGlueInfo->rMiniportAdapterHandle,
                                    (UINT) prHifInfo->u4InterruptVector,
                                    (UINT) prHifInfo->u4InterruptLevel,
                                    TRUE,   /* RequestIsr */
                                    FALSE,   /* SharedInterrupt */
                                    NIC_INTERRUPT_MODE);

    if (rStatus != NDIS_STATUS_SUCCESS) {
        ERRORLOG(("Interrupt conflict: status=0x%08x, IRQ=%d, level-sensitive\n",
            rStatus, prHifInfo->u4InterruptLevel));

        NdisWriteErrorLogEntry(prGlueInfo->rMiniportAdapterHandle,
            NDIS_ERROR_CODE_INTERRUPT_CONNECT, 1,
            (UINT_32) prHifInfo->u4InterruptLevel);
    }

    GLUE_SET_FLAG(prGlueInfo, GLUE_FLAG_INTERRUPT_IN_USE);

    INITLOG(("Register interrupt -- OK\n"));

#if SC32442_SPI
    {
        UINT_32 g_SysIntr;

        prHifInfo->gWaitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

        if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,
                             &prHifInfo->u4InterruptLevel,
                             sizeof(UINT32), &g_SysIntr,
                             sizeof(UINT32), NULL)) {
              INITLOG(("ERROR:Failed to request sysintr value for Timer1 inturrupt!/n"));
        }
        else {
            INITLOG(("Request sysintr value %d!/r/n", g_SysIntr));
            prHifInfo->u4sysIntr = g_SysIntr;
        }

        if (!(InterruptInitialize(g_SysIntr, prHifInfo->gWaitEvent, 0, 0)))
        {
            INITLOG(("ERROR: Interrupt initialize failed.\n"));
        }
    }
#endif

    return rStatus;
} /* windowsRegisterIsrt */