📄 skgeinit.c
字号:
/* get PM Capabilities of PCI config space */ SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word); /* check if VAUX is available */ if (((CtrlStat & CS_VAUX_AVAIL) != 0) && /* check also if PME from D3cold is set */ ((Word & PCI_PME_D3C_SUP) != 0)) { /* set entry in GE init struct */ pAC->GIni.GIVauxAvail = SK_TRUE; } if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) { /* this is Rev. A1 */ pAC->GIni.GIYukonLite = SK_TRUE; } else { /* save Flash-Address Register */ SK_IN32(IoC, B2_FAR, &DWord); /* test Flash-Address Register */ SK_OUT8(IoC, B2_FAR + 3, 0xff); SK_IN8(IoC, B2_FAR + 3, &Byte); if (Byte != 0) { /* this is Rev. A0 */ pAC->GIni.GIYukonLite = SK_TRUE; /* restore Flash-Address Register */ SK_OUT32(IoC, B2_FAR, DWord); } } /* switch power to VCC (WA for VAUX problem) */ SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON)); /* read the Interrupt source */ SK_IN32(IoC, B0_ISRC, &DWord); if ((DWord & IS_HW_ERR) != 0) { /* read the HW Error Interrupt source */ SK_IN32(IoC, B0_HWE_ISRC, &DWord); if ((DWord & IS_IRQ_SENSOR) != 0) { /* disable HW Error IRQ */ pAC->GIni.GIValIrqMask &= ~IS_HW_ERR; } } for (i = 0; i < pAC->GIni.GIMacsFound; i++) { /* set GMAC Link Control reset */ SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET); /* clear GMAC Link Control reset */ SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR); } /* all YU chips work with 78.125 MHz host clock */ pAC->GIni.GIHstClkFact = SK_FACT_78; pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */ }#endif /* YUKON */ /* check if 64-bit PCI Slot is present */ pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0); /* check if 66 MHz PCI Clock is active */ pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0); /* read PCI HW Revision Id. */ SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte); pAC->GIni.GIPciHwRev = Byte; /* read the PMD type */ SK_IN8(IoC, B2_PMD_TYP, &Byte); pAC->GIni.GICopperType = (SK_U8)(Byte == 'T'); /* read the PHY type */ SK_IN8(IoC, B2_E_1, &Byte); Byte &= 0x0f; /* the PHY type is stored in the lower nibble */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { #ifdef GENESIS if (pAC->GIni.GIGenesis) { switch (Byte) { case SK_PHY_XMAC: pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC; break; case SK_PHY_BCOM: pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM; pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); break;#ifdef OTHER_PHY case SK_PHY_LONE: pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE; break; case SK_PHY_NAT: pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT; break;#endif /* OTHER_PHY */ default: /* ERROR: unexpected PHY type detected */ RetVal = 5; break; } }#endif /* GENESIS */ #ifdef YUKON if (pAC->GIni.GIYukon) { if (Byte < (SK_U8)SK_PHY_MARV_COPPER) { /* if this field is not initialized */ Byte = (SK_U8)SK_PHY_MARV_COPPER; pAC->GIni.GICopperType = SK_TRUE; } pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV; if (pAC->GIni.GICopperType) { pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO | SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS | SK_LSPEED_CAP_1000MBPS); pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO; pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); } else { Byte = (SK_U8)SK_PHY_MARV_FIBER; } }#endif /* YUKON */ pAC->GIni.GP[i].PhyType = (int)Byte; SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ("PHY type: %d PHY addr: %04x\n", Byte, pAC->GIni.GP[i].PhyAddr)); } /* get MAC Type & set function pointers dependent on */#ifdef GENESIS if (pAC->GIni.GIGenesis) { pAC->GIni.GIMacType = SK_MAC_XMAC; pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats; pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic; pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter; pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus; }#endif /* GENESIS */ #ifdef YUKON if (pAC->GIni.GIYukon) { pAC->GIni.GIMacType = SK_MAC_GMAC; pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats; pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic; pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter; pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus;#ifdef SPECIAL_HANDLING if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { /* check HW self test result */ SK_IN8(IoC, B2_E_3, &Byte); if (Byte & B2_E3_RES_MASK) { RetVal = 6; } }#endif }#endif /* YUKON */ return(RetVal);} /* SkGeInit1 *//****************************************************************************** * * SkGeInit2() - Level 2 Initialization * * Description: * - start the Blink Source Counter * - start the Descriptor Poll Timer * - configure the MAC-Arbiter * - configure the Packet-Arbiter * - enable the Tx Arbiters * - enable the RAM Interface Arbiter * * Returns: * nothing */static void SkGeInit2(SK_AC *pAC, /* adapter context */SK_IOC IoC) /* IO context */{#ifdef GENESIS SK_U32 DWord;#endif /* GENESIS */ int i; /* start the Descriptor Poll Timer */ if (pAC->GIni.GIPollTimerVal != 0) { if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) { pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG); } SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal); SK_OUT8(IoC, B28_DPT_CTRL, DPT_START); }#ifdef GENESIS if (pAC->GIni.GIGenesis) { /* start the Blink Source Counter */ DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100; SK_OUT32(IoC, B2_BSC_INI, DWord); SK_OUT8(IoC, B2_BSC_CTRL, BSC_START); /* * Configure the MAC Arbiter and the Packet Arbiter. * They will be started once and never be stopped. */ SkGeInitMacArb(pAC, IoC); SkGeInitPktArb(pAC, IoC); }#endif /* GENESIS */ #ifdef YUKON if (pAC->GIni.GIYukon) { /* start Time Stamp Timer */ SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START); }#endif /* YUKON */ /* enable the Tx Arbiters */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB); } /* enable the RAM Interface Arbiter */ SkGeInitRamIface(pAC, IoC);} /* SkGeInit2 *//****************************************************************************** * * SkGeInit() - Initialize the GE Adapter with the specified level. * * Description: * Level 0: Initialize the Module structures. * Level 1: Generic Hardware Initialization. The IOP/MemBase pointer has * to be set before calling this level. * * o Do a software reset. * o Clear all reset bits. * o Verify that the detected hardware is present. * Return an error if not. * o Get the hardware configuration * + Set GIMacsFound with the number of MACs. * + Store the RAM size in GIRamSize. * + Save the PCI Revision ID in GIPciHwRev. * o return an error * if Number of MACs > SK_MAX_MACS * * After returning from Level 0 the adapter * may be accessed with IO operations. * * Level 2: start the Blink Source Counter * * Returns: * 0: success * 1: Number of MACs exceeds SK_MAX_MACS (after level 1) * 2: Adapter not present or not accessible * 3: Illegal initialization level * 4: Initialization Level 1 Call missing * 5: Unexpected PHY type detected * 6: HW self test failed */int SkGeInit(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Level) /* initialization level */{ int RetVal; /* return value */ SK_U32 DWord; RetVal = 0; SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ("SkGeInit(Level %d)\n", Level)); switch (Level) { case SK_INIT_DATA: /* Initialization Level 0 */ SkGeInit0(pAC, IoC); pAC->GIni.GILevel = SK_INIT_DATA; break; case SK_INIT_IO: /* Initialization Level 1 */ RetVal = SkGeInit1(pAC, IoC); if (RetVal != 0) { break; } /* check if the adapter seems to be accessible */ SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL); SK_IN32(IoC, B2_IRQM_INI, &DWord); SK_OUT32(IoC, B2_IRQM_INI, 0L); if (DWord != SK_TEST_VAL) { RetVal = 2; break; } /* check if the number of GIMacsFound matches SK_MAX_MACS */ if (pAC->GIni.GIMacsFound > SK_MAX_MACS) { RetVal = 1; break; } /* Level 1 successfully passed */ pAC->GIni.GILevel = SK_INIT_IO; break; case SK_INIT_RUN: /* Initialization Level 2 */ if (pAC->GIni.GILevel != SK_INIT_IO) {#ifndef SK_DIAG SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG);#endif /* !SK_DIAG */ RetVal = 4; break; } SkGeInit2(pAC, IoC); /* Level 2 successfully passed */ pAC->GIni.GILevel = SK_INIT_RUN; break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG); RetVal = 3; break; } return(RetVal);} /* SkGeInit *//****************************************************************************** * * SkGeDeInit() - Deinitialize the adapter * * Description: * All ports of the adapter will be stopped if not already done. * Do a software reset and switch off all LEDs. * * Returns: * nothing */void SkGeDeInit(SK_AC *pAC, /* adapter context */SK_IOC IoC) /* IO context */{ int i; SK_U16 Word;#ifdef SK_PHY_LP_MODE SK_U8 Byte; SK_U16 PmCtlSts;#endif /* SK_PHY_LP_MODE */#if (!defined(SK_SLIM) && !defined(VCPU)) /* ensure I2C is ready */ SkI2cWaitIrq(pAC, IoC);#endif /* stop all current transfer activity */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { if (pAC->GIni.GP[i].PState != SK_PRT_STOP && pAC->GIni.GP[i].PState != SK_PRT_RESET) { SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST); } }#ifdef SK_PHY_LP_MODE /* * for power saving purposes within mobile environments * we set the PHY to coma mode and switch to D3 power state. */ if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { /* for all ports switch PHY to coma mode */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP); } if (pAC->GIni.GIVauxAvail) { /* switch power to VAUX */ Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF; SK_OUT8(IoC, B0_POWER_CTRL, Byte); } /* switch to D3 state */ SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts); PmCtlSts |= PCI_PM_STATE_D3; SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts); }#endif /* SK_PHY_LP_MODE */ /* Reset all bits in the PCI STATUS register */ /* * Note: PCI Cfg cycles cannot be used, because they are not * available on some platforms after 'boot time'. */ SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); /* do the reset, all LEDs are switched off now */ SK_OUT8(IoC, B0_CTST, CS_RST_SET); pAC->GIni.GILevel = SK_INIT_DATA;} /* SkGeDeInit *//****************************************************************************** * * SkGeInitPort() Initialize the specified port. * * Description: * PRxQSize, PXSQSize, and PXAQSize has to be * configured for the specified port before calling this function. * The descriptor rings has to be initialized too. * * o (Re)configure queues of the specified port. * o configure the MAC of the specified port. * o put ASIC and MAC(s) in operational mode. * o initialize Rx/Tx and Sync LED * o initialize RAM Buffers and MAC FIFOs * * The port is ready to connect when returning. * * Note: * The MAC's Rx and Tx state machine is still disabled when returning. * * Returns: * 0: success * 1: Queue size initialization error. The configured values * for PRxQSize, PXSQSize, or PXAQSize are invalid for one * or more queues. The specified port was NOT initialized. * An error log entry was generated. * 2: The port has to be stopped before it can be initialized again. */int SkGeInitPort(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port) /* Port to configure */{ SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; if (SkGeCheckQSize(pAC, Port) != 0) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG); return(1); } if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG); return(2); } /* configuration ok, initialize the Port now */#ifdef GENESIS if (pAC->GIni.GIGenesis) { /* initialize Rx, Tx and Link LED */ /* * If 1000BT Phy needs LED initialization than swap * LED and XMAC initialization order */ SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA); SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA); /* The Link LED is initialized by RLMT or Diagnostics itself */ SkXmInitMac(pAC, IoC, Port); }#endif /* GENESIS */ #ifdef YUKON if (pAC->GIni.GIYukon) { SkGmInitMac(pAC, IoC, Port); }#endif /* YUKON */ /* do NOT initialize the Link Sync Counter */ SkGeInitMacFifo(pAC, IoC, Port); SkGeInitRamBufs(pAC, IoC, Port); if (pPrt->PXSQSize != 0) { /* enable Force Sync bit if synchronous queue available */ SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC); } SkGeInitBmu(pAC, IoC, Port); /* mark port as initialized */ pPrt->PState = SK_PRT_INIT; return(0);} /* SkGeInitPort */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -