📄 skxmac2.c
字号:
Word |= (SK_U16)PCI_ENA_GPHY_LNK; SK_OUT16(IoC, PCI_C(pAC, PCI_OUR_REG_1), Word);#endif /* PCI_E_L1_STATE */ } pAC->GIni.GP[Port].PState = SK_PRT_STOP; break; /* don't change current power mode */ default: pAC->GIni.GP[Port].PPhyPowerState = LastMode; 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, /* I/O Context */int Port) /* Port Index (e.g. MAC_1) */{ SK_U32 DWord; SK_U32 PowerDownBit; SK_U16 Word; SK_U8 LastMode; int ChipId; int Ret = 0; if (!(CHIP_ID_YUKON_2(pAC) || (pAC->GIni.GIYukonLite && pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3))) { return(1); } /* save current power mode */ LastMode = pAC->GIni.GP[Port].PPhyPowerState; pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE; ChipId = pAC->GIni.GIChipId; SK_DBG_MSG(pAC, SK_DBGMOD_POWM, SK_DBGCAT_CTRL, ("SkGmLeaveLowPowerMode: %u\n", LastMode)); switch (LastMode) { /* COMA mode (deep sleep) */ case PHY_PM_DEEP_SLEEP: if (ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX || ChipId >= CHIP_ID_YUKON_FE_P) {#ifdef PCI_E_L1_STATE SkPciReadCfgWord(pAC, PCI_OUR_REG_1, &Word); /* set the default value into bits 6 & 5 */ Word &= ~(SK_U16)(PCI_ENA_GPHY_LNK | PCI_FORCE_PEX_L1); SkPciWriteCfgWord(pAC, PCI_OUR_REG_1, Word);#endif /* PCI_E_L1_STATE */ SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_4), &DWord); DWord &= P_ASPM_CONTROL_MSK; /* set all bits to 0 except bits 15..12 and 8 */ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_4), DWord); /* set to default value */ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), 0); } SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &Word); if ((Word & PCI_PM_STATE_MSK) != 0) { /* switch to D0 state */ SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, Word & ~PCI_PM_STATE_MSK); } SK_TST_MODE_ON(IoC); if (CHIP_ID_YUKON_2(pAC)) { /* disable Core Clock Division */ SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS); /* set power down bit */ PowerDownBit = (Port == MAC_1) ? PCI_Y2_PHY1_POWD : PCI_Y2_PHY2_POWD; } else { PowerDownBit = PCI_PHY_COMA; } SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord); /* Release PHY from PowerDown/COMA Mode */ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord & ~PowerDownBit); SK_TST_MODE_OFF(IoC); if (CHIP_ID_YUKON_2(pAC)) { if (ChipId == CHIP_ID_YUKON_FE) { /* release IEEE compatible Power Down Mode */ Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_ANE); } else if (ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX || ChipId >= CHIP_ID_YUKON_FE_P) { /* release GPHY Control reset */ SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_CLR); } } else { 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: if (ChipId != CHIP_ID_YUKON_XL) { Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); Word &= ~PHY_M_PC_DIS_125CLK; /* enable MAC 125 MHz clock */ Word |= PHY_M_PC_MAC_POW_UP; /* set MAC power up */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); /* these register changes must be followed by a software reset */ 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: if (ChipId != CHIP_ID_YUKON_XL) { Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); if (ChipId == CHIP_ID_YUKON_FE || ChipId == CHIP_ID_YUKON_FE_P) { /* disable Energy Detect */ Word &= ~PHY_M_PC_ENA_ENE_DT; } else { /* disable energy detect mode & enable MAC 125 MHz clock */ Word &= ~(PHY_M_PC_EN_DET_MSK | PHY_M_PC_DIS_125CLK); }#ifdef XXX /* enable Polarity Reversal */ Word &= ~PHY_M_PC_POL_R_DIS;#endif /* XXX */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); /* these register changes must be followed by a software reset */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); Word |= PHY_CT_RESET; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); } break; /* don't change current power mode */ default: pAC->GIni.GP[Port].PPhyPowerState = LastMode; Ret = 1; } return(Ret);} /* SkGmLeaveLowPowerMode */#endif /* SK_PHY_LP_MODE *//****************************************************************************** * * 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, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */SK_BOOL DoLoop) /* Should a PHY LoopBack be set-up? */{ SK_GEPORT *pPrt; SK_BOOL AutoNeg; SK_BOOL NewPhyType; SK_U16 PhyCtrl; SK_U16 C1000BaseT; SK_U16 AutoNegAdv; SK_U8 PauseMode; int ChipId;#ifndef SK_SLIM int MacCtrl; SK_U16 LoopSpeed;#endif /* !SK_SLIM */ SK_U16 Word; SK_U16 PageReg;#ifndef VCPU SK_U16 PhySpec; SK_U16 ExtPhyCtrl; SK_U16 BlinkCtrl; SK_U16 LedCtrl; SK_U16 LedConf; SK_U16 LedOver; int Mode;#ifndef SK_DIAG SK_EVPARA Para;#endif /* !SK_DIAG */#if (defined(SK_DIAG) || (defined(DEBUG) && !defined(SK_SLIM))) SK_U16 PhyStat; SK_U16 PhyStat1; SK_U16 PhySpecStat;#endif /* SK_DIAG || (DEBUG && !SK_SLIM) */#endif /* !VCPU */ /* set Pause On */ PauseMode = (SK_U8)GMC_PAUSE_ON; pPrt = &pAC->GIni.GP[Port]; ChipId = pAC->GIni.GIChipId; NewPhyType = HW_HAS_NEWER_PHY(pAC); /* Auto-negotiation ? */ AutoNeg = pPrt->PLinkMode != SK_LMODE_HALF && pPrt->PLinkMode != SK_LMODE_FULL; SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyMarv: Port %d, Auto-neg. %s, LMode %d, LSpeed %d, FlowC %d\n", Port, AutoNeg ? "ON" : "OFF", pPrt->PLinkMode, pPrt->PLinkSpeed, pPrt->PFlowCtrlMode));#ifndef VCPU ExtPhyCtrl = 0; /* read Id from PHY */ if (SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1) != 0) {#ifndef SK_DIAG Para.Para64 = Port; SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);#endif /* !SK_DIAG */ return; }#endif /* !VCPU */ if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {#ifndef SK_SLIM if (DoLoop) { /* special setup for newer PHYs */ if (NewPhyType) { LoopSpeed = pPrt->PLinkSpeed; if (LoopSpeed == SK_LSPEED_AUTO) { /* force 1000 Mbps */ LoopSpeed = SK_LSPEED_1000MBPS; } LoopSpeed += 2; /* save page register */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_ADR, &PageReg); /* select page 2 to access MAC control register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 2); if (ChipId == CHIP_ID_YUKON_XL) { /* set PHY reg 0, page 2, field [6:4] */ MacCtrl = PHY_MARV_CTRL; LoopSpeed <<= 4; } else { /* * CHIP_ID_YUKON_EC_U || CHIP_ID_YUKON_EX || * >= CHIP_ID_YUKON_SUPR */ /* set PHY reg 21, page 2, field [2:0] */ MacCtrl = PHY_MARV_MAC_CTRL; } /* set MAC interface speed */ SkGmPhyWrite(pAC, IoC, Port, MacCtrl, LoopSpeed); /* restore page register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, PageReg); /* disable link pulses */ Word = PHY_M_PC_DIS_LINK_P; } else { /* set 'MAC Power up'-bit, set Manual MDI configuration */ Word = PHY_M_PC_MAC_POW_UP; } SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); }#ifndef VCPU else#endif /* !VCPU */#endif /* !SK_SLIM */#ifndef VCPU if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO && !NewPhyType && (pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { /* 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); /* on PHY 88E1040 Rev.D0 (and newer) downshift control changed */ if (pAC->GIni.GIYukonLite || ChipId == CHIP_ID_YUKON_EC) { /* set downshift counter to 3x and enable downshift */ ExtPhyCtrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA; } else { /* set master & slave downshift counter to 1x */ ExtPhyCtrl |= 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)); }#endif /* !VCPU */ }#ifndef VCPU if (CHIP_ID_YUKON_2(pAC)) { /* Read PHY Specific Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &PhySpec); if (!DoLoop && pAC->GIni.GICopperType) { if (ChipId == CHIP_ID_YUKON_FE || ChipId == CHIP_ID_YUKON_FE_P) { /* enable Automatic Crossover (!!! Bits 5..4) */ PhySpec |= (SK_U16)(PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1); if (ChipId == CHIP_ID_YUKON_FE_P && pAC->GIni.GIChipRev == CHIP_REV_YU_FE2_A0) { /* Enable Class A driver for FE+ A0 */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_FE_SPEC_2, &Word); Word |= PHY_M_FESC_SEL_CL_A; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_FE_SPEC_2, Word); } } else { if (!pPrt->PEnDetMode) { /* disable Energy Detect Mode */ PhySpec &= ~PHY_M_PC_EN_DET_MSK; } /* enable Automatic Crossover */ PhySpec |= (SK_U16)PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); /* downshift on PHY 88E1112 and 88E1149 is changed */ if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO && NewPhyType) { /* set downshift counter to 3x and enable downshift */ PhySpec &= ~PHY_M_PC_DSC_MSK; PhySpec |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; } } } /* workaround for deviation #4.88 (CRC errors) */ else { /* disable Automatic Crossover */ PhySpec &= ~PHY_M_PC_MDIX_MSK; } SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PhySpec); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Set PHY Spec Reg. = 0x%04X\n", PhySpec)); } /* special setup for PHY 88E1112 Fiber */ if (ChipId == CHIP_ID_YUKON_XL && !pAC->GIni.GICopperType) { /* select 1000BASE-X only mode in MAC Specific Ctrl Reg. */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 2); SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); Word &= ~PHY_M_MAC_MD_MSK; Word |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX); SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); /* select page 1 to access Fiber registers */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 1); if (pAC->GIni.GIPmdTyp == 'P') { /* for SFP-module set SIGDET polarity to low */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); Word |= PHY_M_FIB_SIGD_POL; SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); } }#endif /* !VCPU */ /* Read PHY Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); Word = PhyCtrl; if (!AutoNeg) { /* disable Auto-negotiation */ Word &= ~PHY_CT_ANE; } /* assert software reset */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word | PHY_CT_RESET); PhyCtrl = 0 /* PHY_CT_COL_TST */; C1000BaseT = 0; AutoNegAdv = PHY_SEL_TYPE;#ifndef SK_SLIM /* 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 */ } }#endif /* !SK_SLIM */ /* Auto-negotiation ? */ if (!AutoNeg) { if (pPrt->PLinkMode == SK_LMODE_FULL) { /* set Full Duplex Mode */ PhyCtrl |= PHY_CT_DUP_MD; }#ifndef SK_SLIM /* set Master/Slave manually if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */ }#endif /* !SK_SLIM */ /* set Speed */ switch (pPrt->PLinkSpeed) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -