📄 skxmac2.c
字号:
* on the rx side. * - Enable 'Check Station Address' bit * - Enable 'Check Address Array' bit */ XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE); /* * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK) * - Enable all bits excepting 'Octets Rx OK Low CntOv' * and 'Octets Rx OK Hi Cnt Ov'. */ XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK); /* * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK) * - Enable all bits excepting 'Octets Tx OK Low CntOv' * and 'Octets Tx OK Hi Cnt Ov'. */ XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK); /* * Do NOT init XMAC interrupt mask here. * All interrupts remain disable until link comes up! */ pPrt->PState = SK_PRT_INIT; /* * Any additional configuration changes may be done now. * The last action is to enable the rx and tx state machine. * This should be done after the autonegotiation process * has been completed successfully. */} /* SkXmInitMac*//****************************************************************************** * * SkXmInitDupMd() - Initialize the XMACs Duplex Mode * * Description: * This function initilaizes the XMACs Duplex Mode. * It should be called after successfully finishing * the Autonegotiation Process * * Returns: * nothing */void SkXmInitDupMd(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port) /* Port Index (MAC_1 + n) */{ switch (pAC->GIni.GP[Port].PLinkModeStatus) { case SK_LMODE_STAT_AUTOHALF: case SK_LMODE_STAT_HALF: /* Configuration Actions for Half Duplex Mode */ /* * XM_BURST = default value. We are propable not quick * enough at the 'XMAC' bus to burst 8kB. * The XMAC stopps bursting if no transmit frames * are available or the burst limit is exceeded. */ /* XM_TX_RT_LIM = default value (15) */ /* XM_TX_STIME = default value (0xff = 4096 bit times) */ break; case SK_LMODE_STAT_AUTOFULL: case SK_LMODE_STAT_FULL: /* Configuration Actions for Full Duplex Mode */ /* * The duplex mode is configured by the PHY, * therefore it seems to be that there is nothing * to do here. */ break; case SK_LMODE_STAT_UNKNOWN: default: SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG); break; }} /* SkXmInitDupMd *//****************************************************************************** * * SkXmInitPauseMd() - initialize the Pause Mode to be used for this port * * Description: * This function initilaizes the Pause Mode which should * be used for this port. * It should be called after successfully finishing * the Autonegotiation Process * * Returns: * nothing */void SkXmInitPauseMd(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port) /* Port Index (MAC_1 + n) */{ SK_GEPORT *pPrt; SK_U32 DWord; SK_U16 Word; pPrt = &pAC->GIni.GP[Port]; if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE || pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) { /* Disable Pause Frame Reception */ XM_IN16(IoC, Port, XM_MMU_CMD, &Word); XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_IGN_PF); } else { /* * enabling pause frame reception is required for 1000BT * because the XMAC is not reset if the link is going down */ /* Enable Pause Frame Reception */ XM_IN16(IoC, Port, XM_MMU_CMD, &Word); XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~XM_MMU_IGN_PF); } if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC || pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) { /* * Configure Pause Frame Generation * Use internal and external Pause Frame Generation. * Sending pause frames is edge triggert. Send a * Pause frame with the maximum pause time if * internal oder external FIFO full condition * occurs. Send a zero pause time frame to * start transmission again. */ /* XM_PAUSE_DA = '010000C28001' (default) */ /* XM_MAC_PTIME = 0xffff (maximum) */ /* remember this value is defined in big endian (!) */ XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff); /* Set Pause Mode in Mode Register */ XM_IN32(IoC, Port, XM_MODE, &DWord); XM_OUT32(IoC, Port, XM_MODE, DWord | XM_PAUSE_MODE); /* Set Pause Mode in MAC Rx FIFO */ SK_OUT16(IoC, MR_ADDR(Port,RX_MFF_CTRL1), MFF_ENA_PAUSE); } else { /* * disable pause frame generation is required for 1000BT * because the XMAC is not reset if the link is going down */ /* Disable Pause Mode in Mode Register */ XM_IN32(IoC, Port, XM_MODE, &DWord); XM_OUT32(IoC, Port, XM_MODE, DWord & ~XM_PAUSE_MODE); /* Disable Pause Mode in MAC Rx FIFO */ SK_OUT16(IoC, MR_ADDR(Port,RX_MFF_CTRL1), MFF_DIS_PAUSE); }} /* SkXmInitPauseMd*//****************************************************************************** * * SkXmInitPhy() - Initialize the XMAC II Phy registers * * Description: * Initialize all the XMACs Phy registers * * Note: * * Returns: * nothing */void SkXmInitPhy(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; pPrt = &pAC->GIni.GP[Port]; switch (pPrt->PhyType) { case SK_PHY_XMAC: SkXmInitPhyXmac(pAC, IoC, Port, DoLoop); break; case SK_PHY_BCOM: SkXmInitPhyBcom(pAC, IoC, Port, DoLoop); break; case SK_PHY_LONE: SkXmInitPhyLone(pAC, IoC, Port, DoLoop); break; case SK_PHY_NAT: SkXmInitPhyNat(pAC, IoC, Port, DoLoop); break; }} /* SkXmInitPhy*//****************************************************************************** * * SkXmInitPhyXmac() - Initialize the XMAC II Phy registers * * Description: * Initialize all the XMACs Phy registers * * Note: * * Returns: * nothing */static void SkXmInitPhyXmac(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 Ctrl; pPrt = &pAC->GIni.GP[Port]; /* Autonegotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || 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 */ Ctrl = (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 */ Ctrl = 0; /* Set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: Ctrl |= PHY_X_AN_HD; break; case SK_LMODE_AUTOFULL: Ctrl |= PHY_X_AN_FD; break; case SK_LMODE_AUTOBOTH: Ctrl |= 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: Ctrl |= PHY_X_P_NO_PAUSE; break; case SK_FLOW_MODE_LOC_SEND: Ctrl |= PHY_X_P_ASYM_MD; break; case SK_FLOW_MODE_SYMMETRIC: Ctrl |= PHY_X_P_SYM_MD; break; case SK_FLOW_MODE_SYM_OR_REM: Ctrl |= 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, Ctrl); /* Restart Autonegotiation */ Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG; } if (DoLoop) { /* Set the Phy Loopback bit, too */ Ctrl |= PHY_CT_LOOP; } /* Write to the Phy control register */ PHY_WRITE(IoC, pPrt, Port, PHY_XMAC_CTRL, Ctrl);} /* SkXmInitPhyXmac*//****************************************************************************** * * 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 Ctrl1; SK_U16 Ctrl2; SK_U16 Ctrl3; SK_U16 Ctrl4; SK_U16 Ctrl5; Ctrl1 = PHY_B_CT_SP1000; Ctrl2 = 0; Ctrl3 = PHY_SEL_TYPE; Ctrl4 = PHY_B_PEC_EN_LTR; Ctrl5 = PHY_B_AC_TX_TST; pPrt = &pAC->GIni.GP[Port]; /* manually Master/Slave ? */ if (pPrt->PMSMode != SK_MS_MODE_AUTO) { Ctrl2 |= PHY_B_1000C_MSE; if (pPrt->PMSMode == SK_MS_MODE_MASTER) { Ctrl2 |= 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 */ Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); /* Determine Master/Slave manually if not already done. */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { Ctrl2 |= 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: Ctrl2 |= PHY_B_1000C_AHD; break; case SK_LMODE_AUTOFULL: Ctrl2 |= PHY_B_1000C_AFD; break; case SK_LMODE_AUTOBOTH: Ctrl2 |= 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: Ctrl3 |= PHY_B_P_NO_PAUSE; break; case SK_FLOW_MODE_LOC_SEND: Ctrl3 |= PHY_B_P_ASYM_MD; break; case SK_FLOW_MODE_SYMMETRIC: Ctrl3 |= PHY_B_P_SYM_MD; break; case SK_FLOW_MODE_SYM_OR_REM: Ctrl3 |= 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 */ Ctrl1 |= 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, Ctrl2); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("1000Base-T Control Reg = %x\n", Ctrl2)); /* Write AutoNeg Advertisement Register */ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUNE_ADV, Ctrl3); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNeg Advertisment Reg = %x\n", Ctrl3)); if (DoLoop) { /* Set the Phy Loopback bit, too */ Ctrl1 |= PHY_CT_LOOP; } if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { /* configure fifo to high latency for xmission of ext. packets*/ Ctrl4 |= PHY_B_PEC_HIGH_LA; /* configure reception of extended packets */ Ctrl5 |= PHY_B_AC_LONG_PACK; PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, Ctrl5); } /* Configure LED Traffic Mode and Jumbo Frame usage if specified */ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4); /* Write to the Phy control register */ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, Ctrl1); SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("PHY Control Reg = %x\n", Ctrl1));} /* SkXmInitPhyBcom *//****************************************************************************** * * SkXmInitPhyLone() - Initialize the Level One Phy registers
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -