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

📄 skge.c

📁 这是Marvell Technology Group Ltd. 4355 (rev 12)网卡在linux下的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
{	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 {			SK_OUT8(IoC, GPHY_CTRL, 0x02);		/* clear PHY reset */		}		SK_OUT8(IoC, GMAC_CTRL, 0x02);			/* clear MAC reset */#ifdef USE_ASF_DASH_FW		SkSetFWLinkParams(pAC, IoC, Port);#else		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, 0x01e1); /* Advertise 10/100 HD/FD */		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, 0x0000); /* Do not advertise 1000 HD/FD */		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, 0xb300); /* 100 MBps, Autoneg, FD */		GM_OUT16(IoC, Port, GM_GP_CTRL, 0x383a);#endif	} else if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) ||			   (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE_P)) {		SK_OUT8(IoC, B0_POWER_CTRL, 0xa9);		/* enable VAUX */		SK_OUT8(IoC, GPHY_CTRL, 0x02);			/* clear PHY reset */		SK_OUT8(IoC, GMAC_CTRL, 0x02);			/* clear MAC reset */		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, 0x0130); /* Enable Automatic Crossover */		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, 0xb300);     /* 100 MBit, disable Autoneg */		/*		 * MAC Configuration:		 * Set the MAC to 100 HD and enable the auto update		 * features for Speed and Duplex Mode.		 * If autonegotiation completes successfully, the		 * MAC takes the link parameters from the PHY.		 * If the link partner doesn't support autonegotiation,		 * the MAC can receive magic packets if the link partner		 * uses 100 HD.		 */		GM_OUT16(IoC, Port, GM_GP_CTRL, 0x383a);	}#ifdef USE_ASF_DASH_FW	SkAsfSuspend(pAC, pAC->IoBase);#endif	/*	 * Set Up Magic Packet parameters	 */#ifndef USE_ASF_DASH_FW	for (i = 0; i < 6; i+=2) {				/* Set up magic packet MAC address */		SK_IN16(IoC, B2_MAC_1 + i, &Word);		SK_OUT16(IoC, WOL_MAC_ADDR_LO + i, Word);	}	Word = 0x0;	Word |= WOL_CTL_ENA_PME_ON_MAGIC_PKT;   /* Enable PME on magic packet */	Word |= WOL_CTL_ENA_MAGIC_PKT_UNIT;     /* Enable magic packet unit */	SK_OUT16(IoC, WOL_CTRL_STAT, Word);#endif#ifdef USE_ASF_DASH_FW	for (i = 0; i < 6; i+=2) {				/* Delete magic packet MAC address */		SK_OUT16(IoC, WOL_MAC_ADDR_LO + i, 0x0);	}	Word = 0x0;	Word |= WOL_CTL_DIS_PME_ON_MAGIC_PKT;   /* Disable PME on magic packet */	Word |= WOL_CTL_DIS_MAGIC_PKT_UNIT;     /* Disable magic packet unit */	Word |= WOL_CTL_DIS_PME_ON_LINK_CHG;    /* Disable PME on link change */	Word |= WOL_CTL_DIS_LINK_CHG_UNIT;      /* Disable link change unit */	SK_OUT16(IoC, WOL_CTRL_STAT, Word);#endif	/*	 * Set up PME generation	 */	/* set PME legacy mode */	/* Only for PCI express based chipsets */	if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) ||		(pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) || 		(CHIP_ID_YUKON_2(pAC))) {		if (pAC->GIni.GIChipId != CHIP_ID_YUKON_EX) {	  		SkPciReadCfgDWord(pAC, PCI_OUR_REG_1, &DWord);	  		DWord |= 0x8000;	  		SkPciWriteCfgDWord(pAC, PCI_OUR_REG_1, DWord);		}	}#ifndef USE_ASF_DASH_FW	SK_OUT8(IoC, RX_GMF_CTRL_T, (SK_U8)GMF_RST_SET);#endif	SK_OUT16(IoC, B0_CTST, Y2_HW_WOL_OFF);

⌨️ 快捷键说明

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