75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/******************************************************************************
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi Copyright (c) 2001-2015, Intel Corporation
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi All rights reserved.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi Redistribution and use in source and binary forms, with or without
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi modification, are permitted provided that the following conditions are met:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi 1. Redistributions of source code must retain the above copyright notice,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi this list of conditions and the following disclaimer.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi 2. Redistributions in binary form must reproduce the above copyright
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi notice, this list of conditions and the following disclaimer in the
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi documentation and/or other materials provided with the distribution.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi 3. Neither the name of the Intel Corporation nor the names of its
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi contributors may be used to endorse or promote products derived from
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi this software without specific prior written permission.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi POSSIBILITY OF SUCH DAMAGE.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi******************************************************************************/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/*$FreeBSD$*/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * 82575EB Gigabit Network Connection
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * 82575EB Gigabit Backplane Connection
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * 82575GB Gigabit Network Connection
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * 82576 Gigabit Network Connection
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * 82576 Quad Port Gigabit Mezzanine Adapter
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * 82580 Gigabit Network Connection
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * I350 Gigabit Network Connection
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi#include "e1000_api.h"
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi#include "e1000_i210.h"
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_init_phy_params_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_init_mac_params_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_acquire_phy_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_release_phy_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_acquire_nvm_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_release_nvm_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_check_for_link_82575(struct e1000_hw *hw);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchistatic s32 e1000_check_for_link_media_swap(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_cfg_done_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 *duplex);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 *data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_reset_hw_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_reset_hw_82580(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_read_phy_reg_82580(struct e1000_hw *hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 offset, u16 *data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_write_phy_reg_82580(struct e1000_hw *hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 offset, u16 data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bool active);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bool active);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bool active);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_setup_copper_link_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_media_type_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 offset, u16 data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 *speed, u16 *duplex);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_phy_id_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic bool e1000_sgmii_active_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_reset_init_script_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_read_mac_addr_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_config_collision_dist_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_power_up_serdes_link_82575(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 offset);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 offset);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_clear_vfta_i350(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_i2c_start(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_i2c_stop(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_clock_in_i2c_byte(struct e1000_hw *hw, u8 *data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_clock_out_i2c_byte(struct e1000_hw *hw, u8 data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_i2c_ack(struct e1000_hw *hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_clock_in_i2c_bit(struct e1000_hw *hw, bool *data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_clock_out_i2c_bit(struct e1000_hw *hw, bool data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic bool e1000_get_i2c_data(u32 *i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic const u16 e1000_82580_rxpbs_table[] = {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi 36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi#define E1000_82580_RXPBS_TABLE_SIZE \
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi (sizeof(e1000_82580_rxpbs_table) / \
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi sizeof(e1000_82580_rxpbs_table[0]))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Called to determine if the I2C pins are being used for I2C or as an
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * external MDIO interface since the two options are mutually exclusive.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic bool e1000_sgmii_uses_mdio_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 reg = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bool ext_mdio = FALSE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_sgmii_uses_mdio_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (hw->mac.type) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_82575:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_82576:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg = E1000_READ_REG(hw, E1000_MDIC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ext_mdio = !!(reg & E1000_MDIC_DEST);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_82580:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i350:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case e1000_i354:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i210:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i211:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg = E1000_READ_REG(hw, E1000_MDICNFG);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ext_mdio;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_init_phy_params_82575 - Init PHY func ptrs.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_phy_info *phy = &hw->phy;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 ctrl_ext;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_init_phy_params_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.read_i2c_byte = e1000_read_i2c_byte_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.write_i2c_byte = e1000_write_i2c_byte_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->phy.media_type != e1000_media_type_copper) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->type = e1000_phy_none;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.power_up = e1000_power_up_phy_copper;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.power_down = e1000_power_down_phy_copper_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->reset_delay_us = 100;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.acquire = e1000_acquire_phy_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.check_reset_block = e1000_check_reset_block_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.commit = e1000_phy_sw_reset_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.get_cfg_done = e1000_get_cfg_done_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.release = e1000_release_phy_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (e1000_sgmii_active_82575(hw)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.reset = e1000_phy_hw_reset_sgmii_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext |= E1000_CTRL_I2C_ENA;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.reset = e1000_phy_hw_reset_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext &= ~E1000_CTRL_I2C_ENA;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_reset_mdicnfg_82580(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (e1000_sgmii_active_82575(hw) && !e1000_sgmii_uses_mdio_82575(hw)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (hw->mac.type) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_82580:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i350:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case e1000_i354:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.read_reg = e1000_read_phy_reg_82580;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.write_reg = e1000_write_phy_reg_82580;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i210:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i211:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.read_reg = e1000_read_phy_reg_gs40g;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.write_reg = e1000_write_phy_reg_gs40g;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.read_reg = e1000_read_phy_reg_igp;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.write_reg = e1000_write_phy_reg_igp;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Set phy->phy_addr and phy->id. */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_get_phy_id_82575(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Verify phy id and set remaining function pointers */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (phy->id) {
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case M88E1543_E_PHY_ID:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case M88E1512_E_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case I347AT4_E_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case M88E1112_E_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case M88E1340M_E_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case M88E1111_I_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->type = e1000_phy_m88;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.check_polarity = e1000_check_polarity_m88;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.get_info = e1000_get_phy_info_m88;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (phy->id == I347AT4_E_PHY_ID ||
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi phy->id == M88E1112_E_PHY_ID ||
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi phy->id == M88E1340M_E_PHY_ID)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.get_cable_length =
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_get_cable_length_m88_gen2;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi else if (phy->id == M88E1543_E_PHY_ID ||
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi phy->id == M88E1512_E_PHY_ID)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi phy->ops.get_cable_length =
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi e1000_get_cable_length_m88_gen2;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.get_cable_length = e1000_get_cable_length_m88;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi /* Check if this PHY is confgured for media swap. */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (phy->id == M88E1112_E_PHY_ID) {
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi u16 data;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw,
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi E1000_M88E1112_PAGE_ADDR,
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi 2);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.read_reg(hw,
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi E1000_M88E1112_MAC_CTRL_1,
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi &data);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi data = (data & E1000_M88E1112_MAC_CTRL_1_MODE_MASK) >>
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (data == E1000_M88E1112_AUTO_COPPER_SGMII ||
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi data == E1000_M88E1112_AUTO_COPPER_BASEX)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi hw->mac.ops.check_for_link =
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi e1000_check_for_link_media_swap;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi }
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (phy->id == M88E1512_E_PHY_ID) {
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = e1000_initialize_M88E1512_phy(hw);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi }
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (phy->id == M88E1543_E_PHY_ID) {
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = e1000_initialize_M88E1543_phy(hw);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case IGP03E1000_E_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case IGP04E1000_E_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->type = e1000_phy_igp_3;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.check_polarity = e1000_check_polarity_igp;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.get_info = e1000_get_phy_info_igp;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.get_cable_length = e1000_get_cable_length_igp_2;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case I82580_I_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case I350_I_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->type = e1000_phy_82580;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.check_polarity = e1000_check_polarity_82577;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.force_speed_duplex =
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_phy_force_speed_duplex_82577;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.get_cable_length = e1000_get_cable_length_82577;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.get_info = e1000_get_phy_info_82577;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case I210_I_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->type = e1000_phy_i210;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.check_polarity = e1000_check_polarity_m88;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.get_info = e1000_get_phy_info_m88;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = -E1000_ERR_PHY;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_init_nvm_params_82575 - Init NVM func ptrs.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchis32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 eecd = E1000_READ_REG(hw, E1000_EECD);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 size;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_init_nvm_params_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_EECD_SIZE_EX_SHIFT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Added to a constant, "size" becomes the left-shift value
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * for setting word_size.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi size += NVM_WORD_SIZE_BASE_SHIFT;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Just in case size is out of range, cap it to the largest
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * EEPROM size supported
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (size > 15)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi size = 15;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->word_size = 1 << size;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.type < e1000_i210) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->opcode_bits = 8;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->delay_usec = 1;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (nvm->override) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_nvm_override_spi_large:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->page_size = 32;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->address_bits = 16;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_nvm_override_spi_small:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->page_size = 8;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->address_bits = 8;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ?
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi 16 : 8;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (nvm->word_size == (1 << 15))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->page_size = 128;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->type = e1000_nvm_eeprom_spi;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->type = e1000_nvm_flash_hw;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Function Pointers */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.acquire = e1000_acquire_nvm_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.release = e1000_release_nvm_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (nvm->word_size < (1 << 15))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.read = e1000_read_nvm_eerd;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.read = e1000_read_nvm_spi;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.write = e1000_write_nvm_spi;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.validate = e1000_validate_nvm_checksum_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.update = e1000_update_nvm_checksum_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.valid_led_default = e1000_valid_led_default_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* override generic family function pointers for specific descendants */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (hw->mac.type) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_82580:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.validate = e1000_validate_nvm_checksum_82580;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.update = e1000_update_nvm_checksum_82580;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i350:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case e1000_i354:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.validate = e1000_validate_nvm_checksum_i350;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm->ops.update = e1000_update_nvm_checksum_i350;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_init_mac_params_82575 - Init MAC func ptrs.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_mac_info *mac = &hw->mac;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_init_mac_params_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Derives media type */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_get_media_type_82575(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Set mta register count */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->mta_reg_count = 128;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Set uta register count */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->uta_reg_count = (hw->mac.type == e1000_82575) ? 0 : 128;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Set rar entry count */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (mac->type == e1000_82576)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (mac->type == e1000_82580)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (mac->type == e1000_i350 || mac->type == e1000_i354)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore /* Disable EEE default settings for EEE supported devices */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (mac->type >= e1000_i350)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dev_spec->eee_disable = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Allow a single clear of the SW semaphore on I210 and newer */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (mac->type >= e1000_i210)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dev_spec->clear_semaphore_once = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Set if part includes ASF firmware */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->asf_firmware_present = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* FWSM register */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->has_fwsm = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* ARC supported; valid only if manageability features are enabled. */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->arc_subsystem_valid =
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi !!(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Function pointers */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* bus type/speed/width */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* reset */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (mac->type >= e1000_82580)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.reset_hw = e1000_reset_hw_82580;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.reset_hw = e1000_reset_hw_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* hw initialization */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if ((mac->type == e1000_i210) || (mac->type == e1000_i211))
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi mac->ops.init_hw = e1000_init_hw_i210;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.init_hw = e1000_init_hw_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* link setup */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.setup_link = e1000_setup_link_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* physical interface link setup */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.setup_physical_interface =
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi (hw->phy.media_type == e1000_media_type_copper)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ? e1000_setup_copper_link_82575 : e1000_setup_serdes_link_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* physical interface shutdown */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.shutdown_serdes = e1000_shutdown_serdes_link_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* physical interface power up */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.power_up_serdes = e1000_power_up_serdes_link_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* check for link */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.check_for_link = e1000_check_for_link_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* read mac address */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* configure collision distance */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.config_collision_dist = e1000_config_collision_dist_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* multicast address update */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (hw->mac.type == e1000_i350 || mac->type == e1000_i354) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* writing VFTA */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.write_vfta = e1000_write_vfta_i350;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* clearing VFTA */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.clear_vfta = e1000_clear_vfta_i350;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* writing VFTA */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.write_vfta = e1000_write_vfta_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* clearing VFTA */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.clear_vfta = e1000_clear_vfta_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.type >= e1000_82580)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.validate_mdi_setting =
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_validate_mdi_setting_crossover_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* ID LED init */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.id_led_init = e1000_id_led_init_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* blink LED */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.blink_led = e1000_blink_led_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* setup LED */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.setup_led = e1000_setup_led_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* cleanup LED */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.cleanup_led = e1000_cleanup_led_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* turn on/off LED */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.led_on = e1000_led_on_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.led_off = e1000_led_off_generic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* clear hardware counters */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* link info */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.get_link_up_info = e1000_get_link_up_info_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* acquire SW_FW sync */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.release_swfw_sync = e1000_release_swfw_sync_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (mac->type >= e1000_i210) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_i210;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.release_swfw_sync = e1000_release_swfw_sync_i210;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* set lan id for port to determine which phy lock to use */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->mac.ops.set_lan_id(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_init_function_pointers_82575 - Init func ptrs.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Called to initialize all function pointers and parameters.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchivoid e1000_init_function_pointers_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_init_function_pointers_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->mac.ops.init_params = e1000_init_mac_params_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->nvm.ops.init_params = e1000_init_nvm_params_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.ops.init_params = e1000_init_phy_params_82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->mbx.ops.init_params = e1000_init_mbx_params_pf;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_acquire_phy_82575 - Acquire rights to access PHY
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Acquire access rights to the correct PHY.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 mask = E1000_SWFW_PHY0_SM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_acquire_phy_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->bus.func == E1000_FUNC_1)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mask = E1000_SWFW_PHY1_SM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else if (hw->bus.func == E1000_FUNC_2)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mask = E1000_SWFW_PHY2_SM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else if (hw->bus.func == E1000_FUNC_3)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mask = E1000_SWFW_PHY3_SM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return hw->mac.ops.acquire_swfw_sync(hw, mask);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_release_phy_82575 - Release rights to access PHY
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * A wrapper to release access rights to the correct PHY.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_release_phy_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 mask = E1000_SWFW_PHY0_SM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_release_phy_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->bus.func == E1000_FUNC_1)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mask = E1000_SWFW_PHY1_SM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else if (hw->bus.func == E1000_FUNC_2)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mask = E1000_SWFW_PHY2_SM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else if (hw->bus.func == E1000_FUNC_3)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mask = E1000_SWFW_PHY3_SM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->mac.ops.release_swfw_sync(hw, mask);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_read_phy_reg_sgmii_82575 - Read PHY register using sgmii
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @offset: register offset to be read
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: pointer to the read data
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Reads the PHY register at offset using the serial gigabit media independent
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * interface and stores the retrieved information in data.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 *data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = -E1000_ERR_PARAM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_read_phy_reg_sgmii_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT1("PHY Address %u is out of range\n", offset);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->phy.ops.acquire(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_read_phy_reg_i2c(hw, offset, data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.ops.release(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_write_phy_reg_sgmii_82575 - Write PHY register using sgmii
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @offset: register offset to write to
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: data to write at register offset
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Writes the data to PHY register at the offset using the serial gigabit
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * media independent interface.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = -E1000_ERR_PARAM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_write_phy_reg_sgmii_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT1("PHY Address %d is out of range\n", offset);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->phy.ops.acquire(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_write_phy_reg_i2c(hw, offset, data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.ops.release(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_get_phy_id_82575 - Retrieve PHY addr and id
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Retrieves the PHY address and ID for both PHY's which do and do not use
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * sgmi interface.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_phy_id_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_phy_info *phy = &hw->phy;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 phy_id;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 ctrl_ext;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 mdic;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_get_phy_id_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore /* some i354 devices need an extra read for phy id */
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (hw->mac.type == e1000_i354)
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore e1000_get_phy_id(hw);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * For SGMII PHYs, we try the list of possible addresses until
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * we find one that works. For non-SGMII PHYs
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * (e.g. integrated copper PHYs), an address of 1 should
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * work. The result of this function should mean phy->phy_addr
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * and phy->id are set correctly.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!e1000_sgmii_active_82575(hw)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->addr = 1;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_get_phy_id(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (e1000_sgmii_uses_mdio_82575(hw)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (hw->mac.type) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_82575:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_82576:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mdic = E1000_READ_REG(hw, E1000_MDIC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mdic &= E1000_MDIC_PHY_MASK;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->addr = mdic >> E1000_MDIC_PHY_SHIFT;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_82580:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i350:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case e1000_i354:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i210:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i211:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mdic = E1000_READ_REG(hw, E1000_MDICNFG);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mdic &= E1000_MDICNFG_PHY_MASK;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = -E1000_ERR_PHY;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_get_phy_id(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Power on sgmii phy if it is disabled */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay(300);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * The address field in the I2CCMD register is 3 bits and 0 is invalid.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Therefore, we need to test 1-7
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (phy->addr = 1; phy->addr < 8; phy->addr++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val == E1000_SUCCESS) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT2("Vendor ID 0x%08X read at address %u\n",
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy_id, phy->addr);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * At the time of this writing, The M88 part is
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * the only supported SGMII PHY product.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (phy_id == M88_VENDOR)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT1("PHY address %u was unreadable\n",
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->addr);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* A valid PHY type couldn't be found. */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (phy->addr == 8) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phy->addr = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = -E1000_ERR_PHY;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_get_phy_id(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* restore previous sfp cage power state */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_phy_hw_reset_sgmii_82575 - Performs a PHY reset
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Resets the PHY using the serial gigabit media independent interface.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi struct e1000_phy_info *phy = &hw->phy;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * This isn't a TRUE "hard" reset, but is the only reset
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * available to us at this time.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Soft resetting SGMII attached PHY...\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(hw->phy.ops.write_reg))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * SFP documentation requires the following to configure the SPF module
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * to work on SGMII. No further documentation is given.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->phy.ops.write_reg(hw, 0x1B, 0x8084);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->phy.ops.commit(hw);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (phy->id == M88E1512_E_PHY_ID)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = e1000_initialize_M88E1512_phy(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_set_d0_lplu_state_82575 - Set Low Power Linkup D0 state
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @active: TRUE to enable LPLU, FALSE to disable
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Sets the LPLU D0 state according to the active flag. When
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * activating LPLU this function also disables smart speed
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * and vice versa. LPLU will not be activated unless the
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * device autonegotiation advertisement meets standards of
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * either 10 or 10/100 or 10/100/1000 at all duplexes.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * This is a function pointer entry point only called by
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * PHY setup routines.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_phy_info *phy = &hw->phy;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_set_d0_lplu_state_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(hw->phy.ops.read_reg))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (active) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data |= IGP02E1000_PM_D0_LPLU;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* When LPLU is enabled, we should disable SmartSpeed */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi &data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data &= ~IGP01E1000_PSCFR_SMART_SPEED;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data &= ~IGP02E1000_PM_D0_LPLU;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * LPLU and SmartSpeed are mutually exclusive. LPLU is used
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * during Dx states where the power conservation is most
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * important. During driver activity we should enable
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * SmartSpeed, so performance is maintained.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (phy->smart_speed == e1000_smart_speed_on) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = phy->ops.read_reg(hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi IGP01E1000_PHY_PORT_CONFIG,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi &data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data |= IGP01E1000_PSCFR_SMART_SPEED;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = phy->ops.write_reg(hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi IGP01E1000_PHY_PORT_CONFIG,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else if (phy->smart_speed == e1000_smart_speed_off) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = phy->ops.read_reg(hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi IGP01E1000_PHY_PORT_CONFIG,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi &data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data &= ~IGP01E1000_PSCFR_SMART_SPEED;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = phy->ops.write_reg(hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi IGP01E1000_PHY_PORT_CONFIG,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_set_d0_lplu_state_82580 - Set Low Power Linkup D0 state
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @active: TRUE to enable LPLU, FALSE to disable
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Sets the LPLU D0 state according to the active flag. When
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * activating LPLU this function also disables smart speed
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * and vice versa. LPLU will not be activated unless the
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * device autonegotiation advertisement meets standards of
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * either 10 or 10/100 or 10/100/1000 at all duplexes.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * This is a function pointer entry point only called by
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * PHY setup routines.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_phy_info *phy = &hw->phy;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_set_d0_lplu_state_82580");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (active) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data |= E1000_82580_PM_D0_LPLU;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* When LPLU is enabled, we should disable SmartSpeed */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data &= ~E1000_82580_PM_SPD;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data &= ~E1000_82580_PM_D0_LPLU;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * LPLU and SmartSpeed are mutually exclusive. LPLU is used
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * during Dx states where the power conservation is most
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * important. During driver activity we should enable
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * SmartSpeed, so performance is maintained.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (phy->smart_speed == e1000_smart_speed_on)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data |= E1000_82580_PM_SPD;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else if (phy->smart_speed == e1000_smart_speed_off)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data &= ~E1000_82580_PM_SPD;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_set_d3_lplu_state_82580 - Sets low power link up state for D3
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @active: boolean used to enable/disable lplu
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Success returns 0, Failure returns 1
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * The low power link up (lplu) state is set to the power management level D3
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * and SmartSpeed is disabled when active is TRUE, else clear lplu for D3
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * is used during Dx states where the power conservation is most important.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * During driver activity, SmartSpeed should be enabled so performance is
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * maintained.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchis32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_phy_info *phy = &hw->phy;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_set_d3_lplu_state_82580");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!active) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data &= ~E1000_82580_PM_D3_LPLU;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * LPLU and SmartSpeed are mutually exclusive. LPLU is used
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * during Dx states where the power conservation is most
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * important. During driver activity we should enable
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * SmartSpeed, so performance is maintained.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (phy->smart_speed == e1000_smart_speed_on)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data |= E1000_82580_PM_SPD;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else if (phy->smart_speed == e1000_smart_speed_off)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data &= ~E1000_82580_PM_SPD;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data |= E1000_82580_PM_D3_LPLU;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* When LPLU is enabled, we should disable SmartSpeed */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data &= ~E1000_82580_PM_SPD;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_acquire_nvm_82575 - Request for access to EEPROM
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Acquire the necessary semaphores for exclusive access to the EEPROM.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Set the EEPROM access request bit and wait for EEPROM access grant bit.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Return successful if access grant bit set, else clear the request for
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * EEPROM access and return -E1000_ERR_NVM (-1).
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_acquire_nvm_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Check if there is some access
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * error this access may hook on
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.type == e1000_i350) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 eecd = E1000_READ_REG(hw, E1000_EECD);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (eecd & (E1000_EECD_BLOCKED | E1000_EECD_ABORT |
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_EECD_TIMEOUT)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Clear all access error flags */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd |
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_EECD_ERROR_CLR);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Nvm bit banging access error detected and cleared.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.type == e1000_82580) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 eecd = E1000_READ_REG(hw, E1000_EECD);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (eecd & E1000_EECD_BLOCKED) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Clear access error flag */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd |
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_EECD_BLOCKED);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Nvm bit banging access error detected and cleared.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_acquire_nvm_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_release_nvm_82575 - Release exclusive access to EEPROM
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Stop any current commands to the EEPROM and clear the EEPROM request bit,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * then release the semaphores acquired.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_release_nvm_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_release_nvm_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_release_nvm_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_acquire_swfw_sync_82575 - Acquire SW/FW semaphore
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @mask: specifies which semaphore to acquire
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Acquire the SW/FW semaphore to access the PHY or NVM. The mask
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * will also specify which port we're acquiring the lock for.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 swfw_sync;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 swmask = mask;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 fwmask = mask << 16;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi s32 i = 0, timeout = 200;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_acquire_swfw_sync_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi while (i < timeout) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (e1000_get_hw_semaphore_generic(hw)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = -E1000_ERR_SWFW_SYNC;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(swfw_sync & (fwmask | swmask)))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Firmware currently using resource (fwmask)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * or other software thread using resource (swmask)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_put_hw_semaphore_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay_irq(5);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi i++;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (i == timeout) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = -E1000_ERR_SWFW_SYNC;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi swfw_sync |= swmask;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_put_hw_semaphore_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_release_swfw_sync_82575 - Release SW/FW semaphore
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @mask: specifies which semaphore to acquire
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Release the SW/FW semaphore used to access the PHY or NVM. The mask
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * will also specify which port we're releasing the lock for.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 swfw_sync;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_release_swfw_sync_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ; /* Empty */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi swfw_sync &= ~mask;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_put_hw_semaphore_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_get_cfg_done_82575 - Read config done bit
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Read the management control register for the config done bit for
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * completion status. NOTE: silicon which is EEPROM-less will fail trying
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * to read the config done bit, so an error is *ONLY* logged and returns
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * would not be able to be reset or change link.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 timeout = PHY_CFG_TIMEOUT;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 mask = E1000_NVM_CFG_DONE_PORT_0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_get_cfg_done_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->bus.func == E1000_FUNC_1)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mask = E1000_NVM_CFG_DONE_PORT_1;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else if (hw->bus.func == E1000_FUNC_2)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mask = E1000_NVM_CFG_DONE_PORT_2;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else if (hw->bus.func == E1000_FUNC_3)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mask = E1000_NVM_CFG_DONE_PORT_3;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi while (timeout) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay(1);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi timeout--;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!timeout)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("MNG configuration cycle has not completed.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* If EEPROM is not marked present, init the PHY manually */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) &&
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi (hw->phy.type == e1000_phy_igp_3))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_phy_init_script_igp3(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_get_link_up_info_82575 - Get link speed/duplex info
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @speed: stores the current speed
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @duplex: stores the current duplex
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * This is a wrapper function, if using the serial gigabit media independent
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * interface, use PCS to retrieve the link speed and duplex information.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Otherwise, use the generic function to get the link speed and duplex info.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 *duplex)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_get_link_up_info_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->phy.media_type != e1000_media_type_copper)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, speed,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi duplex);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi duplex);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_check_for_link_82575 - Check for link
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * If sgmii is enabled, then use the pcs register to determine link, otherwise
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * use the generic interface for determining link.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_check_for_link_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 speed, duplex;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_check_for_link_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->phy.media_type != e1000_media_type_copper) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi &duplex);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Use this flag to determine if link needs to be checked or
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * not. If we have link clear the flag so that we do not
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * continue to check for link.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->mac.get_link_status = !hw->mac.serdes_has_link;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Configure Flow Control now that Auto-Neg has completed.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * First, we need to restore the desired flow control
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * settings because we may have had to re-autoneg with a
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * different link partner.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_config_fc_after_link_up_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Error configuring flow control\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_check_for_copper_link_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi/**
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * e1000_check_for_link_media_swap - Check which M88E1112 interface linked
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * @hw: pointer to the HW structure
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi *
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * Poll the M88E1112 interfaces to see which interface achieved link.
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchistatic s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi{
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi struct e1000_phy_info *phy = &hw->phy;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi s32 ret_val;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi u16 data;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi u8 port = 0;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi DEBUGFUNC("e1000_check_for_link_media_swap");
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* Check for copper. */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return ret_val;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return ret_val;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (data & E1000_M88E1112_STATUS_LINK)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi port = E1000_MEDIA_PORT_COPPER;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* Check for other. */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 1);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return ret_val;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return ret_val;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (data & E1000_M88E1112_STATUS_LINK)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi port = E1000_MEDIA_PORT_OTHER;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi /* Determine if a swap needs to happen. */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (port && (hw->dev_spec._82575.media_port != port)) {
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi hw->dev_spec._82575.media_port = port;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi hw->dev_spec._82575.media_changed = TRUE;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi }
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (port == E1000_MEDIA_PORT_COPPER) {
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* reset page to 0 */
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi return ret_val;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi e1000_check_for_link_82575(hw);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi } else {
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi e1000_check_for_link_82575(hw);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* reset page to 0 */
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi return ret_val;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi }
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return E1000_SUCCESS;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi}
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_power_up_serdes_link_82575 - Power up the serdes link after shutdown
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_power_up_serdes_link_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 reg;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_power_up_serdes_link_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi !e1000_sgmii_active_82575(hw))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Enable PCS to turn on link */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg |= E1000_PCS_CFG_PCS_EN;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Power up the laser */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg &= ~E1000_CTRL_EXT_SDP3_DATA;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* flush the write to verify completion */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay(1);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @speed: stores the current speed
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @duplex: stores the current duplex
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Using the physical coding sub-layer (PCS), retrieve the current speed and
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * duplex, then store the values in the pointers provided.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 *speed, u16 *duplex)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_mac_info *mac = &hw->mac;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 pcs;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore u32 status;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Read the PCS Status register for link state. For non-copper mode,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * the status register is not accurate. The PCS status register is
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * used instead.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * The link up bit determines when link is up on autoneg.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (pcs & E1000_PCS_LSTS_LINK_OK) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->serdes_has_link = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Detect and store PCS speed */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (pcs & E1000_PCS_LSTS_SPEED_1000)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *speed = SPEED_1000;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else if (pcs & E1000_PCS_LSTS_SPEED_100)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *speed = SPEED_100;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *speed = SPEED_10;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Detect and store PCS duplex */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (pcs & E1000_PCS_LSTS_DUPLEX_FULL)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *duplex = FULL_DUPLEX;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *duplex = HALF_DUPLEX;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore /* Check if it is an I354 2.5Gb backplane connection. */
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (mac->type == e1000_i354) {
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore status = E1000_READ_REG(hw, E1000_STATUS);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if ((status & E1000_STATUS_2P5_SKU) &&
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore !(status & E1000_STATUS_2P5_SKU_OVER)) {
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore *speed = SPEED_2500;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore *duplex = FULL_DUPLEX;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore DEBUGOUT("2500 Mbs, ");
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore DEBUGOUT("Full Duplex\n");
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore }
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore }
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->serdes_has_link = FALSE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *speed = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *duplex = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_shutdown_serdes_link_82575 - Remove link during power down
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * In the case of serdes shut down sfp and PCS on driver unload
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * when management pass thru is not enabled.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchivoid e1000_shutdown_serdes_link_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 reg;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_shutdown_serdes_link_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi !e1000_sgmii_active_82575(hw))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!e1000_enable_mng_pass_thru(hw)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Disable PCS to turn off link */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg &= ~E1000_PCS_CFG_PCS_EN;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* shutdown the laser */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg |= E1000_CTRL_EXT_SDP3_DATA;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* flush the write to verify completion */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay(1);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_reset_hw_82575 - Reset hardware
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * This resets the hardware into a known state.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_reset_hw_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 ctrl;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_reset_hw_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Prevent the PCI-E bus from sticking if there is no TLP connection
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * on the last TLP read/write transaction when MAC is reset.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_disable_pcie_master_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("PCI-E Master disable polling has failed.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* set the completion timeout for interface */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_set_pcie_completion_timeout(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("PCI-E Set completion timeout has failed.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Masking off all interrupts\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_RCTL, 0);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay(10);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl = E1000_READ_REG(hw, E1000_CTRL);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Issuing a global reset to MAC\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_get_auto_rd_done_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * When auto config read does not complete, do not
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * return with an error. This can happen in situations
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * where there is no eeprom and prevents getting link.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Auto Read Done did not complete\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* If EEPROM is not present, run manual init scripts */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_reset_init_script_82575(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Clear any pending interrupt events. */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ICR);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Install any alternate MAC address into RAR0 */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_check_alt_mac_addr_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_init_hw_82575 - Initialize hardware
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * This inits the hardware readying it for operation.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchis32 e1000_init_hw_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_mac_info *mac = &hw->mac;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 i, rar_count = mac->rar_entry_count;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_init_hw_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Initialize identification LED */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = mac->ops.id_led_init(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Error initializing identification LED\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* This is not fatal and we should not stop init due to this */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Disabling VLAN filtering */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Initializing the IEEE VLAN\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mac->ops.clear_vfta(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Setup the receive address */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_init_rx_addrs_generic(hw, rar_count);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Zero out the Multicast HASH table */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Zeroing the MTA\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = 0; i < mac->mta_reg_count; i++)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Zero out the Unicast HASH table */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Zeroing the UTA\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = 0; i < mac->uta_reg_count; i++)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG_ARRAY(hw, E1000_UTA, i, 0);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Setup link and flow control */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = mac->ops.setup_link(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Set the default MTU size */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->dev_spec._82575.mtu = 1500;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Clear all of the statistics registers (clear on read). It is
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * important that we do this after we have tried to establish link
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * because the symbol error count will increment wildly if there
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * is no link.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_clear_hw_cntrs_82575(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_setup_copper_link_82575 - Configure copper link settings
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Configures the link for auto-neg or forced speed and duplex. Then we check
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * for link, once link is established calls to configure collision distance
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * and flow control are called.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 ctrl;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 phpm_reg;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_setup_copper_link_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl = E1000_READ_REG(hw, E1000_CTRL);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl |= E1000_CTRL_SLU;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore /* Clear Go Link Disconnect bit on supported devices */
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore switch (hw->mac.type) {
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case e1000_82580:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case e1000_i350:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case e1000_i210:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case e1000_i211:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phpm_reg = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi phpm_reg &= ~E1000_82580_PM_GO_LINKD;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, phpm_reg);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore break;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore default:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_setup_serdes_link_82575(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (e1000_sgmii_active_82575(hw)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* allow time for SFP cage time to power up phy */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay(300);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->phy.ops.reset(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Error resetting the PHY.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (hw->phy.type) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_phy_i210:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_phy_m88:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (hw->phy.id) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case I347AT4_E_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case M88E1112_E_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case M88E1340M_E_PHY_ID:
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi case M88E1543_E_PHY_ID:
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi case M88E1512_E_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case I210_I_PHY_ID:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_copper_link_setup_m88_gen2(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_copper_link_setup_m88(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_phy_igp_3:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_copper_link_setup_igp(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_phy_82580:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_copper_link_setup_82577(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = -E1000_ERR_PHY;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_setup_copper_link_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_setup_serdes_link_82575 - Setup link for serdes
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Configure the physical coding sub-layer (PCS) link. The PCS link is
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * used on copper connections where the serialized gigabit media independent
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * interface (sgmii), or serdes fiber is being used. Configures the link
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * for auto-negotiation or forces speed/duplex.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 ctrl_ext, ctrl_reg, reg, anadv_reg;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bool pcs_autoneg;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_setup_serdes_link_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi !e1000_sgmii_active_82575(hw))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * On the 82575, SerDes loopback mode persists until it is
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * explicitly turned off or a power cycle is performed. A read to
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * the register does not indicate its status. Therefore, we ensure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * loopback mode is disabled during initialization.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* power on the sfp cage if present */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_reg = E1000_READ_REG(hw, E1000_CTRL);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_reg |= E1000_CTRL_SLU;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* set both sw defined pins on 82575/82576*/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg = E1000_READ_REG(hw, E1000_PCS_LCTL);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* default pcs_autoneg to the same setting as mac autoneg */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi pcs_autoneg = hw->mac.autoneg;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case E1000_CTRL_EXT_LINK_MODE_SGMII:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* sgmii mode lets the phy handle forcing speed/duplex */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi pcs_autoneg = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* autoneg time out should be disabled for SGMII mode */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* disable PCS autoneg and support parallel detect only */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi pcs_autoneg = FALSE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* fall through to default case */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.type == e1000_82575 ||
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->mac.type == e1000_82576) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("NVM Read Error\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (data & E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi pcs_autoneg = FALSE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * non-SGMII modes only supports a speed of 1000/Full for the
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * link so it is best to just force the MAC and let the pcs
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * link either autoneg or be forced to 1000/Full
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_CTRL_FD | E1000_CTRL_FRCDPX;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* set speed of 1000/Full if speed/duplex is forced */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, ctrl_reg);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * New SerDes mode allows for forcing speed or autonegotiating speed
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * at 1gb. Autoneg should be default set by most drivers. This is the
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * mode that will be compatible with older link partners and switches.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * However, both are supported by the hardware and some drivers/tools.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (pcs_autoneg) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Set PCS register for autoneg */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Disable force flow control for autoneg */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg &= ~E1000_PCS_LCTL_FORCE_FCTRL;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Configure flow control advertisement for autoneg */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi anadv_reg = E1000_READ_REG(hw, E1000_PCS_ANADV);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi anadv_reg &= ~(E1000_TXCW_ASM_DIR | E1000_TXCW_PAUSE);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (hw->fc.requested_mode) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_fc_full:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_fc_rx_pause:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi anadv_reg |= E1000_TXCW_ASM_DIR;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi anadv_reg |= E1000_TXCW_PAUSE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_fc_tx_pause:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi anadv_reg |= E1000_TXCW_ASM_DIR;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_PCS_ANADV, anadv_reg);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT1("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Set PCS register for forced link */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg |= E1000_PCS_LCTL_FSD; /* Force Speed */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Force flow control for forced link */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi reg |= E1000_PCS_LCTL_FORCE_FCTRL;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT1("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!pcs_autoneg && !e1000_sgmii_active_82575(hw))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_force_mac_fc_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_get_media_type_82575 - derives current media type.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * The media type is chosen reflecting few settings.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * The following are taken into account:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * - link mode set in the current port Init Control Word #3
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * - current link mode settings in CSR register
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * - MDIO vs. I2C PHY control interface chosen
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * - SFP module media type
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_media_type_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 ctrl_ext = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 link_mode = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Set internal phy as default */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dev_spec->sgmii_active = FALSE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dev_spec->module_plugged = FALSE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Get CSR setting */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* extract link mode setting */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (link_mode) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.media_type = e1000_media_type_internal_serdes;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case E1000_CTRL_EXT_LINK_MODE_GMII:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.media_type = e1000_media_type_copper;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case E1000_CTRL_EXT_LINK_MODE_SGMII:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Get phy control interface type set (MDIO vs. I2C)*/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (e1000_sgmii_uses_mdio_82575(hw)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.media_type = e1000_media_type_copper;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dev_spec->sgmii_active = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* fall through for I2C based SGMII */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* read media type from SFP EEPROM */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_set_sfp_media_type_82575(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if ((ret_val != E1000_SUCCESS) ||
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi (hw->phy.media_type == e1000_media_type_unknown)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * If media type was not identified then return media
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * type defined by the CTRL_EXT settings.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.media_type = e1000_media_type_internal_serdes;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (link_mode == E1000_CTRL_EXT_LINK_MODE_SGMII) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.media_type = e1000_media_type_copper;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dev_spec->sgmii_active = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* do not change link mode for 100BaseFX */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (dev_spec->eth_flags.e100_base_fx)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* change current link mode setting */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->phy.media_type == e1000_media_type_copper)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_SGMII;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_set_sfp_media_type_82575 - derives SFP module media type.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * The media type is chosen based on SFP module.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * compatibility flags retrieved from SFP ID EEPROM.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_ERR_CONFIG;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 ctrl_ext = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct sfp_e1000_flags *eth_flags = &dev_spec->eth_flags;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u8 tranceiver_type = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 timeout = 3;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Turn I2C interface ON and power on sfp cage */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_I2C_ENA);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Read SFP module data */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi while (timeout) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_read_sfp_data_byte(hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET),
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi &tranceiver_type);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val == E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay(100);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi timeout--;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_read_sfp_data_byte(hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET),
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi (u8 *)eth_flags);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Check if there is some SFP module plugged and powered */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) ||
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi (tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dev_spec->module_plugged = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.media_type = e1000_media_type_internal_serdes;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else if (eth_flags->e100_base_fx) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dev_spec->sgmii_active = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.media_type = e1000_media_type_internal_serdes;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else if (eth_flags->e1000_base_t) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dev_spec->sgmii_active = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.media_type = e1000_media_type_copper;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.media_type = e1000_media_type_unknown;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("PHY module has not been recognized\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.media_type = e1000_media_type_unknown;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Restore I2C interface setting */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_valid_led_default_82575 - Verify a valid default LED config
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: pointer to the NVM (EEPROM)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Read the EEPROM for the current default LED configuration. If the
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * LED configuration is not valid, set to a valid LED configuration.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_valid_led_default_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("NVM Read Error\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (hw->phy.media_type) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_media_type_internal_serdes:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *data = ID_LED_DEFAULT_82575_SERDES;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_media_type_copper:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *data = ID_LED_DEFAULT;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_sgmii_active_82575 - Return sgmii state
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * 82575 silicon has a serialized gigabit media independent interface (sgmii)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * which can be enabled for use in the embedded applications. Simply
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * return the current state of the sgmii interface.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic bool e1000_sgmii_active_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return dev_spec->sgmii_active;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_reset_init_script_82575 - Inits HW defaults after reset
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Inits recommended HW defaults after a reset when there is no EEPROM
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * detected. This is only for the 82575.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_reset_init_script_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_reset_init_script_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.type == e1000_82575) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Running reset init script for 82575\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* SerDes configuration via SERDESCTRL */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x00, 0x0C);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x01, 0x78);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x1B, 0x23);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x23, 0x15);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* CCM configuration via CCMCTL register */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x14, 0x00);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x10, 0x00);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* PCIe lanes configuration */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x00, 0xEC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x61, 0xDF);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x34, 0x05);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x2F, 0x81);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* PCIe PLL Configuration */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x02, 0x47);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x14, 0x00);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x10, 0x00);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_read_mac_addr_82575 - Read device MAC address
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_read_mac_addr_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_read_mac_addr_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * If there's an alternate MAC address place it in RAR0
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * so that it will override the Si installed default perm
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * address.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_check_alt_mac_addr_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_read_mac_addr_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_config_collision_dist_82575 - Configure collision distance
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Configures the collision distance to the default value and is used
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * during link setup.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_config_collision_dist_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 tctl_ext;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_config_collision_dist_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi tctl_ext = E1000_READ_REG(hw, E1000_TCTL_EXT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi tctl_ext &= ~E1000_TCTL_EXT_COLD;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi tctl_ext |= E1000_COLLISION_DISTANCE << E1000_TCTL_EXT_COLD_SHIFT;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_TCTL_EXT, tctl_ext);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_power_down_phy_copper_82575 - Remove link during PHY power down
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * In the case of a PHY power down to save power, or to turn off link during a
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * driver unload, or wake on lan is not enabled, remove the link.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi struct e1000_phy_info *phy = &hw->phy;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(phy->ops.check_reset_block))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* If the management interface is not enabled, then power down */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(e1000_enable_mng_pass_thru(hw) || phy->ops.check_reset_block(hw)))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_power_down_phy_copper(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_clear_hw_cntrs_82575 - Clear device specific hardware counters
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Clears the hardware counters by reading the counter registers.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_clear_hw_cntrs_82575");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_clear_hw_cntrs_base_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PRC64);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PRC127);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PRC255);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PRC511);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PRC1023);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PRC1522);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PTC64);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PTC127);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PTC255);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PTC511);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PTC1023);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_PTC1522);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ALGNERRC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_RXERRC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_TNCRS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_CEXTERR);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_TSCTC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_TSCTFC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_MGTPRC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_MGTPDC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_MGTPTC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_IAC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ICRXOC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ICRXPTC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ICRXATC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ICTXPTC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ICTXATC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ICTXQEC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ICTXQMTC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ICRXDMTC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_CBTMPC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_HTDPMC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_CBRMPC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_RPTHC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_HGPTC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_HTCBDPC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_HGORCL);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_HGORCH);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_HGOTCL);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_HGOTCH);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_LENERRS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* This register should not be read in copper configurations */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if ((hw->phy.media_type == e1000_media_type_internal_serdes) ||
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_sgmii_active_82575(hw))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_SCVPC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_rx_fifo_flush_82575 - Clean rx fifo after Rx enable
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi * After Rx enable, if manageability is enabled then there is likely some
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * bad data at the start of the fifo and possibly in the DMA fifo. This
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * function clears the fifos and flushes any packets that came in as rx was
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * being enabled.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchivoid e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi int i, ms_wait;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi DEBUGFUNC("e1000_rx_fifo_flush_82575");
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* disable IPv6 options as per hardware errata */
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi rfctl = E1000_READ_REG(hw, E1000_RFCTL);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi rfctl |= E1000_RFCTL_IPV6_EX_DIS;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.type != e1000_82575 ||
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi !(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Disable all Rx queues */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = 0; i < 4; i++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i));
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_RXDCTL(i),
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Poll all queues to verify they have shut down */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (ms_wait = 0; ms_wait < 10; ms_wait++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay(1);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi rx_enabled = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = 0; i < 4; i++)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi rx_enabled |= E1000_READ_REG(hw, E1000_RXDCTL(i));
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ms_wait == 10)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Queue disable timed out after 10ms\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * incoming packets are rejected. Set enable and wait 2ms so that
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * any packet that was coming in as RCTL.EN was set is flushed
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi rlpml = E1000_READ_REG(hw, E1000_RLPML);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_RLPML, 0);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi rctl = E1000_READ_REG(hw, E1000_RCTL);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi temp_rctl |= E1000_RCTL_LPE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl | E1000_RCTL_EN);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay(2);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Enable Rx queues that were previously enabled and restore our
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * previous state
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = 0; i < 4; i++)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl[i]);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_RCTL, rctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_RLPML, rlpml);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Flush receive errors generated by workaround */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ROC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_RNBC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_MPC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_set_pcie_completion_timeout - set pci-e completion timeout
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * The defaults for 82575 and 82576 should be in the range of 50us to 50ms,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * however the hardware default for these parts is 500us to 1ms which is less
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * than the 10ms recommended by the pci-e spec. To address this we need to
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * increase the value to either 10ms to 200ms for capability version 1 config,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * or 16ms to 55ms for version 2.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 gcr = E1000_READ_REG(hw, E1000_GCR);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 pcie_devctl2;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* only take action if timeout value is defaulted to 0 */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (gcr & E1000_GCR_CMPL_TMOUT_MASK)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * if capababilities version is type 1 we can write the
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * timeout of 10ms to 200ms through the GCR register
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(gcr & E1000_GCR_CAP_VER2)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi gcr |= E1000_GCR_CMPL_TMOUT_10ms;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * for version 2 capabilities we need to write the config space
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * directly in order to set the completion timeout value for
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * 16ms to 55ms
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi &pcie_devctl2);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi &pcie_devctl2);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* disable completion timeout resend */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_GCR, gcr);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_vmdq_set_anti_spoofing_pf - enable or disable anti-spoofing
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the hardware struct
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @enable: state to enter, either enabled or disabled
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @pf: Physical Function pool - do not set anti-spoofing for the PF
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * enables/disables L2 switch anti-spoofing functionality.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchivoid e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore u32 reg_val, reg_offset;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (hw->mac.type) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_82576:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore reg_offset = E1000_DTXSWC;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i350:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case e1000_i354:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore reg_offset = E1000_TXSWC;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore default:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore return;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore }
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore reg_val = E1000_READ_REG(hw, reg_offset);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (enable) {
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore reg_val |= (E1000_DTXSWC_MAC_SPOOF_MASK |
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi E1000_DTXSWC_VLAN_SPOOF_MASK);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore /* The PF can spoof - it has to in order to
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore * support emulation mode NICs
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore */
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore } else {
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore reg_val &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi E1000_DTXSWC_VLAN_SPOOF_MASK);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore E1000_WRITE_REG(hw, reg_offset, reg_val);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the hardware struct
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @enable: state to enter, either enabled or disabled
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * enables/disables L2 switch loopback functionality.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchivoid e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 dtxswc;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi switch (hw->mac.type) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_82576:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (enable)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi case e1000_i350:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore case e1000_i354:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dtxswc = E1000_READ_REG(hw, E1000_TXSWC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (enable)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_TXSWC, dtxswc);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi default:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Currently no other hardware supports loopback */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_vmdq_set_replication_pf - enable or disable vmdq replication
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the hardware struct
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @enable: state to enter, either enabled or disabled
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * enables/disables replication of packets across multiple pools.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchivoid e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 vt_ctl = E1000_READ_REG(hw, E1000_VT_CTL);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (enable)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi vt_ctl |= E1000_VT_CTL_VM_REPL_EN;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi vt_ctl &= ~E1000_VT_CTL_VM_REPL_EN;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_VT_CTL, vt_ctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_read_phy_reg_82580 - Read 82580 MDI control register
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @offset: register offset to be read
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: pointer to the read data
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Reads the MDI control register in the PHY at offset and stores the
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * information read to data.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_read_phy_reg_82580");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->phy.ops.acquire(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_read_phy_reg_mdic(hw, offset, data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.ops.release(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_write_phy_reg_82580 - Write 82580 MDI control register
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @offset: register offset to write to
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: data to write to register at offset
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Writes data to MDI control register in the PHY at offset.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_write_phy_reg_82580");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->phy.ops.acquire(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_write_phy_reg_mdic(hw, offset, data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->phy.ops.release(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_reset_mdicnfg_82580 - Reset MDICNFG destination and com_mdio bits
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
ea4c6b78cebe2a3687fa43deeedf6212a124d817Robert Mustacchi * This resets the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * the values found in the EEPROM. This addresses an issue in which these
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * bits are not restored from EEPROM after reset.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 mdicnfg;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 nvm_data = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_reset_mdicnfg_82580");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.type != e1000_82580)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!e1000_sgmii_active_82575(hw))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi &nvm_data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("NVM Read Error\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mdicnfg = E1000_READ_REG(hw, E1000_MDICNFG);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (nvm_data & NVM_WORD24_EXT_MDIO)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mdicnfg |= E1000_MDICNFG_EXT_MDIO;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (nvm_data & NVM_WORD24_COM_MDIO)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi mdicnfg |= E1000_MDICNFG_COM_MDIO;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_MDICNFG, mdicnfg);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_reset_hw_82580 - Reset hardware
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * This resets function or entire device (all ports, etc.)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * to a known state.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_reset_hw_82580(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* BH SW mailbox bit in SW_FW_SYNC */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 swmbsw_mask = E1000_SW_SYNCH_MB;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 ctrl;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bool global_device_reset = hw->dev_spec._82575.global_device_reset;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_reset_hw_82580");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->dev_spec._82575.global_device_reset = FALSE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* 82580 does not reliably do global_device_reset due to hw errata */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.type == e1000_82580)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi global_device_reset = FALSE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Get current control state. */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl = E1000_READ_REG(hw, E1000_CTRL);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Prevent the PCI-E bus from sticking if there is no TLP connection
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * on the last TLP read/write transaction when MAC is reset.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_disable_pcie_master_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("PCI-E Master disable polling has failed.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Masking off all interrupts\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_RCTL, 0);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay(10);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Determine whether or not a global dev reset is requested */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (global_device_reset && hw->mac.ops.acquire_swfw_sync(hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi swmbsw_mask))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi global_device_reset = FALSE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (global_device_reset && !(E1000_READ_REG(hw, E1000_STATUS) &
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_STAT_DEV_RST_SET))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl |= E1000_CTRL_DEV_RST;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl |= E1000_CTRL_RST;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi switch (hw->device_id) {
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi case E1000_DEV_ID_DH89XXCC_SGMII:
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi break;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi default:
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi E1000_WRITE_FLUSH(hw);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi break;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi }
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi /* Add delay to insure DEV_RST or RST has time to complete */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi msec_delay(5);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_get_auto_rd_done_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /*
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * When auto config read does not complete, do not
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * return with an error. This can happen in situations
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * where there is no eeprom and prevents getting link.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Auto Read Done did not complete\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* clear global device reset status bit */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_STATUS, E1000_STAT_DEV_RST_SET);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Clear any pending interrupt events. */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_ICR);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_reset_mdicnfg_82580(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("Could not reset MDICNFG based on EEPROM\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Install any alternate MAC address into RAR0 */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_check_alt_mac_addr_generic(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Release semaphore */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (global_device_reset)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->mac.ops.release_swfw_sync(hw, swmbsw_mask);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_rxpbs_adjust_82580 - adjust RXPBS value to reflect actual Rx PBA size
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: data received by reading RXPBS register
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * The 82580 uses a table based approach for packet buffer allocation sizes.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * This function converts the retrieved value into the correct table value
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * 0x0 36 72 144 1 2 4 8 16
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * 0x8 35 70 140 rsv rsv rsv rsv rsv
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiu16 e1000_rxpbs_adjust_82580(u32 data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 ret_val = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (data < E1000_82580_RXPBS_TABLE_SIZE)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_82580_rxpbs_table[data];
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_validate_nvm_checksum_with_offset - Validate EEPROM
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * checksum
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @offset: offset in words of the checksum protected region
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * and then verifies that the sum of the EEPROM is equal to 0xBABA.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchis32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 checksum = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 i, nvm_data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_validate_nvm_checksum_with_offset");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = offset; i < ((NVM_CHECKSUM_REG + offset) + 1); i++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("NVM Read Error\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi checksum += nvm_data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (checksum != (u16) NVM_SUM) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("NVM Checksum Invalid\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = -E1000_ERR_NVM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_update_nvm_checksum_with_offset - Update EEPROM
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * checksum
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @offset: offset in words of the checksum protected region
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Updates the EEPROM checksum by reading/adding each word of the EEPROM
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * up to the checksum. Then calculates the EEPROM checksum and writes the
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * value to the EEPROM.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchis32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 checksum = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 i, nvm_data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_update_nvm_checksum_with_offset");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = offset; i < (NVM_CHECKSUM_REG + offset); i++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("NVM Read Error while updating checksum.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi checksum += nvm_data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi checksum = (u16) NVM_SUM - checksum;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->nvm.ops.write(hw, (NVM_CHECKSUM_REG + offset), 1,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi &checksum);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("NVM Write Error while updating checksum.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_validate_nvm_checksum_82580 - Validate EEPROM checksum
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Calculates the EEPROM section checksum by reading/adding each word of
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * the EEPROM and then verifies that the sum of the EEPROM is
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * equal to 0xBABA.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 eeprom_regions_count = 1;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 j, nvm_data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 nvm_offset;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_validate_nvm_checksum_82580");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("NVM Read Error\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (nvm_data & NVM_COMPATIBILITY_BIT_MASK) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* if chekcsums compatibility bit is set validate checksums
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * for all 4 ports. */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi eeprom_regions_count = 4;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (j = 0; j < eeprom_regions_count; j++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_validate_nvm_checksum_with_offset(hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm_offset);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_update_nvm_checksum_82580 - Update EEPROM checksum
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Updates the EEPROM section checksums for all 4 ports by reading/adding
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * each word of the EEPROM up to the checksum. Then calculates the EEPROM
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * checksum and writes the value to the EEPROM.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 j, nvm_data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 nvm_offset;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_update_nvm_checksum_82580");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("NVM Read Error while updating checksum compatibility bit.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(nvm_data & NVM_COMPATIBILITY_BIT_MASK)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* set compatibility bit to validate checksums appropriately */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi &nvm_data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("NVM Write Error while updating checksum compatibility bit.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (j = 0; j < 4; j++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_update_nvm_checksum_with_offset(hw, nvm_offset);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_validate_nvm_checksum_i350 - Validate EEPROM checksum
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Calculates the EEPROM section checksum by reading/adding each word of
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * the EEPROM and then verifies that the sum of the EEPROM is
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * equal to 0xBABA.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 j;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 nvm_offset;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_validate_nvm_checksum_i350");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (j = 0; j < 4; j++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_validate_nvm_checksum_with_offset(hw,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm_offset);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_update_nvm_checksum_i350 - Update EEPROM checksum
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Updates the EEPROM section checksums for all 4 ports by reading/adding
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * each word of the EEPROM up to the checksum. Then calculates the EEPROM
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * checksum and writes the value to the EEPROM.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 j;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 nvm_offset;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_update_nvm_checksum_i350");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (j = 0; j < 4; j++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ret_val = e1000_update_nvm_checksum_with_offset(hw, nvm_offset);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ret_val != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi/**
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * __e1000_access_emi_reg - Read/write EMI register
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * @hw: pointer to the HW structure
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * @addr: EMI address to program
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * @data: pointer to value to read/write from/to the EMI address
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * @read: boolean flag to indicate read or write
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi **/
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchistatic s32 __e1000_access_emi_reg(struct e1000_hw *hw, u16 address,
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi u16 *data, bool read)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi{
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi s32 ret_val;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi DEBUGFUNC("__e1000_access_emi_reg");
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, E1000_EMIADD, address);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return ret_val;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (read)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, E1000_EMIDATA, data);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi else
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, E1000_EMIDATA, *data);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return ret_val;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi}
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi/**
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * e1000_read_emi_reg - Read Extended Management Interface register
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * @hw: pointer to the HW structure
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * @addr: EMI address to program
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * @data: value to be read from the EMI address
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi **/
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchis32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi{
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi DEBUGFUNC("e1000_read_emi_reg");
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return __e1000_access_emi_reg(hw, addr, data, TRUE);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi}
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi/**
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * e1000_initialize_M88E1512_phy - Initialize M88E1512 PHY
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi * @hw: pointer to the HW structure
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi *
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi * Initialize Marvell 1512 to work correctly with Avoton.
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi **/
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchis32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi{
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi struct e1000_phy_info *phy = &hw->phy;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi s32 ret_val = E1000_SUCCESS;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi DEBUGFUNC("e1000_initialize_M88E1512_phy");
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi /* Check if this is correct PHY. */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (phy->id != M88E1512_E_PHY_ID)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi /* Switch to PHY page 0xFF. */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xCC0C);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi /* Switch to PHY page 0xFB. */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0x000D);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi /* Switch to PHY page 0x12. */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi /* Change mode to SGMII-to-Copper */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi /* Return the PHY to page 0. */
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi ret_val = phy->ops.commit(hw);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi if (ret_val) {
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi DEBUGOUT("Error committing the PHY changes\n");
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return ret_val;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi }
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi msec_delay(1000);
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchiout:
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return ret_val;
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi}
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi/**
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi * e1000_initialize_M88E1543_phy - Initialize M88E1543 PHY
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi * @hw: pointer to the HW structure
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi *
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi * Initialize Marvell 1543 to work correctly with Avoton.
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi **/
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchis32 e1000_initialize_M88E1543_phy(struct e1000_hw *hw)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi{
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi struct e1000_phy_info *phy = &hw->phy;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi s32 ret_val = E1000_SUCCESS;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi DEBUGFUNC("e1000_initialize_M88E1543_phy");
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* Check if this is correct PHY. */
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (phy->id != M88E1543_E_PHY_ID)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* Switch to PHY page 0xFF. */
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xDC0C);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* Switch to PHY page 0xFB. */
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0xC00D);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* Switch to PHY page 0x12. */
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* Change mode to SGMII-to-Copper */
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* Switch to PHY page 1. */
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x1);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* Change mode to 1000BASE-X/SGMII and autoneg enable; reset */
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1543_FIBER_CTRL, 0x9140);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi /* Return the PHY to page 0. */
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi goto out;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ret_val = phy->ops.commit(hw);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (ret_val) {
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi DEBUGOUT("Error committing the PHY changes\n");
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi return ret_val;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi }
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi msec_delay(1000);
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchiout:
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi return ret_val;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi}
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_set_eee_i350 - Enable/disable EEE support
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi * @adv1g: boolean flag enabling 1G EEE advertisement
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi * @adv100m: boolean flag enabling 100M EEE advertisement
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Enable/disable EEE based on setting in dev_spec structure.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchis32 e1000_set_eee_i350(struct e1000_hw *hw, bool adv1G, bool adv100M)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 ipcnfg, eeer;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_set_eee_i350");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if ((hw->mac.type < e1000_i350) ||
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi (hw->phy.media_type != e1000_media_type_copper))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ipcnfg = E1000_READ_REG(hw, E1000_IPCNFG);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi eeer = E1000_READ_REG(hw, E1000_EEER);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* enable or disable per user setting */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(hw->dev_spec._82575.eee_disable)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 eee_su = E1000_READ_REG(hw, E1000_EEE_SU);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (adv100M)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ipcnfg |= E1000_IPCNFG_EEE_100M_AN;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi else
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ipcnfg &= ~E1000_IPCNFG_EEE_100M_AN;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (adv1G)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ipcnfg |= E1000_IPCNFG_EEE_1G_AN;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi else
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi ipcnfg &= ~E1000_IPCNFG_EEE_1G_AN;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_EEER_LPI_FC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* This bit should not be set in normal operation. */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (eee_su & E1000_EEE_SU_LPI_CLK_STP)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("LPI Clock Stop Bit should not be set!\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_EEER_LPI_FC);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_IPCNFG, ipcnfg);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_EEER, eeer);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_IPCNFG);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_READ_REG(hw, E1000_EEER);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiout:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi return E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore/**
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore * e1000_set_eee_i354 - Enable/disable EEE support
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore * @hw: pointer to the HW structure
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi * @adv1g: boolean flag enabling 1G EEE advertisement
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi * @adv100m: boolean flag enabling 100M EEE advertisement
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore *
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore * Enable/disable EEE legacy mode based on setting in dev_spec structure.
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore *
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore **/
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchis32 e1000_set_eee_i354(struct e1000_hw *hw, bool adv1G, bool adv100M)
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore{
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore struct e1000_phy_info *phy = &hw->phy;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore s32 ret_val = E1000_SUCCESS;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore u16 phy_data;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore DEBUGFUNC("e1000_set_eee_i354");
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if ((hw->phy.media_type != e1000_media_type_copper) ||
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore ((phy->id != M88E1543_E_PHY_ID) &&
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore (phy->id != M88E1512_E_PHY_ID)))
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore goto out;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (!hw->dev_spec._82575.eee_disable) {
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore /* Switch to PHY page 18. */
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 18);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (ret_val)
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore goto out;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore ret_val = phy->ops.read_reg(hw, E1000_M88E1543_EEE_CTRL_1,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore &phy_data);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (ret_val)
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore goto out;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore phy_data |= E1000_M88E1543_EEE_CTRL_1_MS;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore ret_val = phy->ops.write_reg(hw, E1000_M88E1543_EEE_CTRL_1,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore phy_data);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (ret_val)
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore goto out;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore /* Return the PHY to page 0. */
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (ret_val)
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore goto out;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore /* Turn on EEE advertisement. */
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore E1000_EEE_ADV_DEV_I354,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore &phy_data);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (ret_val)
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi goto out;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (adv100M)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi phy_data |= E1000_EEE_ADV_100_SUPPORTED;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi else
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi phy_data &= ~E1000_EEE_ADV_100_SUPPORTED;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi if (adv1G)
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi phy_data |= E1000_EEE_ADV_1000_SUPPORTED;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi else
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi phy_data &= ~E1000_EEE_ADV_1000_SUPPORTED;
49b7860084dbba18bc00b29413d6182197f9fe93Robert Mustacchi
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore E1000_EEE_ADV_DEV_I354,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore phy_data);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore } else {
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore /* Turn off EEE advertisement. */
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore E1000_EEE_ADV_DEV_I354,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore &phy_data);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (ret_val)
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore goto out;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore phy_data &= ~(E1000_EEE_ADV_100_SUPPORTED |
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore E1000_EEE_ADV_1000_SUPPORTED);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore E1000_EEE_ADV_DEV_I354,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore phy_data);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore }
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amoreout:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore return ret_val;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore}
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore/**
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore * e1000_get_eee_status_i354 - Get EEE status
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore * @hw: pointer to the HW structure
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore * @status: EEE status
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore *
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore * Get EEE status by guessing based on whether Tx or Rx LPI indications have
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore * been received.
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore **/
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amores32 e1000_get_eee_status_i354(struct e1000_hw *hw, bool *status)
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore{
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore struct e1000_phy_info *phy = &hw->phy;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore s32 ret_val = E1000_SUCCESS;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore u16 phy_data;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore DEBUGFUNC("e1000_get_eee_status_i354");
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore /* Check if EEE is supported on this device. */
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if ((hw->phy.media_type != e1000_media_type_copper) ||
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore ((phy->id != M88E1543_E_PHY_ID) &&
c124a83e09115de88ecccd4f689983f42a1d53bdRobert Mustacchi (phy->id != M88E1512_E_PHY_ID)))
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore goto out;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore ret_val = e1000_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore E1000_PCS_STATUS_DEV_I354,
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore &phy_data);
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore if (ret_val)
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore goto out;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore *status = phy_data & (E1000_PCS_STATUS_TX_LPI_RCVD |
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore E1000_PCS_STATUS_RX_LPI_RCVD) ? TRUE : FALSE;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amoreout:
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore return ret_val;
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore}
13485e69b5429e6c7d27301fb3c0deee0e93768aGarrett D'Amore
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/* Due to a hw errata, if the host tries to configure the VFTA register
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * while performing queries from the BMC or DMA, then the VFTA in some
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * cases won't be written.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_clear_vfta_i350 - Clear VLAN filter table
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Clears the register array which contains the VLAN filter table by
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * setting all the values to 0.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchivoid e1000_clear_vfta_i350(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 offset;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi int i;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_clear_vfta_350");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = 0; i < 10; i++)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_write_vfta_i350 - Write value to VLAN filter table
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @offset: register offset in VLAN filter table
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @value: register value written to VLAN filter table
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Writes value at the given offset in the register array which stores
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * the VLAN filter table.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchivoid e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi int i;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_write_vfta_350");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = 0; i < 10; i++)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_set_i2c_bb - Enable I2C bit-bang
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to the HW structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Enable I2C bit-bang interface
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchis32 e1000_set_i2c_bb(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 ret_val = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 ctrl_ext, i2cparams;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_set_i2c_bb");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ctrl_ext |= E1000_CTRL_I2C_ENA;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi i2cparams = E1000_READ_REG(hw, E1000_I2CPARAMS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi i2cparams |= E1000_I2CBB_EN;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi i2cparams |= E1000_I2C_DATA_OE_N;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi i2cparams |= E1000_I2C_CLK_OE_N;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cparams);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return ret_val;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_read_i2c_byte_generic - Reads 8 bit word over I2C
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @byte_offset: byte offset to read
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @dev_addr: device address
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: value read
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Performs byte read operation over I2C interface at
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * a specified device address.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchis32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u8 dev_addr, u8 *data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 status = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 max_retry = 10;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 retry = 1;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 swfw_mask = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bool nack = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_read_i2c_byte_generic");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi swfw_mask = E1000_SWFW_PHY0_SM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi do {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi != E1000_SUCCESS) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = E1000_ERR_SWFW_SYNC;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto read_byte_out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_i2c_start(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Device Address and write indication */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_clock_out_i2c_byte(hw, dev_addr);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_get_i2c_ack(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_clock_out_i2c_byte(hw, byte_offset);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_get_i2c_ack(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_i2c_start(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Device Address and read indication */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_clock_out_i2c_byte(hw, (dev_addr | 0x1));
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_get_i2c_ack(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_clock_in_i2c_byte(hw, data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_clock_out_i2c_bit(hw, nack);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_i2c_stop(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchifail:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->mac.ops.release_swfw_sync(hw, swfw_mask);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi msec_delay(100);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_i2c_bus_clear(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi retry++;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (retry < max_retry)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("I2C byte read error - Retrying.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("I2C byte read error.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } while (retry < max_retry);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->mac.ops.release_swfw_sync(hw, swfw_mask);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiread_byte_out:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return status;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_write_i2c_byte_generic - Writes 8 bit word over I2C
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @byte_offset: byte offset to write
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @dev_addr: device address
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: value to write
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Performs byte write operation over I2C interface at
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * a specified device address.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchis32 e1000_write_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u8 dev_addr, u8 data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 status = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 max_retry = 1;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 retry = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u16 swfw_mask = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_write_i2c_byte_generic");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi swfw_mask = E1000_SWFW_PHY0_SM;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != E1000_SUCCESS) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = E1000_ERR_SWFW_SYNC;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto write_byte_out;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi do {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_i2c_start(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_clock_out_i2c_byte(hw, dev_addr);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_get_i2c_ack(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_clock_out_i2c_byte(hw, byte_offset);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_get_i2c_ack(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_clock_out_i2c_byte(hw, data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_get_i2c_ack(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi goto fail;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_i2c_stop(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchifail:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_i2c_bus_clear(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi retry++;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (retry < max_retry)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("I2C byte write error - Retrying.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("I2C byte write error.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } while (retry < max_retry);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi hw->mac.ops.release_swfw_sync(hw, swfw_mask);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchiwrite_byte_out:
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return status;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_i2c_start - Sets I2C start condition
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Sets I2C start condition (High -> Low on SDA while SCL is High)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_i2c_start(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_i2c_start");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Start condition must begin with data and clock high */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_set_i2c_data(hw, &i2cctl, 1);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_raise_i2c_clk(hw, &i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Setup time for start condition (4.7us) */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_SU_STA);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_set_i2c_data(hw, &i2cctl, 0);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Hold time for start condition (4us) */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_HD_STA);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_lower_i2c_clk(hw, &i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Minimum low period of clock is 4.7 us */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_LOW);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_i2c_stop - Sets I2C stop condition
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Sets I2C stop condition (Low -> High on SDA while SCL is High)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_i2c_stop(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_i2c_stop");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Stop condition must begin with data low and clock high */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_set_i2c_data(hw, &i2cctl, 0);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_raise_i2c_clk(hw, &i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Setup time for stop condition (4us) */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_SU_STO);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_set_i2c_data(hw, &i2cctl, 1);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* bus free time between stop and start (4.7us)*/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_BUF);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_clock_in_i2c_byte - Clocks in one byte via I2C
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: data byte to clock in
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Clocks in one byte data via I2C data/clock
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_clock_in_i2c_byte(struct e1000_hw *hw, u8 *data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 i;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bool bit = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_clock_in_i2c_byte");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *data = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = 7; i >= 0; i--) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_clock_in_i2c_bit(hw, &bit);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *data |= bit << i;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_clock_out_i2c_byte - Clocks out one byte via I2C
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: data byte clocked out
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Clocks out one byte data via I2C data/clock
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_clock_out_i2c_byte(struct e1000_hw *hw, u8 data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 status = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 i;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 i2cctl;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bool bit = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_clock_out_i2c_byte");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = 7; i >= 0; i--) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bit = (data >> i) & 0x1;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_clock_out_i2c_bit(hw, bit);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status != E1000_SUCCESS)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Release SDA line (set high) */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi i2cctl |= E1000_I2C_DATA_OE_N;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return status;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_get_i2c_ack - Polls for I2C ACK
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Clocks in/out one bit via I2C data/clock
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_get_i2c_ack(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 status = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 i = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 timeout = 10;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bool ack = TRUE;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_get_i2c_ack");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_raise_i2c_clk(hw, &i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Minimum high period of clock is 4us */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_HIGH);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Wait until SCL returns high */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = 0; i < timeout; i++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(1);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (i2cctl & E1000_I2C_CLK_IN)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi break;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (!(i2cctl & E1000_I2C_CLK_IN))
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return E1000_ERR_I2C;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi ack = e1000_get_i2c_data(&i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (ack) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT("I2C ack was not received.\n");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = E1000_ERR_I2C;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_lower_i2c_clk(hw, &i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Minimum low period of clock is 4.7 us */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_LOW);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return status;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: read data value
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Clocks in one bit via I2C data/clock
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_clock_in_i2c_bit(struct e1000_hw *hw, bool *data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_clock_in_i2c_bit");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_raise_i2c_clk(hw, &i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Minimum high period of clock is 4us */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_HIGH);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *data = e1000_get_i2c_data(&i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_lower_i2c_clk(hw, &i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Minimum low period of clock is 4.7 us */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_LOW);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: data value to write
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Clocks out one bit via I2C data/clock
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_clock_out_i2c_bit(struct e1000_hw *hw, bool data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 status;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_clock_out_i2c_bit");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = e1000_set_i2c_data(hw, &i2cctl, data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (status == E1000_SUCCESS) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_raise_i2c_clk(hw, &i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Minimum high period of clock is 4us */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_HIGH);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_lower_i2c_clk(hw, &i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Minimum low period of clock is 4.7 us.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * This also takes care of the data hold time.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_LOW);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi } else {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = E1000_ERR_I2C;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT1("I2C data was not set to %X\n", data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return status;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_raise_i2c_clk - Raises the I2C SCL clock
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @i2cctl: Current value of I2CCTL register
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Raises the I2C clock line '0'->'1'
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_raise_i2c_clk");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *i2cctl |= E1000_I2C_CLK_OUT;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *i2cctl &= ~E1000_I2C_CLK_OE_N;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* SCL rise time (1000ns) */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_RISE);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_lower_i2c_clk - Lowers the I2C SCL clock
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @i2cctl: Current value of I2CCTL register
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Lowers the I2C clock line '1'->'0'
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_lower_i2c_clk");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *i2cctl &= ~E1000_I2C_CLK_OUT;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *i2cctl &= ~E1000_I2C_CLK_OE_N;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* SCL fall time (300ns) */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_FALL);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_set_i2c_data - Sets the I2C data bit
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @i2cctl: Current value of I2CCTL register
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @data: I2C data value (0 or 1) to set
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Sets the I2C data bit
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi s32 status = E1000_SUCCESS;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_set_i2c_data");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (data)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *i2cctl |= E1000_I2C_DATA_OUT;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *i2cctl &= ~E1000_I2C_DATA_OUT;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *i2cctl &= ~E1000_I2C_DATA_OE_N;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *i2cctl |= E1000_I2C_CLK_OE_N;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi E1000_WRITE_FLUSH(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_RISE + E1000_I2C_T_FALL + E1000_I2C_T_SU_DATA);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (data != e1000_get_i2c_data(i2cctl)) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi status = E1000_ERR_I2C;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGOUT1("Error - I2C data was not set to %X.\n", data);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return status;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_get_i2c_data - Reads the I2C SDA data bit
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @i2cctl: Current value of I2CCTL register
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Returns the I2C data bit value
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchistatic bool e1000_get_i2c_data(u32 *i2cctl)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi bool data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_get_i2c_data");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi if (*i2cctl & E1000_I2C_DATA_IN)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data = 1;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi else
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi data = 0;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi return data;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi/**
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * e1000_i2c_bus_clear - Clears the I2C bus
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * @hw: pointer to hardware structure
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi *
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Clears the I2C bus by sending nine clock pulses.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi * Used when data line is stuck low.
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi **/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchivoid e1000_i2c_bus_clear(struct e1000_hw *hw)
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi{
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi u32 i;
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi DEBUGFUNC("e1000_i2c_bus_clear");
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_i2c_start(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_set_i2c_data(hw, &i2cctl, 1);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi for (i = 0; i < 9; i++) {
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_raise_i2c_clk(hw, &i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Min high period of clock is 4us */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_HIGH);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_lower_i2c_clk(hw, &i2cctl);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Min low period of clock is 4.7us*/
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi usec_delay(E1000_I2C_T_LOW);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi }
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_i2c_start(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi /* Put the i2c bus back to default state */
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi e1000_i2c_stop(hw);
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi}
75eba5b6d79ed4d2ce3daf7b2806306b6b69a938Robert Mustacchi