The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ixgbe/ixgbe_x550.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /******************************************************************************
    2 
    3   Copyright (c) 2001-2020, Intel Corporation
    4   All rights reserved.
    5 
    6   Redistribution and use in source and binary forms, with or without
    7   modification, are permitted provided that the following conditions are met:
    8 
    9    1. Redistributions of source code must retain the above copyright notice,
   10       this list of conditions and the following disclaimer.
   11 
   12    2. Redistributions in binary form must reproduce the above copyright
   13       notice, this list of conditions and the following disclaimer in the
   14       documentation and/or other materials provided with the distribution.
   15 
   16    3. Neither the name of the Intel Corporation nor the names of its
   17       contributors may be used to endorse or promote products derived from
   18       this software without specific prior written permission.
   19 
   20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   21   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   24   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   30   POSSIBILITY OF SUCH DAMAGE.
   31 
   32 ******************************************************************************/
   33 /*$FreeBSD$*/
   34 
   35 #include "ixgbe_x550.h"
   36 #include "ixgbe_x540.h"
   37 #include "ixgbe_type.h"
   38 #include "ixgbe_api.h"
   39 #include "ixgbe_common.h"
   40 #include "ixgbe_phy.h"
   41 
   42 static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed);
   43 static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
   44 static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
   45 static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw);
   46 
   47 /**
   48  * ixgbe_init_ops_X550 - Inits func ptrs and MAC type
   49  * @hw: pointer to hardware structure
   50  *
   51  * Initialize the function pointers and assign the MAC type for X550.
   52  * Does not touch the hardware.
   53  **/
   54 s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw)
   55 {
   56         struct ixgbe_mac_info *mac = &hw->mac;
   57         struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
   58         s32 ret_val;
   59 
   60         DEBUGFUNC("ixgbe_init_ops_X550");
   61 
   62         ret_val = ixgbe_init_ops_X540(hw);
   63         mac->ops.dmac_config = ixgbe_dmac_config_X550;
   64         mac->ops.dmac_config_tcs = ixgbe_dmac_config_tcs_X550;
   65         mac->ops.dmac_update_tcs = ixgbe_dmac_update_tcs_X550;
   66         mac->ops.setup_eee = NULL;
   67         mac->ops.set_source_address_pruning =
   68                         ixgbe_set_source_address_pruning_X550;
   69         mac->ops.set_ethertype_anti_spoofing =
   70                         ixgbe_set_ethertype_anti_spoofing_X550;
   71 
   72         mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic;
   73         eeprom->ops.init_params = ixgbe_init_eeprom_params_X550;
   74         eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
   75         eeprom->ops.read = ixgbe_read_ee_hostif_X550;
   76         eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
   77         eeprom->ops.write = ixgbe_write_ee_hostif_X550;
   78         eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
   79         eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
   80         eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
   81 
   82         mac->ops.disable_mdd = ixgbe_disable_mdd_X550;
   83         mac->ops.enable_mdd = ixgbe_enable_mdd_X550;
   84         mac->ops.mdd_event = ixgbe_mdd_event_X550;
   85         mac->ops.restore_mdd_vf = ixgbe_restore_mdd_vf_X550;
   86         mac->ops.fw_recovery_mode = ixgbe_fw_recovery_mode_X550;
   87         mac->ops.disable_rx = ixgbe_disable_rx_x550;
   88         /* Manageability interface */
   89         mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_x550;
   90         switch (hw->device_id) {
   91         case IXGBE_DEV_ID_X550EM_X_1G_T:
   92                 hw->mac.ops.led_on = NULL;
   93                 hw->mac.ops.led_off = NULL;
   94                 break;
   95         case IXGBE_DEV_ID_X550EM_X_10G_T:
   96         case IXGBE_DEV_ID_X550EM_A_10G_T:
   97                 hw->mac.ops.led_on = ixgbe_led_on_t_X550em;
   98                 hw->mac.ops.led_off = ixgbe_led_off_t_X550em;
   99                 break;
  100         default:
  101                 break;
  102         }
  103         return ret_val;
  104 }
  105 
  106 /**
  107  * ixgbe_read_cs4227 - Read CS4227 register
  108  * @hw: pointer to hardware structure
  109  * @reg: register number to write
  110  * @value: pointer to receive value read
  111  *
  112  * Returns status code
  113  **/
  114 static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
  115 {
  116         return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value);
  117 }
  118 
  119 /**
  120  * ixgbe_write_cs4227 - Write CS4227 register
  121  * @hw: pointer to hardware structure
  122  * @reg: register number to write
  123  * @value: value to write to register
  124  *
  125  * Returns status code
  126  **/
  127 static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
  128 {
  129         return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value);
  130 }
  131 
  132 /**
  133  * ixgbe_read_pe - Read register from port expander
  134  * @hw: pointer to hardware structure
  135  * @reg: register number to read
  136  * @value: pointer to receive read value
  137  *
  138  * Returns status code
  139  **/
  140 static s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
  141 {
  142         s32 status;
  143 
  144         status = ixgbe_read_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
  145         if (status != IXGBE_SUCCESS)
  146                 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
  147                               "port expander access failed with %d\n", status);
  148         return status;
  149 }
  150 
  151 /**
  152  * ixgbe_write_pe - Write register to port expander
  153  * @hw: pointer to hardware structure
  154  * @reg: register number to write
  155  * @value: value to write
  156  *
  157  * Returns status code
  158  **/
  159 static s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
  160 {
  161         s32 status;
  162 
  163         status = ixgbe_write_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
  164         if (status != IXGBE_SUCCESS)
  165                 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
  166                               "port expander access failed with %d\n", status);
  167         return status;
  168 }
  169 
  170 /**
  171  * ixgbe_reset_cs4227 - Reset CS4227 using port expander
  172  * @hw: pointer to hardware structure
  173  *
  174  * This function assumes that the caller has acquired the proper semaphore.
  175  * Returns error code
  176  **/
  177 static s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
  178 {
  179         s32 status;
  180         u32 retry;
  181         u16 value;
  182         u8 reg;
  183 
  184         /* Trigger hard reset. */
  185         status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
  186         if (status != IXGBE_SUCCESS)
  187                 return status;
  188         reg |= IXGBE_PE_BIT1;
  189         status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
  190         if (status != IXGBE_SUCCESS)
  191                 return status;
  192 
  193         status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, &reg);
  194         if (status != IXGBE_SUCCESS)
  195                 return status;
  196         reg &= ~IXGBE_PE_BIT1;
  197         status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
  198         if (status != IXGBE_SUCCESS)
  199                 return status;
  200 
  201         status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
  202         if (status != IXGBE_SUCCESS)
  203                 return status;
  204         reg &= ~IXGBE_PE_BIT1;
  205         status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
  206         if (status != IXGBE_SUCCESS)
  207                 return status;
  208 
  209         usec_delay(IXGBE_CS4227_RESET_HOLD);
  210 
  211         status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
  212         if (status != IXGBE_SUCCESS)
  213                 return status;
  214         reg |= IXGBE_PE_BIT1;
  215         status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
  216         if (status != IXGBE_SUCCESS)
  217                 return status;
  218 
  219         /* Wait for the reset to complete. */
  220         msec_delay(IXGBE_CS4227_RESET_DELAY);
  221         for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
  222                 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
  223                                            &value);
  224                 if (status == IXGBE_SUCCESS &&
  225                     value == IXGBE_CS4227_EEPROM_LOAD_OK)
  226                         break;
  227                 msec_delay(IXGBE_CS4227_CHECK_DELAY);
  228         }
  229         if (retry == IXGBE_CS4227_RETRIES) {
  230                 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
  231                         "CS4227 reset did not complete.");
  232                 return IXGBE_ERR_PHY;
  233         }
  234 
  235         status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
  236         if (status != IXGBE_SUCCESS ||
  237             !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
  238                 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
  239                         "CS4227 EEPROM did not load successfully.");
  240                 return IXGBE_ERR_PHY;
  241         }
  242 
  243         return IXGBE_SUCCESS;
  244 }
  245 
  246 /**
  247  * ixgbe_check_cs4227 - Check CS4227 and reset as needed
  248  * @hw: pointer to hardware structure
  249  **/
  250 static void ixgbe_check_cs4227(struct ixgbe_hw *hw)
  251 {
  252         s32 status = IXGBE_SUCCESS;
  253         u32 swfw_mask = hw->phy.phy_semaphore_mask;
  254         u16 value = 0;
  255         u8 retry;
  256 
  257         for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
  258                 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
  259                 if (status != IXGBE_SUCCESS) {
  260                         ERROR_REPORT2(IXGBE_ERROR_CAUTION,
  261                                 "semaphore failed with %d", status);
  262                         msec_delay(IXGBE_CS4227_CHECK_DELAY);
  263                         continue;
  264                 }
  265 
  266                 /* Get status of reset flow. */
  267                 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
  268 
  269                 if (status == IXGBE_SUCCESS &&
  270                     value == IXGBE_CS4227_RESET_COMPLETE)
  271                         goto out;
  272 
  273                 if (status != IXGBE_SUCCESS ||
  274                     value != IXGBE_CS4227_RESET_PENDING)
  275                         break;
  276 
  277                 /* Reset is pending. Wait and check again. */
  278                 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
  279                 msec_delay(IXGBE_CS4227_CHECK_DELAY);
  280         }
  281 
  282         /* If still pending, assume other instance failed. */
  283         if (retry == IXGBE_CS4227_RETRIES) {
  284                 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
  285                 if (status != IXGBE_SUCCESS) {
  286                         ERROR_REPORT2(IXGBE_ERROR_CAUTION,
  287                                       "semaphore failed with %d", status);
  288                         return;
  289                 }
  290         }
  291 
  292         /* Reset the CS4227. */
  293         status = ixgbe_reset_cs4227(hw);
  294         if (status != IXGBE_SUCCESS) {
  295                 ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
  296                         "CS4227 reset failed: %d", status);
  297                 goto out;
  298         }
  299 
  300         /* Reset takes so long, temporarily release semaphore in case the
  301          * other driver instance is waiting for the reset indication.
  302          */
  303         ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
  304                            IXGBE_CS4227_RESET_PENDING);
  305         hw->mac.ops.release_swfw_sync(hw, swfw_mask);
  306         msec_delay(10);
  307         status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
  308         if (status != IXGBE_SUCCESS) {
  309                 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
  310                         "semaphore failed with %d", status);
  311                 return;
  312         }
  313 
  314         /* Record completion for next time. */
  315         status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
  316                 IXGBE_CS4227_RESET_COMPLETE);
  317 
  318 out:
  319         hw->mac.ops.release_swfw_sync(hw, swfw_mask);
  320         msec_delay(hw->eeprom.semaphore_delay);
  321 }
  322 
  323 /**
  324  * ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
  325  * @hw: pointer to hardware structure
  326  **/
  327 static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
  328 {
  329         u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
  330 
  331         if (hw->bus.lan_id) {
  332                 esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
  333                 esdp |= IXGBE_ESDP_SDP1_DIR;
  334         }
  335         esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
  336         IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
  337         IXGBE_WRITE_FLUSH(hw);
  338 }
  339 
  340 /**
  341  * ixgbe_identify_phy_x550em - Get PHY type based on device id
  342  * @hw: pointer to hardware structure
  343  *
  344  * Returns error code
  345  */
  346 static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
  347 {
  348         hw->mac.ops.set_lan_id(hw);
  349 
  350         ixgbe_read_mng_if_sel_x550em(hw);
  351 
  352         switch (hw->device_id) {
  353         case IXGBE_DEV_ID_X550EM_A_SFP:
  354                 return ixgbe_identify_sfp_module_X550em(hw);
  355         case IXGBE_DEV_ID_X550EM_X_SFP:
  356                 /* set up for CS4227 usage */
  357                 ixgbe_setup_mux_ctl(hw);
  358                 ixgbe_check_cs4227(hw);
  359                 /* Fallthrough */
  360 
  361         case IXGBE_DEV_ID_X550EM_A_SFP_N:
  362                 return ixgbe_identify_sfp_module_X550em(hw);
  363                 break;
  364         case IXGBE_DEV_ID_X550EM_X_KX4:
  365                 hw->phy.type = ixgbe_phy_x550em_kx4;
  366                 break;
  367         case IXGBE_DEV_ID_X550EM_X_XFI:
  368                 hw->phy.type = ixgbe_phy_x550em_xfi;
  369                 break;
  370         case IXGBE_DEV_ID_X550EM_X_KR:
  371         case IXGBE_DEV_ID_X550EM_A_KR:
  372         case IXGBE_DEV_ID_X550EM_A_KR_L:
  373                 hw->phy.type = ixgbe_phy_x550em_kr;
  374                 break;
  375         case IXGBE_DEV_ID_X550EM_A_10G_T:
  376         case IXGBE_DEV_ID_X550EM_X_10G_T:
  377                 return ixgbe_identify_phy_generic(hw);
  378         case IXGBE_DEV_ID_X550EM_X_1G_T:
  379                 hw->phy.type = ixgbe_phy_ext_1g_t;
  380                 break;
  381         case IXGBE_DEV_ID_X550EM_A_1G_T:
  382         case IXGBE_DEV_ID_X550EM_A_1G_T_L:
  383                 hw->phy.type = ixgbe_phy_fw;
  384                 if (hw->bus.lan_id)
  385                         hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
  386                 else
  387                         hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
  388                 break;
  389         default:
  390                 break;
  391         }
  392         return IXGBE_SUCCESS;
  393 }
  394 
  395 /**
  396  * ixgbe_fw_phy_activity - Perform an activity on a PHY
  397  * @hw: pointer to hardware structure
  398  * @activity: activity to perform
  399  * @data: Pointer to 4 32-bit words of data
  400  */
  401 s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity,
  402                           u32 (*data)[FW_PHY_ACT_DATA_COUNT])
  403 {
  404         union {
  405                 struct ixgbe_hic_phy_activity_req cmd;
  406                 struct ixgbe_hic_phy_activity_resp rsp;
  407         } hic;
  408         u16 retries = FW_PHY_ACT_RETRIES;
  409         s32 rc;
  410         u16 i;
  411 
  412         do {
  413                 memset(&hic, 0, sizeof(hic));
  414                 hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD;
  415                 hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN;
  416                 hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
  417                 hic.cmd.port_number = hw->bus.lan_id;
  418                 hic.cmd.activity_id = IXGBE_CPU_TO_LE16(activity);
  419                 for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
  420                         hic.cmd.data[i] = IXGBE_CPU_TO_BE32((*data)[i]);
  421 
  422                 rc = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd,
  423                                                   sizeof(hic.cmd),
  424                                                   IXGBE_HI_COMMAND_TIMEOUT,
  425                                                   true);
  426                 if (rc != IXGBE_SUCCESS)
  427                         return rc;
  428                 if (hic.rsp.hdr.cmd_or_resp.ret_status ==
  429                     FW_CEM_RESP_STATUS_SUCCESS) {
  430                         for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
  431                                 (*data)[i] = IXGBE_BE32_TO_CPU(hic.rsp.data[i]);
  432                         return IXGBE_SUCCESS;
  433                 }
  434                 usec_delay(20);
  435                 --retries;
  436         } while (retries > 0);
  437 
  438         return IXGBE_ERR_HOST_INTERFACE_COMMAND;
  439 }
  440 
  441 static const struct {
  442         u16 fw_speed;
  443         ixgbe_link_speed phy_speed;
  444 } ixgbe_fw_map[] = {
  445         { FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL },
  446         { FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL },
  447         { FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL },
  448         { FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL },
  449         { FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL },
  450         { FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL },
  451 };
  452 
  453 /**
  454  * ixgbe_get_phy_id_fw - Get the phy ID via firmware command
  455  * @hw: pointer to hardware structure
  456  *
  457  * Returns error code
  458  */
  459 static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw)
  460 {
  461         u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
  462         u16 phy_speeds;
  463         u16 phy_id_lo;
  464         s32 rc;
  465         u16 i;
  466 
  467         rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info);
  468         if (rc)
  469                 return rc;
  470 
  471         hw->phy.speeds_supported = 0;
  472         phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK;
  473         for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
  474                 if (phy_speeds & ixgbe_fw_map[i].fw_speed)
  475                         hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed;
  476         }
  477         if (!hw->phy.autoneg_advertised)
  478                 hw->phy.autoneg_advertised = hw->phy.speeds_supported;
  479 
  480         hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK;
  481         phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK;
  482         hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK;
  483         hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK;
  484         if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK)
  485                 return IXGBE_ERR_PHY_ADDR_INVALID;
  486         return IXGBE_SUCCESS;
  487 }
  488 
  489 /**
  490  * ixgbe_identify_phy_fw - Get PHY type based on firmware command
  491  * @hw: pointer to hardware structure
  492  *
  493  * Returns error code
  494  */
  495 static s32 ixgbe_identify_phy_fw(struct ixgbe_hw *hw)
  496 {
  497         if (hw->bus.lan_id)
  498                 hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
  499         else
  500                 hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
  501 
  502         hw->phy.type = ixgbe_phy_fw;
  503         hw->phy.ops.read_reg = NULL;
  504         hw->phy.ops.write_reg = NULL;
  505         return ixgbe_get_phy_id_fw(hw);
  506 }
  507 
  508 /**
  509  * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY
  510  * @hw: pointer to hardware structure
  511  *
  512  * Returns error code
  513  */
  514 s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw)
  515 {
  516         u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
  517 
  518         setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF;
  519         return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup);
  520 }
  521 
  522 static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
  523                                      u32 device_type, u16 *phy_data)
  524 {
  525         UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, *phy_data);
  526         return IXGBE_NOT_IMPLEMENTED;
  527 }
  528 
  529 static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
  530                                       u32 device_type, u16 phy_data)
  531 {
  532         UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, phy_data);
  533         return IXGBE_NOT_IMPLEMENTED;
  534 }
  535 
  536 /**
  537  * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
  538  * @hw: pointer to the hardware structure
  539  * @addr: I2C bus address to read from
  540  * @reg: I2C device register to read from
  541  * @val: pointer to location to receive read value
  542  *
  543  * Returns an error code on error.
  544  **/
  545 static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
  546                                            u16 reg, u16 *val)
  547 {
  548         return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, true);
  549 }
  550 
  551 /**
  552  * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation
  553  * @hw: pointer to the hardware structure
  554  * @addr: I2C bus address to read from
  555  * @reg: I2C device register to read from
  556  * @val: pointer to location to receive read value
  557  *
  558  * Returns an error code on error.
  559  **/
  560 static s32
  561 ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
  562                                          u16 reg, u16 *val)
  563 {
  564         return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, false);
  565 }
  566 
  567 /**
  568  * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
  569  * @hw: pointer to the hardware structure
  570  * @addr: I2C bus address to write to
  571  * @reg: I2C device register to write to
  572  * @val: value to write
  573  *
  574  * Returns an error code on error.
  575  **/
  576 static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
  577                                             u8 addr, u16 reg, u16 val)
  578 {
  579         return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, true);
  580 }
  581 
  582 /**
  583  * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation
  584  * @hw: pointer to the hardware structure
  585  * @addr: I2C bus address to write to
  586  * @reg: I2C device register to write to
  587  * @val: value to write
  588  *
  589  * Returns an error code on error.
  590  **/
  591 static s32
  592 ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw,
  593                                           u8 addr, u16 reg, u16 val)
  594 {
  595         return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, false);
  596 }
  597 
  598 /**
  599 *  ixgbe_init_ops_X550EM - Inits func ptrs and MAC type
  600 *  @hw: pointer to hardware structure
  601 *
  602 *  Initialize the function pointers and for MAC type X550EM.
  603 *  Does not touch the hardware.
  604 **/
  605 s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
  606 {
  607         struct ixgbe_mac_info *mac = &hw->mac;
  608         struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
  609         struct ixgbe_phy_info *phy = &hw->phy;
  610         s32 ret_val;
  611 
  612         DEBUGFUNC("ixgbe_init_ops_X550EM");
  613 
  614         /* Similar to X550 so start there. */
  615         ret_val = ixgbe_init_ops_X550(hw);
  616 
  617         /* Since this function eventually calls
  618          * ixgbe_init_ops_540 by design, we are setting
  619          * the pointers to NULL explicitly here to overwrite
  620          * the values being set in the x540 function.
  621          */
  622         /* Thermal sensor not supported in x550EM */
  623         mac->ops.get_thermal_sensor_data = NULL;
  624         mac->ops.init_thermal_sensor_thresh = NULL;
  625         mac->thermal_sensor_enabled = false;
  626 
  627         /* Bypass not supported in x550EM */
  628         mac->ops.bypass_rw = NULL;
  629         mac->ops.bypass_valid_rd = NULL;
  630         mac->ops.bypass_set = NULL;
  631         mac->ops.bypass_rd_eep = NULL;
  632 
  633         /* FCOE not supported in x550EM */
  634         mac->ops.get_san_mac_addr = NULL;
  635         mac->ops.set_san_mac_addr = NULL;
  636         mac->ops.get_wwn_prefix = NULL;
  637         mac->ops.get_fcoe_boot_status = NULL;
  638 
  639         /* IPsec not supported in x550EM */
  640         mac->ops.disable_sec_rx_path = NULL;
  641         mac->ops.enable_sec_rx_path = NULL;
  642 
  643         /* AUTOC register is not present in x550EM. */
  644         mac->ops.prot_autoc_read = NULL;
  645         mac->ops.prot_autoc_write = NULL;
  646 
  647         /* X550EM bus type is internal*/
  648         hw->bus.type = ixgbe_bus_type_internal;
  649         mac->ops.get_bus_info = ixgbe_get_bus_info_X550em;
  650 
  651 
  652         mac->ops.get_media_type = ixgbe_get_media_type_X550em;
  653         mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em;
  654         mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_X550em;
  655         mac->ops.reset_hw = ixgbe_reset_hw_X550em;
  656         mac->ops.get_supported_physical_layer =
  657                                     ixgbe_get_supported_physical_layer_X550em;
  658 
  659         if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper)
  660                 mac->ops.setup_fc = ixgbe_setup_fc_generic;
  661         else
  662                 mac->ops.setup_fc = ixgbe_setup_fc_X550em;
  663 
  664         /* PHY */
  665         phy->ops.init = ixgbe_init_phy_ops_X550em;
  666         switch (hw->device_id) {
  667         case IXGBE_DEV_ID_X550EM_A_1G_T:
  668         case IXGBE_DEV_ID_X550EM_A_1G_T_L:
  669                 mac->ops.setup_fc = NULL;
  670                 phy->ops.identify = ixgbe_identify_phy_fw;
  671                 phy->ops.set_phy_power = NULL;
  672                 phy->ops.get_firmware_version = NULL;
  673                 break;
  674         case IXGBE_DEV_ID_X550EM_X_1G_T:
  675                 mac->ops.setup_fc = NULL;
  676                 phy->ops.identify = ixgbe_identify_phy_x550em;
  677                 phy->ops.set_phy_power = NULL;
  678                 break;
  679         default:
  680                 phy->ops.identify = ixgbe_identify_phy_x550em;
  681         }
  682 
  683         if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
  684                 phy->ops.set_phy_power = NULL;
  685 
  686 
  687         /* EEPROM */
  688         eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
  689         eeprom->ops.read = ixgbe_read_ee_hostif_X550;
  690         eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
  691         eeprom->ops.write = ixgbe_write_ee_hostif_X550;
  692         eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
  693         eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
  694         eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
  695         eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
  696 
  697         return ret_val;
  698 }
  699 
  700 /**
  701  * ixgbe_setup_fw_link - Setup firmware-controlled PHYs
  702  * @hw: pointer to hardware structure
  703  */
  704 static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw)
  705 {
  706         u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
  707         s32 rc;
  708         u16 i;
  709 
  710         if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
  711                 return 0;
  712 
  713         if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
  714                 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
  715                               "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
  716                 return IXGBE_ERR_INVALID_LINK_SETTINGS;
  717         }
  718 
  719         switch (hw->fc.requested_mode) {
  720         case ixgbe_fc_full:
  721                 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX <<
  722                             FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
  723                 break;
  724         case ixgbe_fc_rx_pause:
  725                 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX <<
  726                             FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
  727                 break;
  728         case ixgbe_fc_tx_pause:
  729                 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX <<
  730                             FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
  731                 break;
  732         default:
  733                 break;
  734         }
  735 
  736         for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
  737                 if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed)
  738                         setup[0] |= (u32)(ixgbe_fw_map[i].fw_speed);
  739         }
  740         setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN;
  741 
  742         if (hw->phy.eee_speeds_advertised)
  743                 setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE;
  744 
  745         rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup);
  746         if (rc)
  747                 return rc;
  748         if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)
  749                 return IXGBE_ERR_OVERTEMP;
  750         return IXGBE_SUCCESS;
  751 }
  752 
  753 /**
  754  * ixgbe_fc_autoneg_fw _ Set up flow control for FW-controlled PHYs
  755  * @hw: pointer to hardware structure
  756  *
  757  * Called at init time to set up flow control.
  758  */
  759 static s32 ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw)
  760 {
  761         if (hw->fc.requested_mode == ixgbe_fc_default)
  762                 hw->fc.requested_mode = ixgbe_fc_full;
  763 
  764         return ixgbe_setup_fw_link(hw);
  765 }
  766 
  767 /**
  768  * ixgbe_setup_eee_fw - Enable/disable EEE support
  769  * @hw: pointer to the HW structure
  770  * @enable_eee: boolean flag to enable EEE
  771  *
  772  * Enable/disable EEE based on enable_eee flag.
  773  * This function controls EEE for firmware-based PHY implementations.
  774  */
  775 static s32 ixgbe_setup_eee_fw(struct ixgbe_hw *hw, bool enable_eee)
  776 {
  777         if (!!hw->phy.eee_speeds_advertised == enable_eee)
  778                 return IXGBE_SUCCESS;
  779         if (enable_eee)
  780                 hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
  781         else
  782                 hw->phy.eee_speeds_advertised = 0;
  783         return hw->phy.ops.setup_link(hw);
  784 }
  785 
  786 /**
  787 *  ixgbe_init_ops_X550EM_a - Inits func ptrs and MAC type
  788 *  @hw: pointer to hardware structure
  789 *
  790 *  Initialize the function pointers and for MAC type X550EM_a.
  791 *  Does not touch the hardware.
  792 **/
  793 s32 ixgbe_init_ops_X550EM_a(struct ixgbe_hw *hw)
  794 {
  795         struct ixgbe_mac_info *mac = &hw->mac;
  796         s32 ret_val;
  797 
  798         DEBUGFUNC("ixgbe_init_ops_X550EM_a");
  799 
  800         /* Start with generic X550EM init */
  801         ret_val = ixgbe_init_ops_X550EM(hw);
  802 
  803         if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
  804             hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) {
  805                 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
  806                 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
  807         } else {
  808                 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a;
  809                 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a;
  810         }
  811         mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550a;
  812         mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550a;
  813 
  814         switch (mac->ops.get_media_type(hw)) {
  815         case ixgbe_media_type_fiber:
  816                 mac->ops.setup_fc = NULL;
  817                 mac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a;
  818                 break;
  819         case ixgbe_media_type_backplane:
  820                 mac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a;
  821                 mac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a;
  822                 break;
  823         default:
  824                 break;
  825         }
  826 
  827         switch (hw->device_id) {
  828         case IXGBE_DEV_ID_X550EM_A_1G_T:
  829         case IXGBE_DEV_ID_X550EM_A_1G_T_L:
  830                 mac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a;
  831                 mac->ops.setup_fc = ixgbe_fc_autoneg_fw;
  832                 mac->ops.setup_eee = ixgbe_setup_eee_fw;
  833                 hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL |
  834                                                IXGBE_LINK_SPEED_1GB_FULL;
  835                 hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
  836                 break;
  837         default:
  838                 break;
  839         }
  840 
  841         return ret_val;
  842 }
  843 
  844 /**
  845 *  ixgbe_init_ops_X550EM_x - Inits func ptrs and MAC type
  846 *  @hw: pointer to hardware structure
  847 *
  848 *  Initialize the function pointers and for MAC type X550EM_x.
  849 *  Does not touch the hardware.
  850 **/
  851 s32 ixgbe_init_ops_X550EM_x(struct ixgbe_hw *hw)
  852 {
  853         struct ixgbe_mac_info *mac = &hw->mac;
  854         struct ixgbe_link_info *link = &hw->link;
  855         s32 ret_val;
  856 
  857         DEBUGFUNC("ixgbe_init_ops_X550EM_x");
  858 
  859         /* Start with generic X550EM init */
  860         ret_val = ixgbe_init_ops_X550EM(hw);
  861 
  862         mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
  863         mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
  864         mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em;
  865         mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em;
  866         link->ops.read_link = ixgbe_read_i2c_combined_generic;
  867         link->ops.read_link_unlocked = ixgbe_read_i2c_combined_generic_unlocked;
  868         link->ops.write_link = ixgbe_write_i2c_combined_generic;
  869         link->ops.write_link_unlocked =
  870                                       ixgbe_write_i2c_combined_generic_unlocked;
  871         link->addr = IXGBE_CS4227;
  872 
  873         if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) {
  874                 mac->ops.setup_fc = NULL;
  875                 mac->ops.setup_eee = NULL;
  876                 mac->ops.init_led_link_act = NULL;
  877         }
  878 
  879         return ret_val;
  880 }
  881 
  882 /**
  883  * ixgbe_dmac_config_X550
  884  * @hw: pointer to hardware structure
  885  *
  886  * Configure DMA coalescing. If enabling dmac, dmac is activated.
  887  * When disabling dmac, dmac enable dmac bit is cleared.
  888  **/
  889 s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw)
  890 {
  891         u32 reg, high_pri_tc;
  892 
  893         DEBUGFUNC("ixgbe_dmac_config_X550");
  894 
  895         /* Disable DMA coalescing before configuring */
  896         reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
  897         reg &= ~IXGBE_DMACR_DMAC_EN;
  898         IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
  899 
  900         /* Disable DMA Coalescing if the watchdog timer is 0 */
  901         if (!hw->mac.dmac_config.watchdog_timer)
  902                 goto out;
  903 
  904         ixgbe_dmac_config_tcs_X550(hw);
  905 
  906         /* Configure DMA Coalescing Control Register */
  907         reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
  908 
  909         /* Set the watchdog timer in units of 40.96 usec */
  910         reg &= ~IXGBE_DMACR_DMACWT_MASK;
  911         reg |= (hw->mac.dmac_config.watchdog_timer * 100) / 4096;
  912 
  913         reg &= ~IXGBE_DMACR_HIGH_PRI_TC_MASK;
  914         /* If fcoe is enabled, set high priority traffic class */
  915         if (hw->mac.dmac_config.fcoe_en) {
  916                 high_pri_tc = 1 << hw->mac.dmac_config.fcoe_tc;
  917                 reg |= ((high_pri_tc << IXGBE_DMACR_HIGH_PRI_TC_SHIFT) &
  918                         IXGBE_DMACR_HIGH_PRI_TC_MASK);
  919         }
  920         reg |= IXGBE_DMACR_EN_MNG_IND;
  921 
  922         /* Enable DMA coalescing after configuration */
  923         reg |= IXGBE_DMACR_DMAC_EN;
  924         IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
  925 
  926 out:
  927         return IXGBE_SUCCESS;
  928 }
  929 
  930 /**
  931  * ixgbe_dmac_config_tcs_X550
  932  * @hw: pointer to hardware structure
  933  *
  934  * Configure DMA coalescing threshold per TC. The dmac enable bit must
  935  * be cleared before configuring.
  936  **/
  937 s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw)
  938 {
  939         u32 tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb;
  940 
  941         DEBUGFUNC("ixgbe_dmac_config_tcs_X550");
  942 
  943         /* Configure DMA coalescing enabled */
  944         switch (hw->mac.dmac_config.link_speed) {
  945         case IXGBE_LINK_SPEED_10_FULL:
  946         case IXGBE_LINK_SPEED_100_FULL:
  947                 pb_headroom = IXGBE_DMACRXT_100M;
  948                 break;
  949         case IXGBE_LINK_SPEED_1GB_FULL:
  950                 pb_headroom = IXGBE_DMACRXT_1G;
  951                 break;
  952         default:
  953                 pb_headroom = IXGBE_DMACRXT_10G;
  954                 break;
  955         }
  956 
  957         maxframe_size_kb = ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >>
  958                              IXGBE_MHADD_MFS_SHIFT) / 1024);
  959 
  960         /* Set the per Rx packet buffer receive threshold */
  961         for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) {
  962                 reg = IXGBE_READ_REG(hw, IXGBE_DMCTH(tc));
  963                 reg &= ~IXGBE_DMCTH_DMACRXT_MASK;
  964 
  965                 if (tc < hw->mac.dmac_config.num_tcs) {
  966                         /* Get Rx PB size */
  967                         rx_pb_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc));
  968                         rx_pb_size = (rx_pb_size & IXGBE_RXPBSIZE_MASK) >>
  969                                 IXGBE_RXPBSIZE_SHIFT;
  970 
  971                         /* Calculate receive buffer threshold in kilobytes */
  972                         if (rx_pb_size > pb_headroom)
  973                                 rx_pb_size = rx_pb_size - pb_headroom;
  974                         else
  975                                 rx_pb_size = 0;
  976 
  977                         /* Minimum of MFS shall be set for DMCTH */
  978                         reg |= (rx_pb_size > maxframe_size_kb) ?
  979                                 rx_pb_size : maxframe_size_kb;
  980                 }
  981                 IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg);
  982         }
  983         return IXGBE_SUCCESS;
  984 }
  985 
  986 /**
  987  * ixgbe_dmac_update_tcs_X550
  988  * @hw: pointer to hardware structure
  989  *
  990  * Disables dmac, updates per TC settings, and then enables dmac.
  991  **/
  992 s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw)
  993 {
  994         u32 reg;
  995 
  996         DEBUGFUNC("ixgbe_dmac_update_tcs_X550");
  997 
  998         /* Disable DMA coalescing before configuring */
  999         reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
 1000         reg &= ~IXGBE_DMACR_DMAC_EN;
 1001         IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
 1002 
 1003         ixgbe_dmac_config_tcs_X550(hw);
 1004 
 1005         /* Enable DMA coalescing after configuration */
 1006         reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
 1007         reg |= IXGBE_DMACR_DMAC_EN;
 1008         IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
 1009 
 1010         return IXGBE_SUCCESS;
 1011 }
 1012 
 1013 /**
 1014  * ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
 1015  * @hw: pointer to hardware structure
 1016  *
 1017  * Initializes the EEPROM parameters ixgbe_eeprom_info within the
 1018  * ixgbe_hw struct in order to set up EEPROM access.
 1019  **/
 1020 s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
 1021 {
 1022         struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
 1023         u32 eec;
 1024         u16 eeprom_size;
 1025 
 1026         DEBUGFUNC("ixgbe_init_eeprom_params_X550");
 1027 
 1028         if (eeprom->type == ixgbe_eeprom_uninitialized) {
 1029                 eeprom->semaphore_delay = 10;
 1030                 eeprom->type = ixgbe_flash;
 1031 
 1032                 eec = IXGBE_READ_REG(hw, IXGBE_EEC);
 1033                 eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
 1034                                     IXGBE_EEC_SIZE_SHIFT);
 1035                 eeprom->word_size = 1 << (eeprom_size +
 1036                                           IXGBE_EEPROM_WORD_SIZE_SHIFT);
 1037 
 1038                 DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
 1039                           eeprom->type, eeprom->word_size);
 1040         }
 1041 
 1042         return IXGBE_SUCCESS;
 1043 }
 1044 
 1045 /**
 1046  * ixgbe_set_source_address_pruning_X550 - Enable/Disbale source address pruning
 1047  * @hw: pointer to hardware structure
 1048  * @enable: enable or disable source address pruning
 1049  * @pool: Rx pool to set source address pruning for
 1050  **/
 1051 void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
 1052                                            unsigned int pool)
 1053 {
 1054         u64 pfflp;
 1055 
 1056         /* max rx pool is 63 */
 1057         if (pool > 63)
 1058                 return;
 1059 
 1060         pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
 1061         pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
 1062 
 1063         if (enable)
 1064                 pfflp |= (1ULL << pool);
 1065         else
 1066                 pfflp &= ~(1ULL << pool);
 1067 
 1068         IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp);
 1069         IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
 1070 }
 1071 
 1072 /**
 1073  * ixgbe_set_ethertype_anti_spoofing_X550 - Configure Ethertype anti-spoofing
 1074  * @hw: pointer to hardware structure
 1075  * @enable: enable or disable switch for Ethertype anti-spoofing
 1076  * @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing
 1077  *
 1078  **/
 1079 void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
 1080                 bool enable, int vf)
 1081 {
 1082         int vf_target_reg = vf >> 3;
 1083         int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT;
 1084         u32 pfvfspoof;
 1085 
 1086         DEBUGFUNC("ixgbe_set_ethertype_anti_spoofing_X550");
 1087 
 1088         pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
 1089         if (enable)
 1090                 pfvfspoof |= (1 << vf_target_shift);
 1091         else
 1092                 pfvfspoof &= ~(1 << vf_target_shift);
 1093 
 1094         IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
 1095 }
 1096 
 1097 /**
 1098  * ixgbe_iosf_wait - Wait for IOSF command completion
 1099  * @hw: pointer to hardware structure
 1100  * @ctrl: pointer to location to receive final IOSF control value
 1101  *
 1102  * Returns failing status on timeout
 1103  *
 1104  * Note: ctrl can be NULL if the IOSF control register value is not needed
 1105  **/
 1106 static s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl)
 1107 {
 1108         u32 i, command = 0;
 1109 
 1110         /* Check every 10 usec to see if the address cycle completed.
 1111          * The SB IOSF BUSY bit will clear when the operation is
 1112          * complete
 1113          */
 1114         for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
 1115                 command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
 1116                 if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
 1117                         break;
 1118                 usec_delay(10);
 1119         }
 1120         if (ctrl)
 1121                 *ctrl = command;
 1122         if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
 1123                 ERROR_REPORT1(IXGBE_ERROR_POLLING, "Wait timed out\n");
 1124                 return IXGBE_ERR_PHY;
 1125         }
 1126 
 1127         return IXGBE_SUCCESS;
 1128 }
 1129 
 1130 /**
 1131  * ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register
 1132  * of the IOSF device
 1133  * @hw: pointer to hardware structure
 1134  * @reg_addr: 32 bit PHY register to write
 1135  * @device_type: 3 bit device type
 1136  * @data: Data to write to the register
 1137  **/
 1138 s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
 1139                             u32 device_type, u32 data)
 1140 {
 1141         u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
 1142         u32 command, error __unused;
 1143         s32 ret;
 1144 
 1145         ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
 1146         if (ret != IXGBE_SUCCESS)
 1147                 return ret;
 1148 
 1149         ret = ixgbe_iosf_wait(hw, NULL);
 1150         if (ret != IXGBE_SUCCESS)
 1151                 goto out;
 1152 
 1153         command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
 1154                    (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
 1155 
 1156         /* Write IOSF control register */
 1157         IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
 1158 
 1159         /* Write IOSF data register */
 1160         IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
 1161 
 1162         ret = ixgbe_iosf_wait(hw, &command);
 1163 
 1164         if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
 1165                 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
 1166                          IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
 1167                 ERROR_REPORT2(IXGBE_ERROR_POLLING,
 1168                               "Failed to write, error %x\n", error);
 1169                 ret = IXGBE_ERR_PHY;
 1170         }
 1171 
 1172 out:
 1173         ixgbe_release_swfw_semaphore(hw, gssr);
 1174         return ret;
 1175 }
 1176 
 1177 /**
 1178  * ixgbe_read_iosf_sb_reg_x550 - Reads specified register of the IOSF device
 1179  * @hw: pointer to hardware structure
 1180  * @reg_addr: 32 bit PHY register to write
 1181  * @device_type: 3 bit device type
 1182  * @data: Pointer to read data from the register
 1183  **/
 1184 s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
 1185                            u32 device_type, u32 *data)
 1186 {
 1187         u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
 1188         u32 command, error __unused;
 1189         s32 ret;
 1190 
 1191         ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
 1192         if (ret != IXGBE_SUCCESS)
 1193                 return ret;
 1194 
 1195         ret = ixgbe_iosf_wait(hw, NULL);
 1196         if (ret != IXGBE_SUCCESS)
 1197                 goto out;
 1198 
 1199         command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
 1200                    (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
 1201 
 1202         /* Write IOSF control register */
 1203         IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
 1204 
 1205         ret = ixgbe_iosf_wait(hw, &command);
 1206 
 1207         if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
 1208                 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
 1209                          IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
 1210                 ERROR_REPORT2(IXGBE_ERROR_POLLING,
 1211                                 "Failed to read, error %x\n", error);
 1212                 ret = IXGBE_ERR_PHY;
 1213         }
 1214 
 1215         if (ret == IXGBE_SUCCESS)
 1216                 *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
 1217 
 1218 out:
 1219         ixgbe_release_swfw_semaphore(hw, gssr);
 1220         return ret;
 1221 }
 1222 
 1223 /**
 1224  * ixgbe_get_phy_token - Get the token for shared phy access
 1225  * @hw: Pointer to hardware structure
 1226  */
 1227 
 1228 s32 ixgbe_get_phy_token(struct ixgbe_hw *hw)
 1229 {
 1230         struct ixgbe_hic_phy_token_req token_cmd;
 1231         s32 status;
 1232 
 1233         token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
 1234         token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
 1235         token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
 1236         token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
 1237         token_cmd.port_number = hw->bus.lan_id;
 1238         token_cmd.command_type = FW_PHY_TOKEN_REQ;
 1239         token_cmd.pad = 0;
 1240         status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd,
 1241                                               sizeof(token_cmd),
 1242                                               IXGBE_HI_COMMAND_TIMEOUT,
 1243                                               true);
 1244         if (status) {
 1245                 DEBUGOUT1("Issuing host interface command failed with Status = %d\n",
 1246                           status);
 1247                 return status;
 1248         }
 1249         if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
 1250                 return IXGBE_SUCCESS;
 1251         if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY) {
 1252                 DEBUGOUT1("Host interface command returned 0x%08x , returning IXGBE_ERR_FW_RESP_INVALID\n",
 1253                           token_cmd.hdr.cmd_or_resp.ret_status);
 1254                 return IXGBE_ERR_FW_RESP_INVALID;
 1255         }
 1256 
 1257         DEBUGOUT("Returning  IXGBE_ERR_TOKEN_RETRY\n");
 1258         return IXGBE_ERR_TOKEN_RETRY;
 1259 }
 1260 
 1261 /**
 1262  * ixgbe_put_phy_token - Put the token for shared phy access
 1263  * @hw: Pointer to hardware structure
 1264  */
 1265 
 1266 s32 ixgbe_put_phy_token(struct ixgbe_hw *hw)
 1267 {
 1268         struct ixgbe_hic_phy_token_req token_cmd;
 1269         s32 status;
 1270 
 1271         token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
 1272         token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
 1273         token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
 1274         token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
 1275         token_cmd.port_number = hw->bus.lan_id;
 1276         token_cmd.command_type = FW_PHY_TOKEN_REL;
 1277         token_cmd.pad = 0;
 1278         status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd,
 1279                                               sizeof(token_cmd),
 1280                                               IXGBE_HI_COMMAND_TIMEOUT,
 1281                                               true);
 1282         if (status)
 1283                 return status;
 1284         if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
 1285                 return IXGBE_SUCCESS;
 1286 
 1287         DEBUGOUT("Put PHY Token host interface command failed");
 1288         return IXGBE_ERR_FW_RESP_INVALID;
 1289 }
 1290 
 1291 /**
 1292  * ixgbe_write_iosf_sb_reg_x550a - Writes a value to specified register
 1293  * of the IOSF device
 1294  * @hw: pointer to hardware structure
 1295  * @reg_addr: 32 bit PHY register to write
 1296  * @device_type: 3 bit device type
 1297  * @data: Data to write to the register
 1298  **/
 1299 s32 ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
 1300                                   u32 device_type, u32 data)
 1301 {
 1302         struct ixgbe_hic_internal_phy_req write_cmd;
 1303         s32 status;
 1304         UNREFERENCED_1PARAMETER(device_type);
 1305 
 1306         memset(&write_cmd, 0, sizeof(write_cmd));
 1307         write_cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
 1308         write_cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
 1309         write_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
 1310         write_cmd.port_number = hw->bus.lan_id;
 1311         write_cmd.command_type = FW_INT_PHY_REQ_WRITE;
 1312         write_cmd.address = IXGBE_CPU_TO_BE16(reg_addr);
 1313         write_cmd.write_data = IXGBE_CPU_TO_BE32(data);
 1314 
 1315         status = ixgbe_host_interface_command(hw, (u32 *)&write_cmd,
 1316                                               sizeof(write_cmd),
 1317                                               IXGBE_HI_COMMAND_TIMEOUT, false);
 1318 
 1319         return status;
 1320 }
 1321 
 1322 /**
 1323  * ixgbe_read_iosf_sb_reg_x550a - Reads specified register of the IOSF device
 1324  * @hw: pointer to hardware structure
 1325  * @reg_addr: 32 bit PHY register to write
 1326  * @device_type: 3 bit device type
 1327  * @data: Pointer to read data from the register
 1328  **/
 1329 s32 ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
 1330                                  u32 device_type, u32 *data)
 1331 {
 1332         union {
 1333                 struct ixgbe_hic_internal_phy_req cmd;
 1334                 struct ixgbe_hic_internal_phy_resp rsp;
 1335         } hic;
 1336         s32 status;
 1337         UNREFERENCED_1PARAMETER(device_type);
 1338 
 1339         memset(&hic, 0, sizeof(hic));
 1340         hic.cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
 1341         hic.cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
 1342         hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
 1343         hic.cmd.port_number = hw->bus.lan_id;
 1344         hic.cmd.command_type = FW_INT_PHY_REQ_READ;
 1345         hic.cmd.address = IXGBE_CPU_TO_BE16(reg_addr);
 1346 
 1347         status = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd,
 1348                                               sizeof(hic.cmd),
 1349                                               IXGBE_HI_COMMAND_TIMEOUT, true);
 1350 
 1351         /* Extract the register value from the response. */
 1352         *data = IXGBE_BE32_TO_CPU(hic.rsp.read_data);
 1353 
 1354         return status;
 1355 }
 1356 
 1357 /**
 1358  * ixgbe_disable_mdd_X550
 1359  * @hw: pointer to hardware structure
 1360  *
 1361  * Disable malicious driver detection
 1362  **/
 1363 void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw)
 1364 {
 1365         u32 reg;
 1366 
 1367         DEBUGFUNC("ixgbe_disable_mdd_X550");
 1368 
 1369         /* Disable MDD for TX DMA and interrupt */
 1370         reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
 1371         reg &= ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
 1372         IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
 1373 
 1374         /* Disable MDD for RX and interrupt */
 1375         reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
 1376         reg &= ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
 1377         IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
 1378 }
 1379 
 1380 /**
 1381  * ixgbe_enable_mdd_X550
 1382  * @hw: pointer to hardware structure
 1383  *
 1384  * Enable malicious driver detection
 1385  **/
 1386 void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw)
 1387 {
 1388         u32 reg;
 1389 
 1390         DEBUGFUNC("ixgbe_enable_mdd_X550");
 1391 
 1392         /* Enable MDD for TX DMA and interrupt */
 1393         reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
 1394         reg |= (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
 1395         IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
 1396 
 1397         /* Enable MDD for RX and interrupt */
 1398         reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
 1399         reg |= (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
 1400         IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
 1401 }
 1402 
 1403 /**
 1404  * ixgbe_restore_mdd_vf_X550
 1405  * @hw: pointer to hardware structure
 1406  * @vf: vf index
 1407  *
 1408  * Restore VF that was disabled during malicious driver detection event
 1409  **/
 1410 void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf)
 1411 {
 1412         u32 idx, reg, num_qs, start_q, bitmask;
 1413 
 1414         DEBUGFUNC("ixgbe_restore_mdd_vf_X550");
 1415 
 1416         /* Map VF to queues */
 1417         reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
 1418         switch (reg & IXGBE_MRQC_MRQE_MASK) {
 1419         case IXGBE_MRQC_VMDQRT8TCEN:
 1420                 num_qs = 8;  /* 16 VFs / pools */
 1421                 bitmask = 0x000000FF;
 1422                 break;
 1423         case IXGBE_MRQC_VMDQRSS32EN:
 1424         case IXGBE_MRQC_VMDQRT4TCEN:
 1425                 num_qs = 4;  /* 32 VFs / pools */
 1426                 bitmask = 0x0000000F;
 1427                 break;
 1428         default:            /* 64 VFs / pools */
 1429                 num_qs = 2;
 1430                 bitmask = 0x00000003;
 1431                 break;
 1432         }
 1433         start_q = vf * num_qs;
 1434 
 1435         /* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */
 1436         idx = start_q / 32;
 1437         reg = 0;
 1438         reg |= (bitmask << (start_q % 32));
 1439         IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), reg);
 1440         IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), reg);
 1441 }
 1442 
 1443 /**
 1444  * ixgbe_mdd_event_X550
 1445  * @hw: pointer to hardware structure
 1446  * @vf_bitmap: vf bitmap of malicious vfs
 1447  *
 1448  * Handle malicious driver detection event.
 1449  **/
 1450 void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap)
 1451 {
 1452         u32 wqbr;
 1453         u32 i, j, reg, q, shift, vf, idx;
 1454 
 1455         DEBUGFUNC("ixgbe_mdd_event_X550");
 1456 
 1457         /* figure out pool size for mapping to vf's */
 1458         reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
 1459         switch (reg & IXGBE_MRQC_MRQE_MASK) {
 1460         case IXGBE_MRQC_VMDQRT8TCEN:
 1461                 shift = 3;  /* 16 VFs / pools */
 1462                 break;
 1463         case IXGBE_MRQC_VMDQRSS32EN:
 1464         case IXGBE_MRQC_VMDQRT4TCEN:
 1465                 shift = 2;  /* 32 VFs / pools */
 1466                 break;
 1467         default:
 1468                 shift = 1;  /* 64 VFs / pools */
 1469                 break;
 1470         }
 1471 
 1472         /* Read WQBR_TX and WQBR_RX and check for malicious queues */
 1473         for (i = 0; i < 4; i++) {
 1474                 wqbr = IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i));
 1475                 wqbr |= IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i));
 1476 
 1477                 if (!wqbr)
 1478                         continue;
 1479 
 1480                 /* Get malicious queue */
 1481                 for (j = 0; j < 32 && wqbr; j++) {
 1482 
 1483                         if (!(wqbr & (1 << j)))
 1484                                 continue;
 1485 
 1486                         /* Get queue from bitmask */
 1487                         q = j + (i * 32);
 1488 
 1489                         /* Map queue to vf */
 1490                         vf = (q >> shift);
 1491 
 1492                         /* Set vf bit in vf_bitmap */
 1493                         idx = vf / 32;
 1494                         vf_bitmap[idx] |= (1 << (vf % 32));
 1495                         wqbr &= ~(1 << j);
 1496                 }
 1497         }
 1498 }
 1499 
 1500 /**
 1501  * ixgbe_get_media_type_X550em - Get media type
 1502  * @hw: pointer to hardware structure
 1503  *
 1504  * Returns the media type (fiber, copper, backplane)
 1505  */
 1506 enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
 1507 {
 1508         enum ixgbe_media_type media_type;
 1509 
 1510         DEBUGFUNC("ixgbe_get_media_type_X550em");
 1511 
 1512         /* Detect if there is a copper PHY attached. */
 1513         switch (hw->device_id) {
 1514         case IXGBE_DEV_ID_X550EM_X_KR:
 1515         case IXGBE_DEV_ID_X550EM_X_KX4:
 1516         case IXGBE_DEV_ID_X550EM_X_XFI:
 1517         case IXGBE_DEV_ID_X550EM_A_KR:
 1518         case IXGBE_DEV_ID_X550EM_A_KR_L:
 1519                 media_type = ixgbe_media_type_backplane;
 1520                 break;
 1521         case IXGBE_DEV_ID_X550EM_X_SFP:
 1522         case IXGBE_DEV_ID_X550EM_A_SFP:
 1523         case IXGBE_DEV_ID_X550EM_A_SFP_N:
 1524         case IXGBE_DEV_ID_X550EM_A_QSFP:
 1525         case IXGBE_DEV_ID_X550EM_A_QSFP_N:
 1526                 media_type = ixgbe_media_type_fiber;
 1527                 break;
 1528         case IXGBE_DEV_ID_X550EM_X_1G_T:
 1529         case IXGBE_DEV_ID_X550EM_X_10G_T:
 1530         case IXGBE_DEV_ID_X550EM_A_10G_T:
 1531                 media_type = ixgbe_media_type_copper;
 1532                 break;
 1533         case IXGBE_DEV_ID_X550EM_A_SGMII:
 1534         case IXGBE_DEV_ID_X550EM_A_SGMII_L:
 1535                 media_type = ixgbe_media_type_backplane;
 1536                 hw->phy.type = ixgbe_phy_sgmii;
 1537                 break;
 1538         case IXGBE_DEV_ID_X550EM_A_1G_T:
 1539         case IXGBE_DEV_ID_X550EM_A_1G_T_L:
 1540                 media_type = ixgbe_media_type_copper;
 1541                 break;
 1542         default:
 1543                 media_type = ixgbe_media_type_unknown;
 1544                 break;
 1545         }
 1546         return media_type;
 1547 }
 1548 
 1549 /**
 1550  * ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
 1551  * @hw: pointer to hardware structure
 1552  * @linear: true if SFP module is linear
 1553  */
 1554 static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
 1555 {
 1556         DEBUGFUNC("ixgbe_supported_sfp_modules_X550em");
 1557 
 1558         switch (hw->phy.sfp_type) {
 1559         case ixgbe_sfp_type_not_present:
 1560                 return IXGBE_ERR_SFP_NOT_PRESENT;
 1561         case ixgbe_sfp_type_da_cu_core0:
 1562         case ixgbe_sfp_type_da_cu_core1:
 1563                 *linear = true;
 1564                 break;
 1565         case ixgbe_sfp_type_srlr_core0:
 1566         case ixgbe_sfp_type_srlr_core1:
 1567         case ixgbe_sfp_type_da_act_lmt_core0:
 1568         case ixgbe_sfp_type_da_act_lmt_core1:
 1569         case ixgbe_sfp_type_1g_sx_core0:
 1570         case ixgbe_sfp_type_1g_sx_core1:
 1571         case ixgbe_sfp_type_1g_lx_core0:
 1572         case ixgbe_sfp_type_1g_lx_core1:
 1573                 *linear = false;
 1574                 break;
 1575         case ixgbe_sfp_type_unknown:
 1576         case ixgbe_sfp_type_1g_cu_core0:
 1577         case ixgbe_sfp_type_1g_cu_core1:
 1578         default:
 1579                 return IXGBE_ERR_SFP_NOT_SUPPORTED;
 1580         }
 1581 
 1582         return IXGBE_SUCCESS;
 1583 }
 1584 
 1585 /**
 1586  * ixgbe_identify_sfp_module_X550em - Identifies SFP modules
 1587  * @hw: pointer to hardware structure
 1588  *
 1589  * Searches for and identifies the SFP module and assigns appropriate PHY type.
 1590  **/
 1591 s32 ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw)
 1592 {
 1593         s32 status;
 1594         bool linear;
 1595 
 1596         DEBUGFUNC("ixgbe_identify_sfp_module_X550em");
 1597 
 1598         status = ixgbe_identify_module_generic(hw);
 1599 
 1600         if (status != IXGBE_SUCCESS)
 1601                 return status;
 1602 
 1603         /* Check if SFP module is supported */
 1604         status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
 1605 
 1606         return status;
 1607 }
 1608 
 1609 /**
 1610  * ixgbe_setup_sfp_modules_X550em - Setup MAC link ops
 1611  * @hw: pointer to hardware structure
 1612  */
 1613 s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
 1614 {
 1615         s32 status;
 1616         bool linear;
 1617 
 1618         DEBUGFUNC("ixgbe_setup_sfp_modules_X550em");
 1619 
 1620         /* Check if SFP module is supported */
 1621         status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
 1622 
 1623         if (status != IXGBE_SUCCESS)
 1624                 return status;
 1625 
 1626         ixgbe_init_mac_link_ops_X550em(hw);
 1627         hw->phy.ops.reset = NULL;
 1628 
 1629         return IXGBE_SUCCESS;
 1630 }
 1631 
 1632 /**
 1633 *  ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the
 1634 *  internal PHY
 1635 *  @hw: pointer to hardware structure
 1636 **/
 1637 static s32 ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw)
 1638 {
 1639         s32 status;
 1640         u32 link_ctrl;
 1641 
 1642         /* Restart auto-negotiation. */
 1643         status = hw->mac.ops.read_iosf_sb_reg(hw,
 1644                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 1645                                        IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl);
 1646 
 1647         if (status) {
 1648                 DEBUGOUT("Auto-negotiation did not complete\n");
 1649                 return status;
 1650         }
 1651 
 1652         link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
 1653         status = hw->mac.ops.write_iosf_sb_reg(hw,
 1654                                         IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 1655                                         IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl);
 1656 
 1657         if (hw->mac.type == ixgbe_mac_X550EM_a) {
 1658                 u32 flx_mask_st20;
 1659 
 1660                 /* Indicate to FW that AN restart has been asserted */
 1661                 status = hw->mac.ops.read_iosf_sb_reg(hw,
 1662                                 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 1663                                 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20);
 1664 
 1665                 if (status) {
 1666                         DEBUGOUT("Auto-negotiation did not complete\n");
 1667                         return status;
 1668                 }
 1669 
 1670                 flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART;
 1671                 status = hw->mac.ops.write_iosf_sb_reg(hw,
 1672                                 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 1673                                 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20);
 1674         }
 1675 
 1676         return status;
 1677 }
 1678 
 1679 /**
 1680  * ixgbe_setup_sgmii - Set up link for sgmii
 1681  * @hw: pointer to hardware structure
 1682  * @speed: new link speed
 1683  * @autoneg_wait: true when waiting for completion is needed
 1684  */
 1685 static s32 ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed,
 1686                              bool autoneg_wait)
 1687 {
 1688         struct ixgbe_mac_info *mac = &hw->mac;
 1689         u32 lval, sval, flx_val;
 1690         s32 rc;
 1691 
 1692         rc = mac->ops.read_iosf_sb_reg(hw,
 1693                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 1694                                        IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
 1695         if (rc)
 1696                 return rc;
 1697 
 1698         lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
 1699         lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
 1700         lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
 1701         lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
 1702         lval |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
 1703         rc = mac->ops.write_iosf_sb_reg(hw,
 1704                                         IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 1705                                         IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
 1706         if (rc)
 1707                 return rc;
 1708 
 1709         rc = mac->ops.read_iosf_sb_reg(hw,
 1710                                        IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
 1711                                        IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
 1712         if (rc)
 1713                 return rc;
 1714 
 1715         sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
 1716         sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
 1717         rc = mac->ops.write_iosf_sb_reg(hw,
 1718                                         IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
 1719                                         IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
 1720         if (rc)
 1721                 return rc;
 1722 
 1723         rc = mac->ops.read_iosf_sb_reg(hw,
 1724                                     IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 1725                                     IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
 1726         if (rc)
 1727                 return rc;
 1728 
 1729         flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
 1730         flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
 1731         flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
 1732         flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
 1733         flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
 1734 
 1735         rc = mac->ops.write_iosf_sb_reg(hw,
 1736                                     IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 1737                                     IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
 1738         if (rc)
 1739                 return rc;
 1740 
 1741         rc = ixgbe_restart_an_internal_phy_x550em(hw);
 1742         if (rc)
 1743                 return rc;
 1744 
 1745         return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
 1746 }
 1747 
 1748 /**
 1749  * ixgbe_setup_sgmii_fw - Set up link for internal PHY SGMII auto-negotiation
 1750  * @hw: pointer to hardware structure
 1751  * @speed: new link speed
 1752  * @autoneg_wait: true when waiting for completion is needed
 1753  */
 1754 static s32 ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed,
 1755                                 bool autoneg_wait)
 1756 {
 1757         struct ixgbe_mac_info *mac = &hw->mac;
 1758         u32 lval, sval, flx_val;
 1759         s32 rc;
 1760 
 1761         rc = mac->ops.read_iosf_sb_reg(hw,
 1762                                        IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 1763                                        IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
 1764         if (rc)
 1765                 return rc;
 1766 
 1767         lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
 1768         lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
 1769         lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
 1770         lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
 1771         lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
 1772         rc = mac->ops.write_iosf_sb_reg(hw,
 1773                                         IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 1774                                         IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
 1775         if (rc)
 1776                 return rc;
 1777 
 1778         rc = mac->ops.read_iosf_sb_reg(hw,
 1779                                        IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
 1780                                        IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
 1781         if (rc)
 1782                 return rc;
 1783 
 1784         sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
 1785         sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
 1786         rc = mac->ops.write_iosf_sb_reg(hw,
 1787                                         IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
 1788                                         IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
 1789         if (rc)
 1790                 return rc;
 1791 
 1792         rc = mac->ops.write_iosf_sb_reg(hw,
 1793                                         IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 1794                                         IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
 1795         if (rc)
 1796                 return rc;
 1797 
 1798         rc = mac->ops.read_iosf_sb_reg(hw,
 1799                                     IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 1800                                     IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
 1801         if (rc)
 1802                 return rc;
 1803 
 1804         flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
 1805         flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
 1806         flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
 1807         flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
 1808         flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
 1809 
 1810         rc = mac->ops.write_iosf_sb_reg(hw,
 1811                                     IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 1812                                     IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
 1813         if (rc)
 1814                 return rc;
 1815 
 1816         rc = ixgbe_restart_an_internal_phy_x550em(hw);
 1817 
 1818         return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
 1819 }
 1820 
 1821 /**
 1822  * ixgbe_init_mac_link_ops_X550em - init mac link function pointers
 1823  * @hw: pointer to hardware structure
 1824  */
 1825 void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
 1826 {
 1827         struct ixgbe_mac_info *mac = &hw->mac;
 1828 
 1829         DEBUGFUNC("ixgbe_init_mac_link_ops_X550em");
 1830 
 1831         switch (hw->mac.ops.get_media_type(hw)) {
 1832         case ixgbe_media_type_fiber:
 1833                 /* CS4227 does not support autoneg, so disable the laser control
 1834                  * functions for SFP+ fiber
 1835                  */
 1836                 mac->ops.disable_tx_laser = NULL;
 1837                 mac->ops.enable_tx_laser = NULL;
 1838                 mac->ops.flap_tx_laser = NULL;
 1839                 mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
 1840                 mac->ops.set_rate_select_speed =
 1841                                         ixgbe_set_soft_rate_select_speed;
 1842 
 1843                 if ((hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) ||
 1844                     (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP))
 1845                         mac->ops.setup_mac_link =
 1846                                                 ixgbe_setup_mac_link_sfp_x550a;
 1847                 else
 1848                         mac->ops.setup_mac_link =
 1849                                                 ixgbe_setup_mac_link_sfp_x550em;
 1850                 break;
 1851         case ixgbe_media_type_copper:
 1852                 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T)
 1853                         break;
 1854                 if (hw->mac.type == ixgbe_mac_X550EM_a) {
 1855                         if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
 1856                             hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) {
 1857                                 mac->ops.setup_link = ixgbe_setup_sgmii_fw;
 1858                                 mac->ops.check_link =
 1859                                                    ixgbe_check_mac_link_generic;
 1860                         } else {
 1861                                 mac->ops.setup_link =
 1862                                                   ixgbe_setup_mac_link_t_X550em;
 1863                         }
 1864                 } else {
 1865                         mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
 1866                         mac->ops.check_link = ixgbe_check_link_t_X550em;
 1867                 }
 1868                 break;
 1869         case ixgbe_media_type_backplane:
 1870                 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
 1871                     hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L)
 1872                         mac->ops.setup_link = ixgbe_setup_sgmii;
 1873                 break;
 1874         default:
 1875                 break;
 1876         }
 1877 }
 1878 
 1879 /**
 1880  * ixgbe_get_link_capabilities_x550em - Determines link capabilities
 1881  * @hw: pointer to hardware structure
 1882  * @speed: pointer to link speed
 1883  * @autoneg: true when autoneg or autotry is enabled
 1884  */
 1885 s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
 1886                                        ixgbe_link_speed *speed,
 1887                                        bool *autoneg)
 1888 {
 1889         DEBUGFUNC("ixgbe_get_link_capabilities_X550em");
 1890 
 1891 
 1892         if (hw->phy.type == ixgbe_phy_fw) {
 1893                 *autoneg = true;
 1894                 *speed = hw->phy.speeds_supported;
 1895                 return 0;
 1896         }
 1897 
 1898         /* SFP */
 1899         if (hw->phy.media_type == ixgbe_media_type_fiber) {
 1900 
 1901                 /* CS4227 SFP must not enable auto-negotiation */
 1902                 *autoneg = false;
 1903 
 1904                 /* Check if 1G SFP module. */
 1905                 if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
 1906                     hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1
 1907                     || hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
 1908                     hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) {
 1909                         *speed = IXGBE_LINK_SPEED_1GB_FULL;
 1910                         return IXGBE_SUCCESS;
 1911                 }
 1912 
 1913                 /* Link capabilities are based on SFP */
 1914                 if (hw->phy.multispeed_fiber)
 1915                         *speed = IXGBE_LINK_SPEED_10GB_FULL |
 1916                                  IXGBE_LINK_SPEED_1GB_FULL;
 1917                 else
 1918                         *speed = IXGBE_LINK_SPEED_10GB_FULL;
 1919         } else {
 1920                 *autoneg = true;
 1921 
 1922                 switch (hw->phy.type) {
 1923                 case ixgbe_phy_x550em_xfi:
 1924                         *speed = IXGBE_LINK_SPEED_1GB_FULL |
 1925                                          IXGBE_LINK_SPEED_10GB_FULL;
 1926                         *autoneg = false;
 1927                         break;
 1928                 case ixgbe_phy_ext_1g_t:
 1929                 case ixgbe_phy_sgmii:
 1930                         *speed = IXGBE_LINK_SPEED_1GB_FULL;
 1931                         break;
 1932                 case ixgbe_phy_x550em_kr:
 1933                         if (hw->mac.type == ixgbe_mac_X550EM_a) {
 1934                                 /* check different backplane modes */
 1935                                 if (hw->phy.nw_mng_if_sel &
 1936                                            IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) {
 1937                                         *speed = IXGBE_LINK_SPEED_2_5GB_FULL;
 1938                                         break;
 1939                                 } else if (hw->device_id ==
 1940                                                    IXGBE_DEV_ID_X550EM_A_KR_L) {
 1941                                         *speed = IXGBE_LINK_SPEED_1GB_FULL;
 1942                                         break;
 1943                                 }
 1944                         }
 1945                         /* fall through */
 1946                 default:
 1947                         *speed = IXGBE_LINK_SPEED_10GB_FULL |
 1948                                  IXGBE_LINK_SPEED_1GB_FULL;
 1949                         break;
 1950                 }
 1951         }
 1952 
 1953         return IXGBE_SUCCESS;
 1954 }
 1955 
 1956 /**
 1957  * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause
 1958  * @hw: pointer to hardware structure
 1959  * @lsc: pointer to boolean flag which indicates whether external Base T
 1960  *      PHY interrupt is lsc
 1961  *
 1962  * Determime if external Base T PHY interrupt cause is high temperature
 1963  * failure alarm or link status change.
 1964  *
 1965  * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
 1966  * failure alarm, else return PHY access status.
 1967  */
 1968 static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
 1969 {
 1970         u32 status;
 1971         u16 reg;
 1972 
 1973         *lsc = false;
 1974 
 1975         /* Vendor alarm triggered */
 1976         status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
 1977                                       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 1978                                       &reg);
 1979 
 1980         if (status != IXGBE_SUCCESS ||
 1981             !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN))
 1982                 return status;
 1983 
 1984         /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */
 1985         status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG,
 1986                                       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 1987                                       &reg);
 1988 
 1989         if (status != IXGBE_SUCCESS ||
 1990             !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
 1991             IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
 1992                 return status;
 1993 
 1994         /* Global alarm triggered */
 1995         status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
 1996                                       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 1997                                       &reg);
 1998 
 1999         if (status != IXGBE_SUCCESS)
 2000                 return status;
 2001 
 2002         /* If high temperature failure, then return over temp error and exit */
 2003         if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
 2004                 /* power down the PHY in case the PHY FW didn't already */
 2005                 ixgbe_set_copper_phy_power(hw, false);
 2006                 return IXGBE_ERR_OVERTEMP;
 2007         } else if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
 2008                 /*  device fault alarm triggered */
 2009                 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
 2010                                           IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 2011                                           &reg);
 2012 
 2013                 if (status != IXGBE_SUCCESS)
 2014                         return status;
 2015 
 2016                 /* if device fault was due to high temp alarm handle and exit */
 2017                 if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
 2018                         /* power down the PHY in case the PHY FW didn't */
 2019                         ixgbe_set_copper_phy_power(hw, false);
 2020                         return IXGBE_ERR_OVERTEMP;
 2021                 }
 2022         }
 2023 
 2024         /* Vendor alarm 2 triggered */
 2025         status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
 2026                                       IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
 2027 
 2028         if (status != IXGBE_SUCCESS ||
 2029             !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT))
 2030                 return status;
 2031 
 2032         /* link connect/disconnect event occurred */
 2033         status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2,
 2034                                       IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
 2035 
 2036         if (status != IXGBE_SUCCESS)
 2037                 return status;
 2038 
 2039         /* Indicate LSC */
 2040         if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC)
 2041                 *lsc = true;
 2042 
 2043         return IXGBE_SUCCESS;
 2044 }
 2045 
 2046 /**
 2047  * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts
 2048  * @hw: pointer to hardware structure
 2049  *
 2050  * Enable link status change and temperature failure alarm for the external
 2051  * Base T PHY
 2052  *
 2053  * Returns PHY access status
 2054  */
 2055 static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
 2056 {
 2057         u32 status;
 2058         u16 reg;
 2059         bool lsc;
 2060 
 2061         /* Clear interrupt flags */
 2062         status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
 2063 
 2064         /* Enable link status change alarm */
 2065 
 2066         /* Enable the LASI interrupts on X552 devices to receive notifications
 2067          * of the link configurations of the external PHY and correspondingly
 2068          * support the configuration of the internal iXFI link, since iXFI does
 2069          * not support auto-negotiation. This is not required for X553 devices
 2070          * having KR support, which performs auto-negotiations and which is used
 2071          * as the internal link to the external PHY. Hence adding a check here
 2072          * to avoid enabling LASI interrupts for X553 devices.
 2073          */
 2074         if (hw->mac.type != ixgbe_mac_X550EM_a) {
 2075                 status = hw->phy.ops.read_reg(hw,
 2076                                         IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
 2077                                         IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
 2078 
 2079                 if (status != IXGBE_SUCCESS)
 2080                         return status;
 2081 
 2082                 reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN;
 2083 
 2084                 status = hw->phy.ops.write_reg(hw,
 2085                                         IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
 2086                                         IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg);
 2087 
 2088                 if (status != IXGBE_SUCCESS)
 2089                         return status;
 2090         }
 2091 
 2092         /* Enable high temperature failure and global fault alarms */
 2093         status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
 2094                                       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 2095                                       &reg);
 2096 
 2097         if (status != IXGBE_SUCCESS)
 2098                 return status;
 2099 
 2100         reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN |
 2101                 IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN);
 2102 
 2103         status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
 2104                                        IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 2105                                        reg);
 2106 
 2107         if (status != IXGBE_SUCCESS)
 2108                 return status;
 2109 
 2110         /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */
 2111         status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
 2112                                       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 2113                                       &reg);
 2114 
 2115         if (status != IXGBE_SUCCESS)
 2116                 return status;
 2117 
 2118         reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
 2119                 IXGBE_MDIO_GLOBAL_ALARM_1_INT);
 2120 
 2121         status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
 2122                                        IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 2123                                        reg);
 2124 
 2125         if (status != IXGBE_SUCCESS)
 2126                 return status;
 2127 
 2128         /* Enable chip-wide vendor alarm */
 2129         status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
 2130                                       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 2131                                       &reg);
 2132 
 2133         if (status != IXGBE_SUCCESS)
 2134                 return status;
 2135 
 2136         reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN;
 2137 
 2138         status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
 2139                                        IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 2140                                        reg);
 2141 
 2142         return status;
 2143 }
 2144 
 2145 /**
 2146  * ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed.
 2147  * @hw: pointer to hardware structure
 2148  * @speed: link speed
 2149  *
 2150  * Configures the integrated KR PHY.
 2151  **/
 2152 static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
 2153                                        ixgbe_link_speed speed)
 2154 {
 2155         s32 status;
 2156         u32 reg_val;
 2157 
 2158         status = hw->mac.ops.read_iosf_sb_reg(hw,
 2159                                         IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 2160                                         IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 2161         if (status)
 2162                 return status;
 2163 
 2164         reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
 2165         reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
 2166                      IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
 2167 
 2168         /* Advertise 10G support. */
 2169         if (speed & IXGBE_LINK_SPEED_10GB_FULL)
 2170                 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
 2171 
 2172         /* Advertise 1G support. */
 2173         if (speed & IXGBE_LINK_SPEED_1GB_FULL)
 2174                 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
 2175 
 2176         status = hw->mac.ops.write_iosf_sb_reg(hw,
 2177                                         IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 2178                                         IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 2179 
 2180         if (hw->mac.type == ixgbe_mac_X550EM_a) {
 2181                 /* Set lane mode  to KR auto negotiation */
 2182                 status = hw->mac.ops.read_iosf_sb_reg(hw,
 2183                                     IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 2184                                     IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 2185 
 2186                 if (status)
 2187                         return status;
 2188 
 2189                 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
 2190                 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
 2191                 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
 2192                 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
 2193                 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
 2194 
 2195                 status = hw->mac.ops.write_iosf_sb_reg(hw,
 2196                                     IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 2197                                     IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 2198         }
 2199 
 2200         return ixgbe_restart_an_internal_phy_x550em(hw);
 2201 }
 2202 
 2203 /**
 2204  * ixgbe_reset_phy_fw - Reset firmware-controlled PHYs
 2205  * @hw: pointer to hardware structure
 2206  */
 2207 static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw)
 2208 {
 2209         u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
 2210         s32 rc;
 2211 
 2212         if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
 2213                 return IXGBE_SUCCESS;
 2214 
 2215         rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_PHY_SW_RESET, &store);
 2216         if (rc)
 2217                 return rc;
 2218         memset(store, 0, sizeof(store));
 2219 
 2220         rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_INIT_PHY, &store);
 2221         if (rc)
 2222                 return rc;
 2223 
 2224         return ixgbe_setup_fw_link(hw);
 2225 }
 2226 
 2227 /**
 2228  * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp
 2229  * @hw: pointer to hardware structure
 2230  */
 2231 static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw)
 2232 {
 2233         u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
 2234         s32 rc;
 2235 
 2236         rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store);
 2237         if (rc)
 2238                 return rc;
 2239 
 2240         if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) {
 2241                 ixgbe_shutdown_fw_phy(hw);
 2242                 return IXGBE_ERR_OVERTEMP;
 2243         }
 2244         return IXGBE_SUCCESS;
 2245 }
 2246 
 2247 /**
 2248  * ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register
 2249  * @hw: pointer to hardware structure
 2250  *
 2251  * Read NW_MNG_IF_SEL register and save field values, and check for valid field
 2252  * values.
 2253  **/
 2254 static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw)
 2255 {
 2256         /* Save NW management interface connected on board. This is used
 2257          * to determine internal PHY mode.
 2258          */
 2259         hw->phy.nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
 2260 
 2261         /* If X552 (X550EM_a) and MDIO is connected to external PHY, then set
 2262          * PHY address. This register field was has only been used for X552.
 2263          */
 2264         if (hw->mac.type == ixgbe_mac_X550EM_a &&
 2265             hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_MDIO_ACT) {
 2266                 hw->phy.addr = (hw->phy.nw_mng_if_sel &
 2267                                 IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >>
 2268                                IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT;
 2269         }
 2270 
 2271         return IXGBE_SUCCESS;
 2272 }
 2273 
 2274 /**
 2275  * ixgbe_init_phy_ops_X550em - PHY/SFP specific init
 2276  * @hw: pointer to hardware structure
 2277  *
 2278  * Initialize any function pointers that were not able to be
 2279  * set during init_shared_code because the PHY/SFP type was
 2280  * not known.  Perform the SFP init if necessary.
 2281  */
 2282 s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
 2283 {
 2284         struct ixgbe_phy_info *phy = &hw->phy;
 2285         s32 ret_val;
 2286 
 2287         DEBUGFUNC("ixgbe_init_phy_ops_X550em");
 2288 
 2289         hw->mac.ops.set_lan_id(hw);
 2290         ixgbe_read_mng_if_sel_x550em(hw);
 2291 
 2292         if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
 2293                 phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
 2294                 ixgbe_setup_mux_ctl(hw);
 2295                 phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em;
 2296         }
 2297 
 2298         switch (hw->device_id) {
 2299         case IXGBE_DEV_ID_X550EM_A_1G_T:
 2300         case IXGBE_DEV_ID_X550EM_A_1G_T_L:
 2301                 phy->ops.read_reg_mdi = NULL;
 2302                 phy->ops.write_reg_mdi = NULL;
 2303                 hw->phy.ops.read_reg = NULL;
 2304                 hw->phy.ops.write_reg = NULL;
 2305                 phy->ops.check_overtemp = ixgbe_check_overtemp_fw;
 2306                 if (hw->bus.lan_id)
 2307                         hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
 2308                 else
 2309                         hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
 2310 
 2311                 break;
 2312         case IXGBE_DEV_ID_X550EM_A_10G_T:
 2313         case IXGBE_DEV_ID_X550EM_A_SFP:
 2314                 hw->phy.ops.read_reg = ixgbe_read_phy_reg_x550a;
 2315                 hw->phy.ops.write_reg = ixgbe_write_phy_reg_x550a;
 2316                 if (hw->bus.lan_id)
 2317                         hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
 2318                 else
 2319                         hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
 2320                 break;
 2321         case IXGBE_DEV_ID_X550EM_X_SFP:
 2322                 /* set up for CS4227 usage */
 2323                 hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
 2324                 break;
 2325         case IXGBE_DEV_ID_X550EM_X_1G_T:
 2326                 phy->ops.read_reg_mdi = NULL;
 2327                 phy->ops.write_reg_mdi = NULL;
 2328         default:
 2329                 break;
 2330         }
 2331 
 2332         /* Identify the PHY or SFP module */
 2333         ret_val = phy->ops.identify(hw);
 2334         if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED ||
 2335             ret_val == IXGBE_ERR_PHY_ADDR_INVALID)
 2336                 return ret_val;
 2337 
 2338         /* Setup function pointers based on detected hardware */
 2339         ixgbe_init_mac_link_ops_X550em(hw);
 2340         if (phy->sfp_type != ixgbe_sfp_type_unknown)
 2341                 phy->ops.reset = NULL;
 2342 
 2343         /* Set functions pointers based on phy type */
 2344         switch (hw->phy.type) {
 2345         case ixgbe_phy_x550em_kx4:
 2346                 phy->ops.setup_link = NULL;
 2347                 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
 2348                 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
 2349                 break;
 2350         case ixgbe_phy_x550em_kr:
 2351                 phy->ops.setup_link = ixgbe_setup_kr_x550em;
 2352                 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
 2353                 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
 2354                 break;
 2355         case ixgbe_phy_ext_1g_t:
 2356                 /* link is managed by FW */
 2357                 phy->ops.setup_link = NULL;
 2358                 phy->ops.reset = NULL;
 2359                 break;
 2360         case ixgbe_phy_x550em_xfi:
 2361                 /* link is managed by HW */
 2362                 phy->ops.setup_link = NULL;
 2363                 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
 2364                 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
 2365                 break;
 2366         case ixgbe_phy_x550em_ext_t:
 2367                 /* If internal link mode is XFI, then setup iXFI internal link,
 2368                  * else setup KR now.
 2369                  */
 2370                 phy->ops.setup_internal_link =
 2371                                               ixgbe_setup_internal_phy_t_x550em;
 2372 
 2373                 /* setup SW LPLU only for first revision of X550EM_x */
 2374                 if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
 2375                     !(IXGBE_FUSES0_REV_MASK &
 2376                       IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
 2377                         phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
 2378 
 2379                 phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
 2380                 phy->ops.reset = ixgbe_reset_phy_t_X550em;
 2381                 break;
 2382         case ixgbe_phy_sgmii:
 2383                 phy->ops.setup_link = NULL;
 2384                 break;
 2385         case ixgbe_phy_fw:
 2386                 phy->ops.setup_link = ixgbe_setup_fw_link;
 2387                 phy->ops.reset = ixgbe_reset_phy_fw;
 2388                 break;
 2389         default:
 2390                 break;
 2391         }
 2392         return ret_val;
 2393 }
 2394 
 2395 /**
 2396  * ixgbe_set_mdio_speed - Set MDIO clock speed
 2397  * @hw: pointer to hardware structure
 2398  */
 2399 static void ixgbe_set_mdio_speed(struct ixgbe_hw *hw)
 2400 {
 2401         u32 hlreg0;
 2402 
 2403         switch (hw->device_id) {
 2404         case IXGBE_DEV_ID_X550EM_X_10G_T:
 2405         case IXGBE_DEV_ID_X550EM_A_SGMII:
 2406         case IXGBE_DEV_ID_X550EM_A_SGMII_L:
 2407         case IXGBE_DEV_ID_X550EM_A_10G_T:
 2408         case IXGBE_DEV_ID_X550EM_A_SFP:
 2409         case IXGBE_DEV_ID_X550EM_A_QSFP:
 2410                 /* Config MDIO clock speed before the first MDIO PHY access */
 2411                 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
 2412                 hlreg0 &= ~IXGBE_HLREG0_MDCSPD;
 2413                 IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
 2414                 break;
 2415         case IXGBE_DEV_ID_X550EM_A_1G_T:
 2416         case IXGBE_DEV_ID_X550EM_A_1G_T_L:
 2417                 /* Select fast MDIO clock speed for these devices */
 2418                 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
 2419                 hlreg0 |= IXGBE_HLREG0_MDCSPD;
 2420                 IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
 2421                 break;
 2422         default:
 2423                 break;
 2424         }
 2425 }
 2426 
 2427 /**
 2428  * ixgbe_reset_hw_X550em - Perform hardware reset
 2429  * @hw: pointer to hardware structure
 2430  *
 2431  * Resets the hardware by resetting the transmit and receive units, masks
 2432  * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
 2433  * reset.
 2434  */
 2435 s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
 2436 {
 2437         ixgbe_link_speed link_speed;
 2438         s32 status;
 2439         u32 ctrl = 0;
 2440         u32 i;
 2441         bool link_up = false;
 2442         u32 swfw_mask = hw->phy.phy_semaphore_mask;
 2443 
 2444         DEBUGFUNC("ixgbe_reset_hw_X550em");
 2445 
 2446         /* Call adapter stop to disable Tx/Rx and clear interrupts */
 2447         status = hw->mac.ops.stop_adapter(hw);
 2448         if (status != IXGBE_SUCCESS) {
 2449                 DEBUGOUT1("Failed to stop adapter, STATUS = %d\n", status);
 2450                 return status;
 2451         }
 2452         /* flush pending Tx transactions */
 2453         ixgbe_clear_tx_pending(hw);
 2454 
 2455         ixgbe_set_mdio_speed(hw);
 2456 
 2457         /* PHY ops must be identified and initialized prior to reset */
 2458         status = hw->phy.ops.init(hw);
 2459 
 2460         if (status)
 2461                 DEBUGOUT1("Failed to initialize PHY ops, STATUS = %d\n",
 2462                           status);
 2463 
 2464         if (status == IXGBE_ERR_SFP_NOT_SUPPORTED ||
 2465             status == IXGBE_ERR_PHY_ADDR_INVALID) {
 2466                 DEBUGOUT("Returning from reset HW due to PHY init failure\n");
 2467                 return status;
 2468         }
 2469 
 2470         /* start the external PHY */
 2471         if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
 2472                 status = ixgbe_init_ext_t_x550em(hw);
 2473                 if (status) {
 2474                         DEBUGOUT1("Failed to start the external PHY, STATUS = %d\n",
 2475                                   status);
 2476                         return status;
 2477                 }
 2478         }
 2479 
 2480         /* Setup SFP module if there is one present. */
 2481         if (hw->phy.sfp_setup_needed) {
 2482                 status = hw->mac.ops.setup_sfp(hw);
 2483                 hw->phy.sfp_setup_needed = false;
 2484         }
 2485 
 2486         if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
 2487                 return status;
 2488 
 2489         /* Reset PHY */
 2490         if (!hw->phy.reset_disable && hw->phy.ops.reset) {
 2491                 if (hw->phy.ops.reset(hw) == IXGBE_ERR_OVERTEMP)
 2492                         return IXGBE_ERR_OVERTEMP;
 2493         }
 2494 
 2495 mac_reset_top:
 2496         /* Issue global reset to the MAC.  Needs to be SW reset if link is up.
 2497          * If link reset is used when link is up, it might reset the PHY when
 2498          * mng is using it.  If link is down or the flag to force full link
 2499          * reset is set, then perform link reset.
 2500          */
 2501         ctrl = IXGBE_CTRL_LNK_RST;
 2502         if (!hw->force_full_reset) {
 2503                 hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
 2504                 if (link_up)
 2505                         ctrl = IXGBE_CTRL_RST;
 2506         }
 2507 
 2508         status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
 2509         if (status != IXGBE_SUCCESS) {
 2510                 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
 2511                         "semaphore failed with %d", status);
 2512                 return IXGBE_ERR_SWFW_SYNC;
 2513         }
 2514         ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
 2515         IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
 2516         IXGBE_WRITE_FLUSH(hw);
 2517         hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 2518 
 2519         /* Poll for reset bit to self-clear meaning reset is complete */
 2520         for (i = 0; i < 10; i++) {
 2521                 usec_delay(1);
 2522                 ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
 2523                 if (!(ctrl & IXGBE_CTRL_RST_MASK))
 2524                         break;
 2525         }
 2526 
 2527         if (ctrl & IXGBE_CTRL_RST_MASK) {
 2528                 status = IXGBE_ERR_RESET_FAILED;
 2529                 DEBUGOUT("Reset polling failed to complete.\n");
 2530         }
 2531 
 2532         msec_delay(50);
 2533 
 2534         /* Double resets are required for recovery from certain error
 2535          * conditions.  Between resets, it is necessary to stall to
 2536          * allow time for any pending HW events to complete.
 2537          */
 2538         if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
 2539                 hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
 2540                 goto mac_reset_top;
 2541         }
 2542 
 2543         /* Store the permanent mac address */
 2544         hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
 2545 
 2546         /* Store MAC address from RAR0, clear receive address registers, and
 2547          * clear the multicast table.  Also reset num_rar_entries to 128,
 2548          * since we modify this value when programming the SAN MAC address.
 2549          */
 2550         hw->mac.num_rar_entries = 128;
 2551         hw->mac.ops.init_rx_addrs(hw);
 2552 
 2553         ixgbe_set_mdio_speed(hw);
 2554 
 2555         if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
 2556                 ixgbe_setup_mux_ctl(hw);
 2557 
 2558         if (status != IXGBE_SUCCESS)
 2559                 DEBUGOUT1("Reset HW failed, STATUS = %d\n", status);
 2560 
 2561         return status;
 2562 }
 2563 
 2564 /**
 2565  * ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
 2566  * @hw: pointer to hardware structure
 2567  */
 2568 s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
 2569 {
 2570         u32 status;
 2571         u16 reg;
 2572 
 2573         status = hw->phy.ops.read_reg(hw,
 2574                                       IXGBE_MDIO_TX_VENDOR_ALARMS_3,
 2575                                       IXGBE_MDIO_PMA_PMD_DEV_TYPE,
 2576                                       &reg);
 2577 
 2578         if (status != IXGBE_SUCCESS)
 2579                 return status;
 2580 
 2581         /* If PHY FW reset completed bit is set then this is the first
 2582          * SW instance after a power on so the PHY FW must be un-stalled.
 2583          */
 2584         if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
 2585                 status = hw->phy.ops.read_reg(hw,
 2586                                         IXGBE_MDIO_GLOBAL_RES_PR_10,
 2587                                         IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 2588                                         &reg);
 2589 
 2590                 if (status != IXGBE_SUCCESS)
 2591                         return status;
 2592 
 2593                 reg &= ~IXGBE_MDIO_POWER_UP_STALL;
 2594 
 2595                 status = hw->phy.ops.write_reg(hw,
 2596                                         IXGBE_MDIO_GLOBAL_RES_PR_10,
 2597                                         IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 2598                                         reg);
 2599 
 2600                 if (status != IXGBE_SUCCESS)
 2601                         return status;
 2602         }
 2603 
 2604         return status;
 2605 }
 2606 
 2607 /**
 2608  * ixgbe_setup_kr_x550em - Configure the KR PHY.
 2609  * @hw: pointer to hardware structure
 2610  **/
 2611 s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
 2612 {
 2613         /* leave link alone for 2.5G */
 2614         if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL)
 2615                 return IXGBE_SUCCESS;
 2616 
 2617         if (ixgbe_check_reset_blocked(hw))
 2618                 return 0;
 2619 
 2620         return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised);
 2621 }
 2622 
 2623 /**
 2624  * ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP
 2625  * @hw: pointer to hardware structure
 2626  * @speed: new link speed
 2627  * @autoneg_wait_to_complete: unused
 2628  *
 2629  * Configure the external PHY and the integrated KR PHY for SFP support.
 2630  **/
 2631 s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
 2632                                     ixgbe_link_speed speed,
 2633                                     bool autoneg_wait_to_complete)
 2634 {
 2635         s32 ret_val;
 2636         u16 reg_slice, reg_val;
 2637         bool setup_linear = false;
 2638         UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
 2639 
 2640         /* Check if SFP module is supported and linear */
 2641         ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
 2642 
 2643         /* If no SFP module present, then return success. Return success since
 2644          * there is no reason to configure CS4227 and SFP not present error is
 2645          * not excepted in the setup MAC link flow.
 2646          */
 2647         if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
 2648                 return IXGBE_SUCCESS;
 2649 
 2650         if (ret_val != IXGBE_SUCCESS)
 2651                 return ret_val;
 2652 
 2653         /* Configure internal PHY for KR/KX. */
 2654         ixgbe_setup_kr_speed_x550em(hw, speed);
 2655 
 2656         /* Configure CS4227 LINE side to proper mode. */
 2657         reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB +
 2658                     (hw->bus.lan_id << 12);
 2659         if (setup_linear)
 2660                 reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
 2661         else
 2662                 reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
 2663         ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice,
 2664                                           reg_val);
 2665         return ret_val;
 2666 }
 2667 
 2668 /**
 2669  * ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode
 2670  * @hw: pointer to hardware structure
 2671  * @speed: the link speed to force
 2672  *
 2673  * Configures the integrated PHY for native SFI mode. Used to connect the
 2674  * internal PHY directly to an SFP cage, without autonegotiation.
 2675  **/
 2676 static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
 2677 {
 2678         struct ixgbe_mac_info *mac = &hw->mac;
 2679         s32 status;
 2680         u32 reg_val;
 2681 
 2682         /* Disable all AN and force speed to 10G Serial. */
 2683         status = mac->ops.read_iosf_sb_reg(hw,
 2684                                 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 2685                                 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 2686         if (status != IXGBE_SUCCESS)
 2687                 return status;
 2688 
 2689         reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
 2690         reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
 2691         reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
 2692         reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
 2693 
 2694         /* Select forced link speed for internal PHY. */
 2695         switch (*speed) {
 2696         case IXGBE_LINK_SPEED_10GB_FULL:
 2697                 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G;
 2698                 break;
 2699         case IXGBE_LINK_SPEED_1GB_FULL:
 2700                 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
 2701                 break;
 2702         default:
 2703                 /* Other link speeds are not supported by internal PHY. */
 2704                 return IXGBE_ERR_LINK_SETUP;
 2705         }
 2706 
 2707         status = mac->ops.write_iosf_sb_reg(hw,
 2708                                 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 2709                                 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 2710 
 2711         /* Toggle port SW reset by AN reset. */
 2712         status = ixgbe_restart_an_internal_phy_x550em(hw);
 2713 
 2714         return status;
 2715 }
 2716 
 2717 /**
 2718  * ixgbe_setup_mac_link_sfp_x550a - Setup internal PHY for SFP
 2719  * @hw: pointer to hardware structure
 2720  * @speed: new link speed
 2721  * @autoneg_wait_to_complete: unused
 2722  *
 2723  * Configure the integrated PHY for SFP support.
 2724  **/
 2725 s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
 2726                                     ixgbe_link_speed speed,
 2727                                     bool autoneg_wait_to_complete)
 2728 {
 2729         s32 ret_val;
 2730         u16 reg_phy_ext;
 2731         bool setup_linear = false;
 2732         u32 reg_slice, reg_phy_int, slice_offset;
 2733 
 2734         UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
 2735 
 2736         /* Check if SFP module is supported and linear */
 2737         ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
 2738 
 2739         /* If no SFP module present, then return success. Return success since
 2740          * SFP not present error is not excepted in the setup MAC link flow.
 2741          */
 2742         if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
 2743                 return IXGBE_SUCCESS;
 2744 
 2745         if (ret_val != IXGBE_SUCCESS)
 2746                 return ret_val;
 2747 
 2748         if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) {
 2749                 /* Configure internal PHY for native SFI based on module type */
 2750                 ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
 2751                                    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 2752                                    IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_phy_int);
 2753 
 2754                 if (ret_val != IXGBE_SUCCESS)
 2755                         return ret_val;
 2756 
 2757                 reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA;
 2758                 if (!setup_linear)
 2759                         reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR;
 2760 
 2761                 ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
 2762                                    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
 2763                                    IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
 2764 
 2765                 if (ret_val != IXGBE_SUCCESS)
 2766                         return ret_val;
 2767 
 2768                 /* Setup SFI internal link. */
 2769                 ret_val = ixgbe_setup_sfi_x550a(hw, &speed);
 2770         } else {
 2771                 /* Configure internal PHY for KR/KX. */
 2772                 ixgbe_setup_kr_speed_x550em(hw, speed);
 2773 
 2774                 if (hw->phy.addr == 0x0 || hw->phy.addr == 0xFFFF) {
 2775                         /* Find Address */
 2776                         DEBUGOUT("Invalid NW_MNG_IF_SEL.MDIO_PHY_ADD value\n");
 2777                         return IXGBE_ERR_PHY_ADDR_INVALID;
 2778                 }
 2779 
 2780                 /* Get external PHY SKU id */
 2781                 ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU,
 2782                                         IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
 2783 
 2784                 if (ret_val != IXGBE_SUCCESS)
 2785                         return ret_val;
 2786 
 2787                 /* When configuring quad port CS4223, the MAC instance is part
 2788                  * of the slice offset.
 2789                  */
 2790                 if (reg_phy_ext == IXGBE_CS4223_SKU_ID)
 2791                         slice_offset = (hw->bus.lan_id +
 2792                                         (hw->bus.instance_id << 1)) << 12;
 2793                 else
 2794                         slice_offset = hw->bus.lan_id << 12;
 2795 
 2796                 /* Configure CS4227/CS4223 LINE side to proper mode. */
 2797                 reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset;
 2798 
 2799                 ret_val = hw->phy.ops.read_reg(hw, reg_slice,
 2800                                         IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
 2801 
 2802                 if (ret_val != IXGBE_SUCCESS)
 2803                         return ret_val;
 2804 
 2805                 reg_phy_ext &= ~((IXGBE_CS4227_EDC_MODE_CX1 << 1) |
 2806                                  (IXGBE_CS4227_EDC_MODE_SR << 1));
 2807 
 2808                 if (setup_linear)
 2809                         reg_phy_ext |= (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
 2810                 else
 2811                         reg_phy_ext |= (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
 2812                 ret_val = hw->phy.ops.write_reg(hw, reg_slice,
 2813                                          IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext);
 2814 
 2815                 /* Flush previous write with a read */
 2816                 ret_val = hw->phy.ops.read_reg(hw, reg_slice,
 2817                                         IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
 2818         }
 2819         return ret_val;
 2820 }
 2821 
 2822 /**
 2823  * ixgbe_setup_ixfi_x550em_x - MAC specific iXFI configuration
 2824  * @hw: pointer to hardware structure
 2825  *
 2826  * iXfI configuration needed for ixgbe_mac_X550EM_x devices.
 2827  **/
 2828 static s32 ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw)
 2829 {
 2830         struct ixgbe_mac_info *mac = &hw->mac;
 2831         s32 status;
 2832         u32 reg_val;
 2833 
 2834         /* Disable training protocol FSM. */
 2835         status = mac->ops.read_iosf_sb_reg(hw,
 2836                                 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
 2837                                 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 2838         if (status != IXGBE_SUCCESS)
 2839                 return status;
 2840         reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
 2841         status = mac->ops.write_iosf_sb_reg(hw,
 2842                                 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
 2843                                 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 2844         if (status != IXGBE_SUCCESS)
 2845                 return status;
 2846 
 2847         /* Disable Flex from training TXFFE. */
 2848         status = mac->ops.read_iosf_sb_reg(hw,
 2849                                 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
 2850                                 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 2851         if (status != IXGBE_SUCCESS)
 2852                 return status;
 2853         reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
 2854         reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
 2855         reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
 2856         status = mac->ops.write_iosf_sb_reg(hw,
 2857                                 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
 2858                                 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 2859         if (status != IXGBE_SUCCESS)
 2860                 return status;
 2861         status = mac->ops.read_iosf_sb_reg(hw,
 2862                                 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
 2863                                 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 2864         if (status != IXGBE_SUCCESS)
 2865                 return status;
 2866         reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
 2867         reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
 2868         reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
 2869         status = mac->ops.write_iosf_sb_reg(hw,
 2870                                 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
 2871                                 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 2872         if (status != IXGBE_SUCCESS)
 2873                 return status;
 2874 
 2875         /* Enable override for coefficients. */
 2876         status = mac->ops.read_iosf_sb_reg(hw,
 2877                                 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
 2878                                 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 2879         if (status != IXGBE_SUCCESS)
 2880                 return status;
 2881         reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
 2882         reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
 2883         reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
 2884         reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
 2885         status = mac->ops.write_iosf_sb_reg(hw,
 2886                                 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
 2887                                 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 2888         return status;
 2889 }
 2890 
 2891 /**
 2892  * ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
 2893  * @hw: pointer to hardware structure
 2894  * @speed: the link speed to force
 2895  *
 2896  * Configures the integrated KR PHY to use iXFI mode. Used to connect an
 2897  * internal and external PHY at a specific speed, without autonegotiation.
 2898  **/
 2899 static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
 2900 {
 2901         struct ixgbe_mac_info *mac = &hw->mac;
 2902         s32 status;
 2903         u32 reg_val;
 2904 
 2905         /* iXFI is only supported with X552 */
 2906         if (mac->type != ixgbe_mac_X550EM_x)
 2907                 return IXGBE_ERR_LINK_SETUP;
 2908 
 2909         /* Disable AN and force speed to 10G Serial. */
 2910         status = mac->ops.read_iosf_sb_reg(hw,
 2911                                         IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 2912                                         IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 2913         if (status != IXGBE_SUCCESS)
 2914                 return status;
 2915 
 2916         reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
 2917         reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
 2918 
 2919         /* Select forced link speed for internal PHY. */
 2920         switch (*speed) {
 2921         case IXGBE_LINK_SPEED_10GB_FULL:
 2922                 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
 2923                 break;
 2924         case IXGBE_LINK_SPEED_1GB_FULL:
 2925                 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
 2926                 break;
 2927         default:
 2928                 /* Other link speeds are not supported by internal KR PHY. */
 2929                 return IXGBE_ERR_LINK_SETUP;
 2930         }
 2931 
 2932         status = mac->ops.write_iosf_sb_reg(hw,
 2933                                         IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 2934                                         IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 2935         if (status != IXGBE_SUCCESS)
 2936                 return status;
 2937 
 2938         /* Additional configuration needed for x550em_x */
 2939         if (hw->mac.type == ixgbe_mac_X550EM_x) {
 2940                 status = ixgbe_setup_ixfi_x550em_x(hw);
 2941                 if (status != IXGBE_SUCCESS)
 2942                         return status;
 2943         }
 2944 
 2945         /* Toggle port SW reset by AN reset. */
 2946         status = ixgbe_restart_an_internal_phy_x550em(hw);
 2947 
 2948         return status;
 2949 }
 2950 
 2951 /**
 2952  * ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status
 2953  * @hw: address of hardware structure
 2954  * @link_up: address of boolean to indicate link status
 2955  *
 2956  * Returns error code if unable to get link status.
 2957  */
 2958 static s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up)
 2959 {
 2960         u32 ret;
 2961         u16 autoneg_status;
 2962 
 2963         *link_up = false;
 2964 
 2965         /* read this twice back to back to indicate current status */
 2966         ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
 2967                                    IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
 2968                                    &autoneg_status);
 2969         if (ret != IXGBE_SUCCESS)
 2970                 return ret;
 2971 
 2972         ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
 2973                                    IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
 2974                                    &autoneg_status);
 2975         if (ret != IXGBE_SUCCESS)
 2976                 return ret;
 2977 
 2978         *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS);
 2979 
 2980         return IXGBE_SUCCESS;
 2981 }
 2982 
 2983 /**
 2984  * ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link
 2985  * @hw: point to hardware structure
 2986  *
 2987  * Configures the link between the integrated KR PHY and the external X557 PHY
 2988  * The driver will call this function when it gets a link status change
 2989  * interrupt from the X557 PHY. This function configures the link speed
 2990  * between the PHYs to match the link speed of the BASE-T link.
 2991  *
 2992  * A return of a non-zero value indicates an error, and the base driver should
 2993  * not report link up.
 2994  */
 2995 s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
 2996 {
 2997         ixgbe_link_speed force_speed;
 2998         bool link_up;
 2999         u32 status;
 3000         u16 speed;
 3001 
 3002         if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
 3003                 return IXGBE_ERR_CONFIG;
 3004 
 3005         if (hw->mac.type == ixgbe_mac_X550EM_x &&
 3006             !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
 3007                 /* If link is down, there is no setup necessary so return  */
 3008                 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
 3009                 if (status != IXGBE_SUCCESS)
 3010                         return status;
 3011 
 3012                 if (!link_up)
 3013                         return IXGBE_SUCCESS;
 3014 
 3015                 status = hw->phy.ops.read_reg(hw,
 3016                                               IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
 3017                                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
 3018                                               &speed);
 3019                 if (status != IXGBE_SUCCESS)
 3020                         return status;
 3021 
 3022                 /* If link is still down - no setup is required so return */
 3023                 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
 3024                 if (status != IXGBE_SUCCESS)
 3025                         return status;
 3026                 if (!link_up)
 3027                         return IXGBE_SUCCESS;
 3028 
 3029                 /* clear everything but the speed and duplex bits */
 3030                 speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
 3031 
 3032                 switch (speed) {
 3033                 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
 3034                         force_speed = IXGBE_LINK_SPEED_10GB_FULL;
 3035                         break;
 3036                 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
 3037                         force_speed = IXGBE_LINK_SPEED_1GB_FULL;
 3038                         break;
 3039                 default:
 3040                         /* Internal PHY does not support anything else */
 3041                         return IXGBE_ERR_INVALID_LINK_SETTINGS;
 3042                 }
 3043 
 3044                 return ixgbe_setup_ixfi_x550em(hw, &force_speed);
 3045         } else {
 3046                 speed = IXGBE_LINK_SPEED_10GB_FULL |
 3047                         IXGBE_LINK_SPEED_1GB_FULL;
 3048                 return ixgbe_setup_kr_speed_x550em(hw, speed);
 3049         }
 3050 }
 3051 
 3052 /**
 3053  * ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback.
 3054  * @hw: pointer to hardware structure
 3055  *
 3056  * Configures the integrated KR PHY to use internal loopback mode.
 3057  **/
 3058 s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw)
 3059 {
 3060         s32 status;
 3061         u32 reg_val;
 3062 
 3063         /* Disable AN and force speed to 10G Serial. */
 3064         status = hw->mac.ops.read_iosf_sb_reg(hw,
 3065                                         IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 3066                                         IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 3067         if (status != IXGBE_SUCCESS)
 3068                 return status;
 3069         reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
 3070         reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
 3071         reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
 3072         status = hw->mac.ops.write_iosf_sb_reg(hw,
 3073                                         IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
 3074                                         IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 3075         if (status != IXGBE_SUCCESS)
 3076                 return status;
 3077 
 3078         /* Set near-end loopback clocks. */
 3079         status = hw->mac.ops.read_iosf_sb_reg(hw,
 3080                                 IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
 3081                                 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 3082         if (status != IXGBE_SUCCESS)
 3083                 return status;
 3084         reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B;
 3085         reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS;
 3086         status = hw->mac.ops.write_iosf_sb_reg(hw,
 3087                                 IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
 3088                                 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 3089         if (status != IXGBE_SUCCESS)
 3090                 return status;
 3091 
 3092         /* Set loopback enable. */
 3093         status = hw->mac.ops.read_iosf_sb_reg(hw,
 3094                                 IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
 3095                                 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 3096         if (status != IXGBE_SUCCESS)
 3097                 return status;
 3098         reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK;
 3099         status = hw->mac.ops.write_iosf_sb_reg(hw,
 3100                                 IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
 3101                                 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 3102         if (status != IXGBE_SUCCESS)
 3103                 return status;
 3104 
 3105         /* Training bypass. */
 3106         status = hw->mac.ops.read_iosf_sb_reg(hw,
 3107                                 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
 3108                                 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 3109         if (status != IXGBE_SUCCESS)
 3110                 return status;
 3111         reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS;
 3112         status = hw->mac.ops.write_iosf_sb_reg(hw,
 3113                                 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
 3114                                 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 3115 
 3116         return status;
 3117 }
 3118 
 3119 /**
 3120  * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
 3121  * assuming that the semaphore is already obtained.
 3122  * @hw: pointer to hardware structure
 3123  * @offset: offset of  word in the EEPROM to read
 3124  * @data: word read from the EEPROM
 3125  *
 3126  * Reads a 16 bit word from the EEPROM using the hostif.
 3127  **/
 3128 s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data)
 3129 {
 3130         const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
 3131         struct ixgbe_hic_read_shadow_ram buffer;
 3132         s32 status;
 3133 
 3134         DEBUGFUNC("ixgbe_read_ee_hostif_X550");
 3135         buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
 3136         buffer.hdr.req.buf_lenh = 0;
 3137         buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
 3138         buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
 3139 
 3140         /* convert offset from words to bytes */
 3141         buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
 3142         /* one word */
 3143         buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
 3144         buffer.pad2 = 0;
 3145         buffer.data = 0;
 3146         buffer.pad3 = 0;
 3147 
 3148         status = hw->mac.ops.acquire_swfw_sync(hw, mask);
 3149         if (status)
 3150                 return status;
 3151 
 3152         status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
 3153                                     IXGBE_HI_COMMAND_TIMEOUT);
 3154         if (!status) {
 3155                 *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
 3156                                                   FW_NVM_DATA_OFFSET);
 3157         }
 3158 
 3159         hw->mac.ops.release_swfw_sync(hw, mask);
 3160         return status;
 3161 }
 3162 
 3163 /**
 3164  * ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
 3165  * @hw: pointer to hardware structure
 3166  * @offset: offset of  word in the EEPROM to read
 3167  * @words: number of words
 3168  * @data: word(s) read from the EEPROM
 3169  *
 3170  * Reads a 16 bit word(s) from the EEPROM using the hostif.
 3171  **/
 3172 s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
 3173                                      u16 offset, u16 words, u16 *data)
 3174 {
 3175         const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
 3176         struct ixgbe_hic_read_shadow_ram buffer;
 3177         u32 current_word = 0;
 3178         u16 words_to_read;
 3179         s32 status;
 3180         u32 i;
 3181 
 3182         DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550");
 3183 
 3184         /* Take semaphore for the entire operation. */
 3185         status = hw->mac.ops.acquire_swfw_sync(hw, mask);
 3186         if (status) {
 3187                 DEBUGOUT("EEPROM read buffer - semaphore failed\n");
 3188                 return status;
 3189         }
 3190 
 3191         while (words) {
 3192                 if (words > FW_MAX_READ_BUFFER_SIZE / 2)
 3193                         words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
 3194                 else
 3195                         words_to_read = words;
 3196 
 3197                 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
 3198                 buffer.hdr.req.buf_lenh = 0;
 3199                 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
 3200                 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
 3201 
 3202                 /* convert offset from words to bytes */
 3203                 buffer.address = IXGBE_CPU_TO_BE32((offset + current_word) * 2);
 3204                 buffer.length = IXGBE_CPU_TO_BE16(words_to_read * 2);
 3205                 buffer.pad2 = 0;
 3206                 buffer.data = 0;
 3207                 buffer.pad3 = 0;
 3208 
 3209                 status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
 3210                                             IXGBE_HI_COMMAND_TIMEOUT);
 3211 
 3212                 if (status) {
 3213                         DEBUGOUT("Host interface command failed\n");
 3214                         goto out;
 3215                 }
 3216 
 3217                 for (i = 0; i < words_to_read; i++) {
 3218                         u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
 3219                                   2 * i;
 3220                         u32 value = IXGBE_READ_REG(hw, reg);
 3221 
 3222                         data[current_word] = (u16)(value & 0xffff);
 3223                         current_word++;
 3224                         i++;
 3225                         if (i < words_to_read) {
 3226                                 value >>= 16;
 3227                                 data[current_word] = (u16)(value & 0xffff);
 3228                                 current_word++;
 3229                         }
 3230                 }
 3231                 words -= words_to_read;
 3232         }
 3233 
 3234 out:
 3235         hw->mac.ops.release_swfw_sync(hw, mask);
 3236         return status;
 3237 }
 3238 
 3239 /**
 3240  * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
 3241  * @hw: pointer to hardware structure
 3242  * @offset: offset of  word in the EEPROM to write
 3243  * @data: word write to the EEPROM
 3244  *
 3245  * Write a 16 bit word to the EEPROM using the hostif.
 3246  **/
 3247 s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
 3248                                     u16 data)
 3249 {
 3250         s32 status;
 3251         struct ixgbe_hic_write_shadow_ram buffer;
 3252 
 3253         DEBUGFUNC("ixgbe_write_ee_hostif_data_X550");
 3254 
 3255         buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
 3256         buffer.hdr.req.buf_lenh = 0;
 3257         buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
 3258         buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
 3259 
 3260          /* one word */
 3261         buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
 3262         buffer.data = data;
 3263         buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
 3264 
 3265         status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
 3266                                               sizeof(buffer),
 3267                                               IXGBE_HI_COMMAND_TIMEOUT, true);
 3268         if (status != IXGBE_SUCCESS) {
 3269                 DEBUGOUT2("for offset %04x failed with status %d\n",
 3270                                   offset, status);
 3271                 return status;
 3272         }
 3273 
 3274         if (buffer.hdr.rsp.buf_lenh_status != FW_CEM_RESP_STATUS_SUCCESS) {
 3275                 DEBUGOUT2("for offset %04x host interface return status %02x\n",
 3276                                   offset, buffer.hdr.rsp.buf_lenh_status);
 3277                 return IXGBE_ERR_HOST_INTERFACE_COMMAND;
 3278         }
 3279 
 3280         return status;
 3281 }
 3282 
 3283 /**
 3284  * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
 3285  * @hw: pointer to hardware structure
 3286  * @offset: offset of  word in the EEPROM to write
 3287  * @data: word write to the EEPROM
 3288  *
 3289  * Write a 16 bit word to the EEPROM using the hostif.
 3290  **/
 3291 s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
 3292                                u16 data)
 3293 {
 3294         s32 status = IXGBE_SUCCESS;
 3295 
 3296         DEBUGFUNC("ixgbe_write_ee_hostif_X550");
 3297 
 3298         if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
 3299             IXGBE_SUCCESS) {
 3300                 status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
 3301                 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 3302         } else {
 3303                 DEBUGOUT("write ee hostif failed to get semaphore");
 3304                 status = IXGBE_ERR_SWFW_SYNC;
 3305         }
 3306 
 3307         return status;
 3308 }
 3309 
 3310 /**
 3311  * ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
 3312  * @hw: pointer to hardware structure
 3313  * @offset: offset of  word in the EEPROM to write
 3314  * @words: number of words
 3315  * @data: word(s) write to the EEPROM
 3316  *
 3317  * Write a 16 bit word(s) to the EEPROM using the hostif.
 3318  **/
 3319 s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
 3320                                       u16 offset, u16 words, u16 *data)
 3321 {
 3322         s32 status = IXGBE_SUCCESS;
 3323         u32 i = 0;
 3324 
 3325         DEBUGFUNC("ixgbe_write_ee_hostif_buffer_X550");
 3326 
 3327         /* Take semaphore for the entire operation. */
 3328         status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 3329         if (status != IXGBE_SUCCESS) {
 3330                 DEBUGOUT("EEPROM write buffer - semaphore failed\n");
 3331                 goto out;
 3332         }
 3333 
 3334         for (i = 0; i < words; i++) {
 3335                 status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
 3336                                                          data[i]);
 3337 
 3338                 if (status != IXGBE_SUCCESS) {
 3339                         DEBUGOUT("Eeprom buffered write failed\n");
 3340                         break;
 3341                 }
 3342         }
 3343 
 3344         hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 3345 out:
 3346 
 3347         return status;
 3348 }
 3349 
 3350 /**
 3351  * ixgbe_checksum_ptr_x550 - Checksum one pointer region
 3352  * @hw: pointer to hardware structure
 3353  * @ptr: pointer offset in eeprom
 3354  * @size: size of section pointed by ptr, if 0 first word will be used as size
 3355  * @csum: address of checksum to update
 3356  * @buffer: pointer to buffer containing calculated checksum
 3357  * @buffer_size: size of buffer
 3358  *
 3359  * Returns error status for any failure
 3360  */
 3361 static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
 3362                                    u16 size, u16 *csum, u16 *buffer,
 3363                                    u32 buffer_size)
 3364 {
 3365         u16 buf[256];
 3366         s32 status;
 3367         u16 length, bufsz, i, start;
 3368         u16 *local_buffer;
 3369 
 3370         bufsz = sizeof(buf) / sizeof(buf[0]);
 3371 
 3372         /* Read a chunk at the pointer location */
 3373         if (!buffer) {
 3374                 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
 3375                 if (status) {
 3376                         DEBUGOUT("Failed to read EEPROM image\n");
 3377                         return status;
 3378                 }
 3379                 local_buffer = buf;
 3380         } else {
 3381                 if (buffer_size < ptr)
 3382                         return  IXGBE_ERR_PARAM;
 3383                 local_buffer = &buffer[ptr];
 3384         }
 3385 
 3386         if (size) {
 3387                 start = 0;
 3388                 length = size;
 3389         } else {
 3390                 start = 1;
 3391                 length = local_buffer[0];
 3392 
 3393                 /* Skip pointer section if length is invalid. */
 3394                 if (length == 0xFFFF || length == 0 ||
 3395                     (ptr + length) >= hw->eeprom.word_size)
 3396                         return IXGBE_SUCCESS;
 3397         }
 3398 
 3399         if (buffer && ((u32)start + (u32)length > buffer_size))
 3400                 return IXGBE_ERR_PARAM;
 3401 
 3402         for (i = start; length; i++, length--) {
 3403                 if (i == bufsz && !buffer) {
 3404                         ptr += bufsz;
 3405                         i = 0;
 3406                         if (length < bufsz)
 3407                                 bufsz = length;
 3408 
 3409                         /* Read a chunk at the pointer location */
 3410                         status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
 3411                                                                   bufsz, buf);
 3412                         if (status) {
 3413                                 DEBUGOUT("Failed to read EEPROM image\n");
 3414                                 return status;
 3415                         }
 3416                 }
 3417                 *csum += local_buffer[i];
 3418         }
 3419         return IXGBE_SUCCESS;
 3420 }
 3421 
 3422 /**
 3423  * ixgbe_calc_checksum_X550 - Calculates and returns the checksum
 3424  * @hw: pointer to hardware structure
 3425  * @buffer: pointer to buffer containing calculated checksum
 3426  * @buffer_size: size of buffer
 3427  *
 3428  * Returns a negative error code on error, or the 16-bit checksum
 3429  **/
 3430 s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, u32 buffer_size)
 3431 {
 3432         u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
 3433         u16 *local_buffer;
 3434         s32 status;
 3435         u16 checksum = 0;
 3436         u16 pointer, i, size;
 3437 
 3438         DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550");
 3439 
 3440         hw->eeprom.ops.init_params(hw);
 3441 
 3442         if (!buffer) {
 3443                 /* Read pointer area */
 3444                 status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
 3445                                                      IXGBE_EEPROM_LAST_WORD + 1,
 3446                                                      eeprom_ptrs);
 3447                 if (status) {
 3448                         DEBUGOUT("Failed to read EEPROM image\n");
 3449                         return status;
 3450                 }
 3451                 local_buffer = eeprom_ptrs;
 3452         } else {
 3453                 if (buffer_size < IXGBE_EEPROM_LAST_WORD)
 3454                         return IXGBE_ERR_PARAM;
 3455                 local_buffer = buffer;
 3456         }
 3457 
 3458         /*
 3459          * For X550 hardware include 0x0-0x41 in the checksum, skip the
 3460          * checksum word itself
 3461          */
 3462         for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
 3463                 if (i != IXGBE_EEPROM_CHECKSUM)
 3464                         checksum += local_buffer[i];
 3465 
 3466         /*
 3467          * Include all data from pointers 0x3, 0x6-0xE.  This excludes the
 3468          * FW, PHY module, and PCIe Expansion/Option ROM pointers.
 3469          */
 3470         for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
 3471                 if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
 3472                         continue;
 3473 
 3474                 pointer = local_buffer[i];
 3475 
 3476                 /* Skip pointer section if the pointer is invalid. */
 3477                 if (pointer == 0xFFFF || pointer == 0 ||
 3478                     pointer >= hw->eeprom.word_size)
 3479                         continue;
 3480 
 3481                 switch (i) {
 3482                 case IXGBE_PCIE_GENERAL_PTR:
 3483                         size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
 3484                         break;
 3485                 case IXGBE_PCIE_CONFIG0_PTR:
 3486                 case IXGBE_PCIE_CONFIG1_PTR:
 3487                         size = IXGBE_PCIE_CONFIG_SIZE;
 3488                         break;
 3489                 default:
 3490                         size = 0;
 3491                         break;
 3492                 }
 3493 
 3494                 status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
 3495                                                 buffer, buffer_size);
 3496                 if (status)
 3497                         return status;
 3498         }
 3499 
 3500         checksum = (u16)IXGBE_EEPROM_SUM - checksum;
 3501 
 3502         return (s32)checksum;
 3503 }
 3504 
 3505 /**
 3506  * ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
 3507  * @hw: pointer to hardware structure
 3508  *
 3509  * Returns a negative error code on error, or the 16-bit checksum
 3510  **/
 3511 s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
 3512 {
 3513         return ixgbe_calc_checksum_X550(hw, NULL, 0);
 3514 }
 3515 
 3516 /**
 3517  * ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
 3518  * @hw: pointer to hardware structure
 3519  * @checksum_val: calculated checksum
 3520  *
 3521  * Performs checksum calculation and validates the EEPROM checksum.  If the
 3522  * caller does not need checksum_val, the value can be NULL.
 3523  **/
 3524 s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, u16 *checksum_val)
 3525 {
 3526         s32 status;
 3527         u16 checksum;
 3528         u16 read_checksum = 0;
 3529 
 3530         DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550");
 3531 
 3532         /* Read the first word from the EEPROM. If this times out or fails, do
 3533          * not continue or we could be in for a very long wait while every
 3534          * EEPROM read fails
 3535          */
 3536         status = hw->eeprom.ops.read(hw, 0, &checksum);
 3537         if (status) {
 3538                 DEBUGOUT("EEPROM read failed\n");
 3539                 return status;
 3540         }
 3541 
 3542         status = hw->eeprom.ops.calc_checksum(hw);
 3543         if (status < 0)
 3544                 return status;
 3545 
 3546         checksum = (u16)(status & 0xffff);
 3547 
 3548         status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
 3549                                            &read_checksum);
 3550         if (status)
 3551                 return status;
 3552 
 3553         /* Verify read checksum from EEPROM is the same as
 3554          * calculated checksum
 3555          */
 3556         if (read_checksum != checksum) {
 3557                 status = IXGBE_ERR_EEPROM_CHECKSUM;
 3558                 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
 3559                              "Invalid EEPROM checksum");
 3560         }
 3561 
 3562         /* If the user cares, return the calculated checksum */
 3563         if (checksum_val)
 3564                 *checksum_val = checksum;
 3565 
 3566         return status;
 3567 }
 3568 
 3569 /**
 3570  * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
 3571  * @hw: pointer to hardware structure
 3572  *
 3573  * After writing EEPROM to shadow RAM using EEWR register, software calculates
 3574  * checksum and updates the EEPROM and instructs the hardware to update
 3575  * the flash.
 3576  **/
 3577 s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
 3578 {
 3579         s32 status;
 3580         u16 checksum = 0;
 3581 
 3582         DEBUGFUNC("ixgbe_update_eeprom_checksum_X550");
 3583 
 3584         /* Read the first word from the EEPROM. If this times out or fails, do
 3585          * not continue or we could be in for a very long wait while every
 3586          * EEPROM read fails
 3587          */
 3588         status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
 3589         if (status) {
 3590                 DEBUGOUT("EEPROM read failed\n");
 3591                 return status;
 3592         }
 3593 
 3594         status = ixgbe_calc_eeprom_checksum_X550(hw);
 3595         if (status < 0)
 3596                 return status;
 3597 
 3598         checksum = (u16)(status & 0xffff);
 3599 
 3600         status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
 3601                                             checksum);
 3602         if (status)
 3603                 return status;
 3604 
 3605         status = ixgbe_update_flash_X550(hw);
 3606 
 3607         return status;
 3608 }
 3609 
 3610 /**
 3611  * ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
 3612  * @hw: pointer to hardware structure
 3613  *
 3614  * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
 3615  **/
 3616 s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
 3617 {
 3618         s32 status = IXGBE_SUCCESS;
 3619         union ixgbe_hic_hdr2 buffer;
 3620 
 3621         DEBUGFUNC("ixgbe_update_flash_X550");
 3622 
 3623         buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
 3624         buffer.req.buf_lenh = 0;
 3625         buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
 3626         buffer.req.checksum = FW_DEFAULT_CHECKSUM;
 3627 
 3628         status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
 3629                                               sizeof(buffer),
 3630                                               IXGBE_HI_COMMAND_TIMEOUT, false);
 3631 
 3632         return status;
 3633 }
 3634 
 3635 /**
 3636  * ixgbe_get_supported_physical_layer_X550em - Returns physical layer type
 3637  * @hw: pointer to hardware structure
 3638  *
 3639  * Determines physical layer capabilities of the current configuration.
 3640  **/
 3641 u64 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw)
 3642 {
 3643         u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
 3644         u16 ext_ability = 0;
 3645 
 3646         DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em");
 3647 
 3648         hw->phy.ops.identify(hw);
 3649 
 3650         switch (hw->phy.type) {
 3651         case ixgbe_phy_x550em_kr:
 3652                 if (hw->mac.type == ixgbe_mac_X550EM_a) {
 3653                         if (hw->phy.nw_mng_if_sel &
 3654                             IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) {
 3655                                 physical_layer =
 3656                                         IXGBE_PHYSICAL_LAYER_2500BASE_KX;
 3657                                 break;
 3658                         } else if (hw->device_id ==
 3659                                    IXGBE_DEV_ID_X550EM_A_KR_L) {
 3660                                 physical_layer =
 3661                                         IXGBE_PHYSICAL_LAYER_1000BASE_KX;
 3662                                 break;
 3663                         }
 3664                 }
 3665                 /* fall through */
 3666         case ixgbe_phy_x550em_xfi:
 3667                 physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR |
 3668                                  IXGBE_PHYSICAL_LAYER_1000BASE_KX;
 3669                 break;
 3670         case ixgbe_phy_x550em_kx4:
 3671                 physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
 3672                                  IXGBE_PHYSICAL_LAYER_1000BASE_KX;
 3673                 break;
 3674         case ixgbe_phy_x550em_ext_t:
 3675                 hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
 3676                                      IXGBE_MDIO_PMA_PMD_DEV_TYPE,
 3677                                      &ext_ability);
 3678                 if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
 3679                         physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
 3680                 if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
 3681                         physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
 3682                 break;
 3683         case ixgbe_phy_fw:
 3684                 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_1GB_FULL)
 3685                         physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
 3686                 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_100_FULL)
 3687                         physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
 3688                 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_10_FULL)
 3689                         physical_layer |= IXGBE_PHYSICAL_LAYER_10BASE_T;
 3690                 break;
 3691         case ixgbe_phy_sgmii:
 3692                 physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
 3693                 break;
 3694         case ixgbe_phy_ext_1g_t:
 3695                 physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
 3696                 break;
 3697         default:
 3698                 break;
 3699         }
 3700 
 3701         if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber)
 3702                 physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw);
 3703 
 3704         return physical_layer;
 3705 }
 3706 
 3707 /**
 3708  * ixgbe_get_bus_info_x550em - Set PCI bus info
 3709  * @hw: pointer to hardware structure
 3710  *
 3711  * Sets bus link width and speed to unknown because X550em is
 3712  * not a PCI device.
 3713  **/
 3714 s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
 3715 {
 3716 
 3717         DEBUGFUNC("ixgbe_get_bus_info_x550em");
 3718 
 3719         hw->bus.width = ixgbe_bus_width_unknown;
 3720         hw->bus.speed = ixgbe_bus_speed_unknown;
 3721 
 3722         hw->mac.ops.set_lan_id(hw);
 3723 
 3724         return IXGBE_SUCCESS;
 3725 }
 3726 
 3727 /**
 3728  * ixgbe_disable_rx_x550 - Disable RX unit
 3729  * @hw: pointer to hardware structure
 3730  *
 3731  * Enables the Rx DMA unit for x550
 3732  **/
 3733 void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
 3734 {
 3735         u32 rxctrl, pfdtxgswc;
 3736         s32 status;
 3737         struct ixgbe_hic_disable_rxen fw_cmd;
 3738 
 3739         DEBUGFUNC("ixgbe_enable_rx_dma_x550");
 3740 
 3741         rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
 3742         if (rxctrl & IXGBE_RXCTRL_RXEN) {
 3743                 pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
 3744                 if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
 3745                         pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
 3746                         IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
 3747                         hw->mac.set_lben = true;
 3748                 } else {
 3749                         hw->mac.set_lben = false;
 3750                 }
 3751 
 3752                 fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
 3753                 fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
 3754                 fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
 3755                 fw_cmd.port_number = (u8)hw->bus.lan_id;
 3756 
 3757                 status = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
 3758                                         sizeof(struct ixgbe_hic_disable_rxen),
 3759                                         IXGBE_HI_COMMAND_TIMEOUT, true);
 3760 
 3761                 /* If we fail - disable RX using register write */
 3762                 if (status) {
 3763                         rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
 3764                         if (rxctrl & IXGBE_RXCTRL_RXEN) {
 3765                                 rxctrl &= ~IXGBE_RXCTRL_RXEN;
 3766                                 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
 3767                         }
 3768                 }
 3769         }
 3770 }
 3771 
 3772 /**
 3773  * ixgbe_enter_lplu_x550em - Transition to low power states
 3774  * @hw: pointer to hardware structure
 3775  *
 3776  * Configures Low Power Link Up on transition to low power states
 3777  * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the
 3778  * X557 PHY immediately prior to entering LPLU.
 3779  **/
 3780 s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
 3781 {
 3782         u16 an_10g_cntl_reg, autoneg_reg, speed;
 3783         s32 status;
 3784         ixgbe_link_speed lcd_speed;
 3785         u32 save_autoneg;
 3786         bool link_up;
 3787 
 3788         /* SW LPLU not required on later HW revisions. */
 3789         if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
 3790             (IXGBE_FUSES0_REV_MASK &
 3791              IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
 3792                 return IXGBE_SUCCESS;
 3793 
 3794         /* If blocked by MNG FW, then don't restart AN */
 3795         if (ixgbe_check_reset_blocked(hw))
 3796                 return IXGBE_SUCCESS;
 3797 
 3798         status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
 3799         if (status != IXGBE_SUCCESS)
 3800                 return status;
 3801 
 3802         status = ixgbe_read_eeprom(hw, NVM_INIT_CTRL_3, &hw->eeprom.ctrl_word_3);
 3803 
 3804         if (status != IXGBE_SUCCESS)
 3805                 return status;
 3806 
 3807         /* If link is down, LPLU disabled in NVM, WoL disabled, or manageability
 3808          * disabled, then force link down by entering low power mode.
 3809          */
 3810         if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) ||
 3811             !(hw->wol_enabled || ixgbe_mng_present(hw)))
 3812                 return ixgbe_set_copper_phy_power(hw, false);
 3813 
 3814         /* Determine LCD */
 3815         status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed);
 3816 
 3817         if (status != IXGBE_SUCCESS)
 3818                 return status;
 3819 
 3820         /* If no valid LCD link speed, then force link down and exit. */
 3821         if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN)
 3822                 return ixgbe_set_copper_phy_power(hw, false);
 3823 
 3824         status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
 3825                                       IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
 3826                                       &speed);
 3827 
 3828         if (status != IXGBE_SUCCESS)
 3829                 return status;
 3830 
 3831         /* If no link now, speed is invalid so take link down */
 3832         status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
 3833         if (status != IXGBE_SUCCESS)
 3834                 return ixgbe_set_copper_phy_power(hw, false);
 3835 
 3836         /* clear everything but the speed bits */
 3837         speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK;
 3838 
 3839         /* If current speed is already LCD, then exit. */
 3840         if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) &&
 3841              (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) ||
 3842             ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) &&
 3843              (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL)))
 3844                 return status;
 3845 
 3846         /* Clear AN completed indication */
 3847         status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM,
 3848                                       IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
 3849                                       &autoneg_reg);
 3850 
 3851         if (status != IXGBE_SUCCESS)
 3852                 return status;
 3853 
 3854         status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
 3855                              IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
 3856                              &an_10g_cntl_reg);
 3857 
 3858         if (status != IXGBE_SUCCESS)
 3859                 return status;
 3860 
 3861         status = hw->phy.ops.read_reg(hw,
 3862                              IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
 3863                              IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
 3864                              &autoneg_reg);
 3865 
 3866         if (status != IXGBE_SUCCESS)
 3867                 return status;
 3868 
 3869         save_autoneg = hw->phy.autoneg_advertised;
 3870 
 3871         /* Setup link at least common link speed */
 3872         status = hw->mac.ops.setup_link(hw, lcd_speed, false);
 3873 
 3874         /* restore autoneg from before setting lplu speed */
 3875         hw->phy.autoneg_advertised = save_autoneg;
 3876 
 3877         return status;
 3878 }
 3879 
 3880 /**
 3881  * ixgbe_get_lcd_x550em - Determine lowest common denominator
 3882  * @hw: pointer to hardware structure
 3883  * @lcd_speed: pointer to lowest common link speed
 3884  *
 3885  * Determine lowest common link speed with link partner.
 3886  **/
 3887 s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed)
 3888 {
 3889         u16 an_lp_status;
 3890         s32 status;
 3891         u16 word = hw->eeprom.ctrl_word_3;
 3892 
 3893         *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN;
 3894 
 3895         status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS,
 3896                                       IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
 3897                                       &an_lp_status);
 3898 
 3899         if (status != IXGBE_SUCCESS)
 3900                 return status;
 3901 
 3902         /* If link partner advertised 1G, return 1G */
 3903         if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) {
 3904                 *lcd_speed = IXGBE_LINK_SPEED_1GB_FULL;
 3905                 return status;
 3906         }
 3907 
 3908         /* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */
 3909         if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) ||
 3910             (word & NVM_INIT_CTRL_3_D10GMP_PORT0))
 3911                 return status;
 3912 
 3913         /* Link partner not capable of lower speeds, return 10G */
 3914         *lcd_speed = IXGBE_LINK_SPEED_10GB_FULL;
 3915         return status;
 3916 }
 3917 
 3918 /**
 3919  * ixgbe_setup_fc_X550em - Set up flow control
 3920  * @hw: pointer to hardware structure
 3921  *
 3922  * Called at init time to set up flow control.
 3923  **/
 3924 s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw)
 3925 {
 3926         s32 ret_val = IXGBE_SUCCESS;
 3927         u32 pause, asm_dir, reg_val;
 3928 
 3929         DEBUGFUNC("ixgbe_setup_fc_X550em");
 3930 
 3931         /* Validate the requested mode */
 3932         if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
 3933                 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
 3934                         "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
 3935                 ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
 3936                 goto out;
 3937         }
 3938 
 3939         /* 10gig parts do not have a word in the EEPROM to determine the
 3940          * default flow control setting, so we explicitly set it to full.
 3941          */
 3942         if (hw->fc.requested_mode == ixgbe_fc_default)
 3943                 hw->fc.requested_mode = ixgbe_fc_full;
 3944 
 3945         /* Determine PAUSE and ASM_DIR bits. */
 3946         switch (hw->fc.requested_mode) {
 3947         case ixgbe_fc_none:
 3948                 pause = 0;
 3949                 asm_dir = 0;
 3950                 break;
 3951         case ixgbe_fc_tx_pause:
 3952                 pause = 0;
 3953                 asm_dir = 1;
 3954                 break;
 3955         case ixgbe_fc_rx_pause:
 3956                 /* Rx Flow control is enabled and Tx Flow control is
 3957                  * disabled by software override. Since there really
 3958                  * isn't a way to advertise that we are capable of RX
 3959                  * Pause ONLY, we will advertise that we support both
 3960                  * symmetric and asymmetric Rx PAUSE, as such we fall
 3961                  * through to the fc_full statement.  Later, we will
 3962                  * disable the adapter's ability to send PAUSE frames.
 3963                  */
 3964         case ixgbe_fc_full:
 3965                 pause = 1;
 3966                 asm_dir = 1;
 3967                 break;
 3968         default:
 3969                 ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
 3970                         "Flow control param set incorrectly\n");
 3971                 ret_val = IXGBE_ERR_CONFIG;
 3972                 goto out;
 3973         }
 3974 
 3975         switch (hw->device_id) {
 3976         case IXGBE_DEV_ID_X550EM_X_KR:
 3977         case IXGBE_DEV_ID_X550EM_A_KR:
 3978         case IXGBE_DEV_ID_X550EM_A_KR_L:
 3979                 ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
 3980                                         IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
 3981                                         IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
 3982                 if (ret_val != IXGBE_SUCCESS)
 3983                         goto out;
 3984                 reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
 3985                         IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
 3986                 if (pause)
 3987                         reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
 3988                 if (asm_dir)
 3989                         reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
 3990                 ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
 3991                                         IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
 3992                                         IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 3993 
 3994                 /* This device does not fully support AN. */
 3995                 hw->fc.disable_fc_autoneg = true;
 3996                 break;
 3997         case IXGBE_DEV_ID_X550EM_X_XFI:
 3998                 hw->fc.disable_fc_autoneg = true;
 3999                 break;
 4000         default:
 4001                 break;
 4002         }
 4003 
 4004 out:
 4005         return ret_val;
 4006 }
 4007 
 4008 /**
 4009  * ixgbe_fc_autoneg_backplane_x550em_a - Enable flow control IEEE clause 37
 4010  * @hw: pointer to hardware structure
 4011  *
 4012  * Enable flow control according to IEEE clause 37.
 4013  **/
 4014 void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw)
 4015 {
 4016         u32 link_s1, lp_an_page_low, an_cntl_1;
 4017         s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
 4018         ixgbe_link_speed speed;
 4019         bool link_up;
 4020 
 4021         /* AN should have completed when the cable was plugged in.
 4022          * Look for reasons to bail out.  Bail out if:
 4023          * - FC autoneg is disabled, or if
 4024          * - link is not up.
 4025          */
 4026         if (hw->fc.disable_fc_autoneg) {
 4027                 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
 4028                              "Flow control autoneg is disabled");
 4029                 goto out;
 4030         }
 4031 
 4032         hw->mac.ops.check_link(hw, &speed, &link_up, false);
 4033         if (!link_up) {
 4034                 ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
 4035                 goto out;
 4036         }
 4037 
 4038         /* Check at auto-negotiation has completed */
 4039         status = hw->mac.ops.read_iosf_sb_reg(hw,
 4040                                         IXGBE_KRM_LINK_S1(hw->bus.lan_id),
 4041                                         IXGBE_SB_IOSF_TARGET_KR_PHY, &link_s1);
 4042 
 4043         if (status != IXGBE_SUCCESS ||
 4044             (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) {
 4045                 DEBUGOUT("Auto-Negotiation did not complete\n");
 4046                 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
 4047                 goto out;
 4048         }
 4049 
 4050         /* Read the 10g AN autoc and LP ability registers and resolve
 4051          * local flow control settings accordingly
 4052          */
 4053         status = hw->mac.ops.read_iosf_sb_reg(hw,
 4054                                 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
 4055                                 IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl_1);
 4056 
 4057         if (status != IXGBE_SUCCESS) {
 4058                 DEBUGOUT("Auto-Negotiation did not complete\n");
 4059                 goto out;
 4060         }
 4061 
 4062         status = hw->mac.ops.read_iosf_sb_reg(hw,
 4063                                 IXGBE_KRM_LP_BASE_PAGE_HIGH(hw->bus.lan_id),
 4064                                 IXGBE_SB_IOSF_TARGET_KR_PHY, &lp_an_page_low);
 4065 
 4066         if (status != IXGBE_SUCCESS) {
 4067                 DEBUGOUT("Auto-Negotiation did not complete\n");
 4068                 goto out;
 4069         }
 4070 
 4071         status = ixgbe_negotiate_fc(hw, an_cntl_1, lp_an_page_low,
 4072                                     IXGBE_KRM_AN_CNTL_1_SYM_PAUSE,
 4073                                     IXGBE_KRM_AN_CNTL_1_ASM_PAUSE,
 4074                                     IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE,
 4075                                     IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE);
 4076 
 4077 out:
 4078         if (status == IXGBE_SUCCESS) {
 4079                 hw->fc.fc_was_autonegged = true;
 4080         } else {
 4081                 hw->fc.fc_was_autonegged = false;
 4082                 hw->fc.current_mode = hw->fc.requested_mode;
 4083         }
 4084 }
 4085 
 4086 /**
 4087  * ixgbe_fc_autoneg_fiber_x550em_a - passthrough FC settings
 4088  * @hw: pointer to hardware structure
 4089  *
 4090  **/
 4091 void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw)
 4092 {
 4093         hw->fc.fc_was_autonegged = false;
 4094         hw->fc.current_mode = hw->fc.requested_mode;
 4095 }
 4096 
 4097 /**
 4098  * ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37
 4099  * @hw: pointer to hardware structure
 4100  *
 4101  * Enable flow control according to IEEE clause 37.
 4102  **/
 4103 void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw)
 4104 {
 4105         s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
 4106         u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
 4107         ixgbe_link_speed speed;
 4108         bool link_up;
 4109 
 4110         /* AN should have completed when the cable was plugged in.
 4111          * Look for reasons to bail out.  Bail out if:
 4112          * - FC autoneg is disabled, or if
 4113          * - link is not up.
 4114          */
 4115         if (hw->fc.disable_fc_autoneg) {
 4116                 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
 4117                              "Flow control autoneg is disabled");
 4118                 goto out;
 4119         }
 4120 
 4121         hw->mac.ops.check_link(hw, &speed, &link_up, false);
 4122         if (!link_up) {
 4123                 ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
 4124                 goto out;
 4125         }
 4126 
 4127         /* Check if auto-negotiation has completed */
 4128         status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info);
 4129         if (status != IXGBE_SUCCESS ||
 4130             !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) {
 4131                 DEBUGOUT("Auto-Negotiation did not complete\n");
 4132                 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
 4133                 goto out;
 4134         }
 4135 
 4136         /* Negotiate the flow control */
 4137         status = ixgbe_negotiate_fc(hw, info[0], info[0],
 4138                                     FW_PHY_ACT_GET_LINK_INFO_FC_RX,
 4139                                     FW_PHY_ACT_GET_LINK_INFO_FC_TX,
 4140                                     FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX,
 4141                                     FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX);
 4142 
 4143 out:
 4144         if (status == IXGBE_SUCCESS) {
 4145                 hw->fc.fc_was_autonegged = true;
 4146         } else {
 4147                 hw->fc.fc_was_autonegged = false;
 4148                 hw->fc.current_mode = hw->fc.requested_mode;
 4149         }
 4150 }
 4151 
 4152 /**
 4153  * ixgbe_setup_fc_backplane_x550em_a - Set up flow control
 4154  * @hw: pointer to hardware structure
 4155  *
 4156  * Called at init time to set up flow control.
 4157  **/
 4158 s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw)
 4159 {
 4160         s32 status = IXGBE_SUCCESS;
 4161         u32 an_cntl = 0;
 4162 
 4163         DEBUGFUNC("ixgbe_setup_fc_backplane_x550em_a");
 4164 
 4165         /* Validate the requested mode */
 4166         if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
 4167                 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
 4168                               "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
 4169                 return IXGBE_ERR_INVALID_LINK_SETTINGS;
 4170         }
 4171 
 4172         if (hw->fc.requested_mode == ixgbe_fc_default)
 4173                 hw->fc.requested_mode = ixgbe_fc_full;
 4174 
 4175         /* Set up the 1G and 10G flow control advertisement registers so the
 4176          * HW will be able to do FC autoneg once the cable is plugged in.  If
 4177          * we link at 10G, the 1G advertisement is harmless and vice versa.
 4178          */
 4179         status = hw->mac.ops.read_iosf_sb_reg(hw,
 4180                                         IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
 4181                                         IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl);
 4182 
 4183         if (status != IXGBE_SUCCESS) {
 4184                 DEBUGOUT("Auto-Negotiation did not complete\n");
 4185                 return status;
 4186         }
 4187 
 4188         /* The possible values of fc.requested_mode are:
 4189          * 0: Flow control is completely disabled
 4190          * 1: Rx flow control is enabled (we can receive pause frames,
 4191          *    but not send pause frames).
 4192          * 2: Tx flow control is enabled (we can send pause frames but
 4193          *    we do not support receiving pause frames).
 4194          * 3: Both Rx and Tx flow control (symmetric) are enabled.
 4195          * other: Invalid.
 4196          */
 4197         switch (hw->fc.requested_mode) {
 4198         case ixgbe_fc_none:
 4199                 /* Flow control completely disabled by software override. */
 4200                 an_cntl &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
 4201                              IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
 4202                 break;
 4203         case ixgbe_fc_tx_pause:
 4204                 /* Tx Flow control is enabled, and Rx Flow control is
 4205                  * disabled by software override.
 4206                  */
 4207                 an_cntl |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
 4208                 an_cntl &= ~IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
 4209                 break;
 4210         case ixgbe_fc_rx_pause:
 4211                 /* Rx Flow control is enabled and Tx Flow control is
 4212                  * disabled by software override. Since there really
 4213                  * isn't a way to advertise that we are capable of RX
 4214                  * Pause ONLY, we will advertise that we support both
 4215                  * symmetric and asymmetric Rx PAUSE, as such we fall
 4216                  * through to the fc_full statement.  Later, we will
 4217                  * disable the adapter's ability to send PAUSE frames.
 4218                  */
 4219         case ixgbe_fc_full:
 4220                 /* Flow control (both Rx and Tx) is enabled by SW override. */
 4221                 an_cntl |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
 4222                            IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
 4223                 break;
 4224         default:
 4225                 ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
 4226                               "Flow control param set incorrectly\n");
 4227                 return IXGBE_ERR_CONFIG;
 4228         }
 4229 
 4230         status = hw->mac.ops.write_iosf_sb_reg(hw,
 4231                                         IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
 4232                                         IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl);
 4233 
 4234         /* Restart auto-negotiation. */
 4235         status = ixgbe_restart_an_internal_phy_x550em(hw);
 4236 
 4237         return status;
 4238 }
 4239 
 4240 /**
 4241  * ixgbe_set_mux - Set mux for port 1 access with CS4227
 4242  * @hw: pointer to hardware structure
 4243  * @state: set mux if 1, clear if 0
 4244  */
 4245 static void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state)
 4246 {
 4247         u32 esdp;
 4248 
 4249         if (!hw->bus.lan_id)
 4250                 return;
 4251         esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
 4252         if (state)
 4253                 esdp |= IXGBE_ESDP_SDP1;
 4254         else
 4255                 esdp &= ~IXGBE_ESDP_SDP1;
 4256         IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
 4257         IXGBE_WRITE_FLUSH(hw);
 4258 }
 4259 
 4260 /**
 4261  * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
 4262  * @hw: pointer to hardware structure
 4263  * @mask: Mask to specify which semaphore to acquire
 4264  *
 4265  * Acquires the SWFW semaphore and sets the I2C MUX
 4266  **/
 4267 s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
 4268 {
 4269         s32 status;
 4270 
 4271         DEBUGFUNC("ixgbe_acquire_swfw_sync_X550em");
 4272 
 4273         status = ixgbe_acquire_swfw_sync_X540(hw, mask);
 4274         if (status)
 4275                 return status;
 4276 
 4277         if (mask & IXGBE_GSSR_I2C_MASK)
 4278                 ixgbe_set_mux(hw, 1);
 4279 
 4280         return IXGBE_SUCCESS;
 4281 }
 4282 
 4283 /**
 4284  * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
 4285  * @hw: pointer to hardware structure
 4286  * @mask: Mask to specify which semaphore to release
 4287  *
 4288  * Releases the SWFW semaphore and sets the I2C MUX
 4289  **/
 4290 void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
 4291 {
 4292         DEBUGFUNC("ixgbe_release_swfw_sync_X550em");
 4293 
 4294         if (mask & IXGBE_GSSR_I2C_MASK)
 4295                 ixgbe_set_mux(hw, 0);
 4296 
 4297         ixgbe_release_swfw_sync_X540(hw, mask);
 4298 }
 4299 
 4300 /**
 4301  * ixgbe_acquire_swfw_sync_X550a - Acquire SWFW semaphore
 4302  * @hw: pointer to hardware structure
 4303  * @mask: Mask to specify which semaphore to acquire
 4304  *
 4305  * Acquires the SWFW semaphore and get the shared phy token as needed
 4306  */
 4307 static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask)
 4308 {
 4309         u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
 4310         int retries = FW_PHY_TOKEN_RETRIES;
 4311         s32 status = IXGBE_SUCCESS;
 4312 
 4313         DEBUGFUNC("ixgbe_acquire_swfw_sync_X550a");
 4314 
 4315         while (--retries) {
 4316                 status = IXGBE_SUCCESS;
 4317                 if (hmask)
 4318                         status = ixgbe_acquire_swfw_sync_X540(hw, hmask);
 4319                 if (status) {
 4320                         DEBUGOUT1("Could not acquire SWFW semaphore, Status = %d\n",
 4321                                   status);
 4322                         return status;
 4323                 }
 4324                 if (!(mask & IXGBE_GSSR_TOKEN_SM))
 4325                         return IXGBE_SUCCESS;
 4326 
 4327                 status = ixgbe_get_phy_token(hw);
 4328                 if (status == IXGBE_ERR_TOKEN_RETRY)
 4329                         DEBUGOUT1("Could not acquire PHY token, Status = %d\n",
 4330                                   status);
 4331 
 4332                 if (status == IXGBE_SUCCESS)
 4333                         return IXGBE_SUCCESS;
 4334 
 4335                 if (hmask)
 4336                         ixgbe_release_swfw_sync_X540(hw, hmask);
 4337 
 4338                 if (status != IXGBE_ERR_TOKEN_RETRY) {
 4339                         DEBUGOUT1("Unable to retry acquiring the PHY token, Status = %d\n",
 4340                                   status);
 4341                         return status;
 4342                 }
 4343         }
 4344 
 4345         DEBUGOUT1("Semaphore acquisition retries failed!: PHY ID = 0x%08X\n",
 4346                   hw->phy.id);
 4347         return status;
 4348 }
 4349 
 4350 /**
 4351  * ixgbe_release_swfw_sync_X550a - Release SWFW semaphore
 4352  * @hw: pointer to hardware structure
 4353  * @mask: Mask to specify which semaphore to release
 4354  *
 4355  * Releases the SWFW semaphore and puts the shared phy token as needed
 4356  */
 4357 static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask)
 4358 {
 4359         u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
 4360 
 4361         DEBUGFUNC("ixgbe_release_swfw_sync_X550a");
 4362 
 4363         if (mask & IXGBE_GSSR_TOKEN_SM)
 4364                 ixgbe_put_phy_token(hw);
 4365 
 4366         if (hmask)
 4367                 ixgbe_release_swfw_sync_X540(hw, hmask);
 4368 }
 4369 
 4370 /**
 4371  * ixgbe_read_phy_reg_x550a  - Reads specified PHY register
 4372  * @hw: pointer to hardware structure
 4373  * @reg_addr: 32 bit address of PHY register to read
 4374  * @device_type: 5 bit device type
 4375  * @phy_data: Pointer to read data from PHY register
 4376  *
 4377  * Reads a value from a specified PHY register using the SWFW lock and PHY
 4378  * Token. The PHY Token is needed since the MDIO is shared between to MAC
 4379  * instances.
 4380  **/
 4381 s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
 4382                                u32 device_type, u16 *phy_data)
 4383 {
 4384         s32 status;
 4385         u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
 4386 
 4387         DEBUGFUNC("ixgbe_read_phy_reg_x550a");
 4388 
 4389         if (hw->mac.ops.acquire_swfw_sync(hw, mask))
 4390                 return IXGBE_ERR_SWFW_SYNC;
 4391 
 4392         status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data);
 4393 
 4394         hw->mac.ops.release_swfw_sync(hw, mask);
 4395 
 4396         return status;
 4397 }
 4398 
 4399 /**
 4400  * ixgbe_write_phy_reg_x550a - Writes specified PHY register
 4401  * @hw: pointer to hardware structure
 4402  * @reg_addr: 32 bit PHY register to write
 4403  * @device_type: 5 bit device type
 4404  * @phy_data: Data to write to the PHY register
 4405  *
 4406  * Writes a value to specified PHY register using the SWFW lock and PHY Token.
 4407  * The PHY Token is needed since the MDIO is shared between to MAC instances.
 4408  **/
 4409 s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
 4410                                 u32 device_type, u16 phy_data)
 4411 {
 4412         s32 status;
 4413         u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
 4414 
 4415         DEBUGFUNC("ixgbe_write_phy_reg_x550a");
 4416 
 4417         if (hw->mac.ops.acquire_swfw_sync(hw, mask) == IXGBE_SUCCESS) {
 4418                 status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type,
 4419                                                  phy_data);
 4420                 hw->mac.ops.release_swfw_sync(hw, mask);
 4421         } else {
 4422                 status = IXGBE_ERR_SWFW_SYNC;
 4423         }
 4424 
 4425         return status;
 4426 }
 4427 
 4428 /**
 4429  * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
 4430  * @hw: pointer to hardware structure
 4431  *
 4432  * Handle external Base T PHY interrupt. If high temperature
 4433  * failure alarm then return error, else if link status change
 4434  * then setup internal/external PHY link
 4435  *
 4436  * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
 4437  * failure alarm, else return PHY access status.
 4438  */
 4439 s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
 4440 {
 4441         bool lsc;
 4442         u32 status;
 4443 
 4444         status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
 4445 
 4446         if (status != IXGBE_SUCCESS)
 4447                 return status;
 4448 
 4449         if (lsc)
 4450                 return ixgbe_setup_internal_phy(hw);
 4451 
 4452         return IXGBE_SUCCESS;
 4453 }
 4454 
 4455 /**
 4456  * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed
 4457  * @hw: pointer to hardware structure
 4458  * @speed: new link speed
 4459  * @autoneg_wait_to_complete: true when waiting for completion is needed
 4460  *
 4461  * Setup internal/external PHY link speed based on link speed, then set
 4462  * external PHY auto advertised link speed.
 4463  *
 4464  * Returns error status for any failure
 4465  **/
 4466 s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
 4467                                   ixgbe_link_speed speed,
 4468                                   bool autoneg_wait_to_complete)
 4469 {
 4470         s32 status;
 4471         ixgbe_link_speed force_speed;
 4472         u32 i;
 4473         bool link_up = false;
 4474 
 4475         DEBUGFUNC("ixgbe_setup_mac_link_t_X550em");
 4476 
 4477         /* Setup internal/external PHY link speed to iXFI (10G), unless
 4478          * only 1G is auto advertised then setup KX link.
 4479          */
 4480         if (speed & IXGBE_LINK_SPEED_10GB_FULL)
 4481                 force_speed = IXGBE_LINK_SPEED_10GB_FULL;
 4482         else
 4483                 force_speed = IXGBE_LINK_SPEED_1GB_FULL;
 4484 
 4485         /* If X552 and internal link mode is XFI, then setup XFI internal link.
 4486          */
 4487         if (hw->mac.type == ixgbe_mac_X550EM_x &&
 4488             !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
 4489                 status = ixgbe_setup_ixfi_x550em(hw, &force_speed);
 4490 
 4491                 if (status != IXGBE_SUCCESS)
 4492                         return status;
 4493 
 4494                 /* Wait for the controller to acquire link */
 4495                 for (i = 0; i < 10; i++) {
 4496                         msec_delay(100);
 4497 
 4498                         status = ixgbe_check_link(hw, &force_speed, &link_up,
 4499                                                   false);
 4500                         if (status != IXGBE_SUCCESS)
 4501                                 return status;
 4502 
 4503                         if (link_up)
 4504                                 break;
 4505                 }
 4506         }
 4507 
 4508         return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
 4509 }
 4510 
 4511 /**
 4512  * ixgbe_check_link_t_X550em - Determine link and speed status
 4513  * @hw: pointer to hardware structure
 4514  * @speed: pointer to link speed
 4515  * @link_up: true when link is up
 4516  * @link_up_wait_to_complete: bool used to wait for link up or not
 4517  *
 4518  * Check that both the MAC and X557 external PHY have link.
 4519  **/
 4520 s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
 4521                               bool *link_up, bool link_up_wait_to_complete)
 4522 {
 4523         u32 status;
 4524         u16 i, autoneg_status = 0;
 4525 
 4526         if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
 4527                 return IXGBE_ERR_CONFIG;
 4528 
 4529         status = ixgbe_check_mac_link_generic(hw, speed, link_up,
 4530                                               link_up_wait_to_complete);
 4531 
 4532         /* If check link fails or MAC link is not up, then return */
 4533         if (status != IXGBE_SUCCESS || !(*link_up))
 4534                 return status;
 4535 
 4536         /* MAC link is up, so check external PHY link.
 4537          * X557 PHY. Link status is latching low, and can only be used to detect
 4538          * link drop, and not the current status of the link without performing
 4539          * back-to-back reads.
 4540          */
 4541         for (i = 0; i < 2; i++) {
 4542                 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
 4543                                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
 4544                                               &autoneg_status);
 4545 
 4546                 if (status != IXGBE_SUCCESS)
 4547                         return status;
 4548         }
 4549 
 4550         /* If external PHY link is not up, then indicate link not up */
 4551         if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
 4552                 *link_up = false;
 4553 
 4554         return IXGBE_SUCCESS;
 4555 }
 4556 
 4557 /**
 4558  * ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI
 4559  * @hw: pointer to hardware structure
 4560  **/
 4561 s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw)
 4562 {
 4563         s32 status;
 4564 
 4565         status = ixgbe_reset_phy_generic(hw);
 4566 
 4567         if (status != IXGBE_SUCCESS)
 4568                 return status;
 4569 
 4570         /* Configure Link Status Alarm and Temperature Threshold interrupts */
 4571         return ixgbe_enable_lasi_ext_t_x550em(hw);
 4572 }
 4573 
 4574 /**
 4575  * ixgbe_led_on_t_X550em - Turns on the software controllable LEDs.
 4576  * @hw: pointer to hardware structure
 4577  * @led_idx: led number to turn on
 4578  **/
 4579 s32 ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
 4580 {
 4581         u16 phy_data;
 4582 
 4583         DEBUGFUNC("ixgbe_led_on_t_X550em");
 4584 
 4585         if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
 4586                 return IXGBE_ERR_PARAM;
 4587 
 4588         /* To turn on the LED, set mode to ON. */
 4589         ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
 4590                            IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
 4591         phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK;
 4592         ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
 4593                             IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
 4594 
 4595         /* Some designs have the LEDs wired to the MAC */
 4596         return ixgbe_led_on_generic(hw, led_idx);
 4597 }
 4598 
 4599 /**
 4600  * ixgbe_led_off_t_X550em - Turns off the software controllable LEDs.
 4601  * @hw: pointer to hardware structure
 4602  * @led_idx: led number to turn off
 4603  **/
 4604 s32 ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
 4605 {
 4606         u16 phy_data;
 4607 
 4608         DEBUGFUNC("ixgbe_led_off_t_X550em");
 4609 
 4610         if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
 4611                 return IXGBE_ERR_PARAM;
 4612 
 4613         /* To turn on the LED, set mode to ON. */
 4614         ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
 4615                            IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
 4616         phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK;
 4617         ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
 4618                             IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
 4619 
 4620         /* Some designs have the LEDs wired to the MAC */
 4621         return ixgbe_led_off_generic(hw, led_idx);
 4622 }
 4623 
 4624 /**
 4625  * ixgbe_set_fw_drv_ver_x550 - Sends driver version to firmware
 4626  * @hw: pointer to the HW structure
 4627  * @maj: driver version major number
 4628  * @min: driver version minor number
 4629  * @build: driver version build number
 4630  * @sub: driver version sub build number
 4631  * @len: length of driver_ver string
 4632  * @driver_ver: driver string
 4633  *
 4634  * Sends driver version number to firmware through the manageability
 4635  * block.  On success return IXGBE_SUCCESS
 4636  * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
 4637  * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
 4638  **/
 4639 s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min,
 4640                               u8 build, u8 sub, u16 len, const char *driver_ver)
 4641 {
 4642         struct ixgbe_hic_drv_info2 fw_cmd;
 4643         s32 ret_val = IXGBE_SUCCESS;
 4644         int i;
 4645 
 4646         DEBUGFUNC("ixgbe_set_fw_drv_ver_x550");
 4647 
 4648         if ((len == 0) || (driver_ver == NULL) ||
 4649            (len > sizeof(fw_cmd.driver_string)))
 4650                 return IXGBE_ERR_INVALID_ARGUMENT;
 4651 
 4652         fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
 4653         fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len;
 4654         fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
 4655         fw_cmd.port_num = (u8)hw->bus.func;
 4656         fw_cmd.ver_maj = maj;
 4657         fw_cmd.ver_min = min;
 4658         fw_cmd.ver_build = build;
 4659         fw_cmd.ver_sub = sub;
 4660         fw_cmd.hdr.checksum = 0;
 4661         memcpy(fw_cmd.driver_string, driver_ver, len);
 4662         fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
 4663                                 (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
 4664 
 4665         for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
 4666                 ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
 4667                                                        sizeof(fw_cmd),
 4668                                                        IXGBE_HI_COMMAND_TIMEOUT,
 4669                                                        true);
 4670                 if (ret_val != IXGBE_SUCCESS)
 4671                         continue;
 4672 
 4673                 if (fw_cmd.hdr.cmd_or_resp.ret_status ==
 4674                     FW_CEM_RESP_STATUS_SUCCESS)
 4675                         ret_val = IXGBE_SUCCESS;
 4676                 else
 4677                         ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
 4678 
 4679                 break;
 4680         }
 4681 
 4682         return ret_val;
 4683 }
 4684 
 4685 /**
 4686  * ixgbe_fw_recovery_mode_X550 - Check FW NVM recovery mode
 4687  * @hw: pointer t hardware structure
 4688  *
 4689  * Returns true if in FW NVM recovery mode.
 4690  **/
 4691 bool ixgbe_fw_recovery_mode_X550(struct ixgbe_hw *hw)
 4692 {
 4693         u32 fwsm;
 4694 
 4695         fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw));
 4696 
 4697         return !!(fwsm & IXGBE_FWSM_FW_NVM_RECOVERY_MODE);
 4698 }

Cache object: 11a0583117df17cfd396d3b7bd0a740c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.