📄 skgesirq.c
字号:
if (AutoNeg) { if ((IsrcSum & XM_IS_AND) != 0) { SkHWLinkUp(pAC, IoC, Port); Done = SkMacAutoNegDone(pAC, IoC, Port); if (Done != SK_AND_OK) { /* Get PHY parameters, for debugging only */ SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb); SkXmPhyRead(pAC, IoC, 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); } /* * Dummy Read extended status to prevent extra link down/ups * (clear Page Received bit if set) */ SkXmPhyRead(pAC, IoC, 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) { /* Increase the Timeout counter */ pPrt->PAutoNegTOCt++; /* Timeout occured */ 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) { /* 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)); } if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && pPrt->PLipaAutoNeg == SK_LIPA_AUTO && pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) { /* * This is rather complicated. * we need to check here whether the LIPA_AUTO * we saw before is false alert. We saw at one * switch ( SR8800) that on boot time it sends * just one auto-neg packet and does no further * auto-negotiation. * Solution: we restart the autosensing after * a few timeouts. */ pPrt->PAutoNegTOCt = 0; pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; SkHWInitDefSense(pAC, IoC, 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 /* DEBUG */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link sync(GP), Port %d\n", Port)); SkHWLinkUp(pAC, IoC, Port); /* * Link sync (GP) and so assume a good connection. But if not received * a bunch of frames received in a time slot (maybe broken tx cable) * the port is restart. */ return(SK_HW_PS_LINK); } return(SK_HW_PS_NONE);} /* SkGePortCheckUpXmac *//****************************************************************************** * * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY * * return: * 0 o.k. nothing needed * 1 Restart needed on this port * 2 Link came up */static int SkGePortCheckUpBcom(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* IO Context */int Port) /* Which port should be checked */{ SK_GEPORT *pPrt; /* GIni Port struct pointer */ int Done; SK_U16 Isrc; /* Interrupt source register */ SK_U16 PhyStat; /* Phy Status Register */ SK_U16 ResAb; /* Master/Slave resolution */ SK_U16 Ctrl; /* Broadcom control flags */#ifdef DEBUG SK_U16 LpAb; SK_U16 ExtStat;#endif /* DEBUG */ SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ pPrt = &pAC->GIni.GP[Port]; /* Check for No HCD Link events (#10523) */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);#ifdef xDEBUG if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) == (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) { SK_U32 Stat1, Stat2, Stat3; Stat1 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, "CheckUp1 - Stat: %x, Mask: %x", (void *)Isrc, (void *)Stat1); Stat1 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2); Stat1 = Stat1 << 16 | Stat2; Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); Stat3 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); Stat2 = Stat2 << 16 | Stat3; CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, "Ctrl/Stat: %x, AN Adv/LP: %x", (void *)Stat1, (void *)Stat2); Stat1 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); Stat1 = Stat1 << 16 | Stat2; Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); Stat3 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3); Stat2 = Stat2 << 16 | Stat3; CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x", (void *)Stat1, (void *)Stat2); Stat1 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); Stat1 = Stat1 << 16 | Stat2; Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); Stat3 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); Stat2 = Stat2 << 16 | Stat3; CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x", (void *)Stat1, (void *)Stat2); }#endif /* DEBUG */ if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) { /* * Workaround BCom Errata: * enable and disable loopback mode if "NO HCD" occurs. */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl); SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, (SK_U16)(Ctrl | PHY_CT_LOOP)); SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, (SK_U16)(Ctrl & ~PHY_CT_LOOP)); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("No HCD Link event, Port %d\n", Port));#ifdef xDEBUG CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, "No HCD link event, port %d.", (void *)Port, (void *)NULL);#endif /* DEBUG */ } /* Not obsolete: link status bit is latched to 0 and autoclearing! */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); if (pPrt->PHWLinkUp) { return(SK_HW_PS_NONE); }#ifdef xDEBUG { SK_U32 Stat1, Stat2, Stat3; Stat1 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, "CheckUp1a - Stat: %x, Mask: %x", (void *)Isrc, (void *)Stat1); Stat1 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); Stat1 = Stat1 << 16 | PhyStat; Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); Stat3 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); Stat2 = Stat2 << 16 | Stat3; CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, "Ctrl/Stat: %x, AN Adv/LP: %x", (void *)Stat1, (void *)Stat2); Stat1 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); Stat1 = Stat1 << 16 | Stat2; Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); Stat3 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); Stat2 = Stat2 << 16 | ResAb; CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x", (void *)Stat1, (void *)Stat2); Stat1 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); Stat1 = Stat1 << 16 | Stat2; Stat2 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); Stat3 = 0; SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); Stat2 = Stat2 << 16 | Stat3; CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x", (void *)Stat1, (void *)Stat2); }#endif /* DEBUG */ /* 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 * auto-negotiation is done. */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat)); SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); if ((ResAb & PHY_B_1000S_MSF) != 0) { /* 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_HW_PS_RESTART); } if ((PhyStat & PHY_ST_LSYNC) == 0) { return(SK_HW_PS_NONE); } pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat)); if (AutoNeg) { if ((PhyStat & PHY_ST_AN_OVER) != 0) { SkHWLinkUp(pAC, IoC, Port); Done = SkMacAutoNegDone(pAC, IoC, Port); if (Done != SK_AND_OK) {#ifdef DEBUG /* Get PHY parameters, for debugging only */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb); SkXmPhyRead(pAC, IoC, 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));#endif /* DEBUG */ return(SK_HW_PS_RESTART); } else {#ifdef xDEBUG /* Dummy read ISR to prevent extra link downs/ups */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, "CheckUp2 - Stat: %x", (void *)ExtStat, (void *)NULL); }#endif /* DEBUG */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg done Port %d\n", Port)); return(SK_HW_PS_LINK); } } } else { /* !AutoNeg */ /* 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 /* DEBUG */#ifdef xDEBUG /* Dummy read ISR to prevent extra link downs/ups */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { CMSMPrintString( pAC->pConfigTable, MSG_TYPE_RUNTIME_INFO, "CheckUp3 - Stat: %x", (void *)ExtStat, (void *)NULL); }#endif /* DEBUG */ 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 *//****************************************************************************** * * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY * * return: * 0 o.k. nothing needed * 1 Restart needed on this port * 2 Link came up */static int SkGePortCheckUpGmac(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* IO Context */int Port) /* Which port should be checked */{ SK_GEPORT *pPrt; /* GIni Port struct pointer */ int Done; SK_U16 Isrc; /* Interrupt source */ SK_U16 PhyStat; /* Phy Status */ SK_U16 PhySpecStat;/* Phy Specific Status */ SK_U16 ResAb; /* Master/Slave resolution */ SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ pPrt = &pAC->GIni.GP[Port]; /* Read PHY Interrupt Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &Isrc); if ((Isrc & PHY_M_IS_AN_COMPL) != 0) { /* TBD */ } if ((Isrc & PHY_M_IS_DOWNSH_DET) != 0) { /* TBD */ } if (pPrt->PHWLinkUp) { return(SK_HW_PS_NONE); } /* 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; } /* Read PHY Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat)); SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); if ((ResAb & PHY_B_1000S_MSF) != 0) { /* 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_HW_PS_RESTART); } /* Read PHY Specific Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg: %d, PhySpecStat: 0x%04x\n", AutoNeg, PhySpecStat)); if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -