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

📄 routines.c

📁 Intel EtherExpressTM PRO/100+ Ethernet 网卡在Windows2000/xp下的PCI驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

//-----------------------------------------------------------------------------
// Procedure:   NICIssueSelectiveReset
//
// Description: This routine will issue a selective reset, forcing the adapter
//              the CU and RU back into their idle states.  The receive unit
//              will then be re-enabled if it was previously enabled, because
//              an RNR interrupt will be generated when we abort the RU.
//
// Arguments:
//      Adapter - ptr to Adapter object instance
//
// Returns:
//      NOTHING
//-----------------------------------------------------------------------------

VOID NICIssueSelectiveReset(
    PMP_ADAPTER Adapter)
{
    NDIS_STATUS     Status;
    BOOLEAN         bResult;
    
    // Wait for the SCB to clear before we check the CU status.
    if (!MP_TEST_FLAG(Adapter, fMP_ADAPTER_HARDWARE_ERROR))
    {
        WaitScb(Adapter);
    }

    // If we have issued any transmits, then the CU will either be active, or
    // in the suspended state.  If the CU is active, then we wait for it to be
    // suspended.  If the the CU is suspended, then we need to put the CU back
    // into the idle state by issuing a selective reset.
    if (Adapter->TransmitIdle == FALSE)
    {
        // Wait up to 2 seconds for suspended state
        MP_STALL_AND_WAIT((Adapter->CSRAddress->ScbStatus & SCB_CUS_MASK) != SCB_CUS_ACTIVE, 2000, bResult) 
        if (!bResult)
        {
            MP_SET_HARDWARE_ERROR(Adapter);
        }

        // Check the current status of the receive unit
        if ((Adapter->CSRAddress->ScbStatus & SCB_RUS_MASK) != SCB_RUS_IDLE)
        {
            // Issue an RU abort.  Since an interrupt will be issued, the
            // RU will be started by the DPC.
            Status = D100IssueScbCommand(Adapter, SCB_RUC_ABORT, TRUE);
        }

        // Issue a selective reset.
        DBGPRINT(MP_INFO, ("CU suspended. ScbStatus=%04x Issue selective reset\n", Adapter->CSRAddress->ScbStatus));
        Adapter->CSRAddress->Port = PORT_SELECTIVE_RESET;

        // Wait after a port sel-reset command
        NdisStallExecution(NIC_DELAY_POST_RESET);

        // wait up to 2 ms for port command to complete                                                           
        MP_STALL_AND_WAIT(Adapter->CSRAddress->Port == 0, 2, bResult) 
        if (!bResult)
        {
            MP_SET_HARDWARE_ERROR(Adapter);
        }

        // disable interrupts after issuing reset, because the int
        // line gets raised when reset completes.
        NICDisableInterrupt(Adapter);

        // Restore the transmit software flags.
        Adapter->TransmitIdle = TRUE;
        Adapter->ResumeWait = TRUE;
    }
}

VOID NICIssueFullReset(
    PMP_ADAPTER Adapter)
{
    BOOLEAN     bResult;

    NICIssueSelectiveReset(Adapter);

    Adapter->CSRAddress->Port = PORT_SOFTWARE_RESET;

    // wait up to 2 ms for port command to complete                                                           
    MP_STALL_AND_WAIT(Adapter->CSRAddress->Port == 0, 2, bResult);
    if (!bResult)
    {
        MP_SET_HARDWARE_ERROR(Adapter);
        return;
    }

    NICDisableInterrupt(Adapter);
}


//-----------------------------------------------------------------------------
// Procedure:   D100SubmitCommandBlockAndWait
//
// Description: This routine will submit a command block to be executed, and
//              then it will wait for that command block to be executed.  Since
//              board ints will be disabled, we will ack the interrupt in
//              this routine.
//
// Arguments:
//      Adapter - ptr to Adapter object instance
//
// Returns:
//  NDIS_STATUS_SUCCESS
//  NDIS_STATUS_HARD_ERRORS
//-----------------------------------------------------------------------------

NDIS_STATUS D100SubmitCommandBlockAndWait(
    IN PMP_ADAPTER Adapter)
{
    NDIS_STATUS     Status;
    BOOLEAN         bResult;

    // Points to the Non Tx Command Block.
    volatile PNON_TRANSMIT_CB CommandBlock = Adapter->NonTxCmdBlock;

    // Set the Command Block to be the last command block
    CommandBlock->NonTxCb.Config.ConfigCBHeader.CbCommand |= CB_EL_BIT;

    // Clear the status of the command block
    CommandBlock->NonTxCb.Config.ConfigCBHeader.CbStatus = 0;

#if DBG
    // Don't try to start the CU if the command unit is active.
    if ((Adapter->CSRAddress->ScbStatus & SCB_CUS_MASK) == SCB_CUS_ACTIVE)
    {
        DBGPRINT(MP_ERROR, ("Scb "PTR_FORMAT" ScbStatus %04x\n", Adapter->CSRAddress, Adapter->CSRAddress->ScbStatus));
        ASSERT(FALSE);
        MP_SET_HARDWARE_ERROR(Adapter);
        return(NDIS_STATUS_HARD_ERRORS);
    }
#endif

    // Start the command unit.
    D100IssueScbCommand(Adapter, SCB_CUC_START, FALSE);

    // Wait for the SCB to clear, indicating the completion of the command.
    if (!WaitScb(Adapter))
    {
        return(NDIS_STATUS_HARD_ERRORS);
    }

    // Wait for some status, timeout value 3 secs
    MP_STALL_AND_WAIT(CommandBlock->NonTxCb.Config.ConfigCBHeader.CbStatus & CB_STATUS_COMPLETE, 3000, bResult);
    if (!bResult)
    {
        MP_SET_HARDWARE_ERROR(Adapter);
        return(NDIS_STATUS_HARD_ERRORS);
    }

    // Ack any interrupts
    if (Adapter->CSRAddress->ScbStatus & SCB_ACK_MASK)
    {
        // Ack all pending interrupts now
        Adapter->CSRAddress->ScbStatus &= SCB_ACK_MASK;
    }

    // Check the status of the command, and if the command failed return FALSE,
    // otherwise return TRUE.
    if (!(CommandBlock->NonTxCb.Config.ConfigCBHeader.CbStatus & CB_STATUS_OK))
    {
        DBGPRINT(MP_ERROR, ("Command failed\n"));
        MP_SET_HARDWARE_ERROR(Adapter);
        Status = NDIS_STATUS_HARD_ERRORS;
    }
    else
        Status = NDIS_STATUS_SUCCESS;

    return(Status);
}

//-----------------------------------------------------------------------------
// Procedure: GetConnectionStatus
//
// Description: This function returns the connection status that is
//              a required indication for PC 97 specification from MS
//              the value we are looking for is if there is link to the
//              wire or not.
//
// Arguments: IN Adapter structure pointer
//
// Returns:   NdisMediaStateConnected
//            NdisMediaStateDisconnected
//-----------------------------------------------------------------------------
NDIS_MEDIA_STATE NICGetMediaState(IN PMP_ADAPTER Adapter)
{
    USHORT  MdiStatusReg = 0;
    BOOLEAN bResult1;
    BOOLEAN bResult2;
     
    
    // Read the status register at phy 1
    bResult1 = MdiRead(Adapter, MDI_STATUS_REG, Adapter->PhyAddress, TRUE, &MdiStatusReg);
    bResult2 = MdiRead(Adapter, MDI_STATUS_REG, Adapter->PhyAddress, TRUE, &MdiStatusReg);
    
    // if there is hardware failure, or let the state remains the same
    if (!bResult1 || !bResult2)
    {
        return Adapter->MediaState;
    }
    if (MdiStatusReg & MDI_SR_LINK_STATUS)
        return(NdisMediaStateConnected);
    else
        return(NdisMediaStateDisconnected);

}

⌨️ 快捷键说明

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