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

📄 d100.c

📁 e100bex网卡驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
//              Pointer to SwRfd
//
//  DESCRIPTION: Re-initializes the given SwRfd super-structure
//               and chains it onto the current receive chain
//               We don't need to lock around this routine because
//
//  RETURNS: nothing
//
//-----------------------------------------------------------------------------

VOID
InitAndChainPacket(PD100_ADAPTER Adapter,
                   PD100SwRfd SwRfdPtr)
{
    PRFD_STRUC      Rfd;
    PD100SwRfd      LastRfd;

    DEBUGFUNC("InitAndChainPacket");
    TRACE2(Adapter,("\n"));
    DEBUGCHAR(Adapter,'9');

    Rfd = SwRfdPtr->Rfd;
    // Now we can release the receive resources back to the 82557.
    // We are done with this RFD so re-initialize it.
    Rfd->RfdCbHeader.CbStatus = 0;
    Rfd->RfdActualCount = 0;
    Rfd->RfdCbHeader.CbCommand = (RFD_EL_BIT);
    Rfd->RfdCbHeader.CbLinkPointer = DRIVER_NULL;

    // we remove this step right now because we
    // don't use any of the OOB data besides status
    // if we were noticing receive packet priorities we would probably
    // uncomment this code.
    //    NdisZeroMemory(NDIS_OOB_DATA_FROM_PACKET(SwRfd->ReceivePacket),14);


    // Append the RFD to the end of the 82557 RFD chain.  Normally, this
    // will always be done.  The only exception would be if the driver
    // was configured to use only 1 RFD (a degenerate case anyway).
    if (!QueueEmpty(&Adapter->RfdList))
    {
        LastRfd = (PD100SwRfd)QueueGetTail(&Adapter->RfdList);

        ASSERT(LastRfd);

        // Link it onto the end of the chain dynamically
        Rfd = LastRfd->Rfd;
        Rfd->RfdCbHeader.CbLinkPointer = SwRfdPtr->RfdPhys;
        Rfd->RfdCbHeader.CbCommand = 0;
        DEBUGCHAR(Adapter,(char)(LastRfd->RfdNum+48));
    }

    // The processing on this RFD is done, so put it back on the tail of
    // our list
    QueuePutTail(&Adapter->RfdList, &SwRfdPtr->Link);

    DEBUGCHAR(Adapter,'a');
}

//-----------------------------------------------------------------------------
// Procedure:   D100CheckForHang
//
// Description: This routine should check to see if the adapter is "hung", and
//              fix it if it is.  Right now this routine does not check for a
//              hang, because the adapter should never "timeout".  In the
//              future, this is where the code to check for a timeout would go,
//              if there were bugs in the chipset that could cause transmit
//              "timeouts".
//
// Arguments:
//      MiniportAdapterContext (both) - pointer to the adapter object data area
//
// Returns:
//      False (miniport) - Always
//      Nothing (mac) - Cause the function is a VOID
//-----------------------------------------------------------------------------

