dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/******************************************************************************
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent Copyright (c) 2001-2015, Intel Corporation
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent All rights reserved.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent Redistribution and use in source and binary forms, with or without
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent modification, are permitted provided that the following conditions are met:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent 1. Redistributions of source code must retain the above copyright notice,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent this list of conditions and the following disclaimer.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent 2. Redistributions in binary form must reproduce the above copyright
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent notice, this list of conditions and the following disclaimer in the
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent documentation and/or other materials provided with the distribution.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent 3. Neither the name of the Intel Corporation nor the names of its
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent contributors may be used to endorse or promote products derived from
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent this software without specific prior written permission.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent POSSIBILITY OF SUCH DAMAGE.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent******************************************************************************/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/*$FreeBSD$*/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent#include "ixgbe_x550.h"
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent#include "ixgbe_x540.h"
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent#include "ixgbe_type.h"
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent#include "ixgbe_api.h"
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent#include "ixgbe_common.h"
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent#include "ixgbe_phy.h"
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_init_ops_X550 - Inits func ptrs and MAC type
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Initialize the function pointers and assign the MAC type for X550.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Does not touch the hardware.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_init_ops_X550(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_mac_info *mac = &hw->mac;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 ret_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_init_ops_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_init_ops_X540(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.dmac_config = ixgbe_dmac_config_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.dmac_config_tcs = ixgbe_dmac_config_tcs_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.dmac_update_tcs = ixgbe_dmac_update_tcs_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.setup_eee = ixgbe_setup_eee_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.set_source_address_pruning =
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_set_source_address_pruning_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.set_ethertype_anti_spoofing =
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_set_ethertype_anti_spoofing_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.init_params = ixgbe_init_eeprom_params_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.read = ixgbe_read_ee_hostif_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.write = ixgbe_write_ee_hostif_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.disable_mdd = ixgbe_disable_mdd_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.enable_mdd = ixgbe_enable_mdd_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.mdd_event = ixgbe_mdd_event_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.restore_mdd_vf = ixgbe_restore_mdd_vf_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.disable_rx = ixgbe_disable_rx_x550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.led_on = ixgbe_led_on_t_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.led_off = ixgbe_led_off_t_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_read_cs4227 - Read CS4227 register
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @reg: register number to write
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @value: pointer to receive value read
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns status code
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_read_i2c_combined_unlocked(hw, IXGBE_CS4227, reg, value);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_write_cs4227 - Write CS4227 register
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @reg: register number to write
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @value: value to write to register
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns status code
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_write_i2c_combined_unlocked(hw, IXGBE_CS4227, reg, value);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_read_pe - Read register from port expander
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @reg: register number to read
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @value: pointer to receive read value
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns status code
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT2(IXGBE_ERROR_CAUTION,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "port expander access failed with %d\n", status);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_write_pe - Write register to port expander
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @reg: register number to write
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @value: value to write
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns status code
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT2(IXGBE_ERROR_CAUTION,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "port expander access failed with %d\n", status);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_reset_cs4227 - Reset CS4227 using port expander
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * This function assumes that the caller has acquired the proper semaphore.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns error code
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 retry;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 value;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u8 reg;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Trigger hard reset. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= IXGBE_PE_BIT1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg &= ~IXGBE_PE_BIT1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg &= ~IXGBE_PE_BIT1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent usec_delay(IXGBE_CS4227_RESET_HOLD);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= IXGBE_PE_BIT1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Wait for the reset to complete. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent msec_delay(IXGBE_CS4227_RESET_DELAY);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &value);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status == IXGBE_SUCCESS &&
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent value == IXGBE_CS4227_EEPROM_LOAD_OK)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent msec_delay(IXGBE_CS4227_CHECK_DELAY);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (retry == IXGBE_CS4227_RETRIES) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "CS4227 reset did not complete.");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_PHY;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "CS4227 EEPROM did not load successfully.");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_PHY;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_check_cs4227 - Check CS4227 and reset as needed
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic void ixgbe_check_cs4227(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status = IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 swfw_mask = hw->phy.phy_semaphore_mask;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 value = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u8 retry;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT2(IXGBE_ERROR_CAUTION,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "semaphore failed with %d", status);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent msec_delay(IXGBE_CS4227_CHECK_DELAY);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent continue;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Get status of reset flow. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status == IXGBE_SUCCESS &&
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent value == IXGBE_CS4227_RESET_COMPLETE)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent goto out;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent value != IXGBE_CS4227_RESET_PENDING)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Reset is pending. Wait and check again. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.release_swfw_sync(hw, swfw_mask);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent msec_delay(IXGBE_CS4227_CHECK_DELAY);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If still pending, assume other instance failed. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (retry == IXGBE_CS4227_RETRIES) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT2(IXGBE_ERROR_CAUTION,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "semaphore failed with %d", status);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Reset the CS4227. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_reset_cs4227(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "CS4227 reset failed: %d", status);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent goto out;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Reset takes so long, temporarily release semaphore in case the
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * other driver instance is waiting for the reset indication.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_CS4227_RESET_PENDING);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.release_swfw_sync(hw, swfw_mask);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent msec_delay(10);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT2(IXGBE_ERROR_CAUTION,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "semaphore failed with %d", status);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Record completion for next time. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_CS4227_RESET_COMPLETE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentout:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.release_swfw_sync(hw, swfw_mask);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent msec_delay(hw->eeprom.semaphore_delay);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->bus.lan_id) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent esdp |= IXGBE_ESDP_SDP1_DIR;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_FLUSH(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_identify_phy_x550em - Get PHY type based on device id
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns error code
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (hw->device_id) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_DEV_ID_X550EM_X_SFP:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* set up for CS4227 usage */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_setup_mux_ctl(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_check_cs4227(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_identify_module_generic(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_DEV_ID_X550EM_X_KX4:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.type = ixgbe_phy_x550em_kx4;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_DEV_ID_X550EM_X_KR:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.type = ixgbe_phy_x550em_kr;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_DEV_ID_X550EM_X_1G_T:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_DEV_ID_X550EM_X_10G_T:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_identify_phy_generic(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 device_type, u16 *phy_data)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, *phy_data);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_NOT_IMPLEMENTED;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 device_type, u16 phy_data)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, phy_data);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_NOT_IMPLEMENTED;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent* ixgbe_init_ops_X550EM - Inits func ptrs and MAC type
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent* @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent*
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent* Initialize the function pointers and for MAC type X550EM.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent* Does not touch the hardware.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent**/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_mac_info *mac = &hw->mac;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_phy_info *phy = &hw->phy;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 ret_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_init_ops_X550EM");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Similar to X550 so start there. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_init_ops_X550(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Since this function eventually calls
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_init_ops_540 by design, we are setting
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * the pointers to NULL explicitly here to overwrite
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * the values being set in the x540 function.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* FCOE not supported in x550EM */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.get_san_mac_addr = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.set_san_mac_addr = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.get_wwn_prefix = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.get_fcoe_boot_status = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* IPsec not supported in x550EM */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.disable_sec_rx_path = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.enable_sec_rx_path = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* AUTOC register is not present in x550EM. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.prot_autoc_read = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.prot_autoc_write = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* X550EM bus type is internal*/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->bus.type = ixgbe_bus_type_internal;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.get_bus_info = ixgbe_get_bus_info_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->mac.type == ixgbe_mac_X550EM_x) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.get_media_type = ixgbe_get_media_type_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.reset_hw = ixgbe_reset_hw_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.get_supported_physical_layer =
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_get_supported_physical_layer_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.setup_fc = ixgbe_setup_fc_generic;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent else
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.setup_fc = ixgbe_setup_fc_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->device_id != IXGBE_DEV_ID_X550EM_X_KR)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.setup_eee = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* PHY */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.init = ixgbe_init_phy_ops_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.identify = ixgbe_identify_phy_x550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.set_phy_power = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* EEPROM */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.read = ixgbe_read_ee_hostif_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.write = ixgbe_write_ee_hostif_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_dmac_config_X550
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Configure DMA coalescing. If enabling dmac, dmac is activated.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * When disabling dmac, dmac enable dmac bit is cleared.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 reg, high_pri_tc;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_dmac_config_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Disable DMA coalescing before configuring */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg &= ~IXGBE_DMACR_DMAC_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Disable DMA Coalescing if the watchdog timer is 0 */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!hw->mac.dmac_config.watchdog_timer)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent goto out;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_dmac_config_tcs_X550(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Configure DMA Coalescing Control Register */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Set the watchdog timer in units of 40.96 usec */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg &= ~IXGBE_DMACR_DMACWT_MASK;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= (hw->mac.dmac_config.watchdog_timer * 100) / 4096;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg &= ~IXGBE_DMACR_HIGH_PRI_TC_MASK;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If fcoe is enabled, set high priority traffic class */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->mac.dmac_config.fcoe_en) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent high_pri_tc = 1 << hw->mac.dmac_config.fcoe_tc;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= ((high_pri_tc << IXGBE_DMACR_HIGH_PRI_TC_SHIFT) &
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_DMACR_HIGH_PRI_TC_MASK);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= IXGBE_DMACR_EN_MNG_IND;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Enable DMA coalescing after configuration */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= IXGBE_DMACR_DMAC_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentout:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_dmac_config_tcs_X550
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Configure DMA coalescing threshold per TC. The dmac enable bit must
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * be cleared before configuring.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_dmac_config_tcs_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Configure DMA coalescing enabled */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (hw->mac.dmac_config.link_speed) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_LINK_SPEED_100_FULL:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pb_headroom = IXGBE_DMACRXT_100M;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_LINK_SPEED_1GB_FULL:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pb_headroom = IXGBE_DMACRXT_1G;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pb_headroom = IXGBE_DMACRXT_10G;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent maxframe_size_kb = ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >>
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MHADD_MFS_SHIFT) / 1024);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Set the per Rx packet buffer receive threshold */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_DMCTH(tc));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg &= ~IXGBE_DMCTH_DMACRXT_MASK;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (tc < hw->mac.dmac_config.num_tcs) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Get Rx PB size */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent rx_pb_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent rx_pb_size = (rx_pb_size & IXGBE_RXPBSIZE_MASK) >>
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_RXPBSIZE_SHIFT;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Calculate receive buffer threshold in kilobytes */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (rx_pb_size > pb_headroom)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent rx_pb_size = rx_pb_size - pb_headroom;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent else
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent rx_pb_size = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Minimum of MFS shall be set for DMCTH */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= (rx_pb_size > maxframe_size_kb) ?
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent rx_pb_size : maxframe_size_kb;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_dmac_update_tcs_X550
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Disables dmac, updates per TC settings, and then enables dmac.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 reg;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_dmac_update_tcs_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Disable DMA coalescing before configuring */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg &= ~IXGBE_DMACR_DMAC_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_dmac_config_tcs_X550(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Enable DMA coalescing after configuration */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= IXGBE_DMACR_DMAC_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Initializes the EEPROM parameters ixgbe_eeprom_info within the
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_hw struct in order to set up EEPROM access.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 eec;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 eeprom_size;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_init_eeprom_params_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (eeprom->type == ixgbe_eeprom_uninitialized) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->semaphore_delay = 10;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->type = ixgbe_flash;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eec = IXGBE_READ_REG(hw, IXGBE_EEC);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_EEC_SIZE_SHIFT);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->word_size = 1 << (eeprom_size +
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_EEPROM_WORD_SIZE_SHIFT);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom->type, eeprom->word_size);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_setup_eee_X550 - Enable/disable EEE support
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to the HW structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @enable_eee: boolean flag to enable EEE
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Enable/disable EEE based on enable_eee flag.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Auto-negotiation must be started after BASE-T EEE bits in PHY register 7.3C
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * are modified.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_setup_eee_X550(struct ixgbe_hw *hw, bool enable_eee)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 eeer;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 autoneg_eee_reg;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 link_reg;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 fuse;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_setup_eee_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeer = IXGBE_READ_REG(hw, IXGBE_EEER);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Enable or disable EEE per flag */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (enable_eee) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeer |= (IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->mac.type == ixgbe_mac_X550) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Advertise EEE capability */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_eee_reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent autoneg_eee_reg |= (IXGBE_AUTO_NEG_10GBASE_EEE_ADVT |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_AUTO_NEG_1000BASE_EEE_ADVT |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_AUTO_NEG_100BASE_EEE_ADVT);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_eee_reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Not supported on first revision. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent fuse = IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!(fuse & IXGBE_FUSES0_REV1))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent link_reg |= IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Don't advertise FEC capability when EEE enabled. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent link_reg &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeer &= ~(IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->mac.type == ixgbe_mac_X550) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Disable advertised EEE capability */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_eee_reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent autoneg_eee_reg &= ~(IXGBE_AUTO_NEG_10GBASE_EEE_ADVT |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_AUTO_NEG_1000BASE_EEE_ADVT |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_AUTO_NEG_100BASE_EEE_ADVT);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_eee_reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent link_reg &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Advertise FEC capability when EEE is disabled. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent link_reg |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_EEER, eeer);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_set_source_address_pruning_X550 - Enable/Disbale source address pruning
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @enable: enable or disable source address pruning
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @pool: Rx pool to set source address pruning for
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentvoid ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent unsigned int pool)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u64 pfflp;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* max rx pool is 63 */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (pool > 63)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (enable)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pfflp |= (1ULL << pool);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent else
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pfflp &= ~(1ULL << pool);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype anti-spoofing
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @enable: enable or disable switch for Ethertype anti-spoofing
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentvoid ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool enable, int vf)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent int vf_target_reg = vf >> 3;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 pfvfspoof;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_set_ethertype_anti_spoofing_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (enable)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pfvfspoof |= (1 << vf_target_shift);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent else
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pfvfspoof &= ~(1 << vf_target_shift);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_iosf_wait - Wait for IOSF command completion
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @ctrl: pointer to location to receive final IOSF control value
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns failing status on timeout
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Note: ctrl can be NULL if the IOSF control register value is not needed
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 i, command = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Check every 10 usec to see if the address cycle completed.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * The SB IOSF BUSY bit will clear when the operation is
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * complete
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent usec_delay(10);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ctrl)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *ctrl = command;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT1(IXGBE_ERROR_POLLING, "Wait timed out\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_PHY;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register of the IOSF
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * device
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @reg_addr: 32 bit PHY register to write
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @device_type: 3 bit device type
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @data: Data to write to the register
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 device_type, u32 data)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 command, error;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 ret;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ret != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret = ixgbe_iosf_wait(hw, NULL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ret != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent goto out;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Write IOSF control register */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Write IOSF data register */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret = ixgbe_iosf_wait(hw, &command);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT2(IXGBE_ERROR_POLLING,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "Failed to write, error %x\n", error);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret = IXGBE_ERR_PHY;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentout:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_release_swfw_semaphore(hw, gssr);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_read_iosf_sb_reg_x550 - Writes a value to specified register of the IOSF
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * device
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @reg_addr: 32 bit PHY register to write
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @device_type: 3 bit device type
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @phy_data: Pointer to read data from the register
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 device_type, u32 *data)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 command, error;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 ret;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ret != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret = ixgbe_iosf_wait(hw, NULL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ret != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent goto out;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Write IOSF control register */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret = ixgbe_iosf_wait(hw, &command);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT2(IXGBE_ERROR_POLLING,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "Failed to read, error %x\n", error);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret = IXGBE_ERR_PHY;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ret == IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentout:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_release_swfw_semaphore(hw, gssr);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_disable_mdd_X550
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Disable malicious driver detection
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentvoid ixgbe_disable_mdd_X550(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 reg;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_disable_mdd_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Disable MDD for TX DMA and interrupt */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg &= ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Disable MDD for RX and interrupt */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg &= ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_enable_mdd_X550
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Enable malicious driver detection
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentvoid ixgbe_enable_mdd_X550(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 reg;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_enable_mdd_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Enable MDD for TX DMA and interrupt */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Enable MDD for RX and interrupt */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_restore_mdd_vf_X550
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @vf: vf index
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Restore VF that was disabled during malicious driver detection event
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentvoid ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 idx, reg, num_qs, start_q, bitmask;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_restore_mdd_vf_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Map VF to queues */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (reg & IXGBE_MRQC_MRQE_MASK) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_MRQC_VMDQRT8TCEN:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent num_qs = 8; /* 16 VFs / pools */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bitmask = 0x000000FF;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_MRQC_VMDQRSS32EN:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_MRQC_VMDQRT4TCEN:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent num_qs = 4; /* 32 VFs / pools */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bitmask = 0x0000000F;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default: /* 64 VFs / pools */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent num_qs = 2;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bitmask = 0x00000003;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent start_q = vf * num_qs;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent idx = start_q / 32;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= (bitmask << (start_q % 32));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_mdd_event_X550
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @vf_bitmap: vf bitmap of malicious vfs
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Handle malicious driver detection event.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentvoid ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 wqbr;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 i, j, reg, q, shift, vf, idx;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_mdd_event_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* figure out pool size for mapping to vf's */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (reg & IXGBE_MRQC_MRQE_MASK) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_MRQC_VMDQRT8TCEN:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent shift = 3; /* 16 VFs / pools */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_MRQC_VMDQRSS32EN:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_MRQC_VMDQRT4TCEN:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent shift = 2; /* 32 VFs / pools */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent shift = 1; /* 64 VFs / pools */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Read WQBR_TX and WQBR_RX and check for malicious queues */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (i = 0; i < 4; i++) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent wqbr = IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent wqbr |= IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!wqbr)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent continue;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Get malicious queue */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (j = 0; j < 32 && wqbr; j++) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!(wqbr & (1 << j)))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent continue;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Get queue from bitmask */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent q = j + (i * 32);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Map queue to vf */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent vf = (q >> shift);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Set vf bit in vf_bitmap */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent idx = vf / 32;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent vf_bitmap[idx] |= (1 << (vf % 32));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent wqbr &= ~(1 << j);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_get_media_type_X550em - Get media type
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns the media type (fiber, copper, backplane)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentenum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent enum ixgbe_media_type media_type;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_get_media_type_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Detect if there is a copper PHY attached. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (hw->device_id) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_DEV_ID_X550EM_X_KR:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_DEV_ID_X550EM_X_KX4:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent media_type = ixgbe_media_type_backplane;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_DEV_ID_X550EM_X_SFP:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent media_type = ixgbe_media_type_fiber;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_DEV_ID_X550EM_X_1G_T:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_DEV_ID_X550EM_X_10G_T:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent media_type = ixgbe_media_type_copper;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent media_type = ixgbe_media_type_unknown;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return media_type;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @linear: TRUE if SFP module is linear
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_supported_sfp_modules_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (hw->phy.sfp_type) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_not_present:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_SFP_NOT_PRESENT;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_da_cu_core0:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_da_cu_core1:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *linear = TRUE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_srlr_core0:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_srlr_core1:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_da_act_lmt_core0:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_da_act_lmt_core1:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_1g_sx_core0:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_1g_sx_core1:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_1g_lx_core0:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_1g_lx_core1:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *linear = FALSE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_unknown:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_1g_cu_core0:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_sfp_type_1g_cu_core1:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_SFP_NOT_SUPPORTED;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_identify_sfp_module_X550em - Identifies SFP modules
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Searches for and identifies the SFP module and assigns appropriate PHY type.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool linear;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_identify_sfp_module_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_identify_module_generic(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Check if SFP module is supported */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_setup_sfp_modules_X550em - Setup MAC link ops
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool linear;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_setup_sfp_modules_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Check if SFP module is supported */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_init_mac_link_ops_X550em(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.ops.reset = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_init_mac_link_ops_X550em - init mac link function pointers
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentvoid ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_mac_info *mac = &hw->mac;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_init_mac_link_ops_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (hw->mac.ops.get_media_type(hw)) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_media_type_fiber:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* CS4227 does not support autoneg, so disable the laser control
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * functions for SFP+ fiber
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.disable_tx_laser = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.enable_tx_laser = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.flap_tx_laser = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.set_rate_select_speed =
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_set_soft_rate_select_speed;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_media_type_copper:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent mac->ops.check_link = ixgbe_check_link_t_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_get_link_capabilities_x550em - Determines link capabilities
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @speed: pointer to link speed
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @autoneg: TRUE when autoneg or autotry is enabled
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_link_speed *speed,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool *autoneg)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_get_link_capabilities_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* SFP */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->phy.media_type == ixgbe_media_type_fiber) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* CS4227 SFP must not enable auto-negotiation */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *autoneg = FALSE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Check if 1G SFP module. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent || hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *speed = IXGBE_LINK_SPEED_1GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Link capabilities are based on SFP */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->phy.multispeed_fiber)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *speed = IXGBE_LINK_SPEED_10GB_FULL |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_LINK_SPEED_1GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent else
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *speed = IXGBE_LINK_SPEED_10GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *speed = IXGBE_LINK_SPEED_10GB_FULL |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_LINK_SPEED_1GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *autoneg = TRUE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @lsc: pointer to boolean flag which indicates whether external Base T
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * PHY interrupt is lsc
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Determime if external Base T PHY interrupt cause is high temperature
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * failure alarm or link status change.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * failure alarm, else return PHY access status.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 reg;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *lsc = FALSE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Vendor alarm triggered */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Global alarm triggered */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If high temperature failure, then return over temp error and exit */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* power down the PHY in case the PHY FW didn't already */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_set_copper_phy_power(hw, FALSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_OVERTEMP;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* device fault alarm triggered */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* if device fault was due to high temp alarm handle and exit */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* power down the PHY in case the PHY FW didn't */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_set_copper_phy_power(hw, FALSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_OVERTEMP;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Vendor alarm 2 triggered */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* link connect/disconnect event occurred */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Indicate LSC */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *lsc = TRUE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Enable link status change and temperature failure alarm for the external
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Base T PHY
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns PHY access status
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 reg;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool lsc;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Clear interrupt flags */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Enable link status change alarm */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Enables high temperature failure alarm */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_GLOBAL_ALARM_1_INT);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Enable chip-wide vendor alarm */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @speed: link speed
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Configures the integrated KR PHY.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_link_speed speed)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 reg_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Advertise 10G support. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (speed & IXGBE_LINK_SPEED_10GB_FULL)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Advertise 1G support. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (speed & IXGBE_LINK_SPEED_1GB_FULL)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Restart auto-negotiation. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_init_phy_ops_X550em - PHY/SFP specific init
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Initialize any function pointers that were not able to be
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * set during init_shared_code because the PHY/SFP type was
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * not known. Perform the SFP init if necessary.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_phy_info *phy = &hw->phy;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_link_speed speed;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 ret_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_init_phy_ops_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.set_lan_id(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_setup_mux_ctl(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Save NW management interface connected on board. This is used
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * to determine internal PHY mode.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (phy->nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent speed = IXGBE_LINK_SPEED_10GB_FULL |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_LINK_SPEED_1GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Identify the PHY or SFP module */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = phy->ops.identify(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Setup function pointers based on detected hardware */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_init_mac_link_ops_X550em(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (phy->sfp_type != ixgbe_sfp_type_unknown)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.reset = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Set functions pointers based on phy type */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (hw->phy.type) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_phy_x550em_kx4:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.setup_link = NULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_phy_x550em_kr:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.setup_link = ixgbe_setup_kr_x550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_phy_x550em_ext_t:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Save NW management interface connected on board. This is used
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * to determine internal PHY mode
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If internal link mode is XFI, then setup iXFI internal link,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * else setup KR now.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!(phy->nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.setup_internal_link =
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_setup_internal_phy_t_x550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent speed = IXGBE_LINK_SPEED_10GB_FULL |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_LINK_SPEED_1GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_setup_kr_speed_x550em(hw, speed);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* setup SW LPLU only for first revision */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!(IXGBE_FUSES0_REV1 & IXGBE_READ_REG(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_FUSES0_GROUP(0))))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy->ops.reset = ixgbe_reset_phy_t_X550em;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_reset_hw_X550em - Perform hardware reset
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Resets the hardware by resetting the transmit and receive units, masks
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * reset.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_link_speed link_speed;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 ctrl = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 i;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 hlreg0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool link_up = FALSE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_reset_hw_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Call adapter stop to disable Tx/Rx and clear interrupts */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->mac.ops.stop_adapter(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* flush pending Tx transactions */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_clear_tx_pending(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Config MDIO clock speed before the first MDIO PHY access */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hlreg0 &= ~IXGBE_HLREG0_MDCSPD;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* PHY ops must be identified and initialized prior to reset */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.init(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* start the external PHY */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_init_ext_t_x550em(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Setup SFP module if there is one present. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->phy.sfp_setup_needed) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->mac.ops.setup_sfp(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.sfp_setup_needed = FALSE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Reset PHY */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!hw->phy.reset_disable && hw->phy.ops.reset)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.ops.reset(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentmac_reset_top:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Issue global reset to the MAC. Needs to be SW reset if link is up.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * If link reset is used when link is up, it might reset the PHY when
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * mng is using it. If link is down or the flag to force full link
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * reset is set, then perform link reset.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ctrl = IXGBE_CTRL_LNK_RST;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!hw->force_full_reset) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (link_up)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ctrl = IXGBE_CTRL_RST;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_FLUSH(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Poll for reset bit to self-clear meaning reset is complete */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (i = 0; i < 10; i++) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent usec_delay(1);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!(ctrl & IXGBE_CTRL_RST_MASK))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ctrl & IXGBE_CTRL_RST_MASK) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = IXGBE_ERR_RESET_FAILED;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT("Reset polling failed to complete.\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent msec_delay(50);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Double resets are required for recovery from certain error
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * conditions. Between resets, it is necessary to stall to
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * allow time for any pending HW events to complete.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent goto mac_reset_top;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Store the permanent mac address */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Store MAC address from RAR0, clear receive address registers, and
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * clear the multicast table. Also reset num_rar_entries to 128,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * since we modify this value when programming the SAN MAC address.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.num_rar_entries = 128;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.init_rx_addrs(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_setup_mux_ctl(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 reg;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_TX_VENDOR_ALARMS_3,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_PMA_PMD_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If PHY FW reset completed bit is set then this is the first
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * SW instance after a power on so the PHY FW must be un-stalled.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_GLOBAL_RES_PR_10,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg &= ~IXGBE_MDIO_POWER_UP_STALL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.write_reg(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_GLOBAL_RES_PR_10,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_setup_kr_x550em - Configure the KR PHY.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Configures the integrated KR PHY.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Configure the external PHY and the integrated KR PHY for SFP support.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_link_speed speed,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool autoneg_wait_to_complete)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 ret_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 reg_slice, reg_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool setup_linear = FALSE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Check if SFP module is supported and linear */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If no SFP module present, then return success. Return success since
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * there is no reason to configure CS4227 and SFP not present error is
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * not excepted in the setup MAC link flow.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ret_val != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Configure CS4227 LINE side to 10G SR. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB +
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent (hw->bus.lan_id << 12);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val = IXGBE_CS4227_SPEED_10G;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB +
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent (hw->bus.lan_id << 12);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Configure CS4227 for HOST connection rate then type. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_slice = IXGBE_CS4227_HOST_SPARE22_MSB +
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent (hw->bus.lan_id << 12);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val = (speed & IXGBE_LINK_SPEED_10GB_FULL) ?
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_CS4227_SPEED_10G : IXGBE_CS4227_SPEED_1G;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB +
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent (hw->bus.lan_id << 12);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (setup_linear)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent else
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Setup XFI internal link. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_setup_ixfi_x550em(hw, &speed);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Configure internal PHY for KR/KX. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_setup_kr_speed_x550em(hw, speed);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Configure CS4227 LINE side to proper mode. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB +
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent (hw->bus.lan_id << 12);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (setup_linear)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent else
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @speed: the link speed to force
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Configures the integrated KR PHY to use iXFI mode. Used to connect an
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * internal and external PHY at a specific speed, without autonegotiation.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 reg_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Disable AN and force speed to 10G Serial. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Select forced link speed for internal PHY. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (*speed) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_LINK_SPEED_10GB_FULL:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_LINK_SPEED_1GB_FULL:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Other link speeds are not supported by internal KR PHY. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_LINK_SETUP;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Disable training protocol FSM. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Disable Flex from training TXFFE. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Enable override for coefficients. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Toggle port SW reset by AN reset. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: address of hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @link_up: address of boolean to indicate link status
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns error code if unable to get link status.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 ret;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 autoneg_status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *link_up = FALSE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* read this twice back to back to indicate current status */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &autoneg_status);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ret != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &autoneg_status);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ret != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: point to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Configures the link between the integrated KR PHY and the external X557 PHY
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * The driver will call this function when it gets a link status change
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * interrupt from the X557 PHY. This function configures the link speed
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * between the PHYs to match the link speed of the BASE-T link.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * A return of a non-zero value indicates an error, and the base driver should
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * not report link up.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_link_speed force_speed;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool link_up;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 speed;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_CONFIG;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If link is not up, then there is no setup necessary so return */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!link_up)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &speed);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If link is not still up, then no setup is necessary so return */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!link_up)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* clear everything but the speed and duplex bits */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (speed) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent force_speed = IXGBE_LINK_SPEED_10GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent force_speed = IXGBE_LINK_SPEED_1GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Internal PHY does not support anything else */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_INVALID_LINK_SETTINGS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_setup_ixfi_x550em(hw, &force_speed);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Configures the integrated KR PHY to use internal loopback mode.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 reg_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Disable AN and force speed to 10G Serial. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Set near-end loopback clocks. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Set loopback enable. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Training bypass. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * assuming that the semaphore is already obtained.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @offset: offset of word in the EEPROM to read
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @data: word read from the EEPROM
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Reads a 16 bit word from the EEPROM using the hostif.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 *data)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_hic_read_shadow_ram buffer;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_read_ee_hostif_data_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.buf_lenh = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* convert offset from words to bytes */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* one word */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent sizeof(buffer),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_HI_COMMAND_TIMEOUT, FALSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent FW_NVM_DATA_OFFSET);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @offset: offset of word in the EEPROM to read
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @data: word read from the EEPROM
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Reads a 16 bit word from the EEPROM using the hostif.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 *data)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status = IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_read_ee_hostif_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SUCCESS) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_ee_hostif_data_X550(hw, offset, data);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = IXGBE_ERR_SWFW_SYNC;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @offset: offset of word in the EEPROM to read
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @words: number of words
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @data: word(s) read from the EEPROM
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Reads a 16 bit word(s) from the EEPROM using the hostif.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 offset, u16 words, u16 *data)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_hic_read_shadow_ram buffer;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 current_word = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 words_to_read;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 i;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Take semaphore for the entire operation. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT("EEPROM read buffer - semaphore failed\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent while (words) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (words > FW_MAX_READ_BUFFER_SIZE / 2)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent else
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent words_to_read = words;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.buf_lenh = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* convert offset from words to bytes */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.address = IXGBE_CPU_TO_BE32((offset + current_word) * 2);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.length = IXGBE_CPU_TO_BE16(words_to_read * 2);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent sizeof(buffer),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_HI_COMMAND_TIMEOUT,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent FALSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT("Host interface command failed\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent goto out;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (i = 0; i < words_to_read; i++) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent 2 * i;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 value = IXGBE_READ_REG(hw, reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent data[current_word] = (u16)(value & 0xffff);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent current_word++;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent i++;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (i < words_to_read) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent value >>= 16;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent data[current_word] = (u16)(value & 0xffff);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent current_word++;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent words -= words_to_read;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentout:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @offset: offset of word in the EEPROM to write
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @data: word write to the EEPROM
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Write a 16 bit word to the EEPROM using the hostif.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 data)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_hic_write_shadow_ram buffer;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_write_ee_hostif_data_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.buf_lenh = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* one word */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.data = data;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent sizeof(buffer),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_HI_COMMAND_TIMEOUT, FALSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @offset: offset of word in the EEPROM to write
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @data: word write to the EEPROM
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Write a 16 bit word to the EEPROM using the hostif.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 data)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status = IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_write_ee_hostif_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SUCCESS) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT("write ee hostif failed to get semaphore");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = IXGBE_ERR_SWFW_SYNC;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @offset: offset of word in the EEPROM to write
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @words: number of words
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @data: word(s) write to the EEPROM
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Write a 16 bit word(s) to the EEPROM using the hostif.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 offset, u16 words, u16 *data)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status = IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 i = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_write_ee_hostif_buffer_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Take semaphore for the entire operation. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT("EEPROM write buffer - semaphore failed\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent goto out;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (i = 0; i < words; i++) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent data[i]);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT("Eeprom buffered write failed\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentout:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_checksum_ptr_x550 - Checksum one pointer region
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @ptr: pointer offset in eeprom
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @size: size of section pointed by ptr, if 0 first word will be used as size
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @csum: address of checksum to update
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns error status for any failure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 size, u16 *csum, u16 *buffer,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 buffer_size)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 buf[256];
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 length, bufsz, i, start;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 *local_buffer;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bufsz = sizeof(buf) / sizeof(buf[0]);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Read a chunk at the pointer location */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!buffer) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT("Failed to read EEPROM image\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent local_buffer = buf;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (buffer_size < ptr)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_PARAM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent local_buffer = &buffer[ptr];
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (size) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent start = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent length = size;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent start = 1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent length = local_buffer[0];
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Skip pointer section if length is invalid. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (length == 0xFFFF || length == 0 ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent (ptr + length) >= hw->eeprom.word_size)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (buffer && ((u32)start + (u32)length > buffer_size))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_PARAM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (i = start; length; i++, length--) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (i == bufsz && !buffer) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ptr += bufsz;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent i = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (length < bufsz)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bufsz = length;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Read a chunk at the pointer location */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bufsz, buf);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT("Failed to read EEPROM image\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *csum += local_buffer[i];
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_calc_checksum_X550 - Calculates and returns the checksum
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @buffer: pointer to buffer containing calculated checksum
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @buffer_size: size of buffer
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns a negative error code on error, or the 16-bit checksum
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, u32 buffer_size)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 *local_buffer;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 checksum = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 pointer, i, size;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->eeprom.ops.init_params(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!buffer) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Read pointer area */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_EEPROM_LAST_WORD + 1,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent eeprom_ptrs);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT("Failed to read EEPROM image\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent local_buffer = eeprom_ptrs;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (buffer_size < IXGBE_EEPROM_LAST_WORD)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_PARAM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent local_buffer = buffer;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /*
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * For X550 hardware include 0x0-0x41 in the checksum, skip the
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * checksum word itself
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (i != IXGBE_EEPROM_CHECKSUM)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent checksum += local_buffer[i];
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /*
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Include all data from pointers 0x3, 0x6-0xE. This excludes the
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * FW, PHY module, and PCIe Expansion/Option ROM pointers.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent continue;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pointer = local_buffer[i];
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Skip pointer section if the pointer is invalid. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (pointer == 0xFFFF || pointer == 0 ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pointer >= hw->eeprom.word_size)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent continue;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (i) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_PCIE_GENERAL_PTR:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_PCIE_CONFIG0_PTR:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case IXGBE_PCIE_CONFIG1_PTR:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent size = IXGBE_PCIE_CONFIG_SIZE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent size = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer, buffer_size);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent checksum = (u16)IXGBE_EEPROM_SUM - checksum;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return (s32)checksum;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns a negative error code on error, or the 16-bit checksum
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_calc_checksum_X550(hw, NULL, 0);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @checksum_val: calculated checksum
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Performs checksum calculation and validates the EEPROM checksum. If the
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * caller does not need checksum_val, the value can be NULL.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, u16 *checksum_val)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 checksum;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 read_checksum = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Read the first word from the EEPROM. If this times out or fails, do
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * not continue or we could be in for a very long wait while every
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * EEPROM read fails
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->eeprom.ops.read(hw, 0, &checksum);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT("EEPROM read failed\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->eeprom.ops.calc_checksum(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status < 0)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent checksum = (u16)(status & 0xffff);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &read_checksum);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Verify read checksum from EEPROM is the same as
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * calculated checksum
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (read_checksum != checksum) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = IXGBE_ERR_EEPROM_CHECKSUM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "Invalid EEPROM checksum");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If the user cares, return the calculated checksum */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (checksum_val)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *checksum_val = checksum;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * After writing EEPROM to shadow RAM using EEWR register, software calculates
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * checksum and updates the EEPROM and instructs the hardware to update
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * the flash.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 checksum = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_update_eeprom_checksum_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Read the first word from the EEPROM. If this times out or fails, do
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * not continue or we could be in for a very long wait while every
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * EEPROM read fails
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGOUT("EEPROM read failed\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_calc_eeprom_checksum_X550(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status < 0)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent checksum = (u16)(status & 0xffff);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent checksum);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_update_flash_X550(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status = IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent union ixgbe_hic_hdr2 buffer;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_update_flash_X550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.req.buf_lenh = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent buffer.req.checksum = FW_DEFAULT_CHECKSUM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent sizeof(buffer),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_HI_COMMAND_TIMEOUT, FALSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_get_supported_physical_layer_X550em - Returns physical layer type
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Determines physical layer capabilities of the current configuration.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentu32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 ext_ability = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.ops.identify(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (hw->phy.type) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_phy_x550em_kr:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_PHYSICAL_LAYER_1000BASE_KX;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_phy_x550em_kx4:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_PHYSICAL_LAYER_1000BASE_KX;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_phy_x550em_ext_t:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_PMA_PMD_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &ext_ability);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return physical_layer;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_get_bus_info_x550em - Set PCI bus info
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Sets bus link width and speed to unknown because X550em is
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * not a PCI device.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_get_bus_info_x550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->bus.width = ixgbe_bus_width_unknown;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->bus.speed = ixgbe_bus_speed_unknown;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.ops.set_lan_id(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_disable_rx_x550 - Disable RX unit
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Enables the Rx DMA unit for x550
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentvoid ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 rxctrl, pfdtxgswc;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent struct ixgbe_hic_disable_rxen fw_cmd;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_enable_rx_dma_x550");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (rxctrl & IXGBE_RXCTRL_RXEN) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.set_lben = TRUE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent } else {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->mac.set_lben = FALSE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent fw_cmd.port_number = (u8)hw->bus.lan_id;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent sizeof(struct ixgbe_hic_disable_rxen),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_HI_COMMAND_TIMEOUT, TRUE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If we fail - disable RX using register write */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (rxctrl & IXGBE_RXCTRL_RXEN) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent rxctrl &= ~IXGBE_RXCTRL_RXEN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_enter_lplu_x550em - Transition to low power states
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Configures Low Power Link Up on transition to low power states
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * X557 PHY immediately prior to entering LPLU.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 an_10g_cntl_reg, autoneg_reg, speed;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_link_speed lcd_speed;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 save_autoneg;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool link_up;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* SW LPLU not required on later HW revisions. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (IXGBE_FUSES0_REV1 & IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If blocked by MNG FW, then don't restart AN */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ixgbe_check_reset_blocked(hw))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_read_eeprom(hw, NVM_INIT_CTRL_3, &hw->eeprom.ctrl_word_3);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If link is down, LPLU disabled in NVM, WoL disabled, or manageability
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * disabled, then force link down by entering low power mode.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent !(hw->wol_enabled || ixgbe_mng_present(hw)))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_set_copper_phy_power(hw, FALSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Determine LCD */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If no valid LCD link speed, then force link down and exit. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_set_copper_phy_power(hw, FALSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &speed);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If no link now, speed is invalid so take link down */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_set_copper_phy_power(hw, FALSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* clear everything but the speed bits */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If current speed is already LCD, then exit. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) &&
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) &&
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL)))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Clear AN completed indication */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &autoneg_reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &an_10g_cntl_reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &autoneg_reg);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent save_autoneg = hw->phy.autoneg_advertised;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Setup link at least common link speed */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->mac.ops.setup_link(hw, lcd_speed, FALSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* restore autoneg from before setting lplu speed */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->phy.autoneg_advertised = save_autoneg;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_get_lcd_x550em - Determine lowest common denominator
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @lcd_speed: pointer to lowest common link speed
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Determine lowest common link speed with link partner.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 an_lp_status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 word = hw->eeprom.ctrl_word_3;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &an_lp_status);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If link partner advertised 1G, return 1G */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *lcd_speed = IXGBE_LINK_SPEED_1GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) ||
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent (word & NVM_INIT_CTRL_3_D10GMP_PORT0))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Link partner not capable of lower speeds, return 10G */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *lcd_speed = IXGBE_LINK_SPEED_10GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_setup_fc_X550em - Set up flow control
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Called at init time to set up flow control.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 ret_val = IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 pause, asm_dir, reg_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_setup_fc_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Validate the requested mode */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent goto out;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* 10gig parts do not have a word in the EEPROM to determine the
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * default flow control setting, so we explicitly set it to full.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->fc.requested_mode == ixgbe_fc_default)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->fc.requested_mode = ixgbe_fc_full;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Determine PAUSE and ASM_DIR bits. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent switch (hw->fc.requested_mode) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_fc_none:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pause = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent asm_dir = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_fc_tx_pause:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pause = 0;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent asm_dir = 1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_fc_rx_pause:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Rx Flow control is enabled and Tx Flow control is
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * disabled by software override. Since there really
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * isn't a way to advertise that we are capable of RX
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Pause ONLY, we will advertise that we support both
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * symmetric and asymmetric Rx PAUSE, as such we fall
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * through to the fc_full statement. Later, we will
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * disable the adapter's ability to send PAUSE frames.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent case ixgbe_fc_full:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent pause = 1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent asm_dir = 1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent break;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent default:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent "Flow control param set incorrectly\n");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = IXGBE_ERR_CONFIG;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent goto out;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_read_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (ret_val != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent goto out;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (pause)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (asm_dir)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ret_val = ixgbe_write_iosf_sb_reg_x550(hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* This device does not fully support AN. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent hw->fc.disable_fc_autoneg = TRUE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentout:
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ret_val;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_set_mux - Set mux for port 1 access with CS4227
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @state: set mux if 1, clear if 0
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentstatic void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 esdp;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!hw->bus.lan_id)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (state)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent esdp |= IXGBE_ESDP_SDP1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent else
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent esdp &= ~IXGBE_ESDP_SDP1;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_WRITE_FLUSH(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @mask: Mask to specify which semaphore to acquire
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Acquires the SWFW semaphore and sets the I2C MUX
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_acquire_swfw_sync_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_acquire_swfw_sync_X540(hw, mask);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (mask & IXGBE_GSSR_I2C_MASK)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_set_mux(hw, 1);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @mask: Mask to specify which semaphore to release
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Releases the SWFW semaphore and sets the I2C MUX
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghentvoid ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_release_swfw_sync_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (mask & IXGBE_GSSR_I2C_MASK)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_set_mux(hw, 0);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_release_swfw_sync_X540(hw, mask);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Handle external Base T PHY interrupt. If high temperature
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * failure alarm then return error, else if link status change
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * then setup internal/external PHY link
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * failure alarm, else return PHY access status.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool lsc;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (lsc)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_setup_internal_phy(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @speed: new link speed
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @autoneg_wait_to_complete: TRUE when waiting for completion is needed
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Setup internal/external PHY link speed based on link speed, then set
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * external PHY auto advertised link speed.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Returns error status for any failure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_link_speed speed,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool autoneg_wait_to_complete)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_link_speed force_speed;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_setup_mac_link_t_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Setup internal/external PHY link speed to iXFI (10G), unless
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * only 1G is auto advertised then setup KX link.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (speed & IXGBE_LINK_SPEED_10GB_FULL)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent force_speed = IXGBE_LINK_SPEED_10GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent else
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent force_speed = IXGBE_LINK_SPEED_1GB_FULL;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If internal link mode is XFI, then setup XFI internal link. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_setup_ixfi_x550em(hw, &force_speed);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent }
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_check_link_t_X550em - Determine link and speed status
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @speed: pointer to link speed
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @link_up: TRUE when link is up
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @link_up_wait_to_complete: bool used to wait for link up or not
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Check that both the MAC and X557 external PHY have link.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent bool *link_up, bool link_up_wait_to_complete)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 autoneg_status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_CONFIG;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_check_mac_link_generic(hw, speed, link_up,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent link_up_wait_to_complete);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If check link fails or MAC link is not up, then return */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS || !(*link_up))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* MAC link is up, so check external PHY link.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * Read this twice back to back to indicate current status.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &autoneg_status);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent &autoneg_status);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* If external PHY link is not up, then indicate link not up */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent *link_up = FALSE;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent s32 status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent status = ixgbe_reset_phy_generic(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (status != IXGBE_SUCCESS)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return status;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* Configure Link Status Alarm and Temperature Threshold interrupts */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return ixgbe_enable_lasi_ext_t_x550em(hw);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_led_on_t_X550em - Turns on the software controllable LEDs.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @led_idx: led number to turn on
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 phy_data;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_led_on_t_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_PARAM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* To turn on the LED, set mode to ON. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent/**
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * ixgbe_led_off_t_X550em - Turns off the software controllable LEDs.
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @hw: pointer to hardware structure
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent * @led_idx: led number to turn off
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent **/
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghents32 ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent{
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent u16 phy_data;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent DEBUGFUNC("ixgbe_led_off_t_X550em");
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_ERR_PARAM;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent /* To turn on the LED, set mode to ON. */
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent return IXGBE_SUCCESS;
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent}
dc0cb1cda72a989d92d813e487cdff59f629aa3fDale Ghent