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

📄 skxmac2.c

📁 这是Marvell Technology Group Ltd. 4355 (rev 12)网卡在linux下的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* configure the Serial Mode Register */#ifndef SK_SLIM	SWord = (SK_U16)(DATA_BLIND_VAL(pPrt->PMacDataBlind) |		GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData));	if (pPrt->PMacLimit4) {		/* reset of collision counter after 4 consecutive collisions */		SWord |= GM_SMOD_LIMIT_4;	}#else	SWord = (SK_U16)(DATA_BLIND_VAL(DATA_BLIND_DEF) |		GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF));#endif	if (pPrt->PPortUsage == SK_JUMBO_LINK) {		/* enable jumbo mode (Max. Frame Length = 9018) */		SWord |= GM_SMOD_JUMBO_ENA;	}	if (HW_FEATURE(pAC, HWF_NEW_FLOW_CONTROL)) {		/* enable new Flow-Control */		SWord |= GM_NEW_FLOW_CTRL;	}	GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);	/*	 * configure the GMACs Station Addresses	 * in PROM you can find our addresses at:	 * B2_MAC_1 = xx xx xx xx xx x0 virtual address	 * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A	 * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort	 */	for (i = 0; i < 3; i++) {		/*		 * The following 2 statements are together endianess		 * independent. Remember this when changing.		 */		/* physical address: will be used for pause frames */		SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);#ifdef WA_DEV_16		/* WA for deviation #16 */		if (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) {			/* swap the address bytes */			SWord = ((SWord & 0xff00) >> 8)	| ((SWord & 0x00ff) << 8);			/* write to register in reversed order */			GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord);		}		else {			GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);		}#else		GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);#endif /* WA_DEV_16 */		/* virtual address: will be used for data */		SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);		GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);		/* reset Multicast filtering Hash registers 1-3 */		GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + i * 4, 0);	}	/* reset Multicast filtering Hash register 4 */	GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0);	/* enable interrupt mask for counter overflows */	GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0);	GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);	GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);	pPrt->PState = SK_PRT_STOP;}	/* SkGmInitMac */#ifdef SK_PHY_LP_MODE/****************************************************************************** * *	SkGmEnterLowPowerMode() * * Description: *	This function sets the Marvell Alaska PHY to the low power mode *	given by parameter mode. *	The following low power modes are available: * *		- COMA Mode (Deep Sleep): *			The PHY cannot wake up on its own. * *		- IEEE 22.2.4.1.5 compatible power down mode *			The PHY cannot wake up on its own. * *		- energy detect mode *			The PHY can wake up on its own by detecting activity *			on the CAT 5 cable. * *		- energy detect plus mode *			The PHY can wake up on its own by detecting activity *			on the CAT 5 cable. *			Connected devices can be woken up by sending normal link *			pulses every second. * * Note: * * Returns: *		0: ok *		1: error */int SkGmEnterLowPowerMode(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* I/O Context */int		Port,		/* Port Index (e.g. MAC_1) */SK_U8	Mode)		/* low power mode */{	SK_U8	LastMode;	SK_U8	Byte;	SK_U16	Word;	SK_U16	PhySpec;	SK_U16	ClkDiv;	SK_U32	DWord;	SK_U32	PowerDownBit;	SK_U32	ClkMask;	int		ChipId;	int		Ret = 0;	if (!(CHIP_ID_YUKON_2(pAC) || (pAC->GIni.GIYukonLite &&		pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3))) {		return(1);	}	/* save current power mode */	LastMode = pAC->GIni.GP[Port].PPhyPowerState;	pAC->GIni.GP[Port].PPhyPowerState = Mode;	ChipId = pAC->GIni.GIChipId;	SK_DBG_MSG(pAC, SK_DBGMOD_POWM, SK_DBGCAT_CTRL,		("SkGmEnterLowPowerMode: %u\n", Mode));	/* release GPHY Control reset */	SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_CLR);	/* release GMAC reset */	SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR);	if (ChipId == CHIP_ID_YUKON_EC_U ||		ChipId == CHIP_ID_YUKON_EX ||		ChipId >= CHIP_ID_YUKON_SUPR) {		/* select page 2 to access MAC control register */		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 2);		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);		/* allow GMII Power Down */		Word &= ~PHY_M_MAC_GMIF_PUP;		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);		/* set page register back to 0 */		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);	}	switch (Mode) {	/* COMA mode (deep sleep) */	case PHY_PM_DEEP_SLEEP:		/* setup General Purpose Control Register */		GM_OUT16(IoC, Port, GM_GP_CTRL, GM_GPCR_FL_PASS |			GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);		if (CHIP_ID_YUKON_2(pAC)) {			/* set power down bit */			PowerDownBit = (Port == MAC_1) ? PCI_Y2_PHY1_POWD :				PCI_Y2_PHY2_POWD;			if (ChipId != CHIP_ID_YUKON_EC) {				if (ChipId == CHIP_ID_YUKON_EC_U) {					SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &PhySpec);					/* enable Power Down */					PhySpec |= PHY_M_PC_POW_D_ENA;					SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PhySpec);				}				/* set IEEE compatible Power Down Mode (dev. #4.99) */				Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_PDOWN);			}		}		else {			/* apply COMA mode workaround for Yukon-Plus */			(void)SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 31);			Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xfff3);			PowerDownBit = PCI_PHY_COMA;		}		SK_TST_MODE_ON(IoC);		SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord);		/* set PHY to PowerDown/COMA Mode */		SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord | PowerDownBit);		/* check if this routine was called from a for() loop */		if (CHIP_ID_YUKON_2(pAC) &&			(pAC->GIni.GIMacsFound == 1 || Port == MAC_2)) {			if (ChipId == CHIP_ID_YUKON_EC_U ||				ChipId == CHIP_ID_YUKON_EX ||				ChipId >= CHIP_ID_YUKON_FE_P) {				/* set GPHY Control reset */				SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_SET);				/* additional power saving measurements */				SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_4), &DWord);				if (pAC->GIni.GIGotoD3Cold) {					/* set gating core clock for LTSSM in DETECT state */					DWord |= (P_PEX_LTSSM_STAT(P_PEX_LTSSM_DET_STAT) |						/* enable Gate Root Core Clock */						P_CLK_GATE_ROOT_COR_ENA);					/* set Mask Register for Release/Gate Clock */					SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5),						P_REL_MAIN_PWR_AVAIL | P_GAT_MAIN_PWR_N_AVAIL);				}				else {					/* set gating core clock for LTSSM in L1 state */					DWord |= (P_PEX_LTSSM_STAT(P_PEX_LTSSM_L1_STAT) |						/* auto clock gated scheme controlled by CLKREQ */						P_ASPM_A1_MODE_SELECT |						/* enable Gate Root Core Clock */						P_CLK_GATE_ROOT_COR_ENA);					if (HW_FEATURE(pAC, HWF_WA_DEV_4200)) {						/* enable Clock Power Management (CLKREQ) */						SK_IN16(IoC, PCI_C(pAC, PEX_CAP_REGS(PEX_LNK_CTRL)), &Word);						Word |= PEX_LC_CLK_PM_ENA;						SK_OUT16(IoC, PCI_C(pAC, PEX_CAP_REGS(PEX_LNK_CTRL)), Word);					}					else {						/* force CLKREQ Enable in Our4 (A1b only) */						DWord |= P_ASPM_FORCE_CLKREQ_ENA;					}					if (ChipId == CHIP_ID_YUKON_FE_P) {						/* set delay-timer value to 2 ms */						DWord |= P_TIMER_VALUE_MSK;					}					/* set Mask Register for Release/Gate Clock */					SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5),						P_REL_PCIE_EXIT_L1_ST | P_GAT_PCIE_ENTER_L1_ST |						P_REL_PCIE_RX_EX_IDLE | P_GAT_PCIE_RX_EL_IDLE |						P_REL_GPHY_LINK_UP | P_GAT_GPHY_LINK_DOWN);				}				SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_4), DWord);				if (!pAC->GIni.GIAsfRunning) {					/* stop the watchdog */					SK_OUT32(IoC, CPU_WDOG, 0);					/* put CPU into reset state */					SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, (SK_U8)HCU_CCSR_ASF_RESET);					if (!HW_FEATURE(pAC, HWF_WA_DEV_542)) {						/* put CPU into halt state */						SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, (SK_U8)HCU_CCSR_ASF_HALTED);					}					/* stop the watchdog */					SK_OUT32(IoC, CPU_WDOG, 0);				}			}			else {				/* ASF system clock stopped */				SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, (SK_U8)Y2_ASF_CLK_HALT);			}			if (HW_FEATURE(pAC, HWF_RED_CORE_CLK_SUP)) {				/* divide clock by 4 only for Yukon-EC */				ClkDiv = (ChipId == CHIP_ID_YUKON_EC) ? 1 : 0;				/* on Yukon-2 clock select value is 31 */				DWord = (ChipId == CHIP_ID_YUKON_XL) ?					(Y2_CLK_DIV_VAL_2(0) | Y2_CLK_SEL_VAL_2(31)) :					 Y2_CLK_DIV_VAL(ClkDiv);				/* check for Yukon-2 dual port PCI-Express adapter */				if (!(pAC->GIni.GIMacsFound == 2 &&					  pAC->GIni.GIPciBus == SK_PEX_BUS)) {					/* enable Core Clock Division */					DWord |= Y2_CLK_DIV_ENA;				}				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,					("Set Core Clock: 0x%08X\n", DWord));				/* reduce Core Clock Frequency */				SK_OUT32(IoC, B2_Y2_CLK_CTRL, DWord);			}			if (HW_FEATURE(pAC, HWF_CLK_GATING_ENABLE)) {				/* check for Yukon-2 Rev. A2 */				if (ChipId == CHIP_ID_YUKON_XL &&					pAC->GIni.GIChipRev > CHIP_REV_YU_XL_A1) {					/* enable bits are inverted */					Byte = 0;				}				else {					Byte = (SK_U8)(Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |						Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |						Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);				}				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,					("Set Clock Gating: 0x%02X\n", Byte));				/* disable MAC/PHY, PCI and Core Clock for both Links */				SK_OUT8(IoC, B2_Y2_CLK_GATE, Byte);			}			if (pAC->GIni.GILevel != SK_INIT_IO &&				pAC->GIni.GIMacsFound == 1 &&				pAC->GIni.GIPciBus == SK_PEX_BUS) {				if (ChipId == CHIP_ID_YUKON_EC_U ||					ChipId == CHIP_ID_YUKON_EX ||					ChipId >= CHIP_ID_YUKON_FE_P) {#ifdef PCI_E_L1_STATE					SK_IN16(IoC, PCI_C(pAC, PCI_OUR_REG_1), &Word);					/* force to PCIe L1 */					Word |= (SK_U16)PCI_FORCE_PEX_L1;					SK_OUT16(IoC, PCI_C(pAC, PCI_OUR_REG_1), Word);#else /* !PCI_E_L1_STATE */#ifdef DEEP_SLEEP_D1					SK_IN16(IoC, PCI_C(pAC, PEX_CAP_REGS(PEX_LNK_CTRL)), &Word);					/* check if ASPM L1 enabled */					if ((Word & PEX_LC_ASPM_LC_L1) != 0) {						break;					}#else					break;#endif /* !DEEP_SLEEP_D1 */#endif /* !PCI_E_L1_STATE */				}				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,					("Switch to D1 state\n", DWord));				/* switch to D1 state */				SK_OUT8(IoC, PCI_C(pAC, PCI_PM_CTL_STS), PCI_PM_STATE_D1);			}		}		break;	/* IEEE 22.2.4.1.5 compatible power down mode */	case PHY_PM_IEEE_POWER_DOWN:		if (!CHIP_ID_YUKON_2(pAC) && !pAC->GIni.GIYukonLite) {			Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &PhySpec);			/* disable MAC 125 MHz clock */			PhySpec |= PHY_M_PC_DIS_125CLK;			PhySpec &= ~PHY_M_PC_MAC_POW_UP;			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PhySpec);			/* these register changes must be followed by a software reset */			SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word | PHY_CT_RESET);		}		/* switch IEEE compatible power down mode on */		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_PDOWN);#ifdef DEBUG		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);#endif /* DEBUG */		break;	/* energy detect and energy detect plus mode */	case PHY_PM_ENERGY_DETECT:	case PHY_PM_ENERGY_DETECT_PLUS:		Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &PhySpec);#ifdef XXX		/* disable Polarity Reversal */		PhySpec |= PHY_M_PC_POL_R_DIS;#endif /* XXX */		if (!CHIP_ID_YUKON_2(pAC)) {			/* disable MAC 125 MHz clock */			PhySpec |= PHY_M_PC_DIS_125CLK;		}		if (ChipId == CHIP_ID_YUKON_FE || ChipId == CHIP_ID_YUKON_FE_P) {			/* enable Energy Detect (sense & pulse) */			PhySpec |= PHY_M_PC_ENA_ENE_DT;		}		else {			/* clear energy detect mode bits */			PhySpec &= ~PHY_M_PC_EN_DET_MSK;			PhySpec |= (Mode == PHY_PM_ENERGY_DETECT) ? PHY_M_PC_EN_DET :				PHY_M_PC_EN_DET_PLUS;		}		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PhySpec);		/* these register changes must be followed by a software reset */		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);		Word |= PHY_CT_RESET;		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);		if (ChipId == CHIP_ID_YUKON_FE_P) {			/* Re-enable Link Partner Next Page */			PhySpec |= PHY_M_PC_ENA_LIP_NP;			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PhySpec);		}		if (ChipId == CHIP_ID_YUKON_EC_U ||			ChipId == CHIP_ID_YUKON_EX ||			ChipId >= CHIP_ID_YUKON_FE_P) {			/* additional power saving measurements */			SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_4), &DWord);			if (pAC->GIni.GIGotoD3Cold) {				/* set gating core clock for LTSSM in DETECT state */				DWord |= (P_PEX_LTSSM_STAT(P_PEX_LTSSM_DET_STAT) |					/* enable Gate Root Core Clock */					P_CLK_GATE_ROOT_COR_ENA);				/* set Mask Register for Release/Gate Clock */				SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5),					P_REL_MAIN_PWR_AVAIL | P_GAT_MAIN_PWR_N_AVAIL);			}			else {				/* set gating core clock for LTSSM in L1 state */				DWord |= (P_PEX_LTSSM_STAT(P_PEX_LTSSM_L1_STAT) |					/* auto clock gated scheme controlled by CLKREQ */					P_ASPM_A1_MODE_SELECT |					/* enable Gate Root Core Clock */					P_CLK_GATE_ROOT_COR_ENA);				if (HW_FEATURE(pAC, HWF_WA_DEV_4200)) {					/* enable Clock Power Management (CLKREQ) */					SK_IN16(IoC, PCI_C(pAC, PEX_CAP_REGS(PEX_LNK_CTRL)), &Word);					Word |= PEX_LC_CLK_PM_ENA;					SK_OUT16(IoC, PCI_C(pAC, PEX_CAP_REGS(PEX_LNK_CTRL)), Word);				}				else {					/* force CLKREQ Enable in Our4 (A1b only) */					DWord |= P_ASPM_FORCE_CLKREQ_ENA;				}				if (ChipId == CHIP_ID_YUKON_FE_P) {					/* set delay-timer value to 2 ms */					DWord |= P_TIMER_VALUE_MSK;				}				ClkMask = P_REL_PCIE_EXIT_L1_ST | P_GAT_PCIE_ENTER_L1_ST |						P_REL_PCIE_RX_EX_IDLE | P_GAT_PCIE_RX_EL_IDLE |						P_REL_GPHY_LINK_UP | P_GAT_GPHY_LINK_DOWN;				if (pAC->GIni.GIAsfEnabled) {					ClkMask |= P_REL_CPU_TO_SLEEP | P_GAT_CPU_TO_SLEEP;				}				/* set Mask Register for Release/Gate Clock */				SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), ClkMask);			}			SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_4), DWord);#ifdef PCI_E_L1_STATE			SK_IN16(IoC, PCI_C(pAC, PCI_OUR_REG_1), &Word);			/* enable PCIe L1 on GPHY link down */

⌨️ 快捷键说明

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