📄 skgeinit.c
字号:
(int)((long)ActivePortKilobytes * RAM_QUOTA_RX) / 100); ActivePortKilobytes -= pPrt->PRxQSize; /* add the minimum memory for Rx queue */ pPrt->PRxQSize += MinQueueSize/2; /* synchronous transmit queue */ pPrt->PXSQSize = 0; /* asynchronous transmit queue gets 20% of the rest */ pPrt->PXAQSize = SkGeRoundQueueSize(pAC, ActivePortKilobytes) + /* add the minimum memory for Tx queue */ MinQueueSize/2; }#ifdef DEBUG for (i = 0; i < pAC->GIni.GIMacsFound; i++) { pPrt = &pAC->GIni.GP[i]; SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ("Port %d: RxQSize=%u, TxAQSize=%u, TxSQSize=%u\n", i, pPrt->PRxQSize, pPrt->PXAQSize, pPrt->PXSQSize)); }#endif /* DEBUG */ return(0);} /* SkGeInitAssignRamToQueues *//****************************************************************************** * * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration * * Description: * This function verifies the Queue Size Configuration specified * in the variables 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 16 kB (Yukon-1) resp. 10 kB (Yukon-2). * - The size of at least one Tx queue (synch. or asynch.) * of available ports must not be smaller than 16 kB, * resp. 10 kB (Yukon-2) when Jumbo Frames are used. * - 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 i; int Rtv; int Rtv2; SK_U32 StartAddr;#ifndef SK_SLIM int UsedMem; /* total memory used (max. found ports) */#endif Rtv = 0;#ifndef SK_SLIM UsedMem = 0; for (i = 0; i < pAC->GIni.GIMacsFound; i++) { pPrt = &pAC->GIni.GP[i]; if (CHIP_ID_YUKON_2(pAC)) { UsedMem = 0; } else if (((pPrt->PRxQSize & QZ_UNITS) != 0 || (pPrt->PXSQSize & QZ_UNITS) != 0 || (pPrt->PXAQSize & QZ_UNITS) != 0)) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); return(1); }#ifndef SK_DIAG if (i == Port && pAC->GIni.GIRamSize > SK_MIN_RXQ_SIZE && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG); return(1); } /* * the size of at least one Tx queue (synch. or asynch.) has to be > 0. * if Jumbo Frames are used, this size has to be >= 16 kB. */ if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) || (pPrt->PPortUsage == SK_JUMBO_LINK && ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) || (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG); return(1); }#endif /* !SK_DIAG */ UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize; if (UsedMem > pAC->GIni.GIRamSize) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); return(1); } }#endif /* !SK_SLIM */ /* Now start address calculation */ StartAddr = pAC->GIni.GIRamOffs; for (i = 0; i < pAC->GIni.GIMacsFound; i++) { pPrt = &pAC->GIni.GP[i]; if (CHIP_ID_YUKON_2(pAC)) { StartAddr = 0; } /* 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); return(1); } } return(0);} /* SkGeCheckQSize *//****************************************************************************** * * 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, /* I/O Context */int Port) /* Port Index (MAC_1 + n) */{ SK_U16 Word; /* * For each FIFO: * - release local reset * - use default value for MAC FIFO size * - setup defaults for the control register * - enable the FIFO */ Word = (SK_U16)GMF_RX_CTRL_DEF;#ifndef DISABLE_YUKON_I /* disable Rx GMAC FIFO Flush for YUKON-Plus */ if (pAC->GIni.GIYukonLite) { Word &= ~GMF_RX_F_FL_ON; }#endif /* !DISABLE_YUKON_I */ /* configure Rx GMAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word); Word = RX_FF_FL_DEF_MSK;#ifndef SK_DIAG if (HW_FEATURE(pAC, HWF_WA_DEV_4115)) { /* * Flushing must be enabled (needed for ASF see dev. #4.29), * but the flushing mask should be disabled (see dev. #4.115) */ Word = 0; }#endif /* !SK_DIAG */ /* set Rx GMAC FIFO Flush Mask (after clearing reset) */ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), Word); /* default: 0x0a -> 56 bytes on Yukon-1 and 64 bytes on Yukon-2 */ Word = (SK_U16)RX_GMF_FL_THR_DEF; if (CHIP_ID_YUKON_2(pAC) && pAC->GIni.GIAsfEnabled) { /* WA for dev. #4.30 & 4.89 (reduce to 0x08 -> 48 bytes) */ Word -= 2; } else if (HW_FEATURE(pAC, HWF_WA_DEV_521)) { Word = 0x178; } else { /* * because Pause Packet Truncation in GMAC is not working * we have to increase the Flush Threshold to 64 bytes * in order to flush pause packets in Rx FIFO on Yukon-1 */ Word++; } /* set Rx GMAC FIFO Flush Threshold (after clearing reset) */ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), Word); /* configure Tx GMAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF); if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U || pAC->GIni.GIChipId == CHIP_ID_YUKON_EX || pAC->GIni.GIChipId >= CHIP_ID_YUKON_FE_P) { /* set Rx Pause Threshold */ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_UP_THR), (SK_U16)(HW_FEATURE(pAC, HWF_WA_DEV_521) ? SK_DEV521_ULPP : SK_ECU_ULPP)); SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_LP_THR), (SK_U16)SK_ECU_LLPP); if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EX && pAC->GIni.GIChipRev != CHIP_REV_YU_EX_A0) || pAC->GIni.GIChipId >= CHIP_ID_YUKON_FE_P) { /* Yukon-Extreme B0 and further devices */ /* enable Store & Forward mode for TX */ SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TX_STFW_ENA); } else { if (pAC->GIni.GP[Port].PPortUsage == SK_JUMBO_LINK) { /* set Tx GMAC FIFO Almost Empty Threshold */ SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), (SK_ECU_JUMBO_WM << 16) | (SK_U16)SK_ECU_AE_THR); /* disable Store & Forward mode for TX */ SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TX_STFW_DIS); }#ifdef TEST_ONLY else { /* enable Store & Forward mode for TX */ SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TX_STFW_ENA); }#endif /* TEST_ONLY */ } } if (HW_FEATURE(pAC, HWF_WA_DEV_520)) { /* disable dynamic watermark */ SK_IN16(IoC, MR_ADDR(Port, TX_GMF_EA), &Word); SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_EA), Word & ~TX_DYN_WM_ENA); }} /* SkGeInitMacFifo */#ifdef SK_LNK_SYNC_CNT/****************************************************************************** * * 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 XMAC's reset! * o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this * function. * * Returns: * nothing */void SkGeLoadLnkSyncCnt(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O 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), LNK_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) != 0) { IrqPend = SK_TRUE; } } else { NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2; if ((ISrc & IS_LNK_SYNC_M2) != 0) { 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), LNK_START); if (!IrqPend) { /* clear the unexpected IRQ */ SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_CLR_IRQ); /* restore the interrupt mask */ SK_OUT32(IoC, B0_IMSK, OrgIMsk); }} /* SkGeLoadLnkSyncCnt*/#endif /* SK_LNK_SYNC_CNT */#if defined(SK_DIAG) || defined(SK_CFG_SYNC)/****************************************************************************** * * 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 'unlimited' transmit priority! * * This mode will be restored if the synchronous bandwidth is * deallocated ('IntTime' = 0 and 'LimCount' = 0). * * Returns: * 0: success * 1: parameter 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, /* I/O 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); return(1); } if (pAC->GIni.GP[Port].PXSQSize == 0) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG); return(2); } /* 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); return(1); } /* * - 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), (SK_U8)(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); } return(0);} /* SkGeCfgSync */#endif /* SK_DIAG || SK_CFG_SYNC *//****************************************************************************** * * DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue * * Desccription: * If the queue is used, enable and initialize it. * Make sure the queue is still reset, if it is not used. * * Returns: * nothing */void DoInitRamQueue(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int QuIoOffs, /* Queue I/O Address Offset */SK_U32 QuStartAddr, /* Queue Start Address */SK_U32 QuEndAddr, /* Queue End Address */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -