linux/drivers/net/ethernet/intel/igc/igc_phy.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright (c)  2018 Intel Corporation */
   3
   4#include "igc_phy.h"
   5
   6/**
   7 * igc_check_reset_block - Check if PHY reset is blocked
   8 * @hw: pointer to the HW structure
   9 *
  10 * Read the PHY management control register and check whether a PHY reset
  11 * is blocked.  If a reset is not blocked return 0, otherwise
  12 * return IGC_ERR_BLK_PHY_RESET (12).
  13 */
  14s32 igc_check_reset_block(struct igc_hw *hw)
  15{
  16        u32 manc;
  17
  18        manc = rd32(IGC_MANC);
  19
  20        return (manc & IGC_MANC_BLK_PHY_RST_ON_IDE) ?
  21                IGC_ERR_BLK_PHY_RESET : 0;
  22}
  23
  24/**
  25 * igc_get_phy_id - Retrieve the PHY ID and revision
  26 * @hw: pointer to the HW structure
  27 *
  28 * Reads the PHY registers and stores the PHY ID and possibly the PHY
  29 * revision in the hardware structure.
  30 */
  31s32 igc_get_phy_id(struct igc_hw *hw)
  32{
  33        struct igc_phy_info *phy = &hw->phy;
  34        s32 ret_val = 0;
  35        u16 phy_id;
  36
  37        ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
  38        if (ret_val)
  39                goto out;
  40
  41        phy->id = (u32)(phy_id << 16);
  42        usleep_range(200, 500);
  43        ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
  44        if (ret_val)
  45                goto out;
  46
  47        phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
  48        phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
  49
  50out:
  51        return ret_val;
  52}
  53
  54/**
  55 * igc_phy_has_link - Polls PHY for link
  56 * @hw: pointer to the HW structure
  57 * @iterations: number of times to poll for link
  58 * @usec_interval: delay between polling attempts
  59 * @success: pointer to whether polling was successful or not
  60 *
  61 * Polls the PHY status register for link, 'iterations' number of times.
  62 */
  63s32 igc_phy_has_link(struct igc_hw *hw, u32 iterations,
  64                     u32 usec_interval, bool *success)
  65{
  66        u16 i, phy_status;
  67        s32 ret_val = 0;
  68
  69        for (i = 0; i < iterations; i++) {
  70                /* Some PHYs require the PHY_STATUS register to be read
  71                 * twice due to the link bit being sticky.  No harm doing
  72                 * it across the board.
  73                 */
  74                ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
  75                if (ret_val && usec_interval > 0) {
  76                        /* If the first read fails, another entity may have
  77                         * ownership of the resources, wait and try again to
  78                         * see if they have relinquished the resources yet.
  79                         */
  80                        if (usec_interval >= 1000)
  81                                mdelay(usec_interval / 1000);
  82                        else
  83                                udelay(usec_interval);
  84                }
  85                ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
  86                if (ret_val)
  87                        break;
  88                if (phy_status & MII_SR_LINK_STATUS)
  89                        break;
  90                if (usec_interval >= 1000)
  91                        mdelay(usec_interval / 1000);
  92                else
  93                        udelay(usec_interval);
  94        }
  95
  96        *success = (i < iterations) ? true : false;
  97
  98        return ret_val;
  99}
 100
 101/**
 102 * igc_power_up_phy_copper - Restore copper link in case of PHY power down
 103 * @hw: pointer to the HW structure
 104 *
 105 * In the case of a PHY power down to save power, or to turn off link during a
 106 * driver unload, restore the link to previous settings.
 107 */
 108void igc_power_up_phy_copper(struct igc_hw *hw)
 109{
 110        u16 mii_reg = 0;
 111
 112        /* The PHY will retain its settings across a power down/up cycle */
 113        hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
 114        mii_reg &= ~MII_CR_POWER_DOWN;
 115        hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
 116}
 117
 118/**
 119 * igc_power_down_phy_copper - Power down copper PHY
 120 * @hw: pointer to the HW structure
 121 *
 122 * Power down PHY to save power when interface is down and wake on lan
 123 * is not enabled.
 124 */
 125void igc_power_down_phy_copper(struct igc_hw *hw)
 126{
 127        u16 mii_reg = 0;
 128
 129        /* The PHY will retain its settings across a power down/up cycle */
 130        hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
 131        mii_reg |= MII_CR_POWER_DOWN;
 132
 133        /* Temporary workaround - should be removed when PHY will implement
 134         * IEEE registers as properly
 135         */
 136        /* hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);*/
 137        usleep_range(1000, 2000);
 138}
 139
 140/**
 141 * igc_check_downshift - Checks whether a downshift in speed occurred
 142 * @hw: pointer to the HW structure
 143 *
 144 * Success returns 0, Failure returns 1
 145 *
 146 * A downshift is detected by querying the PHY link health.
 147 */
 148s32 igc_check_downshift(struct igc_hw *hw)
 149{
 150        struct igc_phy_info *phy = &hw->phy;
 151        s32 ret_val;
 152
 153        switch (phy->type) {
 154        case igc_phy_i225:
 155        default:
 156                /* speed downshift not supported */
 157                phy->speed_downgraded = false;
 158                ret_val = 0;
 159        }
 160
 161        return ret_val;
 162}
 163
 164/**
 165 * igc_phy_hw_reset - PHY hardware reset
 166 * @hw: pointer to the HW structure
 167 *
 168 * Verify the reset block is not blocking us from resetting.  Acquire
 169 * semaphore (if necessary) and read/set/write the device control reset
 170 * bit in the PHY.  Wait the appropriate delay time for the device to
 171 * reset and release the semaphore (if necessary).
 172 */
 173s32 igc_phy_hw_reset(struct igc_hw *hw)
 174{
 175        struct igc_phy_info *phy = &hw->phy;
 176        u32 phpm = 0, timeout = 10000;
 177        s32  ret_val;
 178        u32 ctrl;
 179
 180        ret_val = igc_check_reset_block(hw);
 181        if (ret_val) {
 182                ret_val = 0;
 183                goto out;
 184        }
 185
 186        ret_val = phy->ops.acquire(hw);
 187        if (ret_val)
 188                goto out;
 189
 190        phpm = rd32(IGC_I225_PHPM);
 191
 192        ctrl = rd32(IGC_CTRL);
 193        wr32(IGC_CTRL, ctrl | IGC_CTRL_PHY_RST);
 194        wrfl();
 195
 196        udelay(phy->reset_delay_us);
 197
 198        wr32(IGC_CTRL, ctrl);
 199        wrfl();
 200
 201        /* SW should guarantee 100us for the completion of the PHY reset */
 202        usleep_range(100, 150);
 203        do {
 204                phpm = rd32(IGC_I225_PHPM);
 205                timeout--;
 206                udelay(1);
 207        } while (!(phpm & IGC_PHY_RST_COMP) && timeout);
 208
 209        if (!timeout)
 210                hw_dbg("Timeout is expired after a phy reset\n");
 211
 212        usleep_range(100, 150);
 213
 214        phy->ops.release(hw);
 215
 216out:
 217        return ret_val;
 218}
 219
 220/**
 221 * igc_phy_setup_autoneg - Configure PHY for auto-negotiation
 222 * @hw: pointer to the HW structure
 223 *
 224 * Reads the MII auto-neg advertisement register and/or the 1000T control
 225 * register and if the PHY is already setup for auto-negotiation, then
 226 * return successful.  Otherwise, setup advertisement and flow control to
 227 * the appropriate values for the wanted auto-negotiation.
 228 */
 229static s32 igc_phy_setup_autoneg(struct igc_hw *hw)
 230{
 231        struct igc_phy_info *phy = &hw->phy;
 232        u16 aneg_multigbt_an_ctrl = 0;
 233        u16 mii_1000t_ctrl_reg = 0;
 234        u16 mii_autoneg_adv_reg;
 235        s32 ret_val;
 236
 237        phy->autoneg_advertised &= phy->autoneg_mask;
 238
 239        /* Read the MII Auto-Neg Advertisement Register (Address 4). */
 240        ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
 241        if (ret_val)
 242                return ret_val;
 243
 244        if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
 245                /* Read the MII 1000Base-T Control Register (Address 9). */
 246                ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
 247                                            &mii_1000t_ctrl_reg);
 248                if (ret_val)
 249                        return ret_val;
 250        }
 251
 252        if ((phy->autoneg_mask & ADVERTISE_2500_FULL) &&
 253            hw->phy.id == I225_I_PHY_ID) {
 254                /* Read the MULTI GBT AN Control Register - reg 7.32 */
 255                ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
 256                                            MMD_DEVADDR_SHIFT) |
 257                                            ANEG_MULTIGBT_AN_CTRL,
 258                                            &aneg_multigbt_an_ctrl);
 259
 260                if (ret_val)
 261                        return ret_val;
 262        }
 263
 264        /* Need to parse both autoneg_advertised and fc and set up
 265         * the appropriate PHY registers.  First we will parse for
 266         * autoneg_advertised software override.  Since we can advertise
 267         * a plethora of combinations, we need to check each bit
 268         * individually.
 269         */
 270
 271        /* First we clear all the 10/100 mb speed bits in the Auto-Neg
 272         * Advertisement Register (Address 4) and the 1000 mb speed bits in
 273         * the  1000Base-T Control Register (Address 9).
 274         */
 275        mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS |
 276                                 NWAY_AR_100TX_HD_CAPS |
 277                                 NWAY_AR_10T_FD_CAPS   |
 278                                 NWAY_AR_10T_HD_CAPS);
 279        mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
 280
 281        hw_dbg("autoneg_advertised %x\n", phy->autoneg_advertised);
 282
 283        /* Do we want to advertise 10 Mb Half Duplex? */
 284        if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
 285                hw_dbg("Advertise 10mb Half duplex\n");
 286                mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
 287        }
 288
 289        /* Do we want to advertise 10 Mb Full Duplex? */
 290        if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
 291                hw_dbg("Advertise 10mb Full duplex\n");
 292                mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
 293        }
 294
 295        /* Do we want to advertise 100 Mb Half Duplex? */
 296        if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
 297                hw_dbg("Advertise 100mb Half duplex\n");
 298                mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
 299        }
 300
 301        /* Do we want to advertise 100 Mb Full Duplex? */
 302        if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
 303                hw_dbg("Advertise 100mb Full duplex\n");
 304                mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
 305        }
 306
 307        /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
 308        if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
 309                hw_dbg("Advertise 1000mb Half duplex request denied!\n");
 310
 311        /* Do we want to advertise 1000 Mb Full Duplex? */
 312        if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
 313                hw_dbg("Advertise 1000mb Full duplex\n");
 314                mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
 315        }
 316
 317        /* We do not allow the Phy to advertise 2500 Mb Half Duplex */
 318        if (phy->autoneg_advertised & ADVERTISE_2500_HALF)
 319                hw_dbg("Advertise 2500mb Half duplex request denied!\n");
 320
 321        /* Do we want to advertise 2500 Mb Full Duplex? */
 322        if (phy->autoneg_advertised & ADVERTISE_2500_FULL) {
 323                hw_dbg("Advertise 2500mb Full duplex\n");
 324                aneg_multigbt_an_ctrl |= CR_2500T_FD_CAPS;
 325        } else {
 326                aneg_multigbt_an_ctrl &= ~CR_2500T_FD_CAPS;
 327        }
 328
 329        /* Check for a software override of the flow control settings, and
 330         * setup the PHY advertisement registers accordingly.  If
 331         * auto-negotiation is enabled, then software will have to set the
 332         * "PAUSE" bits to the correct value in the Auto-Negotiation
 333         * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
 334         * negotiation.
 335         *
 336         * The possible values of the "fc" parameter are:
 337         *      0:  Flow control is completely disabled
 338         *      1:  Rx flow control is enabled (we can receive pause frames
 339         *          but not send pause frames).
 340         *      2:  Tx flow control is enabled (we can send pause frames
 341         *          but we do not support receiving pause frames).
 342         *      3:  Both Rx and Tx flow control (symmetric) are enabled.
 343         *  other:  No software override.  The flow control configuration
 344         *          in the EEPROM is used.
 345         */
 346        switch (hw->fc.current_mode) {
 347        case igc_fc_none:
 348                /* Flow control (Rx & Tx) is completely disabled by a
 349                 * software over-ride.
 350                 */
 351                mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
 352                break;
 353        case igc_fc_rx_pause:
 354                /* Rx Flow control is enabled, and Tx Flow control is
 355                 * disabled, by a software over-ride.
 356                 *
 357                 * Since there really isn't a way to advertise that we are
 358                 * capable of Rx Pause ONLY, we will advertise that we
 359                 * support both symmetric and asymmetric Rx PAUSE.  Later
 360                 * (in igc_config_fc_after_link_up) we will disable the
 361                 * hw's ability to send PAUSE frames.
 362                 */
 363                mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
 364                break;
 365        case igc_fc_tx_pause:
 366                /* Tx Flow control is enabled, and Rx Flow control is
 367                 * disabled, by a software over-ride.
 368                 */
 369                mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
 370                mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
 371                break;
 372        case igc_fc_full:
 373                /* Flow control (both Rx and Tx) is enabled by a software
 374                 * over-ride.
 375                 */
 376                mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
 377                break;
 378        default:
 379                hw_dbg("Flow control param set incorrectly\n");
 380                return -IGC_ERR_CONFIG;
 381        }
 382
 383        ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
 384        if (ret_val)
 385                return ret_val;
 386
 387        hw_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
 388
 389        if (phy->autoneg_mask & ADVERTISE_1000_FULL)
 390                ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL,
 391                                             mii_1000t_ctrl_reg);
 392
 393        if ((phy->autoneg_mask & ADVERTISE_2500_FULL) &&
 394            hw->phy.id == I225_I_PHY_ID)
 395                ret_val = phy->ops.write_reg(hw,
 396                                             (STANDARD_AN_REG_MASK <<
 397                                             MMD_DEVADDR_SHIFT) |
 398                                             ANEG_MULTIGBT_AN_CTRL,
 399                                             aneg_multigbt_an_ctrl);
 400
 401        return ret_val;
 402}
 403
 404/**
 405 * igc_wait_autoneg - Wait for auto-neg completion
 406 * @hw: pointer to the HW structure
 407 *
 408 * Waits for auto-negotiation to complete or for the auto-negotiation time
 409 * limit to expire, which ever happens first.
 410 */
 411static s32 igc_wait_autoneg(struct igc_hw *hw)
 412{
 413        u16 i, phy_status;
 414        s32 ret_val = 0;
 415
 416        /* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
 417        for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
 418                ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
 419                if (ret_val)
 420                        break;
 421                ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
 422                if (ret_val)
 423                        break;
 424                if (phy_status & MII_SR_AUTONEG_COMPLETE)
 425                        break;
 426                msleep(100);
 427        }
 428
 429        /* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
 430         * has completed.
 431         */
 432        return ret_val;
 433}
 434
 435/**
 436 * igc_copper_link_autoneg - Setup/Enable autoneg for copper link
 437 * @hw: pointer to the HW structure
 438 *
 439 * Performs initial bounds checking on autoneg advertisement parameter, then
 440 * configure to advertise the full capability.  Setup the PHY to autoneg
 441 * and restart the negotiation process between the link partner.  If
 442 * autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
 443 */
 444static s32 igc_copper_link_autoneg(struct igc_hw *hw)
 445{
 446        struct igc_phy_info *phy = &hw->phy;
 447        u16 phy_ctrl;
 448        s32 ret_val;
 449
 450        /* Perform some bounds checking on the autoneg advertisement
 451         * parameter.
 452         */
 453        phy->autoneg_advertised &= phy->autoneg_mask;
 454
 455        /* If autoneg_advertised is zero, we assume it was not defaulted
 456         * by the calling code so we set to advertise full capability.
 457         */
 458        if (phy->autoneg_advertised == 0)
 459                phy->autoneg_advertised = phy->autoneg_mask;
 460
 461        hw_dbg("Reconfiguring auto-neg advertisement params\n");
 462        ret_val = igc_phy_setup_autoneg(hw);
 463        if (ret_val) {
 464                hw_dbg("Error Setting up Auto-Negotiation\n");
 465                goto out;
 466        }
 467        hw_dbg("Restarting Auto-Neg\n");
 468
 469        /* Restart auto-negotiation by setting the Auto Neg Enable bit and
 470         * the Auto Neg Restart bit in the PHY control register.
 471         */
 472        ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
 473        if (ret_val)
 474                goto out;
 475
 476        phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
 477        ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
 478        if (ret_val)
 479                goto out;
 480
 481        /* Does the user want to wait for Auto-Neg to complete here, or
 482         * check at a later time (for example, callback routine).
 483         */
 484        if (phy->autoneg_wait_to_complete) {
 485                ret_val = igc_wait_autoneg(hw);
 486                if (ret_val) {
 487                        hw_dbg("Error while waiting for autoneg to complete\n");
 488                        goto out;
 489                }
 490        }
 491
 492        hw->mac.get_link_status = true;
 493
 494out:
 495        return ret_val;
 496}
 497
 498/**
 499 * igc_setup_copper_link - Configure copper link settings
 500 * @hw: pointer to the HW structure
 501 *
 502 * Calls the appropriate function to configure the link for auto-neg or forced
 503 * speed and duplex.  Then we check for link, once link is established calls
 504 * to configure collision distance and flow control are called.  If link is
 505 * not established, we return -IGC_ERR_PHY (-2).
 506 */
 507s32 igc_setup_copper_link(struct igc_hw *hw)
 508{
 509        s32 ret_val = 0;
 510        bool link;
 511
 512        if (hw->mac.autoneg) {
 513                /* Setup autoneg and flow control advertisement and perform
 514                 * autonegotiation.
 515                 */
 516                ret_val = igc_copper_link_autoneg(hw);
 517                if (ret_val)
 518                        goto out;
 519        } else {
 520                /* PHY will be set to 10H, 10F, 100H or 100F
 521                 * depending on user settings.
 522                 */
 523                hw_dbg("Forcing Speed and Duplex\n");
 524                ret_val = hw->phy.ops.force_speed_duplex(hw);
 525                if (ret_val) {
 526                        hw_dbg("Error Forcing Speed and Duplex\n");
 527                        goto out;
 528                }
 529        }
 530
 531        /* Check link status. Wait up to 100 microseconds for link to become
 532         * valid.
 533         */
 534        ret_val = igc_phy_has_link(hw, COPPER_LINK_UP_LIMIT, 10, &link);
 535        if (ret_val)
 536                goto out;
 537
 538        if (link) {
 539                hw_dbg("Valid link established!!!\n");
 540                igc_config_collision_dist(hw);
 541                ret_val = igc_config_fc_after_link_up(hw);
 542        } else {
 543                hw_dbg("Unable to establish link!!!\n");
 544        }
 545
 546out:
 547        return ret_val;
 548}
 549
 550/**
 551 * igc_read_phy_reg_mdic - Read MDI control register
 552 * @hw: pointer to the HW structure
 553 * @offset: register offset to be read
 554 * @data: pointer to the read data
 555 *
 556 * Reads the MDI control register in the PHY at offset and stores the
 557 * information read to data.
 558 */
 559static s32 igc_read_phy_reg_mdic(struct igc_hw *hw, u32 offset, u16 *data)
 560{
 561        struct igc_phy_info *phy = &hw->phy;
 562        u32 i, mdic = 0;
 563        s32 ret_val = 0;
 564
 565        if (offset > MAX_PHY_REG_ADDRESS) {
 566                hw_dbg("PHY Address %d is out of range\n", offset);
 567                ret_val = -IGC_ERR_PARAM;
 568                goto out;
 569        }
 570
 571        /* Set up Op-code, Phy Address, and register offset in the MDI
 572         * Control register.  The MAC will take care of interfacing with the
 573         * PHY to retrieve the desired data.
 574         */
 575        mdic = ((offset << IGC_MDIC_REG_SHIFT) |
 576                (phy->addr << IGC_MDIC_PHY_SHIFT) |
 577                (IGC_MDIC_OP_READ));
 578
 579        wr32(IGC_MDIC, mdic);
 580
 581        /* Poll the ready bit to see if the MDI read completed
 582         * Increasing the time out as testing showed failures with
 583         * the lower time out
 584         */
 585        for (i = 0; i < IGC_GEN_POLL_TIMEOUT; i++) {
 586                usleep_range(500, 1000);
 587                mdic = rd32(IGC_MDIC);
 588                if (mdic & IGC_MDIC_READY)
 589                        break;
 590        }
 591        if (!(mdic & IGC_MDIC_READY)) {
 592                hw_dbg("MDI Read did not complete\n");
 593                ret_val = -IGC_ERR_PHY;
 594                goto out;
 595        }
 596        if (mdic & IGC_MDIC_ERROR) {
 597                hw_dbg("MDI Error\n");
 598                ret_val = -IGC_ERR_PHY;
 599                goto out;
 600        }
 601        *data = (u16)mdic;
 602
 603out:
 604        return ret_val;
 605}
 606
 607/**
 608 * igc_write_phy_reg_mdic - Write MDI control register
 609 * @hw: pointer to the HW structure
 610 * @offset: register offset to write to
 611 * @data: data to write to register at offset
 612 *
 613 * Writes data to MDI control register in the PHY at offset.
 614 */
 615static s32 igc_write_phy_reg_mdic(struct igc_hw *hw, u32 offset, u16 data)
 616{
 617        struct igc_phy_info *phy = &hw->phy;
 618        u32 i, mdic = 0;
 619        s32 ret_val = 0;
 620
 621        if (offset > MAX_PHY_REG_ADDRESS) {
 622                hw_dbg("PHY Address %d is out of range\n", offset);
 623                ret_val = -IGC_ERR_PARAM;
 624                goto out;
 625        }
 626
 627        /* Set up Op-code, Phy Address, and register offset in the MDI
 628         * Control register.  The MAC will take care of interfacing with the
 629         * PHY to write the desired data.
 630         */
 631        mdic = (((u32)data) |
 632                (offset << IGC_MDIC_REG_SHIFT) |
 633                (phy->addr << IGC_MDIC_PHY_SHIFT) |
 634                (IGC_MDIC_OP_WRITE));
 635
 636        wr32(IGC_MDIC, mdic);
 637
 638        /* Poll the ready bit to see if the MDI read completed
 639         * Increasing the time out as testing showed failures with
 640         * the lower time out
 641         */
 642        for (i = 0; i < IGC_GEN_POLL_TIMEOUT; i++) {
 643                usleep_range(500, 1000);
 644                mdic = rd32(IGC_MDIC);
 645                if (mdic & IGC_MDIC_READY)
 646                        break;
 647        }
 648        if (!(mdic & IGC_MDIC_READY)) {
 649                hw_dbg("MDI Write did not complete\n");
 650                ret_val = -IGC_ERR_PHY;
 651                goto out;
 652        }
 653        if (mdic & IGC_MDIC_ERROR) {
 654                hw_dbg("MDI Error\n");
 655                ret_val = -IGC_ERR_PHY;
 656                goto out;
 657        }
 658
 659out:
 660        return ret_val;
 661}
 662
 663/**
 664 * __igc_access_xmdio_reg - Read/write XMDIO register
 665 * @hw: pointer to the HW structure
 666 * @address: XMDIO address to program
 667 * @dev_addr: device address to program
 668 * @data: pointer to value to read/write from/to the XMDIO address
 669 * @read: boolean flag to indicate read or write
 670 */
 671static s32 __igc_access_xmdio_reg(struct igc_hw *hw, u16 address,
 672                                  u8 dev_addr, u16 *data, bool read)
 673{
 674        s32 ret_val;
 675
 676        ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, dev_addr);
 677        if (ret_val)
 678                return ret_val;
 679
 680        ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, address);
 681        if (ret_val)
 682                return ret_val;
 683
 684        ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, IGC_MMDAC_FUNC_DATA |
 685                                        dev_addr);
 686        if (ret_val)
 687                return ret_val;
 688
 689        if (read)
 690                ret_val = hw->phy.ops.read_reg(hw, IGC_MMDAAD, data);
 691        else
 692                ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, *data);
 693        if (ret_val)
 694                return ret_val;
 695
 696        /* Recalibrate the device back to 0 */
 697        ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, 0);
 698        if (ret_val)
 699                return ret_val;
 700
 701        return ret_val;
 702}
 703
 704/**
 705 * igc_read_xmdio_reg - Read XMDIO register
 706 * @hw: pointer to the HW structure
 707 * @addr: XMDIO address to program
 708 * @dev_addr: device address to program
 709 * @data: value to be read from the EMI address
 710 */
 711static s32 igc_read_xmdio_reg(struct igc_hw *hw, u16 addr,
 712                              u8 dev_addr, u16 *data)
 713{
 714        return __igc_access_xmdio_reg(hw, addr, dev_addr, data, true);
 715}
 716
 717/**
 718 * igc_write_xmdio_reg - Write XMDIO register
 719 * @hw: pointer to the HW structure
 720 * @addr: XMDIO address to program
 721 * @dev_addr: device address to program
 722 * @data: value to be written to the XMDIO address
 723 */
 724static s32 igc_write_xmdio_reg(struct igc_hw *hw, u16 addr,
 725                               u8 dev_addr, u16 data)
 726{
 727        return __igc_access_xmdio_reg(hw, addr, dev_addr, &data, false);
 728}
 729
 730/**
 731 * igc_write_phy_reg_gpy - Write GPY PHY register
 732 * @hw: pointer to the HW structure
 733 * @offset: register offset to write to
 734 * @data: data to write at register offset
 735 *
 736 * Acquires semaphore, if necessary, then writes the data to PHY register
 737 * at the offset. Release any acquired semaphores before exiting.
 738 */
 739s32 igc_write_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 data)
 740{
 741        u8 dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
 742        s32 ret_val;
 743
 744        offset = offset & GPY_REG_MASK;
 745
 746        if (!dev_addr) {
 747                ret_val = hw->phy.ops.acquire(hw);
 748                if (ret_val)
 749                        return ret_val;
 750                ret_val = igc_write_phy_reg_mdic(hw, offset, data);
 751                if (ret_val)
 752                        return ret_val;
 753                hw->phy.ops.release(hw);
 754        } else {
 755                ret_val = igc_write_xmdio_reg(hw, (u16)offset, dev_addr,
 756                                              data);
 757        }
 758
 759        return ret_val;
 760}
 761
 762/**
 763 * igc_read_phy_reg_gpy - Read GPY PHY register
 764 * @hw: pointer to the HW structure
 765 * @offset: lower half is register offset to read to
 766 * upper half is MMD to use.
 767 * @data: data to read at register offset
 768 *
 769 * Acquires semaphore, if necessary, then reads the data in the PHY register
 770 * at the offset. Release any acquired semaphores before exiting.
 771 */
 772s32 igc_read_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 *data)
 773{
 774        u8 dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
 775        s32 ret_val;
 776
 777        offset = offset & GPY_REG_MASK;
 778
 779        if (!dev_addr) {
 780                ret_val = hw->phy.ops.acquire(hw);
 781                if (ret_val)
 782                        return ret_val;
 783                ret_val = igc_read_phy_reg_mdic(hw, offset, data);
 784                if (ret_val)
 785                        return ret_val;
 786                hw->phy.ops.release(hw);
 787        } else {
 788                ret_val = igc_read_xmdio_reg(hw, (u16)offset, dev_addr,
 789                                             data);
 790        }
 791
 792        return ret_val;
 793}
 794
 795/**
 796 * igc_read_phy_fw_version - Read gPHY firmware version
 797 * @hw: pointer to the HW structure
 798 */
 799u16 igc_read_phy_fw_version(struct igc_hw *hw)
 800{
 801        struct igc_phy_info *phy = &hw->phy;
 802        u16 gphy_version = 0;
 803        u16 ret_val;
 804
 805        /* NVM image version is reported as firmware version for i225 device */
 806        ret_val = phy->ops.read_reg(hw, IGC_GPHY_VERSION, &gphy_version);
 807        if (ret_val)
 808                hw_dbg("igc_phy: read wrong gphy version\n");
 809
 810        return gphy_version;
 811}
 812