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

📄 athrs26_phy.c

📁 TP-LINK公司TL-WR941N无线路由器的Bootloader U_BOOT源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 atheros ethernet PHY. * * All definitions in this file are operating system independent! */#include <config.h>#include <linux/types.h>#include <common.h>#include <miiphy.h>#include "phy.h"#include "ar7100_soc.h"#include "athrs26_phy.h"/* PHY selections and access functions */typedef enum {    PHY_SRCPORT_INFO,     PHY_PORTINFO_SIZE,} PHY_CAP_TYPE;typedef enum {    PHY_SRCPORT_NONE,    PHY_SRCPORT_VLANTAG,     PHY_SRCPORT_TRAILER,} PHY_SRCPORT_TYPE;#ifdef DEBUG#define DRV_DEBUG 1#endif#define DRV_DEBUG 1#define DRV_DEBUG_PHYERROR  0x00000001#define DRV_DEBUG_PHYCHANGE 0x00000002#define DRV_DEBUG_PHYSETUP  0x00000004#if DRV_DEBUGint athrPhyDebug = DRV_DEBUG_PHYERROR;#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)    \{                                                   \    if (athrPhyDebug & (FLG)) {                       \        logMsg(X0, X1, X2, X3, X4, X5, X6);         \    }                                               \}#define DRV_MSG(x,a,b,c,d,e,f)                      \    logMsg(x,a,b,c,d,e,f)#define DRV_PRINT(FLG, X)                           \{                                                   \    if (athrPhyDebug & (FLG)) {                       \        printf X;                                   \    }                                               \}#else /* !DRV_DEBUG */#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)#define DRV_MSG(x,a,b,c,d,e,f)#define DRV_PRINT(DBG_SW,X)#endif#define ATHR_LAN_PORT_VLAN          1#define ATHR_WAN_PORT_VLAN          2#define ENET_UNIT_LAN 0#define TRUE    1#define FALSE   0#define ATHR_PHY0_ADDR   0x0#define ATHR_PHY1_ADDR   0x1#define ATHR_PHY2_ADDR   0x2#define ATHR_PHY3_ADDR   0x3#define ATHR_PHY4_ADDR   0x4/* * 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_t phyBase;    uint32_t phyAddr;          /* PHY registers associated with this phy port */    uint32_t VLANTableSetting; /* Value to be written to VLAN table */} athrPhyInfo_t;/* * Per-PHY information, indexed by PHY unit number. */static athrPhyInfo_t athrPhyInfo[] = {    {TRUE,   /* phy port 0 -- LAN port 0 */     FALSE,     ENET_UNIT_LAN,     0,     ATHR_PHY0_ADDR,     ATHR_LAN_PORT_VLAN    },    {TRUE,   /* phy port 1 -- LAN port 1 */     FALSE,     ENET_UNIT_LAN,     0,     ATHR_PHY1_ADDR,     ATHR_LAN_PORT_VLAN    },    {TRUE,   /* phy port 2 -- LAN port 2 */     FALSE,     ENET_UNIT_LAN,     0,     ATHR_PHY2_ADDR,      ATHR_LAN_PORT_VLAN    },    {TRUE,   /* phy port 3 -- LAN port 3 */     FALSE,     ENET_UNIT_LAN,     0,     ATHR_PHY3_ADDR,      ATHR_LAN_PORT_VLAN    },    {TRUE,   /* phy port 4 -- WAN port or LAN port 4 */     FALSE,     1,     0,     ATHR_PHY4_ADDR,      ATHR_LAN_PORT_VLAN   /* Send to all ports */    },    {FALSE,  /* phy port 5 -- CPU port (no RJ45 connector) */     TRUE,     ENET_UNIT_LAN,     0,     0x00,      ATHR_LAN_PORT_VLAN    /* Send to all ports */    },};#ifdef CFG_ATHRHDR_ENtypedef struct {    uint8_t data[ATHRHDR_MAX_DATA];    uint8_t len;    uint32_t seq;} cmd_resp_t;typedef struct { uint16_t reg_addr; uint16_t cmd_len; uint8_t *reg_data;}cmd_write_t;static cmd_write_t cmd_write,cmd_read;static cmd_resp_t cmd_resp;static struct eth_device *lan_mac;//static atomic_t seqcnt = ATOMIC_INIT(0);static int  seqcnt = 0;static int cmd = 1;//volatile uchar AthrHdrPkt[60];#endif#define ATHR_GLOBALREGBASE    0//#define ATHR_PHY_MAX (sizeof(athrPhyInfo) / sizeof(athrPhyInfo[0]))#define ATHR_PHY_MAX 5/* Range of valid PHY IDs is [MIN..MAX] */#define ATHR_ID_MIN 0#define ATHR_ID_MAX (ATHR_PHY_MAX-1)/* Convenience macros to access myPhyInfo */#define ATHR_IS_ENET_PORT(phyUnit) (athrPhyInfo[phyUnit].isEnetPort)#define ATHR_IS_PHY_ALIVE(phyUnit) (athrPhyInfo[phyUnit].isPhyAlive)#define ATHR_ETHUNIT(phyUnit) (athrPhyInfo[phyUnit].ethUnit)#define ATHR_PHYBASE(phyUnit) (athrPhyInfo[phyUnit].phyBase)#define ATHR_PHYADDR(phyUnit) (athrPhyInfo[phyUnit].phyAddr)#define ATHR_VLAN_TABLE_SETTING(phyUnit) (athrPhyInfo[phyUnit].VLANTableSetting)#define ATHR_IS_ETHUNIT(phyUnit, ethUnit) \            (ATHR_IS_ENET_PORT(phyUnit) &&        \            ATHR_ETHUNIT(phyUnit) == (ethUnit))#define ATHR_IS_WAN_PORT(phyUnit) (!(ATHR_ETHUNIT(phyUnit)==ENET_UNIT_LAN))            /* Forward references */BOOL       athrs26_phy_is_link_alive(int phyUnit);static uint32_t athrs26_reg_read(uint16_t reg_addr);static void athrs26_reg_write(uint16_t reg_addr,                               uint32_t reg_val);/******************************************************************************** athrs26_phy_is_link_alive - test to see if the specified link is alive** RETURNS:*    TRUE  --> link is alive*    FALSE --> link is down*/void athrs26_reg_init(){    athrs26_reg_write(0x200, 0x200);    athrs26_reg_write(0x300, 0x200);    athrs26_reg_write(0x400, 0x200);    athrs26_reg_write(0x500, 0x200);    athrs26_reg_write(0x600, 0x7d);#ifdef S26_VER_1_0    phy_reg_write(0, 0, 29, 41);    phy_reg_write(0, 0, 30, 0);    phy_reg_write(0, 1, 29, 41);    phy_reg_write(0, 1, 30, 0);    phy_reg_write(0, 2, 29, 41);    phy_reg_write(0, 2, 30, 0);    phy_reg_write(0, 3, 29, 41);    phy_reg_write(0, 3, 30, 0);    phy_reg_write(0, 4, 29, 41);    phy_reg_write(0, 4, 30, 0);#endif    athrs26_reg_write(0x38, 0xc000050e);#ifdef CFG_ATHRHDR_EN    athrs26_reg_write(0x104, 0x4804);#else    athrs26_reg_write(0x104, 0x4004);#endif    athrs26_reg_write(0x60, 0xffffffff);    athrs26_reg_write(0x64, 0xaaaaaaaa);    athrs26_reg_write(0x68, 0x55555555);    athrs26_reg_write(0x6c, 0x0);    athrs26_reg_write(0x70, 0x41af);}BOOLathrs26_phy_is_link_alive(int phyUnit){    uint16_t phyHwStatus;    uint32_t phyBase;    uint32_t phyAddr;    phyBase = ATHR_PHYBASE(phyUnit);    phyAddr = ATHR_PHYADDR(phyUnit);    phy_reg_read(phyBase, phyAddr, ATHR_PHY_SPEC_STATUS, &phyHwStatus);    if (phyHwStatus & ATHR_STATUS_LINK_PASS)        return TRUE;    return FALSE;}/******************************************************************************** athrs26_phy_setup - reset and setup the PHY associated with* the specified MAC unit number.** Resets the associated PHY port.** RETURNS:*    TRUE  --> associated PHY is alive*    FALSE --> no LINKs on this ethernet unit*/BOOLathrs26_phy_setup(int ethUnit){    int         phyUnit;    uint16_t    phyHwStatus;    uint16_t    timeout;    int         liveLinks = 0;    uint32_t    phyBase = 0;    BOOL        foundPhy = FALSE;    uint32_t  phyAddr = 0;    uint32_t  regVal;        /* See if there's any configuration data for this enet */    /* start auto negogiation on each phy */    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {            continue;        }        foundPhy = TRUE;        phyBase = ATHR_PHYBASE(phyUnit);        phyAddr = ATHR_PHYADDR(phyUnit);                phy_reg_write(phyBase, phyAddr, ATHR_AUTONEG_ADVERT,                      ATHR_ADVERTISE_ALL);        /* Reset PHYs*/        phy_reg_write(phyBase, phyAddr, ATHR_PHY_CONTROL,                      ATHR_CTRL_AUTONEGOTIATION_ENABLE                       | ATHR_CTRL_SOFTWARE_RESET);    }    if (!foundPhy) {        return FALSE; /* No PHY's configured for this ethUnit */    }        /*     * After the phy is reset, it takes a little while before     * it can respond properly.     */    sysMsDelay(1000);        /*     * Wait up to .75 seconds for ALL associated PHYs to finish     * autonegotiation.  The only way we get out of here sooner is     * if ALL PHYs are connected AND finish autonegotiation.     */    for (phyUnit=0; (phyUnit < ATHR_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) {        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {            continue;        }        timeout=20;        for (;;) {            phy_reg_read(phyBase, phyAddr, ATHR_PHY_CONTROL, &phyHwStatus);            if (ATHR_RESET_DONE(phyHwStatus)) {                DRV_PRINT(DRV_DEBUG_PHYSETUP,                          ("Port %d, Neg Success\n", phyUnit));                break;            }            if (timeout == 0) {                DRV_PRINT(DRV_DEBUG_PHYSETUP,                          ("Port %d, Negogiation timeout\n", phyUnit));                break;            }            if (--timeout == 0) {                DRV_PRINT(DRV_DEBUG_PHYSETUP,                          ("Port %d, Negogiation timeout\n", phyUnit));                break;            }            sysMsDelay(150);        }    }    /*     * All PHYs have had adequate time to autonegotiate.     * Now initialize software status.     *     * It's possible that some ports may take a bit longer     * to autonegotiate; but we can't wait forever.  They'll     * get noticed by mv_phyCheckStatusChange during regular     * polling activities.     */    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {            continue;        }        if (athrs26_phy_is_link_alive(phyUnit)) {            liveLinks++;            ATHR_IS_PHY_ALIVE(phyUnit) = TRUE;        } else {            ATHR_IS_PHY_ALIVE(phyUnit) = FALSE;        }        phy_reg_read(ATHR_PHYBASE(phyUnit), ATHR_PHYADDR(phyUnit),                     ATHR_PHY_SPEC_STATUS, &regVal);        DRV_PRINT(DRV_DEBUG_PHYSETUP,            ("eth%d: Phy Specific Status=%4.4x\n", ethUnit, regVal));     }#if 0    /* if using header for register configuration, we have to     */    /* configure s26 register after frame transmission is enabled */    athrs26_reg_write(0x200, 0x200);    athrs26_reg_write(0x300, 0x200);    athrs26_reg_write(0x400, 0x200);    athrs26_reg_write(0x500, 0x200);    athrs26_reg_write(0x600, 0x200);	athrs26_reg_write(0x38, 0x50e);#endif#ifndef CFG_ATHRHDR_EN       /* if using header for register configuration, we have to     */    /* configure s26 register after frame transmission is enabled */        athrs26_reg_init();#endif        return (liveLinks > 0);}/******************************************************************************

⌨️ 快捷键说明

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