linux/drivers/net/phy/phy-core.c
<<
>>
Prefs
   1/*
   2 * Core PHY library, taken from phy.c
   3 *
   4 * This program is free software; you can redistribute  it and/or modify it
   5 * under  the terms of  the GNU General  Public License as published by the
   6 * Free Software Foundation;  either version 2 of the  License, or (at your
   7 * option) any later version.
   8 */
   9#include <linux/export.h>
  10#include <linux/phy.h>
  11
  12static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
  13                             u16 regnum)
  14{
  15        /* Write the desired MMD Devad */
  16        __mdiobus_write(bus, phy_addr, MII_MMD_CTRL, devad);
  17
  18        /* Write the desired MMD register address */
  19        __mdiobus_write(bus, phy_addr, MII_MMD_DATA, regnum);
  20
  21        /* Select the Function : DATA with no post increment */
  22        __mdiobus_write(bus, phy_addr, MII_MMD_CTRL,
  23                        devad | MII_MMD_CTRL_NOINCR);
  24}
  25
  26/**
  27 * __phy_read_mmd - Convenience function for reading a register
  28 * from an MMD on a given PHY.
  29 * @phydev: The phy_device struct
  30 * @devad: The MMD to read from (0..31)
  31 * @regnum: The register on the MMD to read (0..65535)
  32 *
  33 * Same rules as for __phy_read();
  34 */
  35int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
  36{
  37        int val;
  38
  39        if (regnum > (u16)~0 || devad > 32)
  40                return -EINVAL;
  41
  42        if (phydev->drv->read_mmd) {
  43                val = phydev->drv->read_mmd(phydev, devad, regnum);
  44        } else if (phydev->is_c45) {
  45                u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
  46
  47                val = __mdiobus_read(phydev->mdio_bus, phydev->mdio_addr, addr);
  48        } else {
  49                struct mii_bus *bus = phydev->mdio_bus;
  50                int phy_addr = phydev->mdio_addr;
  51
  52                mmd_phy_indirect(bus, phy_addr, devad, regnum);
  53
  54                /* Read the content of the MMD's selected register */
  55                val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA);
  56        }
  57        return val;
  58}
  59EXPORT_SYMBOL(__phy_read_mmd);
  60
  61/**
  62 * phy_read_mmd - Convenience function for reading a register
  63 * from an MMD on a given PHY.
  64 * @phydev: The phy_device struct
  65 * @devad: The MMD to read from
  66 * @regnum: The register on the MMD to read
  67 *
  68 * Same rules as for phy_read();
  69 */
  70int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
  71{
  72        int ret;
  73
  74        mutex_lock(&phydev->mdio_bus->mdio_lock);
  75        ret = __phy_read_mmd(phydev, devad, regnum);
  76        mutex_unlock(&phydev->mdio_bus->mdio_lock);
  77
  78        return ret;
  79}
  80EXPORT_SYMBOL(phy_read_mmd);
  81
  82/**
  83 * __phy_write_mmd - Convenience function for writing a register
  84 * on an MMD on a given PHY.
  85 * @phydev: The phy_device struct
  86 * @devad: The MMD to read from
  87 * @regnum: The register on the MMD to read
  88 * @val: value to write to @regnum
  89 *
  90 * Same rules as for __phy_write();
  91 */
  92int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
  93{
  94        int ret;
  95
  96        if (regnum > (u16)~0 || devad > 32)
  97                return -EINVAL;
  98
  99        if (phydev->drv->write_mmd) {
 100                ret = phydev->drv->write_mmd(phydev, devad, regnum, val);
 101        } else if (phydev->is_c45) {
 102                u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
 103
 104                ret = __mdiobus_write(phydev->mdio_bus, phydev->mdio_addr,
 105                                      addr, val);
 106        } else {
 107                struct mii_bus *bus = phydev->mdio_bus;
 108                int phy_addr = phydev->mdio_addr;
 109
 110                mmd_phy_indirect(bus, phy_addr, devad, regnum);
 111
 112                /* Write the data into MMD's selected register */
 113                __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val);
 114
 115                ret = 0;
 116        }
 117        return ret;
 118}
 119EXPORT_SYMBOL(__phy_write_mmd);
 120
 121/**
 122 * phy_write_mmd - Convenience function for writing a register
 123 * on an MMD on a given PHY.
 124 * @phydev: The phy_device struct
 125 * @devad: The MMD to read from
 126 * @regnum: The register on the MMD to read
 127 * @val: value to write to @regnum
 128 *
 129 * Same rules as for phy_write();
 130 */
 131int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
 132{
 133        int ret;
 134
 135        mutex_lock(&phydev->mdio_bus->mdio_lock);
 136        ret = __phy_write_mmd(phydev, devad, regnum, val);
 137        mutex_unlock(&phydev->mdio_bus->mdio_lock);
 138
 139        return ret;
 140}
 141EXPORT_SYMBOL(phy_write_mmd);
 142
 143/**
 144 * __phy_modify_changed() - Convenience function for modifying a PHY register
 145 * @phydev: a pointer to a &struct phy_device
 146 * @regnum: register number
 147 * @mask: bit mask of bits to clear
 148 * @set: bit mask of bits to set
 149 *
 150 * Unlocked helper function which allows a PHY register to be modified as
 151 * new register value = (old register value & ~mask) | set
 152 *
 153 * Returns negative errno, 0 if there was no change, and 1 in case of change
 154 */
 155int __phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask,
 156                         u16 set)
 157{
 158        int new, ret;
 159
 160        ret = __phy_read(phydev, regnum);
 161        if (ret < 0)
 162                return ret;
 163
 164        new = (ret & ~mask) | set;
 165        if (new == ret)
 166                return 0;
 167
 168        ret = __phy_write(phydev, regnum, new);
 169
 170        return ret < 0 ? ret : 1;
 171}
 172EXPORT_SYMBOL_GPL(__phy_modify_changed);
 173
 174/**
 175 * phy_modify_changed - Function for modifying a PHY register
 176 * @phydev: the phy_device struct
 177 * @regnum: register number to modify
 178 * @mask: bit mask of bits to clear
 179 * @set: new value of bits set in mask to write to @regnum
 180 *
 181 * NOTE: MUST NOT be called from interrupt context,
 182 * because the bus read/write functions may wait for an interrupt
 183 * to conclude the operation.
 184 *
 185 * Returns negative errno, 0 if there was no change, and 1 in case of change
 186 */
 187int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
 188{
 189        int ret;
 190
 191        mutex_lock(&phydev->mdio_bus->mdio_lock);
 192        ret = __phy_modify_changed(phydev, regnum, mask, set);
 193        mutex_unlock(&phydev->mdio_bus->mdio_lock);
 194
 195        return ret;
 196}
 197EXPORT_SYMBOL_GPL(phy_modify_changed);
 198
 199/**
 200 * __phy_modify - Convenience function for modifying a PHY register
 201 * @phydev: the phy_device struct
 202 * @regnum: register number to modify
 203 * @mask: bit mask of bits to clear
 204 * @set: new value of bits set in mask to write to @regnum
 205 *
 206 * NOTE: MUST NOT be called from interrupt context,
 207 * because the bus read/write functions may wait for an interrupt
 208 * to conclude the operation.
 209 */
 210int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
 211{
 212        int ret;
 213
 214        ret = __phy_modify_changed(phydev, regnum, mask, set);
 215
 216        return ret < 0 ? ret : 0;
 217}
 218EXPORT_SYMBOL_GPL(__phy_modify);
 219
 220/**
 221 * phy_modify - Convenience function for modifying a given PHY register
 222 * @phydev: the phy_device struct
 223 * @regnum: register number to write
 224 * @mask: bit mask of bits to clear
 225 * @set: new value of bits set in mask to write to @regnum
 226 *
 227 * NOTE: MUST NOT be called from interrupt context,
 228 * because the bus read/write functions may wait for an interrupt
 229 * to conclude the operation.
 230 */
 231int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
 232{
 233        int ret;
 234
 235        mutex_lock(&phydev->mdio_bus->mdio_lock);
 236        ret = __phy_modify(phydev, regnum, mask, set);
 237        mutex_unlock(&phydev->mdio_bus->mdio_lock);
 238
 239        return ret;
 240}
 241EXPORT_SYMBOL_GPL(phy_modify);
 242
 243/**
 244 * __phy_modify_mmd_changed - Function for modifying a register on MMD
 245 * @phydev: the phy_device struct
 246 * @devad: the MMD containing register to modify
 247 * @regnum: register number to modify
 248 * @mask: bit mask of bits to clear
 249 * @set: new value of bits set in mask to write to @regnum
 250 *
 251 * Unlocked helper function which allows a MMD register to be modified as
 252 * new register value = (old register value & ~mask) | set
 253 *
 254 * Returns negative errno, 0 if there was no change, and 1 in case of change
 255 */
 256int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
 257                             u16 mask, u16 set)
 258{
 259        int new, ret;
 260
 261        ret = __phy_read_mmd(phydev, devad, regnum);
 262        if (ret < 0)
 263                return ret;
 264
 265        new = (ret & ~mask) | set;
 266        if (new == ret)
 267                return 0;
 268
 269        ret = __phy_write_mmd(phydev, devad, regnum, new);
 270
 271        return ret < 0 ? ret : 1;
 272}
 273EXPORT_SYMBOL_GPL(__phy_modify_mmd_changed);
 274
 275/**
 276 * phy_modify_mmd_changed - Function for modifying a register on MMD
 277 * @phydev: the phy_device struct
 278 * @devad: the MMD containing register to modify
 279 * @regnum: register number to modify
 280 * @mask: bit mask of bits to clear
 281 * @set: new value of bits set in mask to write to @regnum
 282 *
 283 * NOTE: MUST NOT be called from interrupt context,
 284 * because the bus read/write functions may wait for an interrupt
 285 * to conclude the operation.
 286 *
 287 * Returns negative errno, 0 if there was no change, and 1 in case of change
 288 */
 289int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
 290                           u16 mask, u16 set)
 291{
 292        int ret;
 293
 294        mutex_lock(&phydev->mdio_bus->mdio_lock);
 295        ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
 296        mutex_unlock(&phydev->mdio_bus->mdio_lock);
 297
 298        return ret;
 299}
 300EXPORT_SYMBOL_GPL(phy_modify_mmd_changed);
 301
 302/**
 303 * __phy_modify_mmd - Convenience function for modifying a register on MMD
 304 * @phydev: the phy_device struct
 305 * @devad: the MMD containing register to modify
 306 * @regnum: register number to modify
 307 * @mask: bit mask of bits to clear
 308 * @set: new value of bits set in mask to write to @regnum
 309 *
 310 * NOTE: MUST NOT be called from interrupt context,
 311 * because the bus read/write functions may wait for an interrupt
 312 * to conclude the operation.
 313 */
 314int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
 315                     u16 mask, u16 set)
 316{
 317        int ret;
 318
 319        ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
 320
 321        return ret < 0 ? ret : 0;
 322}
 323EXPORT_SYMBOL_GPL(__phy_modify_mmd);
 324
 325/**
 326 * phy_modify_mmd - Convenience function for modifying a register on MMD
 327 * @phydev: the phy_device struct
 328 * @devad: the MMD containing register to modify
 329 * @regnum: register number to modify
 330 * @mask: bit mask of bits to clear
 331 * @set: new value of bits set in mask to write to @regnum
 332 *
 333 * NOTE: MUST NOT be called from interrupt context,
 334 * because the bus read/write functions may wait for an interrupt
 335 * to conclude the operation.
 336 */
 337int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
 338                   u16 mask, u16 set)
 339{
 340        int ret;
 341
 342        mutex_lock(&phydev->mdio_bus->mdio_lock);
 343        ret = __phy_modify_mmd(phydev, devad, regnum, mask, set);
 344        mutex_unlock(&phydev->mdio_bus->mdio_lock);
 345
 346        return ret;
 347}
 348EXPORT_SYMBOL_GPL(phy_modify_mmd);
 349
 350static int __phy_read_page(struct phy_device *phydev)
 351{
 352        return phydev->drv->read_page(phydev);
 353}
 354
 355static int __phy_write_page(struct phy_device *phydev, int page)
 356{
 357        return phydev->drv->write_page(phydev, page);
 358}
 359
 360/**
 361 * phy_save_page() - take the bus lock and save the current page
 362 * @phydev: a pointer to a &struct phy_device
 363 *
 364 * Take the MDIO bus lock, and return the current page number. On error,
 365 * returns a negative errno. phy_restore_page() must always be called
 366 * after this, irrespective of success or failure of this call.
 367 */
 368int phy_save_page(struct phy_device *phydev)
 369{
 370        mutex_lock(&phydev->mdio_bus->mdio_lock);
 371        return __phy_read_page(phydev);
 372}
 373EXPORT_SYMBOL_GPL(phy_save_page);
 374
 375/**
 376 * phy_select_page() - take the bus lock, save the current page, and set a page
 377 * @phydev: a pointer to a &struct phy_device
 378 * @page: desired page
 379 *
 380 * Take the MDIO bus lock to protect against concurrent access, save the
 381 * current PHY page, and set the current page.  On error, returns a
 382 * negative errno, otherwise returns the previous page number.
 383 * phy_restore_page() must always be called after this, irrespective
 384 * of success or failure of this call.
 385 */
 386int phy_select_page(struct phy_device *phydev, int page)
 387{
 388        int ret, oldpage;
 389
 390        oldpage = ret = phy_save_page(phydev);
 391        if (ret < 0)
 392                return ret;
 393
 394        if (oldpage != page) {
 395                ret = __phy_write_page(phydev, page);
 396                if (ret < 0)
 397                        return ret;
 398        }
 399
 400        return oldpage;
 401}
 402EXPORT_SYMBOL_GPL(phy_select_page);
 403
 404/**
 405 * phy_restore_page() - restore the page register and release the bus lock
 406 * @phydev: a pointer to a &struct phy_device
 407 * @oldpage: the old page, return value from phy_save_page() or phy_select_page()
 408 * @ret: operation's return code
 409 *
 410 * Release the MDIO bus lock, restoring @oldpage if it is a valid page.
 411 * This function propagates the earliest error code from the group of
 412 * operations.
 413 *
 414 * Returns:
 415 *   @oldpage if it was a negative value, otherwise
 416 *   @ret if it was a negative errno value, otherwise
 417 *   phy_write_page()'s negative value if it were in error, otherwise
 418 *   @ret.
 419 */
 420int phy_restore_page(struct phy_device *phydev, int oldpage, int ret)
 421{
 422        int r;
 423
 424        if (oldpage >= 0) {
 425                r = __phy_write_page(phydev, oldpage);
 426
 427                /* Propagate the operation return code if the page write
 428                 * was successful.
 429                 */
 430                if (ret >= 0 && r < 0)
 431                        ret = r;
 432        } else {
 433                /* Propagate the phy page selection error code */
 434                ret = oldpage;
 435        }
 436
 437        mutex_unlock(&phydev->mdio_bus->mdio_lock);
 438
 439        return ret;
 440}
 441EXPORT_SYMBOL_GPL(phy_restore_page);
 442
 443/**
 444 * phy_read_paged() - Convenience function for reading a paged register
 445 * @phydev: a pointer to a &struct phy_device
 446 * @page: the page for the phy
 447 * @regnum: register number
 448 *
 449 * Same rules as for phy_read().
 450 */
 451int phy_read_paged(struct phy_device *phydev, int page, u32 regnum)
 452{
 453        int ret = 0, oldpage;
 454
 455        oldpage = phy_select_page(phydev, page);
 456        if (oldpage >= 0)
 457                ret = __phy_read(phydev, regnum);
 458
 459        return phy_restore_page(phydev, oldpage, ret);
 460}
 461EXPORT_SYMBOL(phy_read_paged);
 462
 463/**
 464 * phy_write_paged() - Convenience function for writing a paged register
 465 * @phydev: a pointer to a &struct phy_device
 466 * @page: the page for the phy
 467 * @regnum: register number
 468 * @val: value to write
 469 *
 470 * Same rules as for phy_write().
 471 */
 472int phy_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val)
 473{
 474        int ret = 0, oldpage;
 475
 476        oldpage = phy_select_page(phydev, page);
 477        if (oldpage >= 0)
 478                ret = __phy_write(phydev, regnum, val);
 479
 480        return phy_restore_page(phydev, oldpage, ret);
 481}
 482EXPORT_SYMBOL(phy_write_paged);
 483
 484/**
 485 * phy_modify_paged() - Convenience function for modifying a paged register
 486 * @phydev: a pointer to a &struct phy_device
 487 * @page: the page for the phy
 488 * @regnum: register number
 489 * @mask: bit mask of bits to clear
 490 * @set: bit mask of bits to set
 491 *
 492 * Same rules as for phy_read() and phy_write().
 493 */
 494int phy_modify_paged(struct phy_device *phydev, int page, u32 regnum,
 495                     u16 mask, u16 set)
 496{
 497        int ret = 0, oldpage;
 498
 499        oldpage = phy_select_page(phydev, page);
 500        if (oldpage >= 0)
 501                ret = __phy_modify(phydev, regnum, mask, set);
 502
 503        return phy_restore_page(phydev, oldpage, ret);
 504}
 505EXPORT_SYMBOL(phy_modify_paged);
 506