⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skgeinit.c

📁 这是Marvell Technology Group Ltd. 4355 (rev 12)网卡在linux下的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			(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 + -