BOOLEAN MPSetPowerLowPrivate( PVOID Context ) /*++ Routine Description: The section follows the steps mentioned in Section C.2.6.2 of the Reference Manual. Arguments: Adapter Pointer to our adapter Return Value: --*/ { CSR_FILTER_STRUC Filter; USHORT IntStatus; MP_PMCSR PMCSR = {0}; ULONG ulResult; PFDO_DATA FdoData = Context; DebugPrint(TRACE, DBG_POWER, "-->MPSetPowerLowPrivate\n"); RtlZeroMemory (&Filter, sizeof (Filter)); do { // // Before issue the command to low power state, we should disable the // interrup and ack all the pending interrupts, then set the adapter's power to // low state. // NICDisableInterrupt(FdoData); NIC_ACK_INTERRUPT(FdoData, IntStatus); // // If the driver should wake up the machine // if (FdoData->AllowWakeArming) { // // Send the WakeUp Patter to the nic MPIssueScbPoMgmtCommand(FdoData, &Filter, TRUE); // // Section C.2.6.2 - The driver needs to wait for the CU to idle // The above function already waits for the CU to idle // ASSERT ((FdoData->CSRAddress->ScbStatus & SCB_CUS_MASK) == SCB_CUS_IDLE); } else { ulResult = FdoData->BusInterface.GetBusData( FdoData->BusInterface.Context, PCI_WHICHSPACE_CONFIG, (PVOID)&PMCSR, FIELD_OFFSET(MP_PM_PCI_SPACE, PMCSR), sizeof(PMCSR)); if(ulResult != sizeof(PMCSR)){ ASSERT(ulResult == sizeof(PMCSR)); DebugPrint(ERROR, DBG_POWER, "GetBusData for PMCSR failed\n"); return FALSE; } if (PMCSR.PME_En == 1) { // // PME is enabled. Clear the PME_En bit. // So that it is not asserted // MpClearPME_En (FdoData,PMCSR); } // // Set the driver to lower power state by OS // } } while (FALSE); DebugPrint(TRACE, DBG_POWER, "<--MPSetPowerLowPrivate\n"); return TRUE; }
VOID NICExtractPMInfoFromPciSpace( PFDO_DATA FdoData, PUCHAR pPciConfig ) /*++ Routine Description: Looks at the PM information in the device specific section of the PCI Config space. Interprets the register values and stores it in the adapter structure Definitions from Table 4.2 & 4.3, Pg 4-9 & 4-10 of the 10/100 Mbit Ethernet Family Software Technical Reference Manual Arguments: Adapter Pointer to our adapter pPciConfig Pointer to Common Pci Space Return Value: --*/ { PMP_PM_PCI_SPACE pPmPciConfig = (PMP_PM_PCI_SPACE )pPciConfig; MP_PMCSR PMCSR; // // First interpret the PM Capabities register // { MP_PM_CAP_REG PmCaps; PmCaps = pPmPciConfig->PMCaps; if(PmCaps.PME_Support & E100_PMC_WAKE_FROM_D0) { FdoData->PoMgmt.bWakeFromD0 = TRUE; } if(PmCaps.PME_Support & E100_PMC_WAKE_FROM_D1) { FdoData->PoMgmt.bWakeFromD1 = TRUE; } if(PmCaps.PME_Support & E100_PMC_WAKE_FROM_D2) { FdoData->PoMgmt.bWakeFromD2 = TRUE; } if(PmCaps.PME_Support & E100_PMC_WAKE_FROM_D3HOT) { FdoData->PoMgmt.bWakeFromD3Hot = TRUE; } if(PmCaps.PME_Support & E100_PMC_WAKE_FROM_D3_AUX) { FdoData->PoMgmt.bWakeFromD3Aux = TRUE; } } // // Interpret the PM Control/Status Register // { PMCSR = pPmPciConfig->PMCSR; if (PMCSR.PME_En == 1) { // // PME is enabled. Clear the PME_En bit. // So that it is not asserted // MpClearPME_En (FdoData,PMCSR); } } }