]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/cmd_mdio.c
Merge branch 'tx28-bugfix' into karo-devel
[karo-tx-uboot.git] / common / cmd_mdio.c
index 77d8df12c5eacc04ea299a1f28b6c1181d7b5f60..fb13d050752a7f2abeb615101e76046257477fe5 100644 (file)
@@ -2,23 +2,7 @@
  * (C) Copyright 2011 Freescale Semiconductor, Inc
  * Andy Fleming
  *
- * 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+
  */
 
 /*
@@ -57,9 +41,11 @@ static int extract_range(char *input, int *plo, int *phi)
        return 0;
 }
 
-int mdio_write_ranges(struct mii_dev *bus, int addrlo,
-                       int addrhi, int devadlo, int devadhi,
-                       int reglo, int reghi, unsigned short data)
+static int mdio_write_ranges(struct phy_device *phydev, struct mii_dev *bus,
+                            int addrlo,
+                            int addrhi, int devadlo, int devadhi,
+                            int reglo, int reghi, unsigned short data,
+                            int extended)
 {
        int addr, devad, reg;
        int err = 0;
@@ -67,7 +53,12 @@ int mdio_write_ranges(struct mii_dev *bus, int addrlo,
        for (addr = addrlo; addr <= addrhi; addr++) {
                for (devad = devadlo; devad <= devadhi; devad++) {
                        for (reg = reglo; reg <= reghi; reg++) {
-                               err = bus->write(bus, addr, devad, reg, data);
+                               if (!extended)
+                                       err = bus->write(bus, addr, devad,
+                                                        reg, data);
+                               else
+                                       err = phydev->drv->writeext(phydev,
+                                                       addr, devad, reg, data);
 
                                if (err)
                                        goto err_out;
@@ -79,9 +70,10 @@ err_out:
        return err;
 }
 
-int mdio_read_ranges(struct mii_dev *bus, int addrlo,
-                       int addrhi, int devadlo, int devadhi,
-                       int reglo, int reghi)
+static int mdio_read_ranges(struct phy_device *phydev, struct mii_dev *bus,
+                           int addrlo,
+                           int addrhi, int devadlo, int devadhi,
+                           int reglo, int reghi, int extended)
 {
        int addr, devad, reg;
 
@@ -93,7 +85,12 @@ int mdio_read_ranges(struct mii_dev *bus, int addrlo,
                        for (reg = reglo; reg <= reghi; reg++) {
                                int val;
 
-                               val = bus->read(bus, addr, devad, reg);
+                               if (!extended)
+                                       val = bus->read(bus, addr, devad, reg);
+                               else
+                                       val = phydev->drv->readext(phydev, addr,
+                                               devad, reg);
+
                                if (val < 0) {
                                        printf("Error\n");
 
@@ -112,8 +109,8 @@ int mdio_read_ranges(struct mii_dev *bus, int addrlo,
 }
 
 /* The register will be in the form [a[-b].]x[-y] */
-int extract_reg_range(char *input, int *devadlo, int *devadhi,
-               int *reglo, int *reghi)
+static int extract_reg_range(char *input, int *devadlo, int *devadhi,
+                            int *reglo, int *reghi)
 {
        char *regstr;
 
@@ -141,10 +138,11 @@ int extract_reg_range(char *input, int *devadlo, int *devadhi,
        return extract_range(regstr, reglo, reghi);
 }
 
-int extract_phy_range(char *const argv[], int argc, struct mii_dev **bus,
-               int *addrlo, int *addrhi)
+static int extract_phy_range(char *const argv[], int argc, struct mii_dev **bus,
+                            struct phy_device **phydev,
+                            int *addrlo, int *addrhi)
 {
-       struct phy_device *phydev;
+       struct phy_device *dev = *phydev;
 
        if ((argc < 1) || (argc > 2))
                return -1;
@@ -170,11 +168,11 @@ int extract_phy_range(char *const argv[], int argc, struct mii_dev **bus,
         * device by the given name.  If none are found, we call
         * extract_range() on the string, and see if it's an address range.
         */
-       phydev = mdio_phydev_for_ethname(argv[0]);
+       dev = mdio_phydev_for_ethname(argv[0]);
 
-       if (phydev) {
-               *addrlo = *addrhi = phydev->addr;
-               *bus = phydev->bus;
+       if (dev) {
+               *addrlo = *addrhi = dev->addr;
+               *bus = dev->bus;
 
                return 0;
        }
@@ -191,6 +189,8 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        unsigned short  data;
        int pos = argc - 1;
        struct mii_dev *bus;
+       struct phy_device *phydev = NULL;
+       int extended = 0;
 
        if (argc < 2)
                return CMD_RET_USAGE;
@@ -213,6 +213,29 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        if (flag & CMD_FLAG_REPEAT)
                op[0] = last_op[0];
 
+       if (strlen(argv[1]) > 1) {
+               op[1] = argv[1][1];
+               if (op[1] == 'x') {
+                       phydev = mdio_phydev_for_ethname(argv[2]);
+
+                       if (phydev) {
+                               addrlo = phydev->addr;
+                               addrhi = addrlo;
+                               bus = phydev->bus;
+                               extended = 1;
+                       } else {
+                               return -1;
+                       }
+
+                       if (!phydev->drv ||
+                           (!phydev->drv->writeext && (op[0] == 'w')) ||
+                           (!phydev->drv->readext && (op[0] == 'r'))) {
+                               puts("PHY does not have extended functions\n");
+                               return -1;
+                       }
+               }
+       }
+
        switch (op[0]) {
        case 'w':
                if (pos > 1)
@@ -226,7 +249,7 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        default:
                if (pos > 1)
                        if (extract_phy_range(&(argv[2]), pos - 1, &bus,
-                                       &addrlo, &addrhi))
+                                       &phydev, &addrlo, &addrhi))
                                return -1;
 
                break;
@@ -243,13 +266,13 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        switch (op[0]) {
        case 'w':
-               mdio_write_ranges(bus, addrlo, addrhi, devadlo, devadhi,
-                               reglo, reghi, data);
+               mdio_write_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi,
+                                 reglo, reghi, data, extended);
                break;
 
        case 'r':
-               mdio_read_ranges(bus, addrlo, addrhi, devadlo, devadhi,
-                               reglo, reghi);
+               mdio_read_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi,
+                                reglo, reghi, extended);
                break;
        }
 
@@ -278,6 +301,10 @@ U_BOOT_CMD(
                "read PHY's register at <devad>.<reg>\n"
        "mdio write <phydev> [<devad>.]<reg> <data> - "
                "write PHY's register at <devad>.<reg>\n"
+       "mdio rx <phydev> [<devad>.]<reg> - "
+               "read PHY's extended register at <devad>.<reg>\n"
+       "mdio wx <phydev> [<devad>.]<reg> <data> - "
+               "write PHY's extended register at <devad>.<reg>\n"
        "<phydev> may be:\n"
        "   <busname>  <addr>\n"
        "   <addr>\n"