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

📄 skge.c

📁 这是Marvell Technology Group Ltd. 4355 (rev 12)网卡在linux下的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}#endif	StatSpeed = pAC->GIni.GP[pNet->NetNr].PLinkSpeedUsed;	if (StatSpeed == SK_LSPEED_STAT_10MBPS) {		StatDuplex = pAC->GIni.GP[pNet->NetNr].PLinkModeStatus;		if ((StatDuplex == SK_LMODE_STAT_AUTOHALF) ||			(StatDuplex == SK_LMODE_STAT_HALF)) {				NewTimerInterval = (HZ*2);		} else {			NewTimerInterval = (HZ);		}	} else if (StatSpeed == SK_LSPEED_STAT_100MBPS) {		NewTimerInterval = (HZ/2);	} else if (StatSpeed == SK_LSPEED_STAT_1000MBPS) {		NewTimerInterval = (HZ/4);	} else {		NewTimerInterval = (HZ*2);	}	if (pNet->InRecover) {	        pNet->KernelTimer.expires = jiffies + NewTimerInterval;		add_timer(&pNet->KernelTimer);		return;	}	if (pNet->TimerExpired)		return;	pNet->TimerExpired = SK_TRUE;#define TXPORT pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]#define RXPORT pAC->RxPort[pNet->PortNr]	if (	(CHIP_ID_YUKON_2(pAC)) &&		(netif_running(pAC->dev[pNet->PortNr]))) {		#ifdef Y2_RX_CHECK		if (HW_FEATURE(pAC, HWF_WA_DEV_4167)) {		/* Checks the RX path */			CheckRxPath(pNet);		}#endif		/* Check the transmitter */		if (!(IS_Q_EMPTY(&TXPORT.TxAQ_working))) {			if (TXPORT.LastDone != TXPORT.TxALET.Done) {				TXPORT.LastDone = TXPORT.TxALET.Done;				pNet->TransmitTimeoutTimer = 0;			} else {				pNet->TransmitTimeoutTimer++;				if (pNet->TransmitTimeoutTimer >= 10) {					pNet->TransmitTimeoutTimer = 0;#ifdef CHECK_TRANSMIT_TIMEOUT					StartTimer =  SK_FALSE;					SkLocalEventQueue(pAC, SKGE_DRV, 						SK_DRV_RECOVER,pNet->PortNr,-1,SK_FALSE);#endif				}			} 		} #ifdef CHECK_TRANSMIT_TIMEOUT//		if (!timer_pending(&pNet->KernelTimer)) {			pNet->KernelTimer.expires = jiffies + NewTimerInterval;			add_timer(&pNet->KernelTimer);			pNet->TimerExpired = SK_FALSE;//		}#endif	}}/******************************************************************************* CheckRXCounters - Checks the the statistics for RX path hang** Description:*	This function is called periodical by a timer. ** Notes:** Function Parameters:** Returns:*	Traffic status**/static SK_BOOL CheckRXCounters(DEV_NET *pNet)  /* holds the pointer to adapter control context */{	SK_AC           	*pAC = pNet->pAC;	SK_BOOL bStatus 	= SK_FALSE;	/* Variable used to store the MAC RX FIFO RP, RPLev*/	SK_U32			MACFifoRP = 0;	SK_U32			MACFifoRLev = 0;	/* Variable used to store the PCI RX FIFO RP, RPLev*/	SK_U32			RXFifoRP = 0;	SK_U8			RXFifoRLev = 0;	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,		("==> CheckRXCounters()\n"));	/*Check if statistic counters hangs*/	if (pNet->LastJiffies == pAC->dev[pNet->PortNr]->last_rx) {		/* Now read the values of read pointer/level from MAC RX FIFO again */		SK_IN32(pAC->IoBase, MR_ADDR(pNet->PortNr, RX_GMF_RP), &MACFifoRP);		SK_IN32(pAC->IoBase, MR_ADDR(pNet->PortNr, RX_GMF_RLEV), &MACFifoRLev);		/* Now read the values of read pointer/level from RX FIFO again */		SK_IN8(pAC->IoBase, Q_ADDR(pAC->GIni.GP[pNet->PortNr].PRxQOff, Q_RX_RP), &RXFifoRP);		SK_IN8(pAC->IoBase, Q_ADDR(pAC->GIni.GP[pNet->PortNr].PRxQOff, Q_RX_RL), &RXFifoRLev);		/* Check if the MAC RX hang */		if ((MACFifoRP == pNet->PreviousMACFifoRP) &&			(MACFifoRLev != 0) &&			(MACFifoRLev >= pNet->PreviousMACFifoRLev)){			bStatus = SK_TRUE;		}		/* Check if the PCI RX hang */		if ((RXFifoRP == pNet->PreviousRXFifoRP) &&			(RXFifoRLev != 0) &&			(RXFifoRLev >= pNet->PreviousRXFifoRLev)){			/*Set the flag to indicate that the RX FIFO hangs*/			bStatus = SK_TRUE;		}	}	/* Store now the values of counters for next check */	pNet->LastJiffies = pAC->dev[pNet->PortNr]->last_rx;	/* Store the values of  read pointer/level from MAC RX FIFO for next test */	pNet->PreviousMACFifoRP = MACFifoRP;	pNet->PreviousMACFifoRLev = MACFifoRLev;	/* Store the values of  read pointer/level from RX FIFO for next test */	pNet->PreviousRXFifoRP = RXFifoRP;	pNet->PreviousRXFifoRLev = RXFifoRLev;	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,		("<== CheckRXCounters()\n"));	return bStatus;}/******************************************************************************* CheckRxPath - Checks if the RX path** Description:*	This function is called periodical by a timer. ** Notes:** Function Parameters:** Returns:*	None.**/static void  CheckRxPath(DEV_NET *pNet)  /* holds the pointer to adapter control context */{	unsigned long		Flags;    /* for the spin locks    */	/* Initialize the pAC structure.*/	SK_AC           	*pAC = pNet->pAC;	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,		("==> CheckRxPath()\n"));	/*If the statistics are not changed then could be an RX problem */	if (CheckRXCounters(pNet)){		/* 		 * First we try the simple solution by resetting the Level Timer		 */		/* Stop Level Timer of Status BMU */		SK_OUT8(pAC->IoBase, STAT_LEV_TIMER_CTRL, TIM_STOP);		/* Start Level Timer of Status BMU */		SK_OUT8(pAC->IoBase, STAT_LEV_TIMER_CTRL, TIM_START);		if (!CheckRXCounters(pNet)) {			return;		}		spin_lock_irqsave(&pAC->SlowPathLock, Flags);		SkLocalEventQueue(pAC, SKGE_DRV,			SK_DRV_RECOVER,pNet->PortNr,-1,SK_TRUE);		/* Reset the fifo counters */		pNet->PreviousMACFifoRP = 0;		pNet->PreviousMACFifoRLev = 0;		pNet->PreviousRXFifoRP = 0;		pNet->PreviousRXFifoRLev = 0;		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);	}	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,		("<== CheckRxPath()\n"));}#endif#ifdef CONFIG_PM/***************************************************************************** * * 	sk98lin_resume - Resume the the card * * Description: *	This function resumes the card into the D0 state * * Returns: N/A *	 */static int sk98lin_resume(struct pci_dev *pdev)   /* the device that is to resume */{	struct net_device   *dev  = pci_get_drvdata(pdev);	DEV_NET		    *pNet = (DEV_NET*) dev->priv;	SK_AC		    *pAC  = pNet->pAC;	SK_U16		     PmCtlSts;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)	int                  rCode;#endif#ifndef USE_ASF_DASH_FW	if (pAC->GIni.GIChipId != CHIP_ID_YUKON_EX) {#endif		/* Set the power state to D0 */		pci_set_power_state(pdev, 0);#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)		pci_restore_state(pdev);#else		pci_restore_state(pdev, pAC->PciState);#endif#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)		rCode = pci_enable_device(pdev);		if (rCode)			return rCode;#else       		pci_enable_device(pdev);#endif		pci_set_master(pdev);		pci_enable_wake(pdev, 3, 0);		pci_enable_wake(pdev, 4, 0);#ifndef USE_ASF_DASH_FW	}#endif	/* Set the adapter power state to D0 */	SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);	PmCtlSts &= ~(PCI_PM_STATE_D3);	/* reset all DState bits */	PmCtlSts |= PCI_PM_STATE_D0;	SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PmCtlSts);#ifdef USE_ASF_DASH_FW	SkAsfResume(pAC, pAC->IoBase);#endif#ifdef USE_ASF_DASH_FW	pAC->ReturningFromSuspend = SK_TRUE;	pAC->SendWolPattern = SK_TRUE;	pAC->ReceivedPacket = SK_FALSE;#endif	/* Reinit the adapter and start the port again */	pAC->BoardLevel = SK_INIT_DATA;	SkDrvLeaveDiagMode(pAC);#ifdef USE_ASF_DASH_FW	printk("sk98lin: resume complete\n");#endif	return 0;} /***************************************************************************** * * 	sk98lin_suspend - Suspend the card * * Description: *	This function suspends the card into a defined state * * Returns: N/A *	 */#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)static int sk98lin_suspend(struct pci_dev	*pdev,   /* pointer to the device that is to suspend */pm_message_t	state)  /* what power state is desired by Linux?    */#elsestatic int sk98lin_suspend(struct pci_dev	*pdev,   /* pointer to the device that is to suspend */SK_U32	state)  /* what power state is desired by Linux?    */#endif{	struct net_device   *dev  = pci_get_drvdata(pdev);	DEV_NET		    *pNet = (DEV_NET*) dev->priv;	SK_AC		    *pAC  = pNet->pAC;	SK_U16		     PciPMControlStatus;	SK_U16		     PciPMCapabilities;	SK_MAC_ADDR	     MacAddr;	int		     i;	/* GEnesis and first yukon revs do not support power management */	if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {		if (pAC->GIni.GIChipRev == 0) {			return 0; /* power management not supported */		}	} 	if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {		return 0; /* not supported for this chipset */	}	if (pAC->WolInfo.ConfiguredWolOptions == 0) {		return 0; /* WOL possible, but disabled via ethtool */	}	if(netif_running(dev)) {		netif_stop_queue(dev); /* stop device if running */	}#ifdef USE_ASF_DASH_FW	pAC->LinkSpeed = pAC->GIni.GP[0].PLinkSpeed;	pAC->LinkSpeedSet = SK_TRUE;	/* Write zeroes to ASF Fifo. */	SetRamAddr(pAC, SK_ST_FIFOTYPE, SK_ST_BUFADDR_LOW, SK_ST_BUFADDR_HIGH);	AccessRamBuf(pAC, SK_ST_BUFSIZE, SK_FALSE);#endif	/* Read the PM control/status register from the PCI config space */	SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CTL_STS), &PciPMControlStatus);	/* Read the power management capabilities from the PCI config space */	SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CAP_REG), &PciPMCapabilities);	/* Enable WakeUp with Magic Packet - get MAC address from adapter */	for (i = 0; i < SK_MAC_ADDR_LEN; i++) {		/* virtual address: will be used for data */		SK_IN8(pAC->IoBase, (B2_MAC_1 + i), &MacAddr.a[i]);	}	SkDrvEnterDiagMode(pAC);	SkEnableWOMagicPacket(pAC, pAC->IoBase, MacAddr);#ifndef USE_ASF_DASH_FW	if (pAC->GIni.GIChipId != CHIP_ID_YUKON_EX) {#endif#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)		pci_save_state(pdev);#else		pci_save_state(pdev, pAC->PciState);#endif		/* Possibly we need to evaluate the return values */		pci_enable_wake(pdev, 3, 1);	/* D3 hot */		pci_enable_wake(pdev, 4, 1);	/* D3 cold */		pci_disable_device(pdev);#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)		pci_set_power_state(pdev, pci_choose_state(pdev, state)); /* set the state */#else		pci_set_power_state(pdev, state); /* set the state */#endif#ifndef USE_ASF_DASH_FW	}#endif#ifdef USE_ASF_DASH_FW	printk("sk98lin: suspend complete\n");#endif	return 0;}/****************************************************************************** * *	SkEnableWOMagicPacket - Enable Wake on Magic Packet on the adapter * * Context: *	init, pageable *	the adapter should be de-initialized before calling this function * * Returns: *	nothing */static void SkEnableWOMagicPacket(SK_AC         *pAC,      /* Adapter Control Context          */SK_IOC         IoC,      /* I/O control context              */SK_MAC_ADDR    MacAddr)  /* MacAddr expected in magic packet */{	SK_U16	Word;	SK_U32	DWord;	int 	Port;	int 	i;	/* Use port 0 as long as we do not have any dual port cards which support WOL */	Port = 0;	DWord = 0;	SK_OUT16(IoC, B0_CTST, 0x0002);        /* clear S/W Reset */	SK_OUT16(IoC, GMAC_LINK_CTRL, 0x0002); /* clear Link Reset */	/*	 * PHY Configuration:	 * Autonegotiation is enabled, advertise 10 HD, 10 FD,	 * 100 HD, and 100 FD.	 */	if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC)   ||		(pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) ||		(pAC->GIni.GIChipId == CHIP_ID_YUKON_XL)   ||		(pAC->GIni.GIChipId == CHIP_ID_YUKON_EX)   ||		(pAC->GIni.GIChipId == CHIP_ID_YUKON)      ||		(pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) {		SK_OUT32(pAC->IoBase, 0x1c84, 0x7000);		SK_OUT32(pAC->IoBase, 0x1c88, 0x0);		SK_OUT32(pAC->IoBase, 0x1c84, 0x7000);		SK_OUT32(pAC->IoBase, 0x1c88, 0x0);		SK_OUT8(IoC, B0_POWER_CTRL, 0xa9);		/* enable VAUX */		/* WA code for COMA mode */		/* Only for yukon plus based chipsets rev A3 */		if  ( (pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) &&		      (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) ) {			SK_IN32(IoC, B2_GP_IO, &DWord);			DWord |= GP_DIR_9;				/* set to output */			DWord &= ~GP_IO_9;				/* clear PHY reset (active high) */			SK_OUT32(IoC, B2_GP_IO, DWord);	/* clear PHY reset */		}		if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) ||			(pAC->GIni.GIChipId == CHIP_ID_YUKON)) {			SK_OUT32(IoC, GPHY_CTRL, 0x01f04001);	/* set PHY reset */			SK_OUT32(IoC, GPHY_CTRL, 0x01f04002);	/* clear PHY reset */		} else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -