linux/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
<<
>>
Prefs
   1/*******************************************************************************
   2 *
   3 *  Intel 10 Gigabit PCI Express Linux driver
   4 *  Copyright(c) 1999 - 2016 Intel Corporation.
   5 *
   6 *  This program is free software; you can redistribute it and/or modify it
   7 *  under the terms and conditions of the GNU General Public License,
   8 *  version 2, as published by the Free Software Foundation.
   9 *
  10 *  This program is distributed in the hope it will be useful, but WITHOUT
  11 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 *  more details.
  14 *
  15 *  The full GNU General Public License is included in this distribution in
  16 *  the file called "COPYING".
  17 *
  18 *  Contact Information:
  19 *  Linux NICS <linux.nics@intel.com>
  20 *  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  21 *  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  22 *
  23 ******************************************************************************/
  24#include "ixgbe_x540.h"
  25#include "ixgbe_type.h"
  26#include "ixgbe_common.h"
  27#include "ixgbe_phy.h"
  28
  29static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *, ixgbe_link_speed);
  30static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *);
  31static void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *);
  32static void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *);
  33static s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *);
  34
  35static s32 ixgbe_get_invariants_X550_x(struct ixgbe_hw *hw)
  36{
  37        struct ixgbe_mac_info *mac = &hw->mac;
  38        struct ixgbe_phy_info *phy = &hw->phy;
  39        struct ixgbe_link_info *link = &hw->link;
  40
  41        /* Start with X540 invariants, since so simular */
  42        ixgbe_get_invariants_X540(hw);
  43
  44        if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
  45                phy->ops.set_phy_power = NULL;
  46
  47        link->addr = IXGBE_CS4227;
  48
  49        return 0;
  50}
  51
  52static s32 ixgbe_get_invariants_X550_a(struct ixgbe_hw *hw)
  53{
  54        struct ixgbe_mac_info *mac = &hw->mac;
  55        struct ixgbe_phy_info *phy = &hw->phy;
  56
  57        /* Start with X540 invariants, since so simular */
  58        ixgbe_get_invariants_X540(hw);
  59
  60        if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
  61                phy->ops.set_phy_power = NULL;
  62
  63        return 0;
  64}
  65
  66static s32 ixgbe_get_invariants_X550_a_fw(struct ixgbe_hw *hw)
  67{
  68        struct ixgbe_phy_info *phy = &hw->phy;
  69
  70        /* Start with X540 invariants, since so similar */
  71        ixgbe_get_invariants_X540(hw);
  72
  73        phy->ops.set_phy_power = NULL;
  74
  75        return 0;
  76}
  77
  78/** ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
  79 *  @hw: pointer to hardware structure
  80 **/
  81static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
  82{
  83        u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
  84
  85        if (hw->bus.lan_id) {
  86                esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
  87                esdp |= IXGBE_ESDP_SDP1_DIR;
  88        }
  89        esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
  90        IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
  91        IXGBE_WRITE_FLUSH(hw);
  92}
  93
  94/**
  95 * ixgbe_read_cs4227 - Read CS4227 register
  96 * @hw: pointer to hardware structure
  97 * @reg: register number to write
  98 * @value: pointer to receive value read
  99 *
 100 * Returns status code
 101 */
 102static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
 103{
 104        return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value);
 105}
 106
 107/**
 108 * ixgbe_write_cs4227 - Write CS4227 register
 109 * @hw: pointer to hardware structure
 110 * @reg: register number to write
 111 * @value: value to write to register
 112 *
 113 * Returns status code
 114 */
 115static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
 116{
 117        return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value);
 118}
 119
 120/**
 121 * ixgbe_read_pe - Read register from port expander
 122 * @hw: pointer to hardware structure
 123 * @reg: register number to read
 124 * @value: pointer to receive read value
 125 *
 126 * Returns status code
 127 */
 128static s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
 129{
 130        s32 status;
 131
 132        status = ixgbe_read_i2c_byte_generic_unlocked(hw, reg, IXGBE_PE, value);
 133        if (status)
 134                hw_err(hw, "port expander access failed with %d\n", status);
 135        return status;
 136}
 137
 138/**
 139 * ixgbe_write_pe - Write register to port expander
 140 * @hw: pointer to hardware structure
 141 * @reg: register number to write
 142 * @value: value to write
 143 *
 144 * Returns status code
 145 */
 146static s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
 147{
 148        s32 status;
 149
 150        status = ixgbe_write_i2c_byte_generic_unlocked(hw, reg, IXGBE_PE,
 151                                                       value);
 152        if (status)
 153                hw_err(hw, "port expander access failed with %d\n", status);
 154        return status;
 155}
 156
 157/**
 158 * ixgbe_reset_cs4227 - Reset CS4227 using port expander
 159 * @hw: pointer to hardware structure
 160 *
 161 * This function assumes that the caller has acquired the proper semaphore.
 162 * Returns error code
 163 */
 164static s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
 165{
 166        s32 status;
 167        u32 retry;
 168        u16 value;
 169        u8 reg;
 170
 171        /* Trigger hard reset. */
 172        status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
 173        if (status)
 174                return status;
 175        reg |= IXGBE_PE_BIT1;
 176        status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
 177        if (status)
 178                return status;
 179
 180        status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, &reg);
 181        if (status)
 182                return status;
 183        reg &= ~IXGBE_PE_BIT1;
 184        status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
 185        if (status)
 186                return status;
 187
 188        status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
 189        if (status)
 190                return status;
 191        reg &= ~IXGBE_PE_BIT1;
 192        status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
 193        if (status)
 194                return status;
 195
 196        usleep_range(IXGBE_CS4227_RESET_HOLD, IXGBE_CS4227_RESET_HOLD + 100);
 197
 198        status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
 199        if (status)
 200                return status;
 201        reg |= IXGBE_PE_BIT1;
 202        status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
 203        if (status)
 204                return status;
 205
 206        /* Wait for the reset to complete. */
 207        msleep(IXGBE_CS4227_RESET_DELAY);
 208        for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
 209                status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
 210                                           &value);
 211                if (!status && value == IXGBE_CS4227_EEPROM_LOAD_OK)
 212                        break;
 213                msleep(IXGBE_CS4227_CHECK_DELAY);
 214        }
 215        if (retry == IXGBE_CS4227_RETRIES) {
 216                hw_err(hw, "CS4227 reset did not complete\n");
 217                return IXGBE_ERR_PHY;
 218        }
 219
 220        status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
 221        if (status || !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
 222                hw_err(hw, "CS4227 EEPROM did not load successfully\n");
 223                return IXGBE_ERR_PHY;
 224        }
 225
 226        return 0;
 227}
 228
 229/**
 230 * ixgbe_check_cs4227 - Check CS4227 and reset as needed
 231 * @hw: pointer to hardware structure
 232 */
 233static void ixgbe_check_cs4227(struct ixgbe_hw *hw)
 234{
 235        u32 swfw_mask = hw->phy.phy_semaphore_mask;
 236        s32 status;
 237        u16 value;
 238        u8 retry;
 239
 240        for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
 241                status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
 242                if (status) {
 243                        hw_err(hw, "semaphore failed with %d\n", status);
 244                        msleep(IXGBE_CS4227_CHECK_DELAY);
 245                        continue;
 246                }
 247
 248                /* Get status of reset flow. */
 249                status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
 250                if (!status && value == IXGBE_CS4227_RESET_COMPLETE)
 251                        goto out;
 252
 253                if (status || value != IXGBE_CS4227_RESET_PENDING)
 254                        break;
 255
 256                /* Reset is pending. Wait and check again. */
 257                hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 258                msleep(IXGBE_CS4227_CHECK_DELAY);
 259        }
 260        /* If still pending, assume other instance failed. */
 261        if (retry == IXGBE_CS4227_RETRIES) {
 262                status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
 263                if (status) {
 264                        hw_err(hw, "semaphore failed with %d\n", status);
 265                        return;
 266                }
 267        }
 268
 269        /* Reset the CS4227. */
 270        status = ixgbe_reset_cs4227(hw);
 271        if (status) {
 272                hw_err(hw, "CS4227 reset failed: %d", status);
 273                goto out;
 274        }
 275
 276        /* Reset takes so long, temporarily release semaphore in case the
 277         * other driver instance is waiting for the reset indication.
 278         */
 279        ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
 280                           IXGBE_CS4227_RESET_PENDING);
 281        hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 282        usleep_range(10000, 12000);
 283        status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
 284        if (status) {
 285                hw_err(hw, "semaphore failed with %d", status);
 286                return;
 287        }
 288
 289        /* Record completion for next time. */
 290        status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
 291                                    IXGBE_CS4227_RESET_COMPLETE);
 292
 293out:
 294        hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 295        msleep(hw->eeprom.semaphore_delay);
 296}
 297
 298/** ixgbe_identify_phy_x550em - Get PHY type based on device id
 299 *  @hw: pointer to hardware structure
 300 *
 301 *  Returns error code
 302 */
 303static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
 304{
 305        switch (hw->device_id) {
 306        case IXGBE_DEV_ID_X550EM_A_SFP:
 307                if (hw->bus.lan_id)
 308                        hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
 309                else
 310                        hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
 311                return ixgbe_identify_module_generic(hw);
 312        case IXGBE_DEV_ID_X550EM_X_SFP:
 313                /* set up for CS4227 usage */
 314                hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
 315                ixgbe_setup_mux_ctl(hw);
 316                ixgbe_check_cs4227(hw);
 317                /* Fallthrough */
 318        case IXGBE_DEV_ID_X550EM_A_SFP_N:
 319                return ixgbe_identify_module_generic(hw);
 320        case IXGBE_DEV_ID_X550EM_X_KX4:
 321                hw->phy.type = ixgbe_phy_x550em_kx4;
 322                break;
 323        case IXGBE_DEV_ID_X550EM_X_KR:
 324        case IXGBE_DEV_ID_X550EM_A_KR:
 325        case IXGBE_DEV_ID_X550EM_A_KR_L:
 326                hw->phy.type = ixgbe_phy_x550em_kr;
 327                break;
 328        case IXGBE_DEV_ID_X550EM_A_10G_T:
 329                if (hw->bus.lan_id)
 330                        hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
 331                else
 332                        hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
 333                /* Fallthrough */
 334        case IXGBE_DEV_ID_X550EM_X_1G_T:
 335        case IXGBE_DEV_ID_X550EM_X_10G_T:
 336                return ixgbe_identify_phy_generic(hw);
 337        default:
 338                break;
 339        }
 340        return 0;
 341}
 342
 343static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
 344                                     u32 device_type, u16 *phy_data)
 345{
 346        return IXGBE_NOT_IMPLEMENTED;
 347}
 348
 349static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
 350                                      u32 device_type, u16 phy_data)
 351{
 352        return IXGBE_NOT_IMPLEMENTED;
 353}
 354
 355/**
 356 * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
 357 * @hw: pointer to the hardware structure
 358 * @addr: I2C bus address to read from
 359 * @reg: I2C device register to read from
 360 * @val: pointer to location to receive read value
 361 *
 362 * Returns an error code on error.
 363 **/
 364static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
 365                                           u16 reg, u16 *val)
 366{
 367        return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, true);
 368}
 369
 370/**
 371 * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation
 372 * @hw: pointer to the hardware structure
 373 * @addr: I2C bus address to read from
 374 * @reg: I2C device register to read from
 375 * @val: pointer to location to receive read value
 376 *
 377 * Returns an error code on error.
 378 **/
 379static s32
 380ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
 381                                         u16 reg, u16 *val)
 382{
 383        return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, false);
 384}
 385
 386/**
 387 * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
 388 * @hw: pointer to the hardware structure
 389 * @addr: I2C bus address to write to
 390 * @reg: I2C device register to write to
 391 * @val: value to write
 392 *
 393 * Returns an error code on error.
 394 **/
 395static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
 396                                            u8 addr, u16 reg, u16 val)
 397{
 398        return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, true);
 399}
 400
 401/**
 402 * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation
 403 * @hw: pointer to the hardware structure
 404 * @addr: I2C bus address to write to
 405 * @reg: I2C device register to write to
 406 * @val: value to write
 407 *
 408 * Returns an error code on error.
 409 **/
 410static s32
 411ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw,
 412                                          u8 addr, u16 reg, u16 val)
 413{
 414        return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, false);
 415}
 416
 417/**
 418 * ixgbe_fw_phy_activity - Perform an activity on a PHY
 419 * @hw: pointer to hardware structure
 420 * @activity: activity to perform
 421 * @data: Pointer to 4 32-bit words of data
 422 */
 423s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity,
 424                          u32 (*data)[FW_PHY_ACT_DATA_COUNT])
 425{
 426        union {
 427                struct ixgbe_hic_phy_activity_req cmd;
 428                struct ixgbe_hic_phy_activity_resp rsp;
 429        } hic;
 430        u16 retries = FW_PHY_ACT_RETRIES;
 431        s32 rc;
 432        u32 i;
 433
 434        do {
 435                memset(&hic, 0, sizeof(hic));
 436                hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD;
 437                hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN;
 438                hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
 439                hic.cmd.port_number = hw->bus.lan_id;
 440                hic.cmd.activity_id = cpu_to_le16(activity);
 441                for (i = 0; i < ARRAY_SIZE(hic.cmd.data); ++i)
 442                        hic.cmd.data[i] = cpu_to_be32((*data)[i]);
 443
 444                rc = ixgbe_host_interface_command(hw, &hic.cmd, sizeof(hic.cmd),
 445                                                  IXGBE_HI_COMMAND_TIMEOUT,
 446                                                  true);
 447                if (rc)
 448                        return rc;
 449                if (hic.rsp.hdr.cmd_or_resp.ret_status ==
 450                    FW_CEM_RESP_STATUS_SUCCESS) {
 451                        for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
 452                                (*data)[i] = be32_to_cpu(hic.rsp.data[i]);
 453                        return 0;
 454                }
 455                usleep_range(20, 30);
 456                --retries;
 457        } while (retries > 0);
 458
 459        return IXGBE_ERR_HOST_INTERFACE_COMMAND;
 460}
 461
 462static const struct {
 463        u16 fw_speed;
 464        ixgbe_link_speed phy_speed;
 465} ixgbe_fw_map[] = {
 466        { FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL },
 467        { FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL },
 468        { FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL },
 469        { FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL },
 470        { FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL },
 471        { FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL },
 472};
 473
 474/**
 475 * ixgbe_get_phy_id_fw - Get the phy ID via firmware command
 476 * @hw: pointer to hardware structure
 477 *
 478 * Returns error code
 479 */
 480static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw)
 481{
 482        u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
 483        u16 phy_speeds;
 484        u16 phy_id_lo;
 485        s32 rc;
 486        u16 i;
 487
 488        if (hw->phy.id)
 489                return 0;
 490
 491        rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info);
 492        if (rc)
 493                return rc;
 494
 495        hw->phy.speeds_supported = 0;
 496        phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK;
 497        for (i = 0; i < ARRAY_SIZE(ixgbe_fw_map); ++i) {
 498                if (phy_speeds & ixgbe_fw_map[i].fw_speed)
 499                        hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed;
 500        }
 501
 502        hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK;
 503        phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK;
 504        hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK;
 505        hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK;
 506        if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK)
 507                return IXGBE_ERR_PHY_ADDR_INVALID;
 508
 509        hw->phy.autoneg_advertised = hw->phy.speeds_supported;
 510        hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL |
 511                                       IXGBE_LINK_SPEED_1GB_FULL;
 512        hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
 513        return 0;
 514}
 515
 516/**
 517 * ixgbe_identify_phy_fw - Get PHY type based on firmware command
 518 * @hw: pointer to hardware structure
 519 *
 520 * Returns error code
 521 */
 522static s32 ixgbe_identify_phy_fw(struct ixgbe_hw *hw)
 523{
 524        if (hw->bus.lan_id)
 525                hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
 526        else
 527                hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
 528
 529        hw->phy.type = ixgbe_phy_fw;
 530        hw->phy.ops.read_reg = NULL;
 531        hw->phy.ops.write_reg = NULL;
 532        return ixgbe_get_phy_id_fw(hw);
 533}
 534
 535/**
 536 * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY
 537 * @hw: pointer to hardware structure
 538 *
 539 * Returns error code
 540 */
 541static s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw)
 542{
 543        u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
 544
 545        setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF;
 546        return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup);
 547}
 548
 549/**
 550 * ixgbe_setup_fw_link - Setup firmware-controlled PHYs
 551 * @hw: pointer to hardware structure
 552 */
 553static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw)
 554{
 555        u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
 556        s32 rc;
 557        u16 i;
 558
 559        if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
 560                return 0;
 561
 562        if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
 563                hw_err(hw, "rx_pause not valid in strict IEEE mode\n");
 564                return IXGBE_ERR_INVALID_LINK_SETTINGS;
 565        }
 566
 567        switch (hw->fc.requested_mode) {
 568        case ixgbe_fc_full:
 569                setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX <<
 570                            FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
 571                break;
 572        case ixgbe_fc_rx_pause:
 573                setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX <<
 574                            FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
 575                break;
 576        case ixgbe_fc_tx_pause:
 577                setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX <<
 578                            FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
 579                break;
 580        default:
 581                break;
 582        }
 583
 584        for (i = 0; i < ARRAY_SIZE(ixgbe_fw_map); ++i) {
 585                if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed)
 586                        setup[0] |= ixgbe_fw_map[i].fw_speed;
 587        }
 588        setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN;
 589
 590        if (hw->phy.eee_speeds_advertised)
 591                setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE;
 592
 593        rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup);
 594        if (rc)
 595                return rc;
 596        if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)
 597                return IXGBE_ERR_OVERTEMP;
 598        return 0;
 599}
 600
 601/**
 602 * ixgbe_fc_autoneg_fw - Set up flow control for FW-controlled PHYs
 603 * @hw: pointer to hardware structure
 604 *
 605 * Called at init time to set up flow control.
 606 */
 607static s32 ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw)
 608{
 609        if (hw->fc.requested_mode == ixgbe_fc_default)
 610                hw->fc.requested_mode = ixgbe_fc_full;
 611
 612        return ixgbe_setup_fw_link(hw);
 613}
 614
 615/** ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
 616 *  @hw: pointer to hardware structure
 617 *
 618 *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
 619 *  ixgbe_hw struct in order to set up EEPROM access.
 620 **/
 621static s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
 622{
 623        struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
 624        u32 eec;
 625        u16 eeprom_size;
 626
 627        if (eeprom->type == ixgbe_eeprom_uninitialized) {
 628                eeprom->semaphore_delay = 10;
 629                eeprom->type = ixgbe_flash;
 630
 631                eec = IXGBE_READ_REG(hw, IXGBE_EEC(hw));
 632                eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
 633                                    IXGBE_EEC_SIZE_SHIFT);
 634                eeprom->word_size = BIT(eeprom_size +
 635                                        IXGBE_EEPROM_WORD_SIZE_SHIFT);
 636
 637                hw_dbg(hw, "Eeprom params: type = %d, size = %d\n",
 638                       eeprom->type, eeprom->word_size);
 639        }
 640
 641        return 0;
 642}
 643
 644/**
 645 * ixgbe_iosf_wait - Wait for IOSF command completion
 646 * @hw: pointer to hardware structure
 647 * @ctrl: pointer to location to receive final IOSF control value
 648 *
 649 * Return: failing status on timeout
 650 *
 651 * Note: ctrl can be NULL if the IOSF control register value is not needed
 652 */
 653static s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl)
 654{
 655        u32 i, command;
 656
 657        /* Check every 10 usec to see if the address cycle completed.
 658         * The SB IOSF BUSY bit will clear when the operation is
 659         * complete.
 660         */
 661        for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
 662                command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
 663                if (!(command & IXGBE_SB_IOSF_CTRL_BUSY))
 664                        break;
 665                udelay(10);
 666        }
 667        if (ctrl)
 668                *ctrl = command;
 669        if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
 670                hw_dbg(hw, "IOSF wait timed out\n");
 671                return IXGBE_ERR_PHY;
 672        }
 673
 674        return 0;
 675}
 676
 677/** ixgbe_read_iosf_sb_reg_x550 - Writes a value to specified register of the
 678 *  IOSF device
 679 *  @hw: pointer to hardware structure
 680 *  @reg_addr: 32 bit PHY register to write
 681 *  @device_type: 3 bit device type
 682 *  @phy_data: Pointer to read data from the register
 683 **/
 684static s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
 685                                       u32 device_type, u32 *data)
 686{
 687        u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
 688        u32 command, error;
 689        s32 ret;
 690
 691        ret = hw->mac.ops.acquire_swfw_sync(hw, gssr);
 692        if (ret)
 693                return ret;
 694
 695        ret = ixgbe_iosf_wait(hw, NULL);
 696        if (ret)
 697                goto out;
 698
 699        command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
 700                   (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
 701
 702        /* Write IOSF control register */
 703        IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
 704
 705        ret = ixgbe_iosf_wait(hw, &command);
 706
 707        if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
 708                error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
 709                         IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
 710                hw_dbg(hw, "Failed to read, error %x\n", error);
 711                return IXGBE_ERR_PHY;
 712        }
 713
 714        if (!ret)
 715                *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
 716
 717out:
 718        hw->mac.ops.release_swfw_sync(hw, gssr);
 719        return ret;
 720}
 721
 722/**
 723 * ixgbe_get_phy_token - Get the token for shared PHY access
 724 * @hw: Pointer to hardware structure
 725 */
 726static s32 ixgbe_get_phy_token(struct ixgbe_hw *hw)
 727{
 728        struct ixgbe_hic_phy_token_req token_cmd;
 729        s32 status;
 730
 731        token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
 732        token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
 733        token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
 734        token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
 735        token_cmd.port_number = hw->bus.lan_id;
 736        token_cmd.command_type = FW_PHY_TOKEN_REQ;
 737        token_cmd.pad = 0;
 738        status = ixgbe_host_interface_command(hw, &token_cmd, sizeof(token_cmd),
 739                                              IXGBE_HI_COMMAND_TIMEOUT,
 740                                              true);
 741        if (status)
 742                return status;
 743        if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
 744                return 0;
 745        if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY)
 746                return IXGBE_ERR_FW_RESP_INVALID;
 747
 748        return IXGBE_ERR_TOKEN_RETRY;
 749}
 750
 751/**
 752 * ixgbe_put_phy_token - Put the token for shared PHY access
 753 * @hw: Pointer to hardware structure
 754 */
 755static s32 ixgbe_put_phy_token(struct ixgbe_hw *hw)
 756{
 757        struct ixgbe_hic_phy_token_req token_cmd;
 758        s32 status;
 759
 760        token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
 761        token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
 762        token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
 763        token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
 764        token_cmd.port_number = hw->bus.lan_id;
 765        token_cmd.command_type = FW_PHY_TOKEN_REL;
 766        token_cmd.pad = 0;
 767        status = ixgbe_host_interface_command(hw, &token_cmd, sizeof(token_cmd),
 768                                              IXGBE_HI_COMMAND_TIMEOUT,
 769                                              true);
 770        if (status)
 771                return status;
 772        if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
 773                return 0;
 774        return IXGBE_ERR_FW_RESP_INVALID;
 775}
 776
 777/**
 778 *  ixgbe_write_iosf_sb_reg_x550a - Write to IOSF PHY register
 779 *  @hw: pointer to hardware structure
 780 *  @reg_addr: 32 bit PHY register to write
 781 *  @device_type: 3 bit device type
 782 *  @data: Data to write to the register
 783 **/
 784static s32 ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
 785                                         __always_unused u32 device_type,
 786                                         u32 data)
 787{
 788        struct ixgbe_hic_internal_phy_req write_cmd;
 789
 790        memset(&write_cmd, 0, sizeof(write_cmd));
 791        write_cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
 792        write_cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
 793        write_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
 794        write_cmd.port_number = hw->bus.lan_id;
 795        write_cmd.command_type = FW_INT_PHY_REQ_WRITE;
 796        write_cmd.address = cpu_to_be16(reg_addr);
 797        write_cmd.write_data = cpu_to_be32(data);
 798
 799        return ixgbe_host_interface_command(hw, &write_cmd, sizeof(write_cmd),
 800                                            IXGBE_HI_COMMAND_TIMEOUT, false);
 801}
 802
 803/**
 804 *  ixgbe_read_iosf_sb_reg_x550a - Read from IOSF PHY register
 805 *  @hw: pointer to hardware structure
 806 *  @reg_addr: 32 bit PHY register to write
 807 *  @device_type: 3 bit device type
 808 *  @data: Pointer to read data from the register
 809 **/
 810static s32 ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
 811                                        __always_unused u32 device_type,
 812                                        u32 *data)
 813{
 814        union {
 815                struct ixgbe_hic_internal_phy_req cmd;
 816                struct ixgbe_hic_internal_phy_resp rsp;
 817        } hic;
 818        s32 status;
 819
 820        memset(&hic, 0, sizeof(hic));
 821        hic.cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
 822        hic.cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
 823        hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
 824        hic.cmd.port_number = hw->bus.lan_id;
 825        hic.cmd.command_type = FW_INT_PHY_REQ_READ;
 826        hic.cmd.address = cpu_to_be16(reg_addr);
 827
 828        status = ixgbe_host_interface_command(hw, &hic.cmd, sizeof(hic.cmd),
 829                                              IXGBE_HI_COMMAND_TIMEOUT, true);
 830
 831        /* Extract the register value from the response. */
 832        *data = be32_to_cpu(hic.rsp.read_data);
 833
 834        return status;
 835}
 836
 837/** ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
 838 *  @hw: pointer to hardware structure
 839 *  @offset: offset of  word in the EEPROM to read
 840 *  @words: number of words
 841 *  @data: word(s) read from the EEPROM
 842 *
 843 *  Reads a 16 bit word(s) from the EEPROM using the hostif.
 844 **/
 845static s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
 846                                            u16 offset, u16 words, u16 *data)
 847{
 848        const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
 849        struct ixgbe_hic_read_shadow_ram buffer;
 850        u32 current_word = 0;
 851        u16 words_to_read;
 852        s32 status;
 853        u32 i;
 854
 855        /* Take semaphore for the entire operation. */
 856        status = hw->mac.ops.acquire_swfw_sync(hw, mask);
 857        if (status) {
 858                hw_dbg(hw, "EEPROM read buffer - semaphore failed\n");
 859                return status;
 860        }
 861
 862        while (words) {
 863                if (words > FW_MAX_READ_BUFFER_SIZE / 2)
 864                        words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
 865                else
 866                        words_to_read = words;
 867
 868                buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
 869                buffer.hdr.req.buf_lenh = 0;
 870                buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
 871                buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
 872
 873                /* convert offset from words to bytes */
 874                buffer.address = cpu_to_be32((offset + current_word) * 2);
 875                buffer.length = cpu_to_be16(words_to_read * 2);
 876
 877                status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
 878                                            IXGBE_HI_COMMAND_TIMEOUT);
 879                if (status) {
 880                        hw_dbg(hw, "Host interface command failed\n");
 881                        goto out;
 882                }
 883
 884                for (i = 0; i < words_to_read; i++) {
 885                        u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
 886                                  2 * i;
 887                        u32 value = IXGBE_READ_REG(hw, reg);
 888
 889                        data[current_word] = (u16)(value & 0xffff);
 890                        current_word++;
 891                        i++;
 892                        if (i < words_to_read) {
 893                                value >>= 16;
 894                                data[current_word] = (u16)(value & 0xffff);
 895                                current_word++;
 896                        }
 897                }
 898                words -= words_to_read;
 899        }
 900
 901out:
 902        hw->mac.ops.release_swfw_sync(hw, mask);
 903        return status;
 904}
 905
 906/** ixgbe_checksum_ptr_x550 - Checksum one pointer region
 907 *  @hw: pointer to hardware structure
 908 *  @ptr: pointer offset in eeprom
 909 *  @size: size of section pointed by ptr, if 0 first word will be used as size
 910 *  @csum: address of checksum to update
 911 *
 912 *  Returns error status for any failure
 913 **/
 914static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
 915                                   u16 size, u16 *csum, u16 *buffer,
 916                                   u32 buffer_size)
 917{
 918        u16 buf[256];
 919        s32 status;
 920        u16 length, bufsz, i, start;
 921        u16 *local_buffer;
 922
 923        bufsz = sizeof(buf) / sizeof(buf[0]);
 924
 925        /* Read a chunk at the pointer location */
 926        if (!buffer) {
 927                status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
 928                if (status) {
 929                        hw_dbg(hw, "Failed to read EEPROM image\n");
 930                        return status;
 931                }
 932                local_buffer = buf;
 933        } else {
 934                if (buffer_size < ptr)
 935                        return  IXGBE_ERR_PARAM;
 936                local_buffer = &buffer[ptr];
 937        }
 938
 939        if (size) {
 940                start = 0;
 941                length = size;
 942        } else {
 943                start = 1;
 944                length = local_buffer[0];
 945
 946                /* Skip pointer section if length is invalid. */
 947                if (length == 0xFFFF || length == 0 ||
 948                    (ptr + length) >= hw->eeprom.word_size)
 949                        return 0;
 950        }
 951
 952        if (buffer && ((u32)start + (u32)length > buffer_size))
 953                return IXGBE_ERR_PARAM;
 954
 955        for (i = start; length; i++, length--) {
 956                if (i == bufsz && !buffer) {
 957                        ptr += bufsz;
 958                        i = 0;
 959                        if (length < bufsz)
 960                                bufsz = length;
 961
 962                        /* Read a chunk at the pointer location */
 963                        status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
 964                                                                  bufsz, buf);
 965                        if (status) {
 966                                hw_dbg(hw, "Failed to read EEPROM image\n");
 967                                return status;
 968                        }
 969                }
 970                *csum += local_buffer[i];
 971        }
 972        return 0;
 973}
 974
 975/** ixgbe_calc_checksum_X550 - Calculates and returns the checksum
 976 *  @hw: pointer to hardware structure
 977 *  @buffer: pointer to buffer containing calculated checksum
 978 *  @buffer_size: size of buffer
 979 *
 980 *  Returns a negative error code on error, or the 16-bit checksum
 981 **/
 982static s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer,
 983                                    u32 buffer_size)
 984{
 985        u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
 986        u16 *local_buffer;
 987        s32 status;
 988        u16 checksum = 0;
 989        u16 pointer, i, size;
 990
 991        hw->eeprom.ops.init_params(hw);
 992
 993        if (!buffer) {
 994                /* Read pointer area */
 995                status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
 996                                                IXGBE_EEPROM_LAST_WORD + 1,
 997                                                eeprom_ptrs);
 998                if (status) {
 999                        hw_dbg(hw, "Failed to read EEPROM image\n");
1000                        return status;
1001                }
1002                local_buffer = eeprom_ptrs;
1003        } else {
1004                if (buffer_size < IXGBE_EEPROM_LAST_WORD)
1005                        return IXGBE_ERR_PARAM;
1006                local_buffer = buffer;
1007        }
1008
1009        /* For X550 hardware include 0x0-0x41 in the checksum, skip the
1010         * checksum word itself
1011         */
1012        for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
1013                if (i != IXGBE_EEPROM_CHECKSUM)
1014                        checksum += local_buffer[i];
1015
1016        /* Include all data from pointers 0x3, 0x6-0xE.  This excludes the
1017         * FW, PHY module, and PCIe Expansion/Option ROM pointers.
1018         */
1019        for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
1020                if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
1021                        continue;
1022
1023                pointer = local_buffer[i];
1024
1025                /* Skip pointer section if the pointer is invalid. */
1026                if (pointer == 0xFFFF || pointer == 0 ||
1027                    pointer >= hw->eeprom.word_size)
1028                        continue;
1029
1030                switch (i) {
1031                case IXGBE_PCIE_GENERAL_PTR:
1032                        size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
1033                        break;
1034                case IXGBE_PCIE_CONFIG0_PTR:
1035                case IXGBE_PCIE_CONFIG1_PTR:
1036                        size = IXGBE_PCIE_CONFIG_SIZE;
1037                        break;
1038                default:
1039                        size = 0;
1040                        break;
1041                }
1042
1043                status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
1044                                                 buffer, buffer_size);
1045                if (status)
1046                        return status;
1047        }
1048
1049        checksum = (u16)IXGBE_EEPROM_SUM - checksum;
1050
1051        return (s32)checksum;
1052}
1053
1054/** ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
1055 *  @hw: pointer to hardware structure
1056 *
1057 *  Returns a negative error code on error, or the 16-bit checksum
1058 **/
1059static s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
1060{
1061        return ixgbe_calc_checksum_X550(hw, NULL, 0);
1062}
1063
1064/** ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
1065 *  @hw: pointer to hardware structure
1066 *  @offset: offset of  word in the EEPROM to read
1067 *  @data: word read from the EEPROM
1068 *
1069 *   Reads a 16 bit word from the EEPROM using the hostif.
1070 **/
1071static s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data)
1072{
1073        const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
1074        struct ixgbe_hic_read_shadow_ram buffer;
1075        s32 status;
1076
1077        buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
1078        buffer.hdr.req.buf_lenh = 0;
1079        buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
1080        buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
1081
1082        /* convert offset from words to bytes */
1083        buffer.address = cpu_to_be32(offset * 2);
1084        /* one word */
1085        buffer.length = cpu_to_be16(sizeof(u16));
1086
1087        status = hw->mac.ops.acquire_swfw_sync(hw, mask);
1088        if (status)
1089                return status;
1090
1091        status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
1092                                    IXGBE_HI_COMMAND_TIMEOUT);
1093        if (!status) {
1094                *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
1095                                                  FW_NVM_DATA_OFFSET);
1096        }
1097
1098        hw->mac.ops.release_swfw_sync(hw, mask);
1099        return status;
1100}
1101
1102/** ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
1103 *  @hw: pointer to hardware structure
1104 *  @checksum_val: calculated checksum
1105 *
1106 *  Performs checksum calculation and validates the EEPROM checksum.  If the
1107 *  caller does not need checksum_val, the value can be NULL.
1108 **/
1109static s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw,
1110                                               u16 *checksum_val)
1111{
1112        s32 status;
1113        u16 checksum;
1114        u16 read_checksum = 0;
1115
1116        /* Read the first word from the EEPROM. If this times out or fails, do
1117         * not continue or we could be in for a very long wait while every
1118         * EEPROM read fails
1119         */
1120        status = hw->eeprom.ops.read(hw, 0, &checksum);
1121        if (status) {
1122                hw_dbg(hw, "EEPROM read failed\n");
1123                return status;
1124        }
1125
1126        status = hw->eeprom.ops.calc_checksum(hw);
1127        if (status < 0)
1128                return status;
1129
1130        checksum = (u16)(status & 0xffff);
1131
1132        status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
1133                                           &read_checksum);
1134        if (status)
1135                return status;
1136
1137        /* Verify read checksum from EEPROM is the same as
1138         * calculated checksum
1139         */
1140        if (read_checksum != checksum) {
1141                status = IXGBE_ERR_EEPROM_CHECKSUM;
1142                hw_dbg(hw, "Invalid EEPROM checksum");
1143        }
1144
1145        /* If the user cares, return the calculated checksum */
1146        if (checksum_val)
1147                *checksum_val = checksum;
1148
1149        return status;
1150}
1151
1152/** ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
1153 *  @hw: pointer to hardware structure
1154 *  @offset: offset of  word in the EEPROM to write
1155 *  @data: word write to the EEPROM
1156 *
1157 *  Write a 16 bit word to the EEPROM using the hostif.
1158 **/
1159static s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
1160                                           u16 data)
1161{
1162        s32 status;
1163        struct ixgbe_hic_write_shadow_ram buffer;
1164
1165        buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
1166        buffer.hdr.req.buf_lenh = 0;
1167        buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
1168        buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
1169
1170        /* one word */
1171        buffer.length = cpu_to_be16(sizeof(u16));
1172        buffer.data = data;
1173        buffer.address = cpu_to_be32(offset * 2);
1174
1175        status = ixgbe_host_interface_command(hw, &buffer, sizeof(buffer),
1176                                              IXGBE_HI_COMMAND_TIMEOUT, false);
1177        return status;
1178}
1179
1180/** ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
1181 *  @hw: pointer to hardware structure
1182 *  @offset: offset of  word in the EEPROM to write
1183 *  @data: word write to the EEPROM
1184 *
1185 *  Write a 16 bit word to the EEPROM using the hostif.
1186 **/
1187static s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 data)
1188{
1189        s32 status = 0;
1190
1191        if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
1192                status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
1193                hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
1194        } else {
1195                hw_dbg(hw, "write ee hostif failed to get semaphore");
1196                status = IXGBE_ERR_SWFW_SYNC;
1197        }
1198
1199        return status;
1200}
1201
1202/** ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
1203 *  @hw: pointer to hardware structure
1204 *
1205 *  Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
1206 **/
1207static s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
1208{
1209        s32 status = 0;
1210        union ixgbe_hic_hdr2 buffer;
1211
1212        buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
1213        buffer.req.buf_lenh = 0;
1214        buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
1215        buffer.req.checksum = FW_DEFAULT_CHECKSUM;
1216
1217        status = ixgbe_host_interface_command(hw, &buffer, sizeof(buffer),
1218                                              IXGBE_HI_COMMAND_TIMEOUT, false);
1219        return status;
1220}
1221
1222/**
1223 * ixgbe_get_bus_info_X550em - Set PCI bus info
1224 * @hw: pointer to hardware structure
1225 *
1226 * Sets bus link width and speed to unknown because X550em is
1227 * not a PCI device.
1228 **/
1229static s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
1230{
1231        hw->bus.type  = ixgbe_bus_type_internal;
1232        hw->bus.width = ixgbe_bus_width_unknown;
1233        hw->bus.speed = ixgbe_bus_speed_unknown;
1234
1235        hw->mac.ops.set_lan_id(hw);
1236
1237        return 0;
1238}
1239
1240/** ixgbe_disable_rx_x550 - Disable RX unit
1241 *
1242 *  Enables the Rx DMA unit for x550
1243 **/
1244static void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
1245{
1246        u32 rxctrl, pfdtxgswc;
1247        s32 status;
1248        struct ixgbe_hic_disable_rxen fw_cmd;
1249
1250        rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
1251        if (rxctrl & IXGBE_RXCTRL_RXEN) {
1252                pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
1253                if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
1254                        pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
1255                        IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
1256                        hw->mac.set_lben = true;
1257                } else {
1258                        hw->mac.set_lben = false;
1259                }
1260
1261                fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
1262                fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
1263                fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1264                fw_cmd.port_number = hw->bus.lan_id;
1265
1266                status = ixgbe_host_interface_command(hw, &fw_cmd,
1267                                        sizeof(struct ixgbe_hic_disable_rxen),
1268                                        IXGBE_HI_COMMAND_TIMEOUT, true);
1269
1270                /* If we fail - disable RX using register write */
1271                if (status) {
1272                        rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
1273                        if (rxctrl & IXGBE_RXCTRL_RXEN) {
1274                                rxctrl &= ~IXGBE_RXCTRL_RXEN;
1275                                IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
1276                        }
1277                }
1278        }
1279}
1280
1281/** ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
1282 *  @hw: pointer to hardware structure
1283 *
1284 *  After writing EEPROM to shadow RAM using EEWR register, software calculates
1285 *  checksum and updates the EEPROM and instructs the hardware to update
1286 *  the flash.
1287 **/
1288static s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
1289{
1290        s32 status;
1291        u16 checksum = 0;
1292
1293        /* Read the first word from the EEPROM. If this times out or fails, do
1294         * not continue or we could be in for a very long wait while every
1295         * EEPROM read fails
1296         */
1297        status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
1298        if (status) {
1299                hw_dbg(hw, "EEPROM read failed\n");
1300                return status;
1301        }
1302
1303        status = ixgbe_calc_eeprom_checksum_X550(hw);
1304        if (status < 0)
1305                return status;
1306
1307        checksum = (u16)(status & 0xffff);
1308
1309        status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
1310                                            checksum);
1311        if (status)
1312                return status;
1313
1314        status = ixgbe_update_flash_X550(hw);
1315
1316        return status;
1317}
1318
1319/** ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
1320 *  @hw: pointer to hardware structure
1321 *  @offset: offset of  word in the EEPROM to write
1322 *  @words: number of words
1323 *  @data: word(s) write to the EEPROM
1324 *
1325 *
1326 *  Write a 16 bit word(s) to the EEPROM using the hostif.
1327 **/
1328static s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
1329                                             u16 offset, u16 words,
1330                                             u16 *data)
1331{
1332        s32 status = 0;
1333        u32 i = 0;
1334
1335        /* Take semaphore for the entire operation. */
1336        status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
1337        if (status) {
1338                hw_dbg(hw, "EEPROM write buffer - semaphore failed\n");
1339                return status;
1340        }
1341
1342        for (i = 0; i < words; i++) {
1343                status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
1344                                                         data[i]);
1345                if (status) {
1346                        hw_dbg(hw, "Eeprom buffered write failed\n");
1347                        break;
1348                }
1349        }
1350
1351        hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
1352
1353        return status;
1354}
1355
1356/** ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register of the
1357 *  IOSF device
1358 *
1359 *  @hw: pointer to hardware structure
1360 *  @reg_addr: 32 bit PHY register to write
1361 *  @device_type: 3 bit device type
1362 *  @data: Data to write to the register
1363 **/
1364static s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
1365                                        u32 device_type, u32 data)
1366{
1367        u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
1368        u32 command, error;
1369        s32 ret;
1370
1371        ret = hw->mac.ops.acquire_swfw_sync(hw, gssr);
1372        if (ret)
1373                return ret;
1374
1375        ret = ixgbe_iosf_wait(hw, NULL);
1376        if (ret)
1377                goto out;
1378
1379        command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
1380                   (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
1381
1382        /* Write IOSF control register */
1383        IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
1384
1385        /* Write IOSF data register */
1386        IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
1387
1388        ret = ixgbe_iosf_wait(hw, &command);
1389
1390        if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
1391                error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
1392                         IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
1393                hw_dbg(hw, "Failed to write, error %x\n", error);
1394                return IXGBE_ERR_PHY;
1395        }
1396
1397out:
1398        hw->mac.ops.release_swfw_sync(hw, gssr);
1399        return ret;
1400}
1401
1402/**
1403 *  ixgbe_setup_ixfi_x550em_x - MAC specific iXFI configuration
1404 *  @hw: pointer to hardware structure
1405 *
1406 *  iXfI configuration needed for ixgbe_mac_X550EM_x devices.
1407 **/
1408static s32 ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw)
1409{
1410        s32 status;
1411        u32 reg_val;
1412
1413        /* Disable training protocol FSM. */
1414        status = ixgbe_read_iosf_sb_reg_x550(hw,
1415                                IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
1416                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1417        if (status)
1418                return status;
1419
1420        reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
1421        status = ixgbe_write_iosf_sb_reg_x550(hw,
1422                                IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
1423                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1424        if (status)
1425                return status;
1426
1427        /* Disable Flex from training TXFFE. */
1428        status = ixgbe_read_iosf_sb_reg_x550(hw,
1429                                IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
1430                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1431        if (status)
1432                return status;
1433
1434        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
1435        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
1436        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
1437        status = ixgbe_write_iosf_sb_reg_x550(hw,
1438                                IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
1439                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1440        if (status)
1441                return status;
1442
1443        status = ixgbe_read_iosf_sb_reg_x550(hw,
1444                                IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
1445                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1446        if (status)
1447                return status;
1448
1449        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
1450        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
1451        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
1452        status = ixgbe_write_iosf_sb_reg_x550(hw,
1453                                IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
1454                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1455        if (status)
1456                return status;
1457
1458        /* Enable override for coefficients. */
1459        status = ixgbe_read_iosf_sb_reg_x550(hw,
1460                                IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
1461                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1462        if (status)
1463                return status;
1464
1465        reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
1466        reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
1467        reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
1468        reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
1469        status = ixgbe_write_iosf_sb_reg_x550(hw,
1470                                IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
1471                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1472        return status;
1473}
1474
1475/**
1476 *  ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the
1477 *  internal PHY
1478 *  @hw: pointer to hardware structure
1479 **/
1480static s32 ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw)
1481{
1482        s32 status;
1483        u32 link_ctrl;
1484
1485        /* Restart auto-negotiation. */
1486        status = hw->mac.ops.read_iosf_sb_reg(hw,
1487                                IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1488                                IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl);
1489
1490        if (status) {
1491                hw_dbg(hw, "Auto-negotiation did not complete\n");
1492                return status;
1493        }
1494
1495        link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
1496        status = hw->mac.ops.write_iosf_sb_reg(hw,
1497                                IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1498                                IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl);
1499
1500        if (hw->mac.type == ixgbe_mac_x550em_a) {
1501                u32 flx_mask_st20;
1502
1503                /* Indicate to FW that AN restart has been asserted */
1504                status = hw->mac.ops.read_iosf_sb_reg(hw,
1505                                IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1506                                IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20);
1507
1508                if (status) {
1509                        hw_dbg(hw, "Auto-negotiation did not complete\n");
1510                        return status;
1511                }
1512
1513                flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART;
1514                status = hw->mac.ops.write_iosf_sb_reg(hw,
1515                                IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1516                                IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20);
1517        }
1518
1519        return status;
1520}
1521
1522/** ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
1523 *  @hw: pointer to hardware structure
1524 *  @speed: the link speed to force
1525 *
1526 *  Configures the integrated KR PHY to use iXFI mode. Used to connect an
1527 *  internal and external PHY at a specific speed, without autonegotiation.
1528 **/
1529static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
1530{
1531        s32 status;
1532        u32 reg_val;
1533
1534        /* Disable AN and force speed to 10G Serial. */
1535        status = ixgbe_read_iosf_sb_reg_x550(hw,
1536                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1537                                        IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1538        if (status)
1539                return status;
1540
1541        reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1542        reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1543
1544        /* Select forced link speed for internal PHY. */
1545        switch (*speed) {
1546        case IXGBE_LINK_SPEED_10GB_FULL:
1547                reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
1548                break;
1549        case IXGBE_LINK_SPEED_1GB_FULL:
1550                reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1551                break;
1552        default:
1553                /* Other link speeds are not supported by internal KR PHY. */
1554                return IXGBE_ERR_LINK_SETUP;
1555        }
1556
1557        status = ixgbe_write_iosf_sb_reg_x550(hw,
1558                                IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1559                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1560        if (status)
1561                return status;
1562
1563        /* Additional configuration needed for x550em_x */
1564        if (hw->mac.type == ixgbe_mac_X550EM_x) {
1565                status = ixgbe_setup_ixfi_x550em_x(hw);
1566                if (status)
1567                        return status;
1568        }
1569
1570        /* Toggle port SW reset by AN reset. */
1571        status = ixgbe_restart_an_internal_phy_x550em(hw);
1572
1573        return status;
1574}
1575
1576/**
1577 *  ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
1578 *  @hw: pointer to hardware structure
1579 *  @linear: true if SFP module is linear
1580 */
1581static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
1582{
1583        switch (hw->phy.sfp_type) {
1584        case ixgbe_sfp_type_not_present:
1585                return IXGBE_ERR_SFP_NOT_PRESENT;
1586        case ixgbe_sfp_type_da_cu_core0:
1587        case ixgbe_sfp_type_da_cu_core1:
1588                *linear = true;
1589                break;
1590        case ixgbe_sfp_type_srlr_core0:
1591        case ixgbe_sfp_type_srlr_core1:
1592        case ixgbe_sfp_type_da_act_lmt_core0:
1593        case ixgbe_sfp_type_da_act_lmt_core1:
1594        case ixgbe_sfp_type_1g_sx_core0:
1595        case ixgbe_sfp_type_1g_sx_core1:
1596        case ixgbe_sfp_type_1g_lx_core0:
1597        case ixgbe_sfp_type_1g_lx_core1:
1598                *linear = false;
1599                break;
1600        case ixgbe_sfp_type_unknown:
1601        case ixgbe_sfp_type_1g_cu_core0:
1602        case ixgbe_sfp_type_1g_cu_core1:
1603        default:
1604                return IXGBE_ERR_SFP_NOT_SUPPORTED;
1605        }
1606
1607        return 0;
1608}
1609
1610/**
1611 *  ixgbe_setup_mac_link_sfp_x550em - Configure the KR PHY for SFP.
1612 *  @hw: pointer to hardware structure
1613 *
1614 *  Configures the extern PHY and the integrated KR PHY for SFP support.
1615 */
1616static s32
1617ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
1618                                ixgbe_link_speed speed,
1619                                __always_unused bool autoneg_wait_to_complete)
1620{
1621        s32 status;
1622        u16 reg_slice, reg_val;
1623        bool setup_linear = false;
1624
1625        /* Check if SFP module is supported and linear */
1626        status = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
1627
1628        /* If no SFP module present, then return success. Return success since
1629         * there is no reason to configure CS4227 and SFP not present error is
1630         * not accepted in the setup MAC link flow.
1631         */
1632        if (status == IXGBE_ERR_SFP_NOT_PRESENT)
1633                return 0;
1634
1635        if (status)
1636                return status;
1637
1638        /* Configure internal PHY for KR/KX. */
1639        ixgbe_setup_kr_speed_x550em(hw, speed);
1640
1641        /* Configure CS4227 LINE side to proper mode. */
1642        reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12);
1643        if (setup_linear)
1644                reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
1645        else
1646                reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
1647
1648        status = hw->link.ops.write_link(hw, hw->link.addr, reg_slice,
1649                                         reg_val);
1650
1651        return status;
1652}
1653
1654/**
1655 * ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode
1656 * @hw: pointer to hardware structure
1657 * @speed: the link speed to force
1658 *
1659 * Configures the integrated PHY for native SFI mode. Used to connect the
1660 * internal PHY directly to an SFP cage, without autonegotiation.
1661 **/
1662static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
1663{
1664        struct ixgbe_mac_info *mac = &hw->mac;
1665        s32 status;
1666        u32 reg_val;
1667
1668        /* Disable all AN and force speed to 10G Serial. */
1669        status = mac->ops.read_iosf_sb_reg(hw,
1670                                IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1671                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1672        if (status)
1673                return status;
1674
1675        reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
1676        reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
1677        reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
1678        reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
1679
1680        /* Select forced link speed for internal PHY. */
1681        switch (*speed) {
1682        case IXGBE_LINK_SPEED_10GB_FULL:
1683                reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G;
1684                break;
1685        case IXGBE_LINK_SPEED_1GB_FULL:
1686                reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
1687                break;
1688        default:
1689                /* Other link speeds are not supported by internal PHY. */
1690                return IXGBE_ERR_LINK_SETUP;
1691        }
1692
1693        status = mac->ops.write_iosf_sb_reg(hw,
1694                                IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1695                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1696
1697        /* Toggle port SW reset by AN reset. */
1698        status = ixgbe_restart_an_internal_phy_x550em(hw);
1699
1700        return status;
1701}
1702
1703/**
1704 * ixgbe_setup_mac_link_sfp_n - Setup internal PHY for native SFP
1705 * @hw: pointer to hardware structure
1706 *
1707 * Configure the the integrated PHY for native SFP support.
1708 */
1709static s32
1710ixgbe_setup_mac_link_sfp_n(struct ixgbe_hw *hw, ixgbe_link_speed speed,
1711                           __always_unused bool autoneg_wait_to_complete)
1712{
1713        bool setup_linear = false;
1714        u32 reg_phy_int;
1715        s32 ret_val;
1716
1717        /* Check if SFP module is supported and linear */
1718        ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
1719
1720        /* If no SFP module present, then return success. Return success since
1721         * SFP not present error is not excepted in the setup MAC link flow.
1722         */
1723        if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
1724                return 0;
1725
1726        if (!ret_val)
1727                return ret_val;
1728
1729        /* Configure internal PHY for native SFI based on module type */
1730        ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
1731                                IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1732                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_phy_int);
1733        if (!ret_val)
1734                return ret_val;
1735
1736        reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA;
1737        if (!setup_linear)
1738                reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR;
1739
1740        ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
1741                                IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1742                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
1743        if (!ret_val)
1744                return ret_val;
1745
1746        /* Setup SFI internal link. */
1747        return ixgbe_setup_sfi_x550a(hw, &speed);
1748}
1749
1750/**
1751 * ixgbe_setup_mac_link_sfp_x550a - Setup internal PHY for SFP
1752 * @hw: pointer to hardware structure
1753 *
1754 * Configure the the integrated PHY for SFP support.
1755 */
1756static s32
1757ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, ixgbe_link_speed speed,
1758                               __always_unused bool autoneg_wait_to_complete)
1759{
1760        u32 reg_slice, slice_offset;
1761        bool setup_linear = false;
1762        u16 reg_phy_ext;
1763        s32 ret_val;
1764
1765        /* Check if SFP module is supported and linear */
1766        ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
1767
1768        /* If no SFP module present, then return success. Return success since
1769         * SFP not present error is not excepted in the setup MAC link flow.
1770         */
1771        if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
1772                return 0;
1773
1774        if (!ret_val)
1775                return ret_val;
1776
1777        /* Configure internal PHY for KR/KX. */
1778        ixgbe_setup_kr_speed_x550em(hw, speed);
1779
1780        if (hw->phy.mdio.prtad == MDIO_PRTAD_NONE)
1781                return IXGBE_ERR_PHY_ADDR_INVALID;
1782
1783        /* Get external PHY device id */
1784        ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_GLOBAL_ID_MSB,
1785                                  IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
1786        if (ret_val)
1787                return ret_val;
1788
1789        /* When configuring quad port CS4223, the MAC instance is part
1790         * of the slice offset.
1791         */
1792        if (reg_phy_ext == IXGBE_CS4223_PHY_ID)
1793                slice_offset = (hw->bus.lan_id +
1794                                (hw->bus.instance_id << 1)) << 12;
1795        else
1796                slice_offset = hw->bus.lan_id << 12;
1797
1798        /* Configure CS4227/CS4223 LINE side to proper mode. */
1799        reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset;
1800        if (setup_linear)
1801                reg_phy_ext = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
1802        else
1803                reg_phy_ext = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
1804        return hw->phy.ops.write_reg(hw, reg_slice, IXGBE_MDIO_ZERO_DEV_TYPE,
1805                                     reg_phy_ext);
1806}
1807
1808/**
1809 * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed
1810 * @hw: pointer to hardware structure
1811 * @speed: new link speed
1812 * @autoneg_wait_to_complete: true when waiting for completion is needed
1813 *
1814 * Setup internal/external PHY link speed based on link speed, then set
1815 * external PHY auto advertised link speed.
1816 *
1817 * Returns error status for any failure
1818 **/
1819static s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
1820                                         ixgbe_link_speed speed,
1821                                         bool autoneg_wait)
1822{
1823        s32 status;
1824        ixgbe_link_speed force_speed;
1825
1826        /* Setup internal/external PHY link speed to iXFI (10G), unless
1827         * only 1G is auto advertised then setup KX link.
1828         */
1829        if (speed & IXGBE_LINK_SPEED_10GB_FULL)
1830                force_speed = IXGBE_LINK_SPEED_10GB_FULL;
1831        else
1832                force_speed = IXGBE_LINK_SPEED_1GB_FULL;
1833
1834        /* If internal link mode is XFI, then setup XFI internal link. */
1835        if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
1836                status = ixgbe_setup_ixfi_x550em(hw, &force_speed);
1837
1838                if (status)
1839                        return status;
1840        }
1841
1842        return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
1843}
1844
1845/** ixgbe_check_link_t_X550em - Determine link and speed status
1846  * @hw: pointer to hardware structure
1847  * @speed: pointer to link speed
1848  * @link_up: true when link is up
1849  * @link_up_wait_to_complete: bool used to wait for link up or not
1850  *
1851  * Check that both the MAC and X557 external PHY have link.
1852  **/
1853static s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw,
1854                                     ixgbe_link_speed *speed,
1855                                     bool *link_up,
1856                                     bool link_up_wait_to_complete)
1857{
1858        u32 status;
1859        u16 i, autoneg_status;
1860
1861        if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
1862                return IXGBE_ERR_CONFIG;
1863
1864        status = ixgbe_check_mac_link_generic(hw, speed, link_up,
1865                                              link_up_wait_to_complete);
1866
1867        /* If check link fails or MAC link is not up, then return */
1868        if (status || !(*link_up))
1869                return status;
1870
1871        /* MAC link is up, so check external PHY link.
1872         * Link status is latching low, and can only be used to detect link
1873         * drop, and not the current status of the link without performing
1874         * back-to-back reads.
1875         */
1876        for (i = 0; i < 2; i++) {
1877                status = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN,
1878                                              &autoneg_status);
1879
1880                if (status)
1881                        return status;
1882        }
1883
1884        /* If external PHY link is not up, then indicate link not up */
1885        if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
1886                *link_up = false;
1887
1888        return 0;
1889}
1890
1891/**
1892 * ixgbe_setup_sgmii - Set up link for sgmii
1893 * @hw: pointer to hardware structure
1894 */
1895static s32
1896ixgbe_setup_sgmii(struct ixgbe_hw *hw, __always_unused ixgbe_link_speed speed,
1897                  __always_unused bool autoneg_wait_to_complete)
1898{
1899        struct ixgbe_mac_info *mac = &hw->mac;
1900        u32 lval, sval, flx_val;
1901        s32 rc;
1902
1903        rc = mac->ops.read_iosf_sb_reg(hw,
1904                                       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1905                                       IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
1906        if (rc)
1907                return rc;
1908
1909        lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1910        lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1911        lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
1912        lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
1913        lval |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1914        rc = mac->ops.write_iosf_sb_reg(hw,
1915                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1916                                        IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1917        if (rc)
1918                return rc;
1919
1920        rc = mac->ops.read_iosf_sb_reg(hw,
1921                                       IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1922                                       IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
1923        if (rc)
1924                return rc;
1925
1926        sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
1927        sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
1928        rc = mac->ops.write_iosf_sb_reg(hw,
1929                                        IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1930                                        IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
1931        if (rc)
1932                return rc;
1933
1934        rc = mac->ops.read_iosf_sb_reg(hw,
1935                                IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1936                                IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
1937        if (rc)
1938                return rc;
1939
1940        rc = mac->ops.read_iosf_sb_reg(hw,
1941                                IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1942                                IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
1943        if (rc)
1944                return rc;
1945
1946        flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
1947        flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
1948        flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
1949        flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
1950        flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
1951
1952        rc = mac->ops.write_iosf_sb_reg(hw,
1953                                IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1954                                IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
1955        if (rc)
1956                return rc;
1957
1958        rc = ixgbe_restart_an_internal_phy_x550em(hw);
1959        return rc;
1960}
1961
1962/**
1963 * ixgbe_setup_sgmii_fw - Set up link for sgmii with firmware-controlled PHYs
1964 * @hw: pointer to hardware structure
1965 */
1966static s32 ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed,
1967                                bool autoneg_wait)
1968{
1969        struct ixgbe_mac_info *mac = &hw->mac;
1970        u32 lval, sval, flx_val;
1971        s32 rc;
1972
1973        rc = mac->ops.read_iosf_sb_reg(hw,
1974                                       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1975                                       IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
1976        if (rc)
1977                return rc;
1978
1979        lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1980        lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1981        lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
1982        lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
1983        lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1984        rc = mac->ops.write_iosf_sb_reg(hw,
1985                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1986                                        IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1987        if (rc)
1988                return rc;
1989
1990        rc = mac->ops.read_iosf_sb_reg(hw,
1991                                       IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1992                                       IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
1993        if (rc)
1994                return rc;
1995
1996        sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
1997        sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
1998        rc = mac->ops.write_iosf_sb_reg(hw,
1999                                        IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
2000                                        IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
2001        if (rc)
2002                return rc;
2003
2004        rc = mac->ops.write_iosf_sb_reg(hw,
2005                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2006                                        IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
2007        if (rc)
2008                return rc;
2009
2010        rc = mac->ops.read_iosf_sb_reg(hw,
2011                                    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2012                                    IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
2013        if (rc)
2014                return rc;
2015
2016        flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
2017        flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
2018        flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
2019        flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
2020        flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
2021
2022        rc = mac->ops.write_iosf_sb_reg(hw,
2023                                    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2024                                    IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
2025        if (rc)
2026                return rc;
2027
2028        ixgbe_restart_an_internal_phy_x550em(hw);
2029
2030        return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
2031}
2032
2033/**
2034 * ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37
2035 * @hw: pointer to hardware structure
2036 *
2037 * Enable flow control according to IEEE clause 37.
2038 */
2039static void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw)
2040{
2041        s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
2042        u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
2043        ixgbe_link_speed speed;
2044        bool link_up;
2045
2046        /* AN should have completed when the cable was plugged in.
2047         * Look for reasons to bail out.  Bail out if:
2048         * - FC autoneg is disabled, or if
2049         * - link is not up.
2050         */
2051        if (hw->fc.disable_fc_autoneg)
2052                goto out;
2053
2054        hw->mac.ops.check_link(hw, &speed, &link_up, false);
2055        if (!link_up)
2056                goto out;
2057
2058        /* Check if auto-negotiation has completed */
2059        status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info);
2060        if (status || !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) {
2061                status = IXGBE_ERR_FC_NOT_NEGOTIATED;
2062                goto out;
2063        }
2064
2065        /* Negotiate the flow control */
2066        status = ixgbe_negotiate_fc(hw, info[0], info[0],
2067                                    FW_PHY_ACT_GET_LINK_INFO_FC_RX,
2068                                    FW_PHY_ACT_GET_LINK_INFO_FC_TX,
2069                                    FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX,
2070                                    FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX);
2071
2072out:
2073        if (!status) {
2074                hw->fc.fc_was_autonegged = true;
2075        } else {
2076                hw->fc.fc_was_autonegged = false;
2077                hw->fc.current_mode = hw->fc.requested_mode;
2078        }
2079}
2080
2081/** ixgbe_init_mac_link_ops_X550em_a - Init mac link function pointers
2082 *  @hw: pointer to hardware structure
2083 **/
2084static void ixgbe_init_mac_link_ops_X550em_a(struct ixgbe_hw *hw)
2085{
2086        struct ixgbe_mac_info *mac = &hw->mac;
2087
2088        switch (mac->ops.get_media_type(hw)) {
2089        case ixgbe_media_type_fiber:
2090                mac->ops.setup_fc = NULL;
2091                mac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a;
2092                break;
2093        case ixgbe_media_type_copper:
2094                if (hw->device_id != IXGBE_DEV_ID_X550EM_A_1G_T &&
2095                    hw->device_id != IXGBE_DEV_ID_X550EM_A_1G_T_L) {
2096                        mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
2097                        break;
2098                }
2099                mac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a;
2100                mac->ops.setup_fc = ixgbe_fc_autoneg_fw;
2101                mac->ops.setup_link = ixgbe_setup_sgmii_fw;
2102                mac->ops.check_link = ixgbe_check_mac_link_generic;
2103                break;
2104        case ixgbe_media_type_backplane:
2105                mac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a;
2106                mac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a;
2107                break;
2108        default:
2109                break;
2110        }
2111}
2112
2113/** ixgbe_init_mac_link_ops_X550em - init mac link function pointers
2114 *  @hw: pointer to hardware structure
2115 **/
2116static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
2117{
2118        struct ixgbe_mac_info *mac = &hw->mac;
2119
2120        mac->ops.setup_fc = ixgbe_setup_fc_x550em;
2121
2122        switch (mac->ops.get_media_type(hw)) {
2123        case ixgbe_media_type_fiber:
2124                /* CS4227 does not support autoneg, so disable the laser control
2125                 * functions for SFP+ fiber
2126                 */
2127                mac->ops.disable_tx_laser = NULL;
2128                mac->ops.enable_tx_laser = NULL;
2129                mac->ops.flap_tx_laser = NULL;
2130                mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
2131                switch (hw->device_id) {
2132                case IXGBE_DEV_ID_X550EM_A_SFP_N:
2133                        mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_n;
2134                        break;
2135                case IXGBE_DEV_ID_X550EM_A_SFP:
2136                        mac->ops.setup_mac_link =
2137                                                ixgbe_setup_mac_link_sfp_x550a;
2138                        break;
2139                default:
2140                        mac->ops.setup_mac_link =
2141                                                ixgbe_setup_mac_link_sfp_x550em;
2142                        break;
2143                }
2144                mac->ops.set_rate_select_speed =
2145                                        ixgbe_set_soft_rate_select_speed;
2146                break;
2147        case ixgbe_media_type_copper:
2148                mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
2149                mac->ops.setup_fc = ixgbe_setup_fc_generic;
2150                mac->ops.check_link = ixgbe_check_link_t_X550em;
2151                break;
2152        case ixgbe_media_type_backplane:
2153                if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
2154                    hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L)
2155                        mac->ops.setup_link = ixgbe_setup_sgmii;
2156                break;
2157        default:
2158                break;
2159        }
2160
2161        /* Additional modification for X550em_a devices */
2162        if (hw->mac.type == ixgbe_mac_x550em_a)
2163                ixgbe_init_mac_link_ops_X550em_a(hw);
2164}
2165
2166/** ixgbe_setup_sfp_modules_X550em - Setup SFP module
2167 * @hw: pointer to hardware structure
2168 */
2169static s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
2170{
2171        s32 status;
2172        bool linear;
2173
2174        /* Check if SFP module is supported */
2175        status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
2176        if (status)
2177                return status;
2178
2179        ixgbe_init_mac_link_ops_X550em(hw);
2180        hw->phy.ops.reset = NULL;
2181
2182        return 0;
2183}
2184
2185/** ixgbe_get_link_capabilities_x550em - Determines link capabilities
2186 * @hw: pointer to hardware structure
2187 * @speed: pointer to link speed
2188 * @autoneg: true when autoneg or autotry is enabled
2189 **/
2190static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
2191                                              ixgbe_link_speed *speed,
2192                                              bool *autoneg)
2193{
2194        if (hw->phy.type == ixgbe_phy_fw) {
2195                *autoneg = true;
2196                *speed = hw->phy.speeds_supported;
2197                return 0;
2198        }
2199
2200        /* SFP */
2201        if (hw->phy.media_type == ixgbe_media_type_fiber) {
2202                /* CS4227 SFP must not enable auto-negotiation */
2203                *autoneg = false;
2204
2205                if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
2206                    hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
2207                        *speed = IXGBE_LINK_SPEED_1GB_FULL;
2208                        return 0;
2209                }
2210
2211                /* Link capabilities are based on SFP */
2212                if (hw->phy.multispeed_fiber)
2213                        *speed = IXGBE_LINK_SPEED_10GB_FULL |
2214                                 IXGBE_LINK_SPEED_1GB_FULL;
2215                else
2216                        *speed = IXGBE_LINK_SPEED_10GB_FULL;
2217        } else {
2218                *speed = IXGBE_LINK_SPEED_10GB_FULL |
2219                         IXGBE_LINK_SPEED_1GB_FULL;
2220                *autoneg = true;
2221        }
2222        return 0;
2223}
2224
2225/**
2226 * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause
2227 * @hw: pointer to hardware structure
2228 * @lsc: pointer to boolean flag which indicates whether external Base T
2229 *       PHY interrupt is lsc
2230 *
2231 * Determime if external Base T PHY interrupt cause is high temperature
2232 * failure alarm or link status change.
2233 *
2234 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
2235 * failure alarm, else return PHY access status.
2236 **/
2237static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
2238{
2239        u32 status;
2240        u16 reg;
2241
2242        *lsc = false;
2243
2244        /* Vendor alarm triggered */
2245        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
2246                                      MDIO_MMD_VEND1,
2247                                      &reg);
2248
2249        if (status || !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN))
2250                return status;
2251
2252        /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */
2253        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG,
2254                                      MDIO_MMD_VEND1,
2255                                      &reg);
2256
2257        if (status || !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
2258                                IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
2259                return status;
2260
2261        /* Global alarm triggered */
2262        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
2263                                      MDIO_MMD_VEND1,
2264                                      &reg);
2265
2266        if (status)
2267                return status;
2268
2269        /* If high temperature failure, then return over temp error and exit */
2270        if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
2271                /* power down the PHY in case the PHY FW didn't already */
2272                ixgbe_set_copper_phy_power(hw, false);
2273                return IXGBE_ERR_OVERTEMP;
2274        }
2275        if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
2276                /*  device fault alarm triggered */
2277                status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
2278                                          MDIO_MMD_VEND1,
2279                                          &reg);
2280                if (status)
2281                        return status;
2282
2283                /* if device fault was due to high temp alarm handle and exit */
2284                if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
2285                        /* power down the PHY in case the PHY FW didn't */
2286                        ixgbe_set_copper_phy_power(hw, false);
2287                        return IXGBE_ERR_OVERTEMP;
2288                }
2289        }
2290
2291        /* Vendor alarm 2 triggered */
2292        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
2293                                      MDIO_MMD_AN, &reg);
2294
2295        if (status || !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT))
2296                return status;
2297
2298        /* link connect/disconnect event occurred */
2299        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2,
2300                                      MDIO_MMD_AN, &reg);
2301
2302        if (status)
2303                return status;
2304
2305        /* Indicate LSC */
2306        if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC)
2307                *lsc = true;
2308
2309        return 0;
2310}
2311
2312/**
2313 * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts
2314 * @hw: pointer to hardware structure
2315 *
2316 * Enable link status change and temperature failure alarm for the external
2317 * Base T PHY
2318 *
2319 * Returns PHY access status
2320 **/
2321static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
2322{
2323        u32 status;
2324        u16 reg;
2325        bool lsc;
2326
2327        /* Clear interrupt flags */
2328        status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
2329
2330        /* Enable link status change alarm */
2331        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
2332                                      MDIO_MMD_AN, &reg);
2333        if (status)
2334                return status;
2335
2336        reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN;
2337
2338        status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
2339                                       MDIO_MMD_AN, reg);
2340        if (status)
2341                return status;
2342
2343        /* Enable high temperature failure and global fault alarms */
2344        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
2345                                      MDIO_MMD_VEND1,
2346                                      &reg);
2347        if (status)
2348                return status;
2349
2350        reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN |
2351                IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN);
2352
2353        status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
2354                                       MDIO_MMD_VEND1,
2355                                       reg);
2356        if (status)
2357                return status;
2358
2359        /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */
2360        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
2361                                      MDIO_MMD_VEND1,
2362                                      &reg);
2363        if (status)
2364                return status;
2365
2366        reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
2367                IXGBE_MDIO_GLOBAL_ALARM_1_INT);
2368
2369        status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
2370                                       MDIO_MMD_VEND1,
2371                                       reg);
2372        if (status)
2373                return status;
2374
2375        /* Enable chip-wide vendor alarm */
2376        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
2377                                      MDIO_MMD_VEND1,
2378                                      &reg);
2379        if (status)
2380                return status;
2381
2382        reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN;
2383
2384        status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
2385                                       MDIO_MMD_VEND1,
2386                                       reg);
2387
2388        return status;
2389}
2390
2391/**
2392 * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
2393 * @hw: pointer to hardware structure
2394 *
2395 * Handle external Base T PHY interrupt. If high temperature
2396 * failure alarm then return error, else if link status change
2397 * then setup internal/external PHY link
2398 *
2399 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
2400 * failure alarm, else return PHY access status.
2401 **/
2402static s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
2403{
2404        struct ixgbe_phy_info *phy = &hw->phy;
2405        bool lsc;
2406        u32 status;
2407
2408        status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
2409        if (status)
2410                return status;
2411
2412        if (lsc && phy->ops.setup_internal_link)
2413                return phy->ops.setup_internal_link(hw);
2414
2415        return 0;
2416}
2417
2418/**
2419 * ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed.
2420 * @hw: pointer to hardware structure
2421 * @speed: link speed
2422 *
2423 * Configures the integrated KR PHY.
2424 **/
2425static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
2426                                       ixgbe_link_speed speed)
2427{
2428        s32 status;
2429        u32 reg_val;
2430
2431        status = hw->mac.ops.read_iosf_sb_reg(hw,
2432                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2433                                        IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2434        if (status)
2435                return status;
2436
2437        reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
2438        reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
2439                     IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
2440
2441        /* Advertise 10G support. */
2442        if (speed & IXGBE_LINK_SPEED_10GB_FULL)
2443                reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
2444
2445        /* Advertise 1G support. */
2446        if (speed & IXGBE_LINK_SPEED_1GB_FULL)
2447                reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
2448
2449        status = hw->mac.ops.write_iosf_sb_reg(hw,
2450                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2451                                        IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2452
2453        if (hw->mac.type == ixgbe_mac_x550em_a) {
2454                /* Set lane mode  to KR auto negotiation */
2455                status = hw->mac.ops.read_iosf_sb_reg(hw,
2456                                IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2457                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2458
2459                if (status)
2460                        return status;
2461
2462                reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
2463                reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
2464                reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
2465                reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
2466                reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
2467
2468                status = hw->mac.ops.write_iosf_sb_reg(hw,
2469                                IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2470                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2471        }
2472
2473        return ixgbe_restart_an_internal_phy_x550em(hw);
2474}
2475
2476/** ixgbe_setup_kx4_x550em - Configure the KX4 PHY.
2477 *  @hw: pointer to hardware structure
2478 *
2479 *   Configures the integrated KX4 PHY.
2480 **/
2481static s32 ixgbe_setup_kx4_x550em(struct ixgbe_hw *hw)
2482{
2483        s32 status;
2484        u32 reg_val;
2485
2486        status = hw->mac.ops.read_iosf_sb_reg(hw, IXGBE_KX4_LINK_CNTL_1,
2487                                              IXGBE_SB_IOSF_TARGET_KX4_PCS0 +
2488                                              hw->bus.lan_id, &reg_val);
2489        if (status)
2490                return status;
2491
2492        reg_val &= ~(IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4 |
2493                     IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX);
2494
2495        reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_ENABLE;
2496
2497        /* Advertise 10G support. */
2498        if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
2499                reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4;
2500
2501        /* Advertise 1G support. */
2502        if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
2503                reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX;
2504
2505        /* Restart auto-negotiation. */
2506        reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_RESTART;
2507        status = hw->mac.ops.write_iosf_sb_reg(hw, IXGBE_KX4_LINK_CNTL_1,
2508                                               IXGBE_SB_IOSF_TARGET_KX4_PCS0 +
2509                                               hw->bus.lan_id, reg_val);
2510
2511        return status;
2512}
2513
2514/**
2515 * ixgbe_setup_kr_x550em - Configure the KR PHY
2516 * @hw: pointer to hardware structure
2517 **/
2518static s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
2519{
2520        /* leave link alone for 2.5G */
2521        if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL)
2522                return 0;
2523
2524        return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised);
2525}
2526
2527/** ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status
2528 *  @hw: address of hardware structure
2529 *  @link_up: address of boolean to indicate link status
2530 *
2531 *  Returns error code if unable to get link status.
2532 **/
2533static s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up)
2534{
2535        u32 ret;
2536        u16 autoneg_status;
2537
2538        *link_up = false;
2539
2540        /* read this twice back to back to indicate current status */
2541        ret = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN,
2542                                   &autoneg_status);
2543        if (ret)
2544                return ret;
2545
2546        ret = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN,
2547                                   &autoneg_status);
2548        if (ret)
2549                return ret;
2550
2551        *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS);
2552
2553        return 0;
2554}
2555
2556/** ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link
2557 *  @hw: point to hardware structure
2558 *
2559 *  Configures the link between the integrated KR PHY and the external X557 PHY
2560 *  The driver will call this function when it gets a link status change
2561 *  interrupt from the X557 PHY. This function configures the link speed
2562 *  between the PHYs to match the link speed of the BASE-T link.
2563 *
2564 * A return of a non-zero value indicates an error, and the base driver should
2565 * not report link up.
2566 **/
2567static s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
2568{
2569        ixgbe_link_speed force_speed;
2570        bool link_up;
2571        u32 status;
2572        u16 speed;
2573
2574        if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
2575                return IXGBE_ERR_CONFIG;
2576
2577        if (hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) {
2578                speed = IXGBE_LINK_SPEED_10GB_FULL |
2579                        IXGBE_LINK_SPEED_1GB_FULL;
2580                return ixgbe_setup_kr_speed_x550em(hw, speed);
2581        }
2582
2583        /* If link is not up, then there is no setup necessary so return  */
2584        status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
2585        if (status)
2586                return status;
2587
2588        if (!link_up)
2589                return 0;
2590
2591        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
2592                                      MDIO_MMD_AN,
2593                                      &speed);
2594        if (status)
2595                return status;
2596
2597        /* If link is not still up, then no setup is necessary so return */
2598        status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
2599        if (status)
2600                return status;
2601
2602        if (!link_up)
2603                return 0;
2604
2605        /* clear everything but the speed and duplex bits */
2606        speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
2607
2608        switch (speed) {
2609        case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
2610                force_speed = IXGBE_LINK_SPEED_10GB_FULL;
2611                break;
2612        case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
2613                force_speed = IXGBE_LINK_SPEED_1GB_FULL;
2614                break;
2615        default:
2616                /* Internal PHY does not support anything else */
2617                return IXGBE_ERR_INVALID_LINK_SETTINGS;
2618        }
2619
2620        return ixgbe_setup_ixfi_x550em(hw, &force_speed);
2621}
2622
2623/** ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI
2624 *  @hw: pointer to hardware structure
2625 **/
2626static s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw)
2627{
2628        s32 status;
2629
2630        status = ixgbe_reset_phy_generic(hw);
2631
2632        if (status)
2633                return status;
2634
2635        /* Configure Link Status Alarm and Temperature Threshold interrupts */
2636        return ixgbe_enable_lasi_ext_t_x550em(hw);
2637}
2638
2639/**
2640 *  ixgbe_led_on_t_x550em - Turns on the software controllable LEDs.
2641 *  @hw: pointer to hardware structure
2642 *  @led_idx: led number to turn on
2643 **/
2644static s32 ixgbe_led_on_t_x550em(struct ixgbe_hw *hw, u32 led_idx)
2645{
2646        u16 phy_data;
2647
2648        if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
2649                return IXGBE_ERR_PARAM;
2650
2651        /* To turn on the LED, set mode to ON. */
2652        hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
2653                             MDIO_MMD_VEND1, &phy_data);
2654        phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK;
2655        hw->phy.ops.write_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
2656                              MDIO_MMD_VEND1, phy_data);
2657
2658        return 0;
2659}
2660
2661/**
2662 *  ixgbe_led_off_t_x550em - Turns off the software controllable LEDs.
2663 *  @hw: pointer to hardware structure
2664 *  @led_idx: led number to turn off
2665 **/
2666static s32 ixgbe_led_off_t_x550em(struct ixgbe_hw *hw, u32 led_idx)
2667{
2668        u16 phy_data;
2669
2670        if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
2671                return IXGBE_ERR_PARAM;
2672
2673        /* To turn on the LED, set mode to ON. */
2674        hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
2675                             MDIO_MMD_VEND1, &phy_data);
2676        phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK;
2677        hw->phy.ops.write_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
2678                              MDIO_MMD_VEND1, phy_data);
2679
2680        return 0;
2681}
2682
2683/**
2684 *  ixgbe_set_fw_drv_ver_x550 - Sends driver version to firmware
2685 *  @hw: pointer to the HW structure
2686 *  @maj: driver version major number
2687 *  @min: driver version minor number
2688 *  @build: driver version build number
2689 *  @sub: driver version sub build number
2690 *  @len: length of driver_ver string
2691 *  @driver_ver: driver string
2692 *
2693 *  Sends driver version number to firmware through the manageability
2694 *  block.  On success return 0
2695 *  else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
2696 *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
2697 **/
2698static s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min,
2699                                     u8 build, u8 sub, u16 len,
2700                                     const char *driver_ver)
2701{
2702        struct ixgbe_hic_drv_info2 fw_cmd;
2703        s32 ret_val;
2704        int i;
2705
2706        if (!len || !driver_ver || (len > sizeof(fw_cmd.driver_string)))
2707                return IXGBE_ERR_INVALID_ARGUMENT;
2708
2709        fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
2710        fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len;
2711        fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
2712        fw_cmd.port_num = (u8)hw->bus.func;
2713        fw_cmd.ver_maj = maj;
2714        fw_cmd.ver_min = min;
2715        fw_cmd.ver_build = build;
2716        fw_cmd.ver_sub = sub;
2717        fw_cmd.hdr.checksum = 0;
2718        memcpy(fw_cmd.driver_string, driver_ver, len);
2719        fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
2720                              (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
2721
2722        for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
2723                ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
2724                                                       sizeof(fw_cmd),
2725                                                       IXGBE_HI_COMMAND_TIMEOUT,
2726                                                       true);
2727                if (ret_val)
2728                        continue;
2729
2730                if (fw_cmd.hdr.cmd_or_resp.ret_status !=
2731                    FW_CEM_RESP_STATUS_SUCCESS)
2732                        return IXGBE_ERR_HOST_INTERFACE_COMMAND;
2733                return 0;
2734        }
2735
2736        return ret_val;
2737}
2738
2739/** ixgbe_get_lcd_x550em - Determine lowest common denominator
2740 *  @hw: pointer to hardware structure
2741 *  @lcd_speed: pointer to lowest common link speed
2742 *
2743 *  Determine lowest common link speed with link partner.
2744 **/
2745static s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw,
2746                                  ixgbe_link_speed *lcd_speed)
2747{
2748        u16 an_lp_status;
2749        s32 status;
2750        u16 word = hw->eeprom.ctrl_word_3;
2751
2752        *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN;
2753
2754        status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS,
2755                                      MDIO_MMD_AN,
2756                                      &an_lp_status);
2757        if (status)
2758                return status;
2759
2760        /* If link partner advertised 1G, return 1G */
2761        if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) {
2762                *lcd_speed = IXGBE_LINK_SPEED_1GB_FULL;
2763                return status;
2764        }
2765
2766        /* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */
2767        if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) ||
2768            (word & NVM_INIT_CTRL_3_D10GMP_PORT0))
2769                return status;
2770
2771        /* Link partner not capable of lower speeds, return 10G */
2772        *lcd_speed = IXGBE_LINK_SPEED_10GB_FULL;
2773        return status;
2774}
2775
2776/**
2777 * ixgbe_setup_fc_x550em - Set up flow control
2778 * @hw: pointer to hardware structure
2779 */
2780static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *hw)
2781{
2782        bool pause, asm_dir;
2783        u32 reg_val;
2784        s32 rc;
2785
2786        /* Validate the requested mode */
2787        if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
2788                hw_err(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
2789                return IXGBE_ERR_INVALID_LINK_SETTINGS;
2790        }
2791
2792        /* 10gig parts do not have a word in the EEPROM to determine the
2793         * default flow control setting, so we explicitly set it to full.
2794         */
2795        if (hw->fc.requested_mode == ixgbe_fc_default)
2796                hw->fc.requested_mode = ixgbe_fc_full;
2797
2798        /* Determine PAUSE and ASM_DIR bits. */
2799        switch (hw->fc.requested_mode) {
2800        case ixgbe_fc_none:
2801                pause = false;
2802                asm_dir = false;
2803                break;
2804        case ixgbe_fc_tx_pause:
2805                pause = false;
2806                asm_dir = true;
2807                break;
2808        case ixgbe_fc_rx_pause:
2809                /* Rx Flow control is enabled and Tx Flow control is
2810                 * disabled by software override. Since there really
2811                 * isn't a way to advertise that we are capable of RX
2812                 * Pause ONLY, we will advertise that we support both
2813                 * symmetric and asymmetric Rx PAUSE, as such we fall
2814                 * through to the fc_full statement.  Later, we will
2815                 * disable the adapter's ability to send PAUSE frames.
2816                 */
2817                /* Fallthrough */
2818        case ixgbe_fc_full:
2819                pause = true;
2820                asm_dir = true;
2821                break;
2822        default:
2823                hw_err(hw, "Flow control param set incorrectly\n");
2824                return IXGBE_ERR_CONFIG;
2825        }
2826
2827        if (hw->device_id != IXGBE_DEV_ID_X550EM_X_KR &&
2828            hw->device_id != IXGBE_DEV_ID_X550EM_A_KR &&
2829            hw->device_id != IXGBE_DEV_ID_X550EM_A_KR_L)
2830                return 0;
2831
2832        rc = hw->mac.ops.read_iosf_sb_reg(hw,
2833                                          IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
2834                                          IXGBE_SB_IOSF_TARGET_KR_PHY,
2835                                          &reg_val);
2836        if (rc)
2837                return rc;
2838
2839        reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
2840                     IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
2841        if (pause)
2842                reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
2843        if (asm_dir)
2844                reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
2845        rc = hw->mac.ops.write_iosf_sb_reg(hw,
2846                                           IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
2847                                           IXGBE_SB_IOSF_TARGET_KR_PHY,
2848                                           reg_val);
2849
2850        /* This device does not fully support AN. */
2851        hw->fc.disable_fc_autoneg = true;
2852
2853        return rc;
2854}
2855
2856/**
2857 *  ixgbe_fc_autoneg_backplane_x550em_a - Enable flow control IEEE clause 37
2858 *  @hw: pointer to hardware structure
2859 **/
2860static void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw)
2861{
2862        u32 link_s1, lp_an_page_low, an_cntl_1;
2863        s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
2864        ixgbe_link_speed speed;
2865        bool link_up;
2866
2867        /* AN should have completed when the cable was plugged in.
2868         * Look for reasons to bail out.  Bail out if:
2869         * - FC autoneg is disabled, or if
2870         * - link is not up.
2871         */
2872        if (hw->fc.disable_fc_autoneg) {
2873                hw_err(hw, "Flow control autoneg is disabled");
2874                goto out;
2875        }
2876
2877        hw->mac.ops.check_link(hw, &speed, &link_up, false);
2878        if (!link_up) {
2879                hw_err(hw, "The link is down");
2880                goto out;
2881        }
2882
2883        /* Check at auto-negotiation has completed */
2884        status = hw->mac.ops.read_iosf_sb_reg(hw,
2885                                        IXGBE_KRM_LINK_S1(hw->bus.lan_id),
2886                                        IXGBE_SB_IOSF_TARGET_KR_PHY, &link_s1);
2887
2888        if (status || (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) {
2889                hw_dbg(hw, "Auto-Negotiation did not complete\n");
2890                status = IXGBE_ERR_FC_NOT_NEGOTIATED;
2891                goto out;
2892        }
2893
2894        /* Read the 10g AN autoc and LP ability registers and resolve
2895         * local flow control settings accordingly
2896         */
2897        status = hw->mac.ops.read_iosf_sb_reg(hw,
2898                                IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
2899                                IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl_1);
2900
2901        if (status) {
2902                hw_dbg(hw, "Auto-Negotiation did not complete\n");
2903                goto out;
2904        }
2905
2906        status = hw->mac.ops.read_iosf_sb_reg(hw,
2907                                IXGBE_KRM_LP_BASE_PAGE_HIGH(hw->bus.lan_id),
2908                                IXGBE_SB_IOSF_TARGET_KR_PHY, &lp_an_page_low);
2909
2910        if (status) {
2911                hw_dbg(hw, "Auto-Negotiation did not complete\n");
2912                goto out;
2913        }
2914
2915        status = ixgbe_negotiate_fc(hw, an_cntl_1, lp_an_page_low,
2916                                    IXGBE_KRM_AN_CNTL_1_SYM_PAUSE,
2917                                    IXGBE_KRM_AN_CNTL_1_ASM_PAUSE,
2918                                    IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE,
2919                                    IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE);
2920
2921out:
2922        if (!status) {
2923                hw->fc.fc_was_autonegged = true;
2924        } else {
2925                hw->fc.fc_was_autonegged = false;
2926                hw->fc.current_mode = hw->fc.requested_mode;
2927        }
2928}
2929
2930/**
2931 *  ixgbe_fc_autoneg_fiber_x550em_a - passthrough FC settings
2932 *  @hw: pointer to hardware structure
2933 **/
2934static void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw)
2935{
2936        hw->fc.fc_was_autonegged = false;
2937        hw->fc.current_mode = hw->fc.requested_mode;
2938}
2939
2940/** ixgbe_enter_lplu_x550em - Transition to low power states
2941 *  @hw: pointer to hardware structure
2942 *
2943 *  Configures Low Power Link Up on transition to low power states
2944 *  (from D0 to non-D0). Link is required to enter LPLU so avoid resetting
2945 *  the X557 PHY immediately prior to entering LPLU.
2946 **/
2947static s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
2948{
2949        u16 an_10g_cntl_reg, autoneg_reg, speed;
2950        s32 status;
2951        ixgbe_link_speed lcd_speed;
2952        u32 save_autoneg;
2953        bool link_up;
2954
2955        /* If blocked by MNG FW, then don't restart AN */
2956        if (ixgbe_check_reset_blocked(hw))
2957                return 0;
2958
2959        status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
2960        if (status)
2961                return status;
2962
2963        status = hw->eeprom.ops.read(hw, NVM_INIT_CTRL_3,
2964                                     &hw->eeprom.ctrl_word_3);
2965        if (status)
2966                return status;
2967
2968        /* If link is down, LPLU disabled in NVM, WoL disabled, or
2969         * manageability disabled, then force link down by entering
2970         * low power mode.
2971         */
2972        if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) ||
2973            !(hw->wol_enabled || ixgbe_mng_present(hw)))
2974                return ixgbe_set_copper_phy_power(hw, false);
2975
2976        /* Determine LCD */
2977        status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed);
2978        if (status)
2979                return status;
2980
2981        /* If no valid LCD link speed, then force link down and exit. */
2982        if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN)
2983                return ixgbe_set_copper_phy_power(hw, false);
2984
2985        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
2986                                      MDIO_MMD_AN,
2987                                      &speed);
2988        if (status)
2989                return status;
2990
2991        /* If no link now, speed is invalid so take link down */
2992        status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
2993        if (status)
2994                return ixgbe_set_copper_phy_power(hw, false);
2995
2996        /* clear everything but the speed bits */
2997        speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK;
2998
2999        /* If current speed is already LCD, then exit. */
3000        if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) &&
3001             (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) ||
3002            ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) &&
3003             (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL)))
3004                return status;
3005
3006        /* Clear AN completed indication */
3007        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM,
3008                                      MDIO_MMD_AN,
3009                                      &autoneg_reg);
3010        if (status)
3011                return status;
3012
3013        status = hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL,
3014                                      MDIO_MMD_AN,
3015                                      &an_10g_cntl_reg);
3016        if (status)
3017                return status;
3018
3019        status = hw->phy.ops.read_reg(hw,
3020                                      IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
3021                                      MDIO_MMD_AN,
3022                                      &autoneg_reg);
3023        if (status)
3024                return status;
3025
3026        save_autoneg = hw->phy.autoneg_advertised;
3027
3028        /* Setup link at least common link speed */
3029        status = hw->mac.ops.setup_link(hw, lcd_speed, false);
3030
3031        /* restore autoneg from before setting lplu speed */
3032        hw->phy.autoneg_advertised = save_autoneg;
3033
3034        return status;
3035}
3036
3037/**
3038 * ixgbe_reset_phy_fw - Reset firmware-controlled PHYs
3039 * @hw: pointer to hardware structure
3040 */
3041static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw)
3042{
3043        u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
3044        s32 rc;
3045
3046        if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
3047                return 0;
3048
3049        rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_PHY_SW_RESET, &store);
3050        if (rc)
3051                return rc;
3052        memset(store, 0, sizeof(store));
3053
3054        rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_INIT_PHY, &store);
3055        if (rc)
3056                return rc;
3057
3058        return ixgbe_setup_fw_link(hw);
3059}
3060
3061/**
3062 * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp
3063 * @hw: pointer to hardware structure
3064 */
3065static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw)
3066{
3067        u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
3068        s32 rc;
3069
3070        rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store);
3071        if (rc)
3072                return rc;
3073
3074        if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) {
3075                ixgbe_shutdown_fw_phy(hw);
3076                return IXGBE_ERR_OVERTEMP;
3077        }
3078        return 0;
3079}
3080
3081/**
3082 * ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register
3083 * @hw: pointer to hardware structure
3084 *
3085 * Read NW_MNG_IF_SEL register and save field values.
3086 */
3087static void ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw)
3088{
3089        /* Save NW management interface connected on board. This is used
3090         * to determine internal PHY mode.
3091         */
3092        hw->phy.nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
3093
3094        /* If X552 (X550EM_a) and MDIO is connected to external PHY, then set
3095         * PHY address. This register field was has only been used for X552.
3096         */
3097        if (hw->mac.type == ixgbe_mac_x550em_a &&
3098            hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_MDIO_ACT) {
3099                hw->phy.mdio.prtad = (hw->phy.nw_mng_if_sel &
3100                                      IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >>
3101                                     IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT;
3102        }
3103}
3104
3105/** ixgbe_init_phy_ops_X550em - PHY/SFP specific init
3106 *  @hw: pointer to hardware structure
3107 *
3108 *  Initialize any function pointers that were not able to be
3109 *  set during init_shared_code because the PHY/SFP type was
3110 *  not known.  Perform the SFP init if necessary.
3111 **/
3112static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
3113{
3114        struct ixgbe_phy_info *phy = &hw->phy;
3115        s32 ret_val;
3116
3117        hw->mac.ops.set_lan_id(hw);
3118
3119        ixgbe_read_mng_if_sel_x550em(hw);
3120
3121        if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
3122                phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
3123                ixgbe_setup_mux_ctl(hw);
3124        }
3125
3126        /* Identify the PHY or SFP module */
3127        ret_val = phy->ops.identify(hw);
3128
3129        /* Setup function pointers based on detected hardware */
3130        ixgbe_init_mac_link_ops_X550em(hw);
3131        if (phy->sfp_type != ixgbe_sfp_type_unknown)
3132                phy->ops.reset = NULL;
3133
3134        /* Set functions pointers based on phy type */
3135        switch (hw->phy.type) {
3136        case ixgbe_phy_x550em_kx4:
3137                phy->ops.setup_link = ixgbe_setup_kx4_x550em;
3138                phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
3139                phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
3140                break;
3141        case ixgbe_phy_x550em_kr:
3142                phy->ops.setup_link = ixgbe_setup_kr_x550em;
3143                phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
3144                phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
3145                break;
3146        case ixgbe_phy_x550em_ext_t:
3147                /* Save NW management interface connected on board. This is used
3148                 * to determine internal PHY mode
3149                 */
3150                phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
3151
3152                /* If internal link mode is XFI, then setup iXFI internal link,
3153                 * else setup KR now.
3154                 */
3155                phy->ops.setup_internal_link =
3156                                              ixgbe_setup_internal_phy_t_x550em;
3157
3158                /* setup SW LPLU only for first revision */
3159                if (hw->mac.type == ixgbe_mac_X550EM_x &&
3160                    !(IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)) &
3161                      IXGBE_FUSES0_REV_MASK))
3162                        phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
3163
3164                phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
3165                phy->ops.reset = ixgbe_reset_phy_t_X550em;
3166                break;
3167        case ixgbe_phy_fw:
3168                phy->ops.setup_link = ixgbe_setup_fw_link;
3169                phy->ops.reset = ixgbe_reset_phy_fw;
3170                break;
3171        default:
3172                break;
3173        }
3174
3175        return ret_val;
3176}
3177
3178/** ixgbe_get_media_type_X550em - Get media type
3179 *  @hw: pointer to hardware structure
3180 *
3181 *  Returns the media type (fiber, copper, backplane)
3182 *
3183 */
3184static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
3185{
3186        enum ixgbe_media_type media_type;
3187
3188        /* Detect if there is a copper PHY attached. */
3189        switch (hw->device_id) {
3190        case IXGBE_DEV_ID_X550EM_A_SGMII:
3191        case IXGBE_DEV_ID_X550EM_A_SGMII_L:
3192                hw->phy.type = ixgbe_phy_sgmii;
3193                /* Fallthrough */
3194        case IXGBE_DEV_ID_X550EM_X_KR:
3195        case IXGBE_DEV_ID_X550EM_X_KX4:
3196        case IXGBE_DEV_ID_X550EM_A_KR:
3197        case IXGBE_DEV_ID_X550EM_A_KR_L:
3198                media_type = ixgbe_media_type_backplane;
3199                break;
3200        case IXGBE_DEV_ID_X550EM_X_SFP:
3201        case IXGBE_DEV_ID_X550EM_A_SFP:
3202        case IXGBE_DEV_ID_X550EM_A_SFP_N:
3203                media_type = ixgbe_media_type_fiber;
3204                break;
3205        case IXGBE_DEV_ID_X550EM_X_1G_T:
3206        case IXGBE_DEV_ID_X550EM_X_10G_T:
3207        case IXGBE_DEV_ID_X550EM_A_10G_T:
3208        case IXGBE_DEV_ID_X550EM_A_1G_T:
3209        case IXGBE_DEV_ID_X550EM_A_1G_T_L:
3210                media_type = ixgbe_media_type_copper;
3211                break;
3212        default:
3213                media_type = ixgbe_media_type_unknown;
3214                break;
3215        }
3216        return media_type;
3217}
3218
3219/** ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
3220 ** @hw: pointer to hardware structure
3221 **/
3222static s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
3223{
3224        s32 status;
3225        u16 reg;
3226
3227        status = hw->phy.ops.read_reg(hw,
3228                                      IXGBE_MDIO_TX_VENDOR_ALARMS_3,
3229                                      MDIO_MMD_PMAPMD,
3230                                      &reg);
3231        if (status)
3232                return status;
3233
3234        /* If PHY FW reset completed bit is set then this is the first
3235         * SW instance after a power on so the PHY FW must be un-stalled.
3236         */
3237        if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
3238                status = hw->phy.ops.read_reg(hw,
3239                                        IXGBE_MDIO_GLOBAL_RES_PR_10,
3240                                        MDIO_MMD_VEND1,
3241                                        &reg);
3242                if (status)
3243                        return status;
3244
3245                reg &= ~IXGBE_MDIO_POWER_UP_STALL;
3246
3247                status = hw->phy.ops.write_reg(hw,
3248                                        IXGBE_MDIO_GLOBAL_RES_PR_10,
3249                                        MDIO_MMD_VEND1,
3250                                        reg);
3251                if (status)
3252                        return status;
3253        }
3254
3255        return status;
3256}
3257
3258/**
3259 * ixgbe_set_mdio_speed - Set MDIO clock speed
3260 * @hw: pointer to hardware structure
3261 */
3262static void ixgbe_set_mdio_speed(struct ixgbe_hw *hw)
3263{
3264        u32 hlreg0;
3265
3266        switch (hw->device_id) {
3267        case IXGBE_DEV_ID_X550EM_X_10G_T:
3268        case IXGBE_DEV_ID_X550EM_A_SGMII:
3269        case IXGBE_DEV_ID_X550EM_A_SGMII_L:
3270        case IXGBE_DEV_ID_X550EM_A_10G_T:
3271        case IXGBE_DEV_ID_X550EM_A_SFP:
3272                /* Config MDIO clock speed before the first MDIO PHY access */
3273                hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
3274                hlreg0 &= ~IXGBE_HLREG0_MDCSPD;
3275                IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
3276                break;
3277        case IXGBE_DEV_ID_X550EM_A_1G_T:
3278        case IXGBE_DEV_ID_X550EM_A_1G_T_L:
3279                /* Select fast MDIO clock speed for these devices */
3280                hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
3281                hlreg0 |= IXGBE_HLREG0_MDCSPD;
3282                IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
3283                break;
3284        default:
3285                break;
3286        }
3287}
3288
3289/**  ixgbe_reset_hw_X550em - Perform hardware reset
3290 **  @hw: pointer to hardware structure
3291 **
3292 **  Resets the hardware by resetting the transmit and receive units, masks
3293 **  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
3294 **  reset.
3295 **/
3296static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
3297{
3298        ixgbe_link_speed link_speed;
3299        s32 status;
3300        u32 ctrl = 0;
3301        u32 i;
3302        bool link_up = false;
3303
3304        /* Call adapter stop to disable Tx/Rx and clear interrupts */
3305        status = hw->mac.ops.stop_adapter(hw);
3306        if (status)
3307                return status;
3308
3309        /* flush pending Tx transactions */
3310        ixgbe_clear_tx_pending(hw);
3311
3312        /* PHY ops must be identified and initialized prior to reset */
3313
3314        /* Identify PHY and related function pointers */
3315        status = hw->phy.ops.init(hw);
3316
3317        /* start the external PHY */
3318        if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
3319                status = ixgbe_init_ext_t_x550em(hw);
3320                if (status)
3321                        return status;
3322        }
3323
3324        /* Setup SFP module if there is one present. */
3325        if (hw->phy.sfp_setup_needed) {
3326                status = hw->mac.ops.setup_sfp(hw);
3327                hw->phy.sfp_setup_needed = false;
3328        }
3329
3330        /* Reset PHY */
3331        if (!hw->phy.reset_disable && hw->phy.ops.reset)
3332                hw->phy.ops.reset(hw);
3333
3334mac_reset_top:
3335        /* Issue global reset to the MAC.  Needs to be SW reset if link is up.
3336         * If link reset is used when link is up, it might reset the PHY when
3337         * mng is using it.  If link is down or the flag to force full link
3338         * reset is set, then perform link reset.
3339         */
3340        ctrl = IXGBE_CTRL_LNK_RST;
3341
3342        if (!hw->force_full_reset) {
3343                hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
3344                if (link_up)
3345                        ctrl = IXGBE_CTRL_RST;
3346        }
3347
3348        ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
3349        IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
3350        IXGBE_WRITE_FLUSH(hw);
3351        usleep_range(1000, 1200);
3352
3353        /* Poll for reset bit to self-clear meaning reset is complete */
3354        for (i = 0; i < 10; i++) {
3355                ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
3356                if (!(ctrl & IXGBE_CTRL_RST_MASK))
3357                        break;
3358                udelay(1);
3359        }
3360
3361        if (ctrl & IXGBE_CTRL_RST_MASK) {
3362                status = IXGBE_ERR_RESET_FAILED;
3363                hw_dbg(hw, "Reset polling failed to complete.\n");
3364        }
3365
3366        msleep(50);
3367
3368        /* Double resets are required for recovery from certain error
3369         * clear the multicast table.  Also reset num_rar_entries to 128,
3370         * since we modify this value when programming the SAN MAC address.
3371         */
3372        if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
3373                hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
3374                goto mac_reset_top;
3375        }
3376
3377        /* Store the permanent mac address */
3378        hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
3379
3380        /* Store MAC address from RAR0, clear receive address registers, and
3381         * clear the multicast table.  Also reset num_rar_entries to 128,
3382         * since we modify this value when programming the SAN MAC address.
3383         */
3384        hw->mac.num_rar_entries = 128;
3385        hw->mac.ops.init_rx_addrs(hw);
3386
3387        ixgbe_set_mdio_speed(hw);
3388
3389        if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
3390                ixgbe_setup_mux_ctl(hw);
3391
3392        return status;
3393}
3394
3395/** ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype
3396 *      anti-spoofing
3397 *  @hw:  pointer to hardware structure
3398 *  @enable: enable or disable switch for Ethertype anti-spoofing
3399 *  @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing
3400 **/
3401static void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
3402                                                   bool enable, int vf)
3403{
3404        int vf_target_reg = vf >> 3;
3405        int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT;
3406        u32 pfvfspoof;
3407
3408        pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
3409        if (enable)
3410                pfvfspoof |= BIT(vf_target_shift);
3411        else
3412                pfvfspoof &= ~BIT(vf_target_shift);
3413
3414        IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
3415}
3416
3417/** ixgbe_set_source_address_pruning_X550 - Enable/Disbale src address pruning
3418 *  @hw: pointer to hardware structure
3419 *  @enable: enable or disable source address pruning
3420 *  @pool: Rx pool to set source address pruning for
3421 **/
3422static void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw,
3423                                                  bool enable,
3424                                                  unsigned int pool)
3425{
3426        u64 pfflp;
3427
3428        /* max rx pool is 63 */
3429        if (pool > 63)
3430                return;
3431
3432        pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
3433        pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
3434
3435        if (enable)
3436                pfflp |= (1ULL << pool);
3437        else
3438                pfflp &= ~(1ULL << pool);
3439
3440        IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp);
3441        IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
3442}
3443
3444/**
3445 *  ixgbe_setup_fc_backplane_x550em_a - Set up flow control
3446 *  @hw: pointer to hardware structure
3447 *
3448 *  Called at init time to set up flow control.
3449 **/
3450static s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw)
3451{
3452        s32 status = 0;
3453        u32 an_cntl = 0;
3454
3455        /* Validate the requested mode */
3456        if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
3457                hw_err(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
3458                return IXGBE_ERR_INVALID_LINK_SETTINGS;
3459        }
3460
3461        if (hw->fc.requested_mode == ixgbe_fc_default)
3462                hw->fc.requested_mode = ixgbe_fc_full;
3463
3464        /* Set up the 1G and 10G flow control advertisement registers so the
3465         * HW will be able to do FC autoneg once the cable is plugged in.  If
3466         * we link at 10G, the 1G advertisement is harmless and vice versa.
3467         */
3468        status = hw->mac.ops.read_iosf_sb_reg(hw,
3469                                        IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
3470                                        IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl);
3471
3472        if (status) {
3473                hw_dbg(hw, "Auto-Negotiation did not complete\n");
3474                return status;
3475        }
3476
3477        /* The possible values of fc.requested_mode are:
3478         * 0: Flow control is completely disabled
3479         * 1: Rx flow control is enabled (we can receive pause frames,
3480         *    but not send pause frames).
3481         * 2: Tx flow control is enabled (we can send pause frames but
3482         *    we do not support receiving pause frames).
3483         * 3: Both Rx and Tx flow control (symmetric) are enabled.
3484         * other: Invalid.
3485         */
3486        switch (hw->fc.requested_mode) {
3487        case ixgbe_fc_none:
3488                /* Flow control completely disabled by software override. */
3489                an_cntl &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
3490                             IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
3491                break;
3492        case ixgbe_fc_tx_pause:
3493                /* Tx Flow control is enabled, and Rx Flow control is
3494                 * disabled by software override.
3495                 */
3496                an_cntl |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
3497                an_cntl &= ~IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
3498                break;
3499        case ixgbe_fc_rx_pause:
3500                /* Rx Flow control is enabled and Tx Flow control is
3501                 * disabled by software override. Since there really
3502                 * isn't a way to advertise that we are capable of RX
3503                 * Pause ONLY, we will advertise that we support both
3504                 * symmetric and asymmetric Rx PAUSE, as such we fall
3505                 * through to the fc_full statement.  Later, we will
3506                 * disable the adapter's ability to send PAUSE frames.
3507                 */
3508        case ixgbe_fc_full:
3509                /* Flow control (both Rx and Tx) is enabled by SW override. */
3510                an_cntl |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
3511                           IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
3512                break;
3513        default:
3514                hw_err(hw, "Flow control param set incorrectly\n");
3515                return IXGBE_ERR_CONFIG;
3516        }
3517
3518        status = hw->mac.ops.write_iosf_sb_reg(hw,
3519                                        IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
3520                                        IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl);
3521
3522        /* Restart auto-negotiation. */
3523        status = ixgbe_restart_an_internal_phy_x550em(hw);
3524
3525        return status;
3526}
3527
3528/**
3529 * ixgbe_set_mux - Set mux for port 1 access with CS4227
3530 * @hw: pointer to hardware structure
3531 * @state: set mux if 1, clear if 0
3532 */
3533static void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state)
3534{
3535        u32 esdp;
3536
3537        if (!hw->bus.lan_id)
3538                return;
3539        esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
3540        if (state)
3541                esdp |= IXGBE_ESDP_SDP1;
3542        else
3543                esdp &= ~IXGBE_ESDP_SDP1;
3544        IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
3545        IXGBE_WRITE_FLUSH(hw);
3546}
3547
3548/**
3549 * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
3550 * @hw: pointer to hardware structure
3551 * @mask: Mask to specify which semaphore to acquire
3552 *
3553 * Acquires the SWFW semaphore and sets the I2C MUX
3554 */
3555static s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
3556{
3557        s32 status;
3558
3559        status = ixgbe_acquire_swfw_sync_X540(hw, mask);
3560        if (status)
3561                return status;
3562
3563        if (mask & IXGBE_GSSR_I2C_MASK)
3564                ixgbe_set_mux(hw, 1);
3565
3566        return 0;
3567}
3568
3569/**
3570 * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
3571 * @hw: pointer to hardware structure
3572 * @mask: Mask to specify which semaphore to release
3573 *
3574 * Releases the SWFW semaphore and sets the I2C MUX
3575 */
3576static void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
3577{
3578        if (mask & IXGBE_GSSR_I2C_MASK)
3579                ixgbe_set_mux(hw, 0);
3580
3581        ixgbe_release_swfw_sync_X540(hw, mask);
3582}
3583
3584/**
3585 * ixgbe_acquire_swfw_sync_x550em_a - Acquire SWFW semaphore
3586 * @hw: pointer to hardware structure
3587 * @mask: Mask to specify which semaphore to acquire
3588 *
3589 * Acquires the SWFW semaphore and get the shared PHY token as needed
3590 */
3591static s32 ixgbe_acquire_swfw_sync_x550em_a(struct ixgbe_hw *hw, u32 mask)
3592{
3593        u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
3594        int retries = FW_PHY_TOKEN_RETRIES;
3595        s32 status;
3596
3597        while (--retries) {
3598                status = 0;
3599                if (hmask)
3600                        status = ixgbe_acquire_swfw_sync_X540(hw, hmask);
3601                if (status)
3602                        return status;
3603                if (!(mask & IXGBE_GSSR_TOKEN_SM))
3604                        return 0;
3605
3606                status = ixgbe_get_phy_token(hw);
3607                if (!status)
3608                        return 0;
3609                if (hmask)
3610                        ixgbe_release_swfw_sync_X540(hw, hmask);
3611                if (status != IXGBE_ERR_TOKEN_RETRY)
3612                        return status;
3613                msleep(FW_PHY_TOKEN_DELAY);
3614        }
3615
3616        return status;
3617}
3618
3619/**
3620 * ixgbe_release_swfw_sync_x550em_a - Release SWFW semaphore
3621 * @hw: pointer to hardware structure
3622 * @mask: Mask to specify which semaphore to release
3623 *
3624 * Release the SWFW semaphore and puts the shared PHY token as needed
3625 */
3626static void ixgbe_release_swfw_sync_x550em_a(struct ixgbe_hw *hw, u32 mask)
3627{
3628        u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
3629
3630        if (mask & IXGBE_GSSR_TOKEN_SM)
3631                ixgbe_put_phy_token(hw);
3632
3633        if (hmask)
3634                ixgbe_release_swfw_sync_X540(hw, hmask);
3635}
3636
3637/**
3638 * ixgbe_read_phy_reg_x550a - Reads specified PHY register
3639 * @hw: pointer to hardware structure
3640 * @reg_addr: 32 bit address of PHY register to read
3641 * @phy_data: Pointer to read data from PHY register
3642 *
3643 * Reads a value from a specified PHY register using the SWFW lock and PHY
3644 * Token. The PHY Token is needed since the MDIO is shared between to MAC
3645 * instances.
3646 */
3647static s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
3648                                    u32 device_type, u16 *phy_data)
3649{
3650        u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
3651        s32 status;
3652
3653        if (hw->mac.ops.acquire_swfw_sync(hw, mask))
3654                return IXGBE_ERR_SWFW_SYNC;
3655
3656        status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data);
3657
3658        hw->mac.ops.release_swfw_sync(hw, mask);
3659
3660        return status;
3661}
3662
3663/**
3664 * ixgbe_write_phy_reg_x550a - Writes specified PHY register
3665 * @hw: pointer to hardware structure
3666 * @reg_addr: 32 bit PHY register to write
3667 * @device_type: 5 bit device type
3668 * @phy_data: Data to write to the PHY register
3669 *
3670 * Writes a value to specified PHY register using the SWFW lock and PHY Token.
3671 * The PHY Token is needed since the MDIO is shared between to MAC instances.
3672 */
3673static s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
3674                                     u32 device_type, u16 phy_data)
3675{
3676        u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
3677        s32 status;
3678
3679        if (hw->mac.ops.acquire_swfw_sync(hw, mask))
3680                return IXGBE_ERR_SWFW_SYNC;
3681
3682        status = ixgbe_write_phy_reg_mdi(hw, reg_addr, device_type, phy_data);
3683        hw->mac.ops.release_swfw_sync(hw, mask);
3684
3685        return status;
3686}
3687
3688#define X550_COMMON_MAC \
3689        .init_hw                        = &ixgbe_init_hw_generic, \
3690        .start_hw                       = &ixgbe_start_hw_X540, \
3691        .clear_hw_cntrs                 = &ixgbe_clear_hw_cntrs_generic, \
3692        .enable_rx_dma                  = &ixgbe_enable_rx_dma_generic, \
3693        .get_mac_addr                   = &ixgbe_get_mac_addr_generic, \
3694        .get_device_caps                = &ixgbe_get_device_caps_generic, \
3695        .stop_adapter                   = &ixgbe_stop_adapter_generic, \
3696        .set_lan_id                     = &ixgbe_set_lan_id_multi_port_pcie, \
3697        .read_analog_reg8               = NULL, \
3698        .write_analog_reg8              = NULL, \
3699        .set_rxpba                      = &ixgbe_set_rxpba_generic, \
3700        .check_link                     = &ixgbe_check_mac_link_generic, \
3701        .blink_led_start                = &ixgbe_blink_led_start_X540, \
3702        .blink_led_stop                 = &ixgbe_blink_led_stop_X540, \
3703        .set_rar                        = &ixgbe_set_rar_generic, \
3704        .clear_rar                      = &ixgbe_clear_rar_generic, \
3705        .set_vmdq                       = &ixgbe_set_vmdq_generic, \
3706        .set_vmdq_san_mac               = &ixgbe_set_vmdq_san_mac_generic, \
3707        .clear_vmdq                     = &ixgbe_clear_vmdq_generic, \
3708        .init_rx_addrs                  = &ixgbe_init_rx_addrs_generic, \
3709        .update_mc_addr_list            = &ixgbe_update_mc_addr_list_generic, \
3710        .enable_mc                      = &ixgbe_enable_mc_generic, \
3711        .disable_mc                     = &ixgbe_disable_mc_generic, \
3712        .clear_vfta                     = &ixgbe_clear_vfta_generic, \
3713        .set_vfta                       = &ixgbe_set_vfta_generic, \
3714        .fc_enable                      = &ixgbe_fc_enable_generic, \
3715        .set_fw_drv_ver                 = &ixgbe_set_fw_drv_ver_x550, \
3716        .init_uta_tables                = &ixgbe_init_uta_tables_generic, \
3717        .set_mac_anti_spoofing          = &ixgbe_set_mac_anti_spoofing, \
3718        .set_vlan_anti_spoofing         = &ixgbe_set_vlan_anti_spoofing, \
3719        .set_source_address_pruning     = \
3720                                &ixgbe_set_source_address_pruning_X550, \
3721        .set_ethertype_anti_spoofing    = \
3722                                &ixgbe_set_ethertype_anti_spoofing_X550, \
3723        .disable_rx_buff                = &ixgbe_disable_rx_buff_generic, \
3724        .enable_rx_buff                 = &ixgbe_enable_rx_buff_generic, \
3725        .get_thermal_sensor_data        = NULL, \
3726        .init_thermal_sensor_thresh     = NULL, \
3727        .enable_rx                      = &ixgbe_enable_rx_generic, \
3728        .disable_rx                     = &ixgbe_disable_rx_x550, \
3729
3730static const struct ixgbe_mac_operations mac_ops_X550 = {
3731        X550_COMMON_MAC
3732        .led_on                 = ixgbe_led_on_generic,
3733        .led_off                = ixgbe_led_off_generic,
3734        .init_led_link_act      = ixgbe_init_led_link_act_generic,
3735        .reset_hw               = &ixgbe_reset_hw_X540,
3736        .get_media_type         = &ixgbe_get_media_type_X540,
3737        .get_san_mac_addr       = &ixgbe_get_san_mac_addr_generic,
3738        .get_wwn_prefix         = &ixgbe_get_wwn_prefix_generic,
3739        .setup_link             = &ixgbe_setup_mac_link_X540,
3740        .get_link_capabilities  = &ixgbe_get_copper_link_capabilities_generic,
3741        .get_bus_info           = &ixgbe_get_bus_info_generic,
3742        .setup_sfp              = NULL,
3743        .acquire_swfw_sync      = &ixgbe_acquire_swfw_sync_X540,
3744        .release_swfw_sync      = &ixgbe_release_swfw_sync_X540,
3745        .init_swfw_sync         = &ixgbe_init_swfw_sync_X540,
3746        .prot_autoc_read        = prot_autoc_read_generic,
3747        .prot_autoc_write       = prot_autoc_write_generic,
3748        .setup_fc               = ixgbe_setup_fc_generic,
3749        .fc_autoneg             = ixgbe_fc_autoneg,
3750};
3751
3752static const struct ixgbe_mac_operations mac_ops_X550EM_x = {
3753        X550_COMMON_MAC
3754        .led_on                 = ixgbe_led_on_t_x550em,
3755        .led_off                = ixgbe_led_off_t_x550em,
3756        .init_led_link_act      = ixgbe_init_led_link_act_generic,
3757        .reset_hw               = &ixgbe_reset_hw_X550em,
3758        .get_media_type         = &ixgbe_get_media_type_X550em,
3759        .get_san_mac_addr       = NULL,
3760        .get_wwn_prefix         = NULL,
3761        .setup_link             = &ixgbe_setup_mac_link_X540,
3762        .get_link_capabilities  = &ixgbe_get_link_capabilities_X550em,
3763        .get_bus_info           = &ixgbe_get_bus_info_X550em,
3764        .setup_sfp              = ixgbe_setup_sfp_modules_X550em,
3765        .acquire_swfw_sync      = &ixgbe_acquire_swfw_sync_X550em,
3766        .release_swfw_sync      = &ixgbe_release_swfw_sync_X550em,
3767        .init_swfw_sync         = &ixgbe_init_swfw_sync_X540,
3768        .setup_fc               = NULL, /* defined later */
3769        .fc_autoneg             = ixgbe_fc_autoneg,
3770        .read_iosf_sb_reg       = ixgbe_read_iosf_sb_reg_x550,
3771        .write_iosf_sb_reg      = ixgbe_write_iosf_sb_reg_x550,
3772};
3773
3774static struct ixgbe_mac_operations mac_ops_x550em_a = {
3775        X550_COMMON_MAC
3776        .led_on                 = ixgbe_led_on_t_x550em,
3777        .led_off                = ixgbe_led_off_t_x550em,
3778        .init_led_link_act      = ixgbe_init_led_link_act_generic,
3779        .reset_hw               = ixgbe_reset_hw_X550em,
3780        .get_media_type         = ixgbe_get_media_type_X550em,
3781        .get_san_mac_addr       = NULL,
3782        .get_wwn_prefix         = NULL,
3783        .setup_link             = NULL, /* defined later */
3784        .get_link_capabilities  = ixgbe_get_link_capabilities_X550em,
3785        .get_bus_info           = ixgbe_get_bus_info_X550em,
3786        .setup_sfp              = ixgbe_setup_sfp_modules_X550em,
3787        .acquire_swfw_sync      = ixgbe_acquire_swfw_sync_x550em_a,
3788        .release_swfw_sync      = ixgbe_release_swfw_sync_x550em_a,
3789        .setup_fc               = ixgbe_setup_fc_x550em,
3790        .fc_autoneg             = ixgbe_fc_autoneg,
3791        .read_iosf_sb_reg       = ixgbe_read_iosf_sb_reg_x550a,
3792        .write_iosf_sb_reg      = ixgbe_write_iosf_sb_reg_x550a,
3793};
3794
3795static struct ixgbe_mac_operations mac_ops_x550em_a_fw = {
3796        X550_COMMON_MAC
3797        .led_on                 = ixgbe_led_on_generic,
3798        .led_off                = ixgbe_led_off_generic,
3799        .init_led_link_act      = ixgbe_init_led_link_act_generic,
3800        .reset_hw               = ixgbe_reset_hw_X550em,
3801        .get_media_type         = ixgbe_get_media_type_X550em,
3802        .get_san_mac_addr       = NULL,
3803        .get_wwn_prefix         = NULL,
3804        .setup_link             = NULL, /* defined later */
3805        .get_link_capabilities  = ixgbe_get_link_capabilities_X550em,
3806        .get_bus_info           = ixgbe_get_bus_info_X550em,
3807        .setup_sfp              = ixgbe_setup_sfp_modules_X550em,
3808        .acquire_swfw_sync      = ixgbe_acquire_swfw_sync_x550em_a,
3809        .release_swfw_sync      = ixgbe_release_swfw_sync_x550em_a,
3810        .setup_fc               = ixgbe_setup_fc_x550em,
3811        .fc_autoneg             = ixgbe_fc_autoneg,
3812        .read_iosf_sb_reg       = ixgbe_read_iosf_sb_reg_x550a,
3813        .write_iosf_sb_reg      = ixgbe_write_iosf_sb_reg_x550a,
3814};
3815
3816#define X550_COMMON_EEP \
3817        .read                   = &ixgbe_read_ee_hostif_X550, \
3818        .read_buffer            = &ixgbe_read_ee_hostif_buffer_X550, \
3819        .write                  = &ixgbe_write_ee_hostif_X550, \
3820        .write_buffer           = &ixgbe_write_ee_hostif_buffer_X550, \
3821        .validate_checksum      = &ixgbe_validate_eeprom_checksum_X550, \
3822        .update_checksum        = &ixgbe_update_eeprom_checksum_X550, \
3823        .calc_checksum          = &ixgbe_calc_eeprom_checksum_X550, \
3824
3825static const struct ixgbe_eeprom_operations eeprom_ops_X550 = {
3826        X550_COMMON_EEP
3827        .init_params            = &ixgbe_init_eeprom_params_X550,
3828};
3829
3830static const struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = {
3831        X550_COMMON_EEP
3832        .init_params            = &ixgbe_init_eeprom_params_X540,
3833};
3834
3835#define X550_COMMON_PHY \
3836        .identify_sfp           = &ixgbe_identify_module_generic, \
3837        .reset                  = NULL, \
3838        .setup_link_speed       = &ixgbe_setup_phy_link_speed_generic, \
3839        .read_i2c_byte          = &ixgbe_read_i2c_byte_generic, \
3840        .write_i2c_byte         = &ixgbe_write_i2c_byte_generic, \
3841        .read_i2c_sff8472       = &ixgbe_read_i2c_sff8472_generic, \
3842        .read_i2c_eeprom        = &ixgbe_read_i2c_eeprom_generic, \
3843        .write_i2c_eeprom       = &ixgbe_write_i2c_eeprom_generic, \
3844        .setup_link             = &ixgbe_setup_phy_link_generic, \
3845        .set_phy_power          = NULL,
3846
3847static const struct ixgbe_phy_operations phy_ops_X550 = {
3848        X550_COMMON_PHY
3849        .check_overtemp         = &ixgbe_tn_check_overtemp,
3850        .init                   = NULL,
3851        .identify               = &ixgbe_identify_phy_generic,
3852        .read_reg               = &ixgbe_read_phy_reg_generic,
3853        .write_reg              = &ixgbe_write_phy_reg_generic,
3854};
3855
3856static const struct ixgbe_phy_operations phy_ops_X550EM_x = {
3857        X550_COMMON_PHY
3858        .check_overtemp         = &ixgbe_tn_check_overtemp,
3859        .init                   = &ixgbe_init_phy_ops_X550em,
3860        .identify               = &ixgbe_identify_phy_x550em,
3861        .read_reg               = &ixgbe_read_phy_reg_generic,
3862        .write_reg              = &ixgbe_write_phy_reg_generic,
3863};
3864
3865static const struct ixgbe_phy_operations phy_ops_x550em_a = {
3866        X550_COMMON_PHY
3867        .check_overtemp         = &ixgbe_tn_check_overtemp,
3868        .init                   = &ixgbe_init_phy_ops_X550em,
3869        .identify               = &ixgbe_identify_phy_x550em,
3870        .read_reg               = &ixgbe_read_phy_reg_x550a,
3871        .write_reg              = &ixgbe_write_phy_reg_x550a,
3872        .read_reg_mdi           = &ixgbe_read_phy_reg_mdi,
3873        .write_reg_mdi          = &ixgbe_write_phy_reg_mdi,
3874};
3875
3876static const struct ixgbe_phy_operations phy_ops_x550em_a_fw = {
3877        X550_COMMON_PHY
3878        .check_overtemp         = ixgbe_check_overtemp_fw,
3879        .init                   = ixgbe_init_phy_ops_X550em,
3880        .identify               = ixgbe_identify_phy_fw,
3881        .read_reg               = NULL,
3882        .write_reg              = NULL,
3883        .read_reg_mdi           = NULL,
3884        .write_reg_mdi          = NULL,
3885};
3886
3887static const struct ixgbe_link_operations link_ops_x550em_x = {
3888        .read_link              = &ixgbe_read_i2c_combined_generic,
3889        .read_link_unlocked     = &ixgbe_read_i2c_combined_generic_unlocked,
3890        .write_link             = &ixgbe_write_i2c_combined_generic,
3891        .write_link_unlocked    = &ixgbe_write_i2c_combined_generic_unlocked,
3892};
3893
3894static const u32 ixgbe_mvals_X550[IXGBE_MVALS_IDX_LIMIT] = {
3895        IXGBE_MVALS_INIT(X550)
3896};
3897
3898static const u32 ixgbe_mvals_X550EM_x[IXGBE_MVALS_IDX_LIMIT] = {
3899        IXGBE_MVALS_INIT(X550EM_x)
3900};
3901
3902static const u32 ixgbe_mvals_x550em_a[IXGBE_MVALS_IDX_LIMIT] = {
3903        IXGBE_MVALS_INIT(X550EM_a)
3904};
3905
3906const struct ixgbe_info ixgbe_X550_info = {
3907        .mac                    = ixgbe_mac_X550,
3908        .get_invariants         = &ixgbe_get_invariants_X540,
3909        .mac_ops                = &mac_ops_X550,
3910        .eeprom_ops             = &eeprom_ops_X550,
3911        .phy_ops                = &phy_ops_X550,
3912        .mbx_ops                = &mbx_ops_generic,
3913        .mvals                  = ixgbe_mvals_X550,
3914};
3915
3916const struct ixgbe_info ixgbe_X550EM_x_info = {
3917        .mac                    = ixgbe_mac_X550EM_x,
3918        .get_invariants         = &ixgbe_get_invariants_X550_x,
3919        .mac_ops                = &mac_ops_X550EM_x,
3920        .eeprom_ops             = &eeprom_ops_X550EM_x,
3921        .phy_ops                = &phy_ops_X550EM_x,
3922        .mbx_ops                = &mbx_ops_generic,
3923        .mvals                  = ixgbe_mvals_X550EM_x,
3924        .link_ops               = &link_ops_x550em_x,
3925};
3926
3927const struct ixgbe_info ixgbe_x550em_a_info = {
3928        .mac                    = ixgbe_mac_x550em_a,
3929        .get_invariants         = &ixgbe_get_invariants_X550_a,
3930        .mac_ops                = &mac_ops_x550em_a,
3931        .eeprom_ops             = &eeprom_ops_X550EM_x,
3932        .phy_ops                = &phy_ops_x550em_a,
3933        .mbx_ops                = &mbx_ops_generic,
3934        .mvals                  = ixgbe_mvals_x550em_a,
3935};
3936
3937const struct ixgbe_info ixgbe_x550em_a_fw_info = {
3938        .mac                    = ixgbe_mac_x550em_a,
3939        .get_invariants         = ixgbe_get_invariants_X550_a_fw,
3940        .mac_ops                = &mac_ops_x550em_a_fw,
3941        .eeprom_ops             = &eeprom_ops_X550EM_x,
3942        .phy_ops                = &phy_ops_x550em_a_fw,
3943        .mbx_ops                = &mbx_ops_generic,
3944        .mvals                  = ixgbe_mvals_x550em_a,
3945};
3946