📄 skxmac2.c
字号:
* The PHY cannot wake up on its own. * * - energy detect mode * Power consumption: ~160 mW * The PHY can wake up on its own by detecting activity * on the CAT 5 cable. * * - energy detect plus mode * Power consumption: ~150 mW * The PHY can wake up on its own by detecting activity * on the CAT 5 cable. * Connected devices can be woken up by sending normal link * pulses every one second. * * Note: * * Returns: * 0: ok * 1: error */int SkGmEnterLowPowerMode(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port, /* Port Index (e.g. MAC_1) */SK_U8 Mode) /* low power mode */{ SK_U16 Word; SK_U32 DWord; SK_U8 LastMode; int Ret = 0; if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { /* save current power mode */ LastMode = pAC->GIni.GP[Port].PPhyPowerState; pAC->GIni.GP[Port].PPhyPowerState = Mode; switch (Mode) { /* coma mode (deep sleep) */ case PHY_PM_DEEP_SLEEP: /* setup General Purpose Control Register */ GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS | GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS); /* apply COMA mode workaround */ SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f); SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3); SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); /* Set PHY to Coma Mode */ SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); break; /* IEEE 22.2.4.1.5 compatible power down mode */ case PHY_PM_IEEE_POWER_DOWN: /* * - disable MAC 125 MHz clock * - allow MAC power down */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); Word |= PHY_M_PC_DIS_125CLK; Word &= ~PHY_M_PC_MAC_POW_UP; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); /* * register changes must be followed by a software * reset to take effect */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); Word |= PHY_CT_RESET; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); /* switch IEEE compatible power down mode on */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); Word |= PHY_CT_PDOWN; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); break; /* energy detect and energy detect plus mode */ case PHY_PM_ENERGY_DETECT: case PHY_PM_ENERGY_DETECT_PLUS: /* * - disable MAC 125 MHz clock */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); Word |= PHY_M_PC_DIS_125CLK; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); /* activate energy detect mode 1 */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); /* energy detect mode */ if (Mode == PHY_PM_ENERGY_DETECT) { Word |= PHY_M_PC_EN_DET; } /* energy detect plus mode */ else { Word |= PHY_M_PC_EN_DET_PLUS; } SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); /* * reinitialize the PHY to force a software reset * which is necessary after the register settings * for the energy detect modes. * Furthermore reinitialisation prevents that the * PHY is running out of a stable state. */ SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); break; /* don't change current power mode */ default: pAC->GIni.GP[Port].PPhyPowerState = LastMode; Ret = 1; break; } } /* low power modes are not supported by this chip */ else { Ret = 1; } return(Ret);} /* SkGmEnterLowPowerMode *//****************************************************************************** * * SkGmLeaveLowPowerMode() * * Description: * Leave the current low power mode and switch to normal mode * * Note: * * Returns: * 0: ok * 1: error */int SkGmLeaveLowPowerMode(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port) /* Port Index (e.g. MAC_1) */{ SK_U32 DWord; SK_U16 Word; SK_U8 LastMode; int Ret = 0; if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { /* save current power mode */ LastMode = pAC->GIni.GP[Port].PPhyPowerState; pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE; switch (LastMode) { /* coma mode (deep sleep) */ case PHY_PM_DEEP_SLEEP: SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); /* Release PHY from Coma Mode */ SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); SK_IN32(IoC, B2_GP_IO, &DWord); /* set to output */ DWord |= (GP_DIR_9 | GP_IO_9); /* set PHY reset */ SK_OUT32(IoC, B2_GP_IO, DWord); DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ /* clear PHY reset */ SK_OUT32(IoC, B2_GP_IO, DWord); break; /* IEEE 22.2.4.1.5 compatible power down mode */ case PHY_PM_IEEE_POWER_DOWN: /* * - enable MAC 125 MHz clock * - set MAC power up */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); Word &= ~PHY_M_PC_DIS_125CLK; Word |= PHY_M_PC_MAC_POW_UP; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); /* * register changes must be followed by a software * reset to take effect */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); Word |= PHY_CT_RESET; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); /* switch IEEE compatible power down mode off */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); Word &= ~PHY_CT_PDOWN; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); break; /* energy detect and energy detect plus mode */ case PHY_PM_ENERGY_DETECT: case PHY_PM_ENERGY_DETECT_PLUS: /* * - enable MAC 125 MHz clock */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); Word &= ~PHY_M_PC_DIS_125CLK; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); /* disable energy detect mode */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); Word &= ~PHY_M_PC_EN_DET_MSK; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); /* * reinitialize the PHY to force a software reset * which is necessary after the register settings * for the energy detect modes. * Furthermore reinitialisation prevents that the * PHY is running out of a stable state. */ SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); break; /* don't change current power mode */ default: pAC->GIni.GP[Port].PPhyPowerState = LastMode; Ret = 1; break; } } /* low power modes are not supported by this chip */ else { Ret = 1; } return(Ret);} /* SkGmLeaveLowPowerMode */#endif /* !SK_SLIM *//****************************************************************************** * * SkGmInitPhyMarv() - Initialize the Marvell Phy registers * * Description: initializes all the Marvell Phy registers * * Note: * * Returns: * nothing */static void SkGmInitPhyMarv(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port, /* Port Index (MAC_1 + n) */SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */{ SK_GEPORT *pPrt; SK_U16 PhyCtrl; SK_U16 C1000BaseT; SK_U16 AutoNegAdv; SK_U16 ExtPhyCtrl; SK_U16 LedCtrl; SK_BOOL AutoNeg;#if defined(SK_DIAG) || defined(DEBUG) SK_U16 PhyStat; SK_U16 PhyStat1; SK_U16 PhySpecStat;#endif /* SK_DIAG || DEBUG */ pPrt = &pAC->GIni.GP[Port]; /* Auto-negotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { AutoNeg = SK_FALSE; } else { AutoNeg = SK_TRUE; } SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyMarv: Port %d, auto-negotiation %s\n", Port, AutoNeg ? "ON" : "OFF"));#ifdef VCPU VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n", Port, DoLoop);#else /* VCPU */ if (DoLoop) { /* Set 'MAC Power up'-bit, set Manual MDI configuration */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_MAC_POW_UP); } else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) { /* Read Ext. PHY Specific Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | PHY_M_EC_MAC_S_MSK); ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) | PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); } /* Read PHY Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); if (!AutoNeg) { /* Disable Auto-negotiation */ PhyCtrl &= ~PHY_CT_ANE; } PhyCtrl |= PHY_CT_RESET; /* Assert software reset */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);#endif /* VCPU */ PhyCtrl = 0 /* PHY_CT_COL_TST */; C1000BaseT = 0; AutoNegAdv = PHY_SEL_TYPE; /* manually Master/Slave ? */ if (pPrt->PMSMode != SK_MS_MODE_AUTO) { /* enable Manual Master/Slave */ C1000BaseT |= PHY_M_1000C_MSE; if (pPrt->PMSMode == SK_MS_MODE_MASTER) { C1000BaseT |= PHY_M_1000C_MSC; /* set it to Master */ } } /* Auto-negotiation ? */ if (!AutoNeg) { if (pPrt->PLinkMode == SK_LMODE_FULL) { /* Set Full Duplex Mode */ PhyCtrl |= PHY_CT_DUP_MD; } /* Set Master/Slave manually if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */ } /* Set Speed */ switch (pPrt->PLinkSpeed) { case SK_LSPEED_AUTO: case SK_LSPEED_1000MBPS: PhyCtrl |= PHY_CT_SP1000; break; case SK_LSPEED_100MBPS: PhyCtrl |= PHY_CT_SP100; break; case SK_LSPEED_10MBPS: break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019, SKERR_HWI_E019MSG); } if (!DoLoop) { PhyCtrl |= PHY_CT_RESET; } } else { /* Set Auto-negotiation advertisement */ if (pAC->GIni.GICopperType) { /* Set Speed capabilities */ switch (pPrt->PLinkSpeed) { case SK_LSPEED_AUTO: C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | PHY_M_AN_10_FD | PHY_M_AN_10_HD; break; case SK_LSPEED_1000MBPS: C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; break; case SK_LSPEED_100MBPS: AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | /* advertise 10Base-T also */ PHY_M_AN_10_FD | PHY_M_AN_10_HD; break; case SK_LSPEED_10MBPS: AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD; break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019, SKERR_HWI_E019MSG); } /* Set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: C1000BaseT &= ~PHY_M_1000C_AFD; AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD); break; case SK_LMODE_AUTOFULL: C1000BaseT &= ~PHY_M_1000C_AHD; AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD); break; case SK_LMODE_AUTOBOTH: break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, SKERR_HWI_E015MSG); } /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: AutoNegAdv |= PHY_B_P_NO_PAUSE; break; case SK_FLOW_MODE_LOC_SEND: AutoNegAdv |= PHY_B_P_ASYM_MD; break; case SK_FLOW_MODE_SYMMETRIC: AutoNegAdv |= PHY_B_P_SYM_MD; break; case SK_FLOW_MODE_SYM_OR_REM: AutoNegAdv |= PHY_B_P_BOTH_MD; break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, SKERR_HWI_E016MSG); } } else { /* special defines for FIBER (88E1011S only) */ /* Set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: AutoNegAdv |= PHY_M_AN_1000X_AHD; break; case SK_LMODE_AUTOFULL: AutoNegAdv |= PHY_M_AN_1000X_AFD; break; case SK_LMODE_AUTOBOTH: AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, SKERR_HWI_E015MSG); } /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: AutoNegAdv |= PHY_M_P_NO_PAUSE_X; break; case SK_FLOW_MODE_LOC_SEND: AutoNegAdv |= PHY_M_P_ASYM_MD_X; break; case SK_FLOW_MODE_SYMMETRIC: AutoNegAdv |= PHY_M_P_SYM_MD_X; break; case SK_FLOW_MODE_SYM_OR_REM: AutoNegAdv |= PHY_M_P_BOTH_MD_X; break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, SKERR_HWI_E016MSG); } } if (!DoLoop) { /* Restart Auto-negotiation */ PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG; } } #ifdef VCPU /* * E-mail from Gu Lin (08-03-2002): */ /* Program PHY register 30 as 16'h0708 for simulation speed up */ SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */); VCpuWait(2000);#else /* VCPU */ /* Write 1000Base-T Control Register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT)); /* Write AutoNeg Advertisement Register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));#endif /* VCPU */ if (DoLoop) { /* Set the PHY Loopback bit */ PhyCtrl |= PHY_CT_LOOP;#ifdef XXX /* Program PHY register 16 as 16'h0400 to force link good */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -