📄 skxmac2.c
字号:
#ifdef XXX /* clear GMAC Control reset */ SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR); /* set GMAC Control reset */ SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);#endif /* XXX */ /* set HWCFG_MODE */ DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE | (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB); /* set GPHY Control reset */ SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); /* release GPHY Control reset */ SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);#ifdef VCPU VCpuWait(9000);#endif /* VCPU */ /* clear GMAC Control reset */ SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);#ifdef VCPU VCpuWait(2000);#endif /* VCPU */ /* Auto-negotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { /* Auto-negotiation disabled */ /* get General Purpose Control */ GM_IN16(IoC, Port, GM_GP_CTRL, &SWord); /* disable auto-update for speed, duplex and flow-control */ SWord |= GM_GPCR_AU_ALL_DIS; /* setup General Purpose Control Register */ GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); SWord = GM_GPCR_AU_ALL_DIS; } else { SWord = 0; } /* speed settings */ switch (pPrt->PLinkSpeed) { case SK_LSPEED_AUTO: case SK_LSPEED_1000MBPS: SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100; break; case SK_LSPEED_100MBPS: SWord |= GM_GPCR_SPEED_100; break; case SK_LSPEED_10MBPS: break; } /* duplex settings */ if (pPrt->PLinkMode != SK_LMODE_HALF) { /* set full duplex */ SWord |= GM_GPCR_DUP_FULL; } switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: /* set Pause Off */ SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF); /* disable Tx & Rx flow-control */ SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; break; case SK_FLOW_MODE_LOC_SEND: /* disable Rx flow-control */ SWord |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; break; case SK_FLOW_MODE_SYMMETRIC: case SK_FLOW_MODE_SYM_OR_REM: /* enable Tx & Rx flow-control */ break; } /* setup General Purpose Control Register */ GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); /* dummy read the Interrupt Source Register */ SK_IN16(IoC, GMAC_IRQ_SRC, &SWord); #ifndef VCPU /* read Id from PHY */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1); SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);#endif /* VCPU */ } (void)SkGmResetCounter(pAC, IoC, Port); /* setup Transmit Control Register */ GM_OUT16(IoC, Port, GM_TX_CTRL, GM_TXCR_COL_THR); /* setup Receive Control Register */ GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA | GM_RXCR_CRC_DIS); /* setup Transmit Flow Control Register */ GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff); /* setup Transmit Parameter Register */#ifdef VCPU GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);#endif /* VCPU */ SWord = (SK_U16)(JAM_LEN_VAL(3) | JAM_IPG_VAL(11) | IPG_JAM_DATA(26)); GM_OUT16(IoC, Port, GM_TX_PARAM, SWord); /* configure the Serial Mode Register */#ifdef VCPU GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);#endif /* VCPU */ SWord = GM_SMOD_VLAN_ENA | IPG_VAL_FAST_ETH; if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { /* enable jumbo mode (Max. Frame Length = 9018) */ SWord |= GM_SMOD_JUMBO_ENA; } GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord); /* * configure the GMACs Station Addresses * in PROM you can find our addresses at: * B2_MAC_1 = xx xx xx xx xx x0 virtual address * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort */ for (i = 0; i < 3; i++) { /* * The following 2 statements are together endianess * independent. Remember this when changing. */ /* physical address: will be used for pause frames */ SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);#ifdef WA_DEV_16 /* WA for deviation #16 */ if (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) { /* swap the address bytes */ SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8); /* write to register in reversed order */ GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord); } else { GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord); }#else GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);#endif /* WA_DEV_16 */ /* virtual address: will be used for data */ SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord); GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord); /* reset Multicast filtering Hash registers 1-3 */ GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0); } /* reset Multicast filtering Hash register 4 */ GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0); /* enable interrupt mask for counter overflows */ GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0); GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0); GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0); /* read General Purpose Status */ GM_IN16(IoC, Port, GM_GP_STAT, &SWord); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("MAC Stat Reg=0x%04X\n", SWord));#ifdef SK_DIAG c_print("MAC Stat Reg=0x%04X\n", SWord);#endif /* SK_DIAG */} /* SkGmInitMac */#endif /* YUKON */#ifdef GENESIS/****************************************************************************** * * SkXmInitDupMd() - Initialize the XMACs Duplex Mode * * Description: * This function initializes the XMACs Duplex Mode. * It should be called after successfully finishing * the Auto-negotiation 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 probable not quick * enough at the 'XMAC' bus to burst 8kB. * The XMAC stops 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 initializes the Pause Mode which should * be used for this port. * It should be called after successfully finishing * the Auto-negotiation 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]; XM_IN16(IoC, Port, XM_MMU_CMD, &Word); if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE || pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) { /* Disable Pause Frame Reception */ 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 */ Word &= ~XM_MMU_IGN_PF; } XM_OUT16(IoC, Port, XM_MMU_CMD, Word); XM_IN32(IoC, Port, XM_MODE, &DWord); 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 triggered. * Send a Pause frame with the maximum pause time if * internal oder external FIFO full condition occurs. * Send a zero pause time frame to re-start transmission. */ /* 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 */ 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 */ DWord &= ~XM_PAUSE_MODE; /* Disable Pause Mode in MAC Rx FIFO */ SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE); } XM_OUT32(IoC, Port, XM_MODE, DWord);} /* SkXmInitPauseMd*//****************************************************************************** * * SkXmInitPhyXmac() - Initialize the XMAC Phy registers * * Description: initializes 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 LoopBack be set-up? */{ SK_GEPORT *pPrt; SK_U16 Ctrl; pPrt = &pAC->GIni.GP[Port]; Ctrl = 0; /* Auto-negotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyXmac: no auto-negotiation Port %d\n", Port)); /* Set DuplexMode in Config register */ if (pPrt->PLinkMode == SK_LMODE_FULL) { Ctrl |= PHY_CT_DUP_MD; } /* * Do NOT enable Auto-negotiation 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 auto-negotiation Port %d\n", Port)); /* Set Auto-negotiation advertisement */ /* 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 */ SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl); /* Restart Auto-negotiation */ 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 */ SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl);} /* SkXmInitPhyXmac *//****************************************************************************** * * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers * * Description: initializes 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 LoopBack be set-up? */{ SK_GEPORT *pPrt; SK_U16 Ctrl1; SK_U16 Ctrl2; SK_U16 Ctrl3; SK_U16 Ctrl4; SK_U16 Ctrl5; Ctrl1 = PHY_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; } } /* Auto-negotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyBcom: no auto-negotiation Port %d\n", Port)); /* 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->P
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -