uboot/include/phy.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * Copyright 2011 Freescale Semiconductor, Inc.
   4 *      Andy Fleming <afleming@gmail.com>
   5 *
   6 * This file pretty much stolen from Linux's mii.h/ethtool.h/phy.h
   7 */
   8
   9#ifndef _PHY_H
  10#define _PHY_H
  11
  12#include <dm.h>
  13#include <linux/list.h>
  14#include <linux/mii.h>
  15#include <linux/ethtool.h>
  16#include <linux/mdio.h>
  17#include <phy_interface.h>
  18
  19#define PHY_FIXED_ID            0xa5a55a5a
  20/*
  21 * There is no actual id for this.
  22 * This is just a dummy id for gmii2rgmmi converter.
  23 */
  24#define PHY_GMII2RGMII_ID       0x5a5a5a5a
  25
  26#define PHY_MAX_ADDR 32
  27
  28#define PHY_FLAG_BROKEN_RESET   (1 << 0) /* soft reset not supported */
  29
  30#define PHY_DEFAULT_FEATURES    (SUPPORTED_Autoneg | \
  31                                 SUPPORTED_TP | \
  32                                 SUPPORTED_MII)
  33
  34#define PHY_10BT_FEATURES       (SUPPORTED_10baseT_Half | \
  35                                 SUPPORTED_10baseT_Full)
  36
  37#define PHY_100BT_FEATURES      (SUPPORTED_100baseT_Half | \
  38                                 SUPPORTED_100baseT_Full)
  39
  40#define PHY_1000BT_FEATURES     (SUPPORTED_1000baseT_Half | \
  41                                 SUPPORTED_1000baseT_Full)
  42
  43#define PHY_BASIC_FEATURES      (PHY_10BT_FEATURES | \
  44                                 PHY_100BT_FEATURES | \
  45                                 PHY_DEFAULT_FEATURES)
  46
  47#define PHY_GBIT_FEATURES       (PHY_BASIC_FEATURES | \
  48                                 PHY_1000BT_FEATURES)
  49
  50#define PHY_10G_FEATURES        (PHY_GBIT_FEATURES | \
  51                                SUPPORTED_10000baseT_Full)
  52
  53#ifndef PHY_ANEG_TIMEOUT
  54#define PHY_ANEG_TIMEOUT        4000
  55#endif
  56
  57
  58struct phy_device;
  59
  60#define MDIO_NAME_LEN 32
  61
  62struct mii_dev {
  63        struct list_head link;
  64        char name[MDIO_NAME_LEN];
  65        void *priv;
  66        int (*read)(struct mii_dev *bus, int addr, int devad, int reg);
  67        int (*write)(struct mii_dev *bus, int addr, int devad, int reg,
  68                        u16 val);
  69        int (*reset)(struct mii_dev *bus);
  70        struct phy_device *phymap[PHY_MAX_ADDR];
  71        u32 phy_mask;
  72};
  73
  74/* struct phy_driver: a structure which defines PHY behavior
  75 *
  76 * uid will contain a number which represents the PHY.  During
  77 * startup, the driver will poll the PHY to find out what its
  78 * UID--as defined by registers 2 and 3--is.  The 32-bit result
  79 * gotten from the PHY will be masked to
  80 * discard any bits which may change based on revision numbers
  81 * unimportant to functionality
  82 *
  83 */
  84struct phy_driver {
  85        char *name;
  86        unsigned int uid;
  87        unsigned int mask;
  88        unsigned int mmds;
  89
  90        u32 features;
  91
  92        /* Called to do any driver startup necessities */
  93        /* Will be called during phy_connect */
  94        int (*probe)(struct phy_device *phydev);
  95
  96        /* Called to configure the PHY, and modify the controller
  97         * based on the results.  Should be called after phy_connect */
  98        int (*config)(struct phy_device *phydev);
  99
 100        /* Called when starting up the controller */
 101        int (*startup)(struct phy_device *phydev);
 102
 103        /* Called when bringing down the controller */
 104        int (*shutdown)(struct phy_device *phydev);
 105
 106        int (*readext)(struct phy_device *phydev, int addr, int devad, int reg);
 107        int (*writeext)(struct phy_device *phydev, int addr, int devad, int reg,
 108                        u16 val);
 109
 110        /* Phy specific driver override for reading a MMD register */
 111        int (*read_mmd)(struct phy_device *phydev, int devad, int reg);
 112
 113        /* Phy specific driver override for writing a MMD register */
 114        int (*write_mmd)(struct phy_device *phydev, int devad, int reg,
 115                         u16 val);
 116
 117        struct list_head list;
 118
 119        /* driver private data */
 120        ulong data;
 121};
 122
 123struct phy_device {
 124        /* Information about the PHY type */
 125        /* And management functions */
 126        struct mii_dev *bus;
 127        struct phy_driver *drv;
 128        void *priv;
 129
 130#ifdef CONFIG_DM_ETH
 131        struct udevice *dev;
 132        ofnode node;
 133#else
 134        struct eth_device *dev;
 135#endif
 136
 137        /* forced speed & duplex (no autoneg)
 138         * partner speed & duplex & pause (autoneg)
 139         */
 140        int speed;
 141        int duplex;
 142
 143        /* The most recently read link state */
 144        int link;
 145        int port;
 146        phy_interface_t interface;
 147
 148        u32 advertising;
 149        u32 supported;
 150        u32 mmds;
 151
 152        int autoneg;
 153        int addr;
 154        int pause;
 155        int asym_pause;
 156        u32 phy_id;
 157        bool is_c45;
 158        u32 flags;
 159};
 160
 161struct fixed_link {
 162        int phy_id;
 163        int duplex;
 164        int link_speed;
 165        int pause;
 166        int asym_pause;
 167};
 168
 169static inline int phy_read(struct phy_device *phydev, int devad, int regnum)
 170{
 171        struct mii_dev *bus = phydev->bus;
 172
 173        return bus->read(bus, phydev->addr, devad, regnum);
 174}
 175
 176static inline int phy_write(struct phy_device *phydev, int devad, int regnum,
 177                        u16 val)
 178{
 179        struct mii_dev *bus = phydev->bus;
 180
 181        return bus->write(bus, phydev->addr, devad, regnum, val);
 182}
 183
 184static inline void phy_mmd_start_indirect(struct phy_device *phydev, int devad,
 185                                          int regnum)
 186{
 187        /* Write the desired MMD Devad */
 188        phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, devad);
 189
 190        /* Write the desired MMD register address */
 191        phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, regnum);
 192
 193        /* Select the Function : DATA with no post increment */
 194        phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL,
 195                  (devad | MII_MMD_CTRL_NOINCR));
 196}
 197
 198static inline int phy_read_mmd(struct phy_device *phydev, int devad,
 199                               int regnum)
 200{
 201        struct phy_driver *drv = phydev->drv;
 202
 203        if (regnum > (u16)~0 || devad > 32)
 204                return -EINVAL;
 205
 206        /* driver-specific access */
 207        if (drv->read_mmd)
 208                return drv->read_mmd(phydev, devad, regnum);
 209
 210        /* direct C45 / C22 access */
 211        if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES ||
 212            devad == MDIO_DEVAD_NONE || !devad)
 213                return phy_read(phydev, devad, regnum);
 214
 215        /* indirect C22 access */
 216        phy_mmd_start_indirect(phydev, devad, regnum);
 217
 218        /* Read the content of the MMD's selected register */
 219        return phy_read(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA);
 220}
 221
 222static inline int phy_write_mmd(struct phy_device *phydev, int devad,
 223                                int regnum, u16 val)
 224{
 225        struct phy_driver *drv = phydev->drv;
 226
 227        if (regnum > (u16)~0 || devad > 32)
 228                return -EINVAL;
 229
 230        /* driver-specific access */
 231        if (drv->write_mmd)
 232                return drv->write_mmd(phydev, devad, regnum, val);
 233
 234        /* direct C45 / C22 access */
 235        if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES ||
 236            devad == MDIO_DEVAD_NONE || !devad)
 237                return phy_write(phydev, devad, regnum, val);
 238
 239        /* indirect C22 access */
 240        phy_mmd_start_indirect(phydev, devad, regnum);
 241
 242        /* Write the data into MMD's selected register */
 243        return phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, val);
 244}
 245
 246#ifdef CONFIG_PHYLIB_10G
 247extern struct phy_driver gen10g_driver;
 248
 249/* For now, XGMII is the only 10G interface */
 250static inline int is_10g_interface(phy_interface_t interface)
 251{
 252        return interface == PHY_INTERFACE_MODE_XGMII;
 253}
 254
 255#endif
 256
 257/**
 258 * phy_init() - Initializes the PHY drivers
 259 *
 260 * This function registers all available PHY drivers
 261 *
 262 * @return 0 if OK, -ve on error
 263 */
 264int phy_init(void);
 265
 266/**
 267 * phy_reset() - Resets the specified PHY
 268 *
 269 * Issues a reset of the PHY and waits for it to complete
 270 *
 271 * @phydev:     PHY to reset
 272 * @return 0 if OK, -ve on error
 273 */
 274int phy_reset(struct phy_device *phydev);
 275
 276/**
 277 * phy_find_by_mask() - Searches for a PHY on the specified MDIO bus
 278 *
 279 * The function checks the PHY addresses flagged in phy_mask and returns a
 280 * phy_device pointer if it detects a PHY.
 281 * This function should only be called if just one PHY is expected to be present
 282 * in the set of addresses flagged in phy_mask.  If multiple PHYs are present,
 283 * it is undefined which of these PHYs is returned.
 284 *
 285 * @bus:        MII/MDIO bus to scan
 286 * @phy_mask:   bitmap of PYH addresses to scan
 287 * @interface:  type of MAC-PHY interface
 288 * @return pointer to phy_device if a PHY is found, or NULL otherwise
 289 */
 290struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
 291                phy_interface_t interface);
 292
 293#ifdef CONFIG_DM_ETH
 294
 295/**
 296 * phy_connect_dev() - Associates the given pair of PHY and Ethernet devices
 297 * @phydev:     PHY device
 298 * @dev:        Ethernet device
 299 */
 300void phy_connect_dev(struct phy_device *phydev, struct udevice *dev);
 301
 302/**
 303 * phy_connect() - Creates a PHY device for the Ethernet interface
 304 *
 305 * Creates a PHY device for the PHY at the given address, if one doesn't exist
 306 * already, and associates it with the Ethernet device.
 307 * The function may be called with addr <= 0, in this case addr value is ignored
 308 * and the bus is scanned to detect a PHY.  Scanning should only be used if only
 309 * one PHY is expected to be present on the MDIO bus, otherwise it is undefined
 310 * which PHY is returned.
 311 *
 312 * @bus:        MII/MDIO bus that hosts the PHY
 313 * @addr:       PHY address on MDIO bus
 314 * @dev:        Ethernet device to associate to the PHY
 315 * @interface:  type of MAC-PHY interface
 316 * @return pointer to phy_device if a PHY is found, or NULL otherwise
 317 */
 318struct phy_device *phy_connect(struct mii_dev *bus, int addr,
 319                                struct udevice *dev,
 320                                phy_interface_t interface);
 321
 322static inline ofnode phy_get_ofnode(struct phy_device *phydev)
 323{
 324        if (ofnode_valid(phydev->node))
 325                return phydev->node;
 326        else
 327                return dev_ofnode(phydev->dev);
 328}
 329#else
 330
 331/**
 332 * phy_connect_dev() - Associates the given pair of PHY and Ethernet devices
 333 * @phydev:     PHY device
 334 * @dev:        Ethernet device
 335 */
 336void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev);
 337
 338/**
 339 * phy_connect() - Creates a PHY device for the Ethernet interface
 340 *
 341 * Creates a PHY device for the PHY at the given address, if one doesn't exist
 342 * already, and associates it with the Ethernet device.
 343 * The function may be called with addr <= 0, in this case addr value is ignored
 344 * and the bus is scanned to detect a PHY.  Scanning should only be used if only
 345 * one PHY is expected to be present on the MDIO bus, otherwise it is undefined
 346 * which PHY is returned.
 347 *
 348 * @bus:        MII/MDIO bus that hosts the PHY
 349 * @addr:       PHY address on MDIO bus
 350 * @dev:        Ethernet device to associate to the PHY
 351 * @interface:  type of MAC-PHY interface
 352 * @return pointer to phy_device if a PHY is found, or NULL otherwise
 353 */
 354struct phy_device *phy_connect(struct mii_dev *bus, int addr,
 355                                struct eth_device *dev,
 356                                phy_interface_t interface);
 357
 358static inline ofnode phy_get_ofnode(struct phy_device *phydev)
 359{
 360        return ofnode_null();
 361}
 362#endif
 363int phy_startup(struct phy_device *phydev);
 364int phy_config(struct phy_device *phydev);
 365int phy_shutdown(struct phy_device *phydev);
 366int phy_register(struct phy_driver *drv);
 367int phy_set_supported(struct phy_device *phydev, u32 max_speed);
 368int genphy_config_aneg(struct phy_device *phydev);
 369int genphy_restart_aneg(struct phy_device *phydev);
 370int genphy_update_link(struct phy_device *phydev);
 371int genphy_parse_link(struct phy_device *phydev);
 372int genphy_config(struct phy_device *phydev);
 373int genphy_startup(struct phy_device *phydev);
 374int genphy_shutdown(struct phy_device *phydev);
 375int gen10g_config(struct phy_device *phydev);
 376int gen10g_startup(struct phy_device *phydev);
 377int gen10g_shutdown(struct phy_device *phydev);
 378int gen10g_discover_mmds(struct phy_device *phydev);
 379
 380int phy_b53_init(void);
 381int phy_mv88e61xx_init(void);
 382int phy_aquantia_init(void);
 383int phy_atheros_init(void);
 384int phy_broadcom_init(void);
 385int phy_cortina_init(void);
 386int phy_davicom_init(void);
 387int phy_et1011c_init(void);
 388int phy_lxt_init(void);
 389int phy_marvell_init(void);
 390int phy_micrel_ksz8xxx_init(void);
 391int phy_micrel_ksz90x1_init(void);
 392int phy_meson_gxl_init(void);
 393int phy_natsemi_init(void);
 394int phy_realtek_init(void);
 395int phy_smsc_init(void);
 396int phy_teranetics_init(void);
 397int phy_ti_init(void);
 398int phy_vitesse_init(void);
 399int phy_xilinx_init(void);
 400int phy_mscc_init(void);
 401int phy_fixed_init(void);
 402int phy_xilinx_gmii2rgmii_init(void);
 403
 404int board_phy_config(struct phy_device *phydev);
 405int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id);
 406
 407/**
 408 * phy_get_interface_by_name() - Look up a PHY interface name
 409 *
 410 * @str:        PHY interface name, e.g. "mii"
 411 * @return PHY_INTERFACE_MODE_... value, or -1 if not found
 412 */
 413int phy_get_interface_by_name(const char *str);
 414
 415/**
 416 * phy_interface_is_rgmii - Convenience function for testing if a PHY interface
 417 * is RGMII (all variants)
 418 * @phydev: the phy_device struct
 419 */
 420static inline bool phy_interface_is_rgmii(struct phy_device *phydev)
 421{
 422        return phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
 423                phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID;
 424}
 425
 426/**
 427 * phy_interface_is_sgmii - Convenience function for testing if a PHY interface
 428 * is SGMII (all variants)
 429 * @phydev: the phy_device struct
 430 */
 431static inline bool phy_interface_is_sgmii(struct phy_device *phydev)
 432{
 433        return phydev->interface >= PHY_INTERFACE_MODE_SGMII &&
 434                phydev->interface <= PHY_INTERFACE_MODE_QSGMII;
 435}
 436
 437/* PHY UIDs for various PHYs that are referenced in external code */
 438#define PHY_UID_CS4340          0x13e51002
 439#define PHY_UID_CS4223          0x03e57003
 440#define PHY_UID_TN2020          0x00a19410
 441#define PHY_UID_IN112525_S03    0x02107440
 442
 443#endif
 444