BOOLEAN
D100CheckForHang(NDIS_HANDLE MiniportAdapterContext)
{
    PD100_ADAPTER Adapter;
    DEBUGFUNC("D100CheckForHang");

    Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);

    NdisAcquireSpinLock(&Adapter->Lock);
    DEBUGCHAR(Adapter,'U');


    // We need to dump our statistics if we are implementing the "periodic multicast
    // command workaround"

    if (Adapter->McTimeoutFlag)
    {
        // Dump the current stats
        DumpStatsCounters(Adapter);

        // If we haven't received any frames recently, and we are implementing
        // the "periodic multicast command workaround", then we'll chain in
        // a multicast command to the transmit chain here.
        if ((Adapter->McTimeoutFlag)
            && (!(Adapter->StatsCounters->RcvGoodFrames))
            && (Adapter->AiRevID < D101_A_STEP))
            DoBogusMulticast(Adapter);
    }

    // this is the implementation of the NDIS 4 feature for detecting
    // link status change. It effectively checks every two seconds
    // for link.
    if (Adapter->LinkIsActive != GetConnectionStatus(Adapter))
        // if status has changed
    {
        DEBUGSTR(("e100bex: CheckforHang: media state changed to %s\n",
                    ((Adapter->LinkIsActive == NdisMediaStateConnected)?
                        "Disconnected": "Connected")));

        switch ( Adapter->LinkIsActive )
        {
        case NdisMediaStateConnected:           // changing from connected
            Adapter->LinkIsActive = NdisMediaStateDisconnected;
            NdisReleaseSpinLock(&Adapter->Lock);
            NdisMIndicateStatus(Adapter->D100AdapterHandle,
                NDIS_STATUS_MEDIA_DISCONNECT,
                (PVOID)0,
                0);
            // NOTE:
            // have to indicate status complete every time you indicate status
            NdisMIndicateStatusComplete(Adapter->D100AdapterHandle);

            NdisAcquireSpinLock(&Adapter->Lock);
            break;
        case NdisMediaStateDisconnected:        // changing from disconnected
            Adapter->LinkIsActive = NdisMediaStateConnected;
            NdisReleaseSpinLock(&Adapter->Lock);
            NdisMIndicateStatus(Adapter->D100AdapterHandle,
                NDIS_STATUS_MEDIA_CONNECT,
                (PVOID)0,
                0);
            // NOTE:
            // have to indicate status complete every time you indicate status
            NdisMIndicateStatusComplete(Adapter->D100AdapterHandle);

            NdisAcquireSpinLock(&Adapter->Lock);
            break;
        }
    }


    // return false to indicate that the adapter is not hung, and that
    // D100Reset does NOT need to be called by the wrapper
    DEBUGCHAR(Adapter,'u');

    NdisReleaseSpinLock(&Adapter->Lock);

    return(FALSE);
}


//-----------------------------------------------------------------------------
// Procedure:   D100Halt
//
// Description: Removes an adapter instance that was previously initialized.
//              To "halt" or "remove" an adapter, we disable its interrupt,
//              abort its receive unit (otherwise it would continue to DMA in
//              data), and release all of the resources (memory, i/o space,
//              etc.) that the adapter instance was using.
//              This routine is only called when the adapter is "stopped"
//              or unloaded with a "net stop e100b". To see what is called
//              at machine shutdown see D100ShutdownHandler.
//
// Arguments:
//      MiniportAdapterContext - pointer to the adapter object data area.
//
// Returns:     (none)
//-----------------------------------------------------------------------------

VOID
D100Halt(NDIS_HANDLE MiniportAdapterContext)

{
    PD100_ADAPTER Adapter;

    BOOLEAN     Cancelled;
    DEBUGFUNC("D100Halt");


    DEBUGSTR(("D100Halt\n"));

    Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);

    // Disable the device's interrupt line.
    D100DisableInterrupt(Adapter);

    // check to make sure there are no outstanding transmits
    while(Adapter->FirstTxQueue)
    {
        PNDIS_PACKET QueuePacket = Adapter->FirstTxQueue;

        Adapter->NumPacketsQueued--;
        DequeuePacket(Adapter->FirstTxQueue, Adapter->LastTxQueue);

        NdisMSendComplete(
            Adapter->D100AdapterHandle,
            QueuePacket,
            NDIS_STATUS_FAILURE);

    }

    while (!(QueueEmpty(&Adapter->ActiveChainList)))
    {
        // here we have to fail any sends that haven't completed yet
        PD100SwTcb pSwTcb = (PD100SwTcb) QueuePopHead(&Adapter->ActiveChainList);

        // If this wasn't a multicast command, then we need to check to see
        // if we need to issue send complete
        if ((pSwTcb->Tcb->TxCbHeader.CbCommand & CB_CMD_MASK) != CB_MULTICAST)
        {
            DEBUGCHAR(Adapter,'-');
            // Do a send Complete for this frame
            NdisMSendComplete(
                Adapter->D100AdapterHandle,
                pSwTcb->Packet,
                NDIS_STATUS_FAILURE);
        }
    }

    // deregister shutdown handler because we are halting now, and don't
    // want to have a bugcheck handler registered any more
    NdisMDeregisterAdapterShutdownHandler(Adapter->D100AdapterHandle);

    // added code to cancel our timer if for some reason it was active
    NdisMCancelTimer(&Adapter->D100AsyncResetTimer,
        &Cancelled);

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

    // Abort the Receive unit. so we don't continue to receive packets.  If
    // we didn't abort the Receive unit we could still DMA receive packets
    // into host memory after a warm boot.
    DEBUGCHAR(Adapter,'<');
    D100IssueScbCommand(Adapter, SCB_RUC_ABORT, TRUE);

    // Wait 30 Milliseconds for the device to abort the RU.  This really
    // is not necessary, but I'm a little paranoid about reseting the PHY
    // when the RU is active.
    D100StallExecution(30);

    // Reset the PHY chip.  We do this so that after a warm boot, the PHY will
    // be in a known state, with auto-negotiation enabled.
    ResetPhy(Adapter);

    NdisFreeSpinLock(&Adapter->Lock);

    // Free the entire adapter object, including the shared memory structures.
    FreeAdapterObject(Adapter);
}

