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

📄 mvphy.c

📁 atheros ar531x ethernet driver
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved. *//** Manage the ethernet PHY switch, Marvell 88E6060.* * This module is intended to be largely OS and platform-independent.*/#if defined(linux)#include <linux/config.h>#include <linux/types.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/delay.h>#include "ar531xlnx.h"#endif#if defined(__ECOS)#include "ae531xecos.h"#endif#include "ae531xmac.h"#include "ae531xreg.h"#include "mvPhy.h"#if /* DEBUG */ 1#define MV_DEBUG_ERROR     0x00000001#define MV_DEBUG_PHYSETUP  0x00000002#define MV_DEBUG_PHYCHANGE 0x00000004int mvPhyDebug = MV_DEBUG_ERROR;#define MV_PRINT(FLG, X)                            \{                                                   \    if (mvPhyDebug & (FLG)) {                       \        DEBUG_PRINTF X;                             \    }                                               \}#else#define MV_PRINT(FLG, X)#endif#ifdef CONFIG_VENETDEV_ATH/* * On AR5312 with CONFIG_VENETDEV==1, *   ports 0..3 are LAN ports  (accessed through ae0) *   port 4 is the WAN port.   (accessed through ae1) *  * The phy switch settings in the mvPhyInfo table are set accordingly. */#define MV_WAN_PORT          4#define MV_IS_LAN_PORT(port) ((port) <  MV_WAN_PORT)#define MV_IS_WAN_PORT(port) ((port) == MV_WAN_PORT)#endif/* * Track per-PHY port information. */typedef struct {    BOOL   isEnetPort;       /* normal enet port */    BOOL   isPhyAlive;       /* last known state of link */    int    ethUnit;          /* MAC associated with this phy port */    UINT32 phyBase;    UINT32 phyAddr;          /* PHY registers associated with this phy port */    UINT32 switchPortAddr;   /* switch port regs assoc'ed with this phy port */    UINT32 VLANTableSetting; /* Value to be written to VLAN table */} mvPhyInfo_t;/****************************************************************************** * Per-PHY information, indexed by PHY unit number. * * This table is board-dependent.  It includes information * about which enet MAC controls which PHY port. */mvPhyInfo_t mvPhyInfo[] = {    /*     * On AP30/AR5312, all PHYs are associated with MAC0.     * AP30/AR5312's MAC1 isn't used for anything.     * CONFIG_VENETDEV==1 (router) configuration:     *    Ports 0,1,2, and 3 are "LAN ports"     *    Port 4 is a WAN port     *    Port 5 connects to MAC0 in the AR5312     * CONFIG_VENETDEV==0 (bridge) configuration:     *    Ports 0,1,2,3,4 are "LAN ports"     *    Port 5 connects to the MAC0 in the AR5312     */    {isEnetPort: TRUE,   /* phy port 0 -- LAN port 0 */     isPhyAlive: FALSE,     ethUnit: 0,     phyBase: 0,     phyAddr: 0x10,     switchPortAddr: 0x18,#ifdef CONFIG_VENETDEV_ATH     VLANTableSetting: 0x2e#else     VLANTableSetting: 0x3e#endif    },    {isEnetPort: TRUE,   /* phy port 1 -- LAN port 1 */     isPhyAlive: FALSE,     ethUnit: 0,     phyBase: 0,     phyAddr: 0x11,     switchPortAddr: 0x19,#ifdef CONFIG_VENETDEV_ATH     VLANTableSetting: 0x2d#else     VLANTableSetting: 0x3d#endif    },    {isEnetPort: TRUE,   /* phy port 2 -- LAN port 2 */     isPhyAlive: FALSE,     ethUnit: 0,     phyBase: 0,     phyAddr: 0x12,      switchPortAddr: 0x1a,#ifdef CONFIG_VENETDEV_ATH     VLANTableSetting: 0x2b#else     VLANTableSetting: 0x3b#endif    },    {isEnetPort: TRUE,   /* phy port 3 -- LAN port 3 */     isPhyAlive: FALSE,     ethUnit: 0,     phyBase: 0,     phyAddr: 0x13,      switchPortAddr: 0x1b,#ifdef CONFIG_VENETDEV_ATH     VLANTableSetting: 0x27#else     VLANTableSetting: 0x37#endif    },    {isEnetPort: TRUE,   /* phy port 4 -- WAN port or LAN port 4 */     isPhyAlive: FALSE,     ethUnit: 0,     phyBase: 0,     phyAddr: 0x14,      switchPortAddr: 0x1c,#ifdef CONFIG_VENETDEV_ATH     VLANTableSetting: 0x1020  /* WAN port */#else     VLANTableSetting: 0x2f    /* LAN port 4 */#endif    },    {isEnetPort: FALSE,  /* phy port 5 -- CPU port (no RJ45 connector) */     isPhyAlive: TRUE,     ethUnit: 0,     phyBase: 0,     phyAddr: 0x15,      switchPortAddr: 0x1d,#ifdef CONFIG_VENETDEV_ATH     VLANTableSetting: 0x0f    /* Send only to LAN ports */#else     VLANTableSetting: 0x1f    /* Send to all ports */#endif    },};#define MV_PHY_MAX (sizeof(mvPhyInfo) / sizeof(mvPhyInfo[0]))/* Range of valid PHY IDs is [MIN..MAX] */#define MV_ID_MIN 0#define MV_ID_MAX (MV_PHY_MAX-1)/* Convenience macros to access myPhyInfo */#define MV_IS_ENET_PORT(phyUnit) (mvPhyInfo[phyUnit].isEnetPort)#define MV_IS_PHY_ALIVE(phyUnit) (mvPhyInfo[phyUnit].isPhyAlive)#define MV_ETHUNIT(phyUnit) (mvPhyInfo[phyUnit].ethUnit)#define MV_PHYBASE(phyUnit) (mvPhyInfo[phyUnit].phyBase)#define MV_PHYADDR(phyUnit) (mvPhyInfo[phyUnit].phyAddr)#define MV_SWITCH_PORT_ADDR(phyUnit) (mvPhyInfo[phyUnit].switchPortAddr)#define MV_VLAN_TABLE_SETTING(phyUnit) (mvPhyInfo[phyUnit].VLANTableSetting)#define MV_IS_ETHUNIT(phyUnit, ethUnit) \    (MV_IS_ENET_PORT(phyUnit) &&        \    MV_ETHUNIT(phyUnit) == (ethUnit))/* Forward references */BOOL       mv_phyIsLinkAlive(int phyUnit);LOCAL void mv_VLANInit(int ethUnit);LOCAL void mv_enableConfiguredPorts(int ethUnit);LOCAL void mv_verifyReady(int ethUnit);BOOL       mv_phySetup(int ethUnit, UINT32 phyBase);int        mv_phyIsFullDuplex(int ethUnit);BOOL       mv_phyIsSpeed100(int phyUnit);LOCAL BOOL mv_validPhyId(int phyUnit);void       mv_flushATUDB(int phyUnit);void       mv_phyCheckStatusChange(int ethUnit);void       mv_phySet(int phyUnit, UINT32 regnum, UINT32 value);#if DEBUGvoid       mv_phyShow(int phyUnit);void       mv_switchPortSet(int phyUnit, UINT32 regnum, UINT32 value);void       mv_switchGlobalSet(int phyUnit, UINT32 regnum, UINT32 value);void       mv_showATUDB(int phyUnit);void       mv_setATUDB(int phyUnit, char *mac, int dbNum);void       mv_countGoodFrames(int phyUnit);void       mv_countBadFrames(int phyUnit);void       mv_showFrameCounts(int phyUnit);#endif/******************************************************************************** mv_phyIsLinkAlive - test to see if the specified link is alive** RETURNS:*    TRUE  --> link is alive*    FALSE --> link is down*/BOOLmv_phyIsLinkAlive(int phyUnit){    UINT16 phyHwStatus;    UINT32 phyBase;    UINT32 phyAddr;    phyBase = MV_PHYBASE(phyUnit);    phyAddr = MV_PHYADDR(phyUnit);    phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);    if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) {        return TRUE;    } else {        return FALSE;    }}/******************************************************************************** mv_VLANInit - initialize "port-based VLANs" for the specified enet unit.*/LOCAL voidmv_VLANInit(int ethUnit){    int     phyUnit;    UINT32  phyBase;    UINT32  switchPortAddr;    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {        if (MV_ETHUNIT(phyUnit) != ethUnit) {            continue;        }        phyBase        = MV_PHYBASE(phyUnit);        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);        phyRegWrite(phyBase, switchPortAddr, MV_PORT_BASED_VLAN_MAP,                    MV_VLAN_TABLE_SETTING(phyUnit));	MV_PRINT(MV_DEBUG_PHYSETUP,("phyBase =%x unit = %d MV_VLAN_TABLE_SETTING = %x \n",phyBase, phyUnit, MV_VLAN_TABLE_SETTING(phyUnit) ));                        }}#define phyPortConfigured(phyUnit) TRUE /* TBDFREEDOM2 *//******************************************************************************** mv_enableConfiguredPorts - enable whichever PHY ports are supposed* to be enabled according to administrative configuration.*/LOCAL voidmv_enableConfiguredPorts(int ethUnit){    int     phyUnit;    UINT32  phyBase;    UINT32  switchPortAddr;    UINT16  portControl = 0;    UINT16  portAssociationVector;    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {        if (MV_ETHUNIT(phyUnit) != ethUnit) {            continue;        }        phyBase        = MV_PHYBASE(phyUnit);        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);        if (phyPortConfigured(phyUnit)) {            portControl |= MV_PORT_CONTROL_PORT_STATE_FORWARDING						|  MV_PORT_CONTROL_FORCE_FLOW_CTRL;       #ifdef CONFIG_VENETDEV_ATH            if (!MV_IS_ENET_PORT(phyUnit)) {       /* CPU port */#ifndef HEADER_MODE                            portControl |= MV_PORT_CONTROL_INGRESS_TRAILER_MODE                            |  MV_PORT_CONTROL_EGRESS_TRAILER_MODE;#else                portControl |= MV_PORT_CONTROL_HEADER_MODE;#endif                                         }#endif            phyRegWrite(phyBase, switchPortAddr, MV_PORT_CONTROL, portControl);            portAssociationVector = 1 << phyUnit;            phyRegWrite(phyBase, switchPortAddr,                MV_PORT_ASSOCIATION_VECTOR, portAssociationVector);        }    }}/******************************************************************************** mv_verifyReady - validates that we're dealing with the device* we think we're dealing with, and that it's ready.*/LOCAL voidmv_verifyReady(int ethUnit){    int     phyUnit;    UINT16  globalStatus;    UINT32  phyBase = 0;    UINT32  phyAddr;    UINT32  switchPortAddr;    UINT16  phyID1;    UINT16  phyID2;    UINT16  switchID;    /*     * The first read to the Phy port registers always fails and     * returns 0.   So get things started with a bogus read.     */    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {            continue;        }        phyBase = MV_PHYBASE(phyUnit);        phyAddr = MV_PHYADDR(phyUnit);            (void)phyRegRead(phyBase, phyAddr, MV_PHY_ID1); /* returns 0 */        break;    }    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {            continue;        }        /*******************/        /* Verify phy port */        /*******************/        phyBase = MV_PHYBASE(phyUnit);        phyAddr = MV_PHYADDR(phyUnit);            phyID1 = phyRegRead(phyBase, phyAddr, MV_PHY_ID1);        if (phyID1 != MV_PHY_ID1_EXPECTATION) {            MV_PRINT(MV_DEBUG_PHYSETUP,                      ("Invalid PHY ID1 for ethmac%d port%d.  Expected 0x%04x, read 0x%04x\n",                       ethUnit,                       phyUnit,                       MV_PHY_ID1_EXPECTATION,                       phyID1));            return;        }            phyID2 = phyRegRead(phyBase, phyAddr, MV_PHY_ID2);        if ((phyID2 & MV_OUI_LSB_MASK) != MV_OUI_LSB_EXPECTATION) {            MV_PRINT(MV_DEBUG_PHYSETUP,                      ("Invalid PHY ID2 for ethmac%d port %d.  Expected 0x%04x, read 0x%04x\n",                       ethUnit,                       phyUnit,                       MV_OUI_LSB_EXPECTATION,                       phyID2));            return;        }            MV_PRINT(MV_DEBUG_PHYSETUP,                  ("Found PHY ethmac%d port%d: model 0x%x revision 0x%x\n",                   ethUnit,                   phyUnit,                   (phyID2 & MV_MODEL_NUM_MASK) >> MV_MODEL_NUM_SHIFT,                   (phyID2 & MV_REV_NUM_MASK) >> MV_REV_NUM_SHIFT));                /**********************/        /* Verify switch port */        /**********************/        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);            switchID = phyRegRead(phyBase, switchPortAddr, MV_SWITCH_ID);        if ((switchID & MV_SWITCH_ID_DEV_MASK) !=            MV_SWITCH_ID_DEV_EXPECTATION) {                MV_PRINT(MV_DEBUG_PHYSETUP,                      ("Invalid switch ID for ethmac%d port %d.  Expected 0x%04x, read 0x%04x\n",                       ethUnit,                       phyUnit,                       MV_SWITCH_ID_DEV_EXPECTATION,                       switchID));            return;        }            MV_PRINT(MV_DEBUG_PHYSETUP,                  ("Found PHY switch for enet %d port %d deviceID 0x%x revision 0x%x\n",                    ethUnit,                    phyUnit,                    (switchID & MV_SWITCH_ID_DEV_MASK) >> MV_SWITCH_ID_DEV_SHIFT,                    (switchID & MV_SWITCH_ID_REV_MASK) >> MV_SWITCH_ID_REV_SHIFT))           }        /*******************************/    /* Verify that switch is ready */    /*******************************/    if (phyBase) {        globalStatus = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,                                  MV_SWITCH_GLOBAL_STATUS);        if (!(globalStatus & MV_SWITCH_STATUS_READY_MASK)) {            MV_PRINT(MV_DEBUG_PHYSETUP,                      ("PHY switch for ethmac%d NOT ready!\n",                       ethUnit));        }    } else {        MV_PRINT(MV_DEBUG_PHYSETUP,                  ("No ports configured for ethmac%d\n", ethUnit));    }#if DEBUG                            my_mvPhyShow(ethUnit);            #endif      }/******************************************************************************** mv_phySetup - reset and setup the PHY switch.** Resets each PHY port.*

⌨️ 快捷键说明

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