📄 skxmac2.c
字号:
/* Check Duplex mismatch. */ if ((AuxStat & PHY_B_AS_AN_RES) == PHY_B_RES_1000FD) { pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; } else if ((AuxStat & PHY_B_AS_AN_RES) == PHY_B_RES_1000HD) { pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; } else { /* Error. */ SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegFail: Duplex mode mismatch port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; return (SK_AND_DUP_CAP); } #if 001-Sep-2000 RA;:;: /* Check Master/Slave resolution. */ 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 */ /* Check PAUSE mismatch. */ /* We are NOT using chapter 4.23 of the Xaqti manual. */ /* We are using IEEE 802.3z/D5.0 Table 37-4. */ if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == (PHY_B_AS_PRR | PHY_B_AS_PRT)) { /* Symmetric PAUSE. */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; } else if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == PHY_B_AS_PRR) { /* Enable PAUSE receive, disable PAUSE transmit. */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; } else if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == PHY_B_AS_PRT) { /* Disable PAUSE receive, enable PAUSE transmit. */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; } else { /* PAUSE mismatch -> no PAUSE. */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; } /* We checked everything and may now enable the link. */ pPrt->PAutoNegFail = SK_FALSE; SkXmRxTxEnable(pAC, IoC, Port); return (SK_AND_OK);} /* SkXmAutoNegDoneBcom*//****************************************************************************** * * SkXmAutoNegDoneLone() - 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 SkXmAutoNegDoneLone(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port) /* Port Index (MAC_1 + n) */{ SK_GEPORT *pPrt; SK_U16 ResAb; /* Resolved Ability */ SK_U16 LPAb; /* Link Partner Ability */ SK_U16 QuickStat; /* Auxiliary Status */ SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegDoneLone" "Port %d\n",Port)); pPrt = &pAC->GIni.GP[Port]; /* Get PHY parameters */ PHY_READ(IoC, pPrt, Port, PHY_LONE_AUNE_LP, &LPAb); PHY_READ(IoC, pPrt, Port, PHY_LONE_1000T_STAT, &ResAb); PHY_READ(IoC, pPrt, Port, PHY_LONE_Q_STAT, &QuickStat); if (LPAb & PHY_L_AN_RF) { /* Remote fault bit is set */ /* Error */ SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegFail: Remote fault bit set Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; return (SK_AND_OTHER); } /* Check Duplex mismatch */ if (QuickStat & PHY_L_QS_DUP_MOD) { pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; } else { pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; } /* Check Master/Slave resolution */ if (ResAb & (PHY_L_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_L_1000S_MSR) { pPrt->PMSStatus = SK_MS_STAT_MASTER; } else { pPrt->PMSStatus = SK_MS_STAT_SLAVE; } /* Check PAUSE mismatch */ /* We are NOT using chapter 4.23 of the Xaqti manual */ /* We are using IEEE 802.3z/D5.0 Table 37-4 */ /* we must manually resolve the abilities here */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: /* default */ break; case SK_FLOW_MODE_LOC_SEND: if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) == (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) { /* Disable PAUSE receive, enable PAUSE transmit */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; } break; case SK_FLOW_MODE_SYMMETRIC: if ((QuickStat & PHY_L_QS_PAUSE) == PHY_L_QS_PAUSE) { /* Symmetric PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; } break; case SK_FLOW_MODE_SYM_OR_REM: if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) == PHY_L_QS_AS_PAUSE) { /* Enable PAUSE receive, disable PAUSE transmit */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; } else if ((QuickStat & PHY_L_QS_PAUSE) == PHY_L_QS_PAUSE) { /* Symmetric PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; } break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, SKERR_HWI_E016MSG); } /* We checked everything and may now enable the link */ pPrt->PAutoNegFail = SK_FALSE; SkXmRxTxEnable(pAC, IoC, Port); return (SK_AND_OK);} /* SkXmAutoNegDoneLone *//****************************************************************************** * * SkXmAutoNegDoneNat() - 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 */static int SkXmAutoNegDoneNat(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port) /* Port Index (MAC_1 + n) */{/* todo: National */ return (SK_AND_OK);} /* SkXmAutoNegDoneNat*//****************************************************************************** * * SkXmRxTxEnable() - Enable RxTx activity if port is up * * Description: * * Note: * o The XMACs interrupt source register is NOT read here. * * Returns: * 0 o.k. * != 0 Error happened */int SkXmRxTxEnable(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port) /* Port Index (MAC_1 + n) */{ SK_GEPORT *pPrt; SK_U16 Reg; /* 16bit register value */ SK_U16 IntMask; /* XMac interrupt mask */ SK_U16 SWord; pPrt = &pAC->GIni.GP[Port]; if (!pPrt->PHWLinkUp) { /* The Hardware link is NOT up */ return (0); } if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF || pPrt->PLinkMode == SK_LMODE_AUTOFULL || pPrt->PLinkMode == SK_LMODE_AUTOBOTH) && pPrt->PAutoNegFail) { /* Autonegotiation is not done or failed */ return (0); } /* Set Dup Mode and Pause Mode */ SkXmInitDupMd (pAC, IoC, Port); SkXmInitPauseMd (pAC, IoC, Port); /* * Initialize the Interrupt Mask Register. Default IRQs are... * - Link Asynchronous Event * - Link Partner requests config * - Auto Negotiation Done * - Rx Counter Event Overflow * - Tx Counter Event Overflow * - Transmit FIFO Underrun */ if (pPrt->PhyType == SK_PHY_XMAC) { IntMask = XM_DEF_MSK; } else { /* disable GP0 interrupt bit */ IntMask = XM_DEF_MSK | XM_IS_INP_ASS; } XM_OUT16(IoC, Port, XM_IMSK, IntMask); /* RX/TX enable */ XM_IN16(IoC, Port, XM_MMU_CMD, &Reg); if (pPrt->PhyType != SK_PHY_XMAC && (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) { Reg |= XM_MMU_GMII_FD; } switch (pPrt->PhyType) { case SK_PHY_BCOM: /* Workaround BCOM Errata (#10523) for all BCom Phys */ /* Enable Power Management after link up */ PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord); PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, SWord & ~PHY_B_AC_DIS_PM); PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); break; case SK_PHY_LONE: PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK); break; case SK_PHY_NAT: /* todo National: PHY_WRITE(IoC, pPrt, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */ /* no interrupts possible from National ??? */ break; } XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX); return (0);} /* SkXmRxTxEnable*/#ifndef SK_DIAG/****************************************************************************** * * SkXmIrq() - Interrupt service routine * * Description: * Services an Interrupt of the XMAC II * * Note: * The XMACs interrupt source register is NOT read here. * With an external PHY, some interrupt bits are not meaningfull * any more: * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC * - Page Received (bit #9) XM_IS_RX_PAGE * - NextPageLoadedForXmt (bit #8) XM_IS_TX_PAGE * - AutoNegDone (bit #7) XM_IS_AND * Also probably not valid any more is the GP0 input bit: * - GPRegisterBit0set XM_IS_INP_ASS * * Returns: * nothing */void SkXmIrq(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port, /* Port Index (MAC_1 + n) */SK_U16 IStatus) /* Interrupt status read from the XMAC */{ SK_GEPORT *pPrt; SK_EVPARA Para; SK_U16 IStatus2; pPrt = &pAC->GIni.GP[Port]; if (pPrt->PhyType != SK_PHY_XMAC) { /* mask bits that are not used with ext. PHY */ IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_TX_PAGE | XM_IS_AND | XM_IS_INP_ASS); } /* * LinkPartner Autonegable? */ if (pPrt->PhyType == SK_PHY_XMAC) { SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus); } SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("XmacIrq Port %d Isr %x\n", Port, IStatus)); if (!pPrt->PHWLinkUp) { /* Spurious XMAC interrupt */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("SkXmIrq: spurious interrupt on port %d\n", Port)); return; } if (IStatus & XM_IS_INP_ASS) { /* Reread ISR Register if link is not in sync */ XM_IN16(IoC, Port, XM_ISRC, &IStatus2); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("SkXmIrq: Link async. Double check port %d %x %x\n", Port, IStatus, IStatus2)); IStatus &= ~XM_IS_INP_ASS; IStatus |= IStatus2; } if (IStatus & XM_IS_LNK_AE) { /* not used GP0 is used instead */ } if (IStatus & XM_IS_TX_ABORT) { /* not used */ } if (IStatus & XM_IS_FRC_INT) { /* not used. use ASIC IRQ instead if needed */ } if (IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) { SkHWLinkDown(pAC, IoC, Port); /* Signal to RLMT */ Para.Para32[0] = (SK_U32) Port; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); /* Start workaround Errata #2 timer */ SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer, SK_WA_INA_TIME, SKGE_HWAC, SK_HWEV_WATIM, Para); } if (IStatus & XM_IS_RX_PAGE) { /* not used */ } if (IStatus & XM_IS_TX_PAGE) { /* not used */ } if (IStatus & XM_IS_AND) { SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ, ("SkXmIrq: AND on link that is up port %d\n", Port)); } if (IStatus & XM_IS_TSC_OV) { /* not used */ } if (IStatus & XM_IS_RXC_OV) { Para.Para32[0] = (SK_U32) Port; Para.Para32[1] = (SK_U32) IStatus; SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); } if (IStatus & XM_IS_TXC_OV) { Para.Para32[0] = (SK_U32) Port; Para.Para32[1] = (SK_U32) IStatus; SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); } if (IStatus & XM_IS_RXF_OV) { /* normal situation -> no effect */ } if (IStatus & XM_IS_TXF_UR) { /* may NOT happen -> error log */ SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG); } if (IStatus & XM_IS_TX_COMP) { /* not served here */ } if (IStatus & XM_IS_RX_COMP) { /* not served here */ }} /* SkXmIrq*/#endif /* !SK_DIAG *//* End of file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -