1*5f184715SAndy Fleming /* 2*5f184715SAndy Fleming * Generic PHY Management code 3*5f184715SAndy Fleming * 4*5f184715SAndy Fleming * This program is free software; you can redistribute it and/or 5*5f184715SAndy Fleming * modify it under the terms of the GNU General Public License as 6*5f184715SAndy Fleming * published by the Free Software Foundation; either version 2 of 7*5f184715SAndy Fleming * the License, or (at your option) any later version. 8*5f184715SAndy Fleming * 9*5f184715SAndy Fleming * This program is distributed in the hope that it will be useful, 10*5f184715SAndy Fleming * but WITHOUT ANY WARRANTY; without even the implied warranty of 11*5f184715SAndy Fleming * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12*5f184715SAndy Fleming * GNU General Public License for more details. 13*5f184715SAndy Fleming * 14*5f184715SAndy Fleming * You should have received a copy of the GNU General Public License 15*5f184715SAndy Fleming * along with this program; if not, write to the Free Software 16*5f184715SAndy Fleming * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 17*5f184715SAndy Fleming * MA 02111-1307 USA 18*5f184715SAndy Fleming * 19*5f184715SAndy Fleming * 20*5f184715SAndy Fleming * Copyright 2011 Freescale Semiconductor, Inc. 21*5f184715SAndy Fleming * author Andy Fleming 22*5f184715SAndy Fleming * 23*5f184715SAndy Fleming * Based loosely off of Linux's PHY Lib 24*5f184715SAndy Fleming */ 25*5f184715SAndy Fleming 26*5f184715SAndy Fleming #include <config.h> 27*5f184715SAndy Fleming #include <common.h> 28*5f184715SAndy Fleming #include <miiphy.h> 29*5f184715SAndy Fleming #include <phy.h> 30*5f184715SAndy Fleming 31*5f184715SAndy Fleming int gen10g_shutdown(struct phy_device *phydev) 32*5f184715SAndy Fleming { 33*5f184715SAndy Fleming return 0; 34*5f184715SAndy Fleming } 35*5f184715SAndy Fleming 36*5f184715SAndy Fleming int gen10g_startup(struct phy_device *phydev) 37*5f184715SAndy Fleming { 38*5f184715SAndy Fleming int devad, reg; 39*5f184715SAndy Fleming u32 mmd_mask = phydev->mmds; 40*5f184715SAndy Fleming 41*5f184715SAndy Fleming phydev->link = 1; 42*5f184715SAndy Fleming 43*5f184715SAndy Fleming /* For now just lie and say it's 10G all the time */ 44*5f184715SAndy Fleming phydev->speed = SPEED_10000; 45*5f184715SAndy Fleming phydev->duplex = DUPLEX_FULL; 46*5f184715SAndy Fleming 47*5f184715SAndy Fleming for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) { 48*5f184715SAndy Fleming if (!mmd_mask & 1) 49*5f184715SAndy Fleming continue; 50*5f184715SAndy Fleming 51*5f184715SAndy Fleming /* Read twice because link state is latched and a 52*5f184715SAndy Fleming * read moves the current state into the register */ 53*5f184715SAndy Fleming phy_read(phydev, devad, MDIO_STAT1); 54*5f184715SAndy Fleming reg = phy_read(phydev, devad, MDIO_STAT1); 55*5f184715SAndy Fleming if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS)) 56*5f184715SAndy Fleming phydev->link = 0; 57*5f184715SAndy Fleming } 58*5f184715SAndy Fleming 59*5f184715SAndy Fleming return 0; 60*5f184715SAndy Fleming } 61*5f184715SAndy Fleming 62*5f184715SAndy Fleming int gen10g_discover_mmds(struct phy_device *phydev) 63*5f184715SAndy Fleming { 64*5f184715SAndy Fleming int mmd, stat2, devs1, devs2; 65*5f184715SAndy Fleming 66*5f184715SAndy Fleming /* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY 67*5f184715SAndy Fleming * XS or DTE XS; give up if none is present. */ 68*5f184715SAndy Fleming for (mmd = 1; mmd <= 5; mmd++) { 69*5f184715SAndy Fleming /* Is this MMD present? */ 70*5f184715SAndy Fleming stat2 = phy_read(phydev, mmd, MDIO_STAT2); 71*5f184715SAndy Fleming if (stat2 < 0 || 72*5f184715SAndy Fleming (stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL) 73*5f184715SAndy Fleming continue; 74*5f184715SAndy Fleming 75*5f184715SAndy Fleming /* It should tell us about all the other MMDs */ 76*5f184715SAndy Fleming devs1 = phy_read(phydev, mmd, MDIO_DEVS1); 77*5f184715SAndy Fleming devs2 = phy_read(phydev, mmd, MDIO_DEVS2); 78*5f184715SAndy Fleming if (devs1 < 0 || devs2 < 0) 79*5f184715SAndy Fleming continue; 80*5f184715SAndy Fleming 81*5f184715SAndy Fleming phydev->mmds = devs1 | (devs2 << 16); 82*5f184715SAndy Fleming return 0; 83*5f184715SAndy Fleming } 84*5f184715SAndy Fleming 85*5f184715SAndy Fleming return 0; 86*5f184715SAndy Fleming } 87*5f184715SAndy Fleming 88*5f184715SAndy Fleming int gen10g_config(struct phy_device *phydev) 89*5f184715SAndy Fleming { 90*5f184715SAndy Fleming /* For now, assume 10000baseT. Fill in later */ 91*5f184715SAndy Fleming phydev->supported = phydev->advertising = SUPPORTED_10000baseT_Full; 92*5f184715SAndy Fleming 93*5f184715SAndy Fleming return gen10g_discover_mmds(phydev); 94*5f184715SAndy Fleming } 95*5f184715SAndy Fleming 96*5f184715SAndy Fleming struct phy_driver gen10g_driver = { 97*5f184715SAndy Fleming .uid = 0xffffffff, 98*5f184715SAndy Fleming .mask = 0xffffffff, 99*5f184715SAndy Fleming .name = "Generic 10G PHY", 100*5f184715SAndy Fleming .features = 0, 101*5f184715SAndy Fleming .config = gen10g_config, 102*5f184715SAndy Fleming .startup = gen10g_startup, 103*5f184715SAndy Fleming .shutdown = gen10g_shutdown, 104*5f184715SAndy Fleming }; 105*5f184715SAndy Fleming 106