linux/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
<<
>>
Prefs
   1/*******************************************************************************
   2 *
   3 *  Intel 10 Gigabit PCI Express Linux driver
   4 *  Copyright(c) 1999 - 2015 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);
  30
  31static s32 ixgbe_get_invariants_X550_x(struct ixgbe_hw *hw)
  32{
  33        struct ixgbe_mac_info *mac = &hw->mac;
  34        struct ixgbe_phy_info *phy = &hw->phy;
  35
  36        /* Start with X540 invariants, since so simular */
  37        ixgbe_get_invariants_X540(hw);
  38
  39        if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
  40                phy->ops.set_phy_power = NULL;
  41
  42        return 0;
  43}
  44
  45/** ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
  46 *  @hw: pointer to hardware structure
  47 **/
  48static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
  49{
  50        u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
  51
  52        if (hw->bus.lan_id) {
  53                esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
  54                esdp |= IXGBE_ESDP_SDP1_DIR;
  55        }
  56        esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
  57        IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
  58        IXGBE_WRITE_FLUSH(hw);
  59}
  60
  61/**
  62 * ixgbe_read_cs4227 - Read CS4227 register
  63 * @hw: pointer to hardware structure
  64 * @reg: register number to write
  65 * @value: pointer to receive value read
  66 *
  67 * Returns status code
  68 */
  69static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
  70{
  71        return hw->phy.ops.read_i2c_combined_unlocked(hw, IXGBE_CS4227, reg,
  72                                                      value);
  73}
  74
  75/**
  76 * ixgbe_write_cs4227 - Write CS4227 register
  77 * @hw: pointer to hardware structure
  78 * @reg: register number to write
  79 * @value: value to write to register
  80 *
  81 * Returns status code
  82 */
  83static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
  84{
  85        return hw->phy.ops.write_i2c_combined_unlocked(hw, IXGBE_CS4227, reg,
  86                                                       value);
  87}
  88
  89/**
  90 * ixgbe_read_pe - Read register from port expander
  91 * @hw: pointer to hardware structure
  92 * @reg: register number to read
  93 * @value: pointer to receive read value
  94 *
  95 * Returns status code
  96 */
  97static s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
  98{
  99        s32 status;
 100
 101        status = ixgbe_read_i2c_byte_generic_unlocked(hw, reg, IXGBE_PE, value);
 102        if (status)
 103                hw_err(hw, "port expander access failed with %d\n", status);
 104        return status;
 105}
 106
 107/**
 108 * ixgbe_write_pe - Write register to port expander
 109 * @hw: pointer to hardware structure
 110 * @reg: register number to write
 111 * @value: value to write
 112 *
 113 * Returns status code
 114 */
 115static s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
 116{
 117        s32 status;
 118
 119        status = ixgbe_write_i2c_byte_generic_unlocked(hw, reg, IXGBE_PE,
 120                                                       value);
 121        if (status)
 122                hw_err(hw, "port expander access failed with %d\n", status);
 123        return status;
 124}
 125
 126/**
 127 * ixgbe_reset_cs4227 - Reset CS4227 using port expander
 128 * @hw: pointer to hardware structure
 129 *
 130 * This function assumes that the caller has acquired the proper semaphore.
 131 * Returns error code
 132 */
 133static s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
 134{
 135        s32 status;
 136        u32 retry;
 137        u16 value;
 138        u8 reg;
 139
 140        /* Trigger hard reset. */
 141        status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
 142        if (status)
 143                return status;
 144        reg |= IXGBE_PE_BIT1;
 145        status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
 146        if (status)
 147                return status;
 148
 149        status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, &reg);
 150        if (status)
 151                return status;
 152        reg &= ~IXGBE_PE_BIT1;
 153        status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
 154        if (status)
 155                return status;
 156
 157        status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
 158        if (status)
 159                return status;
 160        reg &= ~IXGBE_PE_BIT1;
 161        status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
 162        if (status)
 163                return status;
 164
 165        usleep_range(IXGBE_CS4227_RESET_HOLD, IXGBE_CS4227_RESET_HOLD + 100);
 166
 167        status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
 168        if (status)
 169                return status;
 170        reg |= IXGBE_PE_BIT1;
 171        status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
 172        if (status)
 173                return status;
 174
 175        /* Wait for the reset to complete. */
 176        msleep(IXGBE_CS4227_RESET_DELAY);
 177        for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
 178                status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
 179                                           &value);
 180                if (!status && value == IXGBE_CS4227_EEPROM_LOAD_OK)
 181                        break;
 182                msleep(IXGBE_CS4227_CHECK_DELAY);
 183        }
 184        if (retry == IXGBE_CS4227_RETRIES) {
 185                hw_err(hw, "CS4227 reset did not complete\n");
 186                return IXGBE_ERR_PHY;
 187        }
 188
 189        status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
 190        if (status || !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
 191                hw_err(hw, "CS4227 EEPROM did not load successfully\n");
 192                return IXGBE_ERR_PHY;
 193        }
 194
 195        return 0;
 196}
 197
 198/**
 199 * ixgbe_check_cs4227 - Check CS4227 and reset as needed
 200 * @hw: pointer to hardware structure
 201 */
 202static void ixgbe_check_cs4227(struct ixgbe_hw *hw)
 203{
 204        u32 swfw_mask = hw->phy.phy_semaphore_mask;
 205        s32 status;
 206        u16 value;
 207        u8 retry;
 208
 209        for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
 210                status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
 211                if (status) {
 212                        hw_err(hw, "semaphore failed with %d\n", status);
 213                        msleep(IXGBE_CS4227_CHECK_DELAY);
 214                        continue;
 215                }
 216
 217                /* Get status of reset flow. */
 218                status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
 219                if (!status && value == IXGBE_CS4227_RESET_COMPLETE)
 220                        goto out;
 221
 222                if (status || value != IXGBE_CS4227_RESET_PENDING)
 223                        break;
 224
 225                /* Reset is pending. Wait and check again. */
 226                hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 227                msleep(IXGBE_CS4227_CHECK_DELAY);
 228        }
 229        /* If still pending, assume other instance failed. */
 230        if (retry == IXGBE_CS4227_RETRIES) {
 231                status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
 232                if (status) {
 233                        hw_err(hw, "semaphore failed with %d\n", status);
 234                        return;
 235                }
 236        }
 237
 238        /* Reset the CS4227. */
 239        status = ixgbe_reset_cs4227(hw);
 240        if (status) {
 241                hw_err(hw, "CS4227 reset failed: %d", status);
 242                goto out;
 243        }
 244
 245        /* Reset takes so long, temporarily release semaphore in case the
 246         * other driver instance is waiting for the reset indication.
 247         */
 248        ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
 249                           IXGBE_CS4227_RESET_PENDING);
 250        hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 251        usleep_range(10000, 12000);
 252        status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
 253        if (status) {
 254                hw_err(hw, "semaphore failed with %d", status);
 255                return;
 256        }
 257
 258        /* Record completion for next time. */
 259        status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
 260                                    IXGBE_CS4227_RESET_COMPLETE);
 261
 262out:
 263        hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 264        msleep(hw->eeprom.semaphore_delay);
 265}
 266
 267/** ixgbe_identify_phy_x550em - Get PHY type based on device id
 268 *  @hw: pointer to hardware structure
 269 *
 270 *  Returns error code
 271 */
 272static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
 273{
 274        switch (hw->device_id) {
 275        case IXGBE_DEV_ID_X550EM_X_SFP:
 276                /* set up for CS4227 usage */
 277                hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
 278                ixgbe_setup_mux_ctl(hw);
 279                ixgbe_check_cs4227(hw);
 280                return ixgbe_identify_module_generic(hw);
 281        case IXGBE_DEV_ID_X550EM_X_KX4:
 282                hw->phy.type = ixgbe_phy_x550em_kx4;
 283                break;
 284        case IXGBE_DEV_ID_X550EM_X_KR:
 285                hw->phy.type = ixgbe_phy_x550em_kr;
 286                break;
 287        case IXGBE_DEV_ID_X550EM_X_1G_T:
 288        case IXGBE_DEV_ID_X550EM_X_10G_T:
 289                return ixgbe_identify_phy_generic(hw);
 290        default:
 291                break;
 292        }
 293        return 0;
 294}
 295
 296static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
 297                                     u32 device_type, u16 *phy_data)
 298{
 299        return IXGBE_NOT_IMPLEMENTED;
 300}
 301
 302static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
 303                                      u32 device_type, u16 phy_data)
 304{
 305        return IXGBE_NOT_IMPLEMENTED;
 306}
 307
 308/** ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
 309 *  @hw: pointer to hardware structure
 310 *
 311 *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
 312 *  ixgbe_hw struct in order to set up EEPROM access.
 313 **/
 314static s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
 315{
 316        struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
 317        u32 eec;
 318        u16 eeprom_size;
 319
 320        if (eeprom->type == ixgbe_eeprom_uninitialized) {
 321                eeprom->semaphore_delay = 10;
 322                eeprom->type = ixgbe_flash;
 323
 324                eec = IXGBE_READ_REG(hw, IXGBE_EEC(hw));
 325                eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
 326                                    IXGBE_EEC_SIZE_SHIFT);
 327                eeprom->word_size = 1 << (eeprom_size +
 328                                          IXGBE_EEPROM_WORD_SIZE_SHIFT);
 329
 330                hw_dbg(hw, "Eeprom params: type = %d, size = %d\n",
 331                       eeprom->type, eeprom->word_size);
 332        }
 333
 334        return 0;
 335}
 336
 337/**
 338 * ixgbe_iosf_wait - Wait for IOSF command completion
 339 * @hw: pointer to hardware structure
 340 * @ctrl: pointer to location to receive final IOSF control value
 341 *
 342 * Return: failing status on timeout
 343 *
 344 * Note: ctrl can be NULL if the IOSF control register value is not needed
 345 */
 346static s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl)
 347{
 348        u32 i, command;
 349
 350        /* Check every 10 usec to see if the address cycle completed.
 351         * The SB IOSF BUSY bit will clear when the operation is
 352         * complete.
 353         */
 354        for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
 355                command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
 356                if (!(command & IXGBE_SB_IOSF_CTRL_BUSY))
 357                        break;
 358                usleep_range(10, 20);
 359        }
 360        if (ctrl)
 361                *ctrl = command;
 362        if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
 363                hw_dbg(hw, "IOSF wait timed out\n");
 364                return IXGBE_ERR_PHY;
 365        }
 366
 367        return 0;
 368}
 369
 370/** ixgbe_read_iosf_sb_reg_x550 - Writes a value to specified register of the
 371 *  IOSF device
 372 *  @hw: pointer to hardware structure
 373 *  @reg_addr: 32 bit PHY register to write
 374 *  @device_type: 3 bit device type
 375 *  @phy_data: Pointer to read data from the register
 376 **/
 377static s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
 378                                       u32 device_type, u32 *data)
 379{
 380        u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
 381        u32 command, error;
 382        s32 ret;
 383
 384        ret = hw->mac.ops.acquire_swfw_sync(hw, gssr);
 385        if (ret)
 386                return ret;
 387
 388        ret = ixgbe_iosf_wait(hw, NULL);
 389        if (ret)
 390                goto out;
 391
 392        command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
 393                   (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
 394
 395        /* Write IOSF control register */
 396        IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
 397
 398        ret = ixgbe_iosf_wait(hw, &command);
 399
 400        if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
 401                error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
 402                         IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
 403                hw_dbg(hw, "Failed to read, error %x\n", error);
 404                return IXGBE_ERR_PHY;
 405        }
 406
 407        if (!ret)
 408                *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
 409
 410out:
 411        hw->mac.ops.release_swfw_sync(hw, gssr);
 412        return ret;
 413}
 414
 415/** ixgbe_read_ee_hostif_data_X550 - Read EEPROM word using a host interface
 416 *  command assuming that the semaphore is already obtained.
 417 *  @hw: pointer to hardware structure
 418 *  @offset: offset of  word in the EEPROM to read
 419 *  @data: word read from the EEPROM
 420 *
 421 *  Reads a 16 bit word from the EEPROM using the hostif.
 422 **/
 423static s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
 424                                          u16 *data)
 425{
 426        s32 status;
 427        struct ixgbe_hic_read_shadow_ram buffer;
 428
 429        buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
 430        buffer.hdr.req.buf_lenh = 0;
 431        buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
 432        buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
 433
 434        /* convert offset from words to bytes */
 435        buffer.address = cpu_to_be32(offset * 2);
 436        /* one word */
 437        buffer.length = cpu_to_be16(sizeof(u16));
 438
 439        status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
 440                                              sizeof(buffer),
 441                                              IXGBE_HI_COMMAND_TIMEOUT, false);
 442        if (status)
 443                return status;
 444
 445        *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
 446                                          FW_NVM_DATA_OFFSET);
 447
 448        return 0;
 449}
 450
 451/** ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
 452 *  @hw: pointer to hardware structure
 453 *  @offset: offset of  word in the EEPROM to read
 454 *  @words: number of words
 455 *  @data: word(s) read from the EEPROM
 456 *
 457 *  Reads a 16 bit word(s) from the EEPROM using the hostif.
 458 **/
 459static s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
 460                                            u16 offset, u16 words, u16 *data)
 461{
 462        struct ixgbe_hic_read_shadow_ram buffer;
 463        u32 current_word = 0;
 464        u16 words_to_read;
 465        s32 status;
 466        u32 i;
 467
 468        /* Take semaphore for the entire operation. */
 469        status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 470        if (status) {
 471                hw_dbg(hw, "EEPROM read buffer - semaphore failed\n");
 472                return status;
 473        }
 474
 475        while (words) {
 476                if (words > FW_MAX_READ_BUFFER_SIZE / 2)
 477                        words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
 478                else
 479                        words_to_read = words;
 480
 481                buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
 482                buffer.hdr.req.buf_lenh = 0;
 483                buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
 484                buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
 485
 486                /* convert offset from words to bytes */
 487                buffer.address = cpu_to_be32((offset + current_word) * 2);
 488                buffer.length = cpu_to_be16(words_to_read * 2);
 489
 490                status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
 491                                                      sizeof(buffer),
 492                                                      IXGBE_HI_COMMAND_TIMEOUT,
 493                                                      false);
 494                if (status) {
 495                        hw_dbg(hw, "Host interface command failed\n");
 496                        goto out;
 497                }
 498
 499                for (i = 0; i < words_to_read; i++) {
 500                        u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
 501                                  2 * i;
 502                        u32 value = IXGBE_READ_REG(hw, reg);
 503
 504                        data[current_word] = (u16)(value & 0xffff);
 505                        current_word++;
 506                        i++;
 507                        if (i < words_to_read) {
 508                                value >>= 16;
 509                                data[current_word] = (u16)(value & 0xffff);
 510                                current_word++;
 511                        }
 512                }
 513                words -= words_to_read;
 514        }
 515
 516out:
 517        hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 518        return status;
 519}
 520
 521/** ixgbe_checksum_ptr_x550 - Checksum one pointer region
 522 *  @hw: pointer to hardware structure
 523 *  @ptr: pointer offset in eeprom
 524 *  @size: size of section pointed by ptr, if 0 first word will be used as size
 525 *  @csum: address of checksum to update
 526 *
 527 *  Returns error status for any failure
 528 **/
 529static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
 530                                   u16 size, u16 *csum, u16 *buffer,
 531                                   u32 buffer_size)
 532{
 533        u16 buf[256];
 534        s32 status;
 535        u16 length, bufsz, i, start;
 536        u16 *local_buffer;
 537
 538        bufsz = sizeof(buf) / sizeof(buf[0]);
 539
 540        /* Read a chunk at the pointer location */
 541        if (!buffer) {
 542                status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
 543                if (status) {
 544                        hw_dbg(hw, "Failed to read EEPROM image\n");
 545                        return status;
 546                }
 547                local_buffer = buf;
 548        } else {
 549                if (buffer_size < ptr)
 550                        return  IXGBE_ERR_PARAM;
 551                local_buffer = &buffer[ptr];
 552        }
 553
 554        if (size) {
 555                start = 0;
 556                length = size;
 557        } else {
 558                start = 1;
 559                length = local_buffer[0];
 560
 561                /* Skip pointer section if length is invalid. */
 562                if (length == 0xFFFF || length == 0 ||
 563                    (ptr + length) >= hw->eeprom.word_size)
 564                        return 0;
 565        }
 566
 567        if (buffer && ((u32)start + (u32)length > buffer_size))
 568                return IXGBE_ERR_PARAM;
 569
 570        for (i = start; length; i++, length--) {
 571                if (i == bufsz && !buffer) {
 572                        ptr += bufsz;
 573                        i = 0;
 574                        if (length < bufsz)
 575                                bufsz = length;
 576
 577                        /* Read a chunk at the pointer location */
 578                        status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
 579                                                                  bufsz, buf);
 580                        if (status) {
 581                                hw_dbg(hw, "Failed to read EEPROM image\n");
 582                                return status;
 583                        }
 584                }
 585                *csum += local_buffer[i];
 586        }
 587        return 0;
 588}
 589
 590/** ixgbe_calc_checksum_X550 - Calculates and returns the checksum
 591 *  @hw: pointer to hardware structure
 592 *  @buffer: pointer to buffer containing calculated checksum
 593 *  @buffer_size: size of buffer
 594 *
 595 *  Returns a negative error code on error, or the 16-bit checksum
 596 **/
 597static s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer,
 598                                    u32 buffer_size)
 599{
 600        u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
 601        u16 *local_buffer;
 602        s32 status;
 603        u16 checksum = 0;
 604        u16 pointer, i, size;
 605
 606        hw->eeprom.ops.init_params(hw);
 607
 608        if (!buffer) {
 609                /* Read pointer area */
 610                status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
 611                                                IXGBE_EEPROM_LAST_WORD + 1,
 612                                                eeprom_ptrs);
 613                if (status) {
 614                        hw_dbg(hw, "Failed to read EEPROM image\n");
 615                        return status;
 616                }
 617                local_buffer = eeprom_ptrs;
 618        } else {
 619                if (buffer_size < IXGBE_EEPROM_LAST_WORD)
 620                        return IXGBE_ERR_PARAM;
 621                local_buffer = buffer;
 622        }
 623
 624        /* For X550 hardware include 0x0-0x41 in the checksum, skip the
 625         * checksum word itself
 626         */
 627        for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
 628                if (i != IXGBE_EEPROM_CHECKSUM)
 629                        checksum += local_buffer[i];
 630
 631        /* Include all data from pointers 0x3, 0x6-0xE.  This excludes the
 632         * FW, PHY module, and PCIe Expansion/Option ROM pointers.
 633         */
 634        for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
 635                if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
 636                        continue;
 637
 638                pointer = local_buffer[i];
 639
 640                /* Skip pointer section if the pointer is invalid. */
 641                if (pointer == 0xFFFF || pointer == 0 ||
 642                    pointer >= hw->eeprom.word_size)
 643                        continue;
 644
 645                switch (i) {
 646                case IXGBE_PCIE_GENERAL_PTR:
 647                        size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
 648                        break;
 649                case IXGBE_PCIE_CONFIG0_PTR:
 650                case IXGBE_PCIE_CONFIG1_PTR:
 651                        size = IXGBE_PCIE_CONFIG_SIZE;
 652                        break;
 653                default:
 654                        size = 0;
 655                        break;
 656                }
 657
 658                status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
 659                                                 buffer, buffer_size);
 660                if (status)
 661                        return status;
 662        }
 663
 664        checksum = (u16)IXGBE_EEPROM_SUM - checksum;
 665
 666        return (s32)checksum;
 667}
 668
 669/** ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
 670 *  @hw: pointer to hardware structure
 671 *
 672 *  Returns a negative error code on error, or the 16-bit checksum
 673 **/
 674static s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
 675{
 676        return ixgbe_calc_checksum_X550(hw, NULL, 0);
 677}
 678
 679/** ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
 680 *  @hw: pointer to hardware structure
 681 *  @offset: offset of  word in the EEPROM to read
 682 *  @data: word read from the EEPROM
 683 *
 684 *   Reads a 16 bit word from the EEPROM using the hostif.
 685 **/
 686static s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data)
 687{
 688        s32 status = 0;
 689
 690        if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
 691                status = ixgbe_read_ee_hostif_data_X550(hw, offset, data);
 692                hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 693        } else {
 694                status = IXGBE_ERR_SWFW_SYNC;
 695        }
 696
 697        return status;
 698}
 699
 700/** ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
 701 *  @hw: pointer to hardware structure
 702 *  @checksum_val: calculated checksum
 703 *
 704 *  Performs checksum calculation and validates the EEPROM checksum.  If the
 705 *  caller does not need checksum_val, the value can be NULL.
 706 **/
 707static s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw,
 708                                               u16 *checksum_val)
 709{
 710        s32 status;
 711        u16 checksum;
 712        u16 read_checksum = 0;
 713
 714        /* Read the first word from the EEPROM. If this times out or fails, do
 715         * not continue or we could be in for a very long wait while every
 716         * EEPROM read fails
 717         */
 718        status = hw->eeprom.ops.read(hw, 0, &checksum);
 719        if (status) {
 720                hw_dbg(hw, "EEPROM read failed\n");
 721                return status;
 722        }
 723
 724        status = hw->eeprom.ops.calc_checksum(hw);
 725        if (status < 0)
 726                return status;
 727
 728        checksum = (u16)(status & 0xffff);
 729
 730        status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
 731                                           &read_checksum);
 732        if (status)
 733                return status;
 734
 735        /* Verify read checksum from EEPROM is the same as
 736         * calculated checksum
 737         */
 738        if (read_checksum != checksum) {
 739                status = IXGBE_ERR_EEPROM_CHECKSUM;
 740                hw_dbg(hw, "Invalid EEPROM checksum");
 741        }
 742
 743        /* If the user cares, return the calculated checksum */
 744        if (checksum_val)
 745                *checksum_val = checksum;
 746
 747        return status;
 748}
 749
 750/** ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
 751 *  @hw: pointer to hardware structure
 752 *  @offset: offset of  word in the EEPROM to write
 753 *  @data: word write to the EEPROM
 754 *
 755 *  Write a 16 bit word to the EEPROM using the hostif.
 756 **/
 757static s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
 758                                           u16 data)
 759{
 760        s32 status;
 761        struct ixgbe_hic_write_shadow_ram buffer;
 762
 763        buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
 764        buffer.hdr.req.buf_lenh = 0;
 765        buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
 766        buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
 767
 768        /* one word */
 769        buffer.length = cpu_to_be16(sizeof(u16));
 770        buffer.data = data;
 771        buffer.address = cpu_to_be32(offset * 2);
 772
 773        status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
 774                                              sizeof(buffer),
 775                                              IXGBE_HI_COMMAND_TIMEOUT, false);
 776        return status;
 777}
 778
 779/** ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
 780 *  @hw: pointer to hardware structure
 781 *  @offset: offset of  word in the EEPROM to write
 782 *  @data: word write to the EEPROM
 783 *
 784 *  Write a 16 bit word to the EEPROM using the hostif.
 785 **/
 786static s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 data)
 787{
 788        s32 status = 0;
 789
 790        if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
 791                status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
 792                hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 793        } else {
 794                hw_dbg(hw, "write ee hostif failed to get semaphore");
 795                status = IXGBE_ERR_SWFW_SYNC;
 796        }
 797
 798        return status;
 799}
 800
 801/** ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
 802 *  @hw: pointer to hardware structure
 803 *
 804 *  Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
 805 **/
 806static s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
 807{
 808        s32 status = 0;
 809        union ixgbe_hic_hdr2 buffer;
 810
 811        buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
 812        buffer.req.buf_lenh = 0;
 813        buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
 814        buffer.req.checksum = FW_DEFAULT_CHECKSUM;
 815
 816        status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
 817                                              sizeof(buffer),
 818                                              IXGBE_HI_COMMAND_TIMEOUT, false);
 819        return status;
 820}
 821
 822/**
 823 * ixgbe_get_bus_info_X550em - Set PCI bus info
 824 * @hw: pointer to hardware structure
 825 *
 826 * Sets bus link width and speed to unknown because X550em is
 827 * not a PCI device.
 828 **/
 829static s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
 830{
 831        hw->bus.type  = ixgbe_bus_type_internal;
 832        hw->bus.width = ixgbe_bus_width_unknown;
 833        hw->bus.speed = ixgbe_bus_speed_unknown;
 834
 835        hw->mac.ops.set_lan_id(hw);
 836
 837        return 0;
 838}
 839
 840/** ixgbe_disable_rx_x550 - Disable RX unit
 841 *
 842 *  Enables the Rx DMA unit for x550
 843 **/
 844static void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
 845{
 846        u32 rxctrl, pfdtxgswc;
 847        s32 status;
 848        struct ixgbe_hic_disable_rxen fw_cmd;
 849
 850        rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
 851        if (rxctrl & IXGBE_RXCTRL_RXEN) {
 852                pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
 853                if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
 854                        pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
 855                        IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
 856                        hw->mac.set_lben = true;
 857                } else {
 858                        hw->mac.set_lben = false;
 859                }
 860
 861                fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
 862                fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
 863                fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
 864                fw_cmd.port_number = (u8)hw->bus.lan_id;
 865
 866                status = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
 867                                        sizeof(struct ixgbe_hic_disable_rxen),
 868                                        IXGBE_HI_COMMAND_TIMEOUT, true);
 869
 870                /* If we fail - disable RX using register write */
 871                if (status) {
 872                        rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
 873                        if (rxctrl & IXGBE_RXCTRL_RXEN) {
 874                                rxctrl &= ~IXGBE_RXCTRL_RXEN;
 875                                IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
 876                        }
 877                }
 878        }
 879}
 880
 881/** ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
 882 *  @hw: pointer to hardware structure
 883 *
 884 *  After writing EEPROM to shadow RAM using EEWR register, software calculates
 885 *  checksum and updates the EEPROM and instructs the hardware to update
 886 *  the flash.
 887 **/
 888static s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
 889{
 890        s32 status;
 891        u16 checksum = 0;
 892
 893        /* Read the first word from the EEPROM. If this times out or fails, do
 894         * not continue or we could be in for a very long wait while every
 895         * EEPROM read fails
 896         */
 897        status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
 898        if (status) {
 899                hw_dbg(hw, "EEPROM read failed\n");
 900                return status;
 901        }
 902
 903        status = ixgbe_calc_eeprom_checksum_X550(hw);
 904        if (status < 0)
 905                return status;
 906
 907        checksum = (u16)(status & 0xffff);
 908
 909        status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
 910                                            checksum);
 911        if (status)
 912                return status;
 913
 914        status = ixgbe_update_flash_X550(hw);
 915
 916        return status;
 917}
 918
 919/** ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
 920 *  @hw: pointer to hardware structure
 921 *  @offset: offset of  word in the EEPROM to write
 922 *  @words: number of words
 923 *  @data: word(s) write to the EEPROM
 924 *
 925 *
 926 *  Write a 16 bit word(s) to the EEPROM using the hostif.
 927 **/
 928static s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
 929                                             u16 offset, u16 words,
 930                                             u16 *data)
 931{
 932        s32 status = 0;
 933        u32 i = 0;
 934
 935        /* Take semaphore for the entire operation. */
 936        status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 937        if (status) {
 938                hw_dbg(hw, "EEPROM write buffer - semaphore failed\n");
 939                return status;
 940        }
 941
 942        for (i = 0; i < words; i++) {
 943                status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
 944                                                         data[i]);
 945                if (status) {
 946                        hw_dbg(hw, "Eeprom buffered write failed\n");
 947                        break;
 948                }
 949        }
 950
 951        hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 952
 953        return status;
 954}
 955
 956/** ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register of the
 957 *  IOSF device
 958 *
 959 *  @hw: pointer to hardware structure
 960 *  @reg_addr: 32 bit PHY register to write
 961 *  @device_type: 3 bit device type
 962 *  @data: Data to write to the register
 963 **/
 964static s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
 965                                        u32 device_type, u32 data)
 966{
 967        u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
 968        u32 command, error;
 969        s32 ret;
 970
 971        ret = hw->mac.ops.acquire_swfw_sync(hw, gssr);
 972        if (ret)
 973                return ret;
 974
 975        ret = ixgbe_iosf_wait(hw, NULL);
 976        if (ret)
 977                goto out;
 978
 979        command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
 980                   (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
 981
 982        /* Write IOSF control register */
 983        IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
 984
 985        /* Write IOSF data register */
 986        IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
 987
 988        ret = ixgbe_iosf_wait(hw, &command);
 989
 990        if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
 991                error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
 992                         IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
 993                hw_dbg(hw, "Failed to write, error %x\n", error);
 994                return IXGBE_ERR_PHY;
 995        }
 996
 997out:
 998        hw->mac.ops.release_swfw_sync(hw, gssr);
 999        return ret;
1000}
1001
1002/** ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
1003 *  @hw: pointer to hardware structure
1004 *  @speed: the link speed to force
1005 *
1006 *  Configures the integrated KR PHY to use iXFI mode. Used to connect an
1007 *  internal and external PHY at a specific speed, without autonegotiation.
1008 **/
1009static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
1010{
1011        s32 status;
1012        u32 reg_val;
1013
1014        /* Disable AN and force speed to 10G Serial. */
1015        status = ixgbe_read_iosf_sb_reg_x550(hw,
1016                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1017                                        IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1018        if (status)
1019                return status;
1020
1021        reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1022        reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1023
1024        /* Select forced link speed for internal PHY. */
1025        switch (*speed) {
1026        case IXGBE_LINK_SPEED_10GB_FULL:
1027                reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
1028                break;
1029        case IXGBE_LINK_SPEED_1GB_FULL:
1030                reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1031                break;
1032        default:
1033                /* Other link speeds are not supported by internal KR PHY. */
1034                return IXGBE_ERR_LINK_SETUP;
1035        }
1036
1037        status = ixgbe_write_iosf_sb_reg_x550(hw,
1038                                IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1039                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1040        if (status)
1041                return status;
1042
1043        /* Disable training protocol FSM. */
1044        status = ixgbe_read_iosf_sb_reg_x550(hw,
1045                                IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
1046                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1047        if (status)
1048                return status;
1049
1050        reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
1051        status = ixgbe_write_iosf_sb_reg_x550(hw,
1052                                IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
1053                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1054        if (status)
1055                return status;
1056
1057        /* Disable Flex from training TXFFE. */
1058        status = ixgbe_read_iosf_sb_reg_x550(hw,
1059                                IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
1060                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1061        if (status)
1062                return status;
1063
1064        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
1065        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
1066        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
1067        status = ixgbe_write_iosf_sb_reg_x550(hw,
1068                                IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
1069                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1070        if (status)
1071                return status;
1072
1073        status = ixgbe_read_iosf_sb_reg_x550(hw,
1074                                IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
1075                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1076        if (status)
1077                return status;
1078
1079        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
1080        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
1081        reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
1082        status = ixgbe_write_iosf_sb_reg_x550(hw,
1083                                IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
1084                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1085        if (status)
1086                return status;
1087
1088        /* Enable override for coefficients. */
1089        status = ixgbe_read_iosf_sb_reg_x550(hw,
1090                                IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
1091                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1092        if (status)
1093                return status;
1094
1095        reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
1096        reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
1097        reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
1098        reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
1099        status = ixgbe_write_iosf_sb_reg_x550(hw,
1100                                IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
1101                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1102        if (status)
1103                return status;
1104
1105        /* Toggle port SW reset by AN reset. */
1106        status = ixgbe_read_iosf_sb_reg_x550(hw,
1107                                IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1108                                IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1109        if (status)
1110                return status;
1111
1112        reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
1113        status = ixgbe_write_iosf_sb_reg_x550(hw,
1114                                IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1115                                IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1116
1117        return status;
1118}
1119
1120/**
1121 *  ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
1122 *  @hw: pointer to hardware structure
1123 *  @linear: true if SFP module is linear
1124 */
1125static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
1126{
1127        switch (hw->phy.sfp_type) {
1128        case ixgbe_sfp_type_not_present:
1129                return IXGBE_ERR_SFP_NOT_PRESENT;
1130        case ixgbe_sfp_type_da_cu_core0:
1131        case ixgbe_sfp_type_da_cu_core1:
1132                *linear = true;
1133                break;
1134        case ixgbe_sfp_type_srlr_core0:
1135        case ixgbe_sfp_type_srlr_core1:
1136        case ixgbe_sfp_type_da_act_lmt_core0:
1137        case ixgbe_sfp_type_da_act_lmt_core1:
1138        case ixgbe_sfp_type_1g_sx_core0:
1139        case ixgbe_sfp_type_1g_sx_core1:
1140        case ixgbe_sfp_type_1g_lx_core0:
1141        case ixgbe_sfp_type_1g_lx_core1:
1142                *linear = false;
1143                break;
1144        case ixgbe_sfp_type_unknown:
1145        case ixgbe_sfp_type_1g_cu_core0:
1146        case ixgbe_sfp_type_1g_cu_core1:
1147        default:
1148                return IXGBE_ERR_SFP_NOT_SUPPORTED;
1149        }
1150
1151        return 0;
1152}
1153
1154/**
1155 *  ixgbe_setup_mac_link_sfp_x550em - Configure the KR PHY for SFP.
1156 *  @hw: pointer to hardware structure
1157 *
1158 *  Configures the extern PHY and the integrated KR PHY for SFP support.
1159 */
1160static s32
1161ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
1162                                ixgbe_link_speed speed,
1163                                __always_unused bool autoneg_wait_to_complete)
1164{
1165        s32 status;
1166        u16 slice, value;
1167        bool setup_linear = false;
1168
1169        /* Check if SFP module is supported and linear */
1170        status = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
1171
1172        /* If no SFP module present, then return success. Return success since
1173         * there is no reason to configure CS4227 and SFP not present error is
1174         * not accepted in the setup MAC link flow.
1175         */
1176        if (status == IXGBE_ERR_SFP_NOT_PRESENT)
1177                return 0;
1178
1179        if (status)
1180                return status;
1181
1182        if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
1183                /* Configure CS4227 LINE side to 10G SR. */
1184                slice = IXGBE_CS4227_LINE_SPARE22_MSB + (hw->bus.lan_id << 12);
1185                value = IXGBE_CS4227_SPEED_10G;
1186                status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
1187                                                          slice, value);
1188                if (status)
1189                        goto i2c_err;
1190
1191                slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12);
1192                value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
1193                status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
1194                                                          slice, value);
1195                if (status)
1196                        goto i2c_err;
1197
1198                /* Configure CS4227 for HOST connection rate then type. */
1199                slice = IXGBE_CS4227_HOST_SPARE22_MSB + (hw->bus.lan_id << 12);
1200                value = speed & IXGBE_LINK_SPEED_10GB_FULL ?
1201                        IXGBE_CS4227_SPEED_10G : IXGBE_CS4227_SPEED_1G;
1202                status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
1203                                                          slice, value);
1204                if (status)
1205                        goto i2c_err;
1206
1207                slice = IXGBE_CS4227_HOST_SPARE24_LSB + (hw->bus.lan_id << 12);
1208                if (setup_linear)
1209                        value = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
1210                else
1211                        value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
1212                status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
1213                                                          slice, value);
1214                if (status)
1215                        goto i2c_err;
1216
1217                /* Setup XFI internal link. */
1218                status = ixgbe_setup_ixfi_x550em(hw, &speed);
1219                if (status) {
1220                        hw_dbg(hw, "setup_ixfi failed with %d\n", status);
1221                        return status;
1222                }
1223        } else {
1224                /* Configure internal PHY for KR/KX. */
1225                status = ixgbe_setup_kr_speed_x550em(hw, speed);
1226                if (status) {
1227                        hw_dbg(hw, "setup_kr_speed failed with %d\n", status);
1228                        return status;
1229                }
1230
1231                /* Configure CS4227 LINE side to proper mode. */
1232                slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12);
1233                if (setup_linear)
1234                        value = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
1235                else
1236                        value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
1237                status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
1238                                                          slice, value);
1239                if (status)
1240                        goto i2c_err;
1241        }
1242
1243        return 0;
1244
1245i2c_err:
1246        hw_dbg(hw, "combined i2c access failed with %d\n", status);
1247        return status;
1248}
1249
1250/**
1251 * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed
1252 * @hw: pointer to hardware structure
1253 * @speed: new link speed
1254 * @autoneg_wait_to_complete: true when waiting for completion is needed
1255 *
1256 * Setup internal/external PHY link speed based on link speed, then set
1257 * external PHY auto advertised link speed.
1258 *
1259 * Returns error status for any failure
1260 **/
1261static s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
1262                                         ixgbe_link_speed speed,
1263                                         bool autoneg_wait)
1264{
1265        s32 status;
1266        ixgbe_link_speed force_speed;
1267
1268        /* Setup internal/external PHY link speed to iXFI (10G), unless
1269         * only 1G is auto advertised then setup KX link.
1270         */
1271        if (speed & IXGBE_LINK_SPEED_10GB_FULL)
1272                force_speed = IXGBE_LINK_SPEED_10GB_FULL;
1273        else
1274                force_speed = IXGBE_LINK_SPEED_1GB_FULL;
1275
1276        /* If internal link mode is XFI, then setup XFI internal link. */
1277        if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
1278                status = ixgbe_setup_ixfi_x550em(hw, &force_speed);
1279
1280                if (status)
1281                        return status;
1282        }
1283
1284        return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
1285}
1286
1287/** ixgbe_check_link_t_X550em - Determine link and speed status
1288  * @hw: pointer to hardware structure
1289  * @speed: pointer to link speed
1290  * @link_up: true when link is up
1291  * @link_up_wait_to_complete: bool used to wait for link up or not
1292  *
1293  * Check that both the MAC and X557 external PHY have link.
1294  **/
1295static s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw,
1296                                     ixgbe_link_speed *speed,
1297                                     bool *link_up,
1298                                     bool link_up_wait_to_complete)
1299{
1300        u32 status;
1301        u16 autoneg_status;
1302
1303        if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
1304                return IXGBE_ERR_CONFIG;
1305
1306        status = ixgbe_check_mac_link_generic(hw, speed, link_up,
1307                                              link_up_wait_to_complete);
1308
1309        /* If check link fails or MAC link is not up, then return */
1310        if (status || !(*link_up))
1311                return status;
1312
1313         /* MAC link is up, so check external PHY link.
1314          * Read this twice back to back to indicate current status.
1315          */
1316        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
1317                                      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1318                                      &autoneg_status);
1319        if (status)
1320                return status;
1321
1322        /* If external PHY link is not up, then indicate link not up */
1323        if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
1324                *link_up = false;
1325
1326        return 0;
1327}
1328
1329/** ixgbe_init_mac_link_ops_X550em - init mac link function pointers
1330 *  @hw: pointer to hardware structure
1331 **/
1332static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
1333{
1334        struct ixgbe_mac_info *mac = &hw->mac;
1335
1336        switch (mac->ops.get_media_type(hw)) {
1337        case ixgbe_media_type_fiber:
1338                /* CS4227 does not support autoneg, so disable the laser control
1339                 * functions for SFP+ fiber
1340                 */
1341                mac->ops.disable_tx_laser = NULL;
1342                mac->ops.enable_tx_laser = NULL;
1343                mac->ops.flap_tx_laser = NULL;
1344                mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
1345                mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em;
1346                mac->ops.set_rate_select_speed =
1347                                        ixgbe_set_soft_rate_select_speed;
1348                break;
1349        case ixgbe_media_type_copper:
1350                mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
1351                mac->ops.check_link = ixgbe_check_link_t_X550em;
1352                break;
1353        default:
1354                break;
1355        }
1356}
1357
1358/** ixgbe_setup_sfp_modules_X550em - Setup SFP module
1359 * @hw: pointer to hardware structure
1360 */
1361static s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
1362{
1363        s32 status;
1364        bool linear;
1365
1366        /* Check if SFP module is supported */
1367        status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
1368        if (status)
1369                return status;
1370
1371        ixgbe_init_mac_link_ops_X550em(hw);
1372        hw->phy.ops.reset = NULL;
1373
1374        return 0;
1375}
1376
1377/** ixgbe_get_link_capabilities_x550em - Determines link capabilities
1378 * @hw: pointer to hardware structure
1379 * @speed: pointer to link speed
1380 * @autoneg: true when autoneg or autotry is enabled
1381 **/
1382static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
1383                                              ixgbe_link_speed *speed,
1384                                              bool *autoneg)
1385{
1386        /* SFP */
1387        if (hw->phy.media_type == ixgbe_media_type_fiber) {
1388                /* CS4227 SFP must not enable auto-negotiation */
1389                *autoneg = false;
1390
1391                if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
1392                    hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
1393                        *speed = IXGBE_LINK_SPEED_1GB_FULL;
1394                        return 0;
1395                }
1396
1397                /* Link capabilities are based on SFP */
1398                if (hw->phy.multispeed_fiber)
1399                        *speed = IXGBE_LINK_SPEED_10GB_FULL |
1400                                 IXGBE_LINK_SPEED_1GB_FULL;
1401                else
1402                        *speed = IXGBE_LINK_SPEED_10GB_FULL;
1403        } else {
1404                *speed = IXGBE_LINK_SPEED_10GB_FULL |
1405                         IXGBE_LINK_SPEED_1GB_FULL;
1406                *autoneg = true;
1407        }
1408        return 0;
1409}
1410
1411/**
1412 * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause
1413 * @hw: pointer to hardware structure
1414 * @lsc: pointer to boolean flag which indicates whether external Base T
1415 *       PHY interrupt is lsc
1416 *
1417 * Determime if external Base T PHY interrupt cause is high temperature
1418 * failure alarm or link status change.
1419 *
1420 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
1421 * failure alarm, else return PHY access status.
1422 **/
1423static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
1424{
1425        u32 status;
1426        u16 reg;
1427
1428        *lsc = false;
1429
1430        /* Vendor alarm triggered */
1431        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
1432                                      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1433                                      &reg);
1434
1435        if (status || !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN))
1436                return status;
1437
1438        /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */
1439        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG,
1440                                      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1441                                      &reg);
1442
1443        if (status || !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
1444                                IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
1445                return status;
1446
1447        /* Global alarm triggered */
1448        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
1449                                      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1450                                      &reg);
1451
1452        if (status)
1453                return status;
1454
1455        /* If high temperature failure, then return over temp error and exit */
1456        if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
1457                /* power down the PHY in case the PHY FW didn't already */
1458                ixgbe_set_copper_phy_power(hw, false);
1459                return IXGBE_ERR_OVERTEMP;
1460        }
1461        if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
1462                /*  device fault alarm triggered */
1463                status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
1464                                          IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1465                                          &reg);
1466                if (status)
1467                        return status;
1468
1469                /* if device fault was due to high temp alarm handle and exit */
1470                if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
1471                        /* power down the PHY in case the PHY FW didn't */
1472                        ixgbe_set_copper_phy_power(hw, false);
1473                        return IXGBE_ERR_OVERTEMP;
1474                }
1475        }
1476
1477        /* Vendor alarm 2 triggered */
1478        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
1479                                      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
1480
1481        if (status || !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT))
1482                return status;
1483
1484        /* link connect/disconnect event occurred */
1485        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2,
1486                                      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
1487
1488        if (status)
1489                return status;
1490
1491        /* Indicate LSC */
1492        if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC)
1493                *lsc = true;
1494
1495        return 0;
1496}
1497
1498/**
1499 * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts
1500 * @hw: pointer to hardware structure
1501 *
1502 * Enable link status change and temperature failure alarm for the external
1503 * Base T PHY
1504 *
1505 * Returns PHY access status
1506 **/
1507static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
1508{
1509        u32 status;
1510        u16 reg;
1511        bool lsc;
1512
1513        /* Clear interrupt flags */
1514        status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
1515
1516        /* Enable link status change alarm */
1517        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
1518                                      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
1519        if (status)
1520                return status;
1521
1522        reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN;
1523
1524        status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
1525                                       IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg);
1526        if (status)
1527                return status;
1528
1529        /* Enable high temperature failure and global fault alarms */
1530        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
1531                                      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1532                                      &reg);
1533        if (status)
1534                return status;
1535
1536        reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN |
1537                IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN);
1538
1539        status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
1540                                       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1541                                       reg);
1542        if (status)
1543                return status;
1544
1545        /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */
1546        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
1547                                      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1548                                      &reg);
1549        if (status)
1550                return status;
1551
1552        reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
1553                IXGBE_MDIO_GLOBAL_ALARM_1_INT);
1554
1555        status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
1556                                       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1557                                       reg);
1558        if (status)
1559                return status;
1560
1561        /* Enable chip-wide vendor alarm */
1562        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
1563                                      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1564                                      &reg);
1565        if (status)
1566                return status;
1567
1568        reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN;
1569
1570        status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
1571                                       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1572                                       reg);
1573
1574        return status;
1575}
1576
1577/**
1578 * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
1579 * @hw: pointer to hardware structure
1580 *
1581 * Handle external Base T PHY interrupt. If high temperature
1582 * failure alarm then return error, else if link status change
1583 * then setup internal/external PHY link
1584 *
1585 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
1586 * failure alarm, else return PHY access status.
1587 **/
1588static s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
1589{
1590        struct ixgbe_phy_info *phy = &hw->phy;
1591        bool lsc;
1592        u32 status;
1593
1594        status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
1595        if (status)
1596                return status;
1597
1598        if (lsc && phy->ops.setup_internal_link)
1599                return phy->ops.setup_internal_link(hw);
1600
1601        return 0;
1602}
1603
1604/**
1605 * ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed.
1606 * @hw: pointer to hardware structure
1607 * @speed: link speed
1608 *
1609 * Configures the integrated KR PHY.
1610 **/
1611static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
1612                                       ixgbe_link_speed speed)
1613{
1614        s32 status;
1615        u32 reg_val;
1616
1617        status = ixgbe_read_iosf_sb_reg_x550(hw,
1618                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1619                                        IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1620        if (status)
1621                return status;
1622
1623        reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1624        reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_FEC_REQ |
1625                     IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC);
1626        reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
1627                     IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
1628
1629        /* Advertise 10G support. */
1630        if (speed & IXGBE_LINK_SPEED_10GB_FULL)
1631                reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
1632
1633        /* Advertise 1G support. */
1634        if (speed & IXGBE_LINK_SPEED_1GB_FULL)
1635                reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
1636
1637        /* Restart auto-negotiation. */
1638        reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
1639        status = ixgbe_write_iosf_sb_reg_x550(hw,
1640                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1641                                        IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1642
1643        return status;
1644}
1645
1646/** ixgbe_setup_kx4_x550em - Configure the KX4 PHY.
1647 *  @hw: pointer to hardware structure
1648 *
1649 *   Configures the integrated KX4 PHY.
1650 **/
1651static s32 ixgbe_setup_kx4_x550em(struct ixgbe_hw *hw)
1652{
1653        s32 status;
1654        u32 reg_val;
1655
1656        status = ixgbe_read_iosf_sb_reg_x550(hw, IXGBE_KX4_LINK_CNTL_1,
1657                                             IXGBE_SB_IOSF_TARGET_KX4_PCS0 +
1658                                             hw->bus.lan_id, &reg_val);
1659        if (status)
1660                return status;
1661
1662        reg_val &= ~(IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4 |
1663                     IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX);
1664
1665        reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_ENABLE;
1666
1667        /* Advertise 10G support. */
1668        if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
1669                reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4;
1670
1671        /* Advertise 1G support. */
1672        if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
1673                reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX;
1674
1675        /* Restart auto-negotiation. */
1676        reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_RESTART;
1677        status = ixgbe_write_iosf_sb_reg_x550(hw, IXGBE_KX4_LINK_CNTL_1,
1678                                              IXGBE_SB_IOSF_TARGET_KX4_PCS0 +
1679                                              hw->bus.lan_id, reg_val);
1680
1681        return status;
1682}
1683
1684/**  ixgbe_setup_kr_x550em - Configure the KR PHY.
1685 *   @hw: pointer to hardware structure
1686 *
1687 *   Configures the integrated KR PHY.
1688 **/
1689static s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
1690{
1691        return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised);
1692}
1693
1694/** ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status
1695 *  @hw: address of hardware structure
1696 *  @link_up: address of boolean to indicate link status
1697 *
1698 *  Returns error code if unable to get link status.
1699 **/
1700static s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up)
1701{
1702        u32 ret;
1703        u16 autoneg_status;
1704
1705        *link_up = false;
1706
1707        /* read this twice back to back to indicate current status */
1708        ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
1709                                   IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1710                                   &autoneg_status);
1711        if (ret)
1712                return ret;
1713
1714        ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
1715                                   IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1716                                   &autoneg_status);
1717        if (ret)
1718                return ret;
1719
1720        *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS);
1721
1722        return 0;
1723}
1724
1725/** ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link
1726 *  @hw: point to hardware structure
1727 *
1728 *  Configures the link between the integrated KR PHY and the external X557 PHY
1729 *  The driver will call this function when it gets a link status change
1730 *  interrupt from the X557 PHY. This function configures the link speed
1731 *  between the PHYs to match the link speed of the BASE-T link.
1732 *
1733 * A return of a non-zero value indicates an error, and the base driver should
1734 * not report link up.
1735 **/
1736static s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
1737{
1738        ixgbe_link_speed force_speed;
1739        bool link_up;
1740        u32 status;
1741        u16 speed;
1742
1743        if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
1744                return IXGBE_ERR_CONFIG;
1745
1746        if (hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) {
1747                speed = IXGBE_LINK_SPEED_10GB_FULL |
1748                        IXGBE_LINK_SPEED_1GB_FULL;
1749                return ixgbe_setup_kr_speed_x550em(hw, speed);
1750        }
1751
1752        /* If link is not up, then there is no setup necessary so return  */
1753        status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
1754        if (status)
1755                return status;
1756
1757        if (!link_up)
1758                return 0;
1759
1760        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
1761                                      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1762                                      &speed);
1763        if (status)
1764                return status;
1765
1766        /* If link is not still up, then no setup is necessary so return */
1767        status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
1768        if (status)
1769                return status;
1770
1771        if (!link_up)
1772                return 0;
1773
1774        /* clear everything but the speed and duplex bits */
1775        speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
1776
1777        switch (speed) {
1778        case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
1779                force_speed = IXGBE_LINK_SPEED_10GB_FULL;
1780                break;
1781        case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
1782                force_speed = IXGBE_LINK_SPEED_1GB_FULL;
1783                break;
1784        default:
1785                /* Internal PHY does not support anything else */
1786                return IXGBE_ERR_INVALID_LINK_SETTINGS;
1787        }
1788
1789        return ixgbe_setup_ixfi_x550em(hw, &force_speed);
1790}
1791
1792/** ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI
1793 *  @hw: pointer to hardware structure
1794 **/
1795static s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw)
1796{
1797        s32 status;
1798
1799        status = ixgbe_reset_phy_generic(hw);
1800
1801        if (status)
1802                return status;
1803
1804        /* Configure Link Status Alarm and Temperature Threshold interrupts */
1805        return ixgbe_enable_lasi_ext_t_x550em(hw);
1806}
1807
1808/** ixgbe_get_lcd_x550em - Determine lowest common denominator
1809 *  @hw: pointer to hardware structure
1810 *  @lcd_speed: pointer to lowest common link speed
1811 *
1812 *  Determine lowest common link speed with link partner.
1813 **/
1814static s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw,
1815                                  ixgbe_link_speed *lcd_speed)
1816{
1817        u16 an_lp_status;
1818        s32 status;
1819        u16 word = hw->eeprom.ctrl_word_3;
1820
1821        *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN;
1822
1823        status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS,
1824                                      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1825                                      &an_lp_status);
1826        if (status)
1827                return status;
1828
1829        /* If link partner advertised 1G, return 1G */
1830        if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) {
1831                *lcd_speed = IXGBE_LINK_SPEED_1GB_FULL;
1832                return status;
1833        }
1834
1835        /* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */
1836        if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) ||
1837            (word & NVM_INIT_CTRL_3_D10GMP_PORT0))
1838                return status;
1839
1840        /* Link partner not capable of lower speeds, return 10G */
1841        *lcd_speed = IXGBE_LINK_SPEED_10GB_FULL;
1842        return status;
1843}
1844
1845/** ixgbe_enter_lplu_x550em - Transition to low power states
1846 *  @hw: pointer to hardware structure
1847 *
1848 *  Configures Low Power Link Up on transition to low power states
1849 *  (from D0 to non-D0). Link is required to enter LPLU so avoid resetting
1850 *  the X557 PHY immediately prior to entering LPLU.
1851 **/
1852static s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
1853{
1854        u16 an_10g_cntl_reg, autoneg_reg, speed;
1855        s32 status;
1856        ixgbe_link_speed lcd_speed;
1857        u32 save_autoneg;
1858        bool link_up;
1859
1860        /* If blocked by MNG FW, then don't restart AN */
1861        if (ixgbe_check_reset_blocked(hw))
1862                return 0;
1863
1864        status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
1865        if (status)
1866                return status;
1867
1868        status = hw->eeprom.ops.read(hw, NVM_INIT_CTRL_3,
1869                                     &hw->eeprom.ctrl_word_3);
1870        if (status)
1871                return status;
1872
1873        /* If link is down, LPLU disabled in NVM, WoL disabled, or
1874         * manageability disabled, then force link down by entering
1875         * low power mode.
1876         */
1877        if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) ||
1878            !(hw->wol_enabled || ixgbe_mng_present(hw)))
1879                return ixgbe_set_copper_phy_power(hw, false);
1880
1881        /* Determine LCD */
1882        status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed);
1883        if (status)
1884                return status;
1885
1886        /* If no valid LCD link speed, then force link down and exit. */
1887        if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN)
1888                return ixgbe_set_copper_phy_power(hw, false);
1889
1890        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
1891                                      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1892                                      &speed);
1893        if (status)
1894                return status;
1895
1896        /* If no link now, speed is invalid so take link down */
1897        status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
1898        if (status)
1899                return ixgbe_set_copper_phy_power(hw, false);
1900
1901        /* clear everything but the speed bits */
1902        speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK;
1903
1904        /* If current speed is already LCD, then exit. */
1905        if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) &&
1906             (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) ||
1907            ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) &&
1908             (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL)))
1909                return status;
1910
1911        /* Clear AN completed indication */
1912        status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM,
1913                                      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1914                                      &autoneg_reg);
1915        if (status)
1916                return status;
1917
1918        status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
1919                                      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1920                                      &an_10g_cntl_reg);
1921        if (status)
1922                return status;
1923
1924        status = hw->phy.ops.read_reg(hw,
1925                                      IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
1926                                      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1927                                      &autoneg_reg);
1928        if (status)
1929                return status;
1930
1931        save_autoneg = hw->phy.autoneg_advertised;
1932
1933        /* Setup link at least common link speed */
1934        status = hw->mac.ops.setup_link(hw, lcd_speed, false);
1935
1936        /* restore autoneg from before setting lplu speed */
1937        hw->phy.autoneg_advertised = save_autoneg;
1938
1939        return status;
1940}
1941
1942/** ixgbe_init_phy_ops_X550em - PHY/SFP specific init
1943 *  @hw: pointer to hardware structure
1944 *
1945 *  Initialize any function pointers that were not able to be
1946 *  set during init_shared_code because the PHY/SFP type was
1947 *  not known.  Perform the SFP init if necessary.
1948 **/
1949static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
1950{
1951        struct ixgbe_phy_info *phy = &hw->phy;
1952        s32 ret_val;
1953
1954        hw->mac.ops.set_lan_id(hw);
1955
1956        if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
1957                phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
1958                ixgbe_setup_mux_ctl(hw);
1959
1960                /* Save NW management interface connected on board. This is used
1961                 * to determine internal PHY mode.
1962                 */
1963                phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
1964        }
1965
1966        /* Identify the PHY or SFP module */
1967        ret_val = phy->ops.identify(hw);
1968
1969        /* Setup function pointers based on detected hardware */
1970        ixgbe_init_mac_link_ops_X550em(hw);
1971        if (phy->sfp_type != ixgbe_sfp_type_unknown)
1972                phy->ops.reset = NULL;
1973
1974        /* Set functions pointers based on phy type */
1975        switch (hw->phy.type) {
1976        case ixgbe_phy_x550em_kx4:
1977                phy->ops.setup_link = ixgbe_setup_kx4_x550em;
1978                phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
1979                phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
1980                break;
1981        case ixgbe_phy_x550em_kr:
1982                phy->ops.setup_link = ixgbe_setup_kr_x550em;
1983                phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
1984                phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
1985                break;
1986        case ixgbe_phy_x550em_ext_t:
1987                /* Save NW management interface connected on board. This is used
1988                 * to determine internal PHY mode
1989                 */
1990                phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
1991
1992                /* If internal link mode is XFI, then setup iXFI internal link,
1993                 * else setup KR now.
1994                 */
1995                phy->ops.setup_internal_link =
1996                                              ixgbe_setup_internal_phy_t_x550em;
1997
1998                /* setup SW LPLU only for first revision */
1999                if (hw->mac.type == ixgbe_mac_X550EM_x &&
2000                    !(IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)) &
2001                      IXGBE_FUSES0_REV_MASK))
2002                        phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
2003
2004                phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
2005                phy->ops.reset = ixgbe_reset_phy_t_X550em;
2006                break;
2007        default:
2008                break;
2009        }
2010
2011        return ret_val;
2012}
2013
2014/** ixgbe_get_media_type_X550em - Get media type
2015 *  @hw: pointer to hardware structure
2016 *
2017 *  Returns the media type (fiber, copper, backplane)
2018 *
2019 */
2020static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
2021{
2022        enum ixgbe_media_type media_type;
2023
2024        /* Detect if there is a copper PHY attached. */
2025        switch (hw->device_id) {
2026        case IXGBE_DEV_ID_X550EM_X_KR:
2027        case IXGBE_DEV_ID_X550EM_X_KX4:
2028                media_type = ixgbe_media_type_backplane;
2029                break;
2030        case IXGBE_DEV_ID_X550EM_X_SFP:
2031                media_type = ixgbe_media_type_fiber;
2032                break;
2033        case IXGBE_DEV_ID_X550EM_X_1G_T:
2034        case IXGBE_DEV_ID_X550EM_X_10G_T:
2035                 media_type = ixgbe_media_type_copper;
2036                break;
2037        default:
2038                media_type = ixgbe_media_type_unknown;
2039                break;
2040        }
2041        return media_type;
2042}
2043
2044/** ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
2045 ** @hw: pointer to hardware structure
2046 **/
2047static s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
2048{
2049        s32 status;
2050        u16 reg;
2051
2052        status = hw->phy.ops.read_reg(hw,
2053                                      IXGBE_MDIO_TX_VENDOR_ALARMS_3,
2054                                      IXGBE_MDIO_PMA_PMD_DEV_TYPE,
2055                                      &reg);
2056        if (status)
2057                return status;
2058
2059        /* If PHY FW reset completed bit is set then this is the first
2060         * SW instance after a power on so the PHY FW must be un-stalled.
2061         */
2062        if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
2063                status = hw->phy.ops.read_reg(hw,
2064                                        IXGBE_MDIO_GLOBAL_RES_PR_10,
2065                                        IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2066                                        &reg);
2067                if (status)
2068                        return status;
2069
2070                reg &= ~IXGBE_MDIO_POWER_UP_STALL;
2071
2072                status = hw->phy.ops.write_reg(hw,
2073                                        IXGBE_MDIO_GLOBAL_RES_PR_10,
2074                                        IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2075                                        reg);
2076                if (status)
2077                        return status;
2078        }
2079
2080        return status;
2081}
2082
2083/**  ixgbe_reset_hw_X550em - Perform hardware reset
2084 **  @hw: pointer to hardware structure
2085 **
2086 **  Resets the hardware by resetting the transmit and receive units, masks
2087 **  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
2088 **  reset.
2089 **/
2090static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
2091{
2092        ixgbe_link_speed link_speed;
2093        s32 status;
2094        u32 ctrl = 0;
2095        u32 i;
2096        u32 hlreg0;
2097        bool link_up = false;
2098
2099        /* Call adapter stop to disable Tx/Rx and clear interrupts */
2100        status = hw->mac.ops.stop_adapter(hw);
2101        if (status)
2102                return status;
2103
2104        /* flush pending Tx transactions */
2105        ixgbe_clear_tx_pending(hw);
2106
2107        /* PHY ops must be identified and initialized prior to reset */
2108
2109        /* Identify PHY and related function pointers */
2110        status = hw->phy.ops.init(hw);
2111
2112        /* start the external PHY */
2113        if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
2114                status = ixgbe_init_ext_t_x550em(hw);
2115                if (status)
2116                        return status;
2117        }
2118
2119        /* Setup SFP module if there is one present. */
2120        if (hw->phy.sfp_setup_needed) {
2121                status = hw->mac.ops.setup_sfp(hw);
2122                hw->phy.sfp_setup_needed = false;
2123        }
2124
2125        /* Reset PHY */
2126        if (!hw->phy.reset_disable && hw->phy.ops.reset)
2127                hw->phy.ops.reset(hw);
2128
2129mac_reset_top:
2130        /* Issue global reset to the MAC.  Needs to be SW reset if link is up.
2131         * If link reset is used when link is up, it might reset the PHY when
2132         * mng is using it.  If link is down or the flag to force full link
2133         * reset is set, then perform link reset.
2134         */
2135        ctrl = IXGBE_CTRL_LNK_RST;
2136
2137        if (!hw->force_full_reset) {
2138                hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
2139                if (link_up)
2140                        ctrl = IXGBE_CTRL_RST;
2141        }
2142
2143        ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
2144        IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
2145        IXGBE_WRITE_FLUSH(hw);
2146        usleep_range(1000, 1200);
2147
2148        /* Poll for reset bit to self-clear meaning reset is complete */
2149        for (i = 0; i < 10; i++) {
2150                ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
2151                if (!(ctrl & IXGBE_CTRL_RST_MASK))
2152                        break;
2153                udelay(1);
2154        }
2155
2156        if (ctrl & IXGBE_CTRL_RST_MASK) {
2157                status = IXGBE_ERR_RESET_FAILED;
2158                hw_dbg(hw, "Reset polling failed to complete.\n");
2159        }
2160
2161        msleep(50);
2162
2163        /* Double resets are required for recovery from certain error
2164         * clear the multicast table.  Also reset num_rar_entries to 128,
2165         * since we modify this value when programming the SAN MAC address.
2166         */
2167        if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
2168                hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
2169                goto mac_reset_top;
2170        }
2171
2172        /* Store the permanent mac address */
2173        hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
2174
2175        /* Store MAC address from RAR0, clear receive address registers, and
2176         * clear the multicast table.  Also reset num_rar_entries to 128,
2177         * since we modify this value when programming the SAN MAC address.
2178         */
2179        hw->mac.num_rar_entries = 128;
2180        hw->mac.ops.init_rx_addrs(hw);
2181
2182        if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) {
2183                hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
2184                hlreg0 &= ~IXGBE_HLREG0_MDCSPD;
2185                IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
2186        }
2187
2188        if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
2189                ixgbe_setup_mux_ctl(hw);
2190
2191        return status;
2192}
2193
2194/** ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype
2195 *      anti-spoofing
2196 *  @hw:  pointer to hardware structure
2197 *  @enable: enable or disable switch for Ethertype anti-spoofing
2198 *  @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing
2199 **/
2200static void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
2201                                                   bool enable, int vf)
2202{
2203        int vf_target_reg = vf >> 3;
2204        int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT;
2205        u32 pfvfspoof;
2206
2207        pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
2208        if (enable)
2209                pfvfspoof |= (1 << vf_target_shift);
2210        else
2211                pfvfspoof &= ~(1 << vf_target_shift);
2212
2213        IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
2214}
2215
2216/** ixgbe_set_source_address_pruning_X550 - Enable/Disbale src address pruning
2217 *  @hw: pointer to hardware structure
2218 *  @enable: enable or disable source address pruning
2219 *  @pool: Rx pool to set source address pruning for
2220 **/
2221static void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw,
2222                                                  bool enable,
2223                                                  unsigned int pool)
2224{
2225        u64 pfflp;
2226
2227        /* max rx pool is 63 */
2228        if (pool > 63)
2229                return;
2230
2231        pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
2232        pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
2233
2234        if (enable)
2235                pfflp |= (1ULL << pool);
2236        else
2237                pfflp &= ~(1ULL << pool);
2238
2239        IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp);
2240        IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
2241}
2242
2243/**
2244 * ixgbe_set_mux - Set mux for port 1 access with CS4227
2245 * @hw: pointer to hardware structure
2246 * @state: set mux if 1, clear if 0
2247 */
2248static void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state)
2249{
2250        u32 esdp;
2251
2252        if (!hw->bus.lan_id)
2253                return;
2254        esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
2255        if (state)
2256                esdp |= IXGBE_ESDP_SDP1;
2257        else
2258                esdp &= ~IXGBE_ESDP_SDP1;
2259        IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
2260        IXGBE_WRITE_FLUSH(hw);
2261}
2262
2263/**
2264 * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
2265 * @hw: pointer to hardware structure
2266 * @mask: Mask to specify which semaphore to acquire
2267 *
2268 * Acquires the SWFW semaphore and sets the I2C MUX
2269 */
2270static s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
2271{
2272        s32 status;
2273
2274        status = ixgbe_acquire_swfw_sync_X540(hw, mask);
2275        if (status)
2276                return status;
2277
2278        if (mask & IXGBE_GSSR_I2C_MASK)
2279                ixgbe_set_mux(hw, 1);
2280
2281        return 0;
2282}
2283
2284/**
2285 * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
2286 * @hw: pointer to hardware structure
2287 * @mask: Mask to specify which semaphore to release
2288 *
2289 * Releases the SWFW semaphore and sets the I2C MUX
2290 */
2291static void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
2292{
2293        if (mask & IXGBE_GSSR_I2C_MASK)
2294                ixgbe_set_mux(hw, 0);
2295
2296        ixgbe_release_swfw_sync_X540(hw, mask);
2297}
2298
2299#define X550_COMMON_MAC \
2300        .init_hw                        = &ixgbe_init_hw_generic, \
2301        .start_hw                       = &ixgbe_start_hw_X540, \
2302        .clear_hw_cntrs                 = &ixgbe_clear_hw_cntrs_generic, \
2303        .enable_rx_dma                  = &ixgbe_enable_rx_dma_generic, \
2304        .get_mac_addr                   = &ixgbe_get_mac_addr_generic, \
2305        .get_device_caps                = &ixgbe_get_device_caps_generic, \
2306        .stop_adapter                   = &ixgbe_stop_adapter_generic, \
2307        .set_lan_id                     = &ixgbe_set_lan_id_multi_port_pcie, \
2308        .read_analog_reg8               = NULL, \
2309        .write_analog_reg8              = NULL, \
2310        .set_rxpba                      = &ixgbe_set_rxpba_generic, \
2311        .check_link                     = &ixgbe_check_mac_link_generic, \
2312        .led_on                         = &ixgbe_led_on_generic, \
2313        .led_off                        = &ixgbe_led_off_generic, \
2314        .blink_led_start                = &ixgbe_blink_led_start_X540, \
2315        .blink_led_stop                 = &ixgbe_blink_led_stop_X540, \
2316        .set_rar                        = &ixgbe_set_rar_generic, \
2317        .clear_rar                      = &ixgbe_clear_rar_generic, \
2318        .set_vmdq                       = &ixgbe_set_vmdq_generic, \
2319        .set_vmdq_san_mac               = &ixgbe_set_vmdq_san_mac_generic, \
2320        .clear_vmdq                     = &ixgbe_clear_vmdq_generic, \
2321        .init_rx_addrs                  = &ixgbe_init_rx_addrs_generic, \
2322        .update_mc_addr_list            = &ixgbe_update_mc_addr_list_generic, \
2323        .enable_mc                      = &ixgbe_enable_mc_generic, \
2324        .disable_mc                     = &ixgbe_disable_mc_generic, \
2325        .clear_vfta                     = &ixgbe_clear_vfta_generic, \
2326        .set_vfta                       = &ixgbe_set_vfta_generic, \
2327        .fc_enable                      = &ixgbe_fc_enable_generic, \
2328        .set_fw_drv_ver                 = &ixgbe_set_fw_drv_ver_generic, \
2329        .init_uta_tables                = &ixgbe_init_uta_tables_generic, \
2330        .set_mac_anti_spoofing          = &ixgbe_set_mac_anti_spoofing, \
2331        .set_vlan_anti_spoofing         = &ixgbe_set_vlan_anti_spoofing, \
2332        .set_source_address_pruning     = \
2333                                &ixgbe_set_source_address_pruning_X550, \
2334        .set_ethertype_anti_spoofing    = \
2335                                &ixgbe_set_ethertype_anti_spoofing_X550, \
2336        .disable_rx_buff                = &ixgbe_disable_rx_buff_generic, \
2337        .enable_rx_buff                 = &ixgbe_enable_rx_buff_generic, \
2338        .get_thermal_sensor_data        = NULL, \
2339        .init_thermal_sensor_thresh     = NULL, \
2340        .prot_autoc_read                = &prot_autoc_read_generic, \
2341        .prot_autoc_write               = &prot_autoc_write_generic, \
2342        .enable_rx                      = &ixgbe_enable_rx_generic, \
2343        .disable_rx                     = &ixgbe_disable_rx_x550, \
2344
2345static struct ixgbe_mac_operations mac_ops_X550 = {
2346        X550_COMMON_MAC
2347        .reset_hw               = &ixgbe_reset_hw_X540,
2348        .get_media_type         = &ixgbe_get_media_type_X540,
2349        .get_san_mac_addr       = &ixgbe_get_san_mac_addr_generic,
2350        .get_wwn_prefix         = &ixgbe_get_wwn_prefix_generic,
2351        .setup_link             = &ixgbe_setup_mac_link_X540,
2352        .get_link_capabilities  = &ixgbe_get_copper_link_capabilities_generic,
2353        .get_bus_info           = &ixgbe_get_bus_info_generic,
2354        .setup_sfp              = NULL,
2355        .acquire_swfw_sync      = &ixgbe_acquire_swfw_sync_X540,
2356        .release_swfw_sync      = &ixgbe_release_swfw_sync_X540,
2357};
2358
2359static struct ixgbe_mac_operations mac_ops_X550EM_x = {
2360        X550_COMMON_MAC
2361        .reset_hw               = &ixgbe_reset_hw_X550em,
2362        .get_media_type         = &ixgbe_get_media_type_X550em,
2363        .get_san_mac_addr       = NULL,
2364        .get_wwn_prefix         = NULL,
2365        .setup_link             = NULL, /* defined later */
2366        .get_link_capabilities  = &ixgbe_get_link_capabilities_X550em,
2367        .get_bus_info           = &ixgbe_get_bus_info_X550em,
2368        .setup_sfp              = ixgbe_setup_sfp_modules_X550em,
2369        .acquire_swfw_sync      = &ixgbe_acquire_swfw_sync_X550em,
2370        .release_swfw_sync      = &ixgbe_release_swfw_sync_X550em,
2371};
2372
2373#define X550_COMMON_EEP \
2374        .read                   = &ixgbe_read_ee_hostif_X550, \
2375        .read_buffer            = &ixgbe_read_ee_hostif_buffer_X550, \
2376        .write                  = &ixgbe_write_ee_hostif_X550, \
2377        .write_buffer           = &ixgbe_write_ee_hostif_buffer_X550, \
2378        .validate_checksum      = &ixgbe_validate_eeprom_checksum_X550, \
2379        .update_checksum        = &ixgbe_update_eeprom_checksum_X550, \
2380        .calc_checksum          = &ixgbe_calc_eeprom_checksum_X550, \
2381
2382static struct ixgbe_eeprom_operations eeprom_ops_X550 = {
2383        X550_COMMON_EEP
2384        .init_params            = &ixgbe_init_eeprom_params_X550,
2385};
2386
2387static struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = {
2388        X550_COMMON_EEP
2389        .init_params            = &ixgbe_init_eeprom_params_X540,
2390};
2391
2392#define X550_COMMON_PHY \
2393        .identify_sfp           = &ixgbe_identify_module_generic, \
2394        .reset                  = NULL, \
2395        .setup_link_speed       = &ixgbe_setup_phy_link_speed_generic, \
2396        .read_i2c_byte          = &ixgbe_read_i2c_byte_generic, \
2397        .write_i2c_byte         = &ixgbe_write_i2c_byte_generic, \
2398        .read_i2c_sff8472       = &ixgbe_read_i2c_sff8472_generic, \
2399        .read_i2c_eeprom        = &ixgbe_read_i2c_eeprom_generic, \
2400        .write_i2c_eeprom       = &ixgbe_write_i2c_eeprom_generic, \
2401        .read_reg               = &ixgbe_read_phy_reg_generic, \
2402        .write_reg              = &ixgbe_write_phy_reg_generic, \
2403        .setup_link             = &ixgbe_setup_phy_link_generic, \
2404        .set_phy_power          = NULL, \
2405        .check_overtemp         = &ixgbe_tn_check_overtemp, \
2406        .get_firmware_version   = &ixgbe_get_phy_firmware_version_generic,
2407
2408static struct ixgbe_phy_operations phy_ops_X550 = {
2409        X550_COMMON_PHY
2410        .init                   = NULL,
2411        .identify               = &ixgbe_identify_phy_generic,
2412};
2413
2414static struct ixgbe_phy_operations phy_ops_X550EM_x = {
2415        X550_COMMON_PHY
2416        .init                   = &ixgbe_init_phy_ops_X550em,
2417        .identify               = &ixgbe_identify_phy_x550em,
2418        .read_i2c_combined      = &ixgbe_read_i2c_combined_generic,
2419        .write_i2c_combined     = &ixgbe_write_i2c_combined_generic,
2420        .read_i2c_combined_unlocked = &ixgbe_read_i2c_combined_generic_unlocked,
2421        .write_i2c_combined_unlocked =
2422                                     &ixgbe_write_i2c_combined_generic_unlocked,
2423};
2424
2425static const u32 ixgbe_mvals_X550[IXGBE_MVALS_IDX_LIMIT] = {
2426        IXGBE_MVALS_INIT(X550)
2427};
2428
2429static const u32 ixgbe_mvals_X550EM_x[IXGBE_MVALS_IDX_LIMIT] = {
2430        IXGBE_MVALS_INIT(X550EM_x)
2431};
2432
2433struct ixgbe_info ixgbe_X550_info = {
2434        .mac                    = ixgbe_mac_X550,
2435        .get_invariants         = &ixgbe_get_invariants_X540,
2436        .mac_ops                = &mac_ops_X550,
2437        .eeprom_ops             = &eeprom_ops_X550,
2438        .phy_ops                = &phy_ops_X550,
2439        .mbx_ops                = &mbx_ops_generic,
2440        .mvals                  = ixgbe_mvals_X550,
2441};
2442
2443struct ixgbe_info ixgbe_X550EM_x_info = {
2444        .mac                    = ixgbe_mac_X550EM_x,
2445        .get_invariants         = &ixgbe_get_invariants_X550_x,
2446        .mac_ops                = &mac_ops_X550EM_x,
2447        .eeprom_ops             = &eeprom_ops_X550EM_x,
2448        .phy_ops                = &phy_ops_X550EM_x,
2449        .mbx_ops                = &mbx_ops_generic,
2450        .mvals                  = ixgbe_mvals_X550EM_x,
2451};
2452