📄 skgeinit.c
字号:
SK_U32 *QuEndAddr) /* end address to calculate */{ SK_U32 EndVal; SK_U32 NextStart; int Rtv; Rtv = 0; if (QuSize == 0) { EndVal = *StartVal; NextStart = EndVal; } else { EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1; NextStart = EndVal + 1; } if (pPrt->PState >= SK_PRT_INIT) { if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) { Rtv = 1; } } else { *QuStartAddr = *StartVal; *QuEndAddr = EndVal; } *StartVal = NextStart; return (Rtv);} /* DoCalcAddr *//****************************************************************************** * * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration * * Description: * This function verifies the Queue Size Configuration specified * in the variabels PRxQSize, PXSQSize, and PXAQSize of all * used ports. * This requirements must be fullfilled to have a valid configuration: * - The size of all queues must not exceed GIRamSize. * - The queue sizes must be specified in units of 8 kB. * - The size of rx queues of available ports must not be * smaller than 16kB. * - The RAM start and end addresses must not be changed * for ports which are already initialized. * Furthermore SkGeCheckQSize() defines the Start and End * Addresses of all ports and stores them into the HWAC port * structure. * * Returns: * 0: Queue Size Configuration valid * 1: Queue Size Configuration invalid */static int SkGeCheckQSize(SK_AC *pAC, /* adapter context */int Port) /* port index */{ SK_GEPORT *pPrt; int UsedMem; int i; int Rtv; int Rtv2; SK_U32 StartAddr; UsedMem = 0; Rtv = 0; for (i = 0; i < pAC->GIni.GIMacsFound; i++) { pPrt = &pAC->GIni.GP[i]; if (( pPrt->PRxQSize & QZ_UNITS) || (pPrt->PXSQSize & QZ_UNITS) || (pPrt->PXAQSize & QZ_UNITS)) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); Rtv = 1; goto CheckQSizeEnd; } UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize; if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG); Rtv = 1; goto CheckQSizeEnd; } } if (UsedMem > pAC->GIni.GIRamSize) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); Rtv = 1; goto CheckQSizeEnd; } /* Now start address calculation */ StartAddr = pAC->GIni.GIRamOffs; for (i = 0; i < pAC->GIni.GIMacsFound; i++) { pPrt = &pAC->GIni.GP[i]; /* Calculate/Check values for the receive queue */ Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr, &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd); Rtv |= Rtv2; /* Calculate/Check values for the synchronous tx queue */ Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr, &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd); Rtv |= Rtv2; /* Calculate/Check values for the asynchronous tx queue */ Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr, &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd); Rtv |= Rtv2; if (Rtv) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG); break; } }CheckQSizeEnd: return (Rtv);} /* SkGeCheckQSize *//****************************************************************************** * * SkGeInitMacArb() - Initialize the MAC Arbiter * * Description: * This function initializes the MAC Arbiter. * It must not be called if there is still an * initilaized or active port. * * Returns: * nothing: */static void SkGeInitMacArb(SK_AC *pAC, /* adapter context */SK_IOC IoC) /* IO context */{ /* release local reset */ SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR); /* configure timeout values */ SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53); SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53); SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53); SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53); SK_OUT8(IoC, B3_MA_RCINI_RX1, 0); SK_OUT8(IoC, B3_MA_RCINI_RX2, 0); SK_OUT8(IoC, B3_MA_RCINI_TX1, 0); SK_OUT8(IoC, B3_MA_RCINI_TX2, 0); /* recovery values are needed for XMAC II Rev. B2 only */ /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */ /* * There is not start or enable buttom to push, therefore * the MAC arbiter is configured and enabled now. */} /* SkGeInitMacArb *//****************************************************************************** * * SkGeInitPktArb() - Initialize the Packet Arbiter * * Description: * This function initializes the Packet Arbiter. * It must not be called if there is still an * initilaized or active port. * * Returns: * nothing: */static void SkGeInitPktArb(SK_AC *pAC, /* adapter context */SK_IOC IoC) /* IO context */{ /* release local reset */ SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR); /* configure timeout values */ SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX); SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX); SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX); SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX); /* * enable timeout timers if jumbo frames not used * NOTE: the packet arbiter timeout interrupt is needed for * half duplex hangup workaround */ if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) { if (pAC->GIni.GIMacsFound == 1) { SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1); } else { SK_OUT16(IoC, B3_PA_CTRL,(PA_ENA_TO_TX1 | PA_ENA_TO_TX2)); } }} /* SkGeInitPktArb *//****************************************************************************** * * SkGeInitMacFifo() - Initialize the MAC FIFOs * * Description: * Initialize all MAC FIFOs of the specified port * * Returns: * nothing */static void SkGeInitMacFifo(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port) /* Port Index (MAC_1 + n) */{ /* * For each FIFO: * - release local reset * - use default value for MAC FIFO size * - setup defaults for the control register * - enable the FIFO */ /* Configure RX MAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR); SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF); SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD); /* Configure TX MAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR); SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD); /* Enable frame flushing if jumbo frames used */ if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH); }} /* SkGeInitMacFifo *//****************************************************************************** * * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting * * Description: * This function starts the Link Sync Counter of the specified * port and enables the generation of an Link Sync IRQ. * The Link Sync Counter may be used to detect an active link, * if autonegotiation is not used. * * Note: * o To ensure receiving the Link Sync Event the LinkSyncCounter * should be initialized BEFORE clearing the XMACs reset! * o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this * function. * * Retruns: * nothing */void SkGeLoadLnkSyncCnt(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port, /* Port Index (MAC_1 + n) */SK_U32 CntVal) /* Counter value */{ SK_U32 OrgIMsk; SK_U32 NewIMsk; SK_U32 ISrc; SK_BOOL IrqPend; /* stop counter */ SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP); /* * ASIC problem: * Each time starting the Link Sync Counter an IRQ is generated * by the adapter. See problem report entry from 21.07.98 * * Workaround: Disable Link Sync IRQ and clear the unexpeced IRQ * if no IRQ is already pending. */ IrqPend = SK_FALSE; SK_IN32(IoC, B0_ISRC, &ISrc); SK_IN32(IoC, B0_IMSK, &OrgIMsk); if (Port == MAC_1) { NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1; if (ISrc & IS_LNK_SYNC_M1) { IrqPend = SK_TRUE; } } else { NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2; if (ISrc & IS_LNK_SYNC_M2) { IrqPend = SK_TRUE; } } if (!IrqPend) { SK_OUT32(IoC, B0_IMSK, NewIMsk); } /* load counter */ SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal); /* start counter */ SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START); if (!IrqPend) { /* clear the unexpected IRQ, and restore the interrupt mask */ SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ); SK_OUT32(IoC, B0_IMSK, OrgIMsk); }} /* SkGeLoadLnkSyncCnt*//****************************************************************************** * * SkGeCfgSync() - Configure synchronous bandwidth for this port. * * Description: * This function may be used to configure synchronous bandwidth * to the specified port. This may be done any time after * initializing the port. The configuration values are NOT saved * in the HWAC port structure and will be overwritten any * time when stopping and starting the port. * Any values for the synchronous configuration will be ignored * if the size of the synchronous queue is zero! * * The default configuration for the synchronous service is * TXA_ENA_FSYNC. This means if the size of * the synchronous queue is unequal zero but no specific * synchronous bandwidth is configured, the synchronous queue * will always have the 'unlimitted' transmit priority! * * This mode will be restored if the synchronous bandwidth is * deallocated ('IntTime' = 0 and 'LimCount' = 0). * * Returns: * 0: success * 1: paramter configuration error * 2: try to configure quality of service although no * synchronous queue is configured */int SkGeCfgSync(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int Port, /* Port Index (MAC_1 + n) */SK_U32 IntTime, /* Interval Timer Value in units of 8ns */SK_U32 LimCount, /* Number of bytes to transfer during IntTime */int SyncMode) /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */{ int Rtv; Rtv = 0; /* check the parameters */ if (LimCount > IntTime || (LimCount == 0 && IntTime != 0) || (LimCount !=0 && IntTime == 0)) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); Rtv = 1; goto CfgSyncEnd; } if (pAC->GIni.GP[Port].PXSQSize != 0) { /* calculate register values */ IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100; LimCount = LimCount / 8; if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); Rtv = 1; goto CfgSyncEnd; } /* * - Enable 'Force Sync' to ensure the synchronous queue * has the priority while configuring the new values. * - Also 'disable alloc' to ensure the settings complies * to the SyncMode parameter. * - Disable 'Rate Control' to configure the new values. * - write IntTime and Limcount * - start 'Rate Control' and disable 'Force Sync' * if Interval Timer or Limit Counter not zero. */ SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime); SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount); SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), (SyncMode & (TXA_ENA_ALLOC|TXA_DIS_ALLOC))); if (IntTime != 0 || LimCount != 0) { SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC|TXA_START_RC); } } else { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG); Rtv = 2; }CfgSyncEnd: return (Rtv);} /* SkGeCfgSync *//****************************************************************************** * * DoInitRamQueue() - Initilaize the RAM Buffer Address of a single Queue * * Desccription: * If the queue is used, enable and initilaize it. * Make sure the queue is still reset, if it is not used. * * Returns: * nothing */static void DoInitRamQueue(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO context */int QuIoOffs, /* Queue IO Address Offset */SK_U32 QuStartAddr, /* Queue Start Address */SK_U32 QuEndAddr, /* Queue End Address */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 */ 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: /* * Do NOT use Store and forward under normal * operation due to performance optimization. * But if Jumbo frames are configured we NEED * the store and forward of the RAM buffer. */ if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { /* * 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 *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -