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