//-----------------------------------------------------------------------------
// Procedure:   D100ShutdownHandler
//
// Description: Removes an adapter instance that was previously initialized.
//              To Shutdown simply Disable interrupts and Stop the receive unit.
//              Since the system is shutting down there is no need to release
//              resources (memory, i/o space, etc.) that the adapter instance
//              was using.
//
// Arguments:
//      MiniportAdapterContext - pointer to the adapter object data area.
//
// Returns:     (none)
//-----------------------------------------------------------------------------

VOID
D100ShutdownHandler(NDIS_HANDLE MiniportAdapterContext)

{

    PD100_ADAPTER Adapter;
    DEBUGFUNC("D100ShutdownHandler");

    Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);

    DEBUGSTR(("D100ShutdownHandler %8x\n",Adapter));
    DEBUGCHAR(Adapter,'!');

    // Disable the device's interrupt line.
    D100DisableInterrupt(Adapter);

    // Abort the Receive unit. so we don't continue to receive packets.  If
    // we didn't abort the Receive unit we could still DMA receive packets
    // into host memory after a warm boot.
    D100IssueScbCommand(Adapter, SCB_RUC_ABORT, TRUE);

    // Wait 30 Milliseconds for the device to abort the RU.  This really
    // is not necessary, but I'm a little paranoid about reseting the PHY
    // when the RU is active.
    D100StallExecution(30);

    // Reset the PHY chip.  We do this so that after a warm boot, the PHY will
    // be in a known state, with auto-negotiation enabled.
    ResetPhy(Adapter);

}

//-----------------------------------------------------------------------------
// Procedure:   D100Initialize/D100AddAdapter
//
// Description: This routine is called once per each supported adapter card in
//              the system.  This routine is responsible for initializing each
//              adapter.  This includes parsing all of the necessary parameters
//              from the registry, allocating and initializing shared memory
//              structures, configuring the 82557 chip, registering the
//              interrupt, and starting the receive unit.
//
// Arguments:
//      OpenErrorStatus (mini) - Returns more info about any failure
//      SelectedMediumIndex (mini) - Returns the index in MediumArray of the
//                                   medium that the miniport is using
//      MediumArraySize (mini) - An array of medium types that the driver
//                               supports
//      MiniportAdapterHandle (mini) - pointer to the adapter object data area.
//
//      WrapperConfigurationContext (both) - A value that we will pass to
//                                           NdisOpenConfiguration.
//
//
// Returns:
//      NDIS_STATUS_SUCCESS - If the adapter was initialized successfully.
//      <not NDIS_STATUS_SUCCESS> - If for some reason the adapter didn't
//                                  initialize
//-----------------------------------------------------------------------------

NDIS_STATUS
D100Initialize(PNDIS_STATUS OpenErrorStatus,
               PUINT SelectedMediumIndex,
               PNDIS_MEDIUM MediumArray,
               UINT MediumArraySize,
               NDIS_HANDLE MiniportAdapterHandle,
               NDIS_HANDLE WrapperConfigurationContext)
{
    ULONG               i;
    NDIS_STATUS         Status;
    PD100_ADAPTER       Adapter;
    NDIS_HANDLE         ConfigHandle;
    NDIS_INTERFACE_TYPE IfType;
    PVOID               OverrideNetAddress;

    DEBUGFUNC("D100Initialize");
    INITSTR(("\n"));

    // If this is a miniport, then fill in the media information.

    // if medium type 802.3 not found in list, exit with error)
    for (i = 0; i < MediumArraySize; i++)
    {
        if (MediumArray[i] == NdisMedium802_3) break;
    }

    if (i == MediumArraySize)
    {
        DEBUGSTR(("802.3 Media type not found.\n"));
        return NDIS_STATUS_UNSUPPORTED_MEDIA;
    }

    // Select ethernet
    *SelectedMediumIndex = i;

⌨️ 快捷键说明

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