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