aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/sk98lin/skgesirq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sk98lin/skgesirq.c')
-rw-r--r--drivers/net/sk98lin/skgesirq.c2229
1 files changed, 2229 insertions, 0 deletions
diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c
new file mode 100644
index 00000000000..3e7aa49afd0
--- /dev/null
+++ b/drivers/net/sk98lin/skgesirq.c
@@ -0,0 +1,2229 @@
+/******************************************************************************
+ *
+ * Name: skgesirq.c
+ * Project: Gigabit Ethernet Adapters, Common Modules
+ * Version: $Revision: 1.92 $
+ * Date: $Date: 2003/09/16 14:37:07 $
+ * Purpose: Special IRQ module
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/*
+ * Special Interrupt handler
+ *
+ * The following abstract should show how this module is included
+ * in the driver path:
+ *
+ * In the ISR of the driver the bits for frame transmission complete and
+ * for receive complete are checked and handled by the driver itself.
+ * The bits of the slow path mask are checked after that and then the
+ * entry into the so-called "slow path" is prepared. It is an implementors
+ * decision whether this is executed directly or just scheduled by
+ * disabling the mask. In the interrupt service routine some events may be
+ * generated, so it would be a good idea to call the EventDispatcher
+ * right after this ISR.
+ *
+ * The Interrupt source register of the adapter is NOT read by this module.
+ * SO if the drivers implementor needs a while loop around the
+ * slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
+ * each loop entered.
+ *
+ * However, the MAC Interrupt status registers are read in a while loop.
+ *
+ */
+
+#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+static const char SysKonnectFileId[] =
+ "@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell.";
+#endif
+
+#include "h/skdrv1st.h" /* Driver Specific Definitions */
+#ifndef SK_SLIM
+#include "h/skgepnmi.h" /* PNMI Definitions */
+#include "h/skrlmt.h" /* RLMT Definitions */
+#endif
+#include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */
+
+/* local function prototypes */
+#ifdef GENESIS
+static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL);
+static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int, SK_BOOL);
+static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);
+#endif /* GENESIS */
+#ifdef YUKON
+static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int, SK_BOOL);
+static void SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16);
+#endif /* YUKON */
+#ifdef OTHER_PHY
+static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int, SK_BOOL);
+static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int, SK_BOOL);
+static void SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);
+#endif /* OTHER_PHY */
+
+#ifdef GENESIS
+/*
+ * array of Rx counter from XMAC which are checked
+ * in AutoSense mode to check whether a link is not able to auto-negotiate.
+ */
+static const SK_U16 SkGeRxRegs[]= {
+ XM_RXF_64B,
+ XM_RXF_127B,
+ XM_RXF_255B,
+ XM_RXF_511B,
+ XM_RXF_1023B,
+ XM_RXF_MAX_SZ
+} ;
+#endif /* GENESIS */
+
+#ifdef __C2MAN__
+/*
+ * Special IRQ function
+ *
+ * General Description:
+ *
+ */
+intro()
+{}
+#endif
+
+/******************************************************************************
+ *
+ * SkHWInitDefSense() - Default Autosensing mode initialization
+ *
+ * Description: sets the PLinkMode for HWInit
+ *
+ * Returns: N/A
+ */
+static void SkHWInitDefSense(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+int Port) /* Port Index (MAC_1 + n) */
+{
+ SK_GEPORT *pPrt; /* GIni Port struct pointer */
+
+ pPrt = &pAC->GIni.GP[Port];
+
+ pPrt->PAutoNegTimeOut = 0;
+
+ if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
+ pPrt->PLinkMode = pPrt->PLinkModeConf;
+ return;
+ }
+
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+ ("AutoSensing: First mode %d on Port %d\n",
+ (int)SK_LMODE_AUTOFULL, Port));
+
+ pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
+
+ return;
+} /* SkHWInitDefSense */
+
+
+#ifdef GENESIS
+/******************************************************************************
+ *
+ * SkHWSenseGetNext() - Get Next Autosensing Mode
+ *
+ * Description: gets the appropriate next mode
+ *
+ * Note:
+ *
+ */
+static SK_U8 SkHWSenseGetNext(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+int Port) /* Port Index (MAC_1 + n) */
+{
+ SK_GEPORT *pPrt; /* GIni Port struct pointer */
+
+ pPrt = &pAC->GIni.GP[Port];
+
+ pPrt->PAutoNegTimeOut = 0;
+
+ if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
+ /* Leave all as configured */
+ return(pPrt->PLinkModeConf);
+ }
+
+ if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) {
+ /* Return next mode AUTOBOTH */
+ return ((SK_U8)SK_LMODE_AUTOBOTH);
+ }
+
+ /* Return default autofull */
+ return ((SK_U8)SK_LMODE_AUTOFULL);
+} /* SkHWSenseGetNext */
+
+
+/******************************************************************************
+ *
+ * SkHWSenseSetNext() - Autosensing Set next mode
+ *
+ * Description: sets the appropriate next mode
+ *
+ * Returns: N/A
+ */
+static void SkHWSenseSetNext(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+int Port, /* Port Index (MAC_1 + n) */
+SK_U8 NewMode) /* New Mode to be written in sense mode */
+{
+ SK_GEPORT *pPrt; /* GIni Port struct pointer */
+
+ pPrt = &pAC->GIni.GP[Port];
+
+ pPrt->PAutoNegTimeOut = 0;
+
+ if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
+ return;
+ }
+
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+ ("AutoSensing: next mode %d on Port %d\n",
+ (int)NewMode, Port));
+
+ pPrt->PLinkMode = NewMode;
+
+ return;
+} /* SkHWSenseSetNext */
+#endif /* GENESIS */
+
+
+/******************************************************************************
+ *
+ * SkHWLinkDown() - Link Down handling
+ *
+ * Description: handles the hardware link down signal
+ *
+ * Returns: N/A
+ */
+void SkHWLinkDown(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+int Port) /* Port Index (MAC_1 + n) */
+{
+ SK_GEPORT *pPrt; /* GIni Port struct pointer */
+
+ pPrt = &pAC->GIni.GP[Port];
+
+ /* Disable all MAC interrupts */
+ SkMacIrqDisable(pAC, IoC, Port);
+
+ /* Disable Receiver and Transmitter */
+ SkMacRxTxDisable(pAC, IoC, Port);
+
+ /* Init default sense mode */
+ SkHWInitDefSense(pAC, IoC, Port);
+
+ if (pPrt->PHWLinkUp == SK_FALSE) {
+ return;
+ }
+
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+ ("Link down Port %d\n", Port));
+
+ /* Set Link to DOWN */
+ pPrt->PHWLinkUp = SK_FALSE;
+
+ /* Reset Port stati */
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
+ pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
+ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED;
+
+ /* Re-init Phy especially when the AutoSense default is set now */
+ SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
+
+ /* GP0: used for workaround of Rev. C Errata 2 */
+
+ /* Do NOT signal to RLMT */
+
+ /* Do NOT start the timer here */
+} /* SkHWLinkDown */
+
+
+/******************************************************************************
+ *
+ * SkHWLinkUp() - Link Up handling
+ *
+ * Description: handles the hardware link up signal
+ *
+ * Returns: N/A
+ */
+static void SkHWLinkUp(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+int Port) /* Port Index (MAC_1 + n) */
+{
+ SK_GEPORT *pPrt; /* GIni Port struct pointer */
+
+ pPrt = &pAC->GIni.GP[Port];
+
+ if (pPrt->PHWLinkUp) {
+ /* We do NOT need to proceed on active link */
+ return;
+ }
+
+ pPrt->PHWLinkUp = SK_TRUE;
+ pPrt->PAutoNegFail = SK_FALSE;
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
+
+ if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF &&
+ pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL &&
+ pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) {
+ /* Link is up and no Auto-negotiation should be done */
+
+ /* Link speed should be the configured one */
+ switch (pPrt->PLinkSpeed) {
+ case SK_LSPEED_AUTO:
+ /* default is 1000 Mbps */
+ case SK_LSPEED_1000MBPS:
+ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
+ break;
+ case SK_LSPEED_100MBPS:
+ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
+ break;
+ case SK_LSPEED_10MBPS:
+ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
+ break;
+ }
+
+ /* Set Link Mode Status */
+ if (pPrt->PLinkMode == SK_LMODE_FULL) {
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL;
+ }
+ else {
+ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
+ }
+
+ /* No flow control without auto-negotiation */
+ pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
+
+ /* enable Rx/Tx */
+ (void)SkMacRxTxEnable(pAC, IoC, Port);
+ }
+} /* SkHWLinkUp */
+
+
+/******************************************************************************
+ *
+ * SkMacParity() - MAC parity workaround
+ *
+ * Description: handles MAC parity errors correctly
+ *
+ * Returns: N/A
+ */
+static void SkMacParity(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+int Port) /* Port Index of the port failed */
+{
+ SK_EVPARA Para;
+ SK_GEPORT *pPrt; /* GIni Port struct pointer */
+ SK_U32 TxMax; /* Tx Max Size Counter */
+
+ pPrt = &pAC->GIni.GP[Port];
+
+ /* Clear IRQ Tx Parity Error */
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+
+ SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR);
+ }
+#endif /* GENESIS */
+
+#ifdef YUKON
+ if (pAC->GIni.GIYukon) {
+ /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
+ SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T),
+ (SK_U8)((pAC->GIni.GIChipId == CHIP_ID_YUKON &&
+ pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
+ }
+#endif /* YUKON */
+
+ if (pPrt->PCheckPar) {
+
+ if (Port == MAC_1) {
+ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
+ }
+ else {
+ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
+ }
+ Para.Para64 = Port;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+
+ Para.Para32[0] = Port;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+
+ return;
+ }
+
+ /* Check whether frames with a size of 1k were sent */
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+ /* Snap statistic counters */
+ (void)SkXmUpdateStats(pAC, IoC, Port);
+
+ (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
+ }
+#endif /* GENESIS */
+
+#ifdef YUKON
+ if (pAC->GIni.GIYukon) {
+
+ (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax);
+ }
+#endif /* YUKON */
+
+ if (TxMax > 0) {
+ /* From now on check the parity */
+ pPrt->PCheckPar = SK_TRUE;
+ }
+} /* SkMacParity */
+
+
+/******************************************************************************
+ *
+ * SkGeHwErr() - Hardware Error service routine
+ *
+ * Description: handles all HW Error interrupts
+ *
+ * Returns: N/A
+ */
+static void SkGeHwErr(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+SK_U32 HwStatus) /* Interrupt status word */
+{
+ SK_EVPARA Para;
+ SK_U16 Word;
+
+ if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) {
+ /* PCI Errors occured */
+ if ((HwStatus & IS_IRQ_STAT) != 0) {
+ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
+ }
+ else {
+ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
+ }
+
+ /* Reset all bits in the PCI STATUS register */
+ SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
+
+ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+ SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
+ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+ Para.Para64 = 0;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
+ }
+
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+
+ if ((HwStatus & IS_NO_STAT_M1) != 0) {
+ /* Ignore it */
+ /* This situation is also indicated in the descriptor */
+ SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT);
+ }
+
+ if ((HwStatus & IS_NO_STAT_M2) != 0) {
+ /* Ignore it */
+ /* This situation is also indicated in the descriptor */
+ SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT);
+ }
+
+ if ((HwStatus & IS_NO_TIST_M1) != 0) {
+ /* Ignore it */
+ /* This situation is also indicated in the descriptor */
+ SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST);
+ }
+
+ if ((HwStatus & IS_NO_TIST_M2) != 0) {
+ /* Ignore it */
+ /* This situation is also indicated in the descriptor */
+ SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST);
+ }
+ }
+#endif /* GENESIS */
+
+#ifdef YUKON
+ if (pAC->GIni.GIYukon) {
+ /* This is necessary only for Rx timing measurements */
+ if ((HwStatus & IS_IRQ_TIST_OV) != 0) {
+ /* increment Time Stamp Timer counter (high) */
+ pAC->GIni.GITimeStampCnt++;
+
+ /* Clear Time Stamp Timer IRQ */
+ SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
+ }
+
+ if ((HwStatus & IS_IRQ_SENSOR) != 0) {
+ /* no sensors on 32-bit Yukon */
+ if (pAC->GIni.GIYukon32Bit) {
+ /* disable HW Error IRQ */
+ pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
+ }
+ }
+ }
+#endif /* YUKON */
+
+ if ((HwStatus & IS_RAM_RD_PAR) != 0) {
+ SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
+ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
+ Para.Para64 = 0;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
+ }
+
+ if ((HwStatus & IS_RAM_WR_PAR) != 0) {
+ SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
+ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
+ Para.Para64 = 0;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
+ }
+
+ if ((HwStatus & IS_M1_PAR_ERR) != 0) {
+ SkMacParity(pAC, IoC, MAC_1);
+ }
+
+ if ((HwStatus & IS_M2_PAR_ERR) != 0) {
+ SkMacParity(pAC, IoC, MAC_2);
+ }
+
+ if ((HwStatus & IS_R1_PAR_ERR) != 0) {
+ /* Clear IRQ */
+ SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);
+
+ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
+ Para.Para64 = MAC_1;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+
+ Para.Para32[0] = MAC_1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+ }
+
+ if ((HwStatus & IS_R2_PAR_ERR) != 0) {
+ /* Clear IRQ */
+ SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);
+
+ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
+ Para.Para64 = MAC_2;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+
+ Para.Para32[0] = MAC_2;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+ }
+} /* SkGeHwErr */
+
+
+/******************************************************************************
+ *
+ * SkGeSirqIsr() - Special Interrupt Service Routine
+ *
+ * Description: handles all non data transfer specific interrupts (slow path)
+ *
+ * Returns: N/A
+ */
+void SkGeSirqIsr(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* IO context */
+SK_U32 Istatus) /* Interrupt status word */
+{
+ SK_EVPARA Para;
+ SK_U32 RegVal32; /* Read register value */
+ SK_GEPORT *pPrt; /* GIni Port struct pointer */
+ SK_U16 PhyInt;
+ int i;
+
+ if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {
+ /* read the HW Error Interrupt source */
+ SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
+
+ SkGeHwErr(pAC, IoC, RegVal32);
+ }
+
+ /*
+ * Packet Timeout interrupts
+ */
+ /* Check whether MACs are correctly initialized */
+ if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) &&
+ pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) {
+ /* MAC 1 was not initialized but Packet timeout occured */
+ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
+ SKERR_SIRQ_E004MSG);
+ }
+
+ if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
+ pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
+ /* MAC 2 was not initialized but Packet timeout occured */
+ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
+ SKERR_SIRQ_E005MSG);
+ }
+
+ if ((Istatus & IS_PA_TO_RX1) != 0) {
+ /* Means network is filling us up */
+ SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,
+ SKERR_SIRQ_E002MSG);
+ SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);
+ }
+
+ if ((Istatus & IS_PA_TO_RX2) != 0) {
+ /* Means network is filling us up */
+ SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,
+ SKERR_SIRQ_E003MSG);
+ SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);
+ }
+
+ if ((Istatus & IS_PA_TO_TX1) != 0) {
+
+ pPrt = &pAC->GIni.GP[0];
+
+ /* May be a normal situation in a server with a slow network */
+ SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
+
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+ /*
+ * workaround: if in half duplex mode, check for Tx hangup.
+ * Read number of TX'ed bytes, wait for 10 ms, then compare
+ * the number with current value. If nothing changed, we assume
+ * that Tx is hanging and do a FIFO flush (see event routine).
+ */
+ if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
+ pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
+ !pPrt->HalfDupTimerActive) {
+ /*
+ * many more pack. arb. timeouts may come in between,
+ * we ignore those
+ */
+ pPrt->HalfDupTimerActive = SK_TRUE;
+ /* Snap statistic counters */
+ (void)SkXmUpdateStats(pAC, IoC, 0);
+
+ (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32);
+
+ pPrt->LastOctets = (SK_U64)RegVal32 << 32;
+
+ (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32);
+
+ pPrt->LastOctets += RegVal32;
+
+ Para.Para32[0] = 0;
+ SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
+ SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
+ }
+ }
+#endif /* GENESIS */
+ }
+
+ if ((Istatus & IS_PA_TO_TX2) != 0) {
+
+ pPrt = &pAC->GIni.GP[1];
+
+ /* May be a normal situation in a server with a slow network */
+ SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
+
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+ /* workaround: see above */
+ if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
+ pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
+ !pPrt->HalfDupTimerActive) {
+ pPrt->HalfDupTimerActive = SK_TRUE;
+ /* Snap statistic counters */
+ (void)SkXmUpdateStats(pAC, IoC, 1);
+
+ (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32);
+
+ pPrt->LastOctets = (SK_U64)RegVal32 << 32;
+
+ (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32);
+
+ pPrt->LastOctets += RegVal32;
+
+ Para.Para32[0] = 1;
+ SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
+ SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
+ }
+ }
+#endif /* GENESIS */
+ }
+
+ /* Check interrupts of the particular queues */
+ if ((Istatus & IS_R1_C) != 0) {
+ /* Clear IRQ */
+ SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
+ SKERR_SIRQ_E006MSG);
+ Para.Para64 = MAC_1;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+ Para.Para32[0] = MAC_1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+ }
+
+ if ((Istatus & IS_R2_C) != 0) {
+ /* Clear IRQ */
+ SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
+ SKERR_SIRQ_E007MSG);
+ Para.Para64 = MAC_2;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+ Para.Para32[0] = MAC_2;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+ }
+
+ if ((Istatus & IS_XS1_C) != 0) {
+ /* Clear IRQ */
+ SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
+ SKERR_SIRQ_E008MSG);
+ Para.Para64 = MAC_1;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+ Para.Para32[0] = MAC_1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+ }
+
+ if ((Istatus & IS_XA1_C) != 0) {
+ /* Clear IRQ */
+ SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
+ SKERR_SIRQ_E009MSG);
+ Para.Para64 = MAC_1;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+ Para.Para32[0] = MAC_1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+ }
+
+ if ((Istatus & IS_XS2_C) != 0) {
+ /* Clear IRQ */
+ SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
+ SKERR_SIRQ_E010MSG);
+ Para.Para64 = MAC_2;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+ Para.Para32[0] = MAC_2;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+ }
+
+ if ((Istatus & IS_XA2_C) != 0) {
+ /* Clear IRQ */
+ SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
+ SKERR_SIRQ_E011MSG);
+ Para.Para64 = MAC_2;
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+ Para.Para32[0] = MAC_2;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+ }
+
+ /* External reg interrupt */
+ if ((Istatus & IS_EXT_REG) != 0) {
+ /* Test IRQs from PHY */
+ for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+
+ pPrt = &pAC->GIni.GP[i];
+
+ if (pPrt->PState == SK_PRT_RESET) {
+ continue;
+ }
+
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+
+ switch (pPrt->PhyType) {
+
+ case SK_PHY_XMAC:
+ break;
+
+ case SK_PHY_BCOM:
+ SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
+
+ if ((PhyInt & ~PHY_B_DEF_MSK) != 0) {
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+ ("Port %d Bcom Int: 0x%04X\n",
+ i, PhyInt));
+ SkPhyIsrBcom(pAC, IoC, i, PhyInt);
+ }
+ break;
+#ifdef OTHER_PHY
+ case SK_PHY_LONE:
+ SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
+
+ if ((PhyInt & PHY_L_DEF_MSK) != 0) {
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+ ("Port %d Lone Int: %x\n",
+ i, PhyInt));
+ SkPhyIsrLone(pAC, IoC, i, PhyInt);
+ }
+ break;
+#endif /* OTHER_PHY */
+ }
+ }
+#endif /* GENESIS */
+
+#ifdef YUKON
+ if (pAC->GIni.GIYukon) {
+ /* Read PHY Interrupt Status */
+ SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);
+
+ if ((PhyInt & PHY_M_DEF_MSK) != 0) {
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+ ("Port %d Marv Int: 0x%04X\n",
+ i, PhyInt));
+ SkPhyIsrGmac(pAC, IoC, i, PhyInt);
+ }
+ }
+#endif /* YUKON */
+ }
+ }
+
+ /* I2C Ready interrupt */
+ if ((Istatus & IS_I2C_READY) != 0) {
+#ifdef SK_SLIM
+ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+#else
+ SkI2cIsr(pAC, IoC);
+#endif
+ }
+
+ /* SW forced interrupt */
+ if ((Istatus & IS_IRQ_SW) != 0) {
+ /* clear the software IRQ */
+ SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ);
+ }
+
+ if ((Istatus & IS_LNK_SYNC_M1) != 0) {
+ /*
+ * We do NOT need the Link Sync interrupt, because it shows
+ * us only a link going down.
+ */
+ /* clear interrupt */
+ SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
+ }
+
+ /* Check MAC after link sync counter */
+ if ((Istatus & IS_MAC1) != 0) {
+ /* IRQ from MAC 1 */
+ SkMacIrq(pAC, IoC, MAC_1);
+ }
+
+ if ((Istatus & IS_LNK_SYNC_M2) != 0) {
+ /*
+ * We do NOT need the Link Sync interrupt, because it shows
+ * us only a link going down.
+ */
+ /* clear interrupt */
+ SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
+ }
+
+ /* Check MAC after link sync counter */
+ if ((Istatus & IS_MAC2) != 0) {
+ /* IRQ from MAC 2 */
+ SkMacIrq(pAC, IoC, MAC_2);
+ }
+
+ /* Timer interrupt (served last) */
+ if ((Istatus & IS_TIMINT) != 0) {
+ /* check for HW Errors */
+ if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) {
+ /* read the HW Error Interrupt source */
+ SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
+
+ SkGeHwErr(pAC, IoC, RegVal32);
+ }
+
+ SkHwtIsr(pAC, IoC);
+ }
+
+} /* SkGeSirqIsr */
+
+
+#ifdef GENESIS
+/******************************************************************************
+ *
+ * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2
+ *
+ * return:
+ * 0 o.k. nothing needed
+ * 1 Restart needed on this port
+ */
+static int SkGePortCheckShorts(
+SK_AC *pAC, /* Adapter Context */
+SK_IOC IoC, /* IO Context */
+int Port) /* Which port should be checked */
+{
+ SK_U32 Shorts; /* Short Event Counter */
+ SK_U32 CheckShorts; /* Check value for Short Event Counter */
+ SK_U64 RxCts; /* Rx Counter (packets on network) */
+ SK_U32 RxTmp; /* Rx temp. Counter */
+ SK_U32 FcsErrCts; /* FCS Error Counter */
+ SK_GEPORT *pPrt; /* GIni Port struct pointer */
+ int Rtv; /* Return value */
+ int i;
+
+ pPrt = &pAC->GIni.GP[Port];
+
+ /* Default: no action */
+ Rtv = SK_HW_PS_NONE;
+
+ (void)SkXmUpdateStats(pAC, IoC, Port);
+
+ /* Extra precaution: check for short Event counter */
+ (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
+
+ /*
+ * Read Rx counters (packets seen on the network and not necessarily
+ * really received.
+ */
+ RxCts = 0;
+
+ for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
+
+ (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
+
+ RxCts += (SK_U64)RxTmp;
+ }
+
+ /* On default: check shorts against zero */
+ CheckShorts = 0;
+
+ /* Extra precaution on active links */
+ if (pPrt->PHWLinkUp) {
+ /* Reset Link Restart counter */
+ pPrt->PLinkResCt = 0;
+ pPrt->PAutoNegTOCt = 0;
+
+ /* If link is up check for 2 */
+ CheckShorts = 2;
+
+ (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
+
+ if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
+ pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
+ (pPrt->PLinkMode == SK_LMODE_HALF ||
+ pPrt->PLinkMode == SK_LMODE_FULL)) {
+ /*
+ * This is autosensing and we are in the fallback
+ * manual full/half duplex mode.
+ */
+ if (RxCts == pPrt->PPrevRx) {
+ /* Nothing received, restart link */
+ pPrt->PPrevFcs = FcsErrCts;
+ pPrt->PPrevShorts = Shorts;
+
+ return(SK_HW_PS_RESTART);
+ }
+ else {
+ pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
+ }
+ }
+
+ if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
+ (!(FcsErrCts - pPrt->PPrevFcs))) {
+ /*
+ * Note: The compare with zero above has to be done the way shown,
+ * otherwise the Linux driver will have a problem.
+ */
+ /*
+ * We received a bunch of frames or no CRC error occured on the
+ * network -> ok.
+ */
+ pPrt->PPrevRx = RxCts;
+ pPrt->PPrevFcs = FcsErrCts;
+ pPrt->PPrevShorts = Shorts;
+
+ return(SK_HW_PS_NONE);
+ }
+
+ pPrt->PPrevFcs = FcsErrCts;
+ }
+
+
+ if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+ ("Short Event Count Restart Port %d \n", Port));
+ Rtv = SK_HW_PS_RESTART;
+ }
+
+ pPrt->PPrevShorts = Shorts;
+ pPrt->PPrevRx = RxCts;
+
+ return(Rtv);
+} /* SkGePortCheckShorts */
+#endif /* GENESIS */
+
+
+/******************************************************************************
+ *
+ * SkGePortCheckUp() - Check if the link is up
+ *
+ * return:
+ * 0 o.k. nothing needed
+ * 1 Restart needed on this port
+ * 2 Link came up
+ */
+static int SkGePortCheckUp(
+SK_AC *pAC, /* Adapter Context */
+SK_IOC IoC, /* IO Context */
+int Port) /* Which port should be checked */
+{
+ SK_GEPORT *pPrt; /* GIni Port struct pointer */
+ SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
+ int Rtv; /* Return value */
+
+ Rtv = SK_HW_PS_NONE;
+
+ pPrt = &pAC->GIni.GP[Port];
+
+ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+ AutoNeg = SK_FALSE;
+ }
+ else {
+ AutoNeg = SK_TRUE;
+ }
+
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+
+ switch (pPrt->PhyType) {
+
+ case SK_PHY_XMAC:
+ Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg);
+ break;
+ case SK_PHY_BCOM:
+ Rtv = SkGePortCheckUpBcom(pAC, IoC, Port, AutoNeg);
+ break;
+#ifdef OTHER_PHY
+ case SK_PHY_LONE:
+ Rtv = SkGePortCheckUpLone(pAC, IoC, Port, AutoNeg);
+ break;
+ case SK_PHY_NAT:
+ Rtv = SkGePortCheckUpNat(pAC, IoC, Port, AutoNeg);
+ break;
+#endif /* OTHER_PHY */
+ }
+ }
+#endif /* GENESIS */
+
+#ifdef YUKON
+ if (pAC->GIni.GIYukon) {
+
+ Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg);
+ }
+#endif /* YUKON */
+
+ return(Rtv);
+} /* SkGePortCheckUp */
+
+
+#ifdef GENESIS
+/******************************************************************************
+ *
+ * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2
+ *
+ * return:
+ * 0 o.k. nothing needed
+ * 1 Restart needed on this port
+ * 2 Link came up
+ */
+static int SkGePortCheckUpXmac(
+SK_AC *pAC, /* Adapter Context */
+SK_IOC IoC, /* IO Context */
+int Port, /* Which port should be checked */
+SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
+{
+ SK_U32 Shorts; /* Short Event Counter */
+ SK_GEPORT *pPrt; /* GIni Port struct pointer */
+ int Done;
+ SK_U32 GpReg; /* General Purpose register value */
+ SK_U16 Isrc; /* Interrupt source register */
+ SK_U16 IsrcSum; /* Interrupt source register sum */
+ SK_U16 LpAb; /* Link Partner Ability */
+ SK_U16 ResAb; /* Resolved Ability */
+ SK_U16 ExtStat; /* Extended Status Register */
+ SK_U8 NextMode; /* Next AutoSensing Mode */
+
+ pPrt = &pAC->GIni.GP[Port];
+
+ if (pPrt->PHWLinkUp) {
+ if (pPrt->PhyType != SK_PHY_XMAC) {
+ return(SK_HW_PS_NONE);
+ }
+ else {
+ return(SkGePortCheckShorts(pAC, IoC, Port));
+ }
+ }
+
+ IsrcSum = pPrt->PIsave;
+ pPrt->PIsave = 0;
+
+ /* Now wait for each port's link */
+ if (pPrt->PLinkBroken) {
+ /* Link was broken */
+ XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
+
+ if ((GpReg & XM_GP_INP_ASS) == 0) {
+ /* The Link is in sync */
+ XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+ IsrcSum |= Isrc;
+ SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
+
+ if ((Isrc & XM_IS_INP_ASS) == 0) {
+ /* It has been in sync since last time */
+ /* Restart the PORT */
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+ ("Link in sync Restart Port %d\n", Port));
+
+ (void)SkXmUpdateStats(pAC, IoC, Port);
+
+ /* We now need to reinitialize the PrevShorts counter */
+ (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
+ pPrt->PPrevShorts = Shorts;
+
+ pPrt->PLinkBroken = SK_FALSE;
+
+ /*
+ * Link Restart Workaround:
+ * it may be possible that the other Link side
+ * restarts its link as well an we detect
+ * another LinkBroken. To prevent this
+ * happening we check for a maximum number
+ * of consecutive restart. If those happens,
+ * we do NOT restart the active link and
+ * check whether the link is now o.k.
+ */
+ pPrt->PLinkResCt++;
+
+ pPrt->PAutoNegTimeOut = 0;
+
+ if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
+ return(SK_HW_PS_RESTART);
+ }
+
+ pPrt->PLinkResCt = 0;
+
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+ ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
+ }
+ else {
+ pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
+
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+ ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
+
+ /* Do nothing more if link is broken */
+ return(SK_HW_PS_NONE);
+ }
+ }
+ else {
+ /* Do nothing more if link is broken */
+ return(SK_HW_PS_NONE);
+ }
+
+ }
+ else {
+ /* Link was not broken, check if it is */
+ XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+ IsrcSum |= Isrc;
+ if ((Isrc & XM_IS_INP_ASS) != 0) {
+ XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+ IsrcSum |= Isrc;
+ if ((Isrc & XM_IS_INP_ASS) != 0) {
+ XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+ IsrcSum |= Isrc;
+ if ((Isrc & XM_IS_INP_ASS) != 0) {
+ pPrt->PLinkBroken = SK_TRUE;
+ /* Re-Init Link partner Autoneg flag */
+ pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+ ("Link broken Port %d\n", Port));
+
+ /* Cable removed-> reinit sense mode */
+ SkHWInitDefSense(pAC, IoC, Port);
+
+ return(SK_HW_PS_RESTART);
+ }
+ }
+ }
+ else {
+ SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
+
+ if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
+ return(SK_HW_PS_RESTART);
+ }
+ }
+ }
+
+ /*
+ * here we usually can check whether the link is in sync and
+ * auto-negotiation is done.
+ */
+ XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
+ XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+ IsrcSum |= Isrc;
+
+ SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
+
+ if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
+ if ((GpReg & XM_GP_INP_ASS) == 0) {
+ /* Save Auto-negotiation Done interrupt only if link is in sync */
+ pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
+ }
+#ifdef DEBUG
+ if ((pPrt->PIsave & XM_IS_AND) != 0) {
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+ ("AutoNeg done rescheduled Port %d\n", Port));
+ }