17ac6653aSJeff Kirsher /******************************************************************************* 27ac6653aSJeff Kirsher STMMAC Ethernet Driver -- MDIO bus implementation 37ac6653aSJeff Kirsher Provides Bus interface for MII registers 47ac6653aSJeff Kirsher 57ac6653aSJeff Kirsher Copyright (C) 2007-2009 STMicroelectronics Ltd 67ac6653aSJeff Kirsher 77ac6653aSJeff Kirsher This program is free software; you can redistribute it and/or modify it 87ac6653aSJeff Kirsher under the terms and conditions of the GNU General Public License, 97ac6653aSJeff Kirsher version 2, as published by the Free Software Foundation. 107ac6653aSJeff Kirsher 117ac6653aSJeff Kirsher This program is distributed in the hope it will be useful, but WITHOUT 127ac6653aSJeff Kirsher ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 137ac6653aSJeff Kirsher FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 147ac6653aSJeff Kirsher more details. 157ac6653aSJeff Kirsher 167ac6653aSJeff Kirsher You should have received a copy of the GNU General Public License along with 177ac6653aSJeff Kirsher this program; if not, write to the Free Software Foundation, Inc., 187ac6653aSJeff Kirsher 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 197ac6653aSJeff Kirsher 207ac6653aSJeff Kirsher The full GNU General Public License is included in this distribution in 217ac6653aSJeff Kirsher the file called "COPYING". 227ac6653aSJeff Kirsher 237ac6653aSJeff Kirsher Author: Carl Shaw <carl.shaw@st.com> 247ac6653aSJeff Kirsher Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com> 257ac6653aSJeff Kirsher *******************************************************************************/ 267ac6653aSJeff Kirsher 277ac6653aSJeff Kirsher #include <linux/mii.h> 287ac6653aSJeff Kirsher #include <linux/phy.h> 297ac6653aSJeff Kirsher #include <linux/slab.h> 300e076471SSrinivas Kandagatla #include <linux/of.h> 310e076471SSrinivas Kandagatla #include <linux/of_gpio.h> 32e34d6569SPhil Reid #include <linux/of_mdio.h> 337ac6653aSJeff Kirsher #include <asm/io.h> 347ac6653aSJeff Kirsher 357ac6653aSJeff Kirsher #include "stmmac.h" 367ac6653aSJeff Kirsher 377ac6653aSJeff Kirsher #define MII_BUSY 0x00000001 387ac6653aSJeff Kirsher #define MII_WRITE 0x00000002 397ac6653aSJeff Kirsher 40ac1f74a7SAlexandre TORGUE /* GMAC4 defines */ 41ac1f74a7SAlexandre TORGUE #define MII_GMAC4_GOC_SHIFT 2 42ac1f74a7SAlexandre TORGUE #define MII_GMAC4_WRITE (1 << MII_GMAC4_GOC_SHIFT) 43ac1f74a7SAlexandre TORGUE #define MII_GMAC4_READ (3 << MII_GMAC4_GOC_SHIFT) 44ac1f74a7SAlexandre TORGUE 45ac1f74a7SAlexandre TORGUE #define MII_PHY_ADDR_GMAC4_SHIFT 21 46ac1f74a7SAlexandre TORGUE #define MII_PHY_ADDR_GMAC4_MASK GENMASK(25, 21) 47ac1f74a7SAlexandre TORGUE #define MII_PHY_REG_GMAC4_SHIFT 16 48ac1f74a7SAlexandre TORGUE #define MII_PHY_REG_GMAC4_MASK GENMASK(20, 16) 49ac1f74a7SAlexandre TORGUE #define MII_CSR_CLK_GMAC4_SHIFT 8 50ac1f74a7SAlexandre TORGUE #define MII_CSR_CLK_GMAC4_MASK GENMASK(11, 8) 51ac1f74a7SAlexandre TORGUE 5239b401dbSDeepak SIKRI static int stmmac_mdio_busy_wait(void __iomem *ioaddr, unsigned int mii_addr) 5339b401dbSDeepak SIKRI { 5439b401dbSDeepak SIKRI unsigned long curr; 5539b401dbSDeepak SIKRI unsigned long finish = jiffies + 3 * HZ; 5639b401dbSDeepak SIKRI 5739b401dbSDeepak SIKRI do { 5839b401dbSDeepak SIKRI curr = jiffies; 5939b401dbSDeepak SIKRI if (readl(ioaddr + mii_addr) & MII_BUSY) 6039b401dbSDeepak SIKRI cpu_relax(); 6139b401dbSDeepak SIKRI else 6239b401dbSDeepak SIKRI return 0; 6339b401dbSDeepak SIKRI } while (!time_after_eq(curr, finish)); 6439b401dbSDeepak SIKRI 6539b401dbSDeepak SIKRI return -EBUSY; 6639b401dbSDeepak SIKRI } 6739b401dbSDeepak SIKRI 687ac6653aSJeff Kirsher /** 697ac6653aSJeff Kirsher * stmmac_mdio_read 707ac6653aSJeff Kirsher * @bus: points to the mii_bus structure 717ac6653aSJeff Kirsher * @phyaddr: MII addr reg bits 15-11 727ac6653aSJeff Kirsher * @phyreg: MII addr reg bits 10-6 737ac6653aSJeff Kirsher * Description: it reads data from the MII register from within the phy device. 747ac6653aSJeff Kirsher * For the 7111 GMAC, we must set the bit 0 in the MII address register while 757ac6653aSJeff Kirsher * accessing the PHY registers. 767ac6653aSJeff Kirsher * Fortunately, it seems this has no drawback for the 7109 MAC. 777ac6653aSJeff Kirsher */ 787ac6653aSJeff Kirsher static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) 797ac6653aSJeff Kirsher { 807ac6653aSJeff Kirsher struct net_device *ndev = bus->priv; 817ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 827ac6653aSJeff Kirsher unsigned int mii_address = priv->hw->mii.addr; 837ac6653aSJeff Kirsher unsigned int mii_data = priv->hw->mii.data; 847ac6653aSJeff Kirsher 857ac6653aSJeff Kirsher int data; 867ac6653aSJeff Kirsher u16 regValue = (((phyaddr << 11) & (0x0000F800)) | 877ac6653aSJeff Kirsher ((phyreg << 6) & (0x000007C0))); 88cd7201f4SGiuseppe CAVALLARO regValue |= MII_BUSY | ((priv->clk_csr & 0xF) << 2); 897ac6653aSJeff Kirsher 9039b401dbSDeepak SIKRI if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) 9139b401dbSDeepak SIKRI return -EBUSY; 9239b401dbSDeepak SIKRI 937ac6653aSJeff Kirsher writel(regValue, priv->ioaddr + mii_address); 9439b401dbSDeepak SIKRI 9539b401dbSDeepak SIKRI if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) 9639b401dbSDeepak SIKRI return -EBUSY; 977ac6653aSJeff Kirsher 987ac6653aSJeff Kirsher /* Read the data from the MII data register */ 997ac6653aSJeff Kirsher data = (int)readl(priv->ioaddr + mii_data); 1007ac6653aSJeff Kirsher 1017ac6653aSJeff Kirsher return data; 1027ac6653aSJeff Kirsher } 1037ac6653aSJeff Kirsher 1047ac6653aSJeff Kirsher /** 1057ac6653aSJeff Kirsher * stmmac_mdio_write 1067ac6653aSJeff Kirsher * @bus: points to the mii_bus structure 1077ac6653aSJeff Kirsher * @phyaddr: MII addr reg bits 15-11 1087ac6653aSJeff Kirsher * @phyreg: MII addr reg bits 10-6 1097ac6653aSJeff Kirsher * @phydata: phy data 1107ac6653aSJeff Kirsher * Description: it writes the data into the MII register from within the device. 1117ac6653aSJeff Kirsher */ 1127ac6653aSJeff Kirsher static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, 1137ac6653aSJeff Kirsher u16 phydata) 1147ac6653aSJeff Kirsher { 1157ac6653aSJeff Kirsher struct net_device *ndev = bus->priv; 1167ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 1177ac6653aSJeff Kirsher unsigned int mii_address = priv->hw->mii.addr; 1187ac6653aSJeff Kirsher unsigned int mii_data = priv->hw->mii.data; 1197ac6653aSJeff Kirsher 1207ac6653aSJeff Kirsher u16 value = 1217ac6653aSJeff Kirsher (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0))) 1227ac6653aSJeff Kirsher | MII_WRITE; 1237ac6653aSJeff Kirsher 124cd7201f4SGiuseppe CAVALLARO value |= MII_BUSY | ((priv->clk_csr & 0xF) << 2); 1257ac6653aSJeff Kirsher 1267ac6653aSJeff Kirsher /* Wait until any existing MII operation is complete */ 12739b401dbSDeepak SIKRI if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) 12839b401dbSDeepak SIKRI return -EBUSY; 1297ac6653aSJeff Kirsher 1307ac6653aSJeff Kirsher /* Set the MII address register to write */ 1317ac6653aSJeff Kirsher writel(phydata, priv->ioaddr + mii_data); 1327ac6653aSJeff Kirsher writel(value, priv->ioaddr + mii_address); 1337ac6653aSJeff Kirsher 1347ac6653aSJeff Kirsher /* Wait until any existing MII operation is complete */ 13539b401dbSDeepak SIKRI return stmmac_mdio_busy_wait(priv->ioaddr, mii_address); 1367ac6653aSJeff Kirsher } 1377ac6653aSJeff Kirsher 1387ac6653aSJeff Kirsher /** 139ac1f74a7SAlexandre TORGUE * stmmac_mdio_read_gmac4 140ac1f74a7SAlexandre TORGUE * @bus: points to the mii_bus structure 141ac1f74a7SAlexandre TORGUE * @phyaddr: MII addr reg bits 25-21 142ac1f74a7SAlexandre TORGUE * @phyreg: MII addr reg bits 20-16 143ac1f74a7SAlexandre TORGUE * Description: it reads data from the MII register of GMAC4 from within 144ac1f74a7SAlexandre TORGUE * the phy device. 145ac1f74a7SAlexandre TORGUE */ 146ac1f74a7SAlexandre TORGUE static int stmmac_mdio_read_gmac4(struct mii_bus *bus, int phyaddr, int phyreg) 147ac1f74a7SAlexandre TORGUE { 148ac1f74a7SAlexandre TORGUE struct net_device *ndev = bus->priv; 149ac1f74a7SAlexandre TORGUE struct stmmac_priv *priv = netdev_priv(ndev); 150ac1f74a7SAlexandre TORGUE unsigned int mii_address = priv->hw->mii.addr; 151ac1f74a7SAlexandre TORGUE unsigned int mii_data = priv->hw->mii.data; 152ac1f74a7SAlexandre TORGUE int data; 153ac1f74a7SAlexandre TORGUE u32 value = (((phyaddr << MII_PHY_ADDR_GMAC4_SHIFT) & 154ac1f74a7SAlexandre TORGUE (MII_PHY_ADDR_GMAC4_MASK)) | 155ac1f74a7SAlexandre TORGUE ((phyreg << MII_PHY_REG_GMAC4_SHIFT) & 156ac1f74a7SAlexandre TORGUE (MII_PHY_REG_GMAC4_MASK))) | MII_GMAC4_READ; 157ac1f74a7SAlexandre TORGUE 158ac1f74a7SAlexandre TORGUE value |= MII_BUSY | ((priv->clk_csr & MII_CSR_CLK_GMAC4_MASK) 159ac1f74a7SAlexandre TORGUE << MII_CSR_CLK_GMAC4_SHIFT); 160ac1f74a7SAlexandre TORGUE 161ac1f74a7SAlexandre TORGUE if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) 162ac1f74a7SAlexandre TORGUE return -EBUSY; 163ac1f74a7SAlexandre TORGUE 164ac1f74a7SAlexandre TORGUE writel(value, priv->ioaddr + mii_address); 165ac1f74a7SAlexandre TORGUE 166ac1f74a7SAlexandre TORGUE if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) 167ac1f74a7SAlexandre TORGUE return -EBUSY; 168ac1f74a7SAlexandre TORGUE 169ac1f74a7SAlexandre TORGUE /* Read the data from the MII data register */ 170ac1f74a7SAlexandre TORGUE data = (int)readl(priv->ioaddr + mii_data); 171ac1f74a7SAlexandre TORGUE 172ac1f74a7SAlexandre TORGUE return data; 173ac1f74a7SAlexandre TORGUE } 174ac1f74a7SAlexandre TORGUE 175ac1f74a7SAlexandre TORGUE /** 176ac1f74a7SAlexandre TORGUE * stmmac_mdio_write_gmac4 177ac1f74a7SAlexandre TORGUE * @bus: points to the mii_bus structure 178ac1f74a7SAlexandre TORGUE * @phyaddr: MII addr reg bits 25-21 179ac1f74a7SAlexandre TORGUE * @phyreg: MII addr reg bits 20-16 180ac1f74a7SAlexandre TORGUE * @phydata: phy data 181ac1f74a7SAlexandre TORGUE * Description: it writes the data into the MII register of GMAC4 from within 182ac1f74a7SAlexandre TORGUE * the device. 183ac1f74a7SAlexandre TORGUE */ 184ac1f74a7SAlexandre TORGUE static int stmmac_mdio_write_gmac4(struct mii_bus *bus, int phyaddr, int phyreg, 185ac1f74a7SAlexandre TORGUE u16 phydata) 186ac1f74a7SAlexandre TORGUE { 187ac1f74a7SAlexandre TORGUE struct net_device *ndev = bus->priv; 188ac1f74a7SAlexandre TORGUE struct stmmac_priv *priv = netdev_priv(ndev); 189ac1f74a7SAlexandre TORGUE unsigned int mii_address = priv->hw->mii.addr; 190ac1f74a7SAlexandre TORGUE unsigned int mii_data = priv->hw->mii.data; 191ac1f74a7SAlexandre TORGUE 192ac1f74a7SAlexandre TORGUE u32 value = (((phyaddr << MII_PHY_ADDR_GMAC4_SHIFT) & 193ac1f74a7SAlexandre TORGUE (MII_PHY_ADDR_GMAC4_MASK)) | 194ac1f74a7SAlexandre TORGUE ((phyreg << MII_PHY_REG_GMAC4_SHIFT) & 195ac1f74a7SAlexandre TORGUE (MII_PHY_REG_GMAC4_MASK))) | MII_GMAC4_WRITE; 196ac1f74a7SAlexandre TORGUE 197ac1f74a7SAlexandre TORGUE value |= MII_BUSY | ((priv->clk_csr & MII_CSR_CLK_GMAC4_MASK) 198ac1f74a7SAlexandre TORGUE << MII_CSR_CLK_GMAC4_SHIFT); 199ac1f74a7SAlexandre TORGUE 200ac1f74a7SAlexandre TORGUE /* Wait until any existing MII operation is complete */ 201ac1f74a7SAlexandre TORGUE if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) 202ac1f74a7SAlexandre TORGUE return -EBUSY; 203ac1f74a7SAlexandre TORGUE 204ac1f74a7SAlexandre TORGUE /* Set the MII address register to write */ 205ac1f74a7SAlexandre TORGUE writel(phydata, priv->ioaddr + mii_data); 206ac1f74a7SAlexandre TORGUE writel(value, priv->ioaddr + mii_address); 207ac1f74a7SAlexandre TORGUE 208ac1f74a7SAlexandre TORGUE /* Wait until any existing MII operation is complete */ 209ac1f74a7SAlexandre TORGUE return stmmac_mdio_busy_wait(priv->ioaddr, mii_address); 210ac1f74a7SAlexandre TORGUE } 211ac1f74a7SAlexandre TORGUE 212ac1f74a7SAlexandre TORGUE /** 2137ac6653aSJeff Kirsher * stmmac_mdio_reset 2147ac6653aSJeff Kirsher * @bus: points to the mii_bus structure 2157ac6653aSJeff Kirsher * Description: reset the MII bus 2167ac6653aSJeff Kirsher */ 217073752aaSSrinivas Kandagatla int stmmac_mdio_reset(struct mii_bus *bus) 2187ac6653aSJeff Kirsher { 219bfab27a1SGiuseppe CAVALLARO #if defined(CONFIG_STMMAC_PLATFORM) 2207ac6653aSJeff Kirsher struct net_device *ndev = bus->priv; 2217ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2227ac6653aSJeff Kirsher unsigned int mii_address = priv->hw->mii.addr; 2230e076471SSrinivas Kandagatla struct stmmac_mdio_bus_data *data = priv->plat->mdio_bus_data; 2247ac6653aSJeff Kirsher 2250e076471SSrinivas Kandagatla #ifdef CONFIG_OF 2260e076471SSrinivas Kandagatla if (priv->device->of_node) { 2270e076471SSrinivas Kandagatla 2280e076471SSrinivas Kandagatla if (data->reset_gpio < 0) { 2290e076471SSrinivas Kandagatla struct device_node *np = priv->device->of_node; 2300e076471SSrinivas Kandagatla if (!np) 2310e076471SSrinivas Kandagatla return 0; 2320e076471SSrinivas Kandagatla 2330e076471SSrinivas Kandagatla data->reset_gpio = of_get_named_gpio(np, 2340e076471SSrinivas Kandagatla "snps,reset-gpio", 0); 2350e076471SSrinivas Kandagatla if (data->reset_gpio < 0) 2360e076471SSrinivas Kandagatla return 0; 2370e076471SSrinivas Kandagatla 2380e076471SSrinivas Kandagatla data->active_low = of_property_read_bool(np, 2390e076471SSrinivas Kandagatla "snps,reset-active-low"); 2400e076471SSrinivas Kandagatla of_property_read_u32_array(np, 2410e076471SSrinivas Kandagatla "snps,reset-delays-us", data->delays, 3); 242ae26c1c6SGiuseppe CAVALLARO 243ae26c1c6SGiuseppe CAVALLARO if (gpio_request(data->reset_gpio, "mdio-reset")) 244ae26c1c6SGiuseppe CAVALLARO return 0; 2450e076471SSrinivas Kandagatla } 2460e076471SSrinivas Kandagatla 247ae26c1c6SGiuseppe CAVALLARO gpio_direction_output(data->reset_gpio, 248ae26c1c6SGiuseppe CAVALLARO data->active_low ? 1 : 0); 249892aa01dSSjoerd Simons if (data->delays[0]) 250892aa01dSSjoerd Simons msleep(DIV_ROUND_UP(data->delays[0], 1000)); 251892aa01dSSjoerd Simons 252ae26c1c6SGiuseppe CAVALLARO gpio_set_value(data->reset_gpio, data->active_low ? 0 : 1); 253892aa01dSSjoerd Simons if (data->delays[1]) 254892aa01dSSjoerd Simons msleep(DIV_ROUND_UP(data->delays[1], 1000)); 255892aa01dSSjoerd Simons 256ae26c1c6SGiuseppe CAVALLARO gpio_set_value(data->reset_gpio, data->active_low ? 1 : 0); 257892aa01dSSjoerd Simons if (data->delays[2]) 258892aa01dSSjoerd Simons msleep(DIV_ROUND_UP(data->delays[2], 1000)); 2590e076471SSrinivas Kandagatla } 2600e076471SSrinivas Kandagatla #endif 2610e076471SSrinivas Kandagatla 2620e076471SSrinivas Kandagatla if (data->phy_reset) { 2637ac6653aSJeff Kirsher pr_debug("stmmac_mdio_reset: calling phy_reset\n"); 2640e076471SSrinivas Kandagatla data->phy_reset(priv->plat->bsp_priv); 2657ac6653aSJeff Kirsher } 2667ac6653aSJeff Kirsher 2677ac6653aSJeff Kirsher /* This is a workaround for problems with the STE101P PHY. 2687ac6653aSJeff Kirsher * It doesn't complete its reset until at least one clock cycle 269ac1f74a7SAlexandre TORGUE * on MDC, so perform a dummy mdio read. To be upadted for GMAC4 270ac1f74a7SAlexandre TORGUE * if needed. 2717ac6653aSJeff Kirsher */ 272ac1f74a7SAlexandre TORGUE if (!priv->plat->has_gmac4) 2737ac6653aSJeff Kirsher writel(0, priv->ioaddr + mii_address); 274bfab27a1SGiuseppe CAVALLARO #endif 2757ac6653aSJeff Kirsher return 0; 2767ac6653aSJeff Kirsher } 2777ac6653aSJeff Kirsher 2787ac6653aSJeff Kirsher /** 2797ac6653aSJeff Kirsher * stmmac_mdio_register 2807ac6653aSJeff Kirsher * @ndev: net device structure 2817ac6653aSJeff Kirsher * Description: it registers the MII bus 2827ac6653aSJeff Kirsher */ 2837ac6653aSJeff Kirsher int stmmac_mdio_register(struct net_device *ndev) 2847ac6653aSJeff Kirsher { 2857ac6653aSJeff Kirsher int err = 0; 2867ac6653aSJeff Kirsher struct mii_bus *new_bus; 2877ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2887ac6653aSJeff Kirsher struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data; 289a7657f12SGiuseppe CAVALLARO struct device_node *mdio_node = priv->plat->mdio_node; 2907ac6653aSJeff Kirsher int addr, found; 2917ac6653aSJeff Kirsher 2927ac6653aSJeff Kirsher if (!mdio_bus_data) 2937ac6653aSJeff Kirsher return 0; 2947ac6653aSJeff Kirsher 2957ac6653aSJeff Kirsher new_bus = mdiobus_alloc(); 2967ac6653aSJeff Kirsher if (new_bus == NULL) 2977ac6653aSJeff Kirsher return -ENOMEM; 2987ac6653aSJeff Kirsher 299e7f4dc35SAndrew Lunn if (mdio_bus_data->irqs) 300643d60bfSMarek Vasut memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq)); 3017ac6653aSJeff Kirsher 3020e076471SSrinivas Kandagatla #ifdef CONFIG_OF 3030e076471SSrinivas Kandagatla if (priv->device->of_node) 3040e076471SSrinivas Kandagatla mdio_bus_data->reset_gpio = -1; 3050e076471SSrinivas Kandagatla #endif 3060e076471SSrinivas Kandagatla 30790b9a545SAlessandro Rubini new_bus->name = "stmmac"; 308ac1f74a7SAlexandre TORGUE if (priv->plat->has_gmac4) { 309ac1f74a7SAlexandre TORGUE new_bus->read = &stmmac_mdio_read_gmac4; 310ac1f74a7SAlexandre TORGUE new_bus->write = &stmmac_mdio_write_gmac4; 311ac1f74a7SAlexandre TORGUE } else { 3127ac6653aSJeff Kirsher new_bus->read = &stmmac_mdio_read; 3137ac6653aSJeff Kirsher new_bus->write = &stmmac_mdio_write; 314ac1f74a7SAlexandre TORGUE } 315ac1f74a7SAlexandre TORGUE 3167ac6653aSJeff Kirsher new_bus->reset = &stmmac_mdio_reset; 317db8857bfSFlorian Fainelli snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x", 318d56631a6SSrinivas Kandagatla new_bus->name, priv->plat->bus_id); 3197ac6653aSJeff Kirsher new_bus->priv = ndev; 3207ac6653aSJeff Kirsher new_bus->phy_mask = mdio_bus_data->phy_mask; 3217ac6653aSJeff Kirsher new_bus->parent = priv->device; 322e34d6569SPhil Reid 3236c672c9bSRomain Perier if (mdio_node) 324e34d6569SPhil Reid err = of_mdiobus_register(new_bus, mdio_node); 3256c672c9bSRomain Perier else 3266c672c9bSRomain Perier err = mdiobus_register(new_bus); 3277ac6653aSJeff Kirsher if (err != 0) { 3287ac6653aSJeff Kirsher pr_err("%s: Cannot register as MDIO bus\n", new_bus->name); 3297ac6653aSJeff Kirsher goto bus_register_fail; 3307ac6653aSJeff Kirsher } 3317ac6653aSJeff Kirsher 332cc2fa619SPhil Reid if (priv->plat->phy_node || mdio_node) 333cc2fa619SPhil Reid goto bus_register_done; 334cc2fa619SPhil Reid 3357ac6653aSJeff Kirsher found = 0; 3367ac6653aSJeff Kirsher for (addr = 0; addr < PHY_MAX_ADDR; addr++) { 3377f854420SAndrew Lunn struct phy_device *phydev = mdiobus_get_phy(new_bus, addr); 3387ac6653aSJeff Kirsher if (phydev) { 3397ac6653aSJeff Kirsher int act = 0; 3407ac6653aSJeff Kirsher char irq_num[4]; 3417ac6653aSJeff Kirsher char *irq_str; 3427ac6653aSJeff Kirsher 3437ac6653aSJeff Kirsher /* 3447ac6653aSJeff Kirsher * If an IRQ was provided to be assigned after 3457ac6653aSJeff Kirsher * the bus probe, do it here. 3467ac6653aSJeff Kirsher */ 3477ac6653aSJeff Kirsher if ((mdio_bus_data->irqs == NULL) && 3487ac6653aSJeff Kirsher (mdio_bus_data->probed_phy_irq > 0)) { 349e7f4dc35SAndrew Lunn new_bus->irq[addr] = 350e7f4dc35SAndrew Lunn mdio_bus_data->probed_phy_irq; 3517ac6653aSJeff Kirsher phydev->irq = mdio_bus_data->probed_phy_irq; 3527ac6653aSJeff Kirsher } 3537ac6653aSJeff Kirsher 3547ac6653aSJeff Kirsher /* 3557ac6653aSJeff Kirsher * If we're going to bind the MAC to this PHY bus, 3567ac6653aSJeff Kirsher * and no PHY number was provided to the MAC, 3577ac6653aSJeff Kirsher * use the one probed here. 3587ac6653aSJeff Kirsher */ 359d56631a6SSrinivas Kandagatla if (priv->plat->phy_addr == -1) 3607ac6653aSJeff Kirsher priv->plat->phy_addr = addr; 3617ac6653aSJeff Kirsher 362d56631a6SSrinivas Kandagatla act = (priv->plat->phy_addr == addr); 3637ac6653aSJeff Kirsher switch (phydev->irq) { 3647ac6653aSJeff Kirsher case PHY_POLL: 3657ac6653aSJeff Kirsher irq_str = "POLL"; 3667ac6653aSJeff Kirsher break; 3677ac6653aSJeff Kirsher case PHY_IGNORE_INTERRUPT: 3687ac6653aSJeff Kirsher irq_str = "IGNORE"; 3697ac6653aSJeff Kirsher break; 3707ac6653aSJeff Kirsher default: 3717ac6653aSJeff Kirsher sprintf(irq_num, "%d", phydev->irq); 3727ac6653aSJeff Kirsher irq_str = irq_num; 3737ac6653aSJeff Kirsher break; 3747ac6653aSJeff Kirsher } 3757ac6653aSJeff Kirsher pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n", 3767ac6653aSJeff Kirsher ndev->name, phydev->phy_id, addr, 37784eff6d1SAndrew Lunn irq_str, phydev_name(phydev), 3787ac6653aSJeff Kirsher act ? " active" : ""); 3797ac6653aSJeff Kirsher found = 1; 3807ac6653aSJeff Kirsher } 3817ac6653aSJeff Kirsher } 3827ac6653aSJeff Kirsher 383e34d6569SPhil Reid if (!found && !mdio_node) { 384fe3881cfSJoe Perches pr_warn("%s: No PHY found\n", ndev->name); 3853955b22bSGiuseppe CAVALLARO mdiobus_unregister(new_bus); 3863955b22bSGiuseppe CAVALLARO mdiobus_free(new_bus); 3873955b22bSGiuseppe CAVALLARO return -ENODEV; 3883955b22bSGiuseppe CAVALLARO } 3893955b22bSGiuseppe CAVALLARO 390cc2fa619SPhil Reid bus_register_done: 3913955b22bSGiuseppe CAVALLARO priv->mii = new_bus; 3927ac6653aSJeff Kirsher 3937ac6653aSJeff Kirsher return 0; 3947ac6653aSJeff Kirsher 3957ac6653aSJeff Kirsher bus_register_fail: 3967ac6653aSJeff Kirsher mdiobus_free(new_bus); 3977ac6653aSJeff Kirsher return err; 3987ac6653aSJeff Kirsher } 3997ac6653aSJeff Kirsher 4007ac6653aSJeff Kirsher /** 4017ac6653aSJeff Kirsher * stmmac_mdio_unregister 4027ac6653aSJeff Kirsher * @ndev: net device structure 4037ac6653aSJeff Kirsher * Description: it unregisters the MII bus 4047ac6653aSJeff Kirsher */ 4057ac6653aSJeff Kirsher int stmmac_mdio_unregister(struct net_device *ndev) 4067ac6653aSJeff Kirsher { 4077ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 4087ac6653aSJeff Kirsher 409a5cf5ce9SSrinivas Kandagatla if (!priv->mii) 410a5cf5ce9SSrinivas Kandagatla return 0; 411a5cf5ce9SSrinivas Kandagatla 4127ac6653aSJeff Kirsher mdiobus_unregister(priv->mii); 4137ac6653aSJeff Kirsher priv->mii->priv = NULL; 4147ac6653aSJeff Kirsher mdiobus_free(priv->mii); 4157ac6653aSJeff Kirsher priv->mii = NULL; 4167ac6653aSJeff Kirsher 4177ac6653aSJeff Kirsher return 0; 4187ac6653aSJeff Kirsher } 419