📄 skgesirq.c
字号:
* have a problem. */ /* * we received a bunch of frames or no * CRC error occured on the network -> * ok. */ pPrt->PPrevRx = RxCts; pPrt->PPrevFcs = FcsErrCts; pPrt->PPrevShorts = Shorts; return(SK_HW_PS_NONE) ; } pPrt->PPrevFcs = FcsErrCts; } if ((Shorts - pPrt->PPrevShorts) > CheckShorts) { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ, ("Short Event Count Restart Port %d \n", Port)); Rtv = SK_HW_PS_RESTART; } pPrt->PPrevShorts = Shorts; pPrt->PPrevRx = RxCts; return(Rtv);}/****************************************************************************** * * SkGePortCheckUp - Implementing of the Workaround Errata # 2 * * return: * 0 o.k. nothing needed * 1 Restart needed on this port * 2 Link came up */int SkGePortCheckUp(SK_AC *pAC, /* Adapters context */SK_IOC IoC, /* IO Context */int Port) /* Which port should be checked */{ SK_GEPORT *pPrt; /* GIni Port struct pointer */ pPrt = &pAC->GIni.GP[Port]; switch (pPrt->PhyType) { case SK_PHY_XMAC: return (SkGePortCheckUpXmac(pAC, IoC, Port)); case SK_PHY_BCOM: return (SkGePortCheckUpBcom(pAC, IoC, Port)); case SK_PHY_LONE: return (SkGePortCheckUpLone(pAC, IoC, Port)); case SK_PHY_NAT: return (SkGePortCheckUpNat(pAC, IoC, Port)); } return(SK_HW_PS_NONE) ;}/****************************************************************************** * * SkGePortCheckUpXmac - Implementing of the Workaround Errata # 2 * * return: * 0 o.k. nothing needed * 1 Restart needed on this port * 2 Link came up */static int SkGePortCheckUpXmac(SK_AC *pAC, /* Adapters context */SK_IOC IoC, /* IO Context */int Port) /* Which port should be checked */{ SK_GEPORT *pPrt; /* GIni Port struct pointer */ SK_BOOL AutoNeg; /* Is Autonegotiation used ? */ SK_U16 Isrc; /* Interrupt source register */ SK_U32 GpReg; /* General Purpose register value */ SK_U16 IsrcSum; /* Interrupt source register sum */ SK_U16 LpAb; /* Link Partner Ability */ SK_U16 ResAb; /* Resolved Ability */ SK_U64 Shorts; /* Short Event Counter */ unsigned int Len; SK_U8 NextMode; /* Next AutoSensing Mode */ SK_U16 ExtStat; /* Extended Status Register */ int Done; pPrt = &pAC->GIni.GP[Port]; if (pPrt->PHWLinkUp) { if (pPrt->PhyType != SK_PHY_XMAC) { return(SK_HW_PS_NONE) ; } else { return(SkGePortCheckShorts(pAC, IoC, Port)) ; } } IsrcSum = pPrt->PIsave; pPrt->PIsave = 0; /* Now wait for each ports link */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { AutoNeg = SK_FALSE; } else { AutoNeg = SK_TRUE; } if (pPrt->PLinkBroken) { /* Link was broken */ XM_IN32(IoC,Port,XM_GP_PORT, &GpReg) ; if ((GpReg & XM_GP_INP_ASS) == 0) { /* The Link is in sync */ XM_IN16(IoC,Port,XM_ISRC, &Isrc) ; IsrcSum |= Isrc; SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); if ((Isrc & XM_IS_INP_ASS) == 0) { /* It has been in sync since last Time */ /* Restart the PORT */ SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ, ("Link in sync Restart Port %d\n", Port)); /* * We now need to reinitialize the PrevSHorts * counter. */ Len = sizeof(SK_U64); SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_RX_SHORTS, (char *) &Shorts, &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(Port)); pPrt->PPrevShorts = Shorts; pAC->GIni.GP[Port].PLinkBroken = SK_FALSE ; /* * Link Restart Workaround: * it may be possible that the other Link side * restarts its link as well an we detect * another LinkBroken. To prevent this * happening we check for a maximum number * of consecutive restart. If those happens, * we do NOT restart the active link and * check whether the lionk is now o.k. */ pAC->GIni.GP[Port].PLinkResCt ++; pPrt->PAutoNegTimeOut = 0; if (pAC->GIni.GP[Port].PLinkResCt < SK_MAX_LRESTART) { return(SK_HW_PS_RESTART) ; } SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum)); pAC->GIni.GP[Port].PLinkResCt = 0; } else { pPrt->PIsave = (SK_U16) (IsrcSum & (XM_IS_AND)); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum)); /* Do nothing more if link is broken */ return(SK_HW_PS_NONE) ; } } else { /* Do nothing more if link is broken */ return(SK_HW_PS_NONE) ; } } else { /* Link was not broken, check if it is */ XM_IN16(IoC,Port,XM_ISRC, &Isrc) ; IsrcSum |= Isrc; if ((Isrc & XM_IS_INP_ASS) == XM_IS_INP_ASS) { XM_IN16(IoC,Port,XM_ISRC, &Isrc) ; IsrcSum |= Isrc; if ((Isrc & XM_IS_INP_ASS) == XM_IS_INP_ASS) { XM_IN16(IoC,Port,XM_ISRC, &Isrc) ; IsrcSum |= Isrc; if ((Isrc & XM_IS_INP_ASS) == XM_IS_INP_ASS) { pPrt->PLinkBroken = SK_TRUE ; /* * Re-Init Link partner Autoneg flag */ pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; SK_DBG_MSG(pAC,SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link broken Port %d\n", Port)); /* cable removed-> reinit Sensemode */ /* Init default sense mode */ SkHWInitDefSense(pAC, IoC, Port); return(SK_HW_PS_RESTART) ; } } } else { SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc); if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) { return(SK_HW_PS_RESTART) ; } } } /* * here we usually can check whether the link is in sync and * autonegotiation is done. */ XM_IN32(IoC,Port,XM_GP_PORT, &GpReg) ; XM_IN16(IoC,Port,XM_ISRC, &Isrc) ; IsrcSum |= Isrc; SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) { if ((GpReg & XM_GP_INP_ASS) == 0) { /* * Save Autonegotiation Done interrupt only if link * is in sync */ pPrt->PIsave = (SK_U16) (IsrcSum & (XM_IS_AND)); }#ifdef DEBUG if (pPrt->PIsave & (XM_IS_AND)) { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNeg done rescheduled Port %d\n", Port)); }#endif return(SK_HW_PS_NONE) ; } if (AutoNeg) { if (IsrcSum & XM_IS_AND) { SkHWLinkUp(pAC, IoC, Port) ; Done = SkXmAutoNegDone(pAC,IoC,Port); if (Done != SK_AND_OK) { /* Get PHY parameters, for debuging only */ PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_LP, &LpAb); PHY_READ(IoC, pPrt, Port, PHY_XMAC_RES_ABI, &ResAb); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n", Port, LpAb, ResAb)); /* Try next possible mode */ NextMode = SkHWSenseGetNext(pAC, IoC, Port); SkHWLinkDown(pAC, IoC, Port) ; if (Done == SK_AND_DUP_CAP) { /* GoTo next mode */ SkHWSenseSetNext(pAC, IoC, Port, NextMode); } return(SK_HW_PS_RESTART) ; } else { /* * Dummy Read extended status to prevent * extra link down/ups * (clear Page Received bit if set) */ PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_EXP, &ExtStat); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNeg done Port %d\n", Port)); return(SK_HW_PS_LINK) ; } } /* * AutoNeg not done, but HW link is up. Check for timeouts */ pPrt->PAutoNegTimeOut ++; if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { /* * Timeout occured. * What do we need now? */ SK_DBG_MSG(pAC,SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("AutoNeg timeout Port %d\n", Port)); if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && pPrt->PLipaAutoNeg != SK_LIPA_AUTO) { /* * Timeout occured * Set Link manually up. */ SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL); SK_DBG_MSG(pAC,SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Set manual full duplex Port %d\n", Port)); } /* * Do the restart */ return(SK_HW_PS_RESTART) ; } } else { /* * Link is up and we don't need more. */#ifdef DEBUG if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("ERROR: Lipa auto detected on port %d\n", Port)); }#endif SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ, ("Link sync(GP), Port %d\n", Port)); SkHWLinkUp(pAC, IoC, Port) ; return(SK_HW_PS_LINK) ; } return(SK_HW_PS_NONE) ;}/****************************************************************************** * * SkGePortCheckUpBcom - Check, if the link is up * * return: * 0 o.k. nothing needed * 1 Restart needed on this port * 2 Link came up */static int SkGePortCheckUpBcom(SK_AC *pAC, /* Adapters context */SK_IOC IoC, /* IO Context */int Port) /* Which port should be checked */{ SK_GEPORT *pPrt; /* GIni Port struct pointer */ SK_BOOL AutoNeg; /* Is Autonegotiation used ? */ SK_U16 Isrc; /* Interrupt source register */ SK_U16 LpAb; /* Link Partner Ability */ SK_U16 ExtStat; /* Extended Status Register */ SK_U16 PhyStat; /* Phy Status Register */ int Done; SK_U16 ResAb; SK_U16 SWord; pPrt = &pAC->GIni.GP[Port]; /* Check for No HCD Link events (#10523) */ PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &Isrc); if ((Isrc & PHY_B_IS_NO_HDCL) == PHY_B_IS_NO_HDCL) { /* Workaround BCOM Errata */ /* enable and disable Loopback mode if NO HCD occurs */ PHY_READ(IoC, pPrt, Port, PHY_BCOM_CTRL, &SWord); PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, SWord | PHY_CT_LOOP); PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, SWord & ~PHY_CT_LOOP); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("No HCD Link event, Port %d\n", Port)); } PHY_READ(IoC, pPrt, Port, PHY_BCOM_STAT, &PhyStat); if (pPrt->PHWLinkUp) { return(SK_HW_PS_NONE) ; } pPrt->PIsave = 0; /* Now wait for each port's link */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { AutoNeg = SK_FALSE; } else { AutoNeg = SK_TRUE; } /* * here we usually can check whether the link is in sync and * autonegotiation is done. */ XM_IN16(IoC, Port, XM_ISRC, &Isrc) ; PHY_READ(IoC, pPrt, Port, PHY_BCOM_STAT, &PhyStat); SkXmAutoNegLipaBcom(pAC, IoC, Port, PhyStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg:%d, PhyStat: %Xh.\n", AutoNeg, PhyStat)); PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb); if ((PhyStat & PHY_ST_LSYNC) == 0) { if (ResAb & (PHY_B_1000S_MSF)) { /* Error */ SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("Master/Slave Fault port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; pPrt->PMSStatus = SK_MS_STAT_FAULT; return (SK_AND_OTHER); } return (SK_HW_PS_NONE); } if (ResAb & (PHY_B_1000S_MSF)) { /* Error */ SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("Master/Slave Fault port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; pPrt->PMSStatus = SK_MS_STAT_FAULT; return (SK_AND_OTHER); } else if (ResAb & PHY_B_1000S_MSR) { pPrt->PMSStatus = SK_MS_STAT_MASTER; } else { pPrt->PMSStatus = SK_MS_STAT_SLAVE; } SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg:%d, PhyStat: %Xh.\n", AutoNeg, PhyStat)); if (AutoNeg) { if (PhyStat & PHY_ST_AN_OVER) { SkHWLinkUp(pAC, IoC, Port); Done = SkXmAutoNegDone(pAC,IoC,Port); if (Done != SK_AND_OK) { /* Get PHY parameters, for debuging only */ PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUNE_LP, &LpAb); PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ExtStat); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNeg FAIL Port %d (LpAb %x, " "1000TStat %x)\n", Port, LpAb, ExtStat)); return(SK_HW_PS_RESTART) ; } else { /* * Dummy Read interrupt status to prevent * extra link down/ups */ PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &ExtStat); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNeg done Port %d\n", Port)); return(SK_HW_PS_LINK) ; } } } else { /* * Link is up and we don't need more. */#ifdef DEBUG if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("ERROR: Lipa auto detected on port %d\n", Port)); }#endif#if 0 PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb); if (ResAb & (PHY_B_1000S_MSF)) { /* Error */ SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("Master/Slave Fault port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; pPrt->PMSStatus = SK_MS_STAT_FAULT; return (SK_AND_OTHER); } else if (ResAb & PHY_B_1000S_MSR) { pPrt->PMSStatus = SK_MS_STAT_MASTER ; } else { pPrt->PMSStatus = SK_MS_STAT_SLAVE ; }#endif /* 0 */ /* * Dummy Read interrupt status to prevent * extra link down/ups */ PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &ExtStat); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ, ("Link sync(GP), Port %d\n", Port)); SkHWLinkUp(pAC, IoC, Port) ; return(SK_HW_PS_LINK) ; } return(SK_HW_PS_NONE) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -