skxmac2.c
来自「linux 内核源代码」· C语言 代码 · 共 2,599 行 · 第 1/5 页
C
2,599 行
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 */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);#endif /* XXX */#ifndef VCPU if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) { /* Write Ext. PHY Specific Control */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, (SK_U16)((pPrt->PLinkSpeed + 2) << 4)); }#endif /* VCPU */ }#ifdef TEST_ONLY else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) { /* Write PHY Specific Control */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_EN_DET_MSK); }#endif /* Write to the PHY Control register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl));#ifdef VCPU VCpuWait(2000);#else LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS); if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) { LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL; } if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) { LedCtrl |= PHY_M_LEDC_DP_CTRL; } SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl); if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) { /* only in forced 100 Mbps mode */ if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) { SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER, PHY_M_LED_MO_100(MO_LED_ON)); } }#ifdef SK_DIAG c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl); c_print("Set 1000 B-T=0x%04X\n", C1000BaseT); c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv); c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl);#endif /* SK_DIAG */#if defined(SK_DIAG) || defined(DEBUG) /* Read PHY Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); /* Read 1000Base-T Control Register */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("1000B-T Ctrl =0x%04X\n", C1000BaseT)); /* Read AutoNeg Advertisement Register */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); /* Read Ext. PHY Specific Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); /* Read PHY Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("PHY Stat Reg.=0x%04X\n", PhyStat)); SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("PHY Stat Reg.=0x%04X\n", PhyStat1)); /* Read PHY Specific Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("PHY Spec Stat=0x%04X\n", PhySpecStat));#endif /* SK_DIAG || DEBUG */#ifdef SK_DIAG c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl); c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT); c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv); c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl); c_print("PHY Stat Reg=0x%04X\n", PhyStat); c_print("PHY Stat Reg=0x%04X\n", PhyStat1); c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);#endif /* SK_DIAG */#endif /* VCPU */} /* SkGmInitPhyMarv */#endif /* YUKON */#ifdef OTHER_PHY/****************************************************************************** * * SkXmInitPhyLone() - Initialize the Level One Phy registers * * Description: initializes all the Level One Phy registers * * Note: * * Returns: * nothing */static void SkXmInitPhyLone(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 Ctrl1; SK_U16 Ctrl2; SK_U16 Ctrl3; Ctrl1 = PHY_CT_SP1000; Ctrl2 = 0; Ctrl3 = PHY_SEL_TYPE; pPrt = &pAC->GIni.GP[Port]; /* manually Master/Slave ? */ if (pPrt->PMSMode != SK_MS_MODE_AUTO) { Ctrl2 |= PHY_L_1000C_MSE; if (pPrt->PMSMode == SK_MS_MODE_MASTER) { Ctrl2 |= PHY_L_1000C_MSC; } } /* Auto-negotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { /* * level one spec say: "1000 Mbps: manual mode not allowed" * but lets see what happens... */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyLone: no auto-negotiation Port %d\n", Port)); /* Set DuplexMode in Config register */ if (pPrt->PLinkMode == SK_LMODE_FULL) { Ctrl1 |= PHY_CT_DUP_MD; } /* Determine Master/Slave manually if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */ } /* * Do NOT enable Auto-negotiation here. This would hold * the link down because no IDLES are transmitted */ } else { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyLone: with auto-negotiation Port %d\n", Port)); /* Set Auto-negotiation advertisement */ /* Set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: Ctrl2 |= PHY_L_1000C_AHD; break; case SK_LMODE_AUTOFULL: Ctrl2 |= PHY_L_1000C_AFD; break; case SK_LMODE_AUTOBOTH: Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD; 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: Ctrl3 |= PHY_L_P_NO_PAUSE; break; case SK_FLOW_MODE_LOC_SEND: Ctrl3 |= PHY_L_P_ASYM_MD; break; case SK_FLOW_MODE_SYMMETRIC: Ctrl3 |= PHY_L_P_SYM_MD; break; case SK_FLOW_MODE_SYM_OR_REM: Ctrl3 |= PHY_L_P_BOTH_MD; break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, SKERR_HWI_E016MSG); } /* Restart Auto-negotiation */ Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG; } /* Write 1000Base-T Control Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); /* Write AutoNeg Advertisement Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); if (DoLoop) { /* Set the Phy Loopback bit, too */ Ctrl1 |= PHY_CT_LOOP; } /* Write to the Phy control register */ SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("PHY Control Reg=0x%04X\n", Ctrl1));} /* SkXmInitPhyLone *//****************************************************************************** * * SkXmInitPhyNat() - Initialize the National Phy registers * * Description: initializes all the National Phy registers * * Note: * * Returns: * nothing */static void SkXmInitPhyNat(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? */{/* todo: National */} /* SkXmInitPhyNat */#endif /* OTHER_PHY *//****************************************************************************** * * SkMacInitPhy() - Initialize the PHY registers * * Description: calls the Init PHY routines dep. on board type * * Note: * * Returns: * nothing */void SkMacInitPhy(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; pPrt = &pAC->GIni.GP[Port];#ifdef GENESIS if (pAC->GIni.GIGenesis) { switch (pPrt->PhyType) { case SK_PHY_XMAC: SkXmInitPhyXmac(pAC, IoC, Port, DoLoop); break; case SK_PHY_BCOM: SkXmInitPhyBcom(pAC, IoC, Port, DoLoop); break;#ifdef OTHER_PHY case SK_PHY_LONE:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?