linux/include/linux/mdio.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * linux/mdio.h: definitions for MDIO (clause 45) transceivers
   4 * Copyright 2006-2009 Solarflare Communications Inc.
   5 */
   6#ifndef __LINUX_MDIO_H__
   7#define __LINUX_MDIO_H__
   8
   9#include <uapi/linux/mdio.h>
  10#include <linux/bitfield.h>
  11#include <linux/mod_devicetable.h>
  12
  13/* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit
  14 * IEEE 802.3ae clause 45 addressing mode used by 10GIGE phy chips.
  15 */
  16#define MII_ADDR_C45            (1<<30)
  17#define MII_DEVADDR_C45_SHIFT   16
  18#define MII_DEVADDR_C45_MASK    GENMASK(20, 16)
  19#define MII_REGADDR_C45_MASK    GENMASK(15, 0)
  20
  21struct gpio_desc;
  22struct mii_bus;
  23struct reset_control;
  24
  25/* Multiple levels of nesting are possible. However typically this is
  26 * limited to nested DSA like layer, a MUX layer, and the normal
  27 * user. Instead of trying to handle the general case, just define
  28 * these cases.
  29 */
  30enum mdio_mutex_lock_class {
  31        MDIO_MUTEX_NORMAL,
  32        MDIO_MUTEX_MUX,
  33        MDIO_MUTEX_NESTED,
  34};
  35
  36struct mdio_device {
  37        struct device dev;
  38
  39        struct mii_bus *bus;
  40        char modalias[MDIO_NAME_SIZE];
  41
  42        int (*bus_match)(struct device *dev, struct device_driver *drv);
  43        void (*device_free)(struct mdio_device *mdiodev);
  44        void (*device_remove)(struct mdio_device *mdiodev);
  45
  46        /* Bus address of the MDIO device (0-31) */
  47        int addr;
  48        int flags;
  49        struct gpio_desc *reset_gpio;
  50        struct reset_control *reset_ctrl;
  51        unsigned int reset_assert_delay;
  52        unsigned int reset_deassert_delay;
  53};
  54
  55static inline struct mdio_device *to_mdio_device(const struct device *dev)
  56{
  57        return container_of(dev, struct mdio_device, dev);
  58}
  59
  60/* struct mdio_driver_common: Common to all MDIO drivers */
  61struct mdio_driver_common {
  62        struct device_driver driver;
  63        int flags;
  64};
  65#define MDIO_DEVICE_FLAG_PHY            1
  66
  67static inline struct mdio_driver_common *
  68to_mdio_common_driver(const struct device_driver *driver)
  69{
  70        return container_of(driver, struct mdio_driver_common, driver);
  71}
  72
  73/* struct mdio_driver: Generic MDIO driver */
  74struct mdio_driver {
  75        struct mdio_driver_common mdiodrv;
  76
  77        /*
  78         * Called during discovery.  Used to set
  79         * up device-specific structures, if any
  80         */
  81        int (*probe)(struct mdio_device *mdiodev);
  82
  83        /* Clears up any memory if needed */
  84        void (*remove)(struct mdio_device *mdiodev);
  85
  86        /* Quiesces the device on system shutdown, turns off interrupts etc */
  87        void (*shutdown)(struct mdio_device *mdiodev);
  88};
  89
  90static inline struct mdio_driver *
  91to_mdio_driver(const struct device_driver *driver)
  92{
  93        return container_of(to_mdio_common_driver(driver), struct mdio_driver,
  94                            mdiodrv);
  95}
  96
  97/* device driver data */
  98static inline void mdiodev_set_drvdata(struct mdio_device *mdio, void *data)
  99{
 100        dev_set_drvdata(&mdio->dev, data);
 101}
 102
 103static inline void *mdiodev_get_drvdata(struct mdio_device *mdio)
 104{
 105        return dev_get_drvdata(&mdio->dev);
 106}
 107
 108void mdio_device_free(struct mdio_device *mdiodev);
 109struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr);
 110int mdio_device_register(struct mdio_device *mdiodev);
 111void mdio_device_remove(struct mdio_device *mdiodev);
 112void mdio_device_reset(struct mdio_device *mdiodev, int value);
 113int mdio_driver_register(struct mdio_driver *drv);
 114void mdio_driver_unregister(struct mdio_driver *drv);
 115int mdio_device_bus_match(struct device *dev, struct device_driver *drv);
 116
 117static inline bool mdio_phy_id_is_c45(int phy_id)
 118{
 119        return (phy_id & MDIO_PHY_ID_C45) && !(phy_id & ~MDIO_PHY_ID_C45_MASK);
 120}
 121
 122static inline __u16 mdio_phy_id_prtad(int phy_id)
 123{
 124        return (phy_id & MDIO_PHY_ID_PRTAD) >> 5;
 125}
 126
 127static inline __u16 mdio_phy_id_devad(int phy_id)
 128{
 129        return phy_id & MDIO_PHY_ID_DEVAD;
 130}
 131
 132/**
 133 * struct mdio_if_info - Ethernet controller MDIO interface
 134 * @prtad: PRTAD of the PHY (%MDIO_PRTAD_NONE if not present/unknown)
 135 * @mmds: Mask of MMDs expected to be present in the PHY.  This must be
 136 *      non-zero unless @prtad = %MDIO_PRTAD_NONE.
 137 * @mode_support: MDIO modes supported.  If %MDIO_SUPPORTS_C22 is set then
 138 *      MII register access will be passed through with @devad =
 139 *      %MDIO_DEVAD_NONE.  If %MDIO_EMULATE_C22 is set then access to
 140 *      commonly used clause 22 registers will be translated into
 141 *      clause 45 registers.
 142 * @dev: Net device structure
 143 * @mdio_read: Register read function; returns value or negative error code
 144 * @mdio_write: Register write function; returns 0 or negative error code
 145 */
 146struct mdio_if_info {
 147        int prtad;
 148        u32 mmds;
 149        unsigned mode_support;
 150
 151        struct net_device *dev;
 152        int (*mdio_read)(struct net_device *dev, int prtad, int devad,
 153                         u16 addr);
 154        int (*mdio_write)(struct net_device *dev, int prtad, int devad,
 155                          u16 addr, u16 val);
 156};
 157
 158#define MDIO_PRTAD_NONE                 (-1)
 159#define MDIO_DEVAD_NONE                 (-1)
 160#define MDIO_SUPPORTS_C22               1
 161#define MDIO_SUPPORTS_C45               2
 162#define MDIO_EMULATE_C22                4
 163
 164struct ethtool_cmd;
 165struct ethtool_pauseparam;
 166extern int mdio45_probe(struct mdio_if_info *mdio, int prtad);
 167extern int mdio_set_flag(const struct mdio_if_info *mdio,
 168                         int prtad, int devad, u16 addr, int mask,
 169                         bool sense);
 170extern int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmds);
 171extern int mdio45_nway_restart(const struct mdio_if_info *mdio);
 172extern void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
 173                                      struct ethtool_cmd *ecmd,
 174                                      u32 npage_adv, u32 npage_lpa);
 175extern void
 176mdio45_ethtool_ksettings_get_npage(const struct mdio_if_info *mdio,
 177                                   struct ethtool_link_ksettings *cmd,
 178                                   u32 npage_adv, u32 npage_lpa);
 179
 180/**
 181 * mdio45_ethtool_gset - get settings for ETHTOOL_GSET
 182 * @mdio: MDIO interface
 183 * @ecmd: Ethtool request structure
 184 *
 185 * Since the CSRs for auto-negotiation using next pages are not fully
 186 * standardised, this function does not attempt to decode them.  Use
 187 * mdio45_ethtool_gset_npage() to specify advertisement bits from next
 188 * pages.
 189 */
 190static inline void mdio45_ethtool_gset(const struct mdio_if_info *mdio,
 191                                       struct ethtool_cmd *ecmd)
 192{
 193        mdio45_ethtool_gset_npage(mdio, ecmd, 0, 0);
 194}
 195
 196/**
 197 * mdio45_ethtool_ksettings_get - get settings for ETHTOOL_GLINKSETTINGS
 198 * @mdio: MDIO interface
 199 * @cmd: Ethtool request structure
 200 *
 201 * Since the CSRs for auto-negotiation using next pages are not fully
 202 * standardised, this function does not attempt to decode them.  Use
 203 * mdio45_ethtool_ksettings_get_npage() to specify advertisement bits
 204 * from next pages.
 205 */
 206static inline void
 207mdio45_ethtool_ksettings_get(const struct mdio_if_info *mdio,
 208                             struct ethtool_link_ksettings *cmd)
 209{
 210        mdio45_ethtool_ksettings_get_npage(mdio, cmd, 0, 0);
 211}
 212
 213extern int mdio_mii_ioctl(const struct mdio_if_info *mdio,
 214                          struct mii_ioctl_data *mii_data, int cmd);
 215
 216/**
 217 * mmd_eee_cap_to_ethtool_sup_t
 218 * @eee_cap: value of the MMD EEE Capability register
 219 *
 220 * A small helper function that translates MMD EEE Capability (3.20) bits
 221 * to ethtool supported settings.
 222 */
 223static inline u32 mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap)
 224{
 225        u32 supported = 0;
 226
 227        if (eee_cap & MDIO_EEE_100TX)
 228                supported |= SUPPORTED_100baseT_Full;
 229        if (eee_cap & MDIO_EEE_1000T)
 230                supported |= SUPPORTED_1000baseT_Full;
 231        if (eee_cap & MDIO_EEE_10GT)
 232                supported |= SUPPORTED_10000baseT_Full;
 233        if (eee_cap & MDIO_EEE_1000KX)
 234                supported |= SUPPORTED_1000baseKX_Full;
 235        if (eee_cap & MDIO_EEE_10GKX4)
 236                supported |= SUPPORTED_10000baseKX4_Full;
 237        if (eee_cap & MDIO_EEE_10GKR)
 238                supported |= SUPPORTED_10000baseKR_Full;
 239
 240        return supported;
 241}
 242
 243/**
 244 * mmd_eee_adv_to_ethtool_adv_t
 245 * @eee_adv: value of the MMD EEE Advertisement/Link Partner Ability registers
 246 *
 247 * A small helper function that translates the MMD EEE Advertisment (7.60)
 248 * and MMD EEE Link Partner Ability (7.61) bits to ethtool advertisement
 249 * settings.
 250 */
 251static inline u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv)
 252{
 253        u32 adv = 0;
 254
 255        if (eee_adv & MDIO_EEE_100TX)
 256                adv |= ADVERTISED_100baseT_Full;
 257        if (eee_adv & MDIO_EEE_1000T)
 258                adv |= ADVERTISED_1000baseT_Full;
 259        if (eee_adv & MDIO_EEE_10GT)
 260                adv |= ADVERTISED_10000baseT_Full;
 261        if (eee_adv & MDIO_EEE_1000KX)
 262                adv |= ADVERTISED_1000baseKX_Full;
 263        if (eee_adv & MDIO_EEE_10GKX4)
 264                adv |= ADVERTISED_10000baseKX4_Full;
 265        if (eee_adv & MDIO_EEE_10GKR)
 266                adv |= ADVERTISED_10000baseKR_Full;
 267
 268        return adv;
 269}
 270
 271/**
 272 * ethtool_adv_to_mmd_eee_adv_t
 273 * @adv: the ethtool advertisement settings
 274 *
 275 * A small helper function that translates ethtool advertisement settings
 276 * to EEE advertisements for the MMD EEE Advertisement (7.60) and
 277 * MMD EEE Link Partner Ability (7.61) registers.
 278 */
 279static inline u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv)
 280{
 281        u16 reg = 0;
 282
 283        if (adv & ADVERTISED_100baseT_Full)
 284                reg |= MDIO_EEE_100TX;
 285        if (adv & ADVERTISED_1000baseT_Full)
 286                reg |= MDIO_EEE_1000T;
 287        if (adv & ADVERTISED_10000baseT_Full)
 288                reg |= MDIO_EEE_10GT;
 289        if (adv & ADVERTISED_1000baseKX_Full)
 290                reg |= MDIO_EEE_1000KX;
 291        if (adv & ADVERTISED_10000baseKX4_Full)
 292                reg |= MDIO_EEE_10GKX4;
 293        if (adv & ADVERTISED_10000baseKR_Full)
 294                reg |= MDIO_EEE_10GKR;
 295
 296        return reg;
 297}
 298
 299/**
 300 * linkmode_adv_to_mii_10gbt_adv_t
 301 * @advertising: the linkmode advertisement settings
 302 *
 303 * A small helper function that translates linkmode advertisement
 304 * settings to phy autonegotiation advertisements for the C45
 305 * 10GBASE-T AN CONTROL (7.32) register.
 306 */
 307static inline u32 linkmode_adv_to_mii_10gbt_adv_t(unsigned long *advertising)
 308{
 309        u32 result = 0;
 310
 311        if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
 312                              advertising))
 313                result |= MDIO_AN_10GBT_CTRL_ADV2_5G;
 314        if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
 315                              advertising))
 316                result |= MDIO_AN_10GBT_CTRL_ADV5G;
 317        if (linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
 318                              advertising))
 319                result |= MDIO_AN_10GBT_CTRL_ADV10G;
 320
 321        return result;
 322}
 323
 324/**
 325 * mii_10gbt_stat_mod_linkmode_lpa_t
 326 * @advertising: target the linkmode advertisement settings
 327 * @lpa: value of the C45 10GBASE-T AN STATUS register
 328 *
 329 * A small helper function that translates C45 10GBASE-T AN STATUS register bits
 330 * to linkmode advertisement settings. Other bits in advertising aren't changed.
 331 */
 332static inline void mii_10gbt_stat_mod_linkmode_lpa_t(unsigned long *advertising,
 333                                                     u32 lpa)
 334{
 335        linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
 336                         advertising, lpa & MDIO_AN_10GBT_STAT_LP2_5G);
 337        linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
 338                         advertising, lpa & MDIO_AN_10GBT_STAT_LP5G);
 339        linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
 340                         advertising, lpa & MDIO_AN_10GBT_STAT_LP10G);
 341}
 342
 343int __mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
 344int __mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
 345int __mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum,
 346                             u16 mask, u16 set);
 347
 348int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
 349int mdiobus_read_nested(struct mii_bus *bus, int addr, u32 regnum);
 350int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
 351int mdiobus_write_nested(struct mii_bus *bus, int addr, u32 regnum, u16 val);
 352int mdiobus_modify(struct mii_bus *bus, int addr, u32 regnum, u16 mask,
 353                   u16 set);
 354int mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum,
 355                           u16 mask, u16 set);
 356
 357static inline int mdiodev_read(struct mdio_device *mdiodev, u32 regnum)
 358{
 359        return mdiobus_read(mdiodev->bus, mdiodev->addr, regnum);
 360}
 361
 362static inline int mdiodev_write(struct mdio_device *mdiodev, u32 regnum,
 363                                u16 val)
 364{
 365        return mdiobus_write(mdiodev->bus, mdiodev->addr, regnum, val);
 366}
 367
 368static inline int mdiodev_modify(struct mdio_device *mdiodev, u32 regnum,
 369                                 u16 mask, u16 set)
 370{
 371        return mdiobus_modify(mdiodev->bus, mdiodev->addr, regnum, mask, set);
 372}
 373
 374static inline int mdiodev_modify_changed(struct mdio_device *mdiodev,
 375                                         u32 regnum, u16 mask, u16 set)
 376{
 377        return mdiobus_modify_changed(mdiodev->bus, mdiodev->addr, regnum,
 378                                      mask, set);
 379}
 380
 381static inline u32 mdiobus_c45_addr(int devad, u16 regnum)
 382{
 383        return MII_ADDR_C45 | devad << MII_DEVADDR_C45_SHIFT | regnum;
 384}
 385
 386static inline u16 mdiobus_c45_regad(u32 regnum)
 387{
 388        return FIELD_GET(MII_REGADDR_C45_MASK, regnum);
 389}
 390
 391static inline u16 mdiobus_c45_devad(u32 regnum)
 392{
 393        return FIELD_GET(MII_DEVADDR_C45_MASK, regnum);
 394}
 395
 396static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
 397                                     u16 regnum)
 398{
 399        return __mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum));
 400}
 401
 402static inline int __mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad,
 403                                      u16 regnum, u16 val)
 404{
 405        return __mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum),
 406                               val);
 407}
 408
 409static inline int mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
 410                                   u16 regnum)
 411{
 412        return mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum));
 413}
 414
 415static inline int mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad,
 416                                    u16 regnum, u16 val)
 417{
 418        return mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum), val);
 419}
 420
 421int mdiobus_register_device(struct mdio_device *mdiodev);
 422int mdiobus_unregister_device(struct mdio_device *mdiodev);
 423bool mdiobus_is_registered_device(struct mii_bus *bus, int addr);
 424struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr);
 425
 426/**
 427 * mdio_module_driver() - Helper macro for registering mdio drivers
 428 * @_mdio_driver: driver to register
 429 *
 430 * Helper macro for MDIO drivers which do not do anything special in module
 431 * init/exit. Each module may only use this macro once, and calling it
 432 * replaces module_init() and module_exit().
 433 */
 434#define mdio_module_driver(_mdio_driver)                                \
 435static int __init mdio_module_init(void)                                \
 436{                                                                       \
 437        return mdio_driver_register(&_mdio_driver);                     \
 438}                                                                       \
 439module_init(mdio_module_init);                                          \
 440static void __exit mdio_module_exit(void)                               \
 441{                                                                       \
 442        mdio_driver_unregister(&_mdio_driver);                          \
 443}                                                                       \
 444module_exit(mdio_module_exit)
 445
 446#endif /* __LINUX_MDIO_H__ */
 447