📄 skgeinit.c
字号:
int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */{ SK_U32 RxUpThresVal; SK_U32 RxLoThresVal; if (QuStartAddr != QuEndAddr) { /* calculate thresholds, assume we have a big Rx queue */ RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8; RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8; /* build HW address format */ QuStartAddr = QuStartAddr / 8; QuEndAddr = QuEndAddr / 8; /* release local reset */ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR); /* configure addresses */ SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr); SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr); SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr); SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr); switch (QuType) { case SK_RX_SRAM_Q: /* configure threshold for small Rx Queue */ RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8; /* continue with SK_RX_BRAM_Q */ case SK_RX_BRAM_Q: /* write threshold for Rx Queue (Pause packets) */ SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal); SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal); /* the high priority threshold not used */ break; case SK_TX_RAM_Q: /* * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB) * or YUKON is used ((GMAC Tx FIFO is only 1 kB) * we NEED Store & Forward of the RAM buffer. */ /* enable Store & Forward Mode for the Tx Side */ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD); break; } /* set queue operational */ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD); } else { /* ensure the queue is still disabled */ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET); }} /* DoInitRamQueue *//****************************************************************************** * * SkGeInitRamBufs() - Initialize the RAM Buffer Queues * * Description: * Initialize all RAM Buffer Queues of the specified port * * Returns: * nothing */static void SkGeInitRamBufs(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port) /* Port Index (MAC_1 + n) */{ SK_GEPORT *pPrt; int RxQType; if (!HW_IS_RAM_IF_AVAIL(pAC)) { return; } pPrt = &pAC->GIni.GP[Port]; if (pPrt->PRxQSize <= SK_MIN_RXQ_SIZE) { RxQType = SK_RX_SRAM_Q; /* small Rx Queue */ } else { RxQType = SK_RX_BRAM_Q; /* big Rx Queue */ } DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart, pPrt->PRxQRamEnd, RxQType); DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart, pPrt->PXsQRamEnd, SK_TX_RAM_Q); DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart, pPrt->PXaQRamEnd, SK_TX_RAM_Q);} /* SkGeInitRamBufs *//****************************************************************************** * * SkGeInitRamIface() - Initialize the RAM Interface * * Description: * This function initializes the Adapters RAM Interface. * * Note: * This function is used in the diagnostics. * * Returns: * nothing */void SkGeInitRamIface(SK_AC *pAC, /* Adapter Context */SK_IOC IoC) /* I/O Context */{ int i; int RamBuffers; if (!HW_IS_RAM_IF_AVAIL(pAC)) { return; } if (CHIP_ID_YUKON_2(pAC)) { RamBuffers = pAC->GIni.GIMacsFound; } else { RamBuffers = 1; } for (i = 0; i < RamBuffers; i++) { /* release local reset */ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_CTRL), (SK_U8)RI_RST_CLR); /* configure timeout values */ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53); SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53); SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53); SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53); SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53); SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53); SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53); SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53); SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53); SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53); SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53); SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53); }} /* SkGeInitRamIface *//****************************************************************************** * * SkGeInitBmu() - Initialize the BMU state machines * * Description: * Initialize all BMU state machines of the specified port * * Returns: * nothing */static void SkGeInitBmu(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port) /* Port Index (MAC_1 + n) */{ SK_GEPORT *pPrt; SK_U16 RxWm; SK_U16 TxWm; pPrt = &pAC->GIni.GP[Port]; RxWm = SK_BMU_RX_WM; TxWm = SK_BMU_TX_WM; if (CHIP_ID_YUKON_2(pAC)) { if (pAC->GIni.GIPciBus == SK_PEX_BUS) { /* for better performance set it to 128 */ RxWm = SK_BMU_RX_WM_PEX; } /* Rx Queue: Release all local resets and set the watermark */ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_CLR_RESET); SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_OPER_INIT); SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_FIFO_OP_ON); SK_OUT16(IoC, Q_ADDR(pPrt->PRxQOff, Q_WM), RxWm); if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U && pAC->GIni.GIChipRev > CHIP_REV_YU_EC_U_A0) { /* MAC Rx RAM Read is controlled by hardware */ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), F_M_RX_RAM_DIS); } /* * Tx Queue: Release all local resets if the queue is used ! * set watermark */ if (pPrt->PXSQSize != 0 && HW_SYNC_TX_SUPPORTED(pAC)) { /* Yukon-EC doesn't have a synchronous Tx queue */ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_CLR_RESET); SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_OPER_INIT); SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_FIFO_OP_ON); SK_OUT16(IoC, Q_ADDR(pPrt->PXsQOff, Q_WM), TxWm); } if (pPrt->PXAQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_CLR_RESET); SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_OPER_INIT); SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_FIFO_OP_ON);#if (!defined(SK_SLIM) && !defined(SK_DIAG)) if (HW_FEATURE(pAC, HWF_TX_IP_ID_INCR_ON)) { /* Enable Tx IP ID Increment */ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_TX_IPIDINCR_ON); }#endif /* !SK_SLIM && !SK_DIAG */ SK_OUT16(IoC, Q_ADDR(pPrt->PXaQOff, Q_WM), TxWm); if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U && pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A0) { /* fix for Yukon-EC Ultra: set BMU FIFO level */ SK_OUT16(IoC, Q_ADDR(pPrt->PXaQOff, Q_AL), SK_ECU_TXFF_LEV); } } }#ifndef DISABLE_YUKON_I else { if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) { /* for better performance */ RxWm /= 2; TxWm /= 2; } /* Rx Queue: Release all local resets and set the watermark */ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET); SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm); /* * Tx Queue: Release all local resets if the queue is used ! * set watermark */ if (pPrt->PXSQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET); SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm); } if (pPrt->PXAQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET); SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm); } }#endif /* !DISABLE_YUKON_I */ /* * Do NOT enable the descriptor poll timers here, because * the descriptor addresses are not specified yet. */} /* SkGeInitBmu *//****************************************************************************** * * TestStopBit() - Test the stop bit of the queue * * Description: * Stopping a queue is not as simple as it seems to be. * If descriptor polling is enabled, it may happen * that RX/TX stop is done and SV idle is NOT set. * In this case we have to issue another stop command. * * Returns: * The queues control status register */static SK_U32 TestStopBit(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int QuIoOffs) /* Queue I/O Address Offset */{ SK_U32 QuCsr; /* CSR contents */ SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); if (CHIP_ID_YUKON_2(pAC)) { if ((QuCsr & (BMU_STOP | BMU_IDLE)) == 0) { /* Stop Descriptor overridden by start command */ SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), BMU_STOP); SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); } }#ifndef DISABLE_YUKON_I else { if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) { /* Stop Descriptor overridden by start command */ SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP); SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); } }#endif /* !DISABLE_YUKON_I */ return(QuCsr);} /* TestStopBit *//****************************************************************************** * * SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'. * * Description: * After calling this function the descriptor rings and Rx and Tx * queues of this port may be reconfigured. * * It is possible to stop the receive and transmit path separate or * both together. * * Dir = SK_STOP_TX Stops the transmit path only and resets the MAC. * The receive queue is still active and * the pending Rx frames may be still transferred * into the RxD. * SK_STOP_RX Stop the receive path. The tansmit path * has to be stopped once before. * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX * * RstMode = SK_SOFT_RST Resets the MAC, the PHY is still alive. * SK_HARD_RST Resets the MAC and the PHY. * * Example: * 1) A Link Down event was signaled for a port. Therefore the activity * of this port should be stopped and a hardware reset should be issued * to enable the workaround of XMAC Errata #2. But the received frames * should not be discarded. * ... * SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST); * (transfer all pending Rx frames) * SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST); * ... * * 2) An event was issued which request the driver to switch * the 'virtual active' link to an other already active port * as soon as possible. The frames in the receive queue of this * port may be lost. But the PHY must not be reset during this * event. * ... * SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST); * ... * * Extended Description: * If SK_STOP_TX is set, * o disable the MAC's receive and transmitter to prevent * from sending incomplete frames * o stop the port's transmit queues before terminating the * BMUs to prevent from performing incomplete PCI cycles * on the PCI bus * - The network Rx and Tx activity and PCI Tx transfer is * disabled now. * o reset the MAC depending on the RstMode * o Stop Interval Timer and Limit Counter of Tx Arbiter, * also disable Force Sync bit and Enable Alloc bit. * o perform a local reset of the port's Tx path * - reset the PCI FIFO of the async Tx queue * - reset the PCI FIFO of the sync Tx queue * - reset the RAM Buffer async Tx queue * - reset the RAM Buffer sync Tx queue * - reset the MAC Tx FIFO * o switch Link and Tx LED off, stop the LED counters * * If SK_STOP_RX is set, * o stop the port's receive queue * - The path data transfer activity is fully stopped now. * o perform a local reset of the port's Rx path * - reset the PCI FIFO of the Rx queue * - reset the RAM Buffer receive queue * - reset the MAC Rx FIFO * o switch Rx LED off, stop the LED counter * * If all ports are stopped, * o reset the RAM Interface. * * Notes: * o This function may be called during the driver states RESET_PORT and * SWITCH_PORT. */void SkGeStopPort(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port to stop (MAC_1 + n) */int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */{ SK_GEPORT *pPrt; SK_U32 RxCsr; SK_U32 XsCsr; SK_U32 XaCsr; SK_U64 ToutStart; SK_U32 CsrStart; SK_U32 CsrStop; SK_U32 CsrIdle; SK_U32 CsrTest; SK_U8 FifoRdShLev; /* FIFO read shadow level */ SK_U8 FifoRdLev; /* FIFO read level */ int i; int ToutCnt; pPrt = &pAC->GIni.GP[Port]; SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("SkGeStopPort: Port %d, Dir %d, RstMode %d\n", Port, Dir, RstMode)); /* set the proper values of Q_CSR register layout depending on the chip */ if (CHIP_ID_YUKON_2(pAC)) { CsrStart = BMU_START; CsrStop = BMU_STOP; CsrIdle = BMU_IDLE; CsrTest = BMU_IDLE; }#ifndef DISABLE_YUKON_I else { CsrStart = CSR_START; CsrStop = CSR_STOP; CsrIdle = CSR_SV_IDLE; CsrTest = CSR_SV_IDLE | CSR_STOP; }#endif /* !DISABLE_YUKON_I */ if ((Dir & SK_STOP_TX) != 0) { if (!pAC->GIni.GIAsfEnabled) { /* disable receiver and transmitter */ SkMacRxTxDisable(pAC, IoC, Port); } else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EX || pAC->GIni.GIChipId == CHIP_ID_YUKON_SUPR) { /* * Enable flushing of non ASF packets; * required, because MAC is not disabled */ SK_OUT32(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), RXMF_TCTL_MACSEC_FLSH_ENA); } /* stop both transmit queues */ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CsrStop); SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CsrStop); /* * If the BMU is in the reset state CSR_STOP will terminate * immediately. */ ToutStart = SkOsGetTime(pAC); ToutCnt = 0; do { XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff); if (HW_SYNC_TX_SUPPORTED(pAC)) { XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -