X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fzynq_gem.c;h=b3ed6eaaf6d6b264fd4bd973d3966fd323c1d27e;hb=985a71d15b8bd9cfbeae1ac1b08a5319abfd246c;hp=8e0e01ce8a7d5156d5a0e6aa40363c6866e4af1a;hpb=01fbf31042e1eba1fcca3e84f70db7de0d176fe4;p=oweals%2Fu-boot.git diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 8e0e01ce8a..b3ed6eaaf6 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -6,23 +6,7 @@ * Based on Xilinx gmac driver: * (C) Copyright 2011 Xilinx * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -95,6 +79,17 @@ ZYNQ_GEM_DMACR_TXSIZE | \ ZYNQ_GEM_DMACR_RXBUF) +/* Use MII register 1 (MII status register) to detect PHY */ +#define PHY_DETECT_REG 1 + +/* Mask used to verify certain PHY features (or register contents) + * in the register above: + * 0x1000: 10Mbps full duplex support + * 0x0800: 10Mbps half duplex support + * 0x0008: Auto-negotiation support + */ +#define PHY_DETECT_MASK 0x1808 + /* Device registers */ struct zynq_gem_regs { u32 nwctrl; /* Network Control reg */ @@ -201,6 +196,44 @@ static u32 phywrite(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 data) ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data); } +static void phy_detection(struct eth_device *dev) +{ + int i; + u16 phyreg; + struct zynq_gem_priv *priv = dev->priv; + + if (priv->phyaddr != -1) { + phyread(dev, priv->phyaddr, PHY_DETECT_REG, &phyreg); + if ((phyreg != 0xFFFF) && + ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { + /* Found a valid PHY address */ + debug("Default phy address %d is valid\n", + priv->phyaddr); + return; + } else { + debug("PHY address is not setup correctly %d\n", + priv->phyaddr); + priv->phyaddr = -1; + } + } + + debug("detecting phy address\n"); + if (priv->phyaddr == -1) { + /* detect the PHY address */ + for (i = 31; i >= 0; i--) { + phyread(dev, i, PHY_DETECT_REG, &phyreg); + if ((phyreg != 0xFFFF) && + ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { + /* Found a valid PHY address */ + priv->phyaddr = i; + debug("Found valid phy address, %d\n", i); + return; + } + } + } + printf("PHY is not detected\n"); +} + static int zynq_gem_setup_mac(struct eth_device *dev) { u32 i, macaddrlow, macaddrhigh; @@ -290,6 +323,8 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis) priv->init++; } + phy_detection(dev); + /* interface - look at tsec */ phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);