[U-Boot] [PATCH v2 1/3] net: phy: Add support for accessing MMD PHY registers

Joe Hershberger joe.hershberger at ni.com
Wed Jan 23 14:12:26 UTC 2019


On Wed, Jan 23, 2019 at 7:14 AM Carlo Caione <ccaione at baylibre.com> wrote:
>
> Two new helper functions (phy_read_mmd() and phy_write_mmd()) are added
> to allow access to the MMD PHY registers.
>
> The MMD PHY registers can be accessed by two means:
>
> 1. Using two new MMD access function hooks in the PHY driver. These
> functions can be implemented when the PHY driver does not support the
> standard IEEE Compatible clause 45 access mechanism described in clause
> 22 or if the PHY uses its own non-standard access mechanism.
>
> 2. The standard clause 45 access extensions to the MMD registers through
> the indirection registers (clause 22) in all the other cases.
>
> Signed-off-by: Carlo Caione <ccaione at baylibre.com>
> ---
>  drivers/net/phy/phy.c |  4 +++
>  include/phy.h         | 62 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 66 insertions(+)
>
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index cda4caa803..6769047407 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -549,6 +549,10 @@ int phy_register(struct phy_driver *drv)
>                 drv->readext += gd->reloc_off;
>         if (drv->writeext)
>                 drv->writeext += gd->reloc_off;
> +       if (drv->read_mmd)
> +               drv->read_mmd += gd->reloc_off;
> +       if (drv->write_mmd)
> +               drv->write_mmd += gd->reloc_off;
>  #endif
>         return 0;
>  }
> diff --git a/include/phy.h b/include/phy.h
> index b86fdfb2ce..0ce41661fa 100644
> --- a/include/phy.h
> +++ b/include/phy.h
> @@ -101,6 +101,13 @@ struct phy_driver {
>         int (*readext)(struct phy_device *phydev, int addr, int devad, int reg);
>         int (*writeext)(struct phy_device *phydev, int addr, int devad, int reg,
>                         u16 val);
> +
> +       /* Phy specific driver override for reading a MMD register */
> +       int (*read_mmd)(struct phy_device *phydev, int devad, int reg);
> +
> +       /* Phy specific driver override for writing a MMD register */
> +       int (*write_mmd)(struct phy_device *phydev, int devad, int reg, u16 val);
> +
>         struct list_head list;
>  };
>
> @@ -164,6 +171,61 @@ static inline int phy_write(struct phy_device *phydev, int devad, int regnum,
>         return bus->write(bus, phydev->addr, devad, regnum, val);
>  }
>
> +static inline void phy_mmd_indirect(struct phy_device *phydev, int devad,
> +                                   int regnum)
> +{
> +       /* Write the desired MMD Devad */
> +       phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, devad);
> +
> +       /* Write the desired MMD register address */
> +       phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, regnum);
> +
> +       /* Select the Function : DATA with no post increment */
> +       phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
> +}
> +
> +static inline int phy_read_mmd(struct phy_device *phydev, int devad,
> +                              int regnum)
> +{
> +       int ret;
> +
> +       if (regnum > (u16)~0 || devad > 32)
> +               return -EINVAL;
> +
> +       if (phydev->drv->read_mmd) {
> +               ret = phydev->drv->read_mmd(phydev, devad, regnum);
> +       } else {
> +               phy_mmd_indirect(phydev, devad, regnum);

I think this function should have a name that more clearly conveys
that it doesn't actually complete an indirect access.

Maybe phy_mmd_start_indirect() ?

> +
> +               /* Read the content of the MMD's selected register */
> +               ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA);
> +       }
> +
> +       return ret;

You shouldn't need this variable... just return from the 2 sites that
return errors.

> +}
> +
> +static inline int phy_write_mmd(struct phy_device *phydev, int devad,
> +                               int regnum, u16 val)
> +{
> +       int ret;
> +
> +       if (regnum > (u16)~0 || devad > 32)
> +               return -EINVAL;
> +
> +       if (phydev->drv->write_mmd) {
> +               ret = phydev->drv->write_mmd(phydev, devad, regnum, val);

You could simply return from here.

> +       } else {
> +               phy_mmd_indirect(phydev, devad, regnum);
> +
> +               /* Write the data into MMD's selected register */
> +               phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, val);
> +
> +               ret = 0;

You should return any error from phy_write above and get rid of the
ret variable.

> +       }
> +
> +       return ret;
> +}
> +
>  #ifdef CONFIG_PHYLIB_10G
>  extern struct phy_driver gen10g_driver;
>
> --
> 2.19.1
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot


More information about the U-Boot mailing list