📄 skxmac2.c
字号:
/****************************************************************************** * * Name: skxmac2.c * Project: Gigabit Ethernet Adapters, Common Modules * Version: $Revision: 2.96 $ * Date: $Date: 2008/04/22 08:59:08 $ * Purpose: Contains functions to initialize the MACs and PHYs * ******************************************************************************//****************************************************************************** * * LICENSE: * (C)Copyright 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. * /LICENSE * ******************************************************************************/#include "h/skdrv1st.h"#include "h/skdrv2nd.h"/* typedefs *******************************************************************//* local variables ************************************************************/#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))static const char SysKonnectFileId[] = "@(#) $Id: skxmac2.c,v 2.96 2008/04/22 08:59:08 rschmidt Exp $ (C) Marvell.";#endif/* function prototypes ********************************************************/static void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL);static int SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int);/****************************************************************************** * * SkGmPhyRead() - Read from GPHY register * * Description: reads a 16-bit word from GPHY through MDIO * * Returns: * 0 o.k. * 1 error during MDIO read * 2 timeout */int SkGmPhyRead(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */int PhyReg, /* Register Address (Offset) */SK_U16 SK_FAR *pVal) /* Pointer to Value */{ SK_U16 Word; SK_U16 Ctrl; SK_GEPORT *pPrt; SK_U32 StartTime; SK_U32 CurrTime; SK_U32 Delta; SK_U32 TimeOut; int Rtv; Rtv = 0; *pVal = 0xffff; pPrt = &pAC->GIni.GP[Port]; /* additional check for MDC/MDIO activity */ GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); if ((Ctrl & GM_SMI_CT_BUSY) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("SkGmPhyRead, Port: %d, Reg: %2d, Busy (Ctrl=0x%04X)\n", Port, PhyReg, Ctrl)); return(1); } /* set PHY-Register offset and 'Read' OpCode (= 1) */ Word = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD); GM_OUT16(IoC, Port, GM_SMI_CTRL, Word); /* additional check for MDC/MDIO activity */ GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); if (Ctrl == 0xffff || (Ctrl & GM_SMI_CT_OP_RD) == 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("SkGmPhyRead, Port: %d, Reg: %2d, Error (Ctrl=0x%04X)\n", Port, PhyReg, Ctrl)); return(1); } Word |= GM_SMI_CT_BUSY; /* get current value of timestamp timer */ SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime); /* set timeout to 10 ms */ TimeOut = HW_MS_TO_TICKS(pAC, 10); do { /* wait until 'Busy' is cleared and 'ReadValid' is set */#ifdef VCPU VCPUwaitTime(1000);#endif /* VCPU */ /* get current value of timestamp timer */ SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); if (CurrTime >= StartTime) { Delta = CurrTime - StartTime; } else { Delta = CurrTime + ~StartTime + 1; } if (Delta > TimeOut) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("SkGmPhyRead, Port: %d, Reg: %2d, Timeout (Ctrl=0x%04X)\n", Port, PhyReg, Ctrl)); Rtv = 2; break; } GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); /* Error on reading SMI Control Register */ if (Ctrl == 0xffff) { return(1); } } while ((Ctrl ^ Word) != (GM_SMI_CT_RD_VAL | GM_SMI_CT_BUSY)); GM_IN16(IoC, Port, GM_SMI_DATA, pVal); /* dummy read after GM_IN16() */ SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("SkGmPhyRead, Port: %d, Reg: %2d, Val = 0x%04X\n", Port, PhyReg, *pVal));#if defined(VCPU) || defined(SK_DIAG) c_print("Read 0x%04X from PHY reg %u on port %c\n", *pVal, PhyReg, 'A' + Port);#endif /* VCPU */ return(Rtv);} /* SkGmPhyRead *//****************************************************************************** * * SkGmPhyWrite() - Write to GPHY register * * Description: writes a 16-bit word to GPHY through MDIO * * Returns: * 0 o.k. * 1 error during MDIO read * 2 timeout */int SkGmPhyWrite(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */int PhyReg, /* Register Address (Offset) */SK_U16 Val) /* Value */{ SK_U16 Ctrl; SK_GEPORT *pPrt; SK_U32 StartTime; SK_U32 CurrTime; SK_U32 Delta; SK_U32 TimeOut; SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("SkGmPhyWrite, Port: %d, Reg: %2d, Val = 0x%04X\n", Port, PhyReg, Val)); pPrt = &pAC->GIni.GP[Port]; /* write the PHY register's value */ GM_OUT16(IoC, Port, GM_SMI_DATA, Val);#ifdef DEBUG /* additional check for MDC/MDIO activity */ GM_IN16(IoC, Port, GM_SMI_DATA, &Ctrl); if (Ctrl != Val) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("PHY write impossible on Port %d (Val=0x%04X)\n", Port, Ctrl)); return(1); }#endif /* DEBUG */ /* set PHY-Register offset and 'Write' OpCode (= 0) */ Ctrl = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg)); GM_OUT16(IoC, Port, GM_SMI_CTRL, Ctrl); /* get current value of timestamp timer */ SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime); /* set timeout to 10 ms */ TimeOut = HW_MS_TO_TICKS(pAC, 10); do { /* wait until 'Busy' is cleared */#ifdef VCPU VCPUwaitTime(1000);#endif /* VCPU */ /* get current value of timestamp timer */ SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); if (CurrTime >= StartTime) { Delta = CurrTime - StartTime; } else { Delta = CurrTime + ~StartTime + 1; } if (Delta > TimeOut) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("PHY write timeout on Port %d (Ctrl=0x%04X)\n", Port, Ctrl)); return(2); } GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); /* Error on reading SMI Control Register */ if (Ctrl == 0xffff) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("PHY write error on Port %d (Ctrl=0x%04X)\n", Port, Ctrl)); return(1); } } while ((Ctrl & GM_SMI_CT_BUSY) != 0); /* dummy read after GM_IN16() */ SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime);#if defined(VCPU) || defined(SK_DIAG) c_print("Wrote 0x%04X to PHY reg %u on port %c\n", Val, PhyReg, 'A' + Port);#endif /* VCPU || SK_DIAG */ return(0);} /* SkGmPhyWrite */#ifdef SK_DIAG/****************************************************************************** * * SkGePhyRead() - Read from PHY register * * Description: calls a read PHY routine dep. on board type * * Returns: * nothing */void SkGePhyRead(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */int PhyReg, /* Register Address (Offset) */SK_U16 *pVal) /* Pointer to Value */{ pAC->GIni.GIFunc.pFnMacPhyRead(pAC, IoC, Port, PhyReg, pVal);} /* SkGePhyRead *//****************************************************************************** * * SkGePhyWrite() - Write to PHY register * * Description: calls a write PHY routine dep. on board type * * Returns: * nothing */void SkGePhyWrite(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */int PhyReg, /* Register Address (Offset) */SK_U16 Val) /* Value */{ pAC->GIni.GIFunc.pFnMacPhyWrite(pAC, IoC, Port, PhyReg, Val);} /* SkGePhyWrite */#endif /* SK_DIAG *//****************************************************************************** * * SkMacPromiscMode() - Enable / Disable Promiscuous Mode * * Description: * enables / disables promiscuous mode by setting Mode Register (XMAC) or * Receive Control Register (GMAC) dep. on board type * * Returns: * nothing */void SkMacPromiscMode(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */SK_BOOL Enable) /* Enable / Disable */{ SK_U16 RcReg; GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); /* enable or disable unicast and multicast filtering */ if (Enable) { RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); } else { RcReg |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); } /* setup Receive Control Register */ GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);} /* SkMacPromiscMode*//****************************************************************************** * * SkMacHashing() - Enable / Disable Hashing * * Description: * enables / disables hashing by setting Mode Register (XMAC) or * Receive Control Register (GMAC) dep. on board type * * Returns: * nothing */void SkMacHashing(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */SK_BOOL Enable) /* Enable / Disable */{ SK_U16 RcReg; GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); /* enable or disable multicast filtering */ if (Enable) { RcReg |= GM_RXCR_MCF_ENA; } else { RcReg &= ~GM_RXCR_MCF_ENA; } /* setup Receive Control Register */ GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);} /* SkMacHashing*/#ifdef SK_DIAG/****************************************************************************** * * SkGmSetRxCmd() - Modify the value of the GMAC's Rx Control Register * * Description: * The features * - FCS (CRC) stripping, SK_STRIP_FCS_ON/OFF * - don't set GMR_FS_LONG_ERR SK_BIG_PK_OK_ON/OFF * for frames > 1514 bytes * - enable Rx of own packets SK_SELF_RX_ON/OFF * * for incoming packets may be enabled/disabled by this function. * Additional modes may be added later. * Multiple modes can be enabled/disabled at the same time. * The new configuration is written to the Rx Command register immediately. * * Returns: * nothing */static void SkGmSetRxCmd(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF, SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */{ SK_U16 RxCmd; if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) { GM_IN16(IoC, Port, GM_RX_CTRL, &RxCmd); if ((Mode & SK_STRIP_FCS_ON) != 0) { RxCmd |= GM_RXCR_CRC_DIS; } else { RxCmd &= ~GM_RXCR_CRC_DIS; } /* Write the new mode to the Rx Control register */ GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd); } if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) { GM_IN16(IoC, Port, GM_SERIAL_MODE, &RxCmd); if ((Mode & SK_BIG_PK_OK_ON) != 0) { RxCmd |= GM_SMOD_JUMBO_ENA; } else { RxCmd &= ~GM_SMOD_JUMBO_ENA; } /* Write the new mode to the Serial Mode register */ GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd); }} /* SkGmSetRxCmd *//****************************************************************************** * * SkMacSetRxCmd() - Modify the value of the MAC's Rx Control Register * * Description: modifies the MAC's Rx Control reg. dep. on board type * * Returns: * nothing */void SkMacSetRxCmd(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */int Mode) /* Rx Mode */{ SkGmSetRxCmd(pAC, IoC, Port, Mode);} /* SkMacSetRxCmd *//****************************************************************************** * * SkMacCrcGener() - Enable / Disable CRC Generation * * Description: enables / disables CRC generation dep. on board type * * Returns: * nothing */void SkMacCrcGener(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */SK_BOOL Enable) /* Enable / Disable */{ SK_U16 Word; GM_IN16(IoC, Port, GM_TX_CTRL, &Word); if (Enable) { Word &= ~GM_TXCR_CRC_DIS; } else { Word |= GM_TXCR_CRC_DIS; } /* setup Tx Control Register */ GM_OUT16(IoC, Port, GM_TX_CTRL, Word);} /* SkMacCrcGener*/#endif /* SK_DIAG *//****************************************************************************** *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -