175eba5b6SRobert Mustacchi /******************************************************************************
275eba5b6SRobert Mustacchi 
349b78600SRobert Mustacchi   Copyright (c) 2001-2015, Intel Corporation
475eba5b6SRobert Mustacchi   All rights reserved.
575eba5b6SRobert Mustacchi 
675eba5b6SRobert Mustacchi   Redistribution and use in source and binary forms, with or without
775eba5b6SRobert Mustacchi   modification, are permitted provided that the following conditions are met:
875eba5b6SRobert Mustacchi 
975eba5b6SRobert Mustacchi    1. Redistributions of source code must retain the above copyright notice,
1075eba5b6SRobert Mustacchi       this list of conditions and the following disclaimer.
1175eba5b6SRobert Mustacchi 
1275eba5b6SRobert Mustacchi    2. Redistributions in binary form must reproduce the above copyright
1375eba5b6SRobert Mustacchi       notice, this list of conditions and the following disclaimer in the
1475eba5b6SRobert Mustacchi       documentation and/or other materials provided with the distribution.
1575eba5b6SRobert Mustacchi 
1675eba5b6SRobert Mustacchi    3. Neither the name of the Intel Corporation nor the names of its
1775eba5b6SRobert Mustacchi       contributors may be used to endorse or promote products derived from
1875eba5b6SRobert Mustacchi       this software without specific prior written permission.
1975eba5b6SRobert Mustacchi 
2075eba5b6SRobert Mustacchi   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2175eba5b6SRobert Mustacchi   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2275eba5b6SRobert Mustacchi   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2375eba5b6SRobert Mustacchi   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2475eba5b6SRobert Mustacchi   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2575eba5b6SRobert Mustacchi   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2675eba5b6SRobert Mustacchi   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2775eba5b6SRobert Mustacchi   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2875eba5b6SRobert Mustacchi   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2975eba5b6SRobert Mustacchi   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3075eba5b6SRobert Mustacchi   POSSIBILITY OF SUCH DAMAGE.
3175eba5b6SRobert Mustacchi 
3275eba5b6SRobert Mustacchi ******************************************************************************/
3375eba5b6SRobert Mustacchi /*$FreeBSD$*/
3475eba5b6SRobert Mustacchi 
3575eba5b6SRobert Mustacchi /*
3675eba5b6SRobert Mustacchi  * 82575EB Gigabit Network Connection
3775eba5b6SRobert Mustacchi  * 82575EB Gigabit Backplane Connection
3875eba5b6SRobert Mustacchi  * 82575GB Gigabit Network Connection
3975eba5b6SRobert Mustacchi  * 82576 Gigabit Network Connection
4075eba5b6SRobert Mustacchi  * 82576 Quad Port Gigabit Mezzanine Adapter
4175eba5b6SRobert Mustacchi  * 82580 Gigabit Network Connection
4275eba5b6SRobert Mustacchi  * I350 Gigabit Network Connection
4375eba5b6SRobert Mustacchi  */
4475eba5b6SRobert Mustacchi 
4575eba5b6SRobert Mustacchi #include "e1000_api.h"
4675eba5b6SRobert Mustacchi #include "e1000_i210.h"
4775eba5b6SRobert Mustacchi 
4875eba5b6SRobert Mustacchi static s32  e1000_init_phy_params_82575(struct e1000_hw *hw);
4975eba5b6SRobert Mustacchi static s32  e1000_init_mac_params_82575(struct e1000_hw *hw);
5075eba5b6SRobert Mustacchi static s32  e1000_acquire_phy_82575(struct e1000_hw *hw);
5175eba5b6SRobert Mustacchi static void e1000_release_phy_82575(struct e1000_hw *hw);
5275eba5b6SRobert Mustacchi static s32  e1000_acquire_nvm_82575(struct e1000_hw *hw);
5375eba5b6SRobert Mustacchi static void e1000_release_nvm_82575(struct e1000_hw *hw);
5475eba5b6SRobert Mustacchi static s32  e1000_check_for_link_82575(struct e1000_hw *hw);
55c124a83eSRobert Mustacchi static s32  e1000_check_for_link_media_swap(struct e1000_hw *hw);
5675eba5b6SRobert Mustacchi static s32  e1000_get_cfg_done_82575(struct e1000_hw *hw);
5775eba5b6SRobert Mustacchi static s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
5875eba5b6SRobert Mustacchi 					 u16 *duplex);
5975eba5b6SRobert Mustacchi static s32  e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
6075eba5b6SRobert Mustacchi static s32  e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
6175eba5b6SRobert Mustacchi 					   u16 *data);
6275eba5b6SRobert Mustacchi static s32  e1000_reset_hw_82575(struct e1000_hw *hw);
6375eba5b6SRobert Mustacchi static s32  e1000_reset_hw_82580(struct e1000_hw *hw);
6475eba5b6SRobert Mustacchi static s32  e1000_read_phy_reg_82580(struct e1000_hw *hw,
6575eba5b6SRobert Mustacchi 				     u32 offset, u16 *data);
6675eba5b6SRobert Mustacchi static s32  e1000_write_phy_reg_82580(struct e1000_hw *hw,
6775eba5b6SRobert Mustacchi 				      u32 offset, u16 data);
6875eba5b6SRobert Mustacchi static s32  e1000_set_d0_lplu_state_82580(struct e1000_hw *hw,
6975eba5b6SRobert Mustacchi 					  bool active);
7075eba5b6SRobert Mustacchi static s32  e1000_set_d3_lplu_state_82580(struct e1000_hw *hw,
7175eba5b6SRobert Mustacchi 					  bool active);
7275eba5b6SRobert Mustacchi static s32  e1000_set_d0_lplu_state_82575(struct e1000_hw *hw,
7375eba5b6SRobert Mustacchi 					  bool active);
7475eba5b6SRobert Mustacchi static s32  e1000_setup_copper_link_82575(struct e1000_hw *hw);
7575eba5b6SRobert Mustacchi static s32  e1000_setup_serdes_link_82575(struct e1000_hw *hw);
7675eba5b6SRobert Mustacchi static s32  e1000_get_media_type_82575(struct e1000_hw *hw);
7775eba5b6SRobert Mustacchi static s32  e1000_set_sfp_media_type_82575(struct e1000_hw *hw);
7875eba5b6SRobert Mustacchi static s32  e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data);
7975eba5b6SRobert Mustacchi static s32  e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
8075eba5b6SRobert Mustacchi 					    u32 offset, u16 data);
8175eba5b6SRobert Mustacchi static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
8275eba5b6SRobert Mustacchi static s32  e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
8375eba5b6SRobert Mustacchi static s32  e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
8475eba5b6SRobert Mustacchi 						 u16 *speed, u16 *duplex);
8575eba5b6SRobert Mustacchi static s32  e1000_get_phy_id_82575(struct e1000_hw *hw);
8675eba5b6SRobert Mustacchi static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
8775eba5b6SRobert Mustacchi static bool e1000_sgmii_active_82575(struct e1000_hw *hw);
8875eba5b6SRobert Mustacchi static s32  e1000_reset_init_script_82575(struct e1000_hw *hw);
8975eba5b6SRobert Mustacchi static s32  e1000_read_mac_addr_82575(struct e1000_hw *hw);
9075eba5b6SRobert Mustacchi static void e1000_config_collision_dist_82575(struct e1000_hw *hw);
9175eba5b6SRobert Mustacchi static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
9275eba5b6SRobert Mustacchi static void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw);
9375eba5b6SRobert Mustacchi static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw);
9475eba5b6SRobert Mustacchi static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw);
9575eba5b6SRobert Mustacchi static s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw);
9675eba5b6SRobert Mustacchi static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw);
9775eba5b6SRobert Mustacchi static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw);
9875eba5b6SRobert Mustacchi static s32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw,
9975eba5b6SRobert Mustacchi 						 u16 offset);
10075eba5b6SRobert Mustacchi static s32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw,
10175eba5b6SRobert Mustacchi 						   u16 offset);
10275eba5b6SRobert Mustacchi static s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw);
10375eba5b6SRobert Mustacchi static s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw);
10475eba5b6SRobert Mustacchi static void e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value);
10575eba5b6SRobert Mustacchi static void e1000_clear_vfta_i350(struct e1000_hw *hw);
10675eba5b6SRobert Mustacchi 
10775eba5b6SRobert Mustacchi static void e1000_i2c_start(struct e1000_hw *hw);
10875eba5b6SRobert Mustacchi static void e1000_i2c_stop(struct e1000_hw *hw);
10975eba5b6SRobert Mustacchi static s32 e1000_clock_in_i2c_byte(struct e1000_hw *hw, u8 *data);
11075eba5b6SRobert Mustacchi static s32 e1000_clock_out_i2c_byte(struct e1000_hw *hw, u8 data);
11175eba5b6SRobert Mustacchi static s32 e1000_get_i2c_ack(struct e1000_hw *hw);
11275eba5b6SRobert Mustacchi static s32 e1000_clock_in_i2c_bit(struct e1000_hw *hw, bool *data);
11375eba5b6SRobert Mustacchi static s32 e1000_clock_out_i2c_bit(struct e1000_hw *hw, bool data);
11475eba5b6SRobert Mustacchi static void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl);
11575eba5b6SRobert Mustacchi static void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl);
11675eba5b6SRobert Mustacchi static s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data);
11775eba5b6SRobert Mustacchi static bool e1000_get_i2c_data(u32 *i2cctl);
11875eba5b6SRobert Mustacchi 
11975eba5b6SRobert Mustacchi static const u16 e1000_82580_rxpbs_table[] = {
12075eba5b6SRobert Mustacchi 	36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
12175eba5b6SRobert Mustacchi #define E1000_82580_RXPBS_TABLE_SIZE \
122c124a83eSRobert Mustacchi 	(sizeof(e1000_82580_rxpbs_table) / \
123c124a83eSRobert Mustacchi 	 sizeof(e1000_82580_rxpbs_table[0]))
12475eba5b6SRobert Mustacchi 
12575eba5b6SRobert Mustacchi 
12675eba5b6SRobert Mustacchi /**
12775eba5b6SRobert Mustacchi  *  e1000_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO
12875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
12975eba5b6SRobert Mustacchi  *
13075eba5b6SRobert Mustacchi  *  Called to determine if the I2C pins are being used for I2C or as an
13175eba5b6SRobert Mustacchi  *  external MDIO interface since the two options are mutually exclusive.
13275eba5b6SRobert Mustacchi  **/
e1000_sgmii_uses_mdio_82575(struct e1000_hw * hw)13375eba5b6SRobert Mustacchi static bool e1000_sgmii_uses_mdio_82575(struct e1000_hw *hw)
13475eba5b6SRobert Mustacchi {
13575eba5b6SRobert Mustacchi 	u32 reg = 0;
13675eba5b6SRobert Mustacchi 	bool ext_mdio = FALSE;
13775eba5b6SRobert Mustacchi 
13875eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_sgmii_uses_mdio_82575");
13975eba5b6SRobert Mustacchi 
14075eba5b6SRobert Mustacchi 	switch (hw->mac.type) {
14175eba5b6SRobert Mustacchi 	case e1000_82575:
14275eba5b6SRobert Mustacchi 	case e1000_82576:
14375eba5b6SRobert Mustacchi 		reg = E1000_READ_REG(hw, E1000_MDIC);
14475eba5b6SRobert Mustacchi 		ext_mdio = !!(reg & E1000_MDIC_DEST);
14575eba5b6SRobert Mustacchi 		break;
14675eba5b6SRobert Mustacchi 	case e1000_82580:
14775eba5b6SRobert Mustacchi 	case e1000_i350:
14813485e69SGarrett D'Amore 	case e1000_i354:
14975eba5b6SRobert Mustacchi 	case e1000_i210:
15075eba5b6SRobert Mustacchi 	case e1000_i211:
15175eba5b6SRobert Mustacchi 		reg = E1000_READ_REG(hw, E1000_MDICNFG);
15275eba5b6SRobert Mustacchi 		ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO);
15375eba5b6SRobert Mustacchi 		break;
15475eba5b6SRobert Mustacchi 	default:
15575eba5b6SRobert Mustacchi 		break;
15675eba5b6SRobert Mustacchi 	}
15775eba5b6SRobert Mustacchi 	return ext_mdio;
15875eba5b6SRobert Mustacchi }
15975eba5b6SRobert Mustacchi 
16075eba5b6SRobert Mustacchi /**
16175eba5b6SRobert Mustacchi  *  e1000_init_phy_params_82575 - Init PHY func ptrs.
16275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
16375eba5b6SRobert Mustacchi  **/
e1000_init_phy_params_82575(struct e1000_hw * hw)16475eba5b6SRobert Mustacchi static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
16575eba5b6SRobert Mustacchi {
16675eba5b6SRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
16775eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
16875eba5b6SRobert Mustacchi 	u32 ctrl_ext;
16975eba5b6SRobert Mustacchi 
17075eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_phy_params_82575");
17175eba5b6SRobert Mustacchi 
17275eba5b6SRobert Mustacchi 	phy->ops.read_i2c_byte = e1000_read_i2c_byte_generic;
17375eba5b6SRobert Mustacchi 	phy->ops.write_i2c_byte = e1000_write_i2c_byte_generic;
17475eba5b6SRobert Mustacchi 
17575eba5b6SRobert Mustacchi 	if (hw->phy.media_type != e1000_media_type_copper) {
17675eba5b6SRobert Mustacchi 		phy->type = e1000_phy_none;
17775eba5b6SRobert Mustacchi 		goto out;
17875eba5b6SRobert Mustacchi 	}
17975eba5b6SRobert Mustacchi 
18075eba5b6SRobert Mustacchi 	phy->ops.power_up   = e1000_power_up_phy_copper;
18175eba5b6SRobert Mustacchi 	phy->ops.power_down = e1000_power_down_phy_copper_82575;
18275eba5b6SRobert Mustacchi 
18375eba5b6SRobert Mustacchi 	phy->autoneg_mask	= AUTONEG_ADVERTISE_SPEED_DEFAULT;
18475eba5b6SRobert Mustacchi 	phy->reset_delay_us	= 100;
18575eba5b6SRobert Mustacchi 
18675eba5b6SRobert Mustacchi 	phy->ops.acquire	= e1000_acquire_phy_82575;
18775eba5b6SRobert Mustacchi 	phy->ops.check_reset_block = e1000_check_reset_block_generic;
18875eba5b6SRobert Mustacchi 	phy->ops.commit		= e1000_phy_sw_reset_generic;
18975eba5b6SRobert Mustacchi 	phy->ops.get_cfg_done	= e1000_get_cfg_done_82575;
19075eba5b6SRobert Mustacchi 	phy->ops.release	= e1000_release_phy_82575;
19175eba5b6SRobert Mustacchi 
19275eba5b6SRobert Mustacchi 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
19375eba5b6SRobert Mustacchi 
19475eba5b6SRobert Mustacchi 	if (e1000_sgmii_active_82575(hw)) {
19575eba5b6SRobert Mustacchi 		phy->ops.reset = e1000_phy_hw_reset_sgmii_82575;
19675eba5b6SRobert Mustacchi 		ctrl_ext |= E1000_CTRL_I2C_ENA;
19775eba5b6SRobert Mustacchi 	} else {
19875eba5b6SRobert Mustacchi 		phy->ops.reset = e1000_phy_hw_reset_generic;
19975eba5b6SRobert Mustacchi 		ctrl_ext &= ~E1000_CTRL_I2C_ENA;
20075eba5b6SRobert Mustacchi 	}
20175eba5b6SRobert Mustacchi 
20275eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
20375eba5b6SRobert Mustacchi 	e1000_reset_mdicnfg_82580(hw);
20475eba5b6SRobert Mustacchi 
20575eba5b6SRobert Mustacchi 	if (e1000_sgmii_active_82575(hw) && !e1000_sgmii_uses_mdio_82575(hw)) {
20675eba5b6SRobert Mustacchi 		phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575;
20775eba5b6SRobert Mustacchi 		phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575;
20875eba5b6SRobert Mustacchi 	} else {
20975eba5b6SRobert Mustacchi 		switch (hw->mac.type) {
21075eba5b6SRobert Mustacchi 		case e1000_82580:
21175eba5b6SRobert Mustacchi 		case e1000_i350:
21213485e69SGarrett D'Amore 		case e1000_i354:
21375eba5b6SRobert Mustacchi 			phy->ops.read_reg = e1000_read_phy_reg_82580;
21475eba5b6SRobert Mustacchi 			phy->ops.write_reg = e1000_write_phy_reg_82580;
21575eba5b6SRobert Mustacchi 			break;
21675eba5b6SRobert Mustacchi 		case e1000_i210:
21775eba5b6SRobert Mustacchi 		case e1000_i211:
21875eba5b6SRobert Mustacchi 			phy->ops.read_reg = e1000_read_phy_reg_gs40g;
21975eba5b6SRobert Mustacchi 			phy->ops.write_reg = e1000_write_phy_reg_gs40g;
22075eba5b6SRobert Mustacchi 			break;
22175eba5b6SRobert Mustacchi 		default:
22275eba5b6SRobert Mustacchi 			phy->ops.read_reg = e1000_read_phy_reg_igp;
22375eba5b6SRobert Mustacchi 			phy->ops.write_reg = e1000_write_phy_reg_igp;
22475eba5b6SRobert Mustacchi 		}
22575eba5b6SRobert Mustacchi 	}
22675eba5b6SRobert Mustacchi 
22775eba5b6SRobert Mustacchi 	/* Set phy->phy_addr and phy->id. */
22875eba5b6SRobert Mustacchi 	ret_val = e1000_get_phy_id_82575(hw);
22975eba5b6SRobert Mustacchi 
23075eba5b6SRobert Mustacchi 	/* Verify phy id and set remaining function pointers */
23175eba5b6SRobert Mustacchi 	switch (phy->id) {
23213485e69SGarrett D'Amore 	case M88E1543_E_PHY_ID:
23313485e69SGarrett D'Amore 	case M88E1512_E_PHY_ID:
23475eba5b6SRobert Mustacchi 	case I347AT4_E_PHY_ID:
23575eba5b6SRobert Mustacchi 	case M88E1112_E_PHY_ID:
23675eba5b6SRobert Mustacchi 	case M88E1340M_E_PHY_ID:
23775eba5b6SRobert Mustacchi 	case M88E1111_I_PHY_ID:
23875eba5b6SRobert Mustacchi 		phy->type		= e1000_phy_m88;
23975eba5b6SRobert Mustacchi 		phy->ops.check_polarity	= e1000_check_polarity_m88;
24075eba5b6SRobert Mustacchi 		phy->ops.get_info	= e1000_get_phy_info_m88;
241c124a83eSRobert Mustacchi 		if (phy->id == I347AT4_E_PHY_ID ||
242c124a83eSRobert Mustacchi 		    phy->id == M88E1112_E_PHY_ID ||
243c124a83eSRobert Mustacchi 		    phy->id == M88E1340M_E_PHY_ID)
24475eba5b6SRobert Mustacchi 			phy->ops.get_cable_length =
24575eba5b6SRobert Mustacchi 					 e1000_get_cable_length_m88_gen2;
246c124a83eSRobert Mustacchi 		else if (phy->id == M88E1543_E_PHY_ID ||
247c124a83eSRobert Mustacchi 			 phy->id == M88E1512_E_PHY_ID)
248c124a83eSRobert Mustacchi 			phy->ops.get_cable_length =
249c124a83eSRobert Mustacchi 					 e1000_get_cable_length_m88_gen2;
250c124a83eSRobert Mustacchi 		else
25175eba5b6SRobert Mustacchi 			phy->ops.get_cable_length = e1000_get_cable_length_m88;
25275eba5b6SRobert Mustacchi 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
253c124a83eSRobert Mustacchi 		/* Check if this PHY is confgured for media swap. */
254c124a83eSRobert Mustacchi 		if (phy->id == M88E1112_E_PHY_ID) {
255c124a83eSRobert Mustacchi 			u16 data;
256c124a83eSRobert Mustacchi 
257c124a83eSRobert Mustacchi 			ret_val = phy->ops.write_reg(hw,
258c124a83eSRobert Mustacchi 						     E1000_M88E1112_PAGE_ADDR,
259c124a83eSRobert Mustacchi 						     2);
260c124a83eSRobert Mustacchi 			if (ret_val)
261c124a83eSRobert Mustacchi 				goto out;
262c124a83eSRobert Mustacchi 
263c124a83eSRobert Mustacchi 			ret_val = phy->ops.read_reg(hw,
264c124a83eSRobert Mustacchi 						    E1000_M88E1112_MAC_CTRL_1,
265c124a83eSRobert Mustacchi 						    &data);
266c124a83eSRobert Mustacchi 			if (ret_val)
267c124a83eSRobert Mustacchi 				goto out;
268c124a83eSRobert Mustacchi 
269c124a83eSRobert Mustacchi 			data = (data & E1000_M88E1112_MAC_CTRL_1_MODE_MASK) >>
270c124a83eSRobert Mustacchi 			       E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT;
271c124a83eSRobert Mustacchi 			if (data == E1000_M88E1112_AUTO_COPPER_SGMII ||
272c124a83eSRobert Mustacchi 			    data == E1000_M88E1112_AUTO_COPPER_BASEX)
273c124a83eSRobert Mustacchi 				hw->mac.ops.check_for_link =
274c124a83eSRobert Mustacchi 						e1000_check_for_link_media_swap;
275c124a83eSRobert Mustacchi 		}
276c124a83eSRobert Mustacchi 		if (phy->id == M88E1512_E_PHY_ID) {
277c124a83eSRobert Mustacchi 			ret_val = e1000_initialize_M88E1512_phy(hw);
278c124a83eSRobert Mustacchi 			if (ret_val)
279c124a83eSRobert Mustacchi 				goto out;
280c124a83eSRobert Mustacchi 		}
28149b78600SRobert Mustacchi 		if (phy->id == M88E1543_E_PHY_ID) {
28249b78600SRobert Mustacchi 			ret_val = e1000_initialize_M88E1543_phy(hw);
28349b78600SRobert Mustacchi 			if (ret_val)
28449b78600SRobert Mustacchi 				goto out;
28549b78600SRobert Mustacchi 		}
28675eba5b6SRobert Mustacchi 		break;
28775eba5b6SRobert Mustacchi 	case IGP03E1000_E_PHY_ID:
28875eba5b6SRobert Mustacchi 	case IGP04E1000_E_PHY_ID:
28975eba5b6SRobert Mustacchi 		phy->type = e1000_phy_igp_3;
29075eba5b6SRobert Mustacchi 		phy->ops.check_polarity = e1000_check_polarity_igp;
29175eba5b6SRobert Mustacchi 		phy->ops.get_info = e1000_get_phy_info_igp;
29275eba5b6SRobert Mustacchi 		phy->ops.get_cable_length = e1000_get_cable_length_igp_2;
29375eba5b6SRobert Mustacchi 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp;
29475eba5b6SRobert Mustacchi 		phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82575;
29575eba5b6SRobert Mustacchi 		phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic;
29675eba5b6SRobert Mustacchi 		break;
29775eba5b6SRobert Mustacchi 	case I82580_I_PHY_ID:
29875eba5b6SRobert Mustacchi 	case I350_I_PHY_ID:
29975eba5b6SRobert Mustacchi 		phy->type = e1000_phy_82580;
30075eba5b6SRobert Mustacchi 		phy->ops.check_polarity = e1000_check_polarity_82577;
30175eba5b6SRobert Mustacchi 		phy->ops.force_speed_duplex =
30275eba5b6SRobert Mustacchi 					 e1000_phy_force_speed_duplex_82577;
30375eba5b6SRobert Mustacchi 		phy->ops.get_cable_length = e1000_get_cable_length_82577;
30475eba5b6SRobert Mustacchi 		phy->ops.get_info = e1000_get_phy_info_82577;
30575eba5b6SRobert Mustacchi 		phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
30675eba5b6SRobert Mustacchi 		phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
30775eba5b6SRobert Mustacchi 		break;
30875eba5b6SRobert Mustacchi 	case I210_I_PHY_ID:
30975eba5b6SRobert Mustacchi 		phy->type		= e1000_phy_i210;
31075eba5b6SRobert Mustacchi 		phy->ops.check_polarity	= e1000_check_polarity_m88;
31175eba5b6SRobert Mustacchi 		phy->ops.get_info	= e1000_get_phy_info_m88;
31275eba5b6SRobert Mustacchi 		phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2;
31375eba5b6SRobert Mustacchi 		phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
31475eba5b6SRobert Mustacchi 		phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
31575eba5b6SRobert Mustacchi 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
31675eba5b6SRobert Mustacchi 		break;
31775eba5b6SRobert Mustacchi 	default:
31875eba5b6SRobert Mustacchi 		ret_val = -E1000_ERR_PHY;
31975eba5b6SRobert Mustacchi 		goto out;
32075eba5b6SRobert Mustacchi 	}
32175eba5b6SRobert Mustacchi 
32275eba5b6SRobert Mustacchi out:
32375eba5b6SRobert Mustacchi 	return ret_val;
32475eba5b6SRobert Mustacchi }
32575eba5b6SRobert Mustacchi 
32675eba5b6SRobert Mustacchi /**
32775eba5b6SRobert Mustacchi  *  e1000_init_nvm_params_82575 - Init NVM func ptrs.
32875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
32975eba5b6SRobert Mustacchi  **/
e1000_init_nvm_params_82575(struct e1000_hw * hw)33075eba5b6SRobert Mustacchi s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
33175eba5b6SRobert Mustacchi {
33275eba5b6SRobert Mustacchi 	struct e1000_nvm_info *nvm = &hw->nvm;
33375eba5b6SRobert Mustacchi 	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
33475eba5b6SRobert Mustacchi 	u16 size;
33575eba5b6SRobert Mustacchi 
33675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_nvm_params_82575");
33775eba5b6SRobert Mustacchi 
33875eba5b6SRobert Mustacchi 	size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
33975eba5b6SRobert Mustacchi 		     E1000_EECD_SIZE_EX_SHIFT);
34075eba5b6SRobert Mustacchi 	/*
34175eba5b6SRobert Mustacchi 	 * Added to a constant, "size" becomes the left-shift value
34275eba5b6SRobert Mustacchi 	 * for setting word_size.
34375eba5b6SRobert Mustacchi 	 */
34475eba5b6SRobert Mustacchi 	size += NVM_WORD_SIZE_BASE_SHIFT;
34575eba5b6SRobert Mustacchi 
34675eba5b6SRobert Mustacchi 	/* Just in case size is out of range, cap it to the largest
34775eba5b6SRobert Mustacchi 	 * EEPROM size supported
34875eba5b6SRobert Mustacchi 	 */
34975eba5b6SRobert Mustacchi 	if (size > 15)
35075eba5b6SRobert Mustacchi 		size = 15;
35175eba5b6SRobert Mustacchi 
35275eba5b6SRobert Mustacchi 	nvm->word_size = 1 << size;
35375eba5b6SRobert Mustacchi 	if (hw->mac.type < e1000_i210) {
35475eba5b6SRobert Mustacchi 		nvm->opcode_bits = 8;
35575eba5b6SRobert Mustacchi 		nvm->delay_usec = 1;
35675eba5b6SRobert Mustacchi 
35775eba5b6SRobert Mustacchi 		switch (nvm->override) {
35875eba5b6SRobert Mustacchi 		case e1000_nvm_override_spi_large:
35975eba5b6SRobert Mustacchi 			nvm->page_size = 32;
36075eba5b6SRobert Mustacchi 			nvm->address_bits = 16;
36175eba5b6SRobert Mustacchi 			break;
36275eba5b6SRobert Mustacchi 		case e1000_nvm_override_spi_small:
36375eba5b6SRobert Mustacchi 			nvm->page_size = 8;
36475eba5b6SRobert Mustacchi 			nvm->address_bits = 8;
36575eba5b6SRobert Mustacchi 			break;
36675eba5b6SRobert Mustacchi 		default:
36775eba5b6SRobert Mustacchi 			nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
36875eba5b6SRobert Mustacchi 			nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ?
36975eba5b6SRobert Mustacchi 					    16 : 8;
37075eba5b6SRobert Mustacchi 			break;
37175eba5b6SRobert Mustacchi 		}
37275eba5b6SRobert Mustacchi 		if (nvm->word_size == (1 << 15))
37375eba5b6SRobert Mustacchi 			nvm->page_size = 128;
37475eba5b6SRobert Mustacchi 
37575eba5b6SRobert Mustacchi 		nvm->type = e1000_nvm_eeprom_spi;
37675eba5b6SRobert Mustacchi 	} else {
37775eba5b6SRobert Mustacchi 		nvm->type = e1000_nvm_flash_hw;
37875eba5b6SRobert Mustacchi 	}
37975eba5b6SRobert Mustacchi 
38075eba5b6SRobert Mustacchi 	/* Function Pointers */
38175eba5b6SRobert Mustacchi 	nvm->ops.acquire = e1000_acquire_nvm_82575;
38275eba5b6SRobert Mustacchi 	nvm->ops.release = e1000_release_nvm_82575;
38375eba5b6SRobert Mustacchi 	if (nvm->word_size < (1 << 15))
38475eba5b6SRobert Mustacchi 		nvm->ops.read = e1000_read_nvm_eerd;
38575eba5b6SRobert Mustacchi 	else
38675eba5b6SRobert Mustacchi 		nvm->ops.read = e1000_read_nvm_spi;
38775eba5b6SRobert Mustacchi 
38875eba5b6SRobert Mustacchi 	nvm->ops.write = e1000_write_nvm_spi;
38975eba5b6SRobert Mustacchi 	nvm->ops.validate = e1000_validate_nvm_checksum_generic;
39075eba5b6SRobert Mustacchi 	nvm->ops.update = e1000_update_nvm_checksum_generic;
39175eba5b6SRobert Mustacchi 	nvm->ops.valid_led_default = e1000_valid_led_default_82575;
39275eba5b6SRobert Mustacchi 
39375eba5b6SRobert Mustacchi 	/* override generic family function pointers for specific descendants */
39475eba5b6SRobert Mustacchi 	switch (hw->mac.type) {
39575eba5b6SRobert Mustacchi 	case e1000_82580:
39675eba5b6SRobert Mustacchi 		nvm->ops.validate = e1000_validate_nvm_checksum_82580;
39775eba5b6SRobert Mustacchi 		nvm->ops.update = e1000_update_nvm_checksum_82580;
39875eba5b6SRobert Mustacchi 		break;
39975eba5b6SRobert Mustacchi 	case e1000_i350:
40013485e69SGarrett D'Amore 	case e1000_i354:
40175eba5b6SRobert Mustacchi 		nvm->ops.validate = e1000_validate_nvm_checksum_i350;
40275eba5b6SRobert Mustacchi 		nvm->ops.update = e1000_update_nvm_checksum_i350;
40375eba5b6SRobert Mustacchi 		break;
40475eba5b6SRobert Mustacchi 	default:
40575eba5b6SRobert Mustacchi 		break;
40675eba5b6SRobert Mustacchi 	}
40775eba5b6SRobert Mustacchi 
40875eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
40975eba5b6SRobert Mustacchi }
41075eba5b6SRobert Mustacchi 
41175eba5b6SRobert Mustacchi /**
41275eba5b6SRobert Mustacchi  *  e1000_init_mac_params_82575 - Init MAC func ptrs.
41375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
41475eba5b6SRobert Mustacchi  **/
e1000_init_mac_params_82575(struct e1000_hw * hw)41575eba5b6SRobert Mustacchi static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
41675eba5b6SRobert Mustacchi {
41775eba5b6SRobert Mustacchi 	struct e1000_mac_info *mac = &hw->mac;
41875eba5b6SRobert Mustacchi 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
41975eba5b6SRobert Mustacchi 
42075eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_mac_params_82575");
42175eba5b6SRobert Mustacchi 
42275eba5b6SRobert Mustacchi 	/* Derives media type */
42375eba5b6SRobert Mustacchi 	e1000_get_media_type_82575(hw);
42475eba5b6SRobert Mustacchi 	/* Set mta register count */
42575eba5b6SRobert Mustacchi 	mac->mta_reg_count = 128;
42675eba5b6SRobert Mustacchi 	/* Set uta register count */
42775eba5b6SRobert Mustacchi 	mac->uta_reg_count = (hw->mac.type == e1000_82575) ? 0 : 128;
42875eba5b6SRobert Mustacchi 	/* Set rar entry count */
42975eba5b6SRobert Mustacchi 	mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
43075eba5b6SRobert Mustacchi 	if (mac->type == e1000_82576)
43175eba5b6SRobert Mustacchi 		mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
43275eba5b6SRobert Mustacchi 	if (mac->type == e1000_82580)
43375eba5b6SRobert Mustacchi 		mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
43413485e69SGarrett D'Amore 	if (mac->type == e1000_i350 || mac->type == e1000_i354)
43575eba5b6SRobert Mustacchi 		mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
43675eba5b6SRobert Mustacchi 
43713485e69SGarrett D'Amore 	/* Disable EEE default settings for EEE supported devices */
43875eba5b6SRobert Mustacchi 	if (mac->type >= e1000_i350)
43975eba5b6SRobert Mustacchi 		dev_spec->eee_disable = TRUE;
44075eba5b6SRobert Mustacchi 
44175eba5b6SRobert Mustacchi 	/* Allow a single clear of the SW semaphore on I210 and newer */
44275eba5b6SRobert Mustacchi 	if (mac->type >= e1000_i210)
44375eba5b6SRobert Mustacchi 		dev_spec->clear_semaphore_once = TRUE;
44475eba5b6SRobert Mustacchi 
44575eba5b6SRobert Mustacchi 	/* Set if part includes ASF firmware */
44675eba5b6SRobert Mustacchi 	mac->asf_firmware_present = TRUE;
44775eba5b6SRobert Mustacchi 	/* FWSM register */
44875eba5b6SRobert Mustacchi 	mac->has_fwsm = TRUE;
44975eba5b6SRobert Mustacchi 	/* ARC supported; valid only if manageability features are enabled. */
45075eba5b6SRobert Mustacchi 	mac->arc_subsystem_valid =
45175eba5b6SRobert Mustacchi 		!!(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK);
45275eba5b6SRobert Mustacchi 
45375eba5b6SRobert Mustacchi 	/* Function pointers */
45475eba5b6SRobert Mustacchi 
45575eba5b6SRobert Mustacchi 	/* bus type/speed/width */
45675eba5b6SRobert Mustacchi 	mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic;
45775eba5b6SRobert Mustacchi 	/* reset */
45875eba5b6SRobert Mustacchi 	if (mac->type >= e1000_82580)
45975eba5b6SRobert Mustacchi 		mac->ops.reset_hw = e1000_reset_hw_82580;
46075eba5b6SRobert Mustacchi 	else
46175eba5b6SRobert Mustacchi 	mac->ops.reset_hw = e1000_reset_hw_82575;
46275eba5b6SRobert Mustacchi 	/* hw initialization */
463c124a83eSRobert Mustacchi 	if ((mac->type == e1000_i210) || (mac->type == e1000_i211))
464c124a83eSRobert Mustacchi 		mac->ops.init_hw = e1000_init_hw_i210;
465c124a83eSRobert Mustacchi 	else
46675eba5b6SRobert Mustacchi 	mac->ops.init_hw = e1000_init_hw_82575;
46775eba5b6SRobert Mustacchi 	/* link setup */
46875eba5b6SRobert Mustacchi 	mac->ops.setup_link = e1000_setup_link_generic;
46975eba5b6SRobert Mustacchi 	/* physical interface link setup */
47075eba5b6SRobert Mustacchi 	mac->ops.setup_physical_interface =
47175eba5b6SRobert Mustacchi 		(hw->phy.media_type == e1000_media_type_copper)
47275eba5b6SRobert Mustacchi 		? e1000_setup_copper_link_82575 : e1000_setup_serdes_link_82575;
47375eba5b6SRobert Mustacchi 	/* physical interface shutdown */
47475eba5b6SRobert Mustacchi 	mac->ops.shutdown_serdes = e1000_shutdown_serdes_link_82575;
47575eba5b6SRobert Mustacchi 	/* physical interface power up */
47675eba5b6SRobert Mustacchi 	mac->ops.power_up_serdes = e1000_power_up_serdes_link_82575;
47775eba5b6SRobert Mustacchi 	/* check for link */
47875eba5b6SRobert Mustacchi 	mac->ops.check_for_link = e1000_check_for_link_82575;
47975eba5b6SRobert Mustacchi 	/* read mac address */
48075eba5b6SRobert Mustacchi 	mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
48175eba5b6SRobert Mustacchi 	/* configure collision distance */
48275eba5b6SRobert Mustacchi 	mac->ops.config_collision_dist = e1000_config_collision_dist_82575;
48375eba5b6SRobert Mustacchi 	/* multicast address update */
48475eba5b6SRobert Mustacchi 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
485c124a83eSRobert Mustacchi 	if (hw->mac.type == e1000_i350 || mac->type == e1000_i354) {
48675eba5b6SRobert Mustacchi 		/* writing VFTA */
48775eba5b6SRobert Mustacchi 		mac->ops.write_vfta = e1000_write_vfta_i350;
48875eba5b6SRobert Mustacchi 		/* clearing VFTA */
48975eba5b6SRobert Mustacchi 		mac->ops.clear_vfta = e1000_clear_vfta_i350;
49075eba5b6SRobert Mustacchi 	} else {
49175eba5b6SRobert Mustacchi 		/* writing VFTA */
49275eba5b6SRobert Mustacchi 		mac->ops.write_vfta = e1000_write_vfta_generic;
49375eba5b6SRobert Mustacchi 		/* clearing VFTA */
49475eba5b6SRobert Mustacchi 		mac->ops.clear_vfta = e1000_clear_vfta_generic;
49575eba5b6SRobert Mustacchi 	}
49675eba5b6SRobert Mustacchi 	if (hw->mac.type >= e1000_82580)
49775eba5b6SRobert Mustacchi 		mac->ops.validate_mdi_setting =
49875eba5b6SRobert Mustacchi 				e1000_validate_mdi_setting_crossover_generic;
49975eba5b6SRobert Mustacchi 	/* ID LED init */
50075eba5b6SRobert Mustacchi 	mac->ops.id_led_init = e1000_id_led_init_generic;
50175eba5b6SRobert Mustacchi 	/* blink LED */
50275eba5b6SRobert Mustacchi 	mac->ops.blink_led = e1000_blink_led_generic;
50375eba5b6SRobert Mustacchi 	/* setup LED */
50475eba5b6SRobert Mustacchi 	mac->ops.setup_led = e1000_setup_led_generic;
50575eba5b6SRobert Mustacchi 	/* cleanup LED */
50675eba5b6SRobert Mustacchi 	mac->ops.cleanup_led = e1000_cleanup_led_generic;
50775eba5b6SRobert Mustacchi 	/* turn on/off LED */
50875eba5b6SRobert Mustacchi 	mac->ops.led_on = e1000_led_on_generic;
50975eba5b6SRobert Mustacchi 	mac->ops.led_off = e1000_led_off_generic;
51075eba5b6SRobert Mustacchi 	/* clear hardware counters */
51175eba5b6SRobert Mustacchi 	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
51275eba5b6SRobert Mustacchi 	/* link info */
51375eba5b6SRobert Mustacchi 	mac->ops.get_link_up_info = e1000_get_link_up_info_82575;
51475eba5b6SRobert Mustacchi 	/* acquire SW_FW sync */
51575eba5b6SRobert Mustacchi 	mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_82575;
51675eba5b6SRobert Mustacchi 	mac->ops.release_swfw_sync = e1000_release_swfw_sync_82575;
51775eba5b6SRobert Mustacchi 	if (mac->type >= e1000_i210) {
51875eba5b6SRobert Mustacchi 		mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_i210;
51975eba5b6SRobert Mustacchi 		mac->ops.release_swfw_sync = e1000_release_swfw_sync_i210;
52075eba5b6SRobert Mustacchi 	}
52175eba5b6SRobert Mustacchi 
52275eba5b6SRobert Mustacchi 	/* set lan id for port to determine which phy lock to use */
52375eba5b6SRobert Mustacchi 	hw->mac.ops.set_lan_id(hw);
52475eba5b6SRobert Mustacchi 
52575eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
52675eba5b6SRobert Mustacchi }
52775eba5b6SRobert Mustacchi 
52875eba5b6SRobert Mustacchi /**
52975eba5b6SRobert Mustacchi  *  e1000_init_function_pointers_82575 - Init func ptrs.
53075eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
53175eba5b6SRobert Mustacchi  *
53275eba5b6SRobert Mustacchi  *  Called to initialize all function pointers and parameters.
53375eba5b6SRobert Mustacchi  **/
e1000_init_function_pointers_82575(struct e1000_hw * hw)53475eba5b6SRobert Mustacchi void e1000_init_function_pointers_82575(struct e1000_hw *hw)
53575eba5b6SRobert Mustacchi {
53675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_function_pointers_82575");
53775eba5b6SRobert Mustacchi 
53875eba5b6SRobert Mustacchi 	hw->mac.ops.init_params = e1000_init_mac_params_82575;
53975eba5b6SRobert Mustacchi 	hw->nvm.ops.init_params = e1000_init_nvm_params_82575;
54075eba5b6SRobert Mustacchi 	hw->phy.ops.init_params = e1000_init_phy_params_82575;
54175eba5b6SRobert Mustacchi 	hw->mbx.ops.init_params = e1000_init_mbx_params_pf;
54275eba5b6SRobert Mustacchi }
54375eba5b6SRobert Mustacchi 
54475eba5b6SRobert Mustacchi /**
54575eba5b6SRobert Mustacchi  *  e1000_acquire_phy_82575 - Acquire rights to access PHY
54675eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
54775eba5b6SRobert Mustacchi  *
54875eba5b6SRobert Mustacchi  *  Acquire access rights to the correct PHY.
54975eba5b6SRobert Mustacchi  **/
e1000_acquire_phy_82575(struct e1000_hw * hw)55075eba5b6SRobert Mustacchi static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
55175eba5b6SRobert Mustacchi {
55275eba5b6SRobert Mustacchi 	u16 mask = E1000_SWFW_PHY0_SM;
55375eba5b6SRobert Mustacchi 
55475eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_acquire_phy_82575");
55575eba5b6SRobert Mustacchi 
55675eba5b6SRobert Mustacchi 	if (hw->bus.func == E1000_FUNC_1)
55775eba5b6SRobert Mustacchi 		mask = E1000_SWFW_PHY1_SM;
55875eba5b6SRobert Mustacchi 	else if (hw->bus.func == E1000_FUNC_2)
55975eba5b6SRobert Mustacchi 		mask = E1000_SWFW_PHY2_SM;
56075eba5b6SRobert Mustacchi 	else if (hw->bus.func == E1000_FUNC_3)
56175eba5b6SRobert Mustacchi 		mask = E1000_SWFW_PHY3_SM;
56275eba5b6SRobert Mustacchi 
56375eba5b6SRobert Mustacchi 	return hw->mac.ops.acquire_swfw_sync(hw, mask);
56475eba5b6SRobert Mustacchi }
56575eba5b6SRobert Mustacchi 
56675eba5b6SRobert Mustacchi /**
56775eba5b6SRobert Mustacchi  *  e1000_release_phy_82575 - Release rights to access PHY
56875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
56975eba5b6SRobert Mustacchi  *
57075eba5b6SRobert Mustacchi  *  A wrapper to release access rights to the correct PHY.
57175eba5b6SRobert Mustacchi  **/
e1000_release_phy_82575(struct e1000_hw * hw)57275eba5b6SRobert Mustacchi static void e1000_release_phy_82575(struct e1000_hw *hw)
57375eba5b6SRobert Mustacchi {
57475eba5b6SRobert Mustacchi 	u16 mask = E1000_SWFW_PHY0_SM;
57575eba5b6SRobert Mustacchi 
57675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_release_phy_82575");
57775eba5b6SRobert Mustacchi 
57875eba5b6SRobert Mustacchi 	if (hw->bus.func == E1000_FUNC_1)
57975eba5b6SRobert Mustacchi 		mask = E1000_SWFW_PHY1_SM;
58075eba5b6SRobert Mustacchi 	else if (hw->bus.func == E1000_FUNC_2)
58175eba5b6SRobert Mustacchi 		mask = E1000_SWFW_PHY2_SM;
58275eba5b6SRobert Mustacchi 	else if (hw->bus.func == E1000_FUNC_3)
58375eba5b6SRobert Mustacchi 		mask = E1000_SWFW_PHY3_SM;
58475eba5b6SRobert Mustacchi 
58575eba5b6SRobert Mustacchi 	hw->mac.ops.release_swfw_sync(hw, mask);
58675eba5b6SRobert Mustacchi }
58775eba5b6SRobert Mustacchi 
58875eba5b6SRobert Mustacchi /**
58975eba5b6SRobert Mustacchi  *  e1000_read_phy_reg_sgmii_82575 - Read PHY register using sgmii
59075eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
59175eba5b6SRobert Mustacchi  *  @offset: register offset to be read
59275eba5b6SRobert Mustacchi  *  @data: pointer to the read data
59375eba5b6SRobert Mustacchi  *
59475eba5b6SRobert Mustacchi  *  Reads the PHY register at offset using the serial gigabit media independent
59575eba5b6SRobert Mustacchi  *  interface and stores the retrieved information in data.
59675eba5b6SRobert Mustacchi  **/
e1000_read_phy_reg_sgmii_82575(struct e1000_hw * hw,u32 offset,u16 * data)59775eba5b6SRobert Mustacchi static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
59875eba5b6SRobert Mustacchi 					  u16 *data)
59975eba5b6SRobert Mustacchi {
60075eba5b6SRobert Mustacchi 	s32 ret_val = -E1000_ERR_PARAM;
60175eba5b6SRobert Mustacchi 
60275eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_read_phy_reg_sgmii_82575");
60375eba5b6SRobert Mustacchi 
60475eba5b6SRobert Mustacchi 	if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
60575eba5b6SRobert Mustacchi 		DEBUGOUT1("PHY Address %u is out of range\n", offset);
60675eba5b6SRobert Mustacchi 		goto out;
60775eba5b6SRobert Mustacchi 	}
60875eba5b6SRobert Mustacchi 
60975eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.acquire(hw);
61075eba5b6SRobert Mustacchi 	if (ret_val)
61175eba5b6SRobert Mustacchi 		goto out;
61275eba5b6SRobert Mustacchi 
61375eba5b6SRobert Mustacchi 	ret_val = e1000_read_phy_reg_i2c(hw, offset, data);
61475eba5b6SRobert Mustacchi 
61575eba5b6SRobert Mustacchi 	hw->phy.ops.release(hw);
61675eba5b6SRobert Mustacchi 
61775eba5b6SRobert Mustacchi out:
61875eba5b6SRobert Mustacchi 	return ret_val;
61975eba5b6SRobert Mustacchi }
62075eba5b6SRobert Mustacchi 
62175eba5b6SRobert Mustacchi /**
62275eba5b6SRobert Mustacchi  *  e1000_write_phy_reg_sgmii_82575 - Write PHY register using sgmii
62375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
62475eba5b6SRobert Mustacchi  *  @offset: register offset to write to
62575eba5b6SRobert Mustacchi  *  @data: data to write at register offset
62675eba5b6SRobert Mustacchi  *
62775eba5b6SRobert Mustacchi  *  Writes the data to PHY register at the offset using the serial gigabit
62875eba5b6SRobert Mustacchi  *  media independent interface.
62975eba5b6SRobert Mustacchi  **/
e1000_write_phy_reg_sgmii_82575(struct e1000_hw * hw,u32 offset,u16 data)63075eba5b6SRobert Mustacchi static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
63175eba5b6SRobert Mustacchi 					   u16 data)
63275eba5b6SRobert Mustacchi {
63375eba5b6SRobert Mustacchi 	s32 ret_val = -E1000_ERR_PARAM;
63475eba5b6SRobert Mustacchi 
63575eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_write_phy_reg_sgmii_82575");
63675eba5b6SRobert Mustacchi 
63775eba5b6SRobert Mustacchi 	if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
63875eba5b6SRobert Mustacchi 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
63975eba5b6SRobert Mustacchi 		goto out;
64075eba5b6SRobert Mustacchi 	}
64175eba5b6SRobert Mustacchi 
64275eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.acquire(hw);
64375eba5b6SRobert Mustacchi 	if (ret_val)
64475eba5b6SRobert Mustacchi 		goto out;
64575eba5b6SRobert Mustacchi 
64675eba5b6SRobert Mustacchi 	ret_val = e1000_write_phy_reg_i2c(hw, offset, data);
64775eba5b6SRobert Mustacchi 
64875eba5b6SRobert Mustacchi 	hw->phy.ops.release(hw);
64975eba5b6SRobert Mustacchi 
65075eba5b6SRobert Mustacchi out:
65175eba5b6SRobert Mustacchi 	return ret_val;
65275eba5b6SRobert Mustacchi }
65375eba5b6SRobert Mustacchi 
65475eba5b6SRobert Mustacchi /**
65575eba5b6SRobert Mustacchi  *  e1000_get_phy_id_82575 - Retrieve PHY addr and id
65675eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
65775eba5b6SRobert Mustacchi  *
65875eba5b6SRobert Mustacchi  *  Retrieves the PHY address and ID for both PHY's which do and do not use
65975eba5b6SRobert Mustacchi  *  sgmi interface.
66075eba5b6SRobert Mustacchi  **/
e1000_get_phy_id_82575(struct e1000_hw * hw)66175eba5b6SRobert Mustacchi static s32 e1000_get_phy_id_82575(struct e1000_hw *hw)
66275eba5b6SRobert Mustacchi {
66375eba5b6SRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
66475eba5b6SRobert Mustacchi 	s32  ret_val = E1000_SUCCESS;
66575eba5b6SRobert Mustacchi 	u16 phy_id;
66675eba5b6SRobert Mustacchi 	u32 ctrl_ext;
66775eba5b6SRobert Mustacchi 	u32 mdic;
66875eba5b6SRobert Mustacchi 
66975eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_get_phy_id_82575");
67075eba5b6SRobert Mustacchi 
67113485e69SGarrett D'Amore 	/* some i354 devices need an extra read for phy id */
67213485e69SGarrett D'Amore 	if (hw->mac.type == e1000_i354)
67313485e69SGarrett D'Amore 		e1000_get_phy_id(hw);
67413485e69SGarrett D'Amore 
67575eba5b6SRobert Mustacchi 	/*
67675eba5b6SRobert Mustacchi 	 * For SGMII PHYs, we try the list of possible addresses until
67775eba5b6SRobert Mustacchi 	 * we find one that works.  For non-SGMII PHYs
67875eba5b6SRobert Mustacchi 	 * (e.g. integrated copper PHYs), an address of 1 should
67975eba5b6SRobert Mustacchi 	 * work.  The result of this function should mean phy->phy_addr
68075eba5b6SRobert Mustacchi 	 * and phy->id are set correctly.
68175eba5b6SRobert Mustacchi 	 */
68275eba5b6SRobert Mustacchi 	if (!e1000_sgmii_active_82575(hw)) {
68375eba5b6SRobert Mustacchi 		phy->addr = 1;
68475eba5b6SRobert Mustacchi 		ret_val = e1000_get_phy_id(hw);
68575eba5b6SRobert Mustacchi 		goto out;
68675eba5b6SRobert Mustacchi 	}
68775eba5b6SRobert Mustacchi 
68875eba5b6SRobert Mustacchi 	if (e1000_sgmii_uses_mdio_82575(hw)) {
68975eba5b6SRobert Mustacchi 		switch (hw->mac.type) {
69075eba5b6SRobert Mustacchi 		case e1000_82575:
69175eba5b6SRobert Mustacchi 		case e1000_82576:
69275eba5b6SRobert Mustacchi 			mdic = E1000_READ_REG(hw, E1000_MDIC);
69375eba5b6SRobert Mustacchi 			mdic &= E1000_MDIC_PHY_MASK;
69475eba5b6SRobert Mustacchi 			phy->addr = mdic >> E1000_MDIC_PHY_SHIFT;
69575eba5b6SRobert Mustacchi 			break;
69675eba5b6SRobert Mustacchi 		case e1000_82580:
69775eba5b6SRobert Mustacchi 		case e1000_i350:
69813485e69SGarrett D'Amore 		case e1000_i354:
69975eba5b6SRobert Mustacchi 		case e1000_i210:
70075eba5b6SRobert Mustacchi 		case e1000_i211:
70175eba5b6SRobert Mustacchi 			mdic = E1000_READ_REG(hw, E1000_MDICNFG);
70275eba5b6SRobert Mustacchi 			mdic &= E1000_MDICNFG_PHY_MASK;
70375eba5b6SRobert Mustacchi 			phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT;
70475eba5b6SRobert Mustacchi 			break;
70575eba5b6SRobert Mustacchi 		default:
70675eba5b6SRobert Mustacchi 			ret_val = -E1000_ERR_PHY;
70775eba5b6SRobert Mustacchi 			goto out;
70875eba5b6SRobert Mustacchi 			break;
70975eba5b6SRobert Mustacchi 		}
71075eba5b6SRobert Mustacchi 		ret_val = e1000_get_phy_id(hw);
71175eba5b6SRobert Mustacchi 		goto out;
71275eba5b6SRobert Mustacchi 	}
71375eba5b6SRobert Mustacchi 
71475eba5b6SRobert Mustacchi 	/* Power on sgmii phy if it is disabled */
71575eba5b6SRobert Mustacchi 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
71675eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL_EXT,
71775eba5b6SRobert Mustacchi 			ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA);
71875eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
71975eba5b6SRobert Mustacchi 	msec_delay(300);
72075eba5b6SRobert Mustacchi 
72175eba5b6SRobert Mustacchi 	/*
72275eba5b6SRobert Mustacchi 	 * The address field in the I2CCMD register is 3 bits and 0 is invalid.
72375eba5b6SRobert Mustacchi 	 * Therefore, we need to test 1-7
72475eba5b6SRobert Mustacchi 	 */
72575eba5b6SRobert Mustacchi 	for (phy->addr = 1; phy->addr < 8; phy->addr++) {
72675eba5b6SRobert Mustacchi 		ret_val = e1000_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id);
72775eba5b6SRobert Mustacchi 		if (ret_val == E1000_SUCCESS) {
72875eba5b6SRobert Mustacchi 			DEBUGOUT2("Vendor ID 0x%08X read at address %u\n",
72975eba5b6SRobert Mustacchi 				  phy_id, phy->addr);
73075eba5b6SRobert Mustacchi 			/*
73175eba5b6SRobert Mustacchi 			 * At the time of this writing, The M88 part is
73275eba5b6SRobert Mustacchi 			 * the only supported SGMII PHY product.
73375eba5b6SRobert Mustacchi 			 */
73475eba5b6SRobert Mustacchi 			if (phy_id == M88_VENDOR)
73575eba5b6SRobert Mustacchi 				break;
73675eba5b6SRobert Mustacchi 		} else {
73775eba5b6SRobert Mustacchi 			DEBUGOUT1("PHY address %u was unreadable\n",
73875eba5b6SRobert Mustacchi 				  phy->addr);
73975eba5b6SRobert Mustacchi 		}
74075eba5b6SRobert Mustacchi 	}
74175eba5b6SRobert Mustacchi 
74275eba5b6SRobert Mustacchi 	/* A valid PHY type couldn't be found. */
74375eba5b6SRobert Mustacchi 	if (phy->addr == 8) {
74475eba5b6SRobert Mustacchi 		phy->addr = 0;
74575eba5b6SRobert Mustacchi 		ret_val = -E1000_ERR_PHY;
74675eba5b6SRobert Mustacchi 	} else {
74775eba5b6SRobert Mustacchi 		ret_val = e1000_get_phy_id(hw);
74875eba5b6SRobert Mustacchi 	}
74975eba5b6SRobert Mustacchi 
75075eba5b6SRobert Mustacchi 	/* restore previous sfp cage power state */
75175eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
75275eba5b6SRobert Mustacchi 
75375eba5b6SRobert Mustacchi out:
75475eba5b6SRobert Mustacchi 	return ret_val;
75575eba5b6SRobert Mustacchi }
75675eba5b6SRobert Mustacchi 
75775eba5b6SRobert Mustacchi /**
75875eba5b6SRobert Mustacchi  *  e1000_phy_hw_reset_sgmii_82575 - Performs a PHY reset
75975eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
76075eba5b6SRobert Mustacchi  *
76175eba5b6SRobert Mustacchi  *  Resets the PHY using the serial gigabit media independent interface.
76275eba5b6SRobert Mustacchi  **/
e1000_phy_hw_reset_sgmii_82575(struct e1000_hw * hw)76375eba5b6SRobert Mustacchi static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
76475eba5b6SRobert Mustacchi {
76575eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
766c124a83eSRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
76775eba5b6SRobert Mustacchi 
76875eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
76975eba5b6SRobert Mustacchi 
77075eba5b6SRobert Mustacchi 	/*
77175eba5b6SRobert Mustacchi 	 * This isn't a TRUE "hard" reset, but is the only reset
77275eba5b6SRobert Mustacchi 	 * available to us at this time.
77375eba5b6SRobert Mustacchi 	 */
77475eba5b6SRobert Mustacchi 
77575eba5b6SRobert Mustacchi 	DEBUGOUT("Soft resetting SGMII attached PHY...\n");
77675eba5b6SRobert Mustacchi 
77775eba5b6SRobert Mustacchi 	if (!(hw->phy.ops.write_reg))
77875eba5b6SRobert Mustacchi 		goto out;
77975eba5b6SRobert Mustacchi 
78075eba5b6SRobert Mustacchi 	/*
78175eba5b6SRobert Mustacchi 	 * SFP documentation requires the following to configure the SPF module
78275eba5b6SRobert Mustacchi 	 * to work on SGMII.  No further documentation is given.
78375eba5b6SRobert Mustacchi 	 */
78475eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.write_reg(hw, 0x1B, 0x8084);
78575eba5b6SRobert Mustacchi 	if (ret_val)
78675eba5b6SRobert Mustacchi 		goto out;
78775eba5b6SRobert Mustacchi 
78875eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.commit(hw);
789c124a83eSRobert Mustacchi 	if (ret_val)
790c124a83eSRobert Mustacchi 		goto out;
79175eba5b6SRobert Mustacchi 
792c124a83eSRobert Mustacchi 	if (phy->id == M88E1512_E_PHY_ID)
793c124a83eSRobert Mustacchi 		ret_val = e1000_initialize_M88E1512_phy(hw);
79475eba5b6SRobert Mustacchi out:
79575eba5b6SRobert Mustacchi 	return ret_val;
79675eba5b6SRobert Mustacchi }
79775eba5b6SRobert Mustacchi 
79875eba5b6SRobert Mustacchi /**
79975eba5b6SRobert Mustacchi  *  e1000_set_d0_lplu_state_82575 - Set Low Power Linkup D0 state
80075eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
80175eba5b6SRobert Mustacchi  *  @active: TRUE to enable LPLU, FALSE to disable
80275eba5b6SRobert Mustacchi  *
80375eba5b6SRobert Mustacchi  *  Sets the LPLU D0 state according to the active flag.  When
80475eba5b6SRobert Mustacchi  *  activating LPLU this function also disables smart speed
80575eba5b6SRobert Mustacchi  *  and vice versa.  LPLU will not be activated unless the
80675eba5b6SRobert Mustacchi  *  device autonegotiation advertisement meets standards of
80775eba5b6SRobert Mustacchi  *  either 10 or 10/100 or 10/100/1000 at all duplexes.
80875eba5b6SRobert Mustacchi  *  This is a function pointer entry point only called by
80975eba5b6SRobert Mustacchi  *  PHY setup routines.
81075eba5b6SRobert Mustacchi  **/
e1000_set_d0_lplu_state_82575(struct e1000_hw * hw,bool active)81175eba5b6SRobert Mustacchi static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
81275eba5b6SRobert Mustacchi {
81375eba5b6SRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
81475eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
81575eba5b6SRobert Mustacchi 	u16 data;
81675eba5b6SRobert Mustacchi 
81775eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_set_d0_lplu_state_82575");
81875eba5b6SRobert Mustacchi 
81975eba5b6SRobert Mustacchi 	if (!(hw->phy.ops.read_reg))
82075eba5b6SRobert Mustacchi 		goto out;
82175eba5b6SRobert Mustacchi 
82275eba5b6SRobert Mustacchi 	ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
82375eba5b6SRobert Mustacchi 	if (ret_val)
82475eba5b6SRobert Mustacchi 		goto out;
82575eba5b6SRobert Mustacchi 
82675eba5b6SRobert Mustacchi 	if (active) {
82775eba5b6SRobert Mustacchi 		data |= IGP02E1000_PM_D0_LPLU;
82875eba5b6SRobert Mustacchi 		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
82975eba5b6SRobert Mustacchi 					     data);
83075eba5b6SRobert Mustacchi 		if (ret_val)
83175eba5b6SRobert Mustacchi 			goto out;
83275eba5b6SRobert Mustacchi 
83375eba5b6SRobert Mustacchi 		/* When LPLU is enabled, we should disable SmartSpeed */
83475eba5b6SRobert Mustacchi 		ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
83575eba5b6SRobert Mustacchi 					    &data);
83675eba5b6SRobert Mustacchi 		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
83775eba5b6SRobert Mustacchi 		ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
83875eba5b6SRobert Mustacchi 					     data);
83975eba5b6SRobert Mustacchi 		if (ret_val)
84075eba5b6SRobert Mustacchi 			goto out;
84175eba5b6SRobert Mustacchi 	} else {
84275eba5b6SRobert Mustacchi 		data &= ~IGP02E1000_PM_D0_LPLU;
84375eba5b6SRobert Mustacchi 		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
84475eba5b6SRobert Mustacchi 					     data);
84575eba5b6SRobert Mustacchi 		/*
84675eba5b6SRobert Mustacchi 		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
84775eba5b6SRobert Mustacchi 		 * during Dx states where the power conservation is most
84875eba5b6SRobert Mustacchi 		 * important.  During driver activity we should enable
84975eba5b6SRobert Mustacchi 		 * SmartSpeed, so performance is maintained.
85075eba5b6SRobert Mustacchi 		 */
85175eba5b6SRobert Mustacchi 		if (phy->smart_speed == e1000_smart_speed_on) {
85275eba5b6SRobert Mustacchi 			ret_val = phy->ops.read_reg(hw,
85375eba5b6SRobert Mustacchi 						    IGP01E1000_PHY_PORT_CONFIG,
85475eba5b6SRobert Mustacchi 						    &data);
85575eba5b6SRobert Mustacchi 			if (ret_val)
85675eba5b6SRobert Mustacchi 				goto out;
85775eba5b6SRobert Mustacchi 
85875eba5b6SRobert Mustacchi 			data |= IGP01E1000_PSCFR_SMART_SPEED;
85975eba5b6SRobert Mustacchi 			ret_val = phy->ops.write_reg(hw,
86075eba5b6SRobert Mustacchi 						     IGP01E1000_PHY_PORT_CONFIG,
86175eba5b6SRobert Mustacchi 						     data);
86275eba5b6SRobert Mustacchi 			if (ret_val)
86375eba5b6SRobert Mustacchi 				goto out;
86475eba5b6SRobert Mustacchi 		} else if (phy->smart_speed == e1000_smart_speed_off) {
86575eba5b6SRobert Mustacchi 			ret_val = phy->ops.read_reg(hw,
86675eba5b6SRobert Mustacchi 						    IGP01E1000_PHY_PORT_CONFIG,
86775eba5b6SRobert Mustacchi 						    &data);
86875eba5b6SRobert Mustacchi 			if (ret_val)
86975eba5b6SRobert Mustacchi 				goto out;
87075eba5b6SRobert Mustacchi 
87175eba5b6SRobert Mustacchi 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
87275eba5b6SRobert Mustacchi 			ret_val = phy->ops.write_reg(hw,
87375eba5b6SRobert Mustacchi 						     IGP01E1000_PHY_PORT_CONFIG,
87475eba5b6SRobert Mustacchi 						     data);
87575eba5b6SRobert Mustacchi 			if (ret_val)
87675eba5b6SRobert Mustacchi 				goto out;
87775eba5b6SRobert Mustacchi 		}
87875eba5b6SRobert Mustacchi 	}
87975eba5b6SRobert Mustacchi 
88075eba5b6SRobert Mustacchi out:
88175eba5b6SRobert Mustacchi 	return ret_val;
88275eba5b6SRobert Mustacchi }
88375eba5b6SRobert Mustacchi 
88475eba5b6SRobert Mustacchi /**
88575eba5b6SRobert Mustacchi  *  e1000_set_d0_lplu_state_82580 - Set Low Power Linkup D0 state
88675eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
88775eba5b6SRobert Mustacchi  *  @active: TRUE to enable LPLU, FALSE to disable
88875eba5b6SRobert Mustacchi  *
88975eba5b6SRobert Mustacchi  *  Sets the LPLU D0 state according to the active flag.  When
89075eba5b6SRobert Mustacchi  *  activating LPLU this function also disables smart speed
89175eba5b6SRobert Mustacchi  *  and vice versa.  LPLU will not be activated unless the
89275eba5b6SRobert Mustacchi  *  device autonegotiation advertisement meets standards of
89375eba5b6SRobert Mustacchi  *  either 10 or 10/100 or 10/100/1000 at all duplexes.
89475eba5b6SRobert Mustacchi  *  This is a function pointer entry point only called by
89575eba5b6SRobert Mustacchi  *  PHY setup routines.
89675eba5b6SRobert Mustacchi  **/
e1000_set_d0_lplu_state_82580(struct e1000_hw * hw,bool active)89775eba5b6SRobert Mustacchi static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
89875eba5b6SRobert Mustacchi {
89975eba5b6SRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
90075eba5b6SRobert Mustacchi 	u32 data;
90175eba5b6SRobert Mustacchi 
90275eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_set_d0_lplu_state_82580");
90375eba5b6SRobert Mustacchi 
90475eba5b6SRobert Mustacchi 	data = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
90575eba5b6SRobert Mustacchi 
90675eba5b6SRobert Mustacchi 	if (active) {
90775eba5b6SRobert Mustacchi 		data |= E1000_82580_PM_D0_LPLU;
90875eba5b6SRobert Mustacchi 
90975eba5b6SRobert Mustacchi 		/* When LPLU is enabled, we should disable SmartSpeed */
91075eba5b6SRobert Mustacchi 		data &= ~E1000_82580_PM_SPD;
91175eba5b6SRobert Mustacchi 	} else {
91275eba5b6SRobert Mustacchi 		data &= ~E1000_82580_PM_D0_LPLU;
91375eba5b6SRobert Mustacchi 
91475eba5b6SRobert Mustacchi 		/*
91575eba5b6SRobert Mustacchi 		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
91675eba5b6SRobert Mustacchi 		 * during Dx states where the power conservation is most
91775eba5b6SRobert Mustacchi 		 * important.  During driver activity we should enable
91875eba5b6SRobert Mustacchi 		 * SmartSpeed, so performance is maintained.
91975eba5b6SRobert Mustacchi 		 */
92075eba5b6SRobert Mustacchi 		if (phy->smart_speed == e1000_smart_speed_on)
92175eba5b6SRobert Mustacchi 			data |= E1000_82580_PM_SPD;
92275eba5b6SRobert Mustacchi 		else if (phy->smart_speed == e1000_smart_speed_off)
92375eba5b6SRobert Mustacchi 			data &= ~E1000_82580_PM_SPD;
92475eba5b6SRobert Mustacchi 	}
92575eba5b6SRobert Mustacchi 
92675eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
927c124a83eSRobert Mustacchi 	return E1000_SUCCESS;
92875eba5b6SRobert Mustacchi }
92975eba5b6SRobert Mustacchi 
93075eba5b6SRobert Mustacchi /**
93175eba5b6SRobert Mustacchi  *  e1000_set_d3_lplu_state_82580 - Sets low power link up state for D3
93275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
93375eba5b6SRobert Mustacchi  *  @active: boolean used to enable/disable lplu
93475eba5b6SRobert Mustacchi  *
93575eba5b6SRobert Mustacchi  *  Success returns 0, Failure returns 1
93675eba5b6SRobert Mustacchi  *
93775eba5b6SRobert Mustacchi  *  The low power link up (lplu) state is set to the power management level D3
93875eba5b6SRobert Mustacchi  *  and SmartSpeed is disabled when active is TRUE, else clear lplu for D3
93975eba5b6SRobert Mustacchi  *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
94075eba5b6SRobert Mustacchi  *  is used during Dx states where the power conservation is most important.
94175eba5b6SRobert Mustacchi  *  During driver activity, SmartSpeed should be enabled so performance is
94275eba5b6SRobert Mustacchi  *  maintained.
94375eba5b6SRobert Mustacchi  **/
e1000_set_d3_lplu_state_82580(struct e1000_hw * hw,bool active)94475eba5b6SRobert Mustacchi s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
94575eba5b6SRobert Mustacchi {
94675eba5b6SRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
94775eba5b6SRobert Mustacchi 	u32 data;
94875eba5b6SRobert Mustacchi 
94975eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_set_d3_lplu_state_82580");
95075eba5b6SRobert Mustacchi 
95175eba5b6SRobert Mustacchi 	data = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
95275eba5b6SRobert Mustacchi 
95375eba5b6SRobert Mustacchi 	if (!active) {
95475eba5b6SRobert Mustacchi 		data &= ~E1000_82580_PM_D3_LPLU;
95575eba5b6SRobert Mustacchi 		/*
95675eba5b6SRobert Mustacchi 		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
95775eba5b6SRobert Mustacchi 		 * during Dx states where the power conservation is most
95875eba5b6SRobert Mustacchi 		 * important.  During driver activity we should enable
95975eba5b6SRobert Mustacchi 		 * SmartSpeed, so performance is maintained.
96075eba5b6SRobert Mustacchi 		 */
96175eba5b6SRobert Mustacchi 		if (phy->smart_speed == e1000_smart_speed_on)
96275eba5b6SRobert Mustacchi 			data |= E1000_82580_PM_SPD;
96375eba5b6SRobert Mustacchi 		else if (phy->smart_speed == e1000_smart_speed_off)
96475eba5b6SRobert Mustacchi 			data &= ~E1000_82580_PM_SPD;
96575eba5b6SRobert Mustacchi 	} else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
96675eba5b6SRobert Mustacchi 		   (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
96775eba5b6SRobert Mustacchi 		   (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
96875eba5b6SRobert Mustacchi 		data |= E1000_82580_PM_D3_LPLU;
96975eba5b6SRobert Mustacchi 		/* When LPLU is enabled, we should disable SmartSpeed */
97075eba5b6SRobert Mustacchi 		data &= ~E1000_82580_PM_SPD;
97175eba5b6SRobert Mustacchi 	}
97275eba5b6SRobert Mustacchi 
97375eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
974c124a83eSRobert Mustacchi 	return E1000_SUCCESS;
97575eba5b6SRobert Mustacchi }
97675eba5b6SRobert Mustacchi 
97775eba5b6SRobert Mustacchi /**
97875eba5b6SRobert Mustacchi  *  e1000_acquire_nvm_82575 - Request for access to EEPROM
97975eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
98075eba5b6SRobert Mustacchi  *
98175eba5b6SRobert Mustacchi  *  Acquire the necessary semaphores for exclusive access to the EEPROM.
98275eba5b6SRobert Mustacchi  *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
98375eba5b6SRobert Mustacchi  *  Return successful if access grant bit set, else clear the request for
98475eba5b6SRobert Mustacchi  *  EEPROM access and return -E1000_ERR_NVM (-1).
98575eba5b6SRobert Mustacchi  **/
e1000_acquire_nvm_82575(struct e1000_hw * hw)98675eba5b6SRobert Mustacchi static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
98775eba5b6SRobert Mustacchi {
988c124a83eSRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
98975eba5b6SRobert Mustacchi 
99075eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_acquire_nvm_82575");
99175eba5b6SRobert Mustacchi 
99275eba5b6SRobert Mustacchi 	ret_val = e1000_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
99375eba5b6SRobert Mustacchi 	if (ret_val)
99475eba5b6SRobert Mustacchi 		goto out;
99575eba5b6SRobert Mustacchi 
99675eba5b6SRobert Mustacchi 	/*
99775eba5b6SRobert Mustacchi 	 * Check if there is some access
99875eba5b6SRobert Mustacchi 	 * error this access may hook on
99975eba5b6SRobert Mustacchi 	 */
100075eba5b6SRobert Mustacchi 	if (hw->mac.type == e1000_i350) {
100175eba5b6SRobert Mustacchi 		u32 eecd = E1000_READ_REG(hw, E1000_EECD);
100275eba5b6SRobert Mustacchi 		if (eecd & (E1000_EECD_BLOCKED | E1000_EECD_ABORT |
100375eba5b6SRobert Mustacchi 		    E1000_EECD_TIMEOUT)) {
100475eba5b6SRobert Mustacchi 			/* Clear all access error flags */
100575eba5b6SRobert Mustacchi 			E1000_WRITE_REG(hw, E1000_EECD, eecd |
100675eba5b6SRobert Mustacchi 					E1000_EECD_ERROR_CLR);
100775eba5b6SRobert Mustacchi 			DEBUGOUT("Nvm bit banging access error detected and cleared.\n");
100875eba5b6SRobert Mustacchi 		}
100975eba5b6SRobert Mustacchi 	}
1010c124a83eSRobert Mustacchi 
101175eba5b6SRobert Mustacchi 	if (hw->mac.type == e1000_82580) {
101275eba5b6SRobert Mustacchi 		u32 eecd = E1000_READ_REG(hw, E1000_EECD);
101375eba5b6SRobert Mustacchi 		if (eecd & E1000_EECD_BLOCKED) {
101475eba5b6SRobert Mustacchi 			/* Clear access error flag */
101575eba5b6SRobert Mustacchi 			E1000_WRITE_REG(hw, E1000_EECD, eecd |
101675eba5b6SRobert Mustacchi 					E1000_EECD_BLOCKED);
101775eba5b6SRobert Mustacchi 			DEBUGOUT("Nvm bit banging access error detected and cleared.\n");
101875eba5b6SRobert Mustacchi 		}
101975eba5b6SRobert Mustacchi 	}
102075eba5b6SRobert Mustacchi 
102175eba5b6SRobert Mustacchi 	ret_val = e1000_acquire_nvm_generic(hw);
102275eba5b6SRobert Mustacchi 	if (ret_val)
102375eba5b6SRobert Mustacchi 		e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
102475eba5b6SRobert Mustacchi 
102575eba5b6SRobert Mustacchi out:
102675eba5b6SRobert Mustacchi 	return ret_val;
102775eba5b6SRobert Mustacchi }
102875eba5b6SRobert Mustacchi 
102975eba5b6SRobert Mustacchi /**
103075eba5b6SRobert Mustacchi  *  e1000_release_nvm_82575 - Release exclusive access to EEPROM
103175eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
103275eba5b6SRobert Mustacchi  *
103375eba5b6SRobert Mustacchi  *  Stop any current commands to the EEPROM and clear the EEPROM request bit,
103475eba5b6SRobert Mustacchi  *  then release the semaphores acquired.
103575eba5b6SRobert Mustacchi  **/
e1000_release_nvm_82575(struct e1000_hw * hw)103675eba5b6SRobert Mustacchi static void e1000_release_nvm_82575(struct e1000_hw *hw)
103775eba5b6SRobert Mustacchi {
103875eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_release_nvm_82575");
103975eba5b6SRobert Mustacchi 
104075eba5b6SRobert Mustacchi 	e1000_release_nvm_generic(hw);
104175eba5b6SRobert Mustacchi 
104275eba5b6SRobert Mustacchi 	e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
104375eba5b6SRobert Mustacchi }
104475eba5b6SRobert Mustacchi 
104575eba5b6SRobert Mustacchi /**
104675eba5b6SRobert Mustacchi  *  e1000_acquire_swfw_sync_82575 - Acquire SW/FW semaphore
104775eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
104875eba5b6SRobert Mustacchi  *  @mask: specifies which semaphore to acquire
104975eba5b6SRobert Mustacchi  *
105075eba5b6SRobert Mustacchi  *  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
105175eba5b6SRobert Mustacchi  *  will also specify which port we're acquiring the lock for.
105275eba5b6SRobert Mustacchi  **/
e1000_acquire_swfw_sync_82575(struct e1000_hw * hw,u16 mask)105375eba5b6SRobert Mustacchi static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
105475eba5b6SRobert Mustacchi {
105575eba5b6SRobert Mustacchi 	u32 swfw_sync;
105675eba5b6SRobert Mustacchi 	u32 swmask = mask;
105775eba5b6SRobert Mustacchi 	u32 fwmask = mask << 16;
105875eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
105949b78600SRobert Mustacchi 	s32 i = 0, timeout = 200;
106075eba5b6SRobert Mustacchi 
106175eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_acquire_swfw_sync_82575");
106275eba5b6SRobert Mustacchi 
106375eba5b6SRobert Mustacchi 	while (i < timeout) {
106475eba5b6SRobert Mustacchi 		if (e1000_get_hw_semaphore_generic(hw)) {
106575eba5b6SRobert Mustacchi 			ret_val = -E1000_ERR_SWFW_SYNC;
106675eba5b6SRobert Mustacchi 			goto out;
106775eba5b6SRobert Mustacchi 		}
106875eba5b6SRobert Mustacchi 
106975eba5b6SRobert Mustacchi 		swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
107075eba5b6SRobert Mustacchi 		if (!(swfw_sync & (fwmask | swmask)))
107175eba5b6SRobert Mustacchi 			break;
107275eba5b6SRobert Mustacchi 
107375eba5b6SRobert Mustacchi 		/*
107475eba5b6SRobert Mustacchi 		 * Firmware currently using resource (fwmask)
107575eba5b6SRobert Mustacchi 		 * or other software thread using resource (swmask)
107675eba5b6SRobert Mustacchi 		 */
107775eba5b6SRobert Mustacchi 		e1000_put_hw_semaphore_generic(hw);
107875eba5b6SRobert Mustacchi 		msec_delay_irq(5);
107975eba5b6SRobert Mustacchi 		i++;
108075eba5b6SRobert Mustacchi 	}
108175eba5b6SRobert Mustacchi 
108275eba5b6SRobert Mustacchi 	if (i == timeout) {
108375eba5b6SRobert Mustacchi 		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
108475eba5b6SRobert Mustacchi 		ret_val = -E1000_ERR_SWFW_SYNC;
108575eba5b6SRobert Mustacchi 		goto out;
108675eba5b6SRobert Mustacchi 	}
108775eba5b6SRobert Mustacchi 
108875eba5b6SRobert Mustacchi 	swfw_sync |= swmask;
108975eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
109075eba5b6SRobert Mustacchi 
109175eba5b6SRobert Mustacchi 	e1000_put_hw_semaphore_generic(hw);
109275eba5b6SRobert Mustacchi 
109375eba5b6SRobert Mustacchi out:
109475eba5b6SRobert Mustacchi 	return ret_val;
109575eba5b6SRobert Mustacchi }
109675eba5b6SRobert Mustacchi 
109775eba5b6SRobert Mustacchi /**
109875eba5b6SRobert Mustacchi  *  e1000_release_swfw_sync_82575 - Release SW/FW semaphore
109975eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
110075eba5b6SRobert Mustacchi  *  @mask: specifies which semaphore to acquire
110175eba5b6SRobert Mustacchi  *
110275eba5b6SRobert Mustacchi  *  Release the SW/FW semaphore used to access the PHY or NVM.  The mask
110375eba5b6SRobert Mustacchi  *  will also specify which port we're releasing the lock for.
110475eba5b6SRobert Mustacchi  **/
e1000_release_swfw_sync_82575(struct e1000_hw * hw,u16 mask)110575eba5b6SRobert Mustacchi static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
110675eba5b6SRobert Mustacchi {
110775eba5b6SRobert Mustacchi 	u32 swfw_sync;
110875eba5b6SRobert Mustacchi 
110975eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_release_swfw_sync_82575");
111075eba5b6SRobert Mustacchi 
111175eba5b6SRobert Mustacchi 	while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS)
111275eba5b6SRobert Mustacchi 		; /* Empty */
111375eba5b6SRobert Mustacchi 
111475eba5b6SRobert Mustacchi 	swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
111575eba5b6SRobert Mustacchi 	swfw_sync &= ~mask;
111675eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
111775eba5b6SRobert Mustacchi 
111875eba5b6SRobert Mustacchi 	e1000_put_hw_semaphore_generic(hw);
111975eba5b6SRobert Mustacchi }
112075eba5b6SRobert Mustacchi 
112175eba5b6SRobert Mustacchi /**
112275eba5b6SRobert Mustacchi  *  e1000_get_cfg_done_82575 - Read config done bit
112375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
112475eba5b6SRobert Mustacchi  *
112575eba5b6SRobert Mustacchi  *  Read the management control register for the config done bit for
112675eba5b6SRobert Mustacchi  *  completion status.  NOTE: silicon which is EEPROM-less will fail trying
112775eba5b6SRobert Mustacchi  *  to read the config done bit, so an error is *ONLY* logged and returns
112875eba5b6SRobert Mustacchi  *  E1000_SUCCESS.  If we were to return with error, EEPROM-less silicon
112975eba5b6SRobert Mustacchi  *  would not be able to be reset or change link.
113075eba5b6SRobert Mustacchi  **/
e1000_get_cfg_done_82575(struct e1000_hw * hw)113175eba5b6SRobert Mustacchi static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
113275eba5b6SRobert Mustacchi {
113375eba5b6SRobert Mustacchi 	s32 timeout = PHY_CFG_TIMEOUT;
113475eba5b6SRobert Mustacchi 	u32 mask = E1000_NVM_CFG_DONE_PORT_0;
113575eba5b6SRobert Mustacchi 
113675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_get_cfg_done_82575");
113775eba5b6SRobert Mustacchi 
113875eba5b6SRobert Mustacchi 	if (hw->bus.func == E1000_FUNC_1)
113975eba5b6SRobert Mustacchi 		mask = E1000_NVM_CFG_DONE_PORT_1;
114075eba5b6SRobert Mustacchi 	else if (hw->bus.func == E1000_FUNC_2)
114175eba5b6SRobert Mustacchi 		mask = E1000_NVM_CFG_DONE_PORT_2;
114275eba5b6SRobert Mustacchi 	else if (hw->bus.func == E1000_FUNC_3)
114375eba5b6SRobert Mustacchi 		mask = E1000_NVM_CFG_DONE_PORT_3;
114475eba5b6SRobert Mustacchi 	while (timeout) {
114575eba5b6SRobert Mustacchi 		if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask)
114675eba5b6SRobert Mustacchi 			break;
114775eba5b6SRobert Mustacchi 		msec_delay(1);
114875eba5b6SRobert Mustacchi 		timeout--;
114975eba5b6SRobert Mustacchi 	}
115075eba5b6SRobert Mustacchi 	if (!timeout)
115175eba5b6SRobert Mustacchi 		DEBUGOUT("MNG configuration cycle has not completed.\n");
115275eba5b6SRobert Mustacchi 
115375eba5b6SRobert Mustacchi 	/* If EEPROM is not marked present, init the PHY manually */
115475eba5b6SRobert Mustacchi 	if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) &&
115575eba5b6SRobert Mustacchi 	    (hw->phy.type == e1000_phy_igp_3))
115675eba5b6SRobert Mustacchi 		e1000_phy_init_script_igp3(hw);
115775eba5b6SRobert Mustacchi 
1158c124a83eSRobert Mustacchi 	return E1000_SUCCESS;
115975eba5b6SRobert Mustacchi }
116075eba5b6SRobert Mustacchi 
116175eba5b6SRobert Mustacchi /**
116275eba5b6SRobert Mustacchi  *  e1000_get_link_up_info_82575 - Get link speed/duplex info
116375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
116475eba5b6SRobert Mustacchi  *  @speed: stores the current speed
116575eba5b6SRobert Mustacchi  *  @duplex: stores the current duplex
116675eba5b6SRobert Mustacchi  *
116775eba5b6SRobert Mustacchi  *  This is a wrapper function, if using the serial gigabit media independent
116875eba5b6SRobert Mustacchi  *  interface, use PCS to retrieve the link speed and duplex information.
116975eba5b6SRobert Mustacchi  *  Otherwise, use the generic function to get the link speed and duplex info.
117075eba5b6SRobert Mustacchi  **/
e1000_get_link_up_info_82575(struct e1000_hw * hw,u16 * speed,u16 * duplex)117175eba5b6SRobert Mustacchi static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
117275eba5b6SRobert Mustacchi 					u16 *duplex)
117375eba5b6SRobert Mustacchi {
117475eba5b6SRobert Mustacchi 	s32 ret_val;
117575eba5b6SRobert Mustacchi 
117675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_get_link_up_info_82575");
117775eba5b6SRobert Mustacchi 
117875eba5b6SRobert Mustacchi 	if (hw->phy.media_type != e1000_media_type_copper)
117975eba5b6SRobert Mustacchi 		ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, speed,
118075eba5b6SRobert Mustacchi 							       duplex);
118175eba5b6SRobert Mustacchi 	else
118275eba5b6SRobert Mustacchi 		ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed,
118375eba5b6SRobert Mustacchi 								    duplex);
118475eba5b6SRobert Mustacchi 
118575eba5b6SRobert Mustacchi 	return ret_val;
118675eba5b6SRobert Mustacchi }
118775eba5b6SRobert Mustacchi 
118875eba5b6SRobert Mustacchi /**
118975eba5b6SRobert Mustacchi  *  e1000_check_for_link_82575 - Check for link
119075eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
119175eba5b6SRobert Mustacchi  *
119275eba5b6SRobert Mustacchi  *  If sgmii is enabled, then use the pcs register to determine link, otherwise
119375eba5b6SRobert Mustacchi  *  use the generic interface for determining link.
119475eba5b6SRobert Mustacchi  **/
e1000_check_for_link_82575(struct e1000_hw * hw)119575eba5b6SRobert Mustacchi static s32 e1000_check_for_link_82575(struct e1000_hw *hw)
119675eba5b6SRobert Mustacchi {
119775eba5b6SRobert Mustacchi 	s32 ret_val;
119875eba5b6SRobert Mustacchi 	u16 speed, duplex;
119975eba5b6SRobert Mustacchi 
120075eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_check_for_link_82575");
120175eba5b6SRobert Mustacchi 
120275eba5b6SRobert Mustacchi 	if (hw->phy.media_type != e1000_media_type_copper) {
120375eba5b6SRobert Mustacchi 		ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed,
120475eba5b6SRobert Mustacchi 							       &duplex);
120575eba5b6SRobert Mustacchi 		/*
120675eba5b6SRobert Mustacchi 		 * Use this flag to determine if link needs to be checked or
120775eba5b6SRobert Mustacchi 		 * not.  If we have link clear the flag so that we do not
120875eba5b6SRobert Mustacchi 		 * continue to check for link.
120975eba5b6SRobert Mustacchi 		 */
121075eba5b6SRobert Mustacchi 		hw->mac.get_link_status = !hw->mac.serdes_has_link;
121175eba5b6SRobert Mustacchi 
121275eba5b6SRobert Mustacchi 		/*
121375eba5b6SRobert Mustacchi 		 * Configure Flow Control now that Auto-Neg has completed.
121475eba5b6SRobert Mustacchi 		 * First, we need to restore the desired flow control
121575eba5b6SRobert Mustacchi 		 * settings because we may have had to re-autoneg with a
121675eba5b6SRobert Mustacchi 		 * different link partner.
121775eba5b6SRobert Mustacchi 		 */
121875eba5b6SRobert Mustacchi 		ret_val = e1000_config_fc_after_link_up_generic(hw);
121975eba5b6SRobert Mustacchi 		if (ret_val)
122075eba5b6SRobert Mustacchi 			DEBUGOUT("Error configuring flow control\n");
122175eba5b6SRobert Mustacchi 	} else {
122275eba5b6SRobert Mustacchi 		ret_val = e1000_check_for_copper_link_generic(hw);
122375eba5b6SRobert Mustacchi 	}
122475eba5b6SRobert Mustacchi 
122575eba5b6SRobert Mustacchi 	return ret_val;
122675eba5b6SRobert Mustacchi }
122775eba5b6SRobert Mustacchi 
1228c124a83eSRobert Mustacchi /**
1229c124a83eSRobert Mustacchi  *  e1000_check_for_link_media_swap - Check which M88E1112 interface linked
1230c124a83eSRobert Mustacchi  *  @hw: pointer to the HW structure
1231c124a83eSRobert Mustacchi  *
1232c124a83eSRobert Mustacchi  *  Poll the M88E1112 interfaces to see which interface achieved link.
1233c124a83eSRobert Mustacchi  */
e1000_check_for_link_media_swap(struct e1000_hw * hw)1234c124a83eSRobert Mustacchi static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
1235c124a83eSRobert Mustacchi {
1236c124a83eSRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
1237c124a83eSRobert Mustacchi 	s32 ret_val;
1238c124a83eSRobert Mustacchi 	u16 data;
1239c124a83eSRobert Mustacchi 	u8 port = 0;
1240c124a83eSRobert Mustacchi 
1241c124a83eSRobert Mustacchi 	DEBUGFUNC("e1000_check_for_link_media_swap");
1242c124a83eSRobert Mustacchi 
124349b78600SRobert Mustacchi 	/* Check for copper. */
1244c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
1245c124a83eSRobert Mustacchi 	if (ret_val)
1246c124a83eSRobert Mustacchi 		return ret_val;
1247c124a83eSRobert Mustacchi 
1248c124a83eSRobert Mustacchi 	ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data);
1249c124a83eSRobert Mustacchi 	if (ret_val)
1250c124a83eSRobert Mustacchi 		return ret_val;
1251c124a83eSRobert Mustacchi 
1252c124a83eSRobert Mustacchi 	if (data & E1000_M88E1112_STATUS_LINK)
1253c124a83eSRobert Mustacchi 		port = E1000_MEDIA_PORT_COPPER;
1254c124a83eSRobert Mustacchi 
125549b78600SRobert Mustacchi 	/* Check for other. */
1256c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 1);
1257c124a83eSRobert Mustacchi 	if (ret_val)
1258c124a83eSRobert Mustacchi 		return ret_val;
1259c124a83eSRobert Mustacchi 
1260c124a83eSRobert Mustacchi 	ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data);
1261c124a83eSRobert Mustacchi 	if (ret_val)
1262c124a83eSRobert Mustacchi 		return ret_val;
1263c124a83eSRobert Mustacchi 
1264c124a83eSRobert Mustacchi 	if (data & E1000_M88E1112_STATUS_LINK)
1265c124a83eSRobert Mustacchi 		port = E1000_MEDIA_PORT_OTHER;
1266c124a83eSRobert Mustacchi 
1267c124a83eSRobert Mustacchi 	/* Determine if a swap needs to happen. */
1268c124a83eSRobert Mustacchi 	if (port && (hw->dev_spec._82575.media_port != port)) {
1269c124a83eSRobert Mustacchi 		hw->dev_spec._82575.media_port = port;
1270c124a83eSRobert Mustacchi 		hw->dev_spec._82575.media_changed = TRUE;
127149b78600SRobert Mustacchi 	}
127249b78600SRobert Mustacchi 
127349b78600SRobert Mustacchi 	if (port == E1000_MEDIA_PORT_COPPER) {
127449b78600SRobert Mustacchi 		/* reset page to 0 */
127549b78600SRobert Mustacchi 		ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
127649b78600SRobert Mustacchi 		if (ret_val)
127749b78600SRobert Mustacchi 			return ret_val;
127849b78600SRobert Mustacchi 		e1000_check_for_link_82575(hw);
1279c124a83eSRobert Mustacchi 	} else {
128049b78600SRobert Mustacchi 		e1000_check_for_link_82575(hw);
128149b78600SRobert Mustacchi 		/* reset page to 0 */
128249b78600SRobert Mustacchi 		ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
128349b78600SRobert Mustacchi 		if (ret_val)
128449b78600SRobert Mustacchi 			return ret_val;
1285c124a83eSRobert Mustacchi 	}
1286c124a83eSRobert Mustacchi 
1287c124a83eSRobert Mustacchi 	return E1000_SUCCESS;
1288c124a83eSRobert Mustacchi }
1289c124a83eSRobert Mustacchi 
129075eba5b6SRobert Mustacchi /**
129175eba5b6SRobert Mustacchi  *  e1000_power_up_serdes_link_82575 - Power up the serdes link after shutdown
129275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
129375eba5b6SRobert Mustacchi  **/
e1000_power_up_serdes_link_82575(struct e1000_hw * hw)129475eba5b6SRobert Mustacchi static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw)
129575eba5b6SRobert Mustacchi {
129675eba5b6SRobert Mustacchi 	u32 reg;
129775eba5b6SRobert Mustacchi 
129875eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_power_up_serdes_link_82575");
129975eba5b6SRobert Mustacchi 
130075eba5b6SRobert Mustacchi 	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
130175eba5b6SRobert Mustacchi 	    !e1000_sgmii_active_82575(hw))
130275eba5b6SRobert Mustacchi 		return;
130375eba5b6SRobert Mustacchi 
130475eba5b6SRobert Mustacchi 	/* Enable PCS to turn on link */
130575eba5b6SRobert Mustacchi 	reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
130675eba5b6SRobert Mustacchi 	reg |= E1000_PCS_CFG_PCS_EN;
130775eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
130875eba5b6SRobert Mustacchi 
130975eba5b6SRobert Mustacchi 	/* Power up the laser */
131075eba5b6SRobert Mustacchi 	reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
131175eba5b6SRobert Mustacchi 	reg &= ~E1000_CTRL_EXT_SDP3_DATA;
131275eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
131375eba5b6SRobert Mustacchi 
131475eba5b6SRobert Mustacchi 	/* flush the write to verify completion */
131575eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
131675eba5b6SRobert Mustacchi 	msec_delay(1);
131775eba5b6SRobert Mustacchi }
131875eba5b6SRobert Mustacchi 
131975eba5b6SRobert Mustacchi /**
132075eba5b6SRobert Mustacchi  *  e1000_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
132175eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
132275eba5b6SRobert Mustacchi  *  @speed: stores the current speed
132375eba5b6SRobert Mustacchi  *  @duplex: stores the current duplex
132475eba5b6SRobert Mustacchi  *
132575eba5b6SRobert Mustacchi  *  Using the physical coding sub-layer (PCS), retrieve the current speed and
132675eba5b6SRobert Mustacchi  *  duplex, then store the values in the pointers provided.
132775eba5b6SRobert Mustacchi  **/
e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw * hw,u16 * speed,u16 * duplex)132875eba5b6SRobert Mustacchi static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
132975eba5b6SRobert Mustacchi 						u16 *speed, u16 *duplex)
133075eba5b6SRobert Mustacchi {
133175eba5b6SRobert Mustacchi 	struct e1000_mac_info *mac = &hw->mac;
133275eba5b6SRobert Mustacchi 	u32 pcs;
133313485e69SGarrett D'Amore 	u32 status;
133475eba5b6SRobert Mustacchi 
133575eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575");
133675eba5b6SRobert Mustacchi 
133775eba5b6SRobert Mustacchi 	/*
133875eba5b6SRobert Mustacchi 	 * Read the PCS Status register for link state. For non-copper mode,
133975eba5b6SRobert Mustacchi 	 * the status register is not accurate. The PCS status register is
134075eba5b6SRobert Mustacchi 	 * used instead.
134175eba5b6SRobert Mustacchi 	 */
134275eba5b6SRobert Mustacchi 	pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT);
134375eba5b6SRobert Mustacchi 
134475eba5b6SRobert Mustacchi 	/*
134575eba5b6SRobert Mustacchi 	 * The link up bit determines when link is up on autoneg.
134675eba5b6SRobert Mustacchi 	 */
134775eba5b6SRobert Mustacchi 	if (pcs & E1000_PCS_LSTS_LINK_OK) {
134875eba5b6SRobert Mustacchi 		mac->serdes_has_link = TRUE;
134975eba5b6SRobert Mustacchi 
135075eba5b6SRobert Mustacchi 		/* Detect and store PCS speed */
135175eba5b6SRobert Mustacchi 		if (pcs & E1000_PCS_LSTS_SPEED_1000)
135275eba5b6SRobert Mustacchi 			*speed = SPEED_1000;
135375eba5b6SRobert Mustacchi 		else if (pcs & E1000_PCS_LSTS_SPEED_100)
135475eba5b6SRobert Mustacchi 			*speed = SPEED_100;
135575eba5b6SRobert Mustacchi 		else
135675eba5b6SRobert Mustacchi 			*speed = SPEED_10;
135775eba5b6SRobert Mustacchi 
135875eba5b6SRobert Mustacchi 		/* Detect and store PCS duplex */
135975eba5b6SRobert Mustacchi 		if (pcs & E1000_PCS_LSTS_DUPLEX_FULL)
136075eba5b6SRobert Mustacchi 			*duplex = FULL_DUPLEX;
136175eba5b6SRobert Mustacchi 		else
136275eba5b6SRobert Mustacchi 			*duplex = HALF_DUPLEX;
136375eba5b6SRobert Mustacchi 
136413485e69SGarrett D'Amore 		/* Check if it is an I354 2.5Gb backplane connection. */
136513485e69SGarrett D'Amore 		if (mac->type == e1000_i354) {
136613485e69SGarrett D'Amore 			status = E1000_READ_REG(hw, E1000_STATUS);
136713485e69SGarrett D'Amore 			if ((status & E1000_STATUS_2P5_SKU) &&
136813485e69SGarrett D'Amore 			    !(status & E1000_STATUS_2P5_SKU_OVER)) {
136913485e69SGarrett D'Amore 				*speed = SPEED_2500;
137013485e69SGarrett D'Amore 				*duplex = FULL_DUPLEX;
137113485e69SGarrett D'Amore 				DEBUGOUT("2500 Mbs, ");
137213485e69SGarrett D'Amore 				DEBUGOUT("Full Duplex\n");
137313485e69SGarrett D'Amore 			}
137413485e69SGarrett D'Amore 		}
137513485e69SGarrett D'Amore 
137675eba5b6SRobert Mustacchi 	} else {
137775eba5b6SRobert Mustacchi 		mac->serdes_has_link = FALSE;
137875eba5b6SRobert Mustacchi 		*speed = 0;
137975eba5b6SRobert Mustacchi 		*duplex = 0;
138075eba5b6SRobert Mustacchi 	}
138175eba5b6SRobert Mustacchi 
138275eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
138375eba5b6SRobert Mustacchi }
138475eba5b6SRobert Mustacchi 
138575eba5b6SRobert Mustacchi /**
138675eba5b6SRobert Mustacchi  *  e1000_shutdown_serdes_link_82575 - Remove link during power down
138775eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
138875eba5b6SRobert Mustacchi  *
138975eba5b6SRobert Mustacchi  *  In the case of serdes shut down sfp and PCS on driver unload
139075eba5b6SRobert Mustacchi  *  when management pass thru is not enabled.
139175eba5b6SRobert Mustacchi  **/
e1000_shutdown_serdes_link_82575(struct e1000_hw * hw)139275eba5b6SRobert Mustacchi void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw)
139375eba5b6SRobert Mustacchi {
139475eba5b6SRobert Mustacchi 	u32 reg;
139575eba5b6SRobert Mustacchi 
139675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_shutdown_serdes_link_82575");
139775eba5b6SRobert Mustacchi 
139875eba5b6SRobert Mustacchi 	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
139975eba5b6SRobert Mustacchi 	    !e1000_sgmii_active_82575(hw))
140075eba5b6SRobert Mustacchi 		return;
140175eba5b6SRobert Mustacchi 
140275eba5b6SRobert Mustacchi 	if (!e1000_enable_mng_pass_thru(hw)) {
140375eba5b6SRobert Mustacchi 		/* Disable PCS to turn off link */
140475eba5b6SRobert Mustacchi 		reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
140575eba5b6SRobert Mustacchi 		reg &= ~E1000_PCS_CFG_PCS_EN;
140675eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
140775eba5b6SRobert Mustacchi 
140875eba5b6SRobert Mustacchi 		/* shutdown the laser */
140975eba5b6SRobert Mustacchi 		reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
141075eba5b6SRobert Mustacchi 		reg |= E1000_CTRL_EXT_SDP3_DATA;
141175eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
141275eba5b6SRobert Mustacchi 
141375eba5b6SRobert Mustacchi 		/* flush the write to verify completion */
141475eba5b6SRobert Mustacchi 		E1000_WRITE_FLUSH(hw);
141575eba5b6SRobert Mustacchi 		msec_delay(1);
141675eba5b6SRobert Mustacchi 	}
141775eba5b6SRobert Mustacchi 
141875eba5b6SRobert Mustacchi 	return;
141975eba5b6SRobert Mustacchi }
142075eba5b6SRobert Mustacchi 
142175eba5b6SRobert Mustacchi /**
142275eba5b6SRobert Mustacchi  *  e1000_reset_hw_82575 - Reset hardware
142375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
142475eba5b6SRobert Mustacchi  *
142575eba5b6SRobert Mustacchi  *  This resets the hardware into a known state.
142675eba5b6SRobert Mustacchi  **/
e1000_reset_hw_82575(struct e1000_hw * hw)142775eba5b6SRobert Mustacchi static s32 e1000_reset_hw_82575(struct e1000_hw *hw)
142875eba5b6SRobert Mustacchi {
142975eba5b6SRobert Mustacchi 	u32 ctrl;
143075eba5b6SRobert Mustacchi 	s32 ret_val;
143175eba5b6SRobert Mustacchi 
143275eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_reset_hw_82575");
143375eba5b6SRobert Mustacchi 
143475eba5b6SRobert Mustacchi 	/*
143575eba5b6SRobert Mustacchi 	 * Prevent the PCI-E bus from sticking if there is no TLP connection
143675eba5b6SRobert Mustacchi 	 * on the last TLP read/write transaction when MAC is reset.
143775eba5b6SRobert Mustacchi 	 */
143875eba5b6SRobert Mustacchi 	ret_val = e1000_disable_pcie_master_generic(hw);
143975eba5b6SRobert Mustacchi 	if (ret_val)
144075eba5b6SRobert Mustacchi 		DEBUGOUT("PCI-E Master disable polling has failed.\n");
144175eba5b6SRobert Mustacchi 
144275eba5b6SRobert Mustacchi 	/* set the completion timeout for interface */
144375eba5b6SRobert Mustacchi 	ret_val = e1000_set_pcie_completion_timeout(hw);
144475eba5b6SRobert Mustacchi 	if (ret_val)
144575eba5b6SRobert Mustacchi 		DEBUGOUT("PCI-E Set completion timeout has failed.\n");
144675eba5b6SRobert Mustacchi 
144775eba5b6SRobert Mustacchi 	DEBUGOUT("Masking off all interrupts\n");
144875eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
144975eba5b6SRobert Mustacchi 
145075eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
145175eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
145275eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
145375eba5b6SRobert Mustacchi 
145475eba5b6SRobert Mustacchi 	msec_delay(10);
145575eba5b6SRobert Mustacchi 
145675eba5b6SRobert Mustacchi 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
145775eba5b6SRobert Mustacchi 
145875eba5b6SRobert Mustacchi 	DEBUGOUT("Issuing a global reset to MAC\n");
145975eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
146075eba5b6SRobert Mustacchi 
146175eba5b6SRobert Mustacchi 	ret_val = e1000_get_auto_rd_done_generic(hw);
146275eba5b6SRobert Mustacchi 	if (ret_val) {
146375eba5b6SRobert Mustacchi 		/*
146475eba5b6SRobert Mustacchi 		 * When auto config read does not complete, do not
146575eba5b6SRobert Mustacchi 		 * return with an error. This can happen in situations
146675eba5b6SRobert Mustacchi 		 * where there is no eeprom and prevents getting link.
146775eba5b6SRobert Mustacchi 		 */
146875eba5b6SRobert Mustacchi 		DEBUGOUT("Auto Read Done did not complete\n");
146975eba5b6SRobert Mustacchi 	}
147075eba5b6SRobert Mustacchi 
147175eba5b6SRobert Mustacchi 	/* If EEPROM is not present, run manual init scripts */
147275eba5b6SRobert Mustacchi 	if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES))
147375eba5b6SRobert Mustacchi 		e1000_reset_init_script_82575(hw);
147475eba5b6SRobert Mustacchi 
147575eba5b6SRobert Mustacchi 	/* Clear any pending interrupt events. */
147675eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
147775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICR);
147875eba5b6SRobert Mustacchi 
147975eba5b6SRobert Mustacchi 	/* Install any alternate MAC address into RAR0 */
148075eba5b6SRobert Mustacchi 	ret_val = e1000_check_alt_mac_addr_generic(hw);
148175eba5b6SRobert Mustacchi 
148275eba5b6SRobert Mustacchi 	return ret_val;
148375eba5b6SRobert Mustacchi }
148475eba5b6SRobert Mustacchi 
148575eba5b6SRobert Mustacchi /**
148675eba5b6SRobert Mustacchi  *  e1000_init_hw_82575 - Initialize hardware
148775eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
148875eba5b6SRobert Mustacchi  *
148975eba5b6SRobert Mustacchi  *  This inits the hardware readying it for operation.
149075eba5b6SRobert Mustacchi  **/
e1000_init_hw_82575(struct e1000_hw * hw)1491c124a83eSRobert Mustacchi s32 e1000_init_hw_82575(struct e1000_hw *hw)
149275eba5b6SRobert Mustacchi {
149375eba5b6SRobert Mustacchi 	struct e1000_mac_info *mac = &hw->mac;
149475eba5b6SRobert Mustacchi 	s32 ret_val;
149575eba5b6SRobert Mustacchi 	u16 i, rar_count = mac->rar_entry_count;
149675eba5b6SRobert Mustacchi 
149775eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_hw_82575");
149875eba5b6SRobert Mustacchi 
149975eba5b6SRobert Mustacchi 	/* Initialize identification LED */
150075eba5b6SRobert Mustacchi 	ret_val = mac->ops.id_led_init(hw);
150175eba5b6SRobert Mustacchi 	if (ret_val) {
150275eba5b6SRobert Mustacchi 		DEBUGOUT("Error initializing identification LED\n");
150375eba5b6SRobert Mustacchi 		/* This is not fatal and we should not stop init due to this */
150475eba5b6SRobert Mustacchi 	}
150575eba5b6SRobert Mustacchi 
150675eba5b6SRobert Mustacchi 	/* Disabling VLAN filtering */
150775eba5b6SRobert Mustacchi 	DEBUGOUT("Initializing the IEEE VLAN\n");
150875eba5b6SRobert Mustacchi 	mac->ops.clear_vfta(hw);
150975eba5b6SRobert Mustacchi 
151075eba5b6SRobert Mustacchi 	/* Setup the receive address */
151175eba5b6SRobert Mustacchi 	e1000_init_rx_addrs_generic(hw, rar_count);
151275eba5b6SRobert Mustacchi 
151375eba5b6SRobert Mustacchi 	/* Zero out the Multicast HASH table */
151475eba5b6SRobert Mustacchi 	DEBUGOUT("Zeroing the MTA\n");
151575eba5b6SRobert Mustacchi 	for (i = 0; i < mac->mta_reg_count; i++)
151675eba5b6SRobert Mustacchi 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
151775eba5b6SRobert Mustacchi 
151875eba5b6SRobert Mustacchi 	/* Zero out the Unicast HASH table */
151975eba5b6SRobert Mustacchi 	DEBUGOUT("Zeroing the UTA\n");
152075eba5b6SRobert Mustacchi 	for (i = 0; i < mac->uta_reg_count; i++)
152175eba5b6SRobert Mustacchi 		E1000_WRITE_REG_ARRAY(hw, E1000_UTA, i, 0);
152275eba5b6SRobert Mustacchi 
152375eba5b6SRobert Mustacchi 	/* Setup link and flow control */
152475eba5b6SRobert Mustacchi 	ret_val = mac->ops.setup_link(hw);
152575eba5b6SRobert Mustacchi 
152675eba5b6SRobert Mustacchi 	/* Set the default MTU size */
152775eba5b6SRobert Mustacchi 	hw->dev_spec._82575.mtu = 1500;
152875eba5b6SRobert Mustacchi 
152975eba5b6SRobert Mustacchi 	/*
153075eba5b6SRobert Mustacchi 	 * Clear all of the statistics registers (clear on read).  It is
153175eba5b6SRobert Mustacchi 	 * important that we do this after we have tried to establish link
153275eba5b6SRobert Mustacchi 	 * because the symbol error count will increment wildly if there
153375eba5b6SRobert Mustacchi 	 * is no link.
153475eba5b6SRobert Mustacchi 	 */
153575eba5b6SRobert Mustacchi 	e1000_clear_hw_cntrs_82575(hw);
153675eba5b6SRobert Mustacchi 
153775eba5b6SRobert Mustacchi 	return ret_val;
153875eba5b6SRobert Mustacchi }
153975eba5b6SRobert Mustacchi 
154075eba5b6SRobert Mustacchi /**
154175eba5b6SRobert Mustacchi  *  e1000_setup_copper_link_82575 - Configure copper link settings
154275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
154375eba5b6SRobert Mustacchi  *
154475eba5b6SRobert Mustacchi  *  Configures the link for auto-neg or forced speed and duplex.  Then we check
154575eba5b6SRobert Mustacchi  *  for link, once link is established calls to configure collision distance
154675eba5b6SRobert Mustacchi  *  and flow control are called.
154775eba5b6SRobert Mustacchi  **/
e1000_setup_copper_link_82575(struct e1000_hw * hw)154875eba5b6SRobert Mustacchi static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
154975eba5b6SRobert Mustacchi {
155075eba5b6SRobert Mustacchi 	u32 ctrl;
155175eba5b6SRobert Mustacchi 	s32 ret_val;
155275eba5b6SRobert Mustacchi 	u32 phpm_reg;
155375eba5b6SRobert Mustacchi 
155475eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_setup_copper_link_82575");
155575eba5b6SRobert Mustacchi 
155675eba5b6SRobert Mustacchi 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
155775eba5b6SRobert Mustacchi 	ctrl |= E1000_CTRL_SLU;
155875eba5b6SRobert Mustacchi 	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
155975eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
156075eba5b6SRobert Mustacchi 
156113485e69SGarrett D'Amore 	/* Clear Go Link Disconnect bit on supported devices */
156213485e69SGarrett D'Amore 	switch (hw->mac.type) {
156313485e69SGarrett D'Amore 	case e1000_82580:
156413485e69SGarrett D'Amore 	case e1000_i350:
156513485e69SGarrett D'Amore 	case e1000_i210:
156613485e69SGarrett D'Amore 	case e1000_i211:
156775eba5b6SRobert Mustacchi 		phpm_reg = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
156875eba5b6SRobert Mustacchi 		phpm_reg &= ~E1000_82580_PM_GO_LINKD;
156975eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, phpm_reg);
157013485e69SGarrett D'Amore 		break;
157113485e69SGarrett D'Amore 	default:
157213485e69SGarrett D'Amore 		break;
157375eba5b6SRobert Mustacchi 	}
157475eba5b6SRobert Mustacchi 
157575eba5b6SRobert Mustacchi 	ret_val = e1000_setup_serdes_link_82575(hw);
157675eba5b6SRobert Mustacchi 	if (ret_val)
157775eba5b6SRobert Mustacchi 		goto out;
157875eba5b6SRobert Mustacchi 
157975eba5b6SRobert Mustacchi 	if (e1000_sgmii_active_82575(hw)) {
158075eba5b6SRobert Mustacchi 		/* allow time for SFP cage time to power up phy */
158175eba5b6SRobert Mustacchi 		msec_delay(300);
158275eba5b6SRobert Mustacchi 
158375eba5b6SRobert Mustacchi 		ret_val = hw->phy.ops.reset(hw);
158475eba5b6SRobert Mustacchi 		if (ret_val) {
158575eba5b6SRobert Mustacchi 			DEBUGOUT("Error resetting the PHY.\n");
158675eba5b6SRobert Mustacchi 			goto out;
158775eba5b6SRobert Mustacchi 		}
158875eba5b6SRobert Mustacchi 	}
158975eba5b6SRobert Mustacchi 	switch (hw->phy.type) {
159075eba5b6SRobert Mustacchi 	case e1000_phy_i210:
159175eba5b6SRobert Mustacchi 	case e1000_phy_m88:
159275eba5b6SRobert Mustacchi 		switch (hw->phy.id) {
159375eba5b6SRobert Mustacchi 		case I347AT4_E_PHY_ID:
159475eba5b6SRobert Mustacchi 		case M88E1112_E_PHY_ID:
159575eba5b6SRobert Mustacchi 		case M88E1340M_E_PHY_ID:
1596c124a83eSRobert Mustacchi 		case M88E1543_E_PHY_ID:
1597c124a83eSRobert Mustacchi 		case M88E1512_E_PHY_ID:
159875eba5b6SRobert Mustacchi 		case I210_I_PHY_ID:
159975eba5b6SRobert Mustacchi 			ret_val = e1000_copper_link_setup_m88_gen2(hw);
160075eba5b6SRobert Mustacchi 			break;
160175eba5b6SRobert Mustacchi 		default:
160275eba5b6SRobert Mustacchi 			ret_val = e1000_copper_link_setup_m88(hw);
160375eba5b6SRobert Mustacchi 			break;
160475eba5b6SRobert Mustacchi 		}
160575eba5b6SRobert Mustacchi 		break;
160675eba5b6SRobert Mustacchi 	case e1000_phy_igp_3:
160775eba5b6SRobert Mustacchi 		ret_val = e1000_copper_link_setup_igp(hw);
160875eba5b6SRobert Mustacchi 		break;
160975eba5b6SRobert Mustacchi 	case e1000_phy_82580:
161075eba5b6SRobert Mustacchi 		ret_val = e1000_copper_link_setup_82577(hw);
161175eba5b6SRobert Mustacchi 		break;
161275eba5b6SRobert Mustacchi 	default:
161375eba5b6SRobert Mustacchi 		ret_val = -E1000_ERR_PHY;
161475eba5b6SRobert Mustacchi 		break;
161575eba5b6SRobert Mustacchi 	}
161675eba5b6SRobert Mustacchi 
161775eba5b6SRobert Mustacchi 	if (ret_val)
161875eba5b6SRobert Mustacchi 		goto out;
161975eba5b6SRobert Mustacchi 
162075eba5b6SRobert Mustacchi 	ret_val = e1000_setup_copper_link_generic(hw);
162175eba5b6SRobert Mustacchi out:
162275eba5b6SRobert Mustacchi 	return ret_val;
162375eba5b6SRobert Mustacchi }
162475eba5b6SRobert Mustacchi 
162575eba5b6SRobert Mustacchi /**
162675eba5b6SRobert Mustacchi  *  e1000_setup_serdes_link_82575 - Setup link for serdes
162775eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
162875eba5b6SRobert Mustacchi  *
162975eba5b6SRobert Mustacchi  *  Configure the physical coding sub-layer (PCS) link.  The PCS link is
163075eba5b6SRobert Mustacchi  *  used on copper connections where the serialized gigabit media independent
163175eba5b6SRobert Mustacchi  *  interface (sgmii), or serdes fiber is being used.  Configures the link
163275eba5b6SRobert Mustacchi  *  for auto-negotiation or forces speed/duplex.
163375eba5b6SRobert Mustacchi  **/
e1000_setup_serdes_link_82575(struct e1000_hw * hw)163475eba5b6SRobert Mustacchi static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw)
163575eba5b6SRobert Mustacchi {
163675eba5b6SRobert Mustacchi 	u32 ctrl_ext, ctrl_reg, reg, anadv_reg;
163775eba5b6SRobert Mustacchi 	bool pcs_autoneg;
163875eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
163975eba5b6SRobert Mustacchi 	u16 data;
164075eba5b6SRobert Mustacchi 
164175eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_setup_serdes_link_82575");
164275eba5b6SRobert Mustacchi 
164375eba5b6SRobert Mustacchi 	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
164475eba5b6SRobert Mustacchi 	    !e1000_sgmii_active_82575(hw))
164575eba5b6SRobert Mustacchi 		return ret_val;
164675eba5b6SRobert Mustacchi 
164775eba5b6SRobert Mustacchi 	/*
164875eba5b6SRobert Mustacchi 	 * On the 82575, SerDes loopback mode persists until it is
164975eba5b6SRobert Mustacchi 	 * explicitly turned off or a power cycle is performed.  A read to
165075eba5b6SRobert Mustacchi 	 * the register does not indicate its status.  Therefore, we ensure
165175eba5b6SRobert Mustacchi 	 * loopback mode is disabled during initialization.
165275eba5b6SRobert Mustacchi 	 */
165375eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
165475eba5b6SRobert Mustacchi 
165575eba5b6SRobert Mustacchi 	/* power on the sfp cage if present */
165675eba5b6SRobert Mustacchi 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
165775eba5b6SRobert Mustacchi 	ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
165875eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
165975eba5b6SRobert Mustacchi 
166075eba5b6SRobert Mustacchi 	ctrl_reg = E1000_READ_REG(hw, E1000_CTRL);
166175eba5b6SRobert Mustacchi 	ctrl_reg |= E1000_CTRL_SLU;
166275eba5b6SRobert Mustacchi 
166375eba5b6SRobert Mustacchi 	/* set both sw defined pins on 82575/82576*/
166475eba5b6SRobert Mustacchi 	if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576)
166575eba5b6SRobert Mustacchi 		ctrl_reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1;
166675eba5b6SRobert Mustacchi 
166775eba5b6SRobert Mustacchi 	reg = E1000_READ_REG(hw, E1000_PCS_LCTL);
166875eba5b6SRobert Mustacchi 
166975eba5b6SRobert Mustacchi 	/* default pcs_autoneg to the same setting as mac autoneg */
167075eba5b6SRobert Mustacchi 	pcs_autoneg = hw->mac.autoneg;
167175eba5b6SRobert Mustacchi 
167275eba5b6SRobert Mustacchi 	switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
167375eba5b6SRobert Mustacchi 	case E1000_CTRL_EXT_LINK_MODE_SGMII:
167475eba5b6SRobert Mustacchi 		/* sgmii mode lets the phy handle forcing speed/duplex */
167575eba5b6SRobert Mustacchi 		pcs_autoneg = TRUE;
167675eba5b6SRobert Mustacchi 		/* autoneg time out should be disabled for SGMII mode */
167775eba5b6SRobert Mustacchi 		reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
167875eba5b6SRobert Mustacchi 		break;
167975eba5b6SRobert Mustacchi 	case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
168075eba5b6SRobert Mustacchi 		/* disable PCS autoneg and support parallel detect only */
168175eba5b6SRobert Mustacchi 		pcs_autoneg = FALSE;
1682*5e832498SToomas Soome 		/* FALLTHROUGH */
168375eba5b6SRobert Mustacchi 	default:
168475eba5b6SRobert Mustacchi 		if (hw->mac.type == e1000_82575 ||
168575eba5b6SRobert Mustacchi 		    hw->mac.type == e1000_82576) {
168675eba5b6SRobert Mustacchi 			ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &data);
168775eba5b6SRobert Mustacchi 			if (ret_val) {
168875eba5b6SRobert Mustacchi 				DEBUGOUT("NVM Read Error\n");
168975eba5b6SRobert Mustacchi 				return ret_val;
169075eba5b6SRobert Mustacchi 			}
169175eba5b6SRobert Mustacchi 
169275eba5b6SRobert Mustacchi 			if (data & E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT)
169375eba5b6SRobert Mustacchi 				pcs_autoneg = FALSE;
169475eba5b6SRobert Mustacchi 		}
169575eba5b6SRobert Mustacchi 
169675eba5b6SRobert Mustacchi 		/*
169775eba5b6SRobert Mustacchi 		 * non-SGMII modes only supports a speed of 1000/Full for the
169875eba5b6SRobert Mustacchi 		 * link so it is best to just force the MAC and let the pcs
169975eba5b6SRobert Mustacchi 		 * link either autoneg or be forced to 1000/Full
170075eba5b6SRobert Mustacchi 		 */
170175eba5b6SRobert Mustacchi 		ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
170275eba5b6SRobert Mustacchi 			    E1000_CTRL_FD | E1000_CTRL_FRCDPX;
170375eba5b6SRobert Mustacchi 
170475eba5b6SRobert Mustacchi 		/* set speed of 1000/Full if speed/duplex is forced */
170575eba5b6SRobert Mustacchi 		reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL;
170675eba5b6SRobert Mustacchi 		break;
170775eba5b6SRobert Mustacchi 	}
170875eba5b6SRobert Mustacchi 
170975eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl_reg);
171075eba5b6SRobert Mustacchi 
171175eba5b6SRobert Mustacchi 	/*
171275eba5b6SRobert Mustacchi 	 * New SerDes mode allows for forcing speed or autonegotiating speed
171375eba5b6SRobert Mustacchi 	 * at 1gb. Autoneg should be default set by most drivers. This is the
171475eba5b6SRobert Mustacchi 	 * mode that will be compatible with older link partners and switches.
171575eba5b6SRobert Mustacchi 	 * However, both are supported by the hardware and some drivers/tools.
171675eba5b6SRobert Mustacchi 	 */
171775eba5b6SRobert Mustacchi 	reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
171875eba5b6SRobert Mustacchi 		 E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
171975eba5b6SRobert Mustacchi 
172075eba5b6SRobert Mustacchi 	if (pcs_autoneg) {
172175eba5b6SRobert Mustacchi 		/* Set PCS register for autoneg */
172275eba5b6SRobert Mustacchi 		reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
172375eba5b6SRobert Mustacchi 		       E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
172475eba5b6SRobert Mustacchi 
172575eba5b6SRobert Mustacchi 		/* Disable force flow control for autoneg */
172675eba5b6SRobert Mustacchi 		reg &= ~E1000_PCS_LCTL_FORCE_FCTRL;
172775eba5b6SRobert Mustacchi 
172875eba5b6SRobert Mustacchi 		/* Configure flow control advertisement for autoneg */
172975eba5b6SRobert Mustacchi 		anadv_reg = E1000_READ_REG(hw, E1000_PCS_ANADV);
173075eba5b6SRobert Mustacchi 		anadv_reg &= ~(E1000_TXCW_ASM_DIR | E1000_TXCW_PAUSE);
173175eba5b6SRobert Mustacchi 
173275eba5b6SRobert Mustacchi 		switch (hw->fc.requested_mode) {
173375eba5b6SRobert Mustacchi 		case e1000_fc_full:
173475eba5b6SRobert Mustacchi 		case e1000_fc_rx_pause:
173575eba5b6SRobert Mustacchi 			anadv_reg |= E1000_TXCW_ASM_DIR;
173675eba5b6SRobert Mustacchi 			anadv_reg |= E1000_TXCW_PAUSE;
173775eba5b6SRobert Mustacchi 			break;
173875eba5b6SRobert Mustacchi 		case e1000_fc_tx_pause:
173975eba5b6SRobert Mustacchi 			anadv_reg |= E1000_TXCW_ASM_DIR;
174075eba5b6SRobert Mustacchi 			break;
174175eba5b6SRobert Mustacchi 		default:
174275eba5b6SRobert Mustacchi 			break;
174375eba5b6SRobert Mustacchi 		}
174475eba5b6SRobert Mustacchi 
174575eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_PCS_ANADV, anadv_reg);
174675eba5b6SRobert Mustacchi 
174775eba5b6SRobert Mustacchi 		DEBUGOUT1("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg);
174875eba5b6SRobert Mustacchi 	} else {
174975eba5b6SRobert Mustacchi 		/* Set PCS register for forced link */
175075eba5b6SRobert Mustacchi 		reg |= E1000_PCS_LCTL_FSD;	/* Force Speed */
175175eba5b6SRobert Mustacchi 
175275eba5b6SRobert Mustacchi 		/* Force flow control for forced link */
175375eba5b6SRobert Mustacchi 		reg |= E1000_PCS_LCTL_FORCE_FCTRL;
175475eba5b6SRobert Mustacchi 
175575eba5b6SRobert Mustacchi 		DEBUGOUT1("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg);
175675eba5b6SRobert Mustacchi 	}
175775eba5b6SRobert Mustacchi 
175875eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg);
175975eba5b6SRobert Mustacchi 
176075eba5b6SRobert Mustacchi 	if (!pcs_autoneg && !e1000_sgmii_active_82575(hw))
176175eba5b6SRobert Mustacchi 		e1000_force_mac_fc_generic(hw);
176275eba5b6SRobert Mustacchi 
176375eba5b6SRobert Mustacchi 	return ret_val;
176475eba5b6SRobert Mustacchi }
176575eba5b6SRobert Mustacchi 
176675eba5b6SRobert Mustacchi /**
176775eba5b6SRobert Mustacchi  *  e1000_get_media_type_82575 - derives current media type.
176875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
176975eba5b6SRobert Mustacchi  *
177075eba5b6SRobert Mustacchi  *  The media type is chosen reflecting few settings.
177175eba5b6SRobert Mustacchi  *  The following are taken into account:
177275eba5b6SRobert Mustacchi  *  - link mode set in the current port Init Control Word #3
177375eba5b6SRobert Mustacchi  *  - current link mode settings in CSR register
177475eba5b6SRobert Mustacchi  *  - MDIO vs. I2C PHY control interface chosen
177575eba5b6SRobert Mustacchi  *  - SFP module media type
177675eba5b6SRobert Mustacchi  **/
e1000_get_media_type_82575(struct e1000_hw * hw)177775eba5b6SRobert Mustacchi static s32 e1000_get_media_type_82575(struct e1000_hw *hw)
177875eba5b6SRobert Mustacchi {
177975eba5b6SRobert Mustacchi 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
178075eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
178175eba5b6SRobert Mustacchi 	u32 ctrl_ext = 0;
178275eba5b6SRobert Mustacchi 	u32 link_mode = 0;
178375eba5b6SRobert Mustacchi 
178475eba5b6SRobert Mustacchi 	/* Set internal phy as default */
178575eba5b6SRobert Mustacchi 	dev_spec->sgmii_active = FALSE;
178675eba5b6SRobert Mustacchi 	dev_spec->module_plugged = FALSE;
178775eba5b6SRobert Mustacchi 
178875eba5b6SRobert Mustacchi 	/* Get CSR setting */
178975eba5b6SRobert Mustacchi 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
179075eba5b6SRobert Mustacchi 
179175eba5b6SRobert Mustacchi 	/* extract link mode setting */
179275eba5b6SRobert Mustacchi 	link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK;
179375eba5b6SRobert Mustacchi 
179475eba5b6SRobert Mustacchi 	switch (link_mode) {
179575eba5b6SRobert Mustacchi 	case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
179675eba5b6SRobert Mustacchi 		hw->phy.media_type = e1000_media_type_internal_serdes;
179775eba5b6SRobert Mustacchi 		break;
179875eba5b6SRobert Mustacchi 	case E1000_CTRL_EXT_LINK_MODE_GMII:
179975eba5b6SRobert Mustacchi 		hw->phy.media_type = e1000_media_type_copper;
180075eba5b6SRobert Mustacchi 		break;
180175eba5b6SRobert Mustacchi 	case E1000_CTRL_EXT_LINK_MODE_SGMII:
180275eba5b6SRobert Mustacchi 		/* Get phy control interface type set (MDIO vs. I2C)*/
180375eba5b6SRobert Mustacchi 		if (e1000_sgmii_uses_mdio_82575(hw)) {
180475eba5b6SRobert Mustacchi 			hw->phy.media_type = e1000_media_type_copper;
180575eba5b6SRobert Mustacchi 			dev_spec->sgmii_active = TRUE;
180675eba5b6SRobert Mustacchi 			break;
180775eba5b6SRobert Mustacchi 		}
180875eba5b6SRobert Mustacchi 		/* fall through for I2C based SGMII */
1809*5e832498SToomas Soome 		/* FALLTHROUGH */
181075eba5b6SRobert Mustacchi 	case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
181175eba5b6SRobert Mustacchi 		/* read media type from SFP EEPROM */
181275eba5b6SRobert Mustacchi 		ret_val = e1000_set_sfp_media_type_82575(hw);
181375eba5b6SRobert Mustacchi 		if ((ret_val != E1000_SUCCESS) ||
181475eba5b6SRobert Mustacchi 		    (hw->phy.media_type == e1000_media_type_unknown)) {
181575eba5b6SRobert Mustacchi 			/*
181675eba5b6SRobert Mustacchi 			 * If media type was not identified then return media
181775eba5b6SRobert Mustacchi 			 * type defined by the CTRL_EXT settings.
181875eba5b6SRobert Mustacchi 			 */
181975eba5b6SRobert Mustacchi 			hw->phy.media_type = e1000_media_type_internal_serdes;
182075eba5b6SRobert Mustacchi 
182175eba5b6SRobert Mustacchi 			if (link_mode == E1000_CTRL_EXT_LINK_MODE_SGMII) {
182275eba5b6SRobert Mustacchi 				hw->phy.media_type = e1000_media_type_copper;
182375eba5b6SRobert Mustacchi 				dev_spec->sgmii_active = TRUE;
182475eba5b6SRobert Mustacchi 			}
182575eba5b6SRobert Mustacchi 
182675eba5b6SRobert Mustacchi 			break;
182775eba5b6SRobert Mustacchi 		}
182875eba5b6SRobert Mustacchi 
182975eba5b6SRobert Mustacchi 		/* do not change link mode for 100BaseFX */
183075eba5b6SRobert Mustacchi 		if (dev_spec->eth_flags.e100_base_fx)
183175eba5b6SRobert Mustacchi 			break;
183275eba5b6SRobert Mustacchi 
183375eba5b6SRobert Mustacchi 		/* change current link mode setting */
183475eba5b6SRobert Mustacchi 		ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK;
183575eba5b6SRobert Mustacchi 
183675eba5b6SRobert Mustacchi 		if (hw->phy.media_type == e1000_media_type_copper)
183775eba5b6SRobert Mustacchi 			ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_SGMII;
183875eba5b6SRobert Mustacchi 		else
183975eba5b6SRobert Mustacchi 			ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
184075eba5b6SRobert Mustacchi 
184175eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
184275eba5b6SRobert Mustacchi 
184375eba5b6SRobert Mustacchi 		break;
184475eba5b6SRobert Mustacchi 	}
184575eba5b6SRobert Mustacchi 
184675eba5b6SRobert Mustacchi 	return ret_val;
184775eba5b6SRobert Mustacchi }
184875eba5b6SRobert Mustacchi 
184975eba5b6SRobert Mustacchi /**
185075eba5b6SRobert Mustacchi  *  e1000_set_sfp_media_type_82575 - derives SFP module media type.
185175eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
185275eba5b6SRobert Mustacchi  *
185375eba5b6SRobert Mustacchi  *  The media type is chosen based on SFP module.
185475eba5b6SRobert Mustacchi  *  compatibility flags retrieved from SFP ID EEPROM.
185575eba5b6SRobert Mustacchi  **/
e1000_set_sfp_media_type_82575(struct e1000_hw * hw)185675eba5b6SRobert Mustacchi static s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw)
185775eba5b6SRobert Mustacchi {
185875eba5b6SRobert Mustacchi 	s32 ret_val = E1000_ERR_CONFIG;
185975eba5b6SRobert Mustacchi 	u32 ctrl_ext = 0;
186075eba5b6SRobert Mustacchi 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
186175eba5b6SRobert Mustacchi 	struct sfp_e1000_flags *eth_flags = &dev_spec->eth_flags;
186275eba5b6SRobert Mustacchi 	u8 tranceiver_type = 0;
186375eba5b6SRobert Mustacchi 	s32 timeout = 3;
186475eba5b6SRobert Mustacchi 
186575eba5b6SRobert Mustacchi 	/* Turn I2C interface ON and power on sfp cage */
186675eba5b6SRobert Mustacchi 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
186775eba5b6SRobert Mustacchi 	ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
186875eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_I2C_ENA);
186975eba5b6SRobert Mustacchi 
187075eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
187175eba5b6SRobert Mustacchi 
187275eba5b6SRobert Mustacchi 	/* Read SFP module data */
187375eba5b6SRobert Mustacchi 	while (timeout) {
187475eba5b6SRobert Mustacchi 		ret_val = e1000_read_sfp_data_byte(hw,
187575eba5b6SRobert Mustacchi 			E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET),
187675eba5b6SRobert Mustacchi 			&tranceiver_type);
187775eba5b6SRobert Mustacchi 		if (ret_val == E1000_SUCCESS)
187875eba5b6SRobert Mustacchi 			break;
187975eba5b6SRobert Mustacchi 		msec_delay(100);
188075eba5b6SRobert Mustacchi 		timeout--;
188175eba5b6SRobert Mustacchi 	}
188275eba5b6SRobert Mustacchi 	if (ret_val != E1000_SUCCESS)
188375eba5b6SRobert Mustacchi 		goto out;
188475eba5b6SRobert Mustacchi 
188575eba5b6SRobert Mustacchi 	ret_val = e1000_read_sfp_data_byte(hw,
188675eba5b6SRobert Mustacchi 			E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET),
188775eba5b6SRobert Mustacchi 			(u8 *)eth_flags);
188875eba5b6SRobert Mustacchi 	if (ret_val != E1000_SUCCESS)
188975eba5b6SRobert Mustacchi 		goto out;
189075eba5b6SRobert Mustacchi 
189175eba5b6SRobert Mustacchi 	/* Check if there is some SFP module plugged and powered */
189275eba5b6SRobert Mustacchi 	if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) ||
189375eba5b6SRobert Mustacchi 	    (tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) {
189475eba5b6SRobert Mustacchi 		dev_spec->module_plugged = TRUE;
189575eba5b6SRobert Mustacchi 		if (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) {
189675eba5b6SRobert Mustacchi 			hw->phy.media_type = e1000_media_type_internal_serdes;
189775eba5b6SRobert Mustacchi 		} else if (eth_flags->e100_base_fx) {
189875eba5b6SRobert Mustacchi 			dev_spec->sgmii_active = TRUE;
189975eba5b6SRobert Mustacchi 			hw->phy.media_type = e1000_media_type_internal_serdes;
190075eba5b6SRobert Mustacchi 		} else if (eth_flags->e1000_base_t) {
190175eba5b6SRobert Mustacchi 			dev_spec->sgmii_active = TRUE;
190275eba5b6SRobert Mustacchi 			hw->phy.media_type = e1000_media_type_copper;
190375eba5b6SRobert Mustacchi 		} else {
190475eba5b6SRobert Mustacchi 			hw->phy.media_type = e1000_media_type_unknown;
190575eba5b6SRobert Mustacchi 			DEBUGOUT("PHY module has not been recognized\n");
190675eba5b6SRobert Mustacchi 			goto out;
190775eba5b6SRobert Mustacchi 		}
190875eba5b6SRobert Mustacchi 	} else {
190975eba5b6SRobert Mustacchi 		hw->phy.media_type = e1000_media_type_unknown;
191075eba5b6SRobert Mustacchi 	}
191175eba5b6SRobert Mustacchi 	ret_val = E1000_SUCCESS;
191275eba5b6SRobert Mustacchi out:
191375eba5b6SRobert Mustacchi 	/* Restore I2C interface setting */
191475eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
191575eba5b6SRobert Mustacchi 	return ret_val;
191675eba5b6SRobert Mustacchi }
191775eba5b6SRobert Mustacchi 
191875eba5b6SRobert Mustacchi /**
191975eba5b6SRobert Mustacchi  *  e1000_valid_led_default_82575 - Verify a valid default LED config
192075eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
192175eba5b6SRobert Mustacchi  *  @data: pointer to the NVM (EEPROM)
192275eba5b6SRobert Mustacchi  *
192375eba5b6SRobert Mustacchi  *  Read the EEPROM for the current default LED configuration.  If the
192475eba5b6SRobert Mustacchi  *  LED configuration is not valid, set to a valid LED configuration.
192575eba5b6SRobert Mustacchi  **/
e1000_valid_led_default_82575(struct e1000_hw * hw,u16 * data)192675eba5b6SRobert Mustacchi static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data)
192775eba5b6SRobert Mustacchi {
192875eba5b6SRobert Mustacchi 	s32 ret_val;
192975eba5b6SRobert Mustacchi 
193075eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_valid_led_default_82575");
193175eba5b6SRobert Mustacchi 
193275eba5b6SRobert Mustacchi 	ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
193375eba5b6SRobert Mustacchi 	if (ret_val) {
193475eba5b6SRobert Mustacchi 		DEBUGOUT("NVM Read Error\n");
193575eba5b6SRobert Mustacchi 		goto out;
193675eba5b6SRobert Mustacchi 	}
193775eba5b6SRobert Mustacchi 
193875eba5b6SRobert Mustacchi 	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
193975eba5b6SRobert Mustacchi 		switch (hw->phy.media_type) {
194075eba5b6SRobert Mustacchi 		case e1000_media_type_internal_serdes:
194175eba5b6SRobert Mustacchi 			*data = ID_LED_DEFAULT_82575_SERDES;
194275eba5b6SRobert Mustacchi 			break;
194375eba5b6SRobert Mustacchi 		case e1000_media_type_copper:
194475eba5b6SRobert Mustacchi 		default:
194575eba5b6SRobert Mustacchi 			*data = ID_LED_DEFAULT;
194675eba5b6SRobert Mustacchi 			break;
194775eba5b6SRobert Mustacchi 		}
194875eba5b6SRobert Mustacchi 	}
194975eba5b6SRobert Mustacchi out:
195075eba5b6SRobert Mustacchi 	return ret_val;
195175eba5b6SRobert Mustacchi }
195275eba5b6SRobert Mustacchi 
195375eba5b6SRobert Mustacchi /**
195475eba5b6SRobert Mustacchi  *  e1000_sgmii_active_82575 - Return sgmii state
195575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
195675eba5b6SRobert Mustacchi  *
195775eba5b6SRobert Mustacchi  *  82575 silicon has a serialized gigabit media independent interface (sgmii)
195875eba5b6SRobert Mustacchi  *  which can be enabled for use in the embedded applications.  Simply
195975eba5b6SRobert Mustacchi  *  return the current state of the sgmii interface.
196075eba5b6SRobert Mustacchi  **/
e1000_sgmii_active_82575(struct e1000_hw * hw)196175eba5b6SRobert Mustacchi static bool e1000_sgmii_active_82575(struct e1000_hw *hw)
196275eba5b6SRobert Mustacchi {
196375eba5b6SRobert Mustacchi 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
196475eba5b6SRobert Mustacchi 	return dev_spec->sgmii_active;
196575eba5b6SRobert Mustacchi }
196675eba5b6SRobert Mustacchi 
196775eba5b6SRobert Mustacchi /**
196875eba5b6SRobert Mustacchi  *  e1000_reset_init_script_82575 - Inits HW defaults after reset
196975eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
197075eba5b6SRobert Mustacchi  *
197175eba5b6SRobert Mustacchi  *  Inits recommended HW defaults after a reset when there is no EEPROM
197275eba5b6SRobert Mustacchi  *  detected. This is only for the 82575.
197375eba5b6SRobert Mustacchi  **/
e1000_reset_init_script_82575(struct e1000_hw * hw)197475eba5b6SRobert Mustacchi static s32 e1000_reset_init_script_82575(struct e1000_hw *hw)
197575eba5b6SRobert Mustacchi {
197675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_reset_init_script_82575");
197775eba5b6SRobert Mustacchi 
197875eba5b6SRobert Mustacchi 	if (hw->mac.type == e1000_82575) {
197975eba5b6SRobert Mustacchi 		DEBUGOUT("Running reset init script for 82575\n");
198075eba5b6SRobert Mustacchi 		/* SerDes configuration via SERDESCTRL */
198175eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x00, 0x0C);
198275eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x01, 0x78);
198375eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x1B, 0x23);
198475eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x23, 0x15);
198575eba5b6SRobert Mustacchi 
198675eba5b6SRobert Mustacchi 		/* CCM configuration via CCMCTL register */
198775eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x14, 0x00);
198875eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x10, 0x00);
198975eba5b6SRobert Mustacchi 
199075eba5b6SRobert Mustacchi 		/* PCIe lanes configuration */
199175eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x00, 0xEC);
199275eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x61, 0xDF);
199375eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x34, 0x05);
199475eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x2F, 0x81);
199575eba5b6SRobert Mustacchi 
199675eba5b6SRobert Mustacchi 		/* PCIe PLL Configuration */
199775eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x02, 0x47);
199875eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x14, 0x00);
199975eba5b6SRobert Mustacchi 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x10, 0x00);
200075eba5b6SRobert Mustacchi 	}
200175eba5b6SRobert Mustacchi 
200275eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
200375eba5b6SRobert Mustacchi }
200475eba5b6SRobert Mustacchi 
200575eba5b6SRobert Mustacchi /**
200675eba5b6SRobert Mustacchi  *  e1000_read_mac_addr_82575 - Read device MAC address
200775eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
200875eba5b6SRobert Mustacchi  **/
e1000_read_mac_addr_82575(struct e1000_hw * hw)200975eba5b6SRobert Mustacchi static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw)
201075eba5b6SRobert Mustacchi {
2011c124a83eSRobert Mustacchi 	s32 ret_val;
201275eba5b6SRobert Mustacchi 
201375eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_read_mac_addr_82575");
201475eba5b6SRobert Mustacchi 
201575eba5b6SRobert Mustacchi 	/*
201675eba5b6SRobert Mustacchi 	 * If there's an alternate MAC address place it in RAR0
201775eba5b6SRobert Mustacchi 	 * so that it will override the Si installed default perm
201875eba5b6SRobert Mustacchi 	 * address.
201975eba5b6SRobert Mustacchi 	 */
202075eba5b6SRobert Mustacchi 	ret_val = e1000_check_alt_mac_addr_generic(hw);
202175eba5b6SRobert Mustacchi 	if (ret_val)
202275eba5b6SRobert Mustacchi 		goto out;
202375eba5b6SRobert Mustacchi 
202475eba5b6SRobert Mustacchi 	ret_val = e1000_read_mac_addr_generic(hw);
202575eba5b6SRobert Mustacchi 
202675eba5b6SRobert Mustacchi out:
202775eba5b6SRobert Mustacchi 	return ret_val;
202875eba5b6SRobert Mustacchi }
202975eba5b6SRobert Mustacchi 
203075eba5b6SRobert Mustacchi /**
203175eba5b6SRobert Mustacchi  *  e1000_config_collision_dist_82575 - Configure collision distance
203275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
203375eba5b6SRobert Mustacchi  *
203475eba5b6SRobert Mustacchi  *  Configures the collision distance to the default value and is used
203575eba5b6SRobert Mustacchi  *  during link setup.
203675eba5b6SRobert Mustacchi  **/
e1000_config_collision_dist_82575(struct e1000_hw * hw)203775eba5b6SRobert Mustacchi static void e1000_config_collision_dist_82575(struct e1000_hw *hw)
203875eba5b6SRobert Mustacchi {
203975eba5b6SRobert Mustacchi 	u32 tctl_ext;
204075eba5b6SRobert Mustacchi 
204175eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_config_collision_dist_82575");
204275eba5b6SRobert Mustacchi 
204375eba5b6SRobert Mustacchi 	tctl_ext = E1000_READ_REG(hw, E1000_TCTL_EXT);
204475eba5b6SRobert Mustacchi 
204575eba5b6SRobert Mustacchi 	tctl_ext &= ~E1000_TCTL_EXT_COLD;
204675eba5b6SRobert Mustacchi 	tctl_ext |= E1000_COLLISION_DISTANCE << E1000_TCTL_EXT_COLD_SHIFT;
204775eba5b6SRobert Mustacchi 
204875eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_TCTL_EXT, tctl_ext);
204975eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
205075eba5b6SRobert Mustacchi }
205175eba5b6SRobert Mustacchi 
205275eba5b6SRobert Mustacchi /**
205375eba5b6SRobert Mustacchi  * e1000_power_down_phy_copper_82575 - Remove link during PHY power down
205475eba5b6SRobert Mustacchi  * @hw: pointer to the HW structure
205575eba5b6SRobert Mustacchi  *
205675eba5b6SRobert Mustacchi  * In the case of a PHY power down to save power, or to turn off link during a
205775eba5b6SRobert Mustacchi  * driver unload, or wake on lan is not enabled, remove the link.
205875eba5b6SRobert Mustacchi  **/
e1000_power_down_phy_copper_82575(struct e1000_hw * hw)205975eba5b6SRobert Mustacchi static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
206075eba5b6SRobert Mustacchi {
206175eba5b6SRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
206275eba5b6SRobert Mustacchi 
206375eba5b6SRobert Mustacchi 	if (!(phy->ops.check_reset_block))
206475eba5b6SRobert Mustacchi 		return;
206575eba5b6SRobert Mustacchi 
206675eba5b6SRobert Mustacchi 	/* If the management interface is not enabled, then power down */
206775eba5b6SRobert Mustacchi 	if (!(e1000_enable_mng_pass_thru(hw) || phy->ops.check_reset_block(hw)))
206875eba5b6SRobert Mustacchi 		e1000_power_down_phy_copper(hw);
206975eba5b6SRobert Mustacchi 
207075eba5b6SRobert Mustacchi 	return;
207175eba5b6SRobert Mustacchi }
207275eba5b6SRobert Mustacchi 
207375eba5b6SRobert Mustacchi /**
207475eba5b6SRobert Mustacchi  *  e1000_clear_hw_cntrs_82575 - Clear device specific hardware counters
207575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
207675eba5b6SRobert Mustacchi  *
207775eba5b6SRobert Mustacchi  *  Clears the hardware counters by reading the counter registers.
207875eba5b6SRobert Mustacchi  **/
e1000_clear_hw_cntrs_82575(struct e1000_hw * hw)207975eba5b6SRobert Mustacchi static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
208075eba5b6SRobert Mustacchi {
208175eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_clear_hw_cntrs_82575");
208275eba5b6SRobert Mustacchi 
208375eba5b6SRobert Mustacchi 	e1000_clear_hw_cntrs_base_generic(hw);
208475eba5b6SRobert Mustacchi 
208575eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC64);
208675eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC127);
208775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC255);
208875eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC511);
208975eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC1023);
209075eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC1522);
209175eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC64);
209275eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC127);
209375eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC255);
209475eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC511);
209575eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC1023);
209675eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC1522);
209775eba5b6SRobert Mustacchi 
209875eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ALGNERRC);
209975eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_RXERRC);
210075eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_TNCRS);
210175eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_CEXTERR);
210275eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_TSCTC);
210375eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_TSCTFC);
210475eba5b6SRobert Mustacchi 
210575eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_MGTPRC);
210675eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_MGTPDC);
210775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_MGTPTC);
210875eba5b6SRobert Mustacchi 
210975eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_IAC);
211075eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICRXOC);
211175eba5b6SRobert Mustacchi 
211275eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICRXPTC);
211375eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICRXATC);
211475eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICTXPTC);
211575eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICTXATC);
211675eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICTXQEC);
211775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICTXQMTC);
211875eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICRXDMTC);
211975eba5b6SRobert Mustacchi 
212075eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_CBTMPC);
212175eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_HTDPMC);
212275eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_CBRMPC);
212375eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_RPTHC);
212475eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_HGPTC);
212575eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_HTCBDPC);
212675eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_HGORCL);
212775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_HGORCH);
212875eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_HGOTCL);
212975eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_HGOTCH);
213075eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_LENERRS);
213175eba5b6SRobert Mustacchi 
213275eba5b6SRobert Mustacchi 	/* This register should not be read in copper configurations */
213375eba5b6SRobert Mustacchi 	if ((hw->phy.media_type == e1000_media_type_internal_serdes) ||
213475eba5b6SRobert Mustacchi 	    e1000_sgmii_active_82575(hw))
213575eba5b6SRobert Mustacchi 		E1000_READ_REG(hw, E1000_SCVPC);
213675eba5b6SRobert Mustacchi }
213775eba5b6SRobert Mustacchi 
213875eba5b6SRobert Mustacchi /**
213975eba5b6SRobert Mustacchi  *  e1000_rx_fifo_flush_82575 - Clean rx fifo after Rx enable
214075eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
214175eba5b6SRobert Mustacchi  *
214249b78600SRobert Mustacchi  *  After Rx enable, if manageability is enabled then there is likely some
214375eba5b6SRobert Mustacchi  *  bad data at the start of the fifo and possibly in the DMA fifo.  This
214475eba5b6SRobert Mustacchi  *  function clears the fifos and flushes any packets that came in as rx was
214575eba5b6SRobert Mustacchi  *  being enabled.
214675eba5b6SRobert Mustacchi  **/
e1000_rx_fifo_flush_82575(struct e1000_hw * hw)214775eba5b6SRobert Mustacchi void e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
214875eba5b6SRobert Mustacchi {
214975eba5b6SRobert Mustacchi 	u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
215075eba5b6SRobert Mustacchi 	int i, ms_wait;
215175eba5b6SRobert Mustacchi 
215249b78600SRobert Mustacchi 	DEBUGFUNC("e1000_rx_fifo_flush_82575");
215349b78600SRobert Mustacchi 
215449b78600SRobert Mustacchi 	/* disable IPv6 options as per hardware errata */
215549b78600SRobert Mustacchi 	rfctl = E1000_READ_REG(hw, E1000_RFCTL);
215649b78600SRobert Mustacchi 	rfctl |= E1000_RFCTL_IPV6_EX_DIS;
215749b78600SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
215849b78600SRobert Mustacchi 
215975eba5b6SRobert Mustacchi 	if (hw->mac.type != e1000_82575 ||
216075eba5b6SRobert Mustacchi 	    !(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
216175eba5b6SRobert Mustacchi 		return;
216275eba5b6SRobert Mustacchi 
216375eba5b6SRobert Mustacchi 	/* Disable all Rx queues */
216475eba5b6SRobert Mustacchi 	for (i = 0; i < 4; i++) {
216575eba5b6SRobert Mustacchi 		rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i));
216675eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_RXDCTL(i),
216775eba5b6SRobert Mustacchi 				rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
216875eba5b6SRobert Mustacchi 	}
216975eba5b6SRobert Mustacchi 	/* Poll all queues to verify they have shut down */
217075eba5b6SRobert Mustacchi 	for (ms_wait = 0; ms_wait < 10; ms_wait++) {
217175eba5b6SRobert Mustacchi 		msec_delay(1);
217275eba5b6SRobert Mustacchi 		rx_enabled = 0;
217375eba5b6SRobert Mustacchi 		for (i = 0; i < 4; i++)
217475eba5b6SRobert Mustacchi 			rx_enabled |= E1000_READ_REG(hw, E1000_RXDCTL(i));
217575eba5b6SRobert Mustacchi 		if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
217675eba5b6SRobert Mustacchi 			break;
217775eba5b6SRobert Mustacchi 	}
217875eba5b6SRobert Mustacchi 
217975eba5b6SRobert Mustacchi 	if (ms_wait == 10)
218075eba5b6SRobert Mustacchi 		DEBUGOUT("Queue disable timed out after 10ms\n");
218175eba5b6SRobert Mustacchi 
218275eba5b6SRobert Mustacchi 	/* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
218375eba5b6SRobert Mustacchi 	 * incoming packets are rejected.  Set enable and wait 2ms so that
218475eba5b6SRobert Mustacchi 	 * any packet that was coming in as RCTL.EN was set is flushed
218575eba5b6SRobert Mustacchi 	 */
218675eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
218775eba5b6SRobert Mustacchi 
218875eba5b6SRobert Mustacchi 	rlpml = E1000_READ_REG(hw, E1000_RLPML);
218975eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RLPML, 0);
219075eba5b6SRobert Mustacchi 
219175eba5b6SRobert Mustacchi 	rctl = E1000_READ_REG(hw, E1000_RCTL);
219275eba5b6SRobert Mustacchi 	temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
219375eba5b6SRobert Mustacchi 	temp_rctl |= E1000_RCTL_LPE;
219475eba5b6SRobert Mustacchi 
219575eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl);
219675eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl | E1000_RCTL_EN);
219775eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
219875eba5b6SRobert Mustacchi 	msec_delay(2);
219975eba5b6SRobert Mustacchi 
220075eba5b6SRobert Mustacchi 	/* Enable Rx queues that were previously enabled and restore our
220175eba5b6SRobert Mustacchi 	 * previous state
220275eba5b6SRobert Mustacchi 	 */
220375eba5b6SRobert Mustacchi 	for (i = 0; i < 4; i++)
220475eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl[i]);
220575eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RCTL, rctl);
220675eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
220775eba5b6SRobert Mustacchi 
220875eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RLPML, rlpml);
220975eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
221075eba5b6SRobert Mustacchi 
221175eba5b6SRobert Mustacchi 	/* Flush receive errors generated by workaround */
221275eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ROC);
221375eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_RNBC);
221475eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_MPC);
221575eba5b6SRobert Mustacchi }
221675eba5b6SRobert Mustacchi 
221775eba5b6SRobert Mustacchi /**
221875eba5b6SRobert Mustacchi  *  e1000_set_pcie_completion_timeout - set pci-e completion timeout
221975eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
222075eba5b6SRobert Mustacchi  *
222175eba5b6SRobert Mustacchi  *  The defaults for 82575 and 82576 should be in the range of 50us to 50ms,
222275eba5b6SRobert Mustacchi  *  however the hardware default for these parts is 500us to 1ms which is less
222375eba5b6SRobert Mustacchi  *  than the 10ms recommended by the pci-e spec.  To address this we need to
222475eba5b6SRobert Mustacchi  *  increase the value to either 10ms to 200ms for capability version 1 config,
222575eba5b6SRobert Mustacchi  *  or 16ms to 55ms for version 2.
222675eba5b6SRobert Mustacchi  **/
e1000_set_pcie_completion_timeout(struct e1000_hw * hw)222775eba5b6SRobert Mustacchi static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw)
222875eba5b6SRobert Mustacchi {
222975eba5b6SRobert Mustacchi 	u32 gcr = E1000_READ_REG(hw, E1000_GCR);
223075eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
223175eba5b6SRobert Mustacchi 	u16 pcie_devctl2;
223275eba5b6SRobert Mustacchi 
223375eba5b6SRobert Mustacchi 	/* only take action if timeout value is defaulted to 0 */
223475eba5b6SRobert Mustacchi 	if (gcr & E1000_GCR_CMPL_TMOUT_MASK)
223575eba5b6SRobert Mustacchi 		goto out;
223675eba5b6SRobert Mustacchi 
223775eba5b6SRobert Mustacchi 	/*
223875eba5b6SRobert Mustacchi 	 * if capababilities version is type 1 we can write the
223975eba5b6SRobert Mustacchi 	 * timeout of 10ms to 200ms through the GCR register
224075eba5b6SRobert Mustacchi 	 */
224175eba5b6SRobert Mustacchi 	if (!(gcr & E1000_GCR_CAP_VER2)) {
224275eba5b6SRobert Mustacchi 		gcr |= E1000_GCR_CMPL_TMOUT_10ms;
224375eba5b6SRobert Mustacchi 		goto out;
224475eba5b6SRobert Mustacchi 	}
224575eba5b6SRobert Mustacchi 
224675eba5b6SRobert Mustacchi 	/*
224775eba5b6SRobert Mustacchi 	 * for version 2 capabilities we need to write the config space
224875eba5b6SRobert Mustacchi 	 * directly in order to set the completion timeout value for
224975eba5b6SRobert Mustacchi 	 * 16ms to 55ms
225075eba5b6SRobert Mustacchi 	 */
225175eba5b6SRobert Mustacchi 	ret_val = e1000_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
225275eba5b6SRobert Mustacchi 					  &pcie_devctl2);
225375eba5b6SRobert Mustacchi 	if (ret_val)
225475eba5b6SRobert Mustacchi 		goto out;
225575eba5b6SRobert Mustacchi 
225675eba5b6SRobert Mustacchi 	pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
225775eba5b6SRobert Mustacchi 
225875eba5b6SRobert Mustacchi 	ret_val = e1000_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
225975eba5b6SRobert Mustacchi 					   &pcie_devctl2);
226075eba5b6SRobert Mustacchi out:
226175eba5b6SRobert Mustacchi 	/* disable completion timeout resend */
226275eba5b6SRobert Mustacchi 	gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
226375eba5b6SRobert Mustacchi 
226475eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_GCR, gcr);
226575eba5b6SRobert Mustacchi 	return ret_val;
226675eba5b6SRobert Mustacchi }
226775eba5b6SRobert Mustacchi 
226875eba5b6SRobert Mustacchi /**
226975eba5b6SRobert Mustacchi  *  e1000_vmdq_set_anti_spoofing_pf - enable or disable anti-spoofing
227075eba5b6SRobert Mustacchi  *  @hw: pointer to the hardware struct
227175eba5b6SRobert Mustacchi  *  @enable: state to enter, either enabled or disabled
227275eba5b6SRobert Mustacchi  *  @pf: Physical Function pool - do not set anti-spoofing for the PF
227375eba5b6SRobert Mustacchi  *
227475eba5b6SRobert Mustacchi  *  enables/disables L2 switch anti-spoofing functionality.
227575eba5b6SRobert Mustacchi  **/
e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw * hw,bool enable,int pf)227675eba5b6SRobert Mustacchi void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
227775eba5b6SRobert Mustacchi {
227813485e69SGarrett D'Amore 	u32 reg_val, reg_offset;
227975eba5b6SRobert Mustacchi 
228075eba5b6SRobert Mustacchi 	switch (hw->mac.type) {
228175eba5b6SRobert Mustacchi 	case e1000_82576:
228213485e69SGarrett D'Amore 		reg_offset = E1000_DTXSWC;
228375eba5b6SRobert Mustacchi 		break;
228475eba5b6SRobert Mustacchi 	case e1000_i350:
228513485e69SGarrett D'Amore 	case e1000_i354:
228613485e69SGarrett D'Amore 		reg_offset = E1000_TXSWC;
228775eba5b6SRobert Mustacchi 		break;
228813485e69SGarrett D'Amore 	default:
228913485e69SGarrett D'Amore 		return;
229013485e69SGarrett D'Amore 	}
2291c124a83eSRobert Mustacchi 
229213485e69SGarrett D'Amore 	reg_val = E1000_READ_REG(hw, reg_offset);
229313485e69SGarrett D'Amore 	if (enable) {
229413485e69SGarrett D'Amore 		reg_val |= (E1000_DTXSWC_MAC_SPOOF_MASK |
2295c124a83eSRobert Mustacchi 			     E1000_DTXSWC_VLAN_SPOOF_MASK);
229613485e69SGarrett D'Amore 		/* The PF can spoof - it has to in order to
229713485e69SGarrett D'Amore 		 * support emulation mode NICs
229813485e69SGarrett D'Amore 		 */
229913485e69SGarrett D'Amore 		reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
230013485e69SGarrett D'Amore 	} else {
230113485e69SGarrett D'Amore 		reg_val &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
2302c124a83eSRobert Mustacchi 			     E1000_DTXSWC_VLAN_SPOOF_MASK);
230375eba5b6SRobert Mustacchi 	}
230413485e69SGarrett D'Amore 	E1000_WRITE_REG(hw, reg_offset, reg_val);
230575eba5b6SRobert Mustacchi }
230675eba5b6SRobert Mustacchi 
230775eba5b6SRobert Mustacchi /**
230875eba5b6SRobert Mustacchi  *  e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback
230975eba5b6SRobert Mustacchi  *  @hw: pointer to the hardware struct
231075eba5b6SRobert Mustacchi  *  @enable: state to enter, either enabled or disabled
231175eba5b6SRobert Mustacchi  *
231275eba5b6SRobert Mustacchi  *  enables/disables L2 switch loopback functionality.
231375eba5b6SRobert Mustacchi  **/
e1000_vmdq_set_loopback_pf(struct e1000_hw * hw,bool enable)231475eba5b6SRobert Mustacchi void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
231575eba5b6SRobert Mustacchi {
231675eba5b6SRobert Mustacchi 	u32 dtxswc;
231775eba5b6SRobert Mustacchi 
231875eba5b6SRobert Mustacchi 	switch (hw->mac.type) {
231975eba5b6SRobert Mustacchi 	case e1000_82576:
232075eba5b6SRobert Mustacchi 		dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
232175eba5b6SRobert Mustacchi 		if (enable)
232275eba5b6SRobert Mustacchi 			dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
232375eba5b6SRobert Mustacchi 		else
232475eba5b6SRobert Mustacchi 			dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
232575eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
232675eba5b6SRobert Mustacchi 		break;
232775eba5b6SRobert Mustacchi 	case e1000_i350:
232813485e69SGarrett D'Amore 	case e1000_i354:
232975eba5b6SRobert Mustacchi 		dtxswc = E1000_READ_REG(hw, E1000_TXSWC);
233075eba5b6SRobert Mustacchi 		if (enable)
233175eba5b6SRobert Mustacchi 			dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
233275eba5b6SRobert Mustacchi 		else
233375eba5b6SRobert Mustacchi 			dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
233475eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_TXSWC, dtxswc);
233575eba5b6SRobert Mustacchi 		break;
233675eba5b6SRobert Mustacchi 	default:
233775eba5b6SRobert Mustacchi 		/* Currently no other hardware supports loopback */
233875eba5b6SRobert Mustacchi 		break;
233975eba5b6SRobert Mustacchi 	}
234075eba5b6SRobert Mustacchi 
234175eba5b6SRobert Mustacchi 
234275eba5b6SRobert Mustacchi }
234375eba5b6SRobert Mustacchi 
234475eba5b6SRobert Mustacchi /**
234575eba5b6SRobert Mustacchi  *  e1000_vmdq_set_replication_pf - enable or disable vmdq replication
234675eba5b6SRobert Mustacchi  *  @hw: pointer to the hardware struct
234775eba5b6SRobert Mustacchi  *  @enable: state to enter, either enabled or disabled
234875eba5b6SRobert Mustacchi  *
234975eba5b6SRobert Mustacchi  *  enables/disables replication of packets across multiple pools.
235075eba5b6SRobert Mustacchi  **/
e1000_vmdq_set_replication_pf(struct e1000_hw * hw,bool enable)235175eba5b6SRobert Mustacchi void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
235275eba5b6SRobert Mustacchi {
235375eba5b6SRobert Mustacchi 	u32 vt_ctl = E1000_READ_REG(hw, E1000_VT_CTL);
235475eba5b6SRobert Mustacchi 
235575eba5b6SRobert Mustacchi 	if (enable)
235675eba5b6SRobert Mustacchi 		vt_ctl |= E1000_VT_CTL_VM_REPL_EN;
235775eba5b6SRobert Mustacchi 	else
235875eba5b6SRobert Mustacchi 		vt_ctl &= ~E1000_VT_CTL_VM_REPL_EN;
235975eba5b6SRobert Mustacchi 
236075eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_VT_CTL, vt_ctl);
236175eba5b6SRobert Mustacchi }
236275eba5b6SRobert Mustacchi 
236375eba5b6SRobert Mustacchi /**
236475eba5b6SRobert Mustacchi  *  e1000_read_phy_reg_82580 - Read 82580 MDI control register
236575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
236675eba5b6SRobert Mustacchi  *  @offset: register offset to be read
236775eba5b6SRobert Mustacchi  *  @data: pointer to the read data
236875eba5b6SRobert Mustacchi  *
236975eba5b6SRobert Mustacchi  *  Reads the MDI control register in the PHY at offset and stores the
237075eba5b6SRobert Mustacchi  *  information read to data.
237175eba5b6SRobert Mustacchi  **/
e1000_read_phy_reg_82580(struct e1000_hw * hw,u32 offset,u16 * data)237275eba5b6SRobert Mustacchi static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data)
237375eba5b6SRobert Mustacchi {
237475eba5b6SRobert Mustacchi 	s32 ret_val;
237575eba5b6SRobert Mustacchi 
237675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_read_phy_reg_82580");
237775eba5b6SRobert Mustacchi 
237875eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.acquire(hw);
237975eba5b6SRobert Mustacchi 	if (ret_val)
238075eba5b6SRobert Mustacchi 		goto out;
238175eba5b6SRobert Mustacchi 
238275eba5b6SRobert Mustacchi 	ret_val = e1000_read_phy_reg_mdic(hw, offset, data);
238375eba5b6SRobert Mustacchi 
238475eba5b6SRobert Mustacchi 	hw->phy.ops.release(hw);
238575eba5b6SRobert Mustacchi 
238675eba5b6SRobert Mustacchi out:
238775eba5b6SRobert Mustacchi 	return ret_val;
238875eba5b6SRobert Mustacchi }
238975eba5b6SRobert Mustacchi 
239075eba5b6SRobert Mustacchi /**
239175eba5b6SRobert Mustacchi  *  e1000_write_phy_reg_82580 - Write 82580 MDI control register
239275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
239375eba5b6SRobert Mustacchi  *  @offset: register offset to write to
239475eba5b6SRobert Mustacchi  *  @data: data to write to register at offset
239575eba5b6SRobert Mustacchi  *
239675eba5b6SRobert Mustacchi  *  Writes data to MDI control register in the PHY at offset.
239775eba5b6SRobert Mustacchi  **/
e1000_write_phy_reg_82580(struct e1000_hw * hw,u32 offset,u16 data)239875eba5b6SRobert Mustacchi static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data)
239975eba5b6SRobert Mustacchi {
240075eba5b6SRobert Mustacchi 	s32 ret_val;
240175eba5b6SRobert Mustacchi 
240275eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_write_phy_reg_82580");
240375eba5b6SRobert Mustacchi 
240475eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.acquire(hw);
240575eba5b6SRobert Mustacchi 	if (ret_val)
240675eba5b6SRobert Mustacchi 		goto out;
240775eba5b6SRobert Mustacchi 
240875eba5b6SRobert Mustacchi 	ret_val = e1000_write_phy_reg_mdic(hw, offset, data);
240975eba5b6SRobert Mustacchi 
241075eba5b6SRobert Mustacchi 	hw->phy.ops.release(hw);
241175eba5b6SRobert Mustacchi 
241275eba5b6SRobert Mustacchi out:
241375eba5b6SRobert Mustacchi 	return ret_val;
241475eba5b6SRobert Mustacchi }
241575eba5b6SRobert Mustacchi 
241675eba5b6SRobert Mustacchi /**
241775eba5b6SRobert Mustacchi  *  e1000_reset_mdicnfg_82580 - Reset MDICNFG destination and com_mdio bits
241875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
241975eba5b6SRobert Mustacchi  *
2420ea4c6b78SRobert Mustacchi  *  This resets the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on
242175eba5b6SRobert Mustacchi  *  the values found in the EEPROM.  This addresses an issue in which these
242275eba5b6SRobert Mustacchi  *  bits are not restored from EEPROM after reset.
242375eba5b6SRobert Mustacchi  **/
e1000_reset_mdicnfg_82580(struct e1000_hw * hw)242475eba5b6SRobert Mustacchi static s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw)
242575eba5b6SRobert Mustacchi {
242675eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
242775eba5b6SRobert Mustacchi 	u32 mdicnfg;
242875eba5b6SRobert Mustacchi 	u16 nvm_data = 0;
242975eba5b6SRobert Mustacchi 
243075eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_reset_mdicnfg_82580");
243175eba5b6SRobert Mustacchi 
243275eba5b6SRobert Mustacchi 	if (hw->mac.type != e1000_82580)
243375eba5b6SRobert Mustacchi 		goto out;
243475eba5b6SRobert Mustacchi 	if (!e1000_sgmii_active_82575(hw))
243575eba5b6SRobert Mustacchi 		goto out;
243675eba5b6SRobert Mustacchi 
243775eba5b6SRobert Mustacchi 	ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
243875eba5b6SRobert Mustacchi 				   NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
243975eba5b6SRobert Mustacchi 				   &nvm_data);
244075eba5b6SRobert Mustacchi 	if (ret_val) {
244175eba5b6SRobert Mustacchi 		DEBUGOUT("NVM Read Error\n");
244275eba5b6SRobert Mustacchi 		goto out;
244375eba5b6SRobert Mustacchi 	}
244475eba5b6SRobert Mustacchi 
244575eba5b6SRobert Mustacchi 	mdicnfg = E1000_READ_REG(hw, E1000_MDICNFG);
244675eba5b6SRobert Mustacchi 	if (nvm_data & NVM_WORD24_EXT_MDIO)
244775eba5b6SRobert Mustacchi 		mdicnfg |= E1000_MDICNFG_EXT_MDIO;
244875eba5b6SRobert Mustacchi 	if (nvm_data & NVM_WORD24_COM_MDIO)
244975eba5b6SRobert Mustacchi 		mdicnfg |= E1000_MDICNFG_COM_MDIO;
245075eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_MDICNFG, mdicnfg);
245175eba5b6SRobert Mustacchi out:
245275eba5b6SRobert Mustacchi 	return ret_val;
245375eba5b6SRobert Mustacchi }
245475eba5b6SRobert Mustacchi 
245575eba5b6SRobert Mustacchi /**
245675eba5b6SRobert Mustacchi  *  e1000_reset_hw_82580 - Reset hardware
245775eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
245875eba5b6SRobert Mustacchi  *
245975eba5b6SRobert Mustacchi  *  This resets function or entire device (all ports, etc.)
246075eba5b6SRobert Mustacchi  *  to a known state.
246175eba5b6SRobert Mustacchi  **/
e1000_reset_hw_82580(struct e1000_hw * hw)246275eba5b6SRobert Mustacchi static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
246375eba5b6SRobert Mustacchi {
246475eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
246575eba5b6SRobert Mustacchi 	/* BH SW mailbox bit in SW_FW_SYNC */
246675eba5b6SRobert Mustacchi 	u16 swmbsw_mask = E1000_SW_SYNCH_MB;
246775eba5b6SRobert Mustacchi 	u32 ctrl;
246875eba5b6SRobert Mustacchi 	bool global_device_reset = hw->dev_spec._82575.global_device_reset;
246975eba5b6SRobert Mustacchi 
247075eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_reset_hw_82580");
247175eba5b6SRobert Mustacchi 
247275eba5b6SRobert Mustacchi 	hw->dev_spec._82575.global_device_reset = FALSE;
247375eba5b6SRobert Mustacchi 
247475eba5b6SRobert Mustacchi 	/* 82580 does not reliably do global_device_reset due to hw errata */
247575eba5b6SRobert Mustacchi 	if (hw->mac.type == e1000_82580)
247675eba5b6SRobert Mustacchi 		global_device_reset = FALSE;
247775eba5b6SRobert Mustacchi 
247875eba5b6SRobert Mustacchi 	/* Get current control state. */
247975eba5b6SRobert Mustacchi 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
248075eba5b6SRobert Mustacchi 
248175eba5b6SRobert Mustacchi 	/*
248275eba5b6SRobert Mustacchi 	 * Prevent the PCI-E bus from sticking if there is no TLP connection
248375eba5b6SRobert Mustacchi 	 * on the last TLP read/write transaction when MAC is reset.
248475eba5b6SRobert Mustacchi 	 */
248575eba5b6SRobert Mustacchi 	ret_val = e1000_disable_pcie_master_generic(hw);
248675eba5b6SRobert Mustacchi 	if (ret_val)
248775eba5b6SRobert Mustacchi 		DEBUGOUT("PCI-E Master disable polling has failed.\n");
248875eba5b6SRobert Mustacchi 
248975eba5b6SRobert Mustacchi 	DEBUGOUT("Masking off all interrupts\n");
249075eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
249175eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
249275eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
249375eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
249475eba5b6SRobert Mustacchi 
249575eba5b6SRobert Mustacchi 	msec_delay(10);
249675eba5b6SRobert Mustacchi 
249775eba5b6SRobert Mustacchi 	/* Determine whether or not a global dev reset is requested */
249875eba5b6SRobert Mustacchi 	if (global_device_reset && hw->mac.ops.acquire_swfw_sync(hw,
249975eba5b6SRobert Mustacchi 	    swmbsw_mask))
250075eba5b6SRobert Mustacchi 			global_device_reset = FALSE;
250175eba5b6SRobert Mustacchi 
250275eba5b6SRobert Mustacchi 	if (global_device_reset && !(E1000_READ_REG(hw, E1000_STATUS) &
250375eba5b6SRobert Mustacchi 	    E1000_STAT_DEV_RST_SET))
250475eba5b6SRobert Mustacchi 		ctrl |= E1000_CTRL_DEV_RST;
250575eba5b6SRobert Mustacchi 	else
250675eba5b6SRobert Mustacchi 		ctrl |= E1000_CTRL_RST;
250775eba5b6SRobert Mustacchi 
250875eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
250975eba5b6SRobert Mustacchi 
2510c124a83eSRobert Mustacchi 	switch (hw->device_id) {
2511c124a83eSRobert Mustacchi 	case E1000_DEV_ID_DH89XXCC_SGMII:
2512c124a83eSRobert Mustacchi 		break;
2513c124a83eSRobert Mustacchi 	default:
2514c124a83eSRobert Mustacchi 		E1000_WRITE_FLUSH(hw);
2515c124a83eSRobert Mustacchi 		break;
2516c124a83eSRobert Mustacchi 	}
2517c124a83eSRobert Mustacchi 
2518c124a83eSRobert Mustacchi 	/* Add delay to insure DEV_RST or RST has time to complete */
2519c124a83eSRobert Mustacchi 	msec_delay(5);
252075eba5b6SRobert Mustacchi 
252175eba5b6SRobert Mustacchi 	ret_val = e1000_get_auto_rd_done_generic(hw);
252275eba5b6SRobert Mustacchi 	if (ret_val) {
252375eba5b6SRobert Mustacchi 		/*
252475eba5b6SRobert Mustacchi 		 * When auto config read does not complete, do not
252575eba5b6SRobert Mustacchi 		 * return with an error. This can happen in situations
252675eba5b6SRobert Mustacchi 		 * where there is no eeprom and prevents getting link.
252775eba5b6SRobert Mustacchi 		 */
252875eba5b6SRobert Mustacchi 		DEBUGOUT("Auto Read Done did not complete\n");
252975eba5b6SRobert Mustacchi 	}
253075eba5b6SRobert Mustacchi 
253175eba5b6SRobert Mustacchi 	/* clear global device reset status bit */
253275eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_STATUS, E1000_STAT_DEV_RST_SET);
253375eba5b6SRobert Mustacchi 
253475eba5b6SRobert Mustacchi 	/* Clear any pending interrupt events. */
253575eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
253675eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICR);
253775eba5b6SRobert Mustacchi 
253875eba5b6SRobert Mustacchi 	ret_val = e1000_reset_mdicnfg_82580(hw);
253975eba5b6SRobert Mustacchi 	if (ret_val)
254075eba5b6SRobert Mustacchi 		DEBUGOUT("Could not reset MDICNFG based on EEPROM\n");
254175eba5b6SRobert Mustacchi 
254275eba5b6SRobert Mustacchi 	/* Install any alternate MAC address into RAR0 */
254375eba5b6SRobert Mustacchi 	ret_val = e1000_check_alt_mac_addr_generic(hw);
254475eba5b6SRobert Mustacchi 
254575eba5b6SRobert Mustacchi 	/* Release semaphore */
254675eba5b6SRobert Mustacchi 	if (global_device_reset)
254775eba5b6SRobert Mustacchi 		hw->mac.ops.release_swfw_sync(hw, swmbsw_mask);
254875eba5b6SRobert Mustacchi 
254975eba5b6SRobert Mustacchi 	return ret_val;
255075eba5b6SRobert Mustacchi }
255175eba5b6SRobert Mustacchi 
255275eba5b6SRobert Mustacchi /**
255375eba5b6SRobert Mustacchi  *  e1000_rxpbs_adjust_82580 - adjust RXPBS value to reflect actual Rx PBA size
255475eba5b6SRobert Mustacchi  *  @data: data received by reading RXPBS register
255575eba5b6SRobert Mustacchi  *
255675eba5b6SRobert Mustacchi  *  The 82580 uses a table based approach for packet buffer allocation sizes.
255775eba5b6SRobert Mustacchi  *  This function converts the retrieved value into the correct table value
255875eba5b6SRobert Mustacchi  *     0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
255975eba5b6SRobert Mustacchi  *  0x0 36  72 144   1   2   4   8  16
256075eba5b6SRobert Mustacchi  *  0x8 35  70 140 rsv rsv rsv rsv rsv
256175eba5b6SRobert Mustacchi  */
e1000_rxpbs_adjust_82580(u32 data)256275eba5b6SRobert Mustacchi u16 e1000_rxpbs_adjust_82580(u32 data)
256375eba5b6SRobert Mustacchi {
256475eba5b6SRobert Mustacchi 	u16 ret_val = 0;
256575eba5b6SRobert Mustacchi 
256675eba5b6SRobert Mustacchi 	if (data < E1000_82580_RXPBS_TABLE_SIZE)
256775eba5b6SRobert Mustacchi 		ret_val = e1000_82580_rxpbs_table[data];
256875eba5b6SRobert Mustacchi 
256975eba5b6SRobert Mustacchi 	return ret_val;
257075eba5b6SRobert Mustacchi }
257175eba5b6SRobert Mustacchi 
257275eba5b6SRobert Mustacchi /**
257375eba5b6SRobert Mustacchi  *  e1000_validate_nvm_checksum_with_offset - Validate EEPROM
257475eba5b6SRobert Mustacchi  *  checksum
257575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
257675eba5b6SRobert Mustacchi  *  @offset: offset in words of the checksum protected region
257775eba5b6SRobert Mustacchi  *
257875eba5b6SRobert Mustacchi  *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
257975eba5b6SRobert Mustacchi  *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
258075eba5b6SRobert Mustacchi  **/
e1000_validate_nvm_checksum_with_offset(struct e1000_hw * hw,u16 offset)258175eba5b6SRobert Mustacchi s32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset)
258275eba5b6SRobert Mustacchi {
258375eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
258475eba5b6SRobert Mustacchi 	u16 checksum = 0;
258575eba5b6SRobert Mustacchi 	u16 i, nvm_data;
258675eba5b6SRobert Mustacchi 
258775eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_validate_nvm_checksum_with_offset");
258875eba5b6SRobert Mustacchi 
258975eba5b6SRobert Mustacchi 	for (i = offset; i < ((NVM_CHECKSUM_REG + offset) + 1); i++) {
259075eba5b6SRobert Mustacchi 		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
259175eba5b6SRobert Mustacchi 		if (ret_val) {
259275eba5b6SRobert Mustacchi 			DEBUGOUT("NVM Read Error\n");
259375eba5b6SRobert Mustacchi 			goto out;
259475eba5b6SRobert Mustacchi 		}
259575eba5b6SRobert Mustacchi 		checksum += nvm_data;
259675eba5b6SRobert Mustacchi 	}
259775eba5b6SRobert Mustacchi 
259875eba5b6SRobert Mustacchi 	if (checksum != (u16) NVM_SUM) {
259975eba5b6SRobert Mustacchi 		DEBUGOUT("NVM Checksum Invalid\n");
260075eba5b6SRobert Mustacchi 		ret_val = -E1000_ERR_NVM;
260175eba5b6SRobert Mustacchi 		goto out;
260275eba5b6SRobert Mustacchi 	}
260375eba5b6SRobert Mustacchi 
260475eba5b6SRobert Mustacchi out:
260575eba5b6SRobert Mustacchi 	return ret_val;
260675eba5b6SRobert Mustacchi }
260775eba5b6SRobert Mustacchi 
260875eba5b6SRobert Mustacchi /**
260975eba5b6SRobert Mustacchi  *  e1000_update_nvm_checksum_with_offset - Update EEPROM
261075eba5b6SRobert Mustacchi  *  checksum
261175eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
261275eba5b6SRobert Mustacchi  *  @offset: offset in words of the checksum protected region
261375eba5b6SRobert Mustacchi  *
261475eba5b6SRobert Mustacchi  *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
261575eba5b6SRobert Mustacchi  *  up to the checksum.  Then calculates the EEPROM checksum and writes the
261675eba5b6SRobert Mustacchi  *  value to the EEPROM.
261775eba5b6SRobert Mustacchi  **/
e1000_update_nvm_checksum_with_offset(struct e1000_hw * hw,u16 offset)261875eba5b6SRobert Mustacchi s32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset)
261975eba5b6SRobert Mustacchi {
262075eba5b6SRobert Mustacchi 	s32 ret_val;
262175eba5b6SRobert Mustacchi 	u16 checksum = 0;
262275eba5b6SRobert Mustacchi 	u16 i, nvm_data;
262375eba5b6SRobert Mustacchi 
262475eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_update_nvm_checksum_with_offset");
262575eba5b6SRobert Mustacchi 
262675eba5b6SRobert Mustacchi 	for (i = offset; i < (NVM_CHECKSUM_REG + offset); i++) {
262775eba5b6SRobert Mustacchi 		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
262875eba5b6SRobert Mustacchi 		if (ret_val) {
262975eba5b6SRobert Mustacchi 			DEBUGOUT("NVM Read Error while updating checksum.\n");
263075eba5b6SRobert Mustacchi 			goto out;
263175eba5b6SRobert Mustacchi 		}
263275eba5b6SRobert Mustacchi 		checksum += nvm_data;
263375eba5b6SRobert Mustacchi 	}
263475eba5b6SRobert Mustacchi 	checksum = (u16) NVM_SUM - checksum;
263575eba5b6SRobert Mustacchi 	ret_val = hw->nvm.ops.write(hw, (NVM_CHECKSUM_REG + offset), 1,
263675eba5b6SRobert Mustacchi 				    &checksum);
263775eba5b6SRobert Mustacchi 	if (ret_val)
263875eba5b6SRobert Mustacchi 		DEBUGOUT("NVM Write Error while updating checksum.\n");
263975eba5b6SRobert Mustacchi 
264075eba5b6SRobert Mustacchi out:
264175eba5b6SRobert Mustacchi 	return ret_val;
264275eba5b6SRobert Mustacchi }
264375eba5b6SRobert Mustacchi 
264475eba5b6SRobert Mustacchi /**
264575eba5b6SRobert Mustacchi  *  e1000_validate_nvm_checksum_82580 - Validate EEPROM checksum
264675eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
264775eba5b6SRobert Mustacchi  *
264875eba5b6SRobert Mustacchi  *  Calculates the EEPROM section checksum by reading/adding each word of
264975eba5b6SRobert Mustacchi  *  the EEPROM and then verifies that the sum of the EEPROM is
265075eba5b6SRobert Mustacchi  *  equal to 0xBABA.
265175eba5b6SRobert Mustacchi  **/
e1000_validate_nvm_checksum_82580(struct e1000_hw * hw)265275eba5b6SRobert Mustacchi static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw)
265375eba5b6SRobert Mustacchi {
2654c124a83eSRobert Mustacchi 	s32 ret_val;
265575eba5b6SRobert Mustacchi 	u16 eeprom_regions_count = 1;
265675eba5b6SRobert Mustacchi 	u16 j, nvm_data;
265775eba5b6SRobert Mustacchi 	u16 nvm_offset;
265875eba5b6SRobert Mustacchi 
265975eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_validate_nvm_checksum_82580");
266075eba5b6SRobert Mustacchi 
266175eba5b6SRobert Mustacchi 	ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data);
266275eba5b6SRobert Mustacchi 	if (ret_val) {
266375eba5b6SRobert Mustacchi 		DEBUGOUT("NVM Read Error\n");
266475eba5b6SRobert Mustacchi 		goto out;
266575eba5b6SRobert Mustacchi 	}
266675eba5b6SRobert Mustacchi 
266775eba5b6SRobert Mustacchi 	if (nvm_data & NVM_COMPATIBILITY_BIT_MASK) {
266875eba5b6SRobert Mustacchi 		/* if chekcsums compatibility bit is set validate checksums
266975eba5b6SRobert Mustacchi 		 * for all 4 ports. */
267075eba5b6SRobert Mustacchi 		eeprom_regions_count = 4;
267175eba5b6SRobert Mustacchi 	}
267275eba5b6SRobert Mustacchi 
267375eba5b6SRobert Mustacchi 	for (j = 0; j < eeprom_regions_count; j++) {
267475eba5b6SRobert Mustacchi 		nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
267575eba5b6SRobert Mustacchi 		ret_val = e1000_validate_nvm_checksum_with_offset(hw,
267675eba5b6SRobert Mustacchi 								  nvm_offset);
267775eba5b6SRobert Mustacchi 		if (ret_val != E1000_SUCCESS)
267875eba5b6SRobert Mustacchi 			goto out;
267975eba5b6SRobert Mustacchi 	}
268075eba5b6SRobert Mustacchi 
268175eba5b6SRobert Mustacchi out:
268275eba5b6SRobert Mustacchi 	return ret_val;
268375eba5b6SRobert Mustacchi }
268475eba5b6SRobert Mustacchi 
268575eba5b6SRobert Mustacchi /**
268675eba5b6SRobert Mustacchi  *  e1000_update_nvm_checksum_82580 - Update EEPROM checksum
268775eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
268875eba5b6SRobert Mustacchi  *
268975eba5b6SRobert Mustacchi  *  Updates the EEPROM section checksums for all 4 ports by reading/adding
269075eba5b6SRobert Mustacchi  *  each word of the EEPROM up to the checksum.  Then calculates the EEPROM
269175eba5b6SRobert Mustacchi  *  checksum and writes the value to the EEPROM.
269275eba5b6SRobert Mustacchi  **/
e1000_update_nvm_checksum_82580(struct e1000_hw * hw)269375eba5b6SRobert Mustacchi static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw)
269475eba5b6SRobert Mustacchi {
269575eba5b6SRobert Mustacchi 	s32 ret_val;
269675eba5b6SRobert Mustacchi 	u16 j, nvm_data;
269775eba5b6SRobert Mustacchi 	u16 nvm_offset;
269875eba5b6SRobert Mustacchi 
269975eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_update_nvm_checksum_82580");
270075eba5b6SRobert Mustacchi 
270175eba5b6SRobert Mustacchi 	ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data);
270275eba5b6SRobert Mustacchi 	if (ret_val) {
270375eba5b6SRobert Mustacchi 		DEBUGOUT("NVM Read Error while updating checksum compatibility bit.\n");
270475eba5b6SRobert Mustacchi 		goto out;
270575eba5b6SRobert Mustacchi 	}
270675eba5b6SRobert Mustacchi 
270775eba5b6SRobert Mustacchi 	if (!(nvm_data & NVM_COMPATIBILITY_BIT_MASK)) {
270875eba5b6SRobert Mustacchi 		/* set compatibility bit to validate checksums appropriately */
270975eba5b6SRobert Mustacchi 		nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK;
271075eba5b6SRobert Mustacchi 		ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1,
271175eba5b6SRobert Mustacchi 					    &nvm_data);
271275eba5b6SRobert Mustacchi 		if (ret_val) {
271375eba5b6SRobert Mustacchi 			DEBUGOUT("NVM Write Error while updating checksum compatibility bit.\n");
271475eba5b6SRobert Mustacchi 			goto out;
271575eba5b6SRobert Mustacchi 		}
271675eba5b6SRobert Mustacchi 	}
271775eba5b6SRobert Mustacchi 
271875eba5b6SRobert Mustacchi 	for (j = 0; j < 4; j++) {
271975eba5b6SRobert Mustacchi 		nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
272075eba5b6SRobert Mustacchi 		ret_val = e1000_update_nvm_checksum_with_offset(hw, nvm_offset);
272175eba5b6SRobert Mustacchi 		if (ret_val)
272275eba5b6SRobert Mustacchi 			goto out;
272375eba5b6SRobert Mustacchi 	}
272475eba5b6SRobert Mustacchi 
272575eba5b6SRobert Mustacchi out:
272675eba5b6SRobert Mustacchi 	return ret_val;
272775eba5b6SRobert Mustacchi }
272875eba5b6SRobert Mustacchi 
272975eba5b6SRobert Mustacchi /**
273075eba5b6SRobert Mustacchi  *  e1000_validate_nvm_checksum_i350 - Validate EEPROM checksum
273175eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
273275eba5b6SRobert Mustacchi  *
273375eba5b6SRobert Mustacchi  *  Calculates the EEPROM section checksum by reading/adding each word of
273475eba5b6SRobert Mustacchi  *  the EEPROM and then verifies that the sum of the EEPROM is
273575eba5b6SRobert Mustacchi  *  equal to 0xBABA.
273675eba5b6SRobert Mustacchi  **/
e1000_validate_nvm_checksum_i350(struct e1000_hw * hw)273775eba5b6SRobert Mustacchi static s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw)
273875eba5b6SRobert Mustacchi {
273975eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
274075eba5b6SRobert Mustacchi 	u16 j;
274175eba5b6SRobert Mustacchi 	u16 nvm_offset;
274275eba5b6SRobert Mustacchi 
274375eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_validate_nvm_checksum_i350");
274475eba5b6SRobert Mustacchi 
274575eba5b6SRobert Mustacchi 	for (j = 0; j < 4; j++) {
274675eba5b6SRobert Mustacchi 		nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
274775eba5b6SRobert Mustacchi 		ret_val = e1000_validate_nvm_checksum_with_offset(hw,
274875eba5b6SRobert Mustacchi 								  nvm_offset);
274975eba5b6SRobert Mustacchi 		if (ret_val != E1000_SUCCESS)
275075eba5b6SRobert Mustacchi 			goto out;
275175eba5b6SRobert Mustacchi 	}
275275eba5b6SRobert Mustacchi 
275375eba5b6SRobert Mustacchi out:
275475eba5b6SRobert Mustacchi 	return ret_val;
275575eba5b6SRobert Mustacchi }
275675eba5b6SRobert Mustacchi 
275775eba5b6SRobert Mustacchi /**
275875eba5b6SRobert Mustacchi  *  e1000_update_nvm_checksum_i350 - Update EEPROM checksum
275975eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
276075eba5b6SRobert Mustacchi  *
276175eba5b6SRobert Mustacchi  *  Updates the EEPROM section checksums for all 4 ports by reading/adding
276275eba5b6SRobert Mustacchi  *  each word of the EEPROM up to the checksum.  Then calculates the EEPROM
276375eba5b6SRobert Mustacchi  *  checksum and writes the value to the EEPROM.
276475eba5b6SRobert Mustacchi  **/
e1000_update_nvm_checksum_i350(struct e1000_hw * hw)276575eba5b6SRobert Mustacchi static s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw)
276675eba5b6SRobert Mustacchi {
276775eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
276875eba5b6SRobert Mustacchi 	u16 j;
276975eba5b6SRobert Mustacchi 	u16 nvm_offset;
277075eba5b6SRobert Mustacchi 
277175eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_update_nvm_checksum_i350");
277275eba5b6SRobert Mustacchi 
277375eba5b6SRobert Mustacchi 	for (j = 0; j < 4; j++) {
277475eba5b6SRobert Mustacchi 		nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
277575eba5b6SRobert Mustacchi 		ret_val = e1000_update_nvm_checksum_with_offset(hw, nvm_offset);
277675eba5b6SRobert Mustacchi 		if (ret_val != E1000_SUCCESS)
277775eba5b6SRobert Mustacchi 			goto out;
277875eba5b6SRobert Mustacchi 	}
277975eba5b6SRobert Mustacchi 
278075eba5b6SRobert Mustacchi out:
278175eba5b6SRobert Mustacchi 	return ret_val;
278275eba5b6SRobert Mustacchi }
278375eba5b6SRobert Mustacchi 
2784c124a83eSRobert Mustacchi /**
2785c124a83eSRobert Mustacchi  *  __e1000_access_emi_reg - Read/write EMI register
2786c124a83eSRobert Mustacchi  *  @hw: pointer to the HW structure
2787c124a83eSRobert Mustacchi  *  @addr: EMI address to program
2788c124a83eSRobert Mustacchi  *  @data: pointer to value to read/write from/to the EMI address
2789c124a83eSRobert Mustacchi  *  @read: boolean flag to indicate read or write
2790c124a83eSRobert Mustacchi  **/
__e1000_access_emi_reg(struct e1000_hw * hw,u16 address,u16 * data,bool read)2791c124a83eSRobert Mustacchi static s32 __e1000_access_emi_reg(struct e1000_hw *hw, u16 address,
2792c124a83eSRobert Mustacchi 				  u16 *data, bool read)
2793c124a83eSRobert Mustacchi {
2794c124a83eSRobert Mustacchi 	s32 ret_val;
2795c124a83eSRobert Mustacchi 
2796c124a83eSRobert Mustacchi 	DEBUGFUNC("__e1000_access_emi_reg");
2797c124a83eSRobert Mustacchi 
2798c124a83eSRobert Mustacchi 	ret_val = hw->phy.ops.write_reg(hw, E1000_EMIADD, address);
2799c124a83eSRobert Mustacchi 	if (ret_val)
2800c124a83eSRobert Mustacchi 		return ret_val;
2801c124a83eSRobert Mustacchi 
2802c124a83eSRobert Mustacchi 	if (read)
2803c124a83eSRobert Mustacchi 		ret_val = hw->phy.ops.read_reg(hw, E1000_EMIDATA, data);
2804c124a83eSRobert Mustacchi 	else
2805c124a83eSRobert Mustacchi 		ret_val = hw->phy.ops.write_reg(hw, E1000_EMIDATA, *data);
2806c124a83eSRobert Mustacchi 
2807c124a83eSRobert Mustacchi 	return ret_val;
2808c124a83eSRobert Mustacchi }
2809c124a83eSRobert Mustacchi 
2810c124a83eSRobert Mustacchi /**
2811c124a83eSRobert Mustacchi  *  e1000_read_emi_reg - Read Extended Management Interface register
2812c124a83eSRobert Mustacchi  *  @hw: pointer to the HW structure
2813c124a83eSRobert Mustacchi  *  @addr: EMI address to program
2814c124a83eSRobert Mustacchi  *  @data: value to be read from the EMI address
2815c124a83eSRobert Mustacchi  **/
e1000_read_emi_reg(struct e1000_hw * hw,u16 addr,u16 * data)2816c124a83eSRobert Mustacchi s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data)
2817c124a83eSRobert Mustacchi {
2818c124a83eSRobert Mustacchi 	DEBUGFUNC("e1000_read_emi_reg");
2819c124a83eSRobert Mustacchi 
2820c124a83eSRobert Mustacchi 	return __e1000_access_emi_reg(hw, addr, data, TRUE);
2821c124a83eSRobert Mustacchi }
2822c124a83eSRobert Mustacchi 
2823c124a83eSRobert Mustacchi /**
2824c124a83eSRobert Mustacchi  *  e1000_initialize_M88E1512_phy - Initialize M88E1512 PHY
2825c124a83eSRobert Mustacchi  *  @hw: pointer to the HW structure
2826c124a83eSRobert Mustacchi  *
282749b78600SRobert Mustacchi  *  Initialize Marvell 1512 to work correctly with Avoton.
2828c124a83eSRobert Mustacchi  **/
e1000_initialize_M88E1512_phy(struct e1000_hw * hw)2829c124a83eSRobert Mustacchi s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw)
2830c124a83eSRobert Mustacchi {
2831c124a83eSRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
2832c124a83eSRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
2833c124a83eSRobert Mustacchi 
2834c124a83eSRobert Mustacchi 	DEBUGFUNC("e1000_initialize_M88E1512_phy");
2835c124a83eSRobert Mustacchi 
2836c124a83eSRobert Mustacchi 	/* Check if this is correct PHY. */
2837c124a83eSRobert Mustacchi 	if (phy->id != M88E1512_E_PHY_ID)
2838c124a83eSRobert Mustacchi 		goto out;
2839c124a83eSRobert Mustacchi 
2840c124a83eSRobert Mustacchi 	/* Switch to PHY page 0xFF. */
2841c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
2842c124a83eSRobert Mustacchi 	if (ret_val)
2843c124a83eSRobert Mustacchi 		goto out;
2844c124a83eSRobert Mustacchi 
2845c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
2846c124a83eSRobert Mustacchi 	if (ret_val)
2847c124a83eSRobert Mustacchi 		goto out;
2848c124a83eSRobert Mustacchi 
2849c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
2850c124a83eSRobert Mustacchi 	if (ret_val)
2851c124a83eSRobert Mustacchi 		goto out;
2852c124a83eSRobert Mustacchi 
2853c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
2854c124a83eSRobert Mustacchi 	if (ret_val)
2855c124a83eSRobert Mustacchi 		goto out;
2856c124a83eSRobert Mustacchi 
2857c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
2858c124a83eSRobert Mustacchi 	if (ret_val)
2859c124a83eSRobert Mustacchi 		goto out;
2860c124a83eSRobert Mustacchi 
2861c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
2862c124a83eSRobert Mustacchi 	if (ret_val)
2863c124a83eSRobert Mustacchi 		goto out;
2864c124a83eSRobert Mustacchi 
2865c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
2866c124a83eSRobert Mustacchi 	if (ret_val)
2867c124a83eSRobert Mustacchi 		goto out;
2868c124a83eSRobert Mustacchi 
2869c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xCC0C);
2870c124a83eSRobert Mustacchi 	if (ret_val)
2871c124a83eSRobert Mustacchi 		goto out;
2872c124a83eSRobert Mustacchi 
2873c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
2874c124a83eSRobert Mustacchi 	if (ret_val)
2875c124a83eSRobert Mustacchi 		goto out;
2876c124a83eSRobert Mustacchi 
2877c124a83eSRobert Mustacchi 	/* Switch to PHY page 0xFB. */
2878c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
2879c124a83eSRobert Mustacchi 	if (ret_val)
2880c124a83eSRobert Mustacchi 		goto out;
2881c124a83eSRobert Mustacchi 
2882c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0x000D);
2883c124a83eSRobert Mustacchi 	if (ret_val)
2884c124a83eSRobert Mustacchi 		goto out;
2885c124a83eSRobert Mustacchi 
2886c124a83eSRobert Mustacchi 	/* Switch to PHY page 0x12. */
2887c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
2888c124a83eSRobert Mustacchi 	if (ret_val)
2889c124a83eSRobert Mustacchi 		goto out;
2890c124a83eSRobert Mustacchi 
2891c124a83eSRobert Mustacchi 	/* Change mode to SGMII-to-Copper */
2892c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
2893c124a83eSRobert Mustacchi 	if (ret_val)
2894c124a83eSRobert Mustacchi 		goto out;
2895c124a83eSRobert Mustacchi 
2896c124a83eSRobert Mustacchi 	/* Return the PHY to page 0. */
2897c124a83eSRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
2898c124a83eSRobert Mustacchi 	if (ret_val)
2899c124a83eSRobert Mustacchi 		goto out;
2900c124a83eSRobert Mustacchi 
2901c124a83eSRobert Mustacchi 	ret_val = phy->ops.commit(hw);
2902c124a83eSRobert Mustacchi 	if (ret_val) {
2903c124a83eSRobert Mustacchi 		DEBUGOUT("Error committing the PHY changes\n");
2904c124a83eSRobert Mustacchi 		return ret_val;
2905c124a83eSRobert Mustacchi 	}
2906c124a83eSRobert Mustacchi 
2907c124a83eSRobert Mustacchi 	msec_delay(1000);
2908c124a83eSRobert Mustacchi out:
2909c124a83eSRobert Mustacchi 	return ret_val;
2910c124a83eSRobert Mustacchi }
2911c124a83eSRobert Mustacchi 
291249b78600SRobert Mustacchi /**
291349b78600SRobert Mustacchi  *  e1000_initialize_M88E1543_phy - Initialize M88E1543 PHY
291449b78600SRobert Mustacchi  *  @hw: pointer to the HW structure
291549b78600SRobert Mustacchi  *
291649b78600SRobert Mustacchi  *  Initialize Marvell 1543 to work correctly with Avoton.
291749b78600SRobert Mustacchi  **/
e1000_initialize_M88E1543_phy(struct e1000_hw * hw)291849b78600SRobert Mustacchi s32 e1000_initialize_M88E1543_phy(struct e1000_hw *hw)
291949b78600SRobert Mustacchi {
292049b78600SRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
292149b78600SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
292249b78600SRobert Mustacchi 
292349b78600SRobert Mustacchi 	DEBUGFUNC("e1000_initialize_M88E1543_phy");
292449b78600SRobert Mustacchi 
292549b78600SRobert Mustacchi 	/* Check if this is correct PHY. */
292649b78600SRobert Mustacchi 	if (phy->id != M88E1543_E_PHY_ID)
292749b78600SRobert Mustacchi 		goto out;
292849b78600SRobert Mustacchi 
292949b78600SRobert Mustacchi 	/* Switch to PHY page 0xFF. */
293049b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
293149b78600SRobert Mustacchi 	if (ret_val)
293249b78600SRobert Mustacchi 		goto out;
293349b78600SRobert Mustacchi 
293449b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
293549b78600SRobert Mustacchi 	if (ret_val)
293649b78600SRobert Mustacchi 		goto out;
293749b78600SRobert Mustacchi 
293849b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
293949b78600SRobert Mustacchi 	if (ret_val)
294049b78600SRobert Mustacchi 		goto out;
294149b78600SRobert Mustacchi 
294249b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
294349b78600SRobert Mustacchi 	if (ret_val)
294449b78600SRobert Mustacchi 		goto out;
294549b78600SRobert Mustacchi 
294649b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
294749b78600SRobert Mustacchi 	if (ret_val)
294849b78600SRobert Mustacchi 		goto out;
294949b78600SRobert Mustacchi 
295049b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
295149b78600SRobert Mustacchi 	if (ret_val)
295249b78600SRobert Mustacchi 		goto out;
295349b78600SRobert Mustacchi 
295449b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
295549b78600SRobert Mustacchi 	if (ret_val)
295649b78600SRobert Mustacchi 		goto out;
295749b78600SRobert Mustacchi 
295849b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xDC0C);
295949b78600SRobert Mustacchi 	if (ret_val)
296049b78600SRobert Mustacchi 		goto out;
296149b78600SRobert Mustacchi 
296249b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
296349b78600SRobert Mustacchi 	if (ret_val)
296449b78600SRobert Mustacchi 		goto out;
296549b78600SRobert Mustacchi 
296649b78600SRobert Mustacchi 	/* Switch to PHY page 0xFB. */
296749b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
296849b78600SRobert Mustacchi 	if (ret_val)
296949b78600SRobert Mustacchi 		goto out;
297049b78600SRobert Mustacchi 
297149b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0xC00D);
297249b78600SRobert Mustacchi 	if (ret_val)
297349b78600SRobert Mustacchi 		goto out;
297449b78600SRobert Mustacchi 
297549b78600SRobert Mustacchi 	/* Switch to PHY page 0x12. */
297649b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
297749b78600SRobert Mustacchi 	if (ret_val)
297849b78600SRobert Mustacchi 		goto out;
297949b78600SRobert Mustacchi 
298049b78600SRobert Mustacchi 	/* Change mode to SGMII-to-Copper */
298149b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
298249b78600SRobert Mustacchi 	if (ret_val)
298349b78600SRobert Mustacchi 		goto out;
298449b78600SRobert Mustacchi 
298549b78600SRobert Mustacchi 	/* Switch to PHY page 1. */
298649b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x1);
298749b78600SRobert Mustacchi 	if (ret_val)
298849b78600SRobert Mustacchi 		goto out;
298949b78600SRobert Mustacchi 
299049b78600SRobert Mustacchi 	/* Change mode to 1000BASE-X/SGMII and autoneg enable; reset */
299149b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_FIBER_CTRL, 0x9140);
299249b78600SRobert Mustacchi 	if (ret_val)
299349b78600SRobert Mustacchi 		goto out;
299449b78600SRobert Mustacchi 
299549b78600SRobert Mustacchi 	/* Return the PHY to page 0. */
299649b78600SRobert Mustacchi 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
299749b78600SRobert Mustacchi 	if (ret_val)
299849b78600SRobert Mustacchi 		goto out;
299949b78600SRobert Mustacchi 
300049b78600SRobert Mustacchi 	ret_val = phy->ops.commit(hw);
300149b78600SRobert Mustacchi 	if (ret_val) {
300249b78600SRobert Mustacchi 		DEBUGOUT("Error committing the PHY changes\n");
300349b78600SRobert Mustacchi 		return ret_val;
300449b78600SRobert Mustacchi 	}
300549b78600SRobert Mustacchi 
300649b78600SRobert Mustacchi 	msec_delay(1000);
300749b78600SRobert Mustacchi out:
300849b78600SRobert Mustacchi 	return ret_val;
300949b78600SRobert Mustacchi }
301049b78600SRobert Mustacchi 
301175eba5b6SRobert Mustacchi /**
301275eba5b6SRobert Mustacchi  *  e1000_set_eee_i350 - Enable/disable EEE support
301375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
301449b78600SRobert Mustacchi  *  @adv1g: boolean flag enabling 1G EEE advertisement
301549b78600SRobert Mustacchi  *  @adv100m: boolean flag enabling 100M EEE advertisement
301675eba5b6SRobert Mustacchi  *
301775eba5b6SRobert Mustacchi  *  Enable/disable EEE based on setting in dev_spec structure.
301875eba5b6SRobert Mustacchi  *
301975eba5b6SRobert Mustacchi  **/
e1000_set_eee_i350(struct e1000_hw * hw,bool adv1G,bool adv100M)302049b78600SRobert Mustacchi s32 e1000_set_eee_i350(struct e1000_hw *hw, bool adv1G, bool adv100M)
302175eba5b6SRobert Mustacchi {
302275eba5b6SRobert Mustacchi 	u32 ipcnfg, eeer;
302375eba5b6SRobert Mustacchi 
302475eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_set_eee_i350");
302575eba5b6SRobert Mustacchi 
302675eba5b6SRobert Mustacchi 	if ((hw->mac.type < e1000_i350) ||
302775eba5b6SRobert Mustacchi 	    (hw->phy.media_type != e1000_media_type_copper))
302875eba5b6SRobert Mustacchi 		goto out;
302975eba5b6SRobert Mustacchi 	ipcnfg = E1000_READ_REG(hw, E1000_IPCNFG);
303075eba5b6SRobert Mustacchi 	eeer = E1000_READ_REG(hw, E1000_EEER);
303175eba5b6SRobert Mustacchi 
303275eba5b6SRobert Mustacchi 	/* enable or disable per user setting */
303375eba5b6SRobert Mustacchi 	if (!(hw->dev_spec._82575.eee_disable)) {
303475eba5b6SRobert Mustacchi 		u32 eee_su = E1000_READ_REG(hw, E1000_EEE_SU);
303575eba5b6SRobert Mustacchi 
303649b78600SRobert Mustacchi 		if (adv100M)
303749b78600SRobert Mustacchi 			ipcnfg |= E1000_IPCNFG_EEE_100M_AN;
303849b78600SRobert Mustacchi 		else
303949b78600SRobert Mustacchi 			ipcnfg &= ~E1000_IPCNFG_EEE_100M_AN;
304049b78600SRobert Mustacchi 
304149b78600SRobert Mustacchi 		if (adv1G)
304249b78600SRobert Mustacchi 			ipcnfg |= E1000_IPCNFG_EEE_1G_AN;
304349b78600SRobert Mustacchi 		else
304449b78600SRobert Mustacchi 			ipcnfg &= ~E1000_IPCNFG_EEE_1G_AN;
304549b78600SRobert Mustacchi 
304675eba5b6SRobert Mustacchi 		eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
304775eba5b6SRobert Mustacchi 			 E1000_EEER_LPI_FC);
304875eba5b6SRobert Mustacchi 
304975eba5b6SRobert Mustacchi 		/* This bit should not be set in normal operation. */
305075eba5b6SRobert Mustacchi 		if (eee_su & E1000_EEE_SU_LPI_CLK_STP)
305175eba5b6SRobert Mustacchi 			DEBUGOUT("LPI Clock Stop Bit should not be set!\n");
305275eba5b6SRobert Mustacchi 	} else {
305375eba5b6SRobert Mustacchi 		ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
305475eba5b6SRobert Mustacchi 		eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
305575eba5b6SRobert Mustacchi 			  E1000_EEER_LPI_FC);
305675eba5b6SRobert Mustacchi 	}
305775eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_IPCNFG, ipcnfg);
305875eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_EEER, eeer);
305975eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_IPCNFG);
306075eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_EEER);
306175eba5b6SRobert Mustacchi out:
306275eba5b6SRobert Mustacchi 
3063c124a83eSRobert Mustacchi 	return E1000_SUCCESS;
306475eba5b6SRobert Mustacchi }
306575eba5b6SRobert Mustacchi 
306613485e69SGarrett D'Amore /**
306713485e69SGarrett D'Amore  *  e1000_set_eee_i354 - Enable/disable EEE support
306813485e69SGarrett D'Amore  *  @hw: pointer to the HW structure
306949b78600SRobert Mustacchi  *  @adv1g: boolean flag enabling 1G EEE advertisement
307049b78600SRobert Mustacchi  *  @adv100m: boolean flag enabling 100M EEE advertisement
307113485e69SGarrett D'Amore  *
307213485e69SGarrett D'Amore  *  Enable/disable EEE legacy mode based on setting in dev_spec structure.
307313485e69SGarrett D'Amore  *
307413485e69SGarrett D'Amore  **/
e1000_set_eee_i354(struct e1000_hw * hw,bool adv1G,bool adv100M)307549b78600SRobert Mustacchi s32 e1000_set_eee_i354(struct e1000_hw *hw, bool adv1G, bool adv100M)
307613485e69SGarrett D'Amore {
307713485e69SGarrett D'Amore 	struct e1000_phy_info *phy = &hw->phy;
307813485e69SGarrett D'Amore 	s32 ret_val = E1000_SUCCESS;
307913485e69SGarrett D'Amore 	u16 phy_data;
308013485e69SGarrett D'Amore 
308113485e69SGarrett D'Amore 	DEBUGFUNC("e1000_set_eee_i354");
308213485e69SGarrett D'Amore 
308313485e69SGarrett D'Amore 	if ((hw->phy.media_type != e1000_media_type_copper) ||
308413485e69SGarrett D'Amore 	    ((phy->id != M88E1543_E_PHY_ID) &&
308513485e69SGarrett D'Amore 	    (phy->id != M88E1512_E_PHY_ID)))
308613485e69SGarrett D'Amore 		goto out;
308713485e69SGarrett D'Amore 
308813485e69SGarrett D'Amore 	if (!hw->dev_spec._82575.eee_disable) {
308913485e69SGarrett D'Amore 		/* Switch to PHY page 18. */
309013485e69SGarrett D'Amore 		ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 18);
309113485e69SGarrett D'Amore 		if (ret_val)
309213485e69SGarrett D'Amore 			goto out;
309313485e69SGarrett D'Amore 
309413485e69SGarrett D'Amore 		ret_val = phy->ops.read_reg(hw, E1000_M88E1543_EEE_CTRL_1,
309513485e69SGarrett D'Amore 					    &phy_data);
309613485e69SGarrett D'Amore 		if (ret_val)
309713485e69SGarrett D'Amore 			goto out;
309813485e69SGarrett D'Amore 
309913485e69SGarrett D'Amore 		phy_data |= E1000_M88E1543_EEE_CTRL_1_MS;
310013485e69SGarrett D'Amore 		ret_val = phy->ops.write_reg(hw, E1000_M88E1543_EEE_CTRL_1,
310113485e69SGarrett D'Amore 					     phy_data);
310213485e69SGarrett D'Amore 		if (ret_val)
310313485e69SGarrett D'Amore 			goto out;
310413485e69SGarrett D'Amore 
310513485e69SGarrett D'Amore 		/* Return the PHY to page 0. */
310613485e69SGarrett D'Amore 		ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
310713485e69SGarrett D'Amore 		if (ret_val)
310813485e69SGarrett D'Amore 			goto out;
310913485e69SGarrett D'Amore 
311013485e69SGarrett D'Amore 		/* Turn on EEE advertisement. */
311113485e69SGarrett D'Amore 		ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
311213485e69SGarrett D'Amore 					       E1000_EEE_ADV_DEV_I354,
311313485e69SGarrett D'Amore 					       &phy_data);
311413485e69SGarrett D'Amore 		if (ret_val)
3115c124a83eSRobert Mustacchi 			goto out;
311613485e69SGarrett D'Amore 
311749b78600SRobert Mustacchi 		if (adv100M)
311849b78600SRobert Mustacchi 			phy_data |= E1000_EEE_ADV_100_SUPPORTED;
311949b78600SRobert Mustacchi 		else
312049b78600SRobert Mustacchi 			phy_data &= ~E1000_EEE_ADV_100_SUPPORTED;
312149b78600SRobert Mustacchi 
312249b78600SRobert Mustacchi 		if (adv1G)
312349b78600SRobert Mustacchi 			phy_data |= E1000_EEE_ADV_1000_SUPPORTED;
312449b78600SRobert Mustacchi 		else
312549b78600SRobert Mustacchi 			phy_data &= ~E1000_EEE_ADV_1000_SUPPORTED;
312649b78600SRobert Mustacchi 
312713485e69SGarrett D'Amore 		ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
312813485e69SGarrett D'Amore 						E1000_EEE_ADV_DEV_I354,
312913485e69SGarrett D'Amore 						phy_data);
313013485e69SGarrett D'Amore 	} else {
313113485e69SGarrett D'Amore 		/* Turn off EEE advertisement. */
313213485e69SGarrett D'Amore 		ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
313313485e69SGarrett D'Amore 					       E1000_EEE_ADV_DEV_I354,
313413485e69SGarrett D'Amore 					       &phy_data);
313513485e69SGarrett D'Amore 		if (ret_val)
313613485e69SGarrett D'Amore 			goto out;
313713485e69SGarrett D'Amore 
313813485e69SGarrett D'Amore 		phy_data &= ~(E1000_EEE_ADV_100_SUPPORTED |
313913485e69SGarrett D'Amore 			      E1000_EEE_ADV_1000_SUPPORTED);
314013485e69SGarrett D'Amore 		ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
314113485e69SGarrett D'Amore 						E1000_EEE_ADV_DEV_I354,
314213485e69SGarrett D'Amore 						phy_data);
314313485e69SGarrett D'Amore 	}
314413485e69SGarrett D'Amore 
314513485e69SGarrett D'Amore out:
314613485e69SGarrett D'Amore 	return ret_val;
314713485e69SGarrett D'Amore }
314813485e69SGarrett D'Amore 
314913485e69SGarrett D'Amore /**
315013485e69SGarrett D'Amore  *  e1000_get_eee_status_i354 - Get EEE status
315113485e69SGarrett D'Amore  *  @hw: pointer to the HW structure
315213485e69SGarrett D'Amore  *  @status: EEE status
315313485e69SGarrett D'Amore  *
315413485e69SGarrett D'Amore  *  Get EEE status by guessing based on whether Tx or Rx LPI indications have
315513485e69SGarrett D'Amore  *  been received.
315613485e69SGarrett D'Amore  **/
e1000_get_eee_status_i354(struct e1000_hw * hw,bool * status)315713485e69SGarrett D'Amore s32 e1000_get_eee_status_i354(struct e1000_hw *hw, bool *status)
315813485e69SGarrett D'Amore {
315913485e69SGarrett D'Amore 	struct e1000_phy_info *phy = &hw->phy;
316013485e69SGarrett D'Amore 	s32 ret_val = E1000_SUCCESS;
316113485e69SGarrett D'Amore 	u16 phy_data;
316213485e69SGarrett D'Amore 
316313485e69SGarrett D'Amore 	DEBUGFUNC("e1000_get_eee_status_i354");
316413485e69SGarrett D'Amore 
316513485e69SGarrett D'Amore 	/* Check if EEE is supported on this device. */
316613485e69SGarrett D'Amore 	if ((hw->phy.media_type != e1000_media_type_copper) ||
316713485e69SGarrett D'Amore 	    ((phy->id != M88E1543_E_PHY_ID) &&
3168c124a83eSRobert Mustacchi 	    (phy->id != M88E1512_E_PHY_ID)))
316913485e69SGarrett D'Amore 		goto out;
317013485e69SGarrett D'Amore 
317113485e69SGarrett D'Amore 	ret_val = e1000_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354,
317213485e69SGarrett D'Amore 				       E1000_PCS_STATUS_DEV_I354,
317313485e69SGarrett D'Amore 				       &phy_data);
317413485e69SGarrett D'Amore 	if (ret_val)
317513485e69SGarrett D'Amore 		goto out;
317613485e69SGarrett D'Amore 
317713485e69SGarrett D'Amore 	*status = phy_data & (E1000_PCS_STATUS_TX_LPI_RCVD |
317813485e69SGarrett D'Amore 			      E1000_PCS_STATUS_RX_LPI_RCVD) ? TRUE : FALSE;
317913485e69SGarrett D'Amore 
318013485e69SGarrett D'Amore out:
318113485e69SGarrett D'Amore 	return ret_val;
318213485e69SGarrett D'Amore }
318313485e69SGarrett D'Amore 
318475eba5b6SRobert Mustacchi /* Due to a hw errata, if the host tries to  configure the VFTA register
318575eba5b6SRobert Mustacchi  * while performing queries from the BMC or DMA, then the VFTA in some
318675eba5b6SRobert Mustacchi  * cases won't be written.
318775eba5b6SRobert Mustacchi  */
318875eba5b6SRobert Mustacchi 
318975eba5b6SRobert Mustacchi /**
319075eba5b6SRobert Mustacchi  *  e1000_clear_vfta_i350 - Clear VLAN filter table
319175eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
319275eba5b6SRobert Mustacchi  *
319375eba5b6SRobert Mustacchi  *  Clears the register array which contains the VLAN filter table by
319475eba5b6SRobert Mustacchi  *  setting all the values to 0.
319575eba5b6SRobert Mustacchi  **/
e1000_clear_vfta_i350(struct e1000_hw * hw)319675eba5b6SRobert Mustacchi void e1000_clear_vfta_i350(struct e1000_hw *hw)
319775eba5b6SRobert Mustacchi {
319875eba5b6SRobert Mustacchi 	u32 offset;
319975eba5b6SRobert Mustacchi 	int i;
320075eba5b6SRobert Mustacchi 
320175eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_clear_vfta_350");
320275eba5b6SRobert Mustacchi 
320375eba5b6SRobert Mustacchi 	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
320475eba5b6SRobert Mustacchi 		for (i = 0; i < 10; i++)
320575eba5b6SRobert Mustacchi 			E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
320675eba5b6SRobert Mustacchi 
320775eba5b6SRobert Mustacchi 		E1000_WRITE_FLUSH(hw);
320875eba5b6SRobert Mustacchi 	}
320975eba5b6SRobert Mustacchi }
321075eba5b6SRobert Mustacchi 
321175eba5b6SRobert Mustacchi /**
321275eba5b6SRobert Mustacchi  *  e1000_write_vfta_i350 - Write value to VLAN filter table
321375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
321475eba5b6SRobert Mustacchi  *  @offset: register offset in VLAN filter table
321575eba5b6SRobert Mustacchi  *  @value: register value written to VLAN filter table
321675eba5b6SRobert Mustacchi  *
321775eba5b6SRobert Mustacchi  *  Writes value at the given offset in the register array which stores
321875eba5b6SRobert Mustacchi  *  the VLAN filter table.
321975eba5b6SRobert Mustacchi  **/
e1000_write_vfta_i350(struct e1000_hw * hw,u32 offset,u32 value)322075eba5b6SRobert Mustacchi void e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value)
322175eba5b6SRobert Mustacchi {
322275eba5b6SRobert Mustacchi 	int i;
322375eba5b6SRobert Mustacchi 
322475eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_write_vfta_350");
322575eba5b6SRobert Mustacchi 
322675eba5b6SRobert Mustacchi 	for (i = 0; i < 10; i++)
322775eba5b6SRobert Mustacchi 		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
322875eba5b6SRobert Mustacchi 
322975eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
323075eba5b6SRobert Mustacchi }
323175eba5b6SRobert Mustacchi 
323275eba5b6SRobert Mustacchi 
323375eba5b6SRobert Mustacchi /**
323475eba5b6SRobert Mustacchi  *  e1000_set_i2c_bb - Enable I2C bit-bang
323575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
323675eba5b6SRobert Mustacchi  *
323775eba5b6SRobert Mustacchi  *  Enable I2C bit-bang interface
323875eba5b6SRobert Mustacchi  *
323975eba5b6SRobert Mustacchi  **/
e1000_set_i2c_bb(struct e1000_hw * hw)324075eba5b6SRobert Mustacchi s32 e1000_set_i2c_bb(struct e1000_hw *hw)
324175eba5b6SRobert Mustacchi {
324275eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
324375eba5b6SRobert Mustacchi 	u32 ctrl_ext, i2cparams;
324475eba5b6SRobert Mustacchi 
324575eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_set_i2c_bb");
324675eba5b6SRobert Mustacchi 
324775eba5b6SRobert Mustacchi 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
324875eba5b6SRobert Mustacchi 	ctrl_ext |= E1000_CTRL_I2C_ENA;
324975eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
325075eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
325175eba5b6SRobert Mustacchi 
325275eba5b6SRobert Mustacchi 	i2cparams = E1000_READ_REG(hw, E1000_I2CPARAMS);
325375eba5b6SRobert Mustacchi 	i2cparams |= E1000_I2CBB_EN;
325475eba5b6SRobert Mustacchi 	i2cparams |= E1000_I2C_DATA_OE_N;
325575eba5b6SRobert Mustacchi 	i2cparams |= E1000_I2C_CLK_OE_N;
325675eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cparams);
325775eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
325875eba5b6SRobert Mustacchi 
325975eba5b6SRobert Mustacchi 	return ret_val;
326075eba5b6SRobert Mustacchi }
326175eba5b6SRobert Mustacchi 
326275eba5b6SRobert Mustacchi /**
326375eba5b6SRobert Mustacchi  *  e1000_read_i2c_byte_generic - Reads 8 bit word over I2C
326475eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
326575eba5b6SRobert Mustacchi  *  @byte_offset: byte offset to read
326675eba5b6SRobert Mustacchi  *  @dev_addr: device address
326775eba5b6SRobert Mustacchi  *  @data: value read
326875eba5b6SRobert Mustacchi  *
326975eba5b6SRobert Mustacchi  *  Performs byte read operation over I2C interface at
327075eba5b6SRobert Mustacchi  *  a specified device address.
327175eba5b6SRobert Mustacchi  **/
e1000_read_i2c_byte_generic(struct e1000_hw * hw,u8 byte_offset,u8 dev_addr,u8 * data)327275eba5b6SRobert Mustacchi s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
327375eba5b6SRobert Mustacchi 				u8 dev_addr, u8 *data)
327475eba5b6SRobert Mustacchi {
327575eba5b6SRobert Mustacchi 	s32 status = E1000_SUCCESS;
327675eba5b6SRobert Mustacchi 	u32 max_retry = 10;
327775eba5b6SRobert Mustacchi 	u32 retry = 1;
327875eba5b6SRobert Mustacchi 	u16 swfw_mask = 0;
327975eba5b6SRobert Mustacchi 
328075eba5b6SRobert Mustacchi 	bool nack = TRUE;
328175eba5b6SRobert Mustacchi 
328275eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_read_i2c_byte_generic");
328375eba5b6SRobert Mustacchi 
328475eba5b6SRobert Mustacchi 	swfw_mask = E1000_SWFW_PHY0_SM;
328575eba5b6SRobert Mustacchi 
328675eba5b6SRobert Mustacchi 	do {
328775eba5b6SRobert Mustacchi 		if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)
328875eba5b6SRobert Mustacchi 		    != E1000_SUCCESS) {
328975eba5b6SRobert Mustacchi 			status = E1000_ERR_SWFW_SYNC;
329075eba5b6SRobert Mustacchi 			goto read_byte_out;
329175eba5b6SRobert Mustacchi 		}
329275eba5b6SRobert Mustacchi 
329375eba5b6SRobert Mustacchi 		e1000_i2c_start(hw);
329475eba5b6SRobert Mustacchi 
329575eba5b6SRobert Mustacchi 		/* Device Address and write indication */
329675eba5b6SRobert Mustacchi 		status = e1000_clock_out_i2c_byte(hw, dev_addr);
329775eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
329875eba5b6SRobert Mustacchi 			goto fail;
329975eba5b6SRobert Mustacchi 
330075eba5b6SRobert Mustacchi 		status = e1000_get_i2c_ack(hw);
330175eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
330275eba5b6SRobert Mustacchi 			goto fail;
330375eba5b6SRobert Mustacchi 
330475eba5b6SRobert Mustacchi 		status = e1000_clock_out_i2c_byte(hw, byte_offset);
330575eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
330675eba5b6SRobert Mustacchi 			goto fail;
330775eba5b6SRobert Mustacchi 
330875eba5b6SRobert Mustacchi 		status = e1000_get_i2c_ack(hw);
330975eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
331075eba5b6SRobert Mustacchi 			goto fail;
331175eba5b6SRobert Mustacchi 
331275eba5b6SRobert Mustacchi 		e1000_i2c_start(hw);
331375eba5b6SRobert Mustacchi 
331475eba5b6SRobert Mustacchi 		/* Device Address and read indication */
331575eba5b6SRobert Mustacchi 		status = e1000_clock_out_i2c_byte(hw, (dev_addr | 0x1));
331675eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
331775eba5b6SRobert Mustacchi 			goto fail;
331875eba5b6SRobert Mustacchi 
331975eba5b6SRobert Mustacchi 		status = e1000_get_i2c_ack(hw);
332075eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
332175eba5b6SRobert Mustacchi 			goto fail;
332275eba5b6SRobert Mustacchi 
332375eba5b6SRobert Mustacchi 		status = e1000_clock_in_i2c_byte(hw, data);
332475eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
332575eba5b6SRobert Mustacchi 			goto fail;
332675eba5b6SRobert Mustacchi 
332775eba5b6SRobert Mustacchi 		status = e1000_clock_out_i2c_bit(hw, nack);
332875eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
332975eba5b6SRobert Mustacchi 			goto fail;
333075eba5b6SRobert Mustacchi 
333175eba5b6SRobert Mustacchi 		e1000_i2c_stop(hw);
333275eba5b6SRobert Mustacchi 		break;
333375eba5b6SRobert Mustacchi 
333475eba5b6SRobert Mustacchi fail:
333575eba5b6SRobert Mustacchi 		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
333675eba5b6SRobert Mustacchi 		msec_delay(100);
333775eba5b6SRobert Mustacchi 		e1000_i2c_bus_clear(hw);
333875eba5b6SRobert Mustacchi 		retry++;
333975eba5b6SRobert Mustacchi 		if (retry < max_retry)
334075eba5b6SRobert Mustacchi 			DEBUGOUT("I2C byte read error - Retrying.\n");
334175eba5b6SRobert Mustacchi 		else
334275eba5b6SRobert Mustacchi 			DEBUGOUT("I2C byte read error.\n");
334375eba5b6SRobert Mustacchi 
334475eba5b6SRobert Mustacchi 	} while (retry < max_retry);
334575eba5b6SRobert Mustacchi 
334675eba5b6SRobert Mustacchi 	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
334775eba5b6SRobert Mustacchi 
334875eba5b6SRobert Mustacchi read_byte_out:
334975eba5b6SRobert Mustacchi 
335075eba5b6SRobert Mustacchi 	return status;
335175eba5b6SRobert Mustacchi }
335275eba5b6SRobert Mustacchi 
335375eba5b6SRobert Mustacchi /**
335475eba5b6SRobert Mustacchi  *  e1000_write_i2c_byte_generic - Writes 8 bit word over I2C
335575eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
335675eba5b6SRobert Mustacchi  *  @byte_offset: byte offset to write
335775eba5b6SRobert Mustacchi  *  @dev_addr: device address
335875eba5b6SRobert Mustacchi  *  @data: value to write
335975eba5b6SRobert Mustacchi  *
336075eba5b6SRobert Mustacchi  *  Performs byte write operation over I2C interface at
336175eba5b6SRobert Mustacchi  *  a specified device address.
336275eba5b6SRobert Mustacchi  **/
e1000_write_i2c_byte_generic(struct e1000_hw * hw,u8 byte_offset,u8 dev_addr,u8 data)336375eba5b6SRobert Mustacchi s32 e1000_write_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
336475eba5b6SRobert Mustacchi 				 u8 dev_addr, u8 data)
336575eba5b6SRobert Mustacchi {
336675eba5b6SRobert Mustacchi 	s32 status = E1000_SUCCESS;
336775eba5b6SRobert Mustacchi 	u32 max_retry = 1;
336875eba5b6SRobert Mustacchi 	u32 retry = 0;
336975eba5b6SRobert Mustacchi 	u16 swfw_mask = 0;
337075eba5b6SRobert Mustacchi 
337175eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_write_i2c_byte_generic");
337275eba5b6SRobert Mustacchi 
337375eba5b6SRobert Mustacchi 	swfw_mask = E1000_SWFW_PHY0_SM;
337475eba5b6SRobert Mustacchi 
337575eba5b6SRobert Mustacchi 	if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != E1000_SUCCESS) {
337675eba5b6SRobert Mustacchi 		status = E1000_ERR_SWFW_SYNC;
337775eba5b6SRobert Mustacchi 		goto write_byte_out;
337875eba5b6SRobert Mustacchi 	}
337975eba5b6SRobert Mustacchi 
338075eba5b6SRobert Mustacchi 	do {
338175eba5b6SRobert Mustacchi 		e1000_i2c_start(hw);
338275eba5b6SRobert Mustacchi 
338375eba5b6SRobert Mustacchi 		status = e1000_clock_out_i2c_byte(hw, dev_addr);
338475eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
338575eba5b6SRobert Mustacchi 			goto fail;
338675eba5b6SRobert Mustacchi 
338775eba5b6SRobert Mustacchi 		status = e1000_get_i2c_ack(hw);
338875eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
338975eba5b6SRobert Mustacchi 			goto fail;
339075eba5b6SRobert Mustacchi 
339175eba5b6SRobert Mustacchi 		status = e1000_clock_out_i2c_byte(hw, byte_offset);
339275eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
339375eba5b6SRobert Mustacchi 			goto fail;
339475eba5b6SRobert Mustacchi 
339575eba5b6SRobert Mustacchi 		status = e1000_get_i2c_ack(hw);
339675eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
339775eba5b6SRobert Mustacchi 			goto fail;
339875eba5b6SRobert Mustacchi 
339975eba5b6SRobert Mustacchi 		status = e1000_clock_out_i2c_byte(hw, data);
340075eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
340175eba5b6SRobert Mustacchi 			goto fail;
340275eba5b6SRobert Mustacchi 
340375eba5b6SRobert Mustacchi 		status = e1000_get_i2c_ack(hw);
340475eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
340575eba5b6SRobert Mustacchi 			goto fail;
340675eba5b6SRobert Mustacchi 
340775eba5b6SRobert Mustacchi 		e1000_i2c_stop(hw);
340875eba5b6SRobert Mustacchi 		break;
340975eba5b6SRobert Mustacchi 
341075eba5b6SRobert Mustacchi fail:
341175eba5b6SRobert Mustacchi 		e1000_i2c_bus_clear(hw);
341275eba5b6SRobert Mustacchi 		retry++;
341375eba5b6SRobert Mustacchi 		if (retry < max_retry)
341475eba5b6SRobert Mustacchi 			DEBUGOUT("I2C byte write error - Retrying.\n");
341575eba5b6SRobert Mustacchi 		else
341675eba5b6SRobert Mustacchi 			DEBUGOUT("I2C byte write error.\n");
341775eba5b6SRobert Mustacchi 	} while (retry < max_retry);
341875eba5b6SRobert Mustacchi 
341975eba5b6SRobert Mustacchi 	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
342075eba5b6SRobert Mustacchi 
342175eba5b6SRobert Mustacchi write_byte_out:
342275eba5b6SRobert Mustacchi 
342375eba5b6SRobert Mustacchi 	return status;
342475eba5b6SRobert Mustacchi }
342575eba5b6SRobert Mustacchi 
342675eba5b6SRobert Mustacchi /**
342775eba5b6SRobert Mustacchi  *  e1000_i2c_start - Sets I2C start condition
342875eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
342975eba5b6SRobert Mustacchi  *
343075eba5b6SRobert Mustacchi  *  Sets I2C start condition (High -> Low on SDA while SCL is High)
343175eba5b6SRobert Mustacchi  **/
e1000_i2c_start(struct e1000_hw * hw)343275eba5b6SRobert Mustacchi static void e1000_i2c_start(struct e1000_hw *hw)
343375eba5b6SRobert Mustacchi {
343475eba5b6SRobert Mustacchi 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
343575eba5b6SRobert Mustacchi 
343675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_i2c_start");
343775eba5b6SRobert Mustacchi 
343875eba5b6SRobert Mustacchi 	/* Start condition must begin with data and clock high */
343975eba5b6SRobert Mustacchi 	e1000_set_i2c_data(hw, &i2cctl, 1);
344075eba5b6SRobert Mustacchi 	e1000_raise_i2c_clk(hw, &i2cctl);
344175eba5b6SRobert Mustacchi 
344275eba5b6SRobert Mustacchi 	/* Setup time for start condition (4.7us) */
344375eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_SU_STA);
344475eba5b6SRobert Mustacchi 
344575eba5b6SRobert Mustacchi 	e1000_set_i2c_data(hw, &i2cctl, 0);
344675eba5b6SRobert Mustacchi 
344775eba5b6SRobert Mustacchi 	/* Hold time for start condition (4us) */
344875eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_HD_STA);
344975eba5b6SRobert Mustacchi 
345075eba5b6SRobert Mustacchi 	e1000_lower_i2c_clk(hw, &i2cctl);
345175eba5b6SRobert Mustacchi 
345275eba5b6SRobert Mustacchi 	/* Minimum low period of clock is 4.7 us */
345375eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_LOW);
345475eba5b6SRobert Mustacchi 
345575eba5b6SRobert Mustacchi }
345675eba5b6SRobert Mustacchi 
345775eba5b6SRobert Mustacchi /**
345875eba5b6SRobert Mustacchi  *  e1000_i2c_stop - Sets I2C stop condition
345975eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
346075eba5b6SRobert Mustacchi  *
346175eba5b6SRobert Mustacchi  *  Sets I2C stop condition (Low -> High on SDA while SCL is High)
346275eba5b6SRobert Mustacchi  **/
e1000_i2c_stop(struct e1000_hw * hw)346375eba5b6SRobert Mustacchi static void e1000_i2c_stop(struct e1000_hw *hw)
346475eba5b6SRobert Mustacchi {
346575eba5b6SRobert Mustacchi 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
346675eba5b6SRobert Mustacchi 
346775eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_i2c_stop");
346875eba5b6SRobert Mustacchi 
346975eba5b6SRobert Mustacchi 	/* Stop condition must begin with data low and clock high */
347075eba5b6SRobert Mustacchi 	e1000_set_i2c_data(hw, &i2cctl, 0);
347175eba5b6SRobert Mustacchi 	e1000_raise_i2c_clk(hw, &i2cctl);
347275eba5b6SRobert Mustacchi 
347375eba5b6SRobert Mustacchi 	/* Setup time for stop condition (4us) */
347475eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_SU_STO);
347575eba5b6SRobert Mustacchi 
347675eba5b6SRobert Mustacchi 	e1000_set_i2c_data(hw, &i2cctl, 1);
347775eba5b6SRobert Mustacchi 
347875eba5b6SRobert Mustacchi 	/* bus free time between stop and start (4.7us)*/
347975eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_BUF);
348075eba5b6SRobert Mustacchi }
348175eba5b6SRobert Mustacchi 
348275eba5b6SRobert Mustacchi /**
348375eba5b6SRobert Mustacchi  *  e1000_clock_in_i2c_byte - Clocks in one byte via I2C
348475eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
348575eba5b6SRobert Mustacchi  *  @data: data byte to clock in
348675eba5b6SRobert Mustacchi  *
348775eba5b6SRobert Mustacchi  *  Clocks in one byte data via I2C data/clock
348875eba5b6SRobert Mustacchi  **/
e1000_clock_in_i2c_byte(struct e1000_hw * hw,u8 * data)348975eba5b6SRobert Mustacchi static s32 e1000_clock_in_i2c_byte(struct e1000_hw *hw, u8 *data)
349075eba5b6SRobert Mustacchi {
349175eba5b6SRobert Mustacchi 	s32 i;
349275eba5b6SRobert Mustacchi 	bool bit = 0;
349375eba5b6SRobert Mustacchi 
349475eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_clock_in_i2c_byte");
349575eba5b6SRobert Mustacchi 
349675eba5b6SRobert Mustacchi 	*data = 0;
349775eba5b6SRobert Mustacchi 	for (i = 7; i >= 0; i--) {
349875eba5b6SRobert Mustacchi 		e1000_clock_in_i2c_bit(hw, &bit);
349975eba5b6SRobert Mustacchi 		*data |= bit << i;
350075eba5b6SRobert Mustacchi 	}
350175eba5b6SRobert Mustacchi 
350275eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
350375eba5b6SRobert Mustacchi }
350475eba5b6SRobert Mustacchi 
350575eba5b6SRobert Mustacchi /**
350675eba5b6SRobert Mustacchi  *  e1000_clock_out_i2c_byte - Clocks out one byte via I2C
350775eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
350875eba5b6SRobert Mustacchi  *  @data: data byte clocked out
350975eba5b6SRobert Mustacchi  *
351075eba5b6SRobert Mustacchi  *  Clocks out one byte data via I2C data/clock
351175eba5b6SRobert Mustacchi  **/
e1000_clock_out_i2c_byte(struct e1000_hw * hw,u8 data)351275eba5b6SRobert Mustacchi static s32 e1000_clock_out_i2c_byte(struct e1000_hw *hw, u8 data)
351375eba5b6SRobert Mustacchi {
351475eba5b6SRobert Mustacchi 	s32 status = E1000_SUCCESS;
351575eba5b6SRobert Mustacchi 	s32 i;
351675eba5b6SRobert Mustacchi 	u32 i2cctl;
351775eba5b6SRobert Mustacchi 	bool bit = 0;
351875eba5b6SRobert Mustacchi 
351975eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_clock_out_i2c_byte");
352075eba5b6SRobert Mustacchi 
352175eba5b6SRobert Mustacchi 	for (i = 7; i >= 0; i--) {
352275eba5b6SRobert Mustacchi 		bit = (data >> i) & 0x1;
352375eba5b6SRobert Mustacchi 		status = e1000_clock_out_i2c_bit(hw, bit);
352475eba5b6SRobert Mustacchi 
352575eba5b6SRobert Mustacchi 		if (status != E1000_SUCCESS)
352675eba5b6SRobert Mustacchi 			break;
352775eba5b6SRobert Mustacchi 	}
352875eba5b6SRobert Mustacchi 
352975eba5b6SRobert Mustacchi 	/* Release SDA line (set high) */
353075eba5b6SRobert Mustacchi 	i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
353175eba5b6SRobert Mustacchi 
353275eba5b6SRobert Mustacchi 	i2cctl |= E1000_I2C_DATA_OE_N;
353375eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cctl);
353475eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
353575eba5b6SRobert Mustacchi 
353675eba5b6SRobert Mustacchi 	return status;
353775eba5b6SRobert Mustacchi }
353875eba5b6SRobert Mustacchi 
353975eba5b6SRobert Mustacchi /**
354075eba5b6SRobert Mustacchi  *  e1000_get_i2c_ack - Polls for I2C ACK
354175eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
354275eba5b6SRobert Mustacchi  *
354375eba5b6SRobert Mustacchi  *  Clocks in/out one bit via I2C data/clock
354475eba5b6SRobert Mustacchi  **/
e1000_get_i2c_ack(struct e1000_hw * hw)354575eba5b6SRobert Mustacchi static s32 e1000_get_i2c_ack(struct e1000_hw *hw)
354675eba5b6SRobert Mustacchi {
354775eba5b6SRobert Mustacchi 	s32 status = E1000_SUCCESS;
354875eba5b6SRobert Mustacchi 	u32 i = 0;
354975eba5b6SRobert Mustacchi 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
355075eba5b6SRobert Mustacchi 	u32 timeout = 10;
355175eba5b6SRobert Mustacchi 	bool ack = TRUE;
355275eba5b6SRobert Mustacchi 
355375eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_get_i2c_ack");
355475eba5b6SRobert Mustacchi 
355575eba5b6SRobert Mustacchi 	e1000_raise_i2c_clk(hw, &i2cctl);
355675eba5b6SRobert Mustacchi 
355775eba5b6SRobert Mustacchi 	/* Minimum high period of clock is 4us */
355875eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_HIGH);
355975eba5b6SRobert Mustacchi 
356075eba5b6SRobert Mustacchi 	/* Wait until SCL returns high */
356175eba5b6SRobert Mustacchi 	for (i = 0; i < timeout; i++) {
356275eba5b6SRobert Mustacchi 		usec_delay(1);
356375eba5b6SRobert Mustacchi 		i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
356475eba5b6SRobert Mustacchi 		if (i2cctl & E1000_I2C_CLK_IN)
356575eba5b6SRobert Mustacchi 			break;
356675eba5b6SRobert Mustacchi 	}
356775eba5b6SRobert Mustacchi 	if (!(i2cctl & E1000_I2C_CLK_IN))
356875eba5b6SRobert Mustacchi 		return E1000_ERR_I2C;
356975eba5b6SRobert Mustacchi 
357075eba5b6SRobert Mustacchi 	ack = e1000_get_i2c_data(&i2cctl);
357175eba5b6SRobert Mustacchi 	if (ack) {
357275eba5b6SRobert Mustacchi 		DEBUGOUT("I2C ack was not received.\n");
357375eba5b6SRobert Mustacchi 		status = E1000_ERR_I2C;
357475eba5b6SRobert Mustacchi 	}
357575eba5b6SRobert Mustacchi 
357675eba5b6SRobert Mustacchi 	e1000_lower_i2c_clk(hw, &i2cctl);
357775eba5b6SRobert Mustacchi 
357875eba5b6SRobert Mustacchi 	/* Minimum low period of clock is 4.7 us */
357975eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_LOW);
358075eba5b6SRobert Mustacchi 
358175eba5b6SRobert Mustacchi 	return status;
358275eba5b6SRobert Mustacchi }
358375eba5b6SRobert Mustacchi 
358475eba5b6SRobert Mustacchi /**
358575eba5b6SRobert Mustacchi  *  e1000_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
358675eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
358775eba5b6SRobert Mustacchi  *  @data: read data value
358875eba5b6SRobert Mustacchi  *
358975eba5b6SRobert Mustacchi  *  Clocks in one bit via I2C data/clock
359075eba5b6SRobert Mustacchi  **/
e1000_clock_in_i2c_bit(struct e1000_hw * hw,bool * data)359175eba5b6SRobert Mustacchi static s32 e1000_clock_in_i2c_bit(struct e1000_hw *hw, bool *data)
359275eba5b6SRobert Mustacchi {
359375eba5b6SRobert Mustacchi 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
359475eba5b6SRobert Mustacchi 
359575eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_clock_in_i2c_bit");
359675eba5b6SRobert Mustacchi 
359775eba5b6SRobert Mustacchi 	e1000_raise_i2c_clk(hw, &i2cctl);
359875eba5b6SRobert Mustacchi 
359975eba5b6SRobert Mustacchi 	/* Minimum high period of clock is 4us */
360075eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_HIGH);
360175eba5b6SRobert Mustacchi 
360275eba5b6SRobert Mustacchi 	i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
360375eba5b6SRobert Mustacchi 	*data = e1000_get_i2c_data(&i2cctl);
360475eba5b6SRobert Mustacchi 
360575eba5b6SRobert Mustacchi 	e1000_lower_i2c_clk(hw, &i2cctl);
360675eba5b6SRobert Mustacchi 
360775eba5b6SRobert Mustacchi 	/* Minimum low period of clock is 4.7 us */
360875eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_LOW);
360975eba5b6SRobert Mustacchi 
361075eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
361175eba5b6SRobert Mustacchi }
361275eba5b6SRobert Mustacchi 
361375eba5b6SRobert Mustacchi /**
361475eba5b6SRobert Mustacchi  *  e1000_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
361575eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
361675eba5b6SRobert Mustacchi  *  @data: data value to write
361775eba5b6SRobert Mustacchi  *
361875eba5b6SRobert Mustacchi  *  Clocks out one bit via I2C data/clock
361975eba5b6SRobert Mustacchi  **/
e1000_clock_out_i2c_bit(struct e1000_hw * hw,bool data)362075eba5b6SRobert Mustacchi static s32 e1000_clock_out_i2c_bit(struct e1000_hw *hw, bool data)
362175eba5b6SRobert Mustacchi {
362275eba5b6SRobert Mustacchi 	s32 status;
362375eba5b6SRobert Mustacchi 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
362475eba5b6SRobert Mustacchi 
362575eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_clock_out_i2c_bit");
362675eba5b6SRobert Mustacchi 
362775eba5b6SRobert Mustacchi 	status = e1000_set_i2c_data(hw, &i2cctl, data);
362875eba5b6SRobert Mustacchi 	if (status == E1000_SUCCESS) {
362975eba5b6SRobert Mustacchi 		e1000_raise_i2c_clk(hw, &i2cctl);
363075eba5b6SRobert Mustacchi 
363175eba5b6SRobert Mustacchi 		/* Minimum high period of clock is 4us */
363275eba5b6SRobert Mustacchi 		usec_delay(E1000_I2C_T_HIGH);
363375eba5b6SRobert Mustacchi 
363475eba5b6SRobert Mustacchi 		e1000_lower_i2c_clk(hw, &i2cctl);
363575eba5b6SRobert Mustacchi 
363675eba5b6SRobert Mustacchi 		/* Minimum low period of clock is 4.7 us.
363775eba5b6SRobert Mustacchi 		 * This also takes care of the data hold time.
363875eba5b6SRobert Mustacchi 		 */
363975eba5b6SRobert Mustacchi 		usec_delay(E1000_I2C_T_LOW);
364075eba5b6SRobert Mustacchi 	} else {
364175eba5b6SRobert Mustacchi 		status = E1000_ERR_I2C;
364275eba5b6SRobert Mustacchi 		DEBUGOUT1("I2C data was not set to %X\n", data);
364375eba5b6SRobert Mustacchi 	}
364475eba5b6SRobert Mustacchi 
364575eba5b6SRobert Mustacchi 	return status;
364675eba5b6SRobert Mustacchi }
364775eba5b6SRobert Mustacchi /**
364875eba5b6SRobert Mustacchi  *  e1000_raise_i2c_clk - Raises the I2C SCL clock
364975eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
365075eba5b6SRobert Mustacchi  *  @i2cctl: Current value of I2CCTL register
365175eba5b6SRobert Mustacchi  *
365275eba5b6SRobert Mustacchi  *  Raises the I2C clock line '0'->'1'
365375eba5b6SRobert Mustacchi  **/
e1000_raise_i2c_clk(struct e1000_hw * hw,u32 * i2cctl)365475eba5b6SRobert Mustacchi static void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl)
365575eba5b6SRobert Mustacchi {
365675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_raise_i2c_clk");
365775eba5b6SRobert Mustacchi 
365875eba5b6SRobert Mustacchi 	*i2cctl |= E1000_I2C_CLK_OUT;
365975eba5b6SRobert Mustacchi 	*i2cctl &= ~E1000_I2C_CLK_OE_N;
366075eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
366175eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
366275eba5b6SRobert Mustacchi 
366375eba5b6SRobert Mustacchi 	/* SCL rise time (1000ns) */
366475eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_RISE);
366575eba5b6SRobert Mustacchi }
366675eba5b6SRobert Mustacchi 
366775eba5b6SRobert Mustacchi /**
366875eba5b6SRobert Mustacchi  *  e1000_lower_i2c_clk - Lowers the I2C SCL clock
366975eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
367075eba5b6SRobert Mustacchi  *  @i2cctl: Current value of I2CCTL register
367175eba5b6SRobert Mustacchi  *
367275eba5b6SRobert Mustacchi  *  Lowers the I2C clock line '1'->'0'
367375eba5b6SRobert Mustacchi  **/
e1000_lower_i2c_clk(struct e1000_hw * hw,u32 * i2cctl)367475eba5b6SRobert Mustacchi static void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl)
367575eba5b6SRobert Mustacchi {
367675eba5b6SRobert Mustacchi 
367775eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_lower_i2c_clk");
367875eba5b6SRobert Mustacchi 
367975eba5b6SRobert Mustacchi 	*i2cctl &= ~E1000_I2C_CLK_OUT;
368075eba5b6SRobert Mustacchi 	*i2cctl &= ~E1000_I2C_CLK_OE_N;
368175eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
368275eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
368375eba5b6SRobert Mustacchi 
368475eba5b6SRobert Mustacchi 	/* SCL fall time (300ns) */
368575eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_FALL);
368675eba5b6SRobert Mustacchi }
368775eba5b6SRobert Mustacchi 
368875eba5b6SRobert Mustacchi /**
368975eba5b6SRobert Mustacchi  *  e1000_set_i2c_data - Sets the I2C data bit
369075eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
369175eba5b6SRobert Mustacchi  *  @i2cctl: Current value of I2CCTL register
369275eba5b6SRobert Mustacchi  *  @data: I2C data value (0 or 1) to set
369375eba5b6SRobert Mustacchi  *
369475eba5b6SRobert Mustacchi  *  Sets the I2C data bit
369575eba5b6SRobert Mustacchi  **/
e1000_set_i2c_data(struct e1000_hw * hw,u32 * i2cctl,bool data)369675eba5b6SRobert Mustacchi static s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data)
369775eba5b6SRobert Mustacchi {
369875eba5b6SRobert Mustacchi 	s32 status = E1000_SUCCESS;
369975eba5b6SRobert Mustacchi 
370075eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_set_i2c_data");
370175eba5b6SRobert Mustacchi 
370275eba5b6SRobert Mustacchi 	if (data)
370375eba5b6SRobert Mustacchi 		*i2cctl |= E1000_I2C_DATA_OUT;
370475eba5b6SRobert Mustacchi 	else
370575eba5b6SRobert Mustacchi 		*i2cctl &= ~E1000_I2C_DATA_OUT;
370675eba5b6SRobert Mustacchi 
370775eba5b6SRobert Mustacchi 	*i2cctl &= ~E1000_I2C_DATA_OE_N;
370875eba5b6SRobert Mustacchi 	*i2cctl |= E1000_I2C_CLK_OE_N;
370975eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
371075eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
371175eba5b6SRobert Mustacchi 
371275eba5b6SRobert Mustacchi 	/* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
371375eba5b6SRobert Mustacchi 	usec_delay(E1000_I2C_T_RISE + E1000_I2C_T_FALL + E1000_I2C_T_SU_DATA);
371475eba5b6SRobert Mustacchi 
371575eba5b6SRobert Mustacchi 	*i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
371675eba5b6SRobert Mustacchi 	if (data != e1000_get_i2c_data(i2cctl)) {
371775eba5b6SRobert Mustacchi 		status = E1000_ERR_I2C;
371875eba5b6SRobert Mustacchi 		DEBUGOUT1("Error - I2C data was not set to %X.\n", data);
371975eba5b6SRobert Mustacchi 	}
372075eba5b6SRobert Mustacchi 
372175eba5b6SRobert Mustacchi 	return status;
372275eba5b6SRobert Mustacchi }
372375eba5b6SRobert Mustacchi 
372475eba5b6SRobert Mustacchi /**
372575eba5b6SRobert Mustacchi  *  e1000_get_i2c_data - Reads the I2C SDA data bit
372675eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
372775eba5b6SRobert Mustacchi  *  @i2cctl: Current value of I2CCTL register
372875eba5b6SRobert Mustacchi  *
372975eba5b6SRobert Mustacchi  *  Returns the I2C data bit value
373075eba5b6SRobert Mustacchi  **/
e1000_get_i2c_data(u32 * i2cctl)373175eba5b6SRobert Mustacchi static bool e1000_get_i2c_data(u32 *i2cctl)
373275eba5b6SRobert Mustacchi {
373375eba5b6SRobert Mustacchi 	bool data;
373475eba5b6SRobert Mustacchi 
373575eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_get_i2c_data");
373675eba5b6SRobert Mustacchi 
373775eba5b6SRobert Mustacchi 	if (*i2cctl & E1000_I2C_DATA_IN)
373875eba5b6SRobert Mustacchi 		data = 1;
373975eba5b6SRobert Mustacchi 	else
374075eba5b6SRobert Mustacchi 		data = 0;
374175eba5b6SRobert Mustacchi 
374275eba5b6SRobert Mustacchi 	return data;
374375eba5b6SRobert Mustacchi }
374475eba5b6SRobert Mustacchi 
374575eba5b6SRobert Mustacchi /**
374675eba5b6SRobert Mustacchi  *  e1000_i2c_bus_clear - Clears the I2C bus
374775eba5b6SRobert Mustacchi  *  @hw: pointer to hardware structure
374875eba5b6SRobert Mustacchi  *
374975eba5b6SRobert Mustacchi  *  Clears the I2C bus by sending nine clock pulses.
375075eba5b6SRobert Mustacchi  *  Used when data line is stuck low.
375175eba5b6SRobert Mustacchi  **/
e1000_i2c_bus_clear(struct e1000_hw * hw)375275eba5b6SRobert Mustacchi void e1000_i2c_bus_clear(struct e1000_hw *hw)
375375eba5b6SRobert Mustacchi {
375475eba5b6SRobert Mustacchi 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
375575eba5b6SRobert Mustacchi 	u32 i;
375675eba5b6SRobert Mustacchi 
375775eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_i2c_bus_clear");
375875eba5b6SRobert Mustacchi 
375975eba5b6SRobert Mustacchi 	e1000_i2c_start(hw);
376075eba5b6SRobert Mustacchi 
376175eba5b6SRobert Mustacchi 	e1000_set_i2c_data(hw, &i2cctl, 1);
376275eba5b6SRobert Mustacchi 
376375eba5b6SRobert Mustacchi 	for (i = 0; i < 9; i++) {
376475eba5b6SRobert Mustacchi 		e1000_raise_i2c_clk(hw, &i2cctl);
376575eba5b6SRobert Mustacchi 
376675eba5b6SRobert Mustacchi 		/* Min high period of clock is 4us */
376775eba5b6SRobert Mustacchi 		usec_delay(E1000_I2C_T_HIGH);
376875eba5b6SRobert Mustacchi 
376975eba5b6SRobert Mustacchi 		e1000_lower_i2c_clk(hw, &i2cctl);
377075eba5b6SRobert Mustacchi 
377175eba5b6SRobert Mustacchi 		/* Min low period of clock is 4.7us*/
377275eba5b6SRobert Mustacchi 		usec_delay(E1000_I2C_T_LOW);
377375eba5b6SRobert Mustacchi 	}
377475eba5b6SRobert Mustacchi 
377575eba5b6SRobert Mustacchi 	e1000_i2c_start(hw);
377675eba5b6SRobert Mustacchi 
377775eba5b6SRobert Mustacchi 	/* Put the i2c bus back to default state */
377875eba5b6SRobert Mustacchi 	e1000_i2c_stop(hw);
377975eba5b6SRobert Mustacchi }
378075eba5b6SRobert Mustacchi 
3781