📄 skxmac2.c
字号:
/****************************************************************************** * * Name: skxmac2.c * Project: Gigabit Ethernet Adapters, Common Modules * Version: $Revision: 1.102 $ * Date: $Date: 2003/10/02 16:53:58 $ * Purpose: Contains functions to initialize the MACs and PHYs * ******************************************************************************//****************************************************************************** * * (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. * ******************************************************************************/#include "h/skdrv1st.h"#include "h/skdrv2nd.h"/* typedefs *******************************************************************//* BCOM PHY magic pattern list */typedef struct s_PhyHack { int PhyReg; /* Phy register */ SK_U16 PhyVal; /* Value to write */} BCOM_HACK;/* local variables ************************************************************/#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))static const char SysKonnectFileId[] = "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";#endif#ifdef GENESISBCOM_HACK BcomRegA1Hack[] = { { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 }, { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 }, { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 }, { 0, 0 }};BCOM_HACK BcomRegC0Hack[] = { { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, { 0, 0 }};#endif/* function prototypes ********************************************************/#ifdef GENESISstatic void SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL);static void SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL);static int SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int);static int SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int);#endif /* GENESIS */#ifdef YUKONstatic void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL);static int SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int);#endif /* YUKON */#ifdef OTHER_PHYstatic void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL);static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL);static int SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int);static int SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int);#endif /* OTHER_PHY */#ifdef GENESIS/****************************************************************************** * * SkXmPhyRead() - Read from XMAC PHY register * * Description: reads a 16-bit word from XMAC PHY or ext. PHY * * Returns: * nothing */void SkXmPhyRead(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 Mmu; SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; /* write the PHY register's address */ XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr); /* get the PHY register's value */ XM_IN16(IoC, Port, XM_PHY_DATA, pVal); if (pPrt->PhyType != SK_PHY_XMAC) { do { XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); /* wait until 'Ready' is set */ } while ((Mmu & XM_MMU_PHY_RDY) == 0); /* get the PHY register's value */ XM_IN16(IoC, Port, XM_PHY_DATA, pVal); }} /* SkXmPhyRead *//****************************************************************************** * * SkXmPhyWrite() - Write to XMAC PHY register * * Description: writes a 16-bit word to XMAC PHY or ext. PHY * * Returns: * nothing */void SkXmPhyWrite(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 Mmu; SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; if (pPrt->PhyType != SK_PHY_XMAC) { do { XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); /* wait until 'Busy' is cleared */ } while ((Mmu & XM_MMU_PHY_BUSY) != 0); } /* write the PHY register's address */ XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr); /* write the PHY register's value */ XM_OUT16(IoC, Port, XM_PHY_DATA, Val); if (pPrt->PhyType != SK_PHY_XMAC) { do { XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); /* wait until 'Busy' is cleared */ } while ((Mmu & XM_MMU_PHY_BUSY) != 0); }} /* SkXmPhyWrite */#endif /* GENESIS */#ifdef YUKON/****************************************************************************** * * SkGmPhyRead() - Read from GPHY register * * Description: reads a 16-bit word from GPHY through MDIO * * Returns: * nothing */void 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 Ctrl; SK_GEPORT *pPrt;#ifdef VCPU u_long SimCyle; u_long SimLowTime; VCPUgetTime(&SimCyle, &SimLowTime); VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n", PhyReg, SimCyle, SimLowTime);#endif /* VCPU */ pPrt = &pAC->GIni.GP[Port]; /* set PHY-Register offset and 'Read' OpCode (= 1) */ *pVal = (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, *pVal); GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); /* additional check for MDC/MDIO activity */ if ((Ctrl & GM_SMI_CT_BUSY) == 0) { *pVal = 0; return; } *pVal |= GM_SMI_CT_BUSY; do {#ifdef VCPU VCPUwaitTime(1000);#endif /* VCPU */ GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); /* wait until 'ReadValid' is set */ } while (Ctrl == *pVal); /* get the PHY register's value */ GM_IN16(IoC, Port, GM_SMI_DATA, pVal);#ifdef VCPU VCPUgetTime(&SimCyle, &SimLowTime); VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", SimCyle, SimLowTime);#endif /* VCPU */} /* SkGmPhyRead *//****************************************************************************** * * SkGmPhyWrite() - Write to GPHY register * * Description: writes a 16-bit word to GPHY through MDIO * * Returns: * nothing */void 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;#ifdef VCPU SK_U32 DWord; u_long SimCyle; u_long SimLowTime; VCPUgetTime(&SimCyle, &SimLowTime); VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n", PhyReg, Val, SimCyle, SimLowTime);#endif /* VCPU */ pPrt = &pAC->GIni.GP[Port]; /* write the PHY register's value */ GM_OUT16(IoC, Port, GM_SMI_DATA, Val); /* set PHY-Register offset and 'Write' OpCode (= 0) */ Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg); GM_OUT16(IoC, Port, GM_SMI_CTRL, Val); GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); /* additional check for MDC/MDIO activity */ if ((Ctrl & GM_SMI_CT_BUSY) == 0) { return; } Val |= GM_SMI_CT_BUSY; do {#ifdef VCPU /* read Timer value */ SK_IN32(IoC, B2_TI_VAL, &DWord); VCPUwaitTime(1000);#endif /* VCPU */ GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); /* wait until 'Busy' is cleared */ } while (Ctrl == Val); #ifdef VCPU VCPUgetTime(&SimCyle, &SimLowTime); VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", SimCyle, SimLowTime);#endif /* VCPU */} /* SkGmPhyWrite */#endif /* YUKON */#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 */{ void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal); if (pAC->GIni.GIGenesis) { r_func = SkXmPhyRead; } else { r_func = SkGmPhyRead; } r_func(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 */{ void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val); if (pAC->GIni.GIGenesis) { w_func = SkXmPhyWrite; } else { w_func = SkGmPhyWrite; } w_func(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, /* IO context */int Port, /* Port Index (MAC_1 + n) */SK_BOOL Enable) /* Enable / Disable */{#ifdef YUKON SK_U16 RcReg;#endif#ifdef GENESIS SK_U32 MdReg;#endif #ifdef GENESIS if (pAC->GIni.GIGenesis) { XM_IN32(IoC, Port, XM_MODE, &MdReg); /* enable or disable promiscuous mode */ if (Enable) { MdReg |= XM_MD_ENA_PROM; } else { MdReg &= ~XM_MD_ENA_PROM; } /* setup Mode Register */ XM_OUT32(IoC, Port, XM_MODE, MdReg); }#endif /* GENESIS */ #ifdef YUKON if (pAC->GIni.GIYukon) { 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); }#endif /* YUKON */} /* 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, /* IO context */int Port, /* Port Index (MAC_1 + n) */SK_BOOL Enable) /* Enable / Disable */{#ifdef YUKON SK_U16 RcReg;#endif #ifdef GENESIS SK_U32 MdReg;#endif#ifdef GENESIS if (pAC->GIni.GIGenesis) { XM_IN32(IoC, Port, XM_MODE, &MdReg); /* enable or disable hashing */ if (Enable) { MdReg |= XM_MD_ENA_HASH; } else { MdReg &= ~XM_MD_ENA_HASH; } /* setup Mode Register */ XM_OUT32(IoC, Port, XM_MODE, MdReg); }#endif /* GENESIS */ #ifdef YUKON if (pAC->GIni.GIYukon) { 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); }#endif /* YUKON */} /* SkMacHashing*/#ifdef SK_DIAG/****************************************************************************** * * SkXmSetRxCmd() - Modify the value of the XMAC's Rx Command Register * * Description: * The features * - FCS stripping, SK_STRIP_FCS_ON/OFF * - pad byte stripping, SK_STRIP_PAD_ON/OFF * - don't set XMR_FS_ERR in status SK_LENERR_OK_ON/OFF * for inrange length error frames * - don't set XMR_FS_ERR in status 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 SkXmSetRxCmd(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* IO 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 OldRxCmd; SK_U16 RxCmd; XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd); RxCmd = OldRxCmd; switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) { case SK_STRIP_FCS_ON: RxCmd |= XM_RX_STRIP_FCS; break; case SK_STRIP_FCS_OFF: RxCmd &= ~XM_RX_STRIP_FCS; break; } switch (Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -