patch-2.4.25 linux-2.4.25/drivers/net/sk98lin/skxmac2.c
Next file: linux-2.4.25/drivers/net/starfire.c
Previous file: linux-2.4.25/drivers/net/sk98lin/sktimer.c
Back to the patch index
Back to the overall index
- Lines: 1024
- Date:
2004-02-18 05:36:31.000000000 -0800
- Orig file:
linux-2.4.24/drivers/net/sk98lin/skxmac2.c
- Orig date:
2003-11-28 10:26:20.000000000 -0800
diff -urN linux-2.4.24/drivers/net/sk98lin/skxmac2.c linux-2.4.25/drivers/net/sk98lin/skxmac2.c
@@ -2,8 +2,8 @@
*
* Name: skxmac2.c
* Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.99 $
- * Date: $Date: 2003/07/11 12:19:33 $
+ * Version: $Revision: 1.102 $
+ * Date: $Date: 2003/10/02 16:53:58 $
* Purpose: Contains functions to initialize the MACs and PHYs
*
******************************************************************************/
@@ -27,6 +27,23 @@
* History:
*
* $Log: skxmac2.c,v $
+ * Revision 1.102 2003/10/02 16:53:58 rschmidt
+ * Changed setting of GMAC parameters with new macros.
+ * Added define SLIM around SkGm...LowPowerMode().
+ * Editorial changes.
+ *
+ * Revision 1.101 2003/09/16 14:49:07 rschmidt
+ * Added routines SkGmClearRst(), SkXmClearRst, SkMacClearRst().
+ * Added WA code for Yukon-Lite's COMA mode in SkGmHardRst().
+ * Replaced PCI-Config R/W through internal access.
+ * Fixed return from coma mode in SkGmLeaveLowPowerMode().
+ * Fixed compiler warnings for different types.
+ * Editorial changes.
+ *
+ * Revision 1.100 2003/09/16 07:09:11 mschmid
+ * Added functions SkGmEnterLowPowerMode() and
+ * SkGmLeaveLowPowerMode()
+ *
* Revision 1.99 2003/07/11 12:19:33 rschmidt
* Reduced init values for Master & Slave downshift counters to
* minimum values.
@@ -164,7 +181,7 @@
* Revision 1.74 2002/08/12 14:00:17 rschmidt
* Replaced usage of Broadcom PHY Ids with defines.
* Corrected error messages in SkGmMacStatistic().
- * Made SkMacPromiscMode() public for ADDR-Modul.
+ * Made SkMacPromiscMode() public for ADDR-Module.
* Editorial changes.
*
* Revision 1.73 2002/08/08 16:26:24 rschmidt
@@ -475,7 +492,7 @@
#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
static const char SysKonnectFileId[] =
- "@(#) $Id: skxmac2.c,v 1.99 2003/07/11 12:19:33 rschmidt Exp $ (C) Marvell.";
+ "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";
#endif
#ifdef GENESIS
@@ -1343,7 +1360,7 @@
* Description:
* The XMAC of the specified 'Port' and all connected devices
* (PHY and SERDES) will receive a reset signal on its *Reset pins.
- * External PHYs must be reset be clearing a bit in the GPIO register
+ * External PHYs must be reset by clearing a bit in the GPIO register
* (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns).
*
* ATTENTION:
@@ -1386,23 +1403,62 @@
/* For external PHYs there must be special handling */
if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
- /* reset external PHY */
+
SK_IN32(IoC, B2_GP_IO, &Reg);
+
if (Port == 0) {
- Reg |= GP_DIR_0; /* set to output */
- Reg &= ~GP_IO_0;
+ Reg |= GP_DIR_0; /* set to output */
+ Reg &= ~GP_IO_0; /* set PHY reset (active low) */
}
else {
- Reg |= GP_DIR_2; /* set to output */
- Reg &= ~GP_IO_2;
+ Reg |= GP_DIR_2; /* set to output */
+ Reg &= ~GP_IO_2; /* set PHY reset (active low) */
}
+ /* reset external PHY */
SK_OUT32(IoC, B2_GP_IO, Reg);
/* short delay */
SK_IN32(IoC, B2_GP_IO, &Reg);
}
-
} /* SkXmHardRst */
+
+
+/******************************************************************************
+ *
+ * SkXmClearRst() - Release the PHY & XMAC reset
+ *
+ * Description:
+ *
+ * Returns:
+ * nothing
+ */
+static void SkXmClearRst(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+int Port) /* Port Index (MAC_1 + n) */
+{
+ SK_U32 DWord;
+
+ /* clear HW reset */
+ SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
+
+ if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
+
+ SK_IN32(IoC, B2_GP_IO, &DWord);
+
+ if (Port == 0) {
+ DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */
+ }
+ else {
+ DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */
+ }
+ /* Clear PHY reset */
+ SK_OUT32(IoC, B2_GP_IO, DWord);
+
+ /* Enable GMII interface */
+ XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
+ }
+} /* SkXmClearRst */
#endif /* GENESIS */
@@ -1452,10 +1508,6 @@
*
* Description:
*
- * ATTENTION:
- * It is absolutely necessary to reset the SW_RST Bit first
- * before calling this function.
- *
* Returns:
* nothing
*/
@@ -1464,6 +1516,20 @@
SK_IOC IoC, /* IO context */
int Port) /* Port Index (MAC_1 + n) */
{
+ SK_U32 DWord;
+
+ /* WA code for COMA mode */
+ if (pAC->GIni.GIYukonLite &&
+ pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+
+ SK_IN32(IoC, B2_GP_IO, &DWord);
+
+ DWord |= (GP_DIR_9 | GP_IO_9);
+
+ /* set PHY reset */
+ SK_OUT32(IoC, B2_GP_IO, DWord);
+ }
+
/* set GPHY Control reset */
SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
@@ -1471,6 +1537,73 @@
SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
} /* SkGmHardRst */
+
+
+/******************************************************************************
+ *
+ * SkGmClearRst() - Release the GPHY & GMAC reset
+ *
+ * Description:
+ *
+ * Returns:
+ * nothing
+ */
+static void SkGmClearRst(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+int Port) /* Port Index (MAC_1 + n) */
+{
+ SK_U32 DWord;
+
+#ifdef XXX
+ /* clear GMAC Control reset */
+ SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
+
+ /* set GMAC Control reset */
+ SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
+#endif /* XXX */
+
+ /* WA code for COMA mode */
+ if (pAC->GIni.GIYukonLite &&
+ pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+
+ SK_IN32(IoC, B2_GP_IO, &DWord);
+
+ DWord |= GP_DIR_9; /* set to output */
+ DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
+
+ /* clear PHY reset */
+ SK_OUT32(IoC, B2_GP_IO, DWord);
+ }
+
+ /* set HWCFG_MODE */
+ DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
+ GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
+ (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
+ GPC_HWCFG_GMII_FIB);
+
+ /* set GPHY Control reset */
+ SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
+
+ /* release GPHY Control reset */
+ SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
+
+#ifdef VCPU
+ VCpuWait(9000);
+#endif /* VCPU */
+
+ /* clear GMAC Control reset */
+ SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
+
+#ifdef VCPU
+ VCpuWait(2000);
+
+ SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord);
+
+ SK_IN32(IoC, B0_ISRC, &DWord);
+#endif /* VCPU */
+
+} /* SkGmClearRst */
#endif /* YUKON */
@@ -1553,6 +1686,38 @@
} /* SkMacHardRst */
+/******************************************************************************
+ *
+ * SkMacClearRst() - Clear the MAC reset
+ *
+ * Description: calls a clear MAC reset routine dep. on board type
+ *
+ * Returns:
+ * nothing
+ */
+void SkMacClearRst(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+int Port) /* Port Index (MAC_1 + n) */
+{
+
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+
+ SkXmClearRst(pAC, IoC, Port);
+ }
+#endif /* GENESIS */
+
+#ifdef YUKON
+ if (pAC->GIni.GIYukon) {
+
+ SkGmClearRst(pAC, IoC, Port);
+ }
+#endif /* YUKON */
+
+} /* SkMacClearRst */
+
+
#ifdef GENESIS
/******************************************************************************
*
@@ -1574,7 +1739,6 @@
int Port) /* Port Index (MAC_1 + n) */
{
SK_GEPORT *pPrt;
- SK_U32 Reg;
int i;
SK_U16 SWord;
@@ -1594,32 +1758,10 @@
}
if (pPrt->PState == SK_PRT_RESET) {
- /*
- * clear HW reset
- * Note: The SW reset is self clearing, therefore there is
- * nothing to do here.
- */
- SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
- /* Ensure that XMAC reset release is done (errata from LReinbold?) */
- SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
+ SkXmClearRst(pAC, IoC, Port);
- /* Clear PHY reset */
if (pPrt->PhyType != SK_PHY_XMAC) {
-
- SK_IN32(IoC, B2_GP_IO, &Reg);
-
- if (Port == 0) {
- Reg |= (GP_DIR_0 | GP_IO_0); /* set to output */
- }
- else {
- Reg |= (GP_DIR_2 | GP_IO_2); /* set to output */
- }
- SK_OUT32(IoC, B2_GP_IO, Reg);
-
- /* Enable GMII interface */
- XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
-
/* read Id from external PHY (all have the same address) */
SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);
@@ -1831,43 +1973,11 @@
}
if (pPrt->PState == SK_PRT_RESET) {
- /* set GPHY Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
-
- /* set GMAC Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
-
-#ifdef XXX
- /* clear GMAC Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
-
- /* set GMAC Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
-#endif /* XXX */
-
- /* set HWCFG_MODE */
- DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
- GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
- (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
- GPC_HWCFG_GMII_FIB);
-
- /* set GPHY Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
-
- /* release GPHY Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
-
-#ifdef VCPU
- VCpuWait(9000);
-#endif /* VCPU */
-
- /* clear GMAC Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
-
-#ifdef VCPU
- VCpuWait(2000);
-#endif /* VCPU */
+
+ SkGmHardRst(pAC, IoC, Port);
+ SkGmClearRst(pAC, IoC, Port);
+
/* Auto-negotiation ? */
if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
/* Auto-negotiation disabled */
@@ -1906,6 +2016,7 @@
SWord |= GM_GPCR_DUP_FULL;
}
+ /* flow-control settings */
switch (pPrt->PFlowCtrlMode) {
case SK_FLOW_MODE_NONE:
/* set Pause Off */
@@ -1940,7 +2051,7 @@
(void)SkGmResetCounter(pAC, IoC, Port);
/* setup Transmit Control Register */
- GM_OUT16(IoC, Port, GM_TX_CTRL, GM_TXCR_COL_THR);
+ GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres));
/* setup Receive Control Register */
GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
@@ -1954,7 +2065,9 @@
GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
#endif /* VCPU */
- SWord = (SK_U16)(JAM_LEN_VAL(3) | JAM_IPG_VAL(11) | IPG_JAM_DATA(26));
+ SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
+ TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
+ TX_IPG_JAM_DATA(pPrt->PMacJamIpgData);
GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
@@ -1963,7 +2076,12 @@
GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
#endif /* VCPU */
- SWord = GM_SMOD_VLAN_ENA | IPG_VAL_FAST_ETH;
+ SWord = 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;
+ }
if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
/* enable jumbo mode (Max. Frame Length = 9018) */
@@ -2021,11 +2139,13 @@
GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
+#if defined(SK_DIAG) || defined(DEBUG)
/* read General Purpose Status */
GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("MAC Stat Reg=0x%04X\n", SWord));
+ ("MAC Stat Reg.=0x%04X\n", SWord));
+#endif /* SK_DIAG || DEBUG */
#ifdef SK_DIAG
c_print("MAC Stat Reg=0x%04X\n", SWord);
@@ -2226,6 +2346,7 @@
SKERR_HWI_E015MSG);
}
+ /* Set Flow-control capabilities */
switch (pPrt->PFlowCtrlMode) {
case SK_FLOW_MODE_NONE:
Ctrl |= PHY_X_P_NO_PAUSE;
@@ -2306,7 +2427,9 @@
SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
("InitPhyBcom: no auto-negotiation Port %d\n", Port));
/* Set DuplexMode in Config register */
- Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
+ if (pPrt->PLinkMode == SK_LMODE_FULL) {
+ Ctrl1 |= PHY_CT_DUP_MD;
+ }
/* Determine Master/Slave manually if not already done */
if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
@@ -2346,6 +2469,7 @@
SKERR_HWI_E015MSG);
}
+ /* Set Flow-control capabilities */
switch (pPrt->PFlowCtrlMode) {
case SK_FLOW_MODE_NONE:
Ctrl3 |= PHY_B_P_NO_PAUSE;
@@ -2375,12 +2499,12 @@
/* Write 1000Base-T Control Register */
SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
+ ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
/* Write AutoNeg Advertisement Register */
SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
+ ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
if (DoLoop) {
/* Set the Phy Loopback bit, too */
@@ -2409,6 +2533,281 @@
#ifdef YUKON
+#ifndef SK_SLIM
+/******************************************************************************
+ *
+ * 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):
+ * Power consumption: ~15 - 30 mW
+ * The PHY cannot wake up on its own.
+ *
+ * - IEEE 22.2.4.1.5 compatible power down mode
+ * Power consumption: ~240 mW
+ * The PHY cannot wake up on its own.
+ *
+ * - energy detect mode
+ * Power consumption: ~160 mW
+ * The PHY can wake up on its own by detecting activity
+ * on the CAT 5 cable.
+ *
+ * - energy detect plus mode
+ * Power consumption: ~150 mW
+ * 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 one second.
+ *
+ * Note:
+ *
+ * Returns:
+ * 0: ok
+ * 1: error
+ */
+int SkGmEnterLowPowerMode(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+int Port, /* Port Index (e.g. MAC_1) */
+SK_U8 Mode) /* low power mode */
+{
+ SK_U16 Word;
+ SK_U32 DWord;
+ SK_U8 LastMode;
+ int Ret = 0;
+
+ if (pAC->GIni.GIYukonLite &&
+ pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+
+ /* save current power mode */
+ LastMode = pAC->GIni.GP[Port].PPhyPowerState;
+ pAC->GIni.GP[Port].PPhyPowerState = Mode;
+
+ switch (Mode) {
+ /* coma mode (deep sleep) */
+ case PHY_PM_DEEP_SLEEP:
+ /* setup General Purpose Control Register */
+ GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS |
+ GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
+
+ /* apply COMA mode workaround */
+ SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f);
+ SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3);
+
+ SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
+
+ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+
+ /* Set PHY to Coma Mode */
+ SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA);
+
+ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+ break;
+
+ /* IEEE 22.2.4.1.5 compatible power down mode */
+ case PHY_PM_IEEE_POWER_DOWN:
+ /*
+ * - disable MAC 125 MHz clock
+ * - allow MAC power down
+ */
+ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+ Word |= PHY_M_PC_DIS_125CLK;
+ Word &= ~PHY_M_PC_MAC_POW_UP;
+ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+ /*
+ * register changes must be followed by a software
+ * reset to take effect
+ */
+ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+ Word |= PHY_CT_RESET;
+ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+
+ /* switch IEEE compatible power down mode on */
+ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+ Word |= PHY_CT_PDOWN;
+ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+ break;
+
+ /* energy detect and energy detect plus mode */
+ case PHY_PM_ENERGY_DETECT:
+ case PHY_PM_ENERGY_DETECT_PLUS:
+ /*
+ * - disable MAC 125 MHz clock
+ */
+ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+ Word |= PHY_M_PC_DIS_125CLK;
+ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+ /* activate energy detect mode 1 */
+ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+
+ /* energy detect mode */
+ if (Mode == PHY_PM_ENERGY_DETECT) {
+ Word |= PHY_M_PC_EN_DET;
+ }
+ /* energy detect plus mode */
+ else {
+ Word |= PHY_M_PC_EN_DET_PLUS;
+ }
+
+ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+ /*
+ * reinitialize the PHY to force a software reset
+ * which is necessary after the register settings
+ * for the energy detect modes.
+ * Furthermore reinitialisation prevents that the
+ * PHY is running out of a stable state.
+ */
+ SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
+ break;
+
+ /* don't change current power mode */
+ default:
+ pAC->GIni.GP[Port].PPhyPowerState = LastMode;
+ Ret = 1;
+ break;
+ }
+ }
+ /* low power modes are not supported by this chip */
+ else {
+ Ret = 1;
+ }
+
+ return(Ret);
+
+} /* SkGmEnterLowPowerMode */
+
+/******************************************************************************
+ *
+ * SkGmLeaveLowPowerMode()
+ *
+ * Description:
+ * Leave the current low power mode and switch to normal mode
+ *
+ * Note:
+ *
+ * Returns:
+ * 0: ok
+ * 1: error
+ */
+int SkGmLeaveLowPowerMode(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+int Port) /* Port Index (e.g. MAC_1) */
+{
+ SK_U32 DWord;
+ SK_U16 Word;
+ SK_U8 LastMode;
+ int Ret = 0;
+
+ if (pAC->GIni.GIYukonLite &&
+ pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+
+ /* save current power mode */
+ LastMode = pAC->GIni.GP[Port].PPhyPowerState;
+ pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
+
+ switch (LastMode) {
+ /* coma mode (deep sleep) */
+ case PHY_PM_DEEP_SLEEP:
+ SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
+
+ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+
+ /* Release PHY from Coma Mode */
+ SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA);
+
+ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+ SK_IN32(IoC, B2_GP_IO, &DWord);
+
+ /* set to output */
+ DWord |= (GP_DIR_9 | GP_IO_9);
+
+ /* set PHY reset */
+ SK_OUT32(IoC, B2_GP_IO, DWord);
+
+ DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
+
+ /* clear PHY reset */
+ SK_OUT32(IoC, B2_GP_IO, DWord);
+ break;
+
+ /* IEEE 22.2.4.1.5 compatible power down mode */
+ case PHY_PM_IEEE_POWER_DOWN:
+ /*
+ * - enable MAC 125 MHz clock
+ * - set MAC power up
+ */
+ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+ Word &= ~PHY_M_PC_DIS_125CLK;
+ Word |= PHY_M_PC_MAC_POW_UP;
+ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+ /*
+ * register changes must be followed by a software
+ * reset to take effect
+ */
+ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+ Word |= PHY_CT_RESET;
+ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+
+ /* switch IEEE compatible power down mode off */
+ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+ Word &= ~PHY_CT_PDOWN;
+ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+ break;
+
+ /* energy detect and energy detect plus mode */
+ case PHY_PM_ENERGY_DETECT:
+ case PHY_PM_ENERGY_DETECT_PLUS:
+ /*
+ * - enable MAC 125 MHz clock
+ */
+ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+ Word &= ~PHY_M_PC_DIS_125CLK;
+ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+ /* disable energy detect mode */
+ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+ Word &= ~PHY_M_PC_EN_DET_MSK;
+ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+ /*
+ * reinitialize the PHY to force a software reset
+ * which is necessary after the register settings
+ * for the energy detect modes.
+ * Furthermore reinitialisation prevents that the
+ * PHY is running out of a stable state.
+ */
+ SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
+ break;
+
+ /* don't change current power mode */
+ default:
+ pAC->GIni.GP[Port].PPhyPowerState = LastMode;
+ Ret = 1;
+ break;
+ }
+ }
+ /* low power modes are not supported by this chip */
+ else {
+ Ret = 1;
+ }
+
+ return(Ret);
+
+} /* SkGmLeaveLowPowerMode */
+#endif /* !SK_SLIM */
+
+
/******************************************************************************
*
* SkGmInitPhyMarv() - Initialize the Marvell Phy registers
@@ -2457,7 +2856,6 @@
VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
Port, DoLoop);
#else /* VCPU */
-
if (DoLoop) {
/* Set 'MAC Power up'-bit, set Manual MDI configuration */
SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
@@ -2475,16 +2873,20 @@
SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
+ ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
}
/* Read PHY Control */
SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
+ if (!AutoNeg) {
+ /* Disable Auto-negotiation */
+ PhyCtrl &= ~PHY_CT_ANE;
+ }
+
PhyCtrl |= PHY_CT_RESET;
/* Assert software reset */
SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
-
#endif /* VCPU */
PhyCtrl = 0 /* PHY_CT_COL_TST */;
@@ -2533,13 +2935,9 @@
if (!DoLoop) {
PhyCtrl |= PHY_CT_RESET;
}
- /*
- * Do NOT enable Auto-negotiation here. This would hold
- * the link down because no IDLES are transmitted
- */
}
else {
- PhyCtrl |= PHY_CT_ANE;
+ /* Set Auto-negotiation advertisement */
if (pAC->GIni.GICopperType) {
/* Set Speed capabilities */
@@ -2554,6 +2952,7 @@
break;
case SK_LSPEED_100MBPS:
AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
+ /* advertise 10Base-T also */
PHY_M_AN_10_FD | PHY_M_AN_10_HD;
break;
case SK_LSPEED_10MBPS:
@@ -2581,7 +2980,7 @@
SKERR_HWI_E015MSG);
}
- /* Set Auto-negotiation advertisement */
+ /* Set Flow-control capabilities */
switch (pPrt->PFlowCtrlMode) {
case SK_FLOW_MODE_NONE:
AutoNegAdv |= PHY_B_P_NO_PAUSE;
@@ -2618,7 +3017,7 @@
SKERR_HWI_E015MSG);
}
- /* Set Auto-negotiation advertisement */
+ /* Set Flow-control capabilities */
switch (pPrt->PFlowCtrlMode) {
case SK_FLOW_MODE_NONE:
AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
@@ -2640,7 +3039,7 @@
if (!DoLoop) {
/* Restart Auto-negotiation */
- PhyCtrl |= PHY_CT_RE_CFG;
+ PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
}
}
@@ -2659,12 +3058,12 @@
/* Write 1000Base-T Control Register */
SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("1000B-T Ctrl=0x%04X\n", C1000BaseT));
+ ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
/* Write AutoNeg Advertisement Register */
SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Auto-Neg.Ad.=0x%04X\n", AutoNegAdv));
+ ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
#endif /* VCPU */
if (DoLoop) {
@@ -2694,6 +3093,8 @@
/* Write to the PHY Control register */
SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+ ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
#ifdef VCPU
VCpuWait(2000);
@@ -2712,7 +3113,7 @@
SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {
- /* only in forced 100Mbps mode */
+ /* only in forced 100 Mbps mode */
if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {
SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,
@@ -2741,7 +3142,7 @@
/* Read AutoNeg Advertisement Register */
SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Auto-Neg. Ad.=0x%04X\n", AutoNegAdv));
+ ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
/* Read Ext. PHY Specific Control */
SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
@@ -2818,13 +3219,15 @@
/* Auto-negotiation ? */
if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
/*
- * level one spec say: "1000Mbps: manual mode not allowed"
+ * level one spec say: "1000 Mbps: manual mode not allowed"
* but lets see what happens...
*/
SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
("InitPhyLone: no auto-negotiation Port %d\n", Port));
/* Set DuplexMode in Config register */
- Ctrl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
+ if (pPrt->PLinkMode == SK_LMODE_FULL) {
+ Ctrl1 |= PHY_CT_DUP_MD;
+ }
/* Determine Master/Slave manually if not already done */
if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
@@ -2857,6 +3260,7 @@
SKERR_HWI_E015MSG);
}
+ /* Set Flow-control capabilities */
switch (pPrt->PFlowCtrlMode) {
case SK_FLOW_MODE_NONE:
Ctrl3 |= PHY_L_P_NO_PAUSE;
@@ -2877,7 +3281,6 @@
/* Restart Auto-negotiation */
Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
-
}
/* Write 1000Base-T Control Register */
@@ -3019,10 +3422,10 @@
/* Check Duplex mismatch */
if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
- pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
}
else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
- pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
}
else {
/* Error */
@@ -3055,7 +3458,7 @@
/* PAUSE mismatch -> no PAUSE */
pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
}
- pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
+ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
return(SK_AND_OK);
} /* SkXmAutoNegDoneXmac */
@@ -3110,10 +3513,10 @@
/* Check Duplex mismatch */
if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) {
- pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
}
else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) {
- pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
}
else {
/* Error */
@@ -3156,7 +3559,7 @@
/* PAUSE mismatch -> no PAUSE */
pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
}
- pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
+ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
return(SK_AND_OK);
} /* SkXmAutoNegDoneBcom */
@@ -3192,6 +3595,8 @@
/* Get PHY parameters */
SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+ ("Link P.Abil.=0x%04X\n", LPAb));
if ((LPAb & PHY_M_AN_RF) != 0) {
SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
@@ -3222,15 +3627,15 @@
SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
pPrt->PAutoNegFail = SK_TRUE;
- pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
return(SK_AND_DUP_CAP);
}
if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
- pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
}
else {
- pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
}
/* Check PAUSE mismatch ??? */
@@ -3255,13 +3660,13 @@
/* set used link speed */
switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
case (unsigned)PHY_M_PS_SPEED_1000:
- pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
+ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
break;
case PHY_M_PS_SPEED_100:
- pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS;
+ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
break;
default:
- pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS;
+ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
}
return(SK_AND_OK);
@@ -3312,10 +3717,10 @@
/* Check Duplex mismatch */
if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) {
- pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
}
else {
- pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
}
/* Check Master/Slave resolution */
@@ -3338,6 +3743,7 @@
/* We are using IEEE 802.3z/D5.0 Table 37-4 */
/* we must manually resolve the abilities here */
pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+
switch (pPrt->PFlowCtrlMode) {
case SK_FLOW_MODE_NONE:
/* default */
@@ -3457,6 +3863,9 @@
return(Rtv);
}
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+ ("AutoNeg done Port %d\n", Port));
+
/* We checked everything and may now enable the link */
pPrt->PAutoNegFail = SK_FALSE;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)