📄 skxmac2.c
字号:
pPrt->PLinkMode == SK_LMODE_FULL) { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("InitPhyXmac: no autonegotiation Port %d\n", Port)); /* No Autonegiotiation */ /* Set DuplexMode in Config register */ Crtl = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); /* * Do NOT enable Autonegotiation here. This would hold * the link down because no IDLES are transmitted */ } else { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("InitPhyXmac: with autonegotiation Port %d\n", Port)); /* Set Autonegotiation advertisement */ Crtl = 0; /* Set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: Crtl |= PHY_X_AN_HD; break; case SK_LMODE_AUTOFULL: Crtl |= PHY_X_AN_FD; break; case SK_LMODE_AUTOBOTH: Crtl |= PHY_X_AN_FD | PHY_X_AN_HD; break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, SKERR_HWI_E015MSG) ; } switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Crtl |= PHY_X_P_NO_PAUSE; break; case SK_FLOW_MODE_LOC_SEND: Crtl |= PHY_X_P_ASYM_MD; break; case SK_FLOW_MODE_SYMMETRIC: Crtl |= PHY_X_P_SYM_MD; break; case SK_FLOW_MODE_SYM_OR_REM: Crtl |= PHY_X_P_BOTH_MD; break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, SKERR_HWI_E016MSG) ; } /* Write AutoNeg Advertisement Register */ PHY_WRITE(IoC, pPrt, Port, PHY_XMAC_AUNE_ADV, Crtl) ; /* Restart Autonegotiation */ Crtl = PHY_CT_ANE | PHY_CT_RE_CFG; } if (DoLoop) { /* Set the Phy Loopback bit, too */ Crtl |= PHY_CT_LOOP; } /* Write to the Phy control register */ PHY_WRITE(IoC, pPrt, Port, PHY_XMAC_CTRL, Crtl) ;}/****************************************************************************** * * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers * * Description: * Initialize all the Broadcom Phy registers * * Note: * * Returns: * nothing */static void SkXmInitPhyBcom(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port, /* Port Index (MAC_1 + n) */SK_BOOL DoLoop) /* Should a Phy LOOback be set-up? */{ SK_GEPORT *pPrt; SK_U16 Crtl1 = PHY_B_CT_SP1000; SK_U16 Crtl2 = 0; SK_U16 Crtl3 = PHY_SEL_TYPE; SK_U16 Crtl4 = PHY_B_PEC_EN_LTR; SK_U16 Crtl5 = PHY_B_AC_TX_TST; pPrt = &pAC->GIni.GP[Port]; /* manuell Master/Slave ? */ if (pPrt->PMSMode != SK_MS_MODE_AUTO) { Crtl2 |= PHY_B_1000C_MSE; if (pPrt->PMSMode == SK_MS_MODE_MASTER) { Crtl2 |= PHY_B_1000C_MSC; } } /* Autonegotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("InitPhyBcom: no autonegotiation Port %d\n", Port)); /* No Autonegiotiation */ /* Set DuplexMode in Config register */ Crtl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); /* Determine Master/Slave manuell if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { Crtl2 |= PHY_B_1000C_MSE; /* set it to Slave */ } /* * Do NOT enable Autonegotiation here. This would hold * the link down because no IDLES are transmitted */ } else { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("InitPhyBcom: with autonegotiation Port %d\n", Port)); /* Set Autonegotiation advertisement */ /* Set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: Crtl2 |= PHY_B_1000C_AHD; break; case SK_LMODE_AUTOFULL: Crtl2 |= PHY_B_1000C_AFD; break; case SK_LMODE_AUTOBOTH: Crtl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD; break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, SKERR_HWI_E015MSG) ; } switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Crtl3 |= PHY_B_P_NO_PAUSE; break; case SK_FLOW_MODE_LOC_SEND: Crtl3 |= PHY_B_P_ASYM_MD; break; case SK_FLOW_MODE_SYMMETRIC: Crtl3 |= PHY_B_P_SYM_MD; break; case SK_FLOW_MODE_SYM_OR_REM: Crtl3 |= PHY_B_P_BOTH_MD; break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, SKERR_HWI_E016MSG); } /* Restart Autonegotiation */ Crtl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; } /* Initialize LED register here? */ /* No. Please do it in SkDgXmitLed() (if required) and swap init order of LEDs and XMAC. (MAl) */ /* Write 1000Base-T Control Register */ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_1000T_CTRL, Crtl2); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("1000Base-T Control Reg = %x\n", Crtl2)); /* Write AutoNeg Advertisement Register */ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUNE_ADV, Crtl3); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNeg Advertisment Reg = %x\n", Crtl3)); if (DoLoop) { /* Set the Phy Loopback bit, too */ Crtl1 |= PHY_CT_LOOP; } if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { /* configure fifo to high latency for xmission of ext. packets*/ Crtl4 |= PHY_B_PEC_HIGH_LA; /* configure reception of extended packets */ Crtl5 |= PHY_B_AC_LONG_PACK; PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, Crtl5); } /* Configure LED Traffic Mode and Jumbo Frame usage if specified */ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_P_EXT_CTRL, Crtl4); /* Write to the Phy control register */ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, Crtl1); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("PHY Control Reg = %x\n", Crtl1));}/****************************************************************************** * * SkXmInitPhyLone() - Initialize the Level One Phy registers * * Description: * Initialize 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 LOOback be set-up? */{ SK_GEPORT *pPrt; SK_U16 Crtl1 = PHY_L_CT_SP1000; SK_U16 Crtl2 = 0; SK_U16 Crtl3 = PHY_SEL_TYPE; pPrt = &pAC->GIni.GP[Port]; /* manuell Master/Slave ? */ if (pPrt->PMSMode != SK_MS_MODE_AUTO) { Crtl2 |= PHY_L_1000C_MSE; if (pPrt->PMSMode == SK_MS_MODE_MASTER) { Crtl2 |= PHY_L_1000C_MSC; } } /* Autonegotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { /* * level one spec say: "1000Mbps: manual mode not allowed" * but lets see what happens... */ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, 0, "Level One PHY only works with Autoneg"); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("InitPhyLone: no autonegotiation Port %d\n", Port)); /* No Autonegiotiation */ /* Set DuplexMode in Config register */ Crtl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); /* Determine Master/Slave manuell if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { Crtl2 |= PHY_L_1000C_MSE; /* set it to Slave */ } /* * Do NOT enable Autonegotiation 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 autonegotiation Port %d\n", Port)); /* Set Autonegotiation advertisement */ /* Set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: Crtl2 |= PHY_L_1000C_AHD; break; case SK_LMODE_AUTOFULL: Crtl2 |= PHY_L_1000C_AFD; break; case SK_LMODE_AUTOBOTH: Crtl2 |= 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) ; } switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Crtl3 |= PHY_L_P_NO_PAUSE; break; case SK_FLOW_MODE_LOC_SEND: Crtl3 |= PHY_L_P_ASYM_MD; break; case SK_FLOW_MODE_SYMMETRIC: Crtl3 |= PHY_L_P_SYM_MD; break; case SK_FLOW_MODE_SYM_OR_REM: Crtl3 |= PHY_L_P_BOTH_MD; break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, SKERR_HWI_E016MSG); } /* Restart Autonegotiation */ Crtl1 = PHY_CT_ANE | PHY_CT_RE_CFG; } /* Initialize LED register here ? */ /* No. Please do it in SkDgXmitLed() (if required) and swap init order of LEDs and XMAC. (MAl) */ /* Write 1000Base-T Control Register */ PHY_WRITE(IoC, pPrt, Port, PHY_LONE_1000T_CTRL, Crtl2); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("1000Base-T Control Reg = %x\n", Crtl2)); /* Write AutoNeg Advertisement Register */ PHY_WRITE(IoC, pPrt, Port, PHY_LONE_AUNE_ADV, Crtl3); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNeg Advertisment Reg = %x\n", Crtl3)); if (DoLoop) { /* Set the Phy Loopback bit, too */ Crtl1 |= PHY_CT_LOOP; } if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { /* * nothing to do for Level one. * PHY supports frames up to 10k. */ } /* Write to the Phy control register */ PHY_WRITE(IoC, pPrt, Port, PHY_LONE_CTRL, Crtl1); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("PHY Control Reg = %x\n", Crtl1));}/****************************************************************************** * * SkXmInitPhyNat() - Initialize the National Phy registers * * Description: * Initialize 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 LOOback be set-up? */{/* todo: National */}/****************************************************************************** * * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do autoneg * * This function analyses the Interrupt status word. If any of the * Autonegotiating interrupt bits are set, the PLipaAutoNeg variable * is set true. */void SkXmAutoNegLipaXmac(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port, /* Port Index (MAC_1 + n) */SK_U16 IStatus) /* Interrupt Status word to analyse */{ SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && (IStatus & (XM_IS_LIPA_RC|XM_IS_RX_PAGE|XM_IS_AND))) { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, IStatus)); pPrt->PLipaAutoNeg = SK_LIPA_AUTO; }}/****************************************************************************** * * SkXmAutoNegLipaBcom() - Decides whether Link Partner could do autoneg * * This function analyses the PHY status word. If any of the * Autonegotiating bits are set, The PLipaAutoNeg variable * is set true. */void SkXmAutoNegLipaBcom(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port, /* Port Index (MAC_1 + n) */SK_U16 PhyStat) /* PHY Status word to analyse */{ SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && (PhyStat & (PHY_ST_AN_OVER))) { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat)); pPrt->PLipaAutoNeg = SK_LIPA_AUTO; }}/****************************************************************************** * * SkXmAutoNegLipaLone() - Decides whether Link Partner could do autoneg * * This function analyses the PHY status word. If any of the * Autonegotiating bits are set, The PLipaAutoNeg variable * is set true. */void SkXmAutoNegLipaLone(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port, /* Port Index (MAC_1 + n) */SK_U16 PhyStat) /* PHY Status word to analyse */{ SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && (PhyStat & (PHY_ST_AN_OVER))) { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat)); pPrt->PLipaAutoNeg = SK_LIPA_AUTO; }}/****************************************************************************** * * SkXmAutoNegLipaNat() - Decides whether Link Partner could do autoneg * * This function analyses the PHY status word. If any of the * Autonegotiating bits are set, The PLipaAutoNeg variable * is set true. */void SkXmAutoNegLipaNat(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port, /* Port Index (MAC_1 + n) */SK_U16 PhyStat) /* PHY Status word to analyse */{ SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && (PhyStat & (PHY_ST_AN_OVER))) { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegLipa: AutoNeg detected on port %d %x\n", Port, PhyStat)); pPrt->PLipaAutoNeg = SK_LIPA_AUTO; }}/****************************************************************************** * * SkXmAutoNegDone() - Auto negotiation handling * * Description: * This function handles the autonegotiation if the Done bit is set. * * Note: * o The XMACs interrupt source register is NOT read here. * o This function is public because it is used in the diagnostics * tool, too. * * Returns: * SK_AND_OK o.k. * SK_AND_DUP_CAP Duplex capability error happened * SK_AND_OTHER Other error happened */int SkXmAutoNegDone(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port) /* Port Index (MAC_1 + n) */{ SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; switch (pPrt->PhyType) { case SK_PHY_XMAC: return (SkXmAutoNegDoneXmac(pAC, IoC, Port)); case SK_PHY_BCOM: return (SkXmAutoNegDoneBcom(pAC, IoC, Port)); case SK_PHY_LONE: return (SkXmAutoNegDoneLone(pAC, IoC, Port)); case SK_PHY_NAT: return (SkXmAutoNegDoneNat(pAC, IoC, Port)); } return(SK_AND_OTHER);}/****************************************************************************** * * SkXmAutoNegDoneXmac() - Auto negotiation handling * * Description: * This function handles the autonegotiation if the Done bit is set. * * Note: * o The XMACs interrupt source register is NOT read here. * * Returns: * SK_AND_OK o.k. * SK_AND_DUP_CAP Duplex capability error happened * SK_AND_OTHER Other error happened */static int SkXmAutoNegDoneXmac(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port) /* Port Index (MAC_1 + n) */{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -