xref: /dragonfly/sys/dev/netif/ig_hal/e1000_82575.c (revision 65aebe9f)
162583d18SSepherosa Ziehau /******************************************************************************
262583d18SSepherosa Ziehau 
3*65aebe9fSSepherosa Ziehau   Copyright (c) 2001-2016, Intel Corporation
462583d18SSepherosa Ziehau   All rights reserved.
562583d18SSepherosa Ziehau 
662583d18SSepherosa Ziehau   Redistribution and use in source and binary forms, with or without
762583d18SSepherosa Ziehau   modification, are permitted provided that the following conditions are met:
862583d18SSepherosa Ziehau 
962583d18SSepherosa Ziehau    1. Redistributions of source code must retain the above copyright notice,
1062583d18SSepherosa Ziehau       this list of conditions and the following disclaimer.
1162583d18SSepherosa Ziehau 
1262583d18SSepherosa Ziehau    2. Redistributions in binary form must reproduce the above copyright
1362583d18SSepherosa Ziehau       notice, this list of conditions and the following disclaimer in the
1462583d18SSepherosa Ziehau       documentation and/or other materials provided with the distribution.
1562583d18SSepherosa Ziehau 
1662583d18SSepherosa Ziehau    3. Neither the name of the Intel Corporation nor the names of its
1762583d18SSepherosa Ziehau       contributors may be used to endorse or promote products derived from
1862583d18SSepherosa Ziehau       this software without specific prior written permission.
1962583d18SSepherosa Ziehau 
2062583d18SSepherosa Ziehau   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2162583d18SSepherosa Ziehau   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2262583d18SSepherosa Ziehau   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2362583d18SSepherosa Ziehau   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2462583d18SSepherosa Ziehau   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2562583d18SSepherosa Ziehau   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2662583d18SSepherosa Ziehau   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2762583d18SSepherosa Ziehau   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2862583d18SSepherosa Ziehau   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2962583d18SSepherosa Ziehau   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3062583d18SSepherosa Ziehau   POSSIBILITY OF SUCH DAMAGE.
3162583d18SSepherosa Ziehau 
3262583d18SSepherosa Ziehau ******************************************************************************/
3362583d18SSepherosa Ziehau /*$FreeBSD$*/
3462583d18SSepherosa Ziehau 
3562583d18SSepherosa Ziehau /*
3662583d18SSepherosa Ziehau  * 82575EB Gigabit Network Connection
3762583d18SSepherosa Ziehau  * 82575EB Gigabit Backplane Connection
3862583d18SSepherosa Ziehau  * 82575GB Gigabit Network Connection
3962583d18SSepherosa Ziehau  * 82576 Gigabit Network Connection
4062583d18SSepherosa Ziehau  * 82576 Quad Port Gigabit Mezzanine Adapter
414be59a01SSepherosa Ziehau  * 82580 Gigabit Network Connection
424be59a01SSepherosa Ziehau  * I350 Gigabit Network Connection
4362583d18SSepherosa Ziehau  */
4462583d18SSepherosa Ziehau 
4562583d18SSepherosa Ziehau #include "e1000_api.h"
464be59a01SSepherosa Ziehau #include "e1000_i210.h"
4762583d18SSepherosa Ziehau 
4862583d18SSepherosa Ziehau static s32  e1000_init_phy_params_82575(struct e1000_hw *hw);
4962583d18SSepherosa Ziehau static s32  e1000_init_mac_params_82575(struct e1000_hw *hw);
5062583d18SSepherosa Ziehau static s32  e1000_acquire_phy_82575(struct e1000_hw *hw);
5162583d18SSepherosa Ziehau static void e1000_release_phy_82575(struct e1000_hw *hw);
5262583d18SSepherosa Ziehau static s32  e1000_acquire_nvm_82575(struct e1000_hw *hw);
5362583d18SSepherosa Ziehau static void e1000_release_nvm_82575(struct e1000_hw *hw);
5462583d18SSepherosa Ziehau static s32  e1000_check_for_link_82575(struct e1000_hw *hw);
55379ebbe7SSepherosa Ziehau static s32  e1000_check_for_link_media_swap(struct e1000_hw *hw);
5662583d18SSepherosa Ziehau static s32  e1000_get_cfg_done_82575(struct e1000_hw *hw);
5762583d18SSepherosa Ziehau static s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
5862583d18SSepherosa Ziehau 					 u16 *duplex);
5962583d18SSepherosa Ziehau static s32  e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
6062583d18SSepherosa Ziehau static s32  e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
6162583d18SSepherosa Ziehau 					   u16 *data);
6262583d18SSepherosa Ziehau static s32  e1000_reset_hw_82575(struct e1000_hw *hw);
6362583d18SSepherosa Ziehau static s32  e1000_reset_hw_82580(struct e1000_hw *hw);
6462583d18SSepherosa Ziehau static s32  e1000_read_phy_reg_82580(struct e1000_hw *hw,
6562583d18SSepherosa Ziehau 				     u32 offset, u16 *data);
6662583d18SSepherosa Ziehau static s32  e1000_write_phy_reg_82580(struct e1000_hw *hw,
6762583d18SSepherosa Ziehau 				      u32 offset, u16 data);
6862583d18SSepherosa Ziehau static s32  e1000_set_d0_lplu_state_82580(struct e1000_hw *hw,
6962583d18SSepherosa Ziehau 					  bool active);
7062583d18SSepherosa Ziehau static s32  e1000_set_d3_lplu_state_82580(struct e1000_hw *hw,
7162583d18SSepherosa Ziehau 					  bool active);
7262583d18SSepherosa Ziehau static s32  e1000_set_d0_lplu_state_82575(struct e1000_hw *hw,
7362583d18SSepherosa Ziehau 					  bool active);
7462583d18SSepherosa Ziehau static s32  e1000_setup_copper_link_82575(struct e1000_hw *hw);
7562583d18SSepherosa Ziehau static s32  e1000_setup_serdes_link_82575(struct e1000_hw *hw);
764be59a01SSepherosa Ziehau static s32  e1000_get_media_type_82575(struct e1000_hw *hw);
774be59a01SSepherosa Ziehau static s32  e1000_set_sfp_media_type_82575(struct e1000_hw *hw);
7862583d18SSepherosa Ziehau static s32  e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data);
7962583d18SSepherosa Ziehau static s32  e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
8062583d18SSepherosa Ziehau 					    u32 offset, u16 data);
8162583d18SSepherosa Ziehau static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
8262583d18SSepherosa Ziehau static s32  e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
8362583d18SSepherosa Ziehau static s32  e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
8462583d18SSepherosa Ziehau 						 u16 *speed, u16 *duplex);
8562583d18SSepherosa Ziehau static s32  e1000_get_phy_id_82575(struct e1000_hw *hw);
8662583d18SSepherosa Ziehau static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
8762583d18SSepherosa Ziehau static bool e1000_sgmii_active_82575(struct e1000_hw *hw);
8862583d18SSepherosa Ziehau static s32  e1000_reset_init_script_82575(struct e1000_hw *hw);
8962583d18SSepherosa Ziehau static s32  e1000_read_mac_addr_82575(struct e1000_hw *hw);
9062583d18SSepherosa Ziehau static void e1000_config_collision_dist_82575(struct e1000_hw *hw);
9162583d18SSepherosa Ziehau static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
9262583d18SSepherosa Ziehau static void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw);
9362583d18SSepherosa Ziehau static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw);
9462583d18SSepherosa Ziehau static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw);
9562583d18SSepherosa Ziehau static s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw);
9662583d18SSepherosa Ziehau static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw);
9762583d18SSepherosa Ziehau static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw);
9862583d18SSepherosa Ziehau static s32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw,
9962583d18SSepherosa Ziehau 						 u16 offset);
10062583d18SSepherosa Ziehau static s32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw,
10162583d18SSepherosa Ziehau 						   u16 offset);
10262583d18SSepherosa Ziehau static s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw);
10362583d18SSepherosa Ziehau static s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw);
1044be59a01SSepherosa Ziehau static void e1000_clear_vfta_i350(struct e1000_hw *hw);
10562583d18SSepherosa Ziehau 
1064be59a01SSepherosa Ziehau static void e1000_i2c_start(struct e1000_hw *hw);
1074be59a01SSepherosa Ziehau static void e1000_i2c_stop(struct e1000_hw *hw);
1084be59a01SSepherosa Ziehau static s32 e1000_clock_in_i2c_byte(struct e1000_hw *hw, u8 *data);
1094be59a01SSepherosa Ziehau static s32 e1000_clock_out_i2c_byte(struct e1000_hw *hw, u8 data);
1104be59a01SSepherosa Ziehau static s32 e1000_get_i2c_ack(struct e1000_hw *hw);
1114be59a01SSepherosa Ziehau static s32 e1000_clock_in_i2c_bit(struct e1000_hw *hw, bool *data);
1124be59a01SSepherosa Ziehau static s32 e1000_clock_out_i2c_bit(struct e1000_hw *hw, bool data);
1134be59a01SSepherosa Ziehau static void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl);
1144be59a01SSepherosa Ziehau static void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl);
1154be59a01SSepherosa Ziehau static s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data);
1164be59a01SSepherosa Ziehau static bool e1000_get_i2c_data(u32 *i2cctl);
1174be59a01SSepherosa Ziehau 
1184be59a01SSepherosa Ziehau static const u16 e1000_82580_rxpbs_table[] = {
1194be59a01SSepherosa Ziehau 	36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
12062583d18SSepherosa Ziehau #define E1000_82580_RXPBS_TABLE_SIZE \
121ba0123e0SSepherosa Ziehau 	(sizeof(e1000_82580_rxpbs_table) / \
122ba0123e0SSepherosa Ziehau 	 sizeof(e1000_82580_rxpbs_table[0]))
12362583d18SSepherosa Ziehau 
12462583d18SSepherosa Ziehau 
12562583d18SSepherosa Ziehau /**
12662583d18SSepherosa Ziehau  *  e1000_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO
12762583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
12862583d18SSepherosa Ziehau  *
12962583d18SSepherosa Ziehau  *  Called to determine if the I2C pins are being used for I2C or as an
13062583d18SSepherosa Ziehau  *  external MDIO interface since the two options are mutually exclusive.
13162583d18SSepherosa Ziehau  **/
e1000_sgmii_uses_mdio_82575(struct e1000_hw * hw)13262583d18SSepherosa Ziehau static bool e1000_sgmii_uses_mdio_82575(struct e1000_hw *hw)
13362583d18SSepherosa Ziehau {
13462583d18SSepherosa Ziehau 	u32 reg = 0;
13562583d18SSepherosa Ziehau 	bool ext_mdio = FALSE;
13662583d18SSepherosa Ziehau 
13762583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_sgmii_uses_mdio_82575");
13862583d18SSepherosa Ziehau 
13962583d18SSepherosa Ziehau 	switch (hw->mac.type) {
14062583d18SSepherosa Ziehau 	case e1000_82575:
14162583d18SSepherosa Ziehau 	case e1000_82576:
14262583d18SSepherosa Ziehau 		reg = E1000_READ_REG(hw, E1000_MDIC);
14362583d18SSepherosa Ziehau 		ext_mdio = !!(reg & E1000_MDIC_DEST);
14462583d18SSepherosa Ziehau 		break;
14562583d18SSepherosa Ziehau 	case e1000_82580:
14662583d18SSepherosa Ziehau 	case e1000_i350:
147379ebbe7SSepherosa Ziehau 	case e1000_i354:
148379ebbe7SSepherosa Ziehau 	case e1000_i210:
149379ebbe7SSepherosa Ziehau 	case e1000_i211:
15062583d18SSepherosa Ziehau 		reg = E1000_READ_REG(hw, E1000_MDICNFG);
15162583d18SSepherosa Ziehau 		ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO);
15262583d18SSepherosa Ziehau 		break;
15362583d18SSepherosa Ziehau 	default:
15462583d18SSepherosa Ziehau 		break;
15562583d18SSepherosa Ziehau 	}
15662583d18SSepherosa Ziehau 	return ext_mdio;
15762583d18SSepherosa Ziehau }
15862583d18SSepherosa Ziehau 
15962583d18SSepherosa Ziehau /**
16062583d18SSepherosa Ziehau  *  e1000_init_phy_params_82575 - Init PHY func ptrs.
16162583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
16262583d18SSepherosa Ziehau  **/
e1000_init_phy_params_82575(struct e1000_hw * hw)16362583d18SSepherosa Ziehau static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
16462583d18SSepherosa Ziehau {
16562583d18SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
16662583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
16762583d18SSepherosa Ziehau 	u32 ctrl_ext;
16862583d18SSepherosa Ziehau 
16962583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_init_phy_params_82575");
17062583d18SSepherosa Ziehau 
1714be59a01SSepherosa Ziehau 	phy->ops.read_i2c_byte = e1000_read_i2c_byte_generic;
1724be59a01SSepherosa Ziehau 	phy->ops.write_i2c_byte = e1000_write_i2c_byte_generic;
1734be59a01SSepherosa Ziehau 
17462583d18SSepherosa Ziehau 	if (hw->phy.media_type != e1000_media_type_copper) {
17562583d18SSepherosa Ziehau 		phy->type = e1000_phy_none;
17662583d18SSepherosa Ziehau 		goto out;
17762583d18SSepherosa Ziehau 	}
17862583d18SSepherosa Ziehau 
17962583d18SSepherosa Ziehau 	phy->ops.power_up   = e1000_power_up_phy_copper;
18062583d18SSepherosa Ziehau 	phy->ops.power_down = e1000_power_down_phy_copper_82575;
18162583d18SSepherosa Ziehau 
18262583d18SSepherosa Ziehau 	phy->autoneg_mask	= AUTONEG_ADVERTISE_SPEED_DEFAULT;
18362583d18SSepherosa Ziehau 	phy->reset_delay_us	= 100;
18462583d18SSepherosa Ziehau 
18562583d18SSepherosa Ziehau 	phy->ops.acquire	= e1000_acquire_phy_82575;
18662583d18SSepherosa Ziehau 	phy->ops.check_reset_block = e1000_check_reset_block_generic;
18762583d18SSepherosa Ziehau 	phy->ops.commit		= e1000_phy_sw_reset_generic;
18862583d18SSepherosa Ziehau 	phy->ops.get_cfg_done	= e1000_get_cfg_done_82575;
18962583d18SSepherosa Ziehau 	phy->ops.release	= e1000_release_phy_82575;
19062583d18SSepherosa Ziehau 
19162583d18SSepherosa Ziehau 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
19262583d18SSepherosa Ziehau 
19362583d18SSepherosa Ziehau 	if (e1000_sgmii_active_82575(hw)) {
19462583d18SSepherosa Ziehau 		phy->ops.reset = e1000_phy_hw_reset_sgmii_82575;
19562583d18SSepherosa Ziehau 		ctrl_ext |= E1000_CTRL_I2C_ENA;
19662583d18SSepherosa Ziehau 	} else {
19762583d18SSepherosa Ziehau 		phy->ops.reset = e1000_phy_hw_reset_generic;
19862583d18SSepherosa Ziehau 		ctrl_ext &= ~E1000_CTRL_I2C_ENA;
19962583d18SSepherosa Ziehau 	}
20062583d18SSepherosa Ziehau 
20162583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
20262583d18SSepherosa Ziehau 	e1000_reset_mdicnfg_82580(hw);
20362583d18SSepherosa Ziehau 
20462583d18SSepherosa Ziehau 	if (e1000_sgmii_active_82575(hw) && !e1000_sgmii_uses_mdio_82575(hw)) {
20562583d18SSepherosa Ziehau 		phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575;
20662583d18SSepherosa Ziehau 		phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575;
2074be59a01SSepherosa Ziehau 	} else {
2084be59a01SSepherosa Ziehau 		switch (hw->mac.type) {
2094be59a01SSepherosa Ziehau 		case e1000_82580:
2104be59a01SSepherosa Ziehau 		case e1000_i350:
211379ebbe7SSepherosa Ziehau 		case e1000_i354:
21262583d18SSepherosa Ziehau 			phy->ops.read_reg = e1000_read_phy_reg_82580;
21362583d18SSepherosa Ziehau 			phy->ops.write_reg = e1000_write_phy_reg_82580;
2144be59a01SSepherosa Ziehau 			break;
2154be59a01SSepherosa Ziehau 		case e1000_i210:
2164be59a01SSepherosa Ziehau 		case e1000_i211:
2174be59a01SSepherosa Ziehau 			phy->ops.read_reg = e1000_read_phy_reg_gs40g;
2184be59a01SSepherosa Ziehau 			phy->ops.write_reg = e1000_write_phy_reg_gs40g;
2194be59a01SSepherosa Ziehau 			break;
2204be59a01SSepherosa Ziehau 		default:
22162583d18SSepherosa Ziehau 			phy->ops.read_reg = e1000_read_phy_reg_igp;
22262583d18SSepherosa Ziehau 			phy->ops.write_reg = e1000_write_phy_reg_igp;
22362583d18SSepherosa Ziehau 		}
2244be59a01SSepherosa Ziehau 	}
22562583d18SSepherosa Ziehau 
22662583d18SSepherosa Ziehau 	/* Set phy->phy_addr and phy->id. */
22762583d18SSepherosa Ziehau 	ret_val = e1000_get_phy_id_82575(hw);
22862583d18SSepherosa Ziehau 
22962583d18SSepherosa Ziehau 	/* Verify phy id and set remaining function pointers */
23062583d18SSepherosa Ziehau 	switch (phy->id) {
231ba0123e0SSepherosa Ziehau 	case M88E1543_E_PHY_ID:
232ba0123e0SSepherosa Ziehau 	case M88E1512_E_PHY_ID:
23362583d18SSepherosa Ziehau 	case I347AT4_E_PHY_ID:
23462583d18SSepherosa Ziehau 	case M88E1112_E_PHY_ID:
23562583d18SSepherosa Ziehau 	case M88E1340M_E_PHY_ID:
23662583d18SSepherosa Ziehau 	case M88E1111_I_PHY_ID:
23762583d18SSepherosa Ziehau 		phy->type		= e1000_phy_m88;
23862583d18SSepherosa Ziehau 		phy->ops.check_polarity	= e1000_check_polarity_m88;
23962583d18SSepherosa Ziehau 		phy->ops.get_info	= e1000_get_phy_info_m88;
24062583d18SSepherosa Ziehau 		if (phy->id == I347AT4_E_PHY_ID ||
24162583d18SSepherosa Ziehau 		    phy->id == M88E1112_E_PHY_ID ||
24262583d18SSepherosa Ziehau 		    phy->id == M88E1340M_E_PHY_ID)
2434be59a01SSepherosa Ziehau 			phy->ops.get_cable_length =
2444be59a01SSepherosa Ziehau 					 e1000_get_cable_length_m88_gen2;
245ba0123e0SSepherosa Ziehau 		else if (phy->id == M88E1543_E_PHY_ID ||
246ba0123e0SSepherosa Ziehau 			 phy->id == M88E1512_E_PHY_ID)
247379ebbe7SSepherosa Ziehau 			phy->ops.get_cable_length =
248379ebbe7SSepherosa Ziehau 					 e1000_get_cable_length_m88_gen2;
24962583d18SSepherosa Ziehau 		else
25062583d18SSepherosa Ziehau 			phy->ops.get_cable_length = e1000_get_cable_length_m88;
25162583d18SSepherosa Ziehau 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
252379ebbe7SSepherosa Ziehau 		/* Check if this PHY is confgured for media swap. */
253379ebbe7SSepherosa Ziehau 		if (phy->id == M88E1112_E_PHY_ID) {
254379ebbe7SSepherosa Ziehau 			u16 data;
255379ebbe7SSepherosa Ziehau 
256379ebbe7SSepherosa Ziehau 			ret_val = phy->ops.write_reg(hw,
257379ebbe7SSepherosa Ziehau 						     E1000_M88E1112_PAGE_ADDR,
258379ebbe7SSepherosa Ziehau 						     2);
259379ebbe7SSepherosa Ziehau 			if (ret_val)
260379ebbe7SSepherosa Ziehau 				goto out;
261379ebbe7SSepherosa Ziehau 
262379ebbe7SSepherosa Ziehau 			ret_val = phy->ops.read_reg(hw,
263379ebbe7SSepherosa Ziehau 						    E1000_M88E1112_MAC_CTRL_1,
264379ebbe7SSepherosa Ziehau 						    &data);
265379ebbe7SSepherosa Ziehau 			if (ret_val)
266379ebbe7SSepherosa Ziehau 				goto out;
267379ebbe7SSepherosa Ziehau 
268ba0123e0SSepherosa Ziehau 			data = (data & E1000_M88E1112_MAC_CTRL_1_MODE_MASK) >>
269ba0123e0SSepherosa Ziehau 			       E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT;
270ba0123e0SSepherosa Ziehau 			if (data == E1000_M88E1112_AUTO_COPPER_SGMII ||
271ba0123e0SSepherosa Ziehau 			    data == E1000_M88E1112_AUTO_COPPER_BASEX)
272379ebbe7SSepherosa Ziehau 				hw->mac.ops.check_for_link =
273379ebbe7SSepherosa Ziehau 						e1000_check_for_link_media_swap;
274379ebbe7SSepherosa Ziehau 		}
275ba0123e0SSepherosa Ziehau 		if (phy->id == M88E1512_E_PHY_ID) {
276ba0123e0SSepherosa Ziehau 			ret_val = e1000_initialize_M88E1512_phy(hw);
277ba0123e0SSepherosa Ziehau 			if (ret_val)
278ba0123e0SSepherosa Ziehau 				goto out;
279ba0123e0SSepherosa Ziehau 		}
280a40fda39SSepherosa Ziehau 		if (phy->id == M88E1543_E_PHY_ID) {
281a40fda39SSepherosa Ziehau 			ret_val = e1000_initialize_M88E1543_phy(hw);
282a40fda39SSepherosa Ziehau 			if (ret_val)
283a40fda39SSepherosa Ziehau 				goto out;
284a40fda39SSepherosa Ziehau 		}
28562583d18SSepherosa Ziehau 		break;
28662583d18SSepherosa Ziehau 	case IGP03E1000_E_PHY_ID:
28762583d18SSepherosa Ziehau 	case IGP04E1000_E_PHY_ID:
28862583d18SSepherosa Ziehau 		phy->type = e1000_phy_igp_3;
28962583d18SSepherosa Ziehau 		phy->ops.check_polarity = e1000_check_polarity_igp;
29062583d18SSepherosa Ziehau 		phy->ops.get_info = e1000_get_phy_info_igp;
29162583d18SSepherosa Ziehau 		phy->ops.get_cable_length = e1000_get_cable_length_igp_2;
29262583d18SSepherosa Ziehau 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp;
29362583d18SSepherosa Ziehau 		phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82575;
29462583d18SSepherosa Ziehau 		phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic;
29562583d18SSepherosa Ziehau 		break;
29662583d18SSepherosa Ziehau 	case I82580_I_PHY_ID:
29762583d18SSepherosa Ziehau 	case I350_I_PHY_ID:
29862583d18SSepherosa Ziehau 		phy->type = e1000_phy_82580;
29962583d18SSepherosa Ziehau 		phy->ops.check_polarity = e1000_check_polarity_82577;
3004be59a01SSepherosa Ziehau 		phy->ops.force_speed_duplex =
3014be59a01SSepherosa Ziehau 					 e1000_phy_force_speed_duplex_82577;
30262583d18SSepherosa Ziehau 		phy->ops.get_cable_length = e1000_get_cable_length_82577;
30362583d18SSepherosa Ziehau 		phy->ops.get_info = e1000_get_phy_info_82577;
30462583d18SSepherosa Ziehau 		phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
30562583d18SSepherosa Ziehau 		phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
30662583d18SSepherosa Ziehau 		break;
3074be59a01SSepherosa Ziehau 	case I210_I_PHY_ID:
3084be59a01SSepherosa Ziehau 		phy->type		= e1000_phy_i210;
3094be59a01SSepherosa Ziehau 		phy->ops.check_polarity	= e1000_check_polarity_m88;
3104be59a01SSepherosa Ziehau 		phy->ops.get_info	= e1000_get_phy_info_m88;
3114be59a01SSepherosa Ziehau 		phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2;
3124be59a01SSepherosa Ziehau 		phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
3134be59a01SSepherosa Ziehau 		phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
3144be59a01SSepherosa Ziehau 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
3154be59a01SSepherosa Ziehau 		break;
31662583d18SSepherosa Ziehau 	default:
31762583d18SSepherosa Ziehau 		ret_val = -E1000_ERR_PHY;
31862583d18SSepherosa Ziehau 		goto out;
31962583d18SSepherosa Ziehau 	}
32062583d18SSepherosa Ziehau 
32162583d18SSepherosa Ziehau out:
32262583d18SSepherosa Ziehau 	return ret_val;
32362583d18SSepherosa Ziehau }
32462583d18SSepherosa Ziehau 
32562583d18SSepherosa Ziehau /**
32662583d18SSepherosa Ziehau  *  e1000_init_nvm_params_82575 - Init NVM func ptrs.
32762583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
32862583d18SSepherosa Ziehau  **/
e1000_init_nvm_params_82575(struct e1000_hw * hw)32962583d18SSepherosa Ziehau s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
33062583d18SSepherosa Ziehau {
33162583d18SSepherosa Ziehau 	struct e1000_nvm_info *nvm = &hw->nvm;
33262583d18SSepherosa Ziehau 	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
33362583d18SSepherosa Ziehau 	u16 size;
33462583d18SSepherosa Ziehau 
33562583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_init_nvm_params_82575");
33662583d18SSepherosa Ziehau 
33762583d18SSepherosa Ziehau 	size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
33862583d18SSepherosa Ziehau 		     E1000_EECD_SIZE_EX_SHIFT);
33962583d18SSepherosa Ziehau 	/*
34062583d18SSepherosa Ziehau 	 * Added to a constant, "size" becomes the left-shift value
34162583d18SSepherosa Ziehau 	 * for setting word_size.
34262583d18SSepherosa Ziehau 	 */
34362583d18SSepherosa Ziehau 	size += NVM_WORD_SIZE_BASE_SHIFT;
34462583d18SSepherosa Ziehau 
3454be59a01SSepherosa Ziehau 	/* Just in case size is out of range, cap it to the largest
3464be59a01SSepherosa Ziehau 	 * EEPROM size supported
3474be59a01SSepherosa Ziehau 	 */
3484be59a01SSepherosa Ziehau 	if (size > 15)
3494be59a01SSepherosa Ziehau 		size = 15;
3504be59a01SSepherosa Ziehau 
35162583d18SSepherosa Ziehau 	nvm->word_size = 1 << size;
3524be59a01SSepherosa Ziehau 	if (hw->mac.type < e1000_i210) {
35362583d18SSepherosa Ziehau 		nvm->opcode_bits = 8;
35462583d18SSepherosa Ziehau 		nvm->delay_usec = 1;
3554be59a01SSepherosa Ziehau 
35662583d18SSepherosa Ziehau 		switch (nvm->override) {
35762583d18SSepherosa Ziehau 		case e1000_nvm_override_spi_large:
35862583d18SSepherosa Ziehau 			nvm->page_size = 32;
35962583d18SSepherosa Ziehau 			nvm->address_bits = 16;
36062583d18SSepherosa Ziehau 			break;
36162583d18SSepherosa Ziehau 		case e1000_nvm_override_spi_small:
36262583d18SSepherosa Ziehau 			nvm->page_size = 8;
36362583d18SSepherosa Ziehau 			nvm->address_bits = 8;
36462583d18SSepherosa Ziehau 			break;
36562583d18SSepherosa Ziehau 		default:
36662583d18SSepherosa Ziehau 			nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
3674be59a01SSepherosa Ziehau 			nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ?
3684be59a01SSepherosa Ziehau 					    16 : 8;
36962583d18SSepherosa Ziehau 			break;
37062583d18SSepherosa Ziehau 		}
37162583d18SSepherosa Ziehau 		if (nvm->word_size == (1 << 15))
37262583d18SSepherosa Ziehau 			nvm->page_size = 128;
37362583d18SSepherosa Ziehau 
3744be59a01SSepherosa Ziehau 		nvm->type = e1000_nvm_eeprom_spi;
3754be59a01SSepherosa Ziehau 	} else {
3764be59a01SSepherosa Ziehau 		nvm->type = e1000_nvm_flash_hw;
3774be59a01SSepherosa Ziehau 	}
378379ebbe7SSepherosa Ziehau 
37962583d18SSepherosa Ziehau 	/* Function Pointers */
38062583d18SSepherosa Ziehau 	nvm->ops.acquire = e1000_acquire_nvm_82575;
38162583d18SSepherosa Ziehau 	nvm->ops.release = e1000_release_nvm_82575;
38262583d18SSepherosa Ziehau 	if (nvm->word_size < (1 << 15))
38362583d18SSepherosa Ziehau 		nvm->ops.read = e1000_read_nvm_eerd;
38462583d18SSepherosa Ziehau 	else
38562583d18SSepherosa Ziehau 		nvm->ops.read = e1000_read_nvm_spi;
38662583d18SSepherosa Ziehau 
38762583d18SSepherosa Ziehau 	nvm->ops.write = e1000_write_nvm_spi;
38862583d18SSepherosa Ziehau 	nvm->ops.validate = e1000_validate_nvm_checksum_generic;
38962583d18SSepherosa Ziehau 	nvm->ops.update = e1000_update_nvm_checksum_generic;
39062583d18SSepherosa Ziehau 	nvm->ops.valid_led_default = e1000_valid_led_default_82575;
39162583d18SSepherosa Ziehau 
3924be59a01SSepherosa Ziehau 	/* override generic family function pointers for specific descendants */
39362583d18SSepherosa Ziehau 	switch (hw->mac.type) {
39462583d18SSepherosa Ziehau 	case e1000_82580:
39562583d18SSepherosa Ziehau 		nvm->ops.validate = e1000_validate_nvm_checksum_82580;
39662583d18SSepherosa Ziehau 		nvm->ops.update = e1000_update_nvm_checksum_82580;
39762583d18SSepherosa Ziehau 		break;
39862583d18SSepherosa Ziehau 	case e1000_i350:
399379ebbe7SSepherosa Ziehau 	case e1000_i354:
40062583d18SSepherosa Ziehau 		nvm->ops.validate = e1000_validate_nvm_checksum_i350;
40162583d18SSepherosa Ziehau 		nvm->ops.update = e1000_update_nvm_checksum_i350;
40262583d18SSepherosa Ziehau 		break;
40362583d18SSepherosa Ziehau 	default:
40462583d18SSepherosa Ziehau 		break;
40562583d18SSepherosa Ziehau 	}
40662583d18SSepherosa Ziehau 
40762583d18SSepherosa Ziehau 	return E1000_SUCCESS;
40862583d18SSepherosa Ziehau }
40962583d18SSepherosa Ziehau 
41062583d18SSepherosa Ziehau /**
41162583d18SSepherosa Ziehau  *  e1000_init_mac_params_82575 - Init MAC func ptrs.
41262583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
41362583d18SSepherosa Ziehau  **/
e1000_init_mac_params_82575(struct e1000_hw * hw)41462583d18SSepherosa Ziehau static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
41562583d18SSepherosa Ziehau {
41662583d18SSepherosa Ziehau 	struct e1000_mac_info *mac = &hw->mac;
41762583d18SSepherosa Ziehau 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
41862583d18SSepherosa Ziehau 
41962583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_init_mac_params_82575");
42062583d18SSepherosa Ziehau 
4214be59a01SSepherosa Ziehau 	/* Derives media type */
4224be59a01SSepherosa Ziehau 	e1000_get_media_type_82575(hw);
42362583d18SSepherosa Ziehau 	/* Set mta register count */
42462583d18SSepherosa Ziehau 	mac->mta_reg_count = 128;
42562583d18SSepherosa Ziehau 	/* Set uta register count */
42662583d18SSepherosa Ziehau 	mac->uta_reg_count = (hw->mac.type == e1000_82575) ? 0 : 128;
42762583d18SSepherosa Ziehau 	/* Set rar entry count */
42862583d18SSepherosa Ziehau 	mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
42962583d18SSepherosa Ziehau 	if (mac->type == e1000_82576)
43062583d18SSepherosa Ziehau 		mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
43162583d18SSepherosa Ziehau 	if (mac->type == e1000_82580)
43262583d18SSepherosa Ziehau 		mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
433379ebbe7SSepherosa Ziehau 	if (mac->type == e1000_i350 || mac->type == e1000_i354)
43462583d18SSepherosa Ziehau 		mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
435379ebbe7SSepherosa Ziehau 
436379ebbe7SSepherosa Ziehau 	/* Enable EEE default settings for EEE supported devices */
437379ebbe7SSepherosa Ziehau 	if (mac->type >= e1000_i350)
43862583d18SSepherosa Ziehau 		dev_spec->eee_disable = FALSE;
439379ebbe7SSepherosa Ziehau 
440379ebbe7SSepherosa Ziehau 	/* Allow a single clear of the SW semaphore on I210 and newer */
441379ebbe7SSepherosa Ziehau 	if (mac->type >= e1000_i210)
442379ebbe7SSepherosa Ziehau 		dev_spec->clear_semaphore_once = TRUE;
44362583d18SSepherosa Ziehau 
44462583d18SSepherosa Ziehau 	/* Set if part includes ASF firmware */
44562583d18SSepherosa Ziehau 	mac->asf_firmware_present = TRUE;
44662583d18SSepherosa Ziehau 	/* FWSM register */
44762583d18SSepherosa Ziehau 	mac->has_fwsm = TRUE;
44862583d18SSepherosa Ziehau 	/* ARC supported; valid only if manageability features are enabled. */
44962583d18SSepherosa Ziehau 	mac->arc_subsystem_valid =
4504be59a01SSepherosa Ziehau 		!!(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK);
45162583d18SSepherosa Ziehau 
45262583d18SSepherosa Ziehau 	/* Function pointers */
45362583d18SSepherosa Ziehau 
45462583d18SSepherosa Ziehau 	/* bus type/speed/width */
45562583d18SSepherosa Ziehau 	mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic;
45662583d18SSepherosa Ziehau 	/* reset */
45762583d18SSepherosa Ziehau 	if (mac->type >= e1000_82580)
45862583d18SSepherosa Ziehau 		mac->ops.reset_hw = e1000_reset_hw_82580;
45962583d18SSepherosa Ziehau 	else
46062583d18SSepherosa Ziehau 	mac->ops.reset_hw = e1000_reset_hw_82575;
46162583d18SSepherosa Ziehau 	/* hw initialization */
462ba0123e0SSepherosa Ziehau 	if ((mac->type == e1000_i210) || (mac->type == e1000_i211))
463ba0123e0SSepherosa Ziehau 		mac->ops.init_hw = e1000_init_hw_i210;
464ba0123e0SSepherosa Ziehau 	else
46562583d18SSepherosa Ziehau 	mac->ops.init_hw = e1000_init_hw_82575;
46662583d18SSepherosa Ziehau 	/* link setup */
46762583d18SSepherosa Ziehau 	mac->ops.setup_link = e1000_setup_link_generic;
46862583d18SSepherosa Ziehau 	/* physical interface link setup */
46962583d18SSepherosa Ziehau 	mac->ops.setup_physical_interface =
47062583d18SSepherosa Ziehau 		(hw->phy.media_type == e1000_media_type_copper)
4714be59a01SSepherosa Ziehau 		? e1000_setup_copper_link_82575 : e1000_setup_serdes_link_82575;
47262583d18SSepherosa Ziehau 	/* physical interface shutdown */
47362583d18SSepherosa Ziehau 	mac->ops.shutdown_serdes = e1000_shutdown_serdes_link_82575;
47462583d18SSepherosa Ziehau 	/* physical interface power up */
47562583d18SSepherosa Ziehau 	mac->ops.power_up_serdes = e1000_power_up_serdes_link_82575;
47662583d18SSepherosa Ziehau 	/* check for link */
47762583d18SSepherosa Ziehau 	mac->ops.check_for_link = e1000_check_for_link_82575;
47862583d18SSepherosa Ziehau 	/* read mac address */
47962583d18SSepherosa Ziehau 	mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
48062583d18SSepherosa Ziehau 	/* configure collision distance */
48162583d18SSepherosa Ziehau 	mac->ops.config_collision_dist = e1000_config_collision_dist_82575;
48262583d18SSepherosa Ziehau 	/* multicast address update */
48362583d18SSepherosa Ziehau 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
484379ebbe7SSepherosa Ziehau 	if (hw->mac.type == e1000_i350 || mac->type == e1000_i354) {
4854be59a01SSepherosa Ziehau 		/* writing VFTA */
4864be59a01SSepherosa Ziehau 		mac->ops.write_vfta = e1000_write_vfta_i350;
4874be59a01SSepherosa Ziehau 		/* clearing VFTA */
4884be59a01SSepherosa Ziehau 		mac->ops.clear_vfta = e1000_clear_vfta_i350;
4894be59a01SSepherosa Ziehau 	} else {
49062583d18SSepherosa Ziehau 		/* writing VFTA */
49162583d18SSepherosa Ziehau 		mac->ops.write_vfta = e1000_write_vfta_generic;
49262583d18SSepherosa Ziehau 		/* clearing VFTA */
49362583d18SSepherosa Ziehau 		mac->ops.clear_vfta = e1000_clear_vfta_generic;
4944be59a01SSepherosa Ziehau 	}
4954be59a01SSepherosa Ziehau 	if (hw->mac.type >= e1000_82580)
4964be59a01SSepherosa Ziehau 		mac->ops.validate_mdi_setting =
4974be59a01SSepherosa Ziehau 				e1000_validate_mdi_setting_crossover_generic;
49862583d18SSepherosa Ziehau 	/* ID LED init */
49962583d18SSepherosa Ziehau 	mac->ops.id_led_init = e1000_id_led_init_generic;
50062583d18SSepherosa Ziehau 	/* blink LED */
50162583d18SSepherosa Ziehau 	mac->ops.blink_led = e1000_blink_led_generic;
50262583d18SSepherosa Ziehau 	/* setup LED */
50362583d18SSepherosa Ziehau 	mac->ops.setup_led = e1000_setup_led_generic;
50462583d18SSepherosa Ziehau 	/* cleanup LED */
50562583d18SSepherosa Ziehau 	mac->ops.cleanup_led = e1000_cleanup_led_generic;
50662583d18SSepherosa Ziehau 	/* turn on/off LED */
50762583d18SSepherosa Ziehau 	mac->ops.led_on = e1000_led_on_generic;
50862583d18SSepherosa Ziehau 	mac->ops.led_off = e1000_led_off_generic;
50962583d18SSepherosa Ziehau 	/* clear hardware counters */
51062583d18SSepherosa Ziehau 	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
51162583d18SSepherosa Ziehau 	/* link info */
51262583d18SSepherosa Ziehau 	mac->ops.get_link_up_info = e1000_get_link_up_info_82575;
5134be59a01SSepherosa Ziehau 	/* acquire SW_FW sync */
5144be59a01SSepherosa Ziehau 	mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_82575;
5154be59a01SSepherosa Ziehau 	mac->ops.release_swfw_sync = e1000_release_swfw_sync_82575;
5164be59a01SSepherosa Ziehau 	if (mac->type >= e1000_i210) {
5174be59a01SSepherosa Ziehau 		mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_i210;
5184be59a01SSepherosa Ziehau 		mac->ops.release_swfw_sync = e1000_release_swfw_sync_i210;
5194be59a01SSepherosa Ziehau 	}
52062583d18SSepherosa Ziehau 
52162583d18SSepherosa Ziehau 	/* set lan id for port to determine which phy lock to use */
52262583d18SSepherosa Ziehau 	hw->mac.ops.set_lan_id(hw);
52362583d18SSepherosa Ziehau 
52462583d18SSepherosa Ziehau 	return E1000_SUCCESS;
52562583d18SSepherosa Ziehau }
52662583d18SSepherosa Ziehau 
52762583d18SSepherosa Ziehau /**
52862583d18SSepherosa Ziehau  *  e1000_init_function_pointers_82575 - Init func ptrs.
52962583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
53062583d18SSepherosa Ziehau  *
53162583d18SSepherosa Ziehau  *  Called to initialize all function pointers and parameters.
53262583d18SSepherosa Ziehau  **/
e1000_init_function_pointers_82575(struct e1000_hw * hw)53362583d18SSepherosa Ziehau void e1000_init_function_pointers_82575(struct e1000_hw *hw)
53462583d18SSepherosa Ziehau {
53562583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_init_function_pointers_82575");
53662583d18SSepherosa Ziehau 
53762583d18SSepherosa Ziehau 	hw->mac.ops.init_params = e1000_init_mac_params_82575;
53862583d18SSepherosa Ziehau 	hw->nvm.ops.init_params = e1000_init_nvm_params_82575;
53962583d18SSepherosa Ziehau 	hw->phy.ops.init_params = e1000_init_phy_params_82575;
54062583d18SSepherosa Ziehau 	hw->mbx.ops.init_params = e1000_init_mbx_params_pf;
54162583d18SSepherosa Ziehau }
54262583d18SSepherosa Ziehau 
54362583d18SSepherosa Ziehau /**
54462583d18SSepherosa Ziehau  *  e1000_acquire_phy_82575 - Acquire rights to access PHY
54562583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
54662583d18SSepherosa Ziehau  *
54762583d18SSepherosa Ziehau  *  Acquire access rights to the correct PHY.
54862583d18SSepherosa Ziehau  **/
e1000_acquire_phy_82575(struct e1000_hw * hw)54962583d18SSepherosa Ziehau static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
55062583d18SSepherosa Ziehau {
55162583d18SSepherosa Ziehau 	u16 mask = E1000_SWFW_PHY0_SM;
55262583d18SSepherosa Ziehau 
55362583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_acquire_phy_82575");
55462583d18SSepherosa Ziehau 
55562583d18SSepherosa Ziehau 	if (hw->bus.func == E1000_FUNC_1)
55662583d18SSepherosa Ziehau 		mask = E1000_SWFW_PHY1_SM;
55762583d18SSepherosa Ziehau 	else if (hw->bus.func == E1000_FUNC_2)
55862583d18SSepherosa Ziehau 		mask = E1000_SWFW_PHY2_SM;
55962583d18SSepherosa Ziehau 	else if (hw->bus.func == E1000_FUNC_3)
56062583d18SSepherosa Ziehau 		mask = E1000_SWFW_PHY3_SM;
56162583d18SSepherosa Ziehau 
5624be59a01SSepherosa Ziehau 	return hw->mac.ops.acquire_swfw_sync(hw, mask);
56362583d18SSepherosa Ziehau }
56462583d18SSepherosa Ziehau 
56562583d18SSepherosa Ziehau /**
56662583d18SSepherosa Ziehau  *  e1000_release_phy_82575 - Release rights to access PHY
56762583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
56862583d18SSepherosa Ziehau  *
56962583d18SSepherosa Ziehau  *  A wrapper to release access rights to the correct PHY.
57062583d18SSepherosa Ziehau  **/
e1000_release_phy_82575(struct e1000_hw * hw)57162583d18SSepherosa Ziehau static void e1000_release_phy_82575(struct e1000_hw *hw)
57262583d18SSepherosa Ziehau {
57362583d18SSepherosa Ziehau 	u16 mask = E1000_SWFW_PHY0_SM;
57462583d18SSepherosa Ziehau 
57562583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_release_phy_82575");
57662583d18SSepherosa Ziehau 
57762583d18SSepherosa Ziehau 	if (hw->bus.func == E1000_FUNC_1)
57862583d18SSepherosa Ziehau 		mask = E1000_SWFW_PHY1_SM;
57962583d18SSepherosa Ziehau 	else if (hw->bus.func == E1000_FUNC_2)
58062583d18SSepherosa Ziehau 		mask = E1000_SWFW_PHY2_SM;
58162583d18SSepherosa Ziehau 	else if (hw->bus.func == E1000_FUNC_3)
58262583d18SSepherosa Ziehau 		mask = E1000_SWFW_PHY3_SM;
58362583d18SSepherosa Ziehau 
5844be59a01SSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, mask);
58562583d18SSepherosa Ziehau }
58662583d18SSepherosa Ziehau 
58762583d18SSepherosa Ziehau /**
58862583d18SSepherosa Ziehau  *  e1000_read_phy_reg_sgmii_82575 - Read PHY register using sgmii
58962583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
59062583d18SSepherosa Ziehau  *  @offset: register offset to be read
59162583d18SSepherosa Ziehau  *  @data: pointer to the read data
59262583d18SSepherosa Ziehau  *
59362583d18SSepherosa Ziehau  *  Reads the PHY register at offset using the serial gigabit media independent
59462583d18SSepherosa Ziehau  *  interface and stores the retrieved information in data.
59562583d18SSepherosa Ziehau  **/
e1000_read_phy_reg_sgmii_82575(struct e1000_hw * hw,u32 offset,u16 * data)59662583d18SSepherosa Ziehau static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
59762583d18SSepherosa Ziehau 					  u16 *data)
59862583d18SSepherosa Ziehau {
59962583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_PARAM;
60062583d18SSepherosa Ziehau 
60162583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_read_phy_reg_sgmii_82575");
60262583d18SSepherosa Ziehau 
60362583d18SSepherosa Ziehau 	if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
60462583d18SSepherosa Ziehau 		DEBUGOUT1("PHY Address %u is out of range\n", offset);
60562583d18SSepherosa Ziehau 		goto out;
60662583d18SSepherosa Ziehau 	}
60762583d18SSepherosa Ziehau 
60862583d18SSepherosa Ziehau 	ret_val = hw->phy.ops.acquire(hw);
60962583d18SSepherosa Ziehau 	if (ret_val)
61062583d18SSepherosa Ziehau 		goto out;
61162583d18SSepherosa Ziehau 
61262583d18SSepherosa Ziehau 	ret_val = e1000_read_phy_reg_i2c(hw, offset, data);
61362583d18SSepherosa Ziehau 
61462583d18SSepherosa Ziehau 	hw->phy.ops.release(hw);
61562583d18SSepherosa Ziehau 
61662583d18SSepherosa Ziehau out:
61762583d18SSepherosa Ziehau 	return ret_val;
61862583d18SSepherosa Ziehau }
61962583d18SSepherosa Ziehau 
62062583d18SSepherosa Ziehau /**
62162583d18SSepherosa Ziehau  *  e1000_write_phy_reg_sgmii_82575 - Write PHY register using sgmii
62262583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
62362583d18SSepherosa Ziehau  *  @offset: register offset to write to
62462583d18SSepherosa Ziehau  *  @data: data to write at register offset
62562583d18SSepherosa Ziehau  *
62662583d18SSepherosa Ziehau  *  Writes the data to PHY register at the offset using the serial gigabit
62762583d18SSepherosa Ziehau  *  media independent interface.
62862583d18SSepherosa Ziehau  **/
e1000_write_phy_reg_sgmii_82575(struct e1000_hw * hw,u32 offset,u16 data)62962583d18SSepherosa Ziehau static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
63062583d18SSepherosa Ziehau 					   u16 data)
63162583d18SSepherosa Ziehau {
63262583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_PARAM;
63362583d18SSepherosa Ziehau 
63462583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_write_phy_reg_sgmii_82575");
63562583d18SSepherosa Ziehau 
63662583d18SSepherosa Ziehau 	if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
63762583d18SSepherosa Ziehau 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
63862583d18SSepherosa Ziehau 		goto out;
63962583d18SSepherosa Ziehau 	}
64062583d18SSepherosa Ziehau 
64162583d18SSepherosa Ziehau 	ret_val = hw->phy.ops.acquire(hw);
64262583d18SSepherosa Ziehau 	if (ret_val)
64362583d18SSepherosa Ziehau 		goto out;
64462583d18SSepherosa Ziehau 
64562583d18SSepherosa Ziehau 	ret_val = e1000_write_phy_reg_i2c(hw, offset, data);
64662583d18SSepherosa Ziehau 
64762583d18SSepherosa Ziehau 	hw->phy.ops.release(hw);
64862583d18SSepherosa Ziehau 
64962583d18SSepherosa Ziehau out:
65062583d18SSepherosa Ziehau 	return ret_val;
65162583d18SSepherosa Ziehau }
65262583d18SSepherosa Ziehau 
65362583d18SSepherosa Ziehau /**
65462583d18SSepherosa Ziehau  *  e1000_get_phy_id_82575 - Retrieve PHY addr and id
65562583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
65662583d18SSepherosa Ziehau  *
65762583d18SSepherosa Ziehau  *  Retrieves the PHY address and ID for both PHY's which do and do not use
65862583d18SSepherosa Ziehau  *  sgmi interface.
65962583d18SSepherosa Ziehau  **/
e1000_get_phy_id_82575(struct e1000_hw * hw)66062583d18SSepherosa Ziehau static s32 e1000_get_phy_id_82575(struct e1000_hw *hw)
66162583d18SSepherosa Ziehau {
66262583d18SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
66362583d18SSepherosa Ziehau 	s32  ret_val = E1000_SUCCESS;
66462583d18SSepherosa Ziehau 	u16 phy_id;
66562583d18SSepherosa Ziehau 	u32 ctrl_ext;
66662583d18SSepherosa Ziehau 	u32 mdic;
66762583d18SSepherosa Ziehau 
66862583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_get_phy_id_82575");
66962583d18SSepherosa Ziehau 
670ba0123e0SSepherosa Ziehau 	/* some i354 devices need an extra read for phy id */
671ba0123e0SSepherosa Ziehau 	if (hw->mac.type == e1000_i354)
672ba0123e0SSepherosa Ziehau 		e1000_get_phy_id(hw);
673ba0123e0SSepherosa Ziehau 
67462583d18SSepherosa Ziehau 	/*
67562583d18SSepherosa Ziehau 	 * For SGMII PHYs, we try the list of possible addresses until
67662583d18SSepherosa Ziehau 	 * we find one that works.  For non-SGMII PHYs
67762583d18SSepherosa Ziehau 	 * (e.g. integrated copper PHYs), an address of 1 should
67862583d18SSepherosa Ziehau 	 * work.  The result of this function should mean phy->phy_addr
67962583d18SSepherosa Ziehau 	 * and phy->id are set correctly.
68062583d18SSepherosa Ziehau 	 */
68162583d18SSepherosa Ziehau 	if (!e1000_sgmii_active_82575(hw)) {
68262583d18SSepherosa Ziehau 		phy->addr = 1;
68362583d18SSepherosa Ziehau 		ret_val = e1000_get_phy_id(hw);
68462583d18SSepherosa Ziehau 		goto out;
68562583d18SSepherosa Ziehau 	}
68662583d18SSepherosa Ziehau 
68762583d18SSepherosa Ziehau 	if (e1000_sgmii_uses_mdio_82575(hw)) {
68862583d18SSepherosa Ziehau 		switch (hw->mac.type) {
68962583d18SSepherosa Ziehau 		case e1000_82575:
69062583d18SSepherosa Ziehau 		case e1000_82576:
69162583d18SSepherosa Ziehau 			mdic = E1000_READ_REG(hw, E1000_MDIC);
69262583d18SSepherosa Ziehau 			mdic &= E1000_MDIC_PHY_MASK;
69362583d18SSepherosa Ziehau 			phy->addr = mdic >> E1000_MDIC_PHY_SHIFT;
69462583d18SSepherosa Ziehau 			break;
69562583d18SSepherosa Ziehau 		case e1000_82580:
69662583d18SSepherosa Ziehau 		case e1000_i350:
697379ebbe7SSepherosa Ziehau 		case e1000_i354:
698379ebbe7SSepherosa Ziehau 		case e1000_i210:
699379ebbe7SSepherosa Ziehau 		case e1000_i211:
70062583d18SSepherosa Ziehau 			mdic = E1000_READ_REG(hw, E1000_MDICNFG);
70162583d18SSepherosa Ziehau 			mdic &= E1000_MDICNFG_PHY_MASK;
70262583d18SSepherosa Ziehau 			phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT;
70362583d18SSepherosa Ziehau 			break;
70462583d18SSepherosa Ziehau 		default:
70562583d18SSepherosa Ziehau 			ret_val = -E1000_ERR_PHY;
70662583d18SSepherosa Ziehau 			goto out;
70762583d18SSepherosa Ziehau 			break;
70862583d18SSepherosa Ziehau 		}
70962583d18SSepherosa Ziehau 		ret_val = e1000_get_phy_id(hw);
71062583d18SSepherosa Ziehau 		goto out;
71162583d18SSepherosa Ziehau 	}
71262583d18SSepherosa Ziehau 
71362583d18SSepherosa Ziehau 	/* Power on sgmii phy if it is disabled */
71462583d18SSepherosa Ziehau 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
71562583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL_EXT,
71662583d18SSepherosa Ziehau 			ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA);
71762583d18SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
71862583d18SSepherosa Ziehau 	msec_delay(300);
71962583d18SSepherosa Ziehau 
72062583d18SSepherosa Ziehau 	/*
72162583d18SSepherosa Ziehau 	 * The address field in the I2CCMD register is 3 bits and 0 is invalid.
72262583d18SSepherosa Ziehau 	 * Therefore, we need to test 1-7
72362583d18SSepherosa Ziehau 	 */
72462583d18SSepherosa Ziehau 	for (phy->addr = 1; phy->addr < 8; phy->addr++) {
72562583d18SSepherosa Ziehau 		ret_val = e1000_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id);
72662583d18SSepherosa Ziehau 		if (ret_val == E1000_SUCCESS) {
72762583d18SSepherosa Ziehau 			DEBUGOUT2("Vendor ID 0x%08X read at address %u\n",
7284be59a01SSepherosa Ziehau 				  phy_id, phy->addr);
72962583d18SSepherosa Ziehau 			/*
73062583d18SSepherosa Ziehau 			 * At the time of this writing, The M88 part is
73162583d18SSepherosa Ziehau 			 * the only supported SGMII PHY product.
73262583d18SSepherosa Ziehau 			 */
73362583d18SSepherosa Ziehau 			if (phy_id == M88_VENDOR)
73462583d18SSepherosa Ziehau 				break;
73562583d18SSepherosa Ziehau 		} else {
73662583d18SSepherosa Ziehau 			DEBUGOUT1("PHY address %u was unreadable\n",
73762583d18SSepherosa Ziehau 				  phy->addr);
73862583d18SSepherosa Ziehau 		}
73962583d18SSepherosa Ziehau 	}
74062583d18SSepherosa Ziehau 
74162583d18SSepherosa Ziehau 	/* A valid PHY type couldn't be found. */
74262583d18SSepherosa Ziehau 	if (phy->addr == 8) {
74362583d18SSepherosa Ziehau 		phy->addr = 0;
74462583d18SSepherosa Ziehau 		ret_val = -E1000_ERR_PHY;
74562583d18SSepherosa Ziehau 	} else {
74662583d18SSepherosa Ziehau 		ret_val = e1000_get_phy_id(hw);
74762583d18SSepherosa Ziehau 	}
74862583d18SSepherosa Ziehau 
74962583d18SSepherosa Ziehau 	/* restore previous sfp cage power state */
75062583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
75162583d18SSepherosa Ziehau 
75262583d18SSepherosa Ziehau out:
75362583d18SSepherosa Ziehau 	return ret_val;
75462583d18SSepherosa Ziehau }
75562583d18SSepherosa Ziehau 
75662583d18SSepherosa Ziehau /**
75762583d18SSepherosa Ziehau  *  e1000_phy_hw_reset_sgmii_82575 - Performs a PHY reset
75862583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
75962583d18SSepherosa Ziehau  *
76062583d18SSepherosa Ziehau  *  Resets the PHY using the serial gigabit media independent interface.
76162583d18SSepherosa Ziehau  **/
e1000_phy_hw_reset_sgmii_82575(struct e1000_hw * hw)76262583d18SSepherosa Ziehau static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
76362583d18SSepherosa Ziehau {
76462583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
765ba0123e0SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
76662583d18SSepherosa Ziehau 
76762583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
76862583d18SSepherosa Ziehau 
76962583d18SSepherosa Ziehau 	/*
77062583d18SSepherosa Ziehau 	 * This isn't a TRUE "hard" reset, but is the only reset
77162583d18SSepherosa Ziehau 	 * available to us at this time.
77262583d18SSepherosa Ziehau 	 */
77362583d18SSepherosa Ziehau 
77462583d18SSepherosa Ziehau 	DEBUGOUT("Soft resetting SGMII attached PHY...\n");
77562583d18SSepherosa Ziehau 
77662583d18SSepherosa Ziehau 	if (!(hw->phy.ops.write_reg))
77762583d18SSepherosa Ziehau 		goto out;
77862583d18SSepherosa Ziehau 
77962583d18SSepherosa Ziehau 	/*
78062583d18SSepherosa Ziehau 	 * SFP documentation requires the following to configure the SPF module
78162583d18SSepherosa Ziehau 	 * to work on SGMII.  No further documentation is given.
78262583d18SSepherosa Ziehau 	 */
78362583d18SSepherosa Ziehau 	ret_val = hw->phy.ops.write_reg(hw, 0x1B, 0x8084);
78462583d18SSepherosa Ziehau 	if (ret_val)
78562583d18SSepherosa Ziehau 		goto out;
78662583d18SSepherosa Ziehau 
78762583d18SSepherosa Ziehau 	ret_val = hw->phy.ops.commit(hw);
788ba0123e0SSepherosa Ziehau 	if (ret_val)
789ba0123e0SSepherosa Ziehau 		goto out;
79062583d18SSepherosa Ziehau 
791ba0123e0SSepherosa Ziehau 	if (phy->id == M88E1512_E_PHY_ID)
792ba0123e0SSepherosa Ziehau 		ret_val = e1000_initialize_M88E1512_phy(hw);
79362583d18SSepherosa Ziehau out:
79462583d18SSepherosa Ziehau 	return ret_val;
79562583d18SSepherosa Ziehau }
79662583d18SSepherosa Ziehau 
79762583d18SSepherosa Ziehau /**
79862583d18SSepherosa Ziehau  *  e1000_set_d0_lplu_state_82575 - Set Low Power Linkup D0 state
79962583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
80062583d18SSepherosa Ziehau  *  @active: TRUE to enable LPLU, FALSE to disable
80162583d18SSepherosa Ziehau  *
80262583d18SSepherosa Ziehau  *  Sets the LPLU D0 state according to the active flag.  When
80362583d18SSepherosa Ziehau  *  activating LPLU this function also disables smart speed
80462583d18SSepherosa Ziehau  *  and vice versa.  LPLU will not be activated unless the
80562583d18SSepherosa Ziehau  *  device autonegotiation advertisement meets standards of
80662583d18SSepherosa Ziehau  *  either 10 or 10/100 or 10/100/1000 at all duplexes.
80762583d18SSepherosa Ziehau  *  This is a function pointer entry point only called by
80862583d18SSepherosa Ziehau  *  PHY setup routines.
80962583d18SSepherosa Ziehau  **/
e1000_set_d0_lplu_state_82575(struct e1000_hw * hw,bool active)81062583d18SSepherosa Ziehau static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
81162583d18SSepherosa Ziehau {
81262583d18SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
81362583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
81462583d18SSepherosa Ziehau 	u16 data;
81562583d18SSepherosa Ziehau 
81662583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_set_d0_lplu_state_82575");
81762583d18SSepherosa Ziehau 
81862583d18SSepherosa Ziehau 	if (!(hw->phy.ops.read_reg))
81962583d18SSepherosa Ziehau 		goto out;
82062583d18SSepherosa Ziehau 
82162583d18SSepherosa Ziehau 	ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
82262583d18SSepherosa Ziehau 	if (ret_val)
82362583d18SSepherosa Ziehau 		goto out;
82462583d18SSepherosa Ziehau 
82562583d18SSepherosa Ziehau 	if (active) {
82662583d18SSepherosa Ziehau 		data |= IGP02E1000_PM_D0_LPLU;
82762583d18SSepherosa Ziehau 		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
82862583d18SSepherosa Ziehau 					     data);
82962583d18SSepherosa Ziehau 		if (ret_val)
83062583d18SSepherosa Ziehau 			goto out;
83162583d18SSepherosa Ziehau 
83262583d18SSepherosa Ziehau 		/* When LPLU is enabled, we should disable SmartSpeed */
83362583d18SSepherosa Ziehau 		ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
83462583d18SSepherosa Ziehau 					    &data);
83562583d18SSepherosa Ziehau 		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
83662583d18SSepherosa Ziehau 		ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
83762583d18SSepherosa Ziehau 					     data);
83862583d18SSepherosa Ziehau 		if (ret_val)
83962583d18SSepherosa Ziehau 			goto out;
84062583d18SSepherosa Ziehau 	} else {
84162583d18SSepherosa Ziehau 		data &= ~IGP02E1000_PM_D0_LPLU;
84262583d18SSepherosa Ziehau 		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
84362583d18SSepherosa Ziehau 					     data);
84462583d18SSepherosa Ziehau 		/*
84562583d18SSepherosa Ziehau 		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
84662583d18SSepherosa Ziehau 		 * during Dx states where the power conservation is most
84762583d18SSepherosa Ziehau 		 * important.  During driver activity we should enable
84862583d18SSepherosa Ziehau 		 * SmartSpeed, so performance is maintained.
84962583d18SSepherosa Ziehau 		 */
85062583d18SSepherosa Ziehau 		if (phy->smart_speed == e1000_smart_speed_on) {
85162583d18SSepherosa Ziehau 			ret_val = phy->ops.read_reg(hw,
85262583d18SSepherosa Ziehau 						    IGP01E1000_PHY_PORT_CONFIG,
85362583d18SSepherosa Ziehau 						    &data);
85462583d18SSepherosa Ziehau 			if (ret_val)
85562583d18SSepherosa Ziehau 				goto out;
85662583d18SSepherosa Ziehau 
85762583d18SSepherosa Ziehau 			data |= IGP01E1000_PSCFR_SMART_SPEED;
85862583d18SSepherosa Ziehau 			ret_val = phy->ops.write_reg(hw,
85962583d18SSepherosa Ziehau 						     IGP01E1000_PHY_PORT_CONFIG,
86062583d18SSepherosa Ziehau 						     data);
86162583d18SSepherosa Ziehau 			if (ret_val)
86262583d18SSepherosa Ziehau 				goto out;
86362583d18SSepherosa Ziehau 		} else if (phy->smart_speed == e1000_smart_speed_off) {
86462583d18SSepherosa Ziehau 			ret_val = phy->ops.read_reg(hw,
86562583d18SSepherosa Ziehau 						    IGP01E1000_PHY_PORT_CONFIG,
86662583d18SSepherosa Ziehau 						    &data);
86762583d18SSepherosa Ziehau 			if (ret_val)
86862583d18SSepherosa Ziehau 				goto out;
86962583d18SSepherosa Ziehau 
87062583d18SSepherosa Ziehau 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
87162583d18SSepherosa Ziehau 			ret_val = phy->ops.write_reg(hw,
87262583d18SSepherosa Ziehau 						     IGP01E1000_PHY_PORT_CONFIG,
87362583d18SSepherosa Ziehau 						     data);
87462583d18SSepherosa Ziehau 			if (ret_val)
87562583d18SSepherosa Ziehau 				goto out;
87662583d18SSepherosa Ziehau 		}
87762583d18SSepherosa Ziehau 	}
87862583d18SSepherosa Ziehau 
87962583d18SSepherosa Ziehau out:
88062583d18SSepherosa Ziehau 	return ret_val;
88162583d18SSepherosa Ziehau }
88262583d18SSepherosa Ziehau 
88362583d18SSepherosa Ziehau /**
88462583d18SSepherosa Ziehau  *  e1000_set_d0_lplu_state_82580 - Set Low Power Linkup D0 state
88562583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
88662583d18SSepherosa Ziehau  *  @active: TRUE to enable LPLU, FALSE to disable
88762583d18SSepherosa Ziehau  *
88862583d18SSepherosa Ziehau  *  Sets the LPLU D0 state according to the active flag.  When
88962583d18SSepherosa Ziehau  *  activating LPLU this function also disables smart speed
89062583d18SSepherosa Ziehau  *  and vice versa.  LPLU will not be activated unless the
89162583d18SSepherosa Ziehau  *  device autonegotiation advertisement meets standards of
89262583d18SSepherosa Ziehau  *  either 10 or 10/100 or 10/100/1000 at all duplexes.
89362583d18SSepherosa Ziehau  *  This is a function pointer entry point only called by
89462583d18SSepherosa Ziehau  *  PHY setup routines.
89562583d18SSepherosa Ziehau  **/
e1000_set_d0_lplu_state_82580(struct e1000_hw * hw,bool active)89662583d18SSepherosa Ziehau static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
89762583d18SSepherosa Ziehau {
89862583d18SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
8994be59a01SSepherosa Ziehau 	u32 data;
90062583d18SSepherosa Ziehau 
90162583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_set_d0_lplu_state_82580");
90262583d18SSepherosa Ziehau 
90362583d18SSepherosa Ziehau 	data = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
90462583d18SSepherosa Ziehau 
90562583d18SSepherosa Ziehau 	if (active) {
90662583d18SSepherosa Ziehau 		data |= E1000_82580_PM_D0_LPLU;
90762583d18SSepherosa Ziehau 
90862583d18SSepherosa Ziehau 		/* When LPLU is enabled, we should disable SmartSpeed */
90962583d18SSepherosa Ziehau 		data &= ~E1000_82580_PM_SPD;
91062583d18SSepherosa Ziehau 	} else {
91162583d18SSepherosa Ziehau 		data &= ~E1000_82580_PM_D0_LPLU;
91262583d18SSepherosa Ziehau 
91362583d18SSepherosa Ziehau 		/*
91462583d18SSepherosa Ziehau 		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
91562583d18SSepherosa Ziehau 		 * during Dx states where the power conservation is most
91662583d18SSepherosa Ziehau 		 * important.  During driver activity we should enable
91762583d18SSepherosa Ziehau 		 * SmartSpeed, so performance is maintained.
91862583d18SSepherosa Ziehau 		 */
9194be59a01SSepherosa Ziehau 		if (phy->smart_speed == e1000_smart_speed_on)
92062583d18SSepherosa Ziehau 			data |= E1000_82580_PM_SPD;
9214be59a01SSepherosa Ziehau 		else if (phy->smart_speed == e1000_smart_speed_off)
92262583d18SSepherosa Ziehau 			data &= ~E1000_82580_PM_SPD;
92362583d18SSepherosa Ziehau 	}
92462583d18SSepherosa Ziehau 
92562583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
926ba0123e0SSepherosa Ziehau 	return E1000_SUCCESS;
92762583d18SSepherosa Ziehau }
92862583d18SSepherosa Ziehau 
92962583d18SSepherosa Ziehau /**
93062583d18SSepherosa Ziehau  *  e1000_set_d3_lplu_state_82580 - Sets low power link up state for D3
93162583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
93262583d18SSepherosa Ziehau  *  @active: boolean used to enable/disable lplu
93362583d18SSepherosa Ziehau  *
93462583d18SSepherosa Ziehau  *  Success returns 0, Failure returns 1
93562583d18SSepherosa Ziehau  *
93662583d18SSepherosa Ziehau  *  The low power link up (lplu) state is set to the power management level D3
93762583d18SSepherosa Ziehau  *  and SmartSpeed is disabled when active is TRUE, else clear lplu for D3
93862583d18SSepherosa Ziehau  *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
93962583d18SSepherosa Ziehau  *  is used during Dx states where the power conservation is most important.
94062583d18SSepherosa Ziehau  *  During driver activity, SmartSpeed should be enabled so performance is
94162583d18SSepherosa Ziehau  *  maintained.
94262583d18SSepherosa Ziehau  **/
e1000_set_d3_lplu_state_82580(struct e1000_hw * hw,bool active)94362583d18SSepherosa Ziehau s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
94462583d18SSepherosa Ziehau {
94562583d18SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
9464be59a01SSepherosa Ziehau 	u32 data;
94762583d18SSepherosa Ziehau 
94862583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_set_d3_lplu_state_82580");
94962583d18SSepherosa Ziehau 
95062583d18SSepherosa Ziehau 	data = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
95162583d18SSepherosa Ziehau 
95262583d18SSepherosa Ziehau 	if (!active) {
95362583d18SSepherosa Ziehau 		data &= ~E1000_82580_PM_D3_LPLU;
95462583d18SSepherosa Ziehau 		/*
95562583d18SSepherosa Ziehau 		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
95662583d18SSepherosa Ziehau 		 * during Dx states where the power conservation is most
95762583d18SSepherosa Ziehau 		 * important.  During driver activity we should enable
95862583d18SSepherosa Ziehau 		 * SmartSpeed, so performance is maintained.
95962583d18SSepherosa Ziehau 		 */
9604be59a01SSepherosa Ziehau 		if (phy->smart_speed == e1000_smart_speed_on)
96162583d18SSepherosa Ziehau 			data |= E1000_82580_PM_SPD;
9624be59a01SSepherosa Ziehau 		else if (phy->smart_speed == e1000_smart_speed_off)
96362583d18SSepherosa Ziehau 			data &= ~E1000_82580_PM_SPD;
96462583d18SSepherosa Ziehau 	} else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
96562583d18SSepherosa Ziehau 		   (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
96662583d18SSepherosa Ziehau 		   (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
96762583d18SSepherosa Ziehau 		data |= E1000_82580_PM_D3_LPLU;
96862583d18SSepherosa Ziehau 		/* When LPLU is enabled, we should disable SmartSpeed */
96962583d18SSepherosa Ziehau 		data &= ~E1000_82580_PM_SPD;
97062583d18SSepherosa Ziehau 	}
97162583d18SSepherosa Ziehau 
97262583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
973ba0123e0SSepherosa Ziehau 	return E1000_SUCCESS;
97462583d18SSepherosa Ziehau }
97562583d18SSepherosa Ziehau 
97662583d18SSepherosa Ziehau /**
97762583d18SSepherosa Ziehau  *  e1000_acquire_nvm_82575 - Request for access to EEPROM
97862583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
97962583d18SSepherosa Ziehau  *
98062583d18SSepherosa Ziehau  *  Acquire the necessary semaphores for exclusive access to the EEPROM.
98162583d18SSepherosa Ziehau  *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
98262583d18SSepherosa Ziehau  *  Return successful if access grant bit set, else clear the request for
98362583d18SSepherosa Ziehau  *  EEPROM access and return -E1000_ERR_NVM (-1).
98462583d18SSepherosa Ziehau  **/
e1000_acquire_nvm_82575(struct e1000_hw * hw)98562583d18SSepherosa Ziehau static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
98662583d18SSepherosa Ziehau {
987ba0123e0SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
98862583d18SSepherosa Ziehau 
98962583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_acquire_nvm_82575");
99062583d18SSepherosa Ziehau 
99162583d18SSepherosa Ziehau 	ret_val = e1000_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
99262583d18SSepherosa Ziehau 	if (ret_val)
99362583d18SSepherosa Ziehau 		goto out;
99462583d18SSepherosa Ziehau 
99562583d18SSepherosa Ziehau 	/*
99662583d18SSepherosa Ziehau 	 * Check if there is some access
99762583d18SSepherosa Ziehau 	 * error this access may hook on
99862583d18SSepherosa Ziehau 	 */
99962583d18SSepherosa Ziehau 	if (hw->mac.type == e1000_i350) {
100062583d18SSepherosa Ziehau 		u32 eecd = E1000_READ_REG(hw, E1000_EECD);
100162583d18SSepherosa Ziehau 		if (eecd & (E1000_EECD_BLOCKED | E1000_EECD_ABORT |
100262583d18SSepherosa Ziehau 		    E1000_EECD_TIMEOUT)) {
100362583d18SSepherosa Ziehau 			/* Clear all access error flags */
100462583d18SSepherosa Ziehau 			E1000_WRITE_REG(hw, E1000_EECD, eecd |
100562583d18SSepherosa Ziehau 					E1000_EECD_ERROR_CLR);
10064be59a01SSepherosa Ziehau 			DEBUGOUT("Nvm bit banging access error detected and cleared.\n");
100762583d18SSepherosa Ziehau 		}
100862583d18SSepherosa Ziehau 	}
1009ba0123e0SSepherosa Ziehau 
101062583d18SSepherosa Ziehau 	if (hw->mac.type == e1000_82580) {
101162583d18SSepherosa Ziehau 		u32 eecd = E1000_READ_REG(hw, E1000_EECD);
101262583d18SSepherosa Ziehau 		if (eecd & E1000_EECD_BLOCKED) {
101362583d18SSepherosa Ziehau 			/* Clear access error flag */
101462583d18SSepherosa Ziehau 			E1000_WRITE_REG(hw, E1000_EECD, eecd |
101562583d18SSepherosa Ziehau 					E1000_EECD_BLOCKED);
10164be59a01SSepherosa Ziehau 			DEBUGOUT("Nvm bit banging access error detected and cleared.\n");
101762583d18SSepherosa Ziehau 		}
101862583d18SSepherosa Ziehau 	}
101962583d18SSepherosa Ziehau 
102062583d18SSepherosa Ziehau 	ret_val = e1000_acquire_nvm_generic(hw);
102162583d18SSepherosa Ziehau 	if (ret_val)
102262583d18SSepherosa Ziehau 		e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
102362583d18SSepherosa Ziehau 
102462583d18SSepherosa Ziehau out:
102562583d18SSepherosa Ziehau 	return ret_val;
102662583d18SSepherosa Ziehau }
102762583d18SSepherosa Ziehau 
102862583d18SSepherosa Ziehau /**
102962583d18SSepherosa Ziehau  *  e1000_release_nvm_82575 - Release exclusive access to EEPROM
103062583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
103162583d18SSepherosa Ziehau  *
103262583d18SSepherosa Ziehau  *  Stop any current commands to the EEPROM and clear the EEPROM request bit,
103362583d18SSepherosa Ziehau  *  then release the semaphores acquired.
103462583d18SSepherosa Ziehau  **/
e1000_release_nvm_82575(struct e1000_hw * hw)103562583d18SSepherosa Ziehau static void e1000_release_nvm_82575(struct e1000_hw *hw)
103662583d18SSepherosa Ziehau {
103762583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_release_nvm_82575");
103862583d18SSepherosa Ziehau 
10394be59a01SSepherosa Ziehau 	e1000_release_nvm_generic(hw);
10404be59a01SSepherosa Ziehau 
104162583d18SSepherosa Ziehau 	e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
104262583d18SSepherosa Ziehau }
104362583d18SSepherosa Ziehau 
104462583d18SSepherosa Ziehau /**
104562583d18SSepherosa Ziehau  *  e1000_acquire_swfw_sync_82575 - Acquire SW/FW semaphore
104662583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
104762583d18SSepherosa Ziehau  *  @mask: specifies which semaphore to acquire
104862583d18SSepherosa Ziehau  *
104962583d18SSepherosa Ziehau  *  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
105062583d18SSepherosa Ziehau  *  will also specify which port we're acquiring the lock for.
105162583d18SSepherosa Ziehau  **/
e1000_acquire_swfw_sync_82575(struct e1000_hw * hw,u16 mask)105262583d18SSepherosa Ziehau static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
105362583d18SSepherosa Ziehau {
105462583d18SSepherosa Ziehau 	u32 swfw_sync;
105562583d18SSepherosa Ziehau 	u32 swmask = mask;
105662583d18SSepherosa Ziehau 	u32 fwmask = mask << 16;
105762583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
1058ba0123e0SSepherosa Ziehau 	s32 i = 0, timeout = 200;
105962583d18SSepherosa Ziehau 
106062583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_acquire_swfw_sync_82575");
106162583d18SSepherosa Ziehau 
106262583d18SSepherosa Ziehau 	while (i < timeout) {
106362583d18SSepherosa Ziehau 		if (e1000_get_hw_semaphore_generic(hw)) {
106462583d18SSepherosa Ziehau 			ret_val = -E1000_ERR_SWFW_SYNC;
106562583d18SSepherosa Ziehau 			goto out;
106662583d18SSepherosa Ziehau 		}
106762583d18SSepherosa Ziehau 
106862583d18SSepherosa Ziehau 		swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
106962583d18SSepherosa Ziehau 		if (!(swfw_sync & (fwmask | swmask)))
107062583d18SSepherosa Ziehau 			break;
107162583d18SSepherosa Ziehau 
107262583d18SSepherosa Ziehau 		/*
107362583d18SSepherosa Ziehau 		 * Firmware currently using resource (fwmask)
107462583d18SSepherosa Ziehau 		 * or other software thread using resource (swmask)
107562583d18SSepherosa Ziehau 		 */
107662583d18SSepherosa Ziehau 		e1000_put_hw_semaphore_generic(hw);
107762583d18SSepherosa Ziehau 		msec_delay_irq(5);
107862583d18SSepherosa Ziehau 		i++;
107962583d18SSepherosa Ziehau 	}
108062583d18SSepherosa Ziehau 
108162583d18SSepherosa Ziehau 	if (i == timeout) {
108262583d18SSepherosa Ziehau 		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
108362583d18SSepherosa Ziehau 		ret_val = -E1000_ERR_SWFW_SYNC;
108462583d18SSepherosa Ziehau 		goto out;
108562583d18SSepherosa Ziehau 	}
108662583d18SSepherosa Ziehau 
108762583d18SSepherosa Ziehau 	swfw_sync |= swmask;
108862583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
108962583d18SSepherosa Ziehau 
109062583d18SSepherosa Ziehau 	e1000_put_hw_semaphore_generic(hw);
109162583d18SSepherosa Ziehau 
109262583d18SSepherosa Ziehau out:
109362583d18SSepherosa Ziehau 	return ret_val;
109462583d18SSepherosa Ziehau }
109562583d18SSepherosa Ziehau 
109662583d18SSepherosa Ziehau /**
109762583d18SSepherosa Ziehau  *  e1000_release_swfw_sync_82575 - Release SW/FW semaphore
109862583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
109962583d18SSepherosa Ziehau  *  @mask: specifies which semaphore to acquire
110062583d18SSepherosa Ziehau  *
110162583d18SSepherosa Ziehau  *  Release the SW/FW semaphore used to access the PHY or NVM.  The mask
110262583d18SSepherosa Ziehau  *  will also specify which port we're releasing the lock for.
110362583d18SSepherosa Ziehau  **/
e1000_release_swfw_sync_82575(struct e1000_hw * hw,u16 mask)110462583d18SSepherosa Ziehau static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
110562583d18SSepherosa Ziehau {
110662583d18SSepherosa Ziehau 	u32 swfw_sync;
110762583d18SSepherosa Ziehau 
110862583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_release_swfw_sync_82575");
110962583d18SSepherosa Ziehau 
11104be59a01SSepherosa Ziehau 	while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS)
11114be59a01SSepherosa Ziehau 		; /* Empty */
111262583d18SSepherosa Ziehau 
111362583d18SSepherosa Ziehau 	swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
111462583d18SSepherosa Ziehau 	swfw_sync &= ~mask;
111562583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
111662583d18SSepherosa Ziehau 
111762583d18SSepherosa Ziehau 	e1000_put_hw_semaphore_generic(hw);
111862583d18SSepherosa Ziehau }
111962583d18SSepherosa Ziehau 
112062583d18SSepherosa Ziehau /**
112162583d18SSepherosa Ziehau  *  e1000_get_cfg_done_82575 - Read config done bit
112262583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
112362583d18SSepherosa Ziehau  *
112462583d18SSepherosa Ziehau  *  Read the management control register for the config done bit for
112562583d18SSepherosa Ziehau  *  completion status.  NOTE: silicon which is EEPROM-less will fail trying
112662583d18SSepherosa Ziehau  *  to read the config done bit, so an error is *ONLY* logged and returns
112762583d18SSepherosa Ziehau  *  E1000_SUCCESS.  If we were to return with error, EEPROM-less silicon
112862583d18SSepherosa Ziehau  *  would not be able to be reset or change link.
112962583d18SSepherosa Ziehau  **/
e1000_get_cfg_done_82575(struct e1000_hw * hw)113062583d18SSepherosa Ziehau static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
113162583d18SSepherosa Ziehau {
113262583d18SSepherosa Ziehau 	s32 timeout = PHY_CFG_TIMEOUT;
113362583d18SSepherosa Ziehau 	u32 mask = E1000_NVM_CFG_DONE_PORT_0;
113462583d18SSepherosa Ziehau 
113562583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_get_cfg_done_82575");
113662583d18SSepherosa Ziehau 
113762583d18SSepherosa Ziehau 	if (hw->bus.func == E1000_FUNC_1)
113862583d18SSepherosa Ziehau 		mask = E1000_NVM_CFG_DONE_PORT_1;
113962583d18SSepherosa Ziehau 	else if (hw->bus.func == E1000_FUNC_2)
114062583d18SSepherosa Ziehau 		mask = E1000_NVM_CFG_DONE_PORT_2;
114162583d18SSepherosa Ziehau 	else if (hw->bus.func == E1000_FUNC_3)
114262583d18SSepherosa Ziehau 		mask = E1000_NVM_CFG_DONE_PORT_3;
114362583d18SSepherosa Ziehau 	while (timeout) {
114462583d18SSepherosa Ziehau 		if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask)
114562583d18SSepherosa Ziehau 			break;
114662583d18SSepherosa Ziehau 		msec_delay(1);
114762583d18SSepherosa Ziehau 		timeout--;
114862583d18SSepherosa Ziehau 	}
114962583d18SSepherosa Ziehau 	if (!timeout)
115062583d18SSepherosa Ziehau 		DEBUGOUT("MNG configuration cycle has not completed.\n");
115162583d18SSepherosa Ziehau 
115262583d18SSepherosa Ziehau 	/* If EEPROM is not marked present, init the PHY manually */
11534be59a01SSepherosa Ziehau 	if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) &&
115462583d18SSepherosa Ziehau 	    (hw->phy.type == e1000_phy_igp_3))
115562583d18SSepherosa Ziehau 		e1000_phy_init_script_igp3(hw);
115662583d18SSepherosa Ziehau 
1157ba0123e0SSepherosa Ziehau 	return E1000_SUCCESS;
115862583d18SSepherosa Ziehau }
115962583d18SSepherosa Ziehau 
116062583d18SSepherosa Ziehau /**
116162583d18SSepherosa Ziehau  *  e1000_get_link_up_info_82575 - Get link speed/duplex info
116262583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
116362583d18SSepherosa Ziehau  *  @speed: stores the current speed
116462583d18SSepherosa Ziehau  *  @duplex: stores the current duplex
116562583d18SSepherosa Ziehau  *
116662583d18SSepherosa Ziehau  *  This is a wrapper function, if using the serial gigabit media independent
116762583d18SSepherosa Ziehau  *  interface, use PCS to retrieve the link speed and duplex information.
116862583d18SSepherosa Ziehau  *  Otherwise, use the generic function to get the link speed and duplex info.
116962583d18SSepherosa Ziehau  **/
e1000_get_link_up_info_82575(struct e1000_hw * hw,u16 * speed,u16 * duplex)117062583d18SSepherosa Ziehau static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
117162583d18SSepherosa Ziehau 					u16 *duplex)
117262583d18SSepherosa Ziehau {
117362583d18SSepherosa Ziehau 	s32 ret_val;
117462583d18SSepherosa Ziehau 
117562583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_get_link_up_info_82575");
117662583d18SSepherosa Ziehau 
117762583d18SSepherosa Ziehau 	if (hw->phy.media_type != e1000_media_type_copper)
117862583d18SSepherosa Ziehau 		ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, speed,
117962583d18SSepherosa Ziehau 							       duplex);
118062583d18SSepherosa Ziehau 	else
118162583d18SSepherosa Ziehau 		ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed,
118262583d18SSepherosa Ziehau 								    duplex);
118362583d18SSepherosa Ziehau 
118462583d18SSepherosa Ziehau 	return ret_val;
118562583d18SSepherosa Ziehau }
118662583d18SSepherosa Ziehau 
118762583d18SSepherosa Ziehau /**
118862583d18SSepherosa Ziehau  *  e1000_check_for_link_82575 - Check for link
118962583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
119062583d18SSepherosa Ziehau  *
119162583d18SSepherosa Ziehau  *  If sgmii is enabled, then use the pcs register to determine link, otherwise
119262583d18SSepherosa Ziehau  *  use the generic interface for determining link.
119362583d18SSepherosa Ziehau  **/
e1000_check_for_link_82575(struct e1000_hw * hw)119462583d18SSepherosa Ziehau static s32 e1000_check_for_link_82575(struct e1000_hw *hw)
119562583d18SSepherosa Ziehau {
119662583d18SSepherosa Ziehau 	s32 ret_val;
119762583d18SSepherosa Ziehau 	u16 speed, duplex;
119862583d18SSepherosa Ziehau 
119962583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_check_for_link_82575");
120062583d18SSepherosa Ziehau 
120162583d18SSepherosa Ziehau 	if (hw->phy.media_type != e1000_media_type_copper) {
120262583d18SSepherosa Ziehau 		ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed,
120362583d18SSepherosa Ziehau 							       &duplex);
120462583d18SSepherosa Ziehau 		/*
120562583d18SSepherosa Ziehau 		 * Use this flag to determine if link needs to be checked or
120662583d18SSepherosa Ziehau 		 * not.  If we have link clear the flag so that we do not
120762583d18SSepherosa Ziehau 		 * continue to check for link.
120862583d18SSepherosa Ziehau 		 */
120962583d18SSepherosa Ziehau 		hw->mac.get_link_status = !hw->mac.serdes_has_link;
12104be59a01SSepherosa Ziehau 
12114be59a01SSepherosa Ziehau 		/*
12124be59a01SSepherosa Ziehau 		 * Configure Flow Control now that Auto-Neg has completed.
12134be59a01SSepherosa Ziehau 		 * First, we need to restore the desired flow control
12144be59a01SSepherosa Ziehau 		 * settings because we may have had to re-autoneg with a
12154be59a01SSepherosa Ziehau 		 * different link partner.
12164be59a01SSepherosa Ziehau 		 */
12174be59a01SSepherosa Ziehau 		ret_val = e1000_config_fc_after_link_up_generic(hw);
12184be59a01SSepherosa Ziehau 		if (ret_val)
12194be59a01SSepherosa Ziehau 			DEBUGOUT("Error configuring flow control\n");
122062583d18SSepherosa Ziehau 	} else {
122162583d18SSepherosa Ziehau 		ret_val = e1000_check_for_copper_link_generic(hw);
122262583d18SSepherosa Ziehau 	}
122362583d18SSepherosa Ziehau 
122462583d18SSepherosa Ziehau 	return ret_val;
122562583d18SSepherosa Ziehau }
122662583d18SSepherosa Ziehau 
122762583d18SSepherosa Ziehau /**
1228379ebbe7SSepherosa Ziehau  *  e1000_check_for_link_media_swap - Check which M88E1112 interface linked
1229379ebbe7SSepherosa Ziehau  *  @hw: pointer to the HW structure
1230379ebbe7SSepherosa Ziehau  *
1231379ebbe7SSepherosa Ziehau  *  Poll the M88E1112 interfaces to see which interface achieved link.
1232379ebbe7SSepherosa Ziehau  */
e1000_check_for_link_media_swap(struct e1000_hw * hw)1233379ebbe7SSepherosa Ziehau static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
1234379ebbe7SSepherosa Ziehau {
1235379ebbe7SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
1236379ebbe7SSepherosa Ziehau 	s32 ret_val;
1237379ebbe7SSepherosa Ziehau 	u16 data;
1238379ebbe7SSepherosa Ziehau 	u8 port = 0;
1239379ebbe7SSepherosa Ziehau 
1240379ebbe7SSepherosa Ziehau 	DEBUGFUNC("e1000_check_for_link_media_swap");
1241379ebbe7SSepherosa Ziehau 
1242ba0123e0SSepherosa Ziehau 	/* Check for copper. */
1243379ebbe7SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
1244379ebbe7SSepherosa Ziehau 	if (ret_val)
1245379ebbe7SSepherosa Ziehau 		return ret_val;
1246379ebbe7SSepherosa Ziehau 
1247379ebbe7SSepherosa Ziehau 	ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data);
1248379ebbe7SSepherosa Ziehau 	if (ret_val)
1249379ebbe7SSepherosa Ziehau 		return ret_val;
1250379ebbe7SSepherosa Ziehau 
1251379ebbe7SSepherosa Ziehau 	if (data & E1000_M88E1112_STATUS_LINK)
1252379ebbe7SSepherosa Ziehau 		port = E1000_MEDIA_PORT_COPPER;
1253379ebbe7SSepherosa Ziehau 
1254ba0123e0SSepherosa Ziehau 	/* Check for other. */
1255379ebbe7SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 1);
1256379ebbe7SSepherosa Ziehau 	if (ret_val)
1257379ebbe7SSepherosa Ziehau 		return ret_val;
1258379ebbe7SSepherosa Ziehau 
1259379ebbe7SSepherosa Ziehau 	ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data);
1260379ebbe7SSepherosa Ziehau 	if (ret_val)
1261379ebbe7SSepherosa Ziehau 		return ret_val;
1262379ebbe7SSepherosa Ziehau 
1263379ebbe7SSepherosa Ziehau 	if (data & E1000_M88E1112_STATUS_LINK)
1264379ebbe7SSepherosa Ziehau 		port = E1000_MEDIA_PORT_OTHER;
1265379ebbe7SSepherosa Ziehau 
1266379ebbe7SSepherosa Ziehau 	/* Determine if a swap needs to happen. */
1267379ebbe7SSepherosa Ziehau 	if (port && (hw->dev_spec._82575.media_port != port)) {
1268379ebbe7SSepherosa Ziehau 		hw->dev_spec._82575.media_port = port;
1269379ebbe7SSepherosa Ziehau 		hw->dev_spec._82575.media_changed = TRUE;
1270ba0123e0SSepherosa Ziehau 	}
1271ba0123e0SSepherosa Ziehau 
1272ba0123e0SSepherosa Ziehau 	if (port == E1000_MEDIA_PORT_COPPER) {
1273ba0123e0SSepherosa Ziehau 		/* reset page to 0 */
1274ba0123e0SSepherosa Ziehau 		ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
1275ba0123e0SSepherosa Ziehau 		if (ret_val)
1276ba0123e0SSepherosa Ziehau 			return ret_val;
1277ba0123e0SSepherosa Ziehau 		e1000_check_for_link_82575(hw);
1278379ebbe7SSepherosa Ziehau 	} else {
1279ba0123e0SSepherosa Ziehau 		e1000_check_for_link_82575(hw);
1280ba0123e0SSepherosa Ziehau 		/* reset page to 0 */
1281ba0123e0SSepherosa Ziehau 		ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
1282ba0123e0SSepherosa Ziehau 		if (ret_val)
1283ba0123e0SSepherosa Ziehau 			return ret_val;
1284379ebbe7SSepherosa Ziehau 	}
1285379ebbe7SSepherosa Ziehau 
1286379ebbe7SSepherosa Ziehau 	return E1000_SUCCESS;
1287379ebbe7SSepherosa Ziehau }
1288379ebbe7SSepherosa Ziehau 
1289379ebbe7SSepherosa Ziehau /**
129062583d18SSepherosa Ziehau  *  e1000_power_up_serdes_link_82575 - Power up the serdes link after shutdown
129162583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
129262583d18SSepherosa Ziehau  **/
e1000_power_up_serdes_link_82575(struct e1000_hw * hw)129362583d18SSepherosa Ziehau static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw)
129462583d18SSepherosa Ziehau {
129562583d18SSepherosa Ziehau 	u32 reg;
129662583d18SSepherosa Ziehau 
129762583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_power_up_serdes_link_82575");
129862583d18SSepherosa Ziehau 
129962583d18SSepherosa Ziehau 	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
130062583d18SSepherosa Ziehau 	    !e1000_sgmii_active_82575(hw))
130162583d18SSepherosa Ziehau 		return;
130262583d18SSepherosa Ziehau 
130362583d18SSepherosa Ziehau 	/* Enable PCS to turn on link */
130462583d18SSepherosa Ziehau 	reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
130562583d18SSepherosa Ziehau 	reg |= E1000_PCS_CFG_PCS_EN;
130662583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
130762583d18SSepherosa Ziehau 
130862583d18SSepherosa Ziehau 	/* Power up the laser */
130962583d18SSepherosa Ziehau 	reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
131062583d18SSepherosa Ziehau 	reg &= ~E1000_CTRL_EXT_SDP3_DATA;
131162583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
131262583d18SSepherosa Ziehau 
131362583d18SSepherosa Ziehau 	/* flush the write to verify completion */
131462583d18SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
131562583d18SSepherosa Ziehau 	msec_delay(1);
131662583d18SSepherosa Ziehau }
131762583d18SSepherosa Ziehau 
131862583d18SSepherosa Ziehau /**
131962583d18SSepherosa Ziehau  *  e1000_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
132062583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
132162583d18SSepherosa Ziehau  *  @speed: stores the current speed
132262583d18SSepherosa Ziehau  *  @duplex: stores the current duplex
132362583d18SSepherosa Ziehau  *
132462583d18SSepherosa Ziehau  *  Using the physical coding sub-layer (PCS), retrieve the current speed and
132562583d18SSepherosa Ziehau  *  duplex, then store the values in the pointers provided.
132662583d18SSepherosa Ziehau  **/
e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw * hw,u16 * speed,u16 * duplex)132762583d18SSepherosa Ziehau static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
132862583d18SSepherosa Ziehau 						u16 *speed, u16 *duplex)
132962583d18SSepherosa Ziehau {
133062583d18SSepherosa Ziehau 	struct e1000_mac_info *mac = &hw->mac;
133162583d18SSepherosa Ziehau 	u32 pcs;
1332ba0123e0SSepherosa Ziehau 	u32 status;
133362583d18SSepherosa Ziehau 
133462583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575");
133562583d18SSepherosa Ziehau 
133662583d18SSepherosa Ziehau 	/*
133762583d18SSepherosa Ziehau 	 * Read the PCS Status register for link state. For non-copper mode,
133862583d18SSepherosa Ziehau 	 * the status register is not accurate. The PCS status register is
133962583d18SSepherosa Ziehau 	 * used instead.
134062583d18SSepherosa Ziehau 	 */
134162583d18SSepherosa Ziehau 	pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT);
134262583d18SSepherosa Ziehau 
134362583d18SSepherosa Ziehau 	/*
13444be59a01SSepherosa Ziehau 	 * The link up bit determines when link is up on autoneg.
134562583d18SSepherosa Ziehau 	 */
13464be59a01SSepherosa Ziehau 	if (pcs & E1000_PCS_LSTS_LINK_OK) {
134762583d18SSepherosa Ziehau 		mac->serdes_has_link = TRUE;
134862583d18SSepherosa Ziehau 
134962583d18SSepherosa Ziehau 		/* Detect and store PCS speed */
13504be59a01SSepherosa Ziehau 		if (pcs & E1000_PCS_LSTS_SPEED_1000)
135162583d18SSepherosa Ziehau 			*speed = SPEED_1000;
13524be59a01SSepherosa Ziehau 		else if (pcs & E1000_PCS_LSTS_SPEED_100)
135362583d18SSepherosa Ziehau 			*speed = SPEED_100;
13544be59a01SSepherosa Ziehau 		else
135562583d18SSepherosa Ziehau 			*speed = SPEED_10;
135662583d18SSepherosa Ziehau 
135762583d18SSepherosa Ziehau 		/* Detect and store PCS duplex */
13584be59a01SSepherosa Ziehau 		if (pcs & E1000_PCS_LSTS_DUPLEX_FULL)
135962583d18SSepherosa Ziehau 			*duplex = FULL_DUPLEX;
13604be59a01SSepherosa Ziehau 		else
136162583d18SSepherosa Ziehau 			*duplex = HALF_DUPLEX;
1362379ebbe7SSepherosa Ziehau 
1363ba0123e0SSepherosa Ziehau 		/* Check if it is an I354 2.5Gb backplane connection. */
1364ba0123e0SSepherosa Ziehau 		if (mac->type == e1000_i354) {
1365ba0123e0SSepherosa Ziehau 			status = E1000_READ_REG(hw, E1000_STATUS);
1366ba0123e0SSepherosa Ziehau 			if ((status & E1000_STATUS_2P5_SKU) &&
1367ba0123e0SSepherosa Ziehau 			    !(status & E1000_STATUS_2P5_SKU_OVER)) {
1368ba0123e0SSepherosa Ziehau 				*speed = SPEED_2500;
1369ba0123e0SSepherosa Ziehau 				*duplex = FULL_DUPLEX;
1370ba0123e0SSepherosa Ziehau 				DEBUGOUT("2500 Mbs, ");
1371ba0123e0SSepherosa Ziehau 				DEBUGOUT("Full Duplex\n");
1372ba0123e0SSepherosa Ziehau 			}
1373ba0123e0SSepherosa Ziehau 		}
1374ba0123e0SSepherosa Ziehau 
13754be59a01SSepherosa Ziehau 	} else {
13764be59a01SSepherosa Ziehau 		mac->serdes_has_link = FALSE;
13774be59a01SSepherosa Ziehau 		*speed = 0;
13784be59a01SSepherosa Ziehau 		*duplex = 0;
137962583d18SSepherosa Ziehau 	}
138062583d18SSepherosa Ziehau 
138162583d18SSepherosa Ziehau 	return E1000_SUCCESS;
138262583d18SSepherosa Ziehau }
138362583d18SSepherosa Ziehau 
138462583d18SSepherosa Ziehau /**
138562583d18SSepherosa Ziehau  *  e1000_shutdown_serdes_link_82575 - Remove link during power down
138662583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
138762583d18SSepherosa Ziehau  *
138862583d18SSepherosa Ziehau  *  In the case of serdes shut down sfp and PCS on driver unload
138962583d18SSepherosa Ziehau  *  when management pass thru is not enabled.
139062583d18SSepherosa Ziehau  **/
e1000_shutdown_serdes_link_82575(struct e1000_hw * hw)139162583d18SSepherosa Ziehau void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw)
139262583d18SSepherosa Ziehau {
139362583d18SSepherosa Ziehau 	u32 reg;
139462583d18SSepherosa Ziehau 
139562583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_shutdown_serdes_link_82575");
139662583d18SSepherosa Ziehau 
139762583d18SSepherosa Ziehau 	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
139862583d18SSepherosa Ziehau 	    !e1000_sgmii_active_82575(hw))
139962583d18SSepherosa Ziehau 		return;
140062583d18SSepherosa Ziehau 
140162583d18SSepherosa Ziehau 	if (!e1000_enable_mng_pass_thru(hw)) {
140262583d18SSepherosa Ziehau 		/* Disable PCS to turn off link */
140362583d18SSepherosa Ziehau 		reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
140462583d18SSepherosa Ziehau 		reg &= ~E1000_PCS_CFG_PCS_EN;
140562583d18SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
140662583d18SSepherosa Ziehau 
140762583d18SSepherosa Ziehau 		/* shutdown the laser */
140862583d18SSepherosa Ziehau 		reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
140962583d18SSepherosa Ziehau 		reg |= E1000_CTRL_EXT_SDP3_DATA;
141062583d18SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
141162583d18SSepherosa Ziehau 
141262583d18SSepherosa Ziehau 		/* flush the write to verify completion */
141362583d18SSepherosa Ziehau 		E1000_WRITE_FLUSH(hw);
141462583d18SSepherosa Ziehau 		msec_delay(1);
141562583d18SSepherosa Ziehau 	}
141662583d18SSepherosa Ziehau 
141762583d18SSepherosa Ziehau 	return;
141862583d18SSepherosa Ziehau }
141962583d18SSepherosa Ziehau 
142062583d18SSepherosa Ziehau /**
142162583d18SSepherosa Ziehau  *  e1000_reset_hw_82575 - Reset hardware
142262583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
142362583d18SSepherosa Ziehau  *
142462583d18SSepherosa Ziehau  *  This resets the hardware into a known state.
142562583d18SSepherosa Ziehau  **/
e1000_reset_hw_82575(struct e1000_hw * hw)142662583d18SSepherosa Ziehau static s32 e1000_reset_hw_82575(struct e1000_hw *hw)
142762583d18SSepherosa Ziehau {
142862583d18SSepherosa Ziehau 	u32 ctrl;
142962583d18SSepherosa Ziehau 	s32 ret_val;
143062583d18SSepherosa Ziehau 
143162583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_reset_hw_82575");
143262583d18SSepherosa Ziehau 
143362583d18SSepherosa Ziehau 	/*
143462583d18SSepherosa Ziehau 	 * Prevent the PCI-E bus from sticking if there is no TLP connection
143562583d18SSepherosa Ziehau 	 * on the last TLP read/write transaction when MAC is reset.
143662583d18SSepherosa Ziehau 	 */
143762583d18SSepherosa Ziehau 	ret_val = e1000_disable_pcie_master_generic(hw);
14384be59a01SSepherosa Ziehau 	if (ret_val)
143962583d18SSepherosa Ziehau 		DEBUGOUT("PCI-E Master disable polling has failed.\n");
144062583d18SSepherosa Ziehau 
144162583d18SSepherosa Ziehau 	/* set the completion timeout for interface */
144262583d18SSepherosa Ziehau 	ret_val = e1000_set_pcie_completion_timeout(hw);
14434be59a01SSepherosa Ziehau 	if (ret_val)
144462583d18SSepherosa Ziehau 		DEBUGOUT("PCI-E Set completion timeout has failed.\n");
144562583d18SSepherosa Ziehau 
144662583d18SSepherosa Ziehau 	DEBUGOUT("Masking off all interrupts\n");
144762583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
144862583d18SSepherosa Ziehau 
144962583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
145062583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
145162583d18SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
145262583d18SSepherosa Ziehau 
145362583d18SSepherosa Ziehau 	msec_delay(10);
145462583d18SSepherosa Ziehau 
145562583d18SSepherosa Ziehau 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
145662583d18SSepherosa Ziehau 
145762583d18SSepherosa Ziehau 	DEBUGOUT("Issuing a global reset to MAC\n");
145862583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
145962583d18SSepherosa Ziehau 
146062583d18SSepherosa Ziehau 	ret_val = e1000_get_auto_rd_done_generic(hw);
146162583d18SSepherosa Ziehau 	if (ret_val) {
146262583d18SSepherosa Ziehau 		/*
146362583d18SSepherosa Ziehau 		 * When auto config read does not complete, do not
146462583d18SSepherosa Ziehau 		 * return with an error. This can happen in situations
146562583d18SSepherosa Ziehau 		 * where there is no eeprom and prevents getting link.
146662583d18SSepherosa Ziehau 		 */
146762583d18SSepherosa Ziehau 		DEBUGOUT("Auto Read Done did not complete\n");
146862583d18SSepherosa Ziehau 	}
146962583d18SSepherosa Ziehau 
147062583d18SSepherosa Ziehau 	/* If EEPROM is not present, run manual init scripts */
14714be59a01SSepherosa Ziehau 	if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES))
147262583d18SSepherosa Ziehau 		e1000_reset_init_script_82575(hw);
147362583d18SSepherosa Ziehau 
147462583d18SSepherosa Ziehau 	/* Clear any pending interrupt events. */
147562583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
147662583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ICR);
147762583d18SSepherosa Ziehau 
147862583d18SSepherosa Ziehau 	/* Install any alternate MAC address into RAR0 */
147962583d18SSepherosa Ziehau 	ret_val = e1000_check_alt_mac_addr_generic(hw);
148062583d18SSepherosa Ziehau 
148162583d18SSepherosa Ziehau 	return ret_val;
148262583d18SSepherosa Ziehau }
148362583d18SSepherosa Ziehau 
148462583d18SSepherosa Ziehau /**
148562583d18SSepherosa Ziehau  *  e1000_init_hw_82575 - Initialize hardware
148662583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
148762583d18SSepherosa Ziehau  *
148862583d18SSepherosa Ziehau  *  This inits the hardware readying it for operation.
148962583d18SSepherosa Ziehau  **/
e1000_init_hw_82575(struct e1000_hw * hw)1490ba0123e0SSepherosa Ziehau s32 e1000_init_hw_82575(struct e1000_hw *hw)
149162583d18SSepherosa Ziehau {
149262583d18SSepherosa Ziehau 	struct e1000_mac_info *mac = &hw->mac;
149362583d18SSepherosa Ziehau 	s32 ret_val;
149462583d18SSepherosa Ziehau 	u16 i, rar_count = mac->rar_entry_count;
149562583d18SSepherosa Ziehau 
149662583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_init_hw_82575");
149762583d18SSepherosa Ziehau 
149862583d18SSepherosa Ziehau 	/* Initialize identification LED */
149962583d18SSepherosa Ziehau 	ret_val = mac->ops.id_led_init(hw);
150062583d18SSepherosa Ziehau 	if (ret_val) {
150162583d18SSepherosa Ziehau 		DEBUGOUT("Error initializing identification LED\n");
150262583d18SSepherosa Ziehau 		/* This is not fatal and we should not stop init due to this */
150362583d18SSepherosa Ziehau 	}
150462583d18SSepherosa Ziehau 
150562583d18SSepherosa Ziehau 	/* Disabling VLAN filtering */
150662583d18SSepherosa Ziehau 	DEBUGOUT("Initializing the IEEE VLAN\n");
150762583d18SSepherosa Ziehau 	mac->ops.clear_vfta(hw);
150862583d18SSepherosa Ziehau 
150962583d18SSepherosa Ziehau 	/* Setup the receive address */
151062583d18SSepherosa Ziehau 	e1000_init_rx_addrs_generic(hw, rar_count);
151162583d18SSepherosa Ziehau 
151262583d18SSepherosa Ziehau 	/* Zero out the Multicast HASH table */
151362583d18SSepherosa Ziehau 	DEBUGOUT("Zeroing the MTA\n");
151462583d18SSepherosa Ziehau 	for (i = 0; i < mac->mta_reg_count; i++)
151562583d18SSepherosa Ziehau 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
151662583d18SSepherosa Ziehau 
151762583d18SSepherosa Ziehau 	/* Zero out the Unicast HASH table */
151862583d18SSepherosa Ziehau 	DEBUGOUT("Zeroing the UTA\n");
151962583d18SSepherosa Ziehau 	for (i = 0; i < mac->uta_reg_count; i++)
152062583d18SSepherosa Ziehau 		E1000_WRITE_REG_ARRAY(hw, E1000_UTA, i, 0);
152162583d18SSepherosa Ziehau 
152262583d18SSepherosa Ziehau 	/* Setup link and flow control */
152362583d18SSepherosa Ziehau 	ret_val = mac->ops.setup_link(hw);
152462583d18SSepherosa Ziehau 
15254be59a01SSepherosa Ziehau 	/* Set the default MTU size */
15264be59a01SSepherosa Ziehau 	hw->dev_spec._82575.mtu = 1500;
15274be59a01SSepherosa Ziehau 
152862583d18SSepherosa Ziehau 	/*
152962583d18SSepherosa Ziehau 	 * Clear all of the statistics registers (clear on read).  It is
153062583d18SSepherosa Ziehau 	 * important that we do this after we have tried to establish link
153162583d18SSepherosa Ziehau 	 * because the symbol error count will increment wildly if there
153262583d18SSepherosa Ziehau 	 * is no link.
153362583d18SSepherosa Ziehau 	 */
153462583d18SSepherosa Ziehau 	e1000_clear_hw_cntrs_82575(hw);
153562583d18SSepherosa Ziehau 
153662583d18SSepherosa Ziehau 	return ret_val;
153762583d18SSepherosa Ziehau }
153862583d18SSepherosa Ziehau 
153962583d18SSepherosa Ziehau /**
154062583d18SSepherosa Ziehau  *  e1000_setup_copper_link_82575 - Configure copper link settings
154162583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
154262583d18SSepherosa Ziehau  *
154362583d18SSepherosa Ziehau  *  Configures the link for auto-neg or forced speed and duplex.  Then we check
154462583d18SSepherosa Ziehau  *  for link, once link is established calls to configure collision distance
154562583d18SSepherosa Ziehau  *  and flow control are called.
154662583d18SSepherosa Ziehau  **/
e1000_setup_copper_link_82575(struct e1000_hw * hw)154762583d18SSepherosa Ziehau static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
154862583d18SSepherosa Ziehau {
154962583d18SSepherosa Ziehau 	u32 ctrl;
155062583d18SSepherosa Ziehau 	s32 ret_val;
15514be59a01SSepherosa Ziehau 	u32 phpm_reg;
155262583d18SSepherosa Ziehau 
155362583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_setup_copper_link_82575");
155462583d18SSepherosa Ziehau 
155562583d18SSepherosa Ziehau 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
155662583d18SSepherosa Ziehau 	ctrl |= E1000_CTRL_SLU;
155762583d18SSepherosa Ziehau 	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
155862583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
155962583d18SSepherosa Ziehau 
1560ba0123e0SSepherosa Ziehau 	/* Clear Go Link Disconnect bit on supported devices */
1561ba0123e0SSepherosa Ziehau 	switch (hw->mac.type) {
1562ba0123e0SSepherosa Ziehau 	case e1000_82580:
1563ba0123e0SSepherosa Ziehau 	case e1000_i350:
1564ba0123e0SSepherosa Ziehau 	case e1000_i210:
1565ba0123e0SSepherosa Ziehau 	case e1000_i211:
15664be59a01SSepherosa Ziehau 		phpm_reg = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
15674be59a01SSepherosa Ziehau 		phpm_reg &= ~E1000_82580_PM_GO_LINKD;
15684be59a01SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, phpm_reg);
1569ba0123e0SSepherosa Ziehau 		break;
1570ba0123e0SSepherosa Ziehau 	default:
1571ba0123e0SSepherosa Ziehau 		break;
15724be59a01SSepherosa Ziehau 	}
15734be59a01SSepherosa Ziehau 
157462583d18SSepherosa Ziehau 	ret_val = e1000_setup_serdes_link_82575(hw);
157562583d18SSepherosa Ziehau 	if (ret_val)
157662583d18SSepherosa Ziehau 		goto out;
157762583d18SSepherosa Ziehau 
15784be59a01SSepherosa Ziehau 	if (e1000_sgmii_active_82575(hw)) {
157962583d18SSepherosa Ziehau 		/* allow time for SFP cage time to power up phy */
158062583d18SSepherosa Ziehau 		msec_delay(300);
158162583d18SSepherosa Ziehau 
158262583d18SSepherosa Ziehau 		ret_val = hw->phy.ops.reset(hw);
158362583d18SSepherosa Ziehau 		if (ret_val) {
158462583d18SSepherosa Ziehau 			DEBUGOUT("Error resetting the PHY.\n");
158562583d18SSepherosa Ziehau 			goto out;
158662583d18SSepherosa Ziehau 		}
158762583d18SSepherosa Ziehau 	}
158862583d18SSepherosa Ziehau 	switch (hw->phy.type) {
15894be59a01SSepherosa Ziehau 	case e1000_phy_i210:
159062583d18SSepherosa Ziehau 	case e1000_phy_m88:
1591379ebbe7SSepherosa Ziehau 		switch (hw->phy.id) {
1592379ebbe7SSepherosa Ziehau 		case I347AT4_E_PHY_ID:
1593379ebbe7SSepherosa Ziehau 		case M88E1112_E_PHY_ID:
1594379ebbe7SSepherosa Ziehau 		case M88E1340M_E_PHY_ID:
1595ba0123e0SSepherosa Ziehau 		case M88E1543_E_PHY_ID:
1596ba0123e0SSepherosa Ziehau 		case M88E1512_E_PHY_ID:
1597379ebbe7SSepherosa Ziehau 		case I210_I_PHY_ID:
159862583d18SSepherosa Ziehau 			ret_val = e1000_copper_link_setup_m88_gen2(hw);
1599379ebbe7SSepherosa Ziehau 			break;
1600379ebbe7SSepherosa Ziehau 		default:
160162583d18SSepherosa Ziehau 			ret_val = e1000_copper_link_setup_m88(hw);
160262583d18SSepherosa Ziehau 			break;
1603379ebbe7SSepherosa Ziehau 		}
1604379ebbe7SSepherosa Ziehau 		break;
160562583d18SSepherosa Ziehau 	case e1000_phy_igp_3:
160662583d18SSepherosa Ziehau 		ret_val = e1000_copper_link_setup_igp(hw);
160762583d18SSepherosa Ziehau 		break;
160862583d18SSepherosa Ziehau 	case e1000_phy_82580:
160962583d18SSepherosa Ziehau 		ret_val = e1000_copper_link_setup_82577(hw);
161062583d18SSepherosa Ziehau 		break;
161162583d18SSepherosa Ziehau 	default:
161262583d18SSepherosa Ziehau 		ret_val = -E1000_ERR_PHY;
161362583d18SSepherosa Ziehau 		break;
161462583d18SSepherosa Ziehau 	}
161562583d18SSepherosa Ziehau 
161662583d18SSepherosa Ziehau 	if (ret_val)
161762583d18SSepherosa Ziehau 		goto out;
161862583d18SSepherosa Ziehau 
161962583d18SSepherosa Ziehau 	ret_val = e1000_setup_copper_link_generic(hw);
162062583d18SSepherosa Ziehau out:
162162583d18SSepherosa Ziehau 	return ret_val;
162262583d18SSepherosa Ziehau }
162362583d18SSepherosa Ziehau 
162462583d18SSepherosa Ziehau /**
162562583d18SSepherosa Ziehau  *  e1000_setup_serdes_link_82575 - Setup link for serdes
162662583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
162762583d18SSepherosa Ziehau  *
162862583d18SSepherosa Ziehau  *  Configure the physical coding sub-layer (PCS) link.  The PCS link is
162962583d18SSepherosa Ziehau  *  used on copper connections where the serialized gigabit media independent
163062583d18SSepherosa Ziehau  *  interface (sgmii), or serdes fiber is being used.  Configures the link
163162583d18SSepherosa Ziehau  *  for auto-negotiation or forces speed/duplex.
163262583d18SSepherosa Ziehau  **/
e1000_setup_serdes_link_82575(struct e1000_hw * hw)163362583d18SSepherosa Ziehau static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw)
163462583d18SSepherosa Ziehau {
16354be59a01SSepherosa Ziehau 	u32 ctrl_ext, ctrl_reg, reg, anadv_reg;
163662583d18SSepherosa Ziehau 	bool pcs_autoneg;
16374be59a01SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
16384be59a01SSepherosa Ziehau 	u16 data;
163962583d18SSepherosa Ziehau 
164062583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_setup_serdes_link_82575");
164162583d18SSepherosa Ziehau 
164262583d18SSepherosa Ziehau 	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
164362583d18SSepherosa Ziehau 	    !e1000_sgmii_active_82575(hw))
16444be59a01SSepherosa Ziehau 		return ret_val;
164562583d18SSepherosa Ziehau 
164662583d18SSepherosa Ziehau 	/*
164762583d18SSepherosa Ziehau 	 * On the 82575, SerDes loopback mode persists until it is
164862583d18SSepherosa Ziehau 	 * explicitly turned off or a power cycle is performed.  A read to
164962583d18SSepherosa Ziehau 	 * the register does not indicate its status.  Therefore, we ensure
165062583d18SSepherosa Ziehau 	 * loopback mode is disabled during initialization.
165162583d18SSepherosa Ziehau 	 */
165262583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
165362583d18SSepherosa Ziehau 
165462583d18SSepherosa Ziehau 	/* power on the sfp cage if present */
165562583d18SSepherosa Ziehau 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
165662583d18SSepherosa Ziehau 	ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
165762583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
165862583d18SSepherosa Ziehau 
165962583d18SSepherosa Ziehau 	ctrl_reg = E1000_READ_REG(hw, E1000_CTRL);
166062583d18SSepherosa Ziehau 	ctrl_reg |= E1000_CTRL_SLU;
166162583d18SSepherosa Ziehau 
166262583d18SSepherosa Ziehau 	/* set both sw defined pins on 82575/82576*/
166362583d18SSepherosa Ziehau 	if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576)
166462583d18SSepherosa Ziehau 		ctrl_reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1;
166562583d18SSepherosa Ziehau 
166662583d18SSepherosa Ziehau 	reg = E1000_READ_REG(hw, E1000_PCS_LCTL);
166762583d18SSepherosa Ziehau 
166862583d18SSepherosa Ziehau 	/* default pcs_autoneg to the same setting as mac autoneg */
166962583d18SSepherosa Ziehau 	pcs_autoneg = hw->mac.autoneg;
167062583d18SSepherosa Ziehau 
167162583d18SSepherosa Ziehau 	switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
167262583d18SSepherosa Ziehau 	case E1000_CTRL_EXT_LINK_MODE_SGMII:
167362583d18SSepherosa Ziehau 		/* sgmii mode lets the phy handle forcing speed/duplex */
167462583d18SSepherosa Ziehau 		pcs_autoneg = TRUE;
167562583d18SSepherosa Ziehau 		/* autoneg time out should be disabled for SGMII mode */
167662583d18SSepherosa Ziehau 		reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
167762583d18SSepherosa Ziehau 		break;
167862583d18SSepherosa Ziehau 	case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
167962583d18SSepherosa Ziehau 		/* disable PCS autoneg and support parallel detect only */
168062583d18SSepherosa Ziehau 		pcs_autoneg = FALSE;
168162583d18SSepherosa Ziehau 		/* fall through to default case */
168262583d18SSepherosa Ziehau 	default:
16834be59a01SSepherosa Ziehau 		if (hw->mac.type == e1000_82575 ||
16844be59a01SSepherosa Ziehau 		    hw->mac.type == e1000_82576) {
16854be59a01SSepherosa Ziehau 			ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &data);
16864be59a01SSepherosa Ziehau 			if (ret_val) {
16874be59a01SSepherosa Ziehau 				DEBUGOUT("NVM Read Error\n");
16884be59a01SSepherosa Ziehau 				return ret_val;
16894be59a01SSepherosa Ziehau 			}
16904be59a01SSepherosa Ziehau 
16914be59a01SSepherosa Ziehau 			if (data & E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT)
16924be59a01SSepherosa Ziehau 				pcs_autoneg = FALSE;
16934be59a01SSepherosa Ziehau 		}
16944be59a01SSepherosa Ziehau 
169562583d18SSepherosa Ziehau 		/*
169662583d18SSepherosa Ziehau 		 * non-SGMII modes only supports a speed of 1000/Full for the
169762583d18SSepherosa Ziehau 		 * link so it is best to just force the MAC and let the pcs
169862583d18SSepherosa Ziehau 		 * link either autoneg or be forced to 1000/Full
169962583d18SSepherosa Ziehau 		 */
170062583d18SSepherosa Ziehau 		ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
170162583d18SSepherosa Ziehau 			    E1000_CTRL_FD | E1000_CTRL_FRCDPX;
170262583d18SSepherosa Ziehau 
170362583d18SSepherosa Ziehau 		/* set speed of 1000/Full if speed/duplex is forced */
170462583d18SSepherosa Ziehau 		reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL;
170562583d18SSepherosa Ziehau 		break;
170662583d18SSepherosa Ziehau 	}
170762583d18SSepherosa Ziehau 
170862583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl_reg);
170962583d18SSepherosa Ziehau 
171062583d18SSepherosa Ziehau 	/*
171162583d18SSepherosa Ziehau 	 * New SerDes mode allows for forcing speed or autonegotiating speed
171262583d18SSepherosa Ziehau 	 * at 1gb. Autoneg should be default set by most drivers. This is the
171362583d18SSepherosa Ziehau 	 * mode that will be compatible with older link partners and switches.
171462583d18SSepherosa Ziehau 	 * However, both are supported by the hardware and some drivers/tools.
171562583d18SSepherosa Ziehau 	 */
171662583d18SSepherosa Ziehau 	reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
171762583d18SSepherosa Ziehau 		 E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
171862583d18SSepherosa Ziehau 
171962583d18SSepherosa Ziehau 	if (pcs_autoneg) {
172062583d18SSepherosa Ziehau 		/* Set PCS register for autoneg */
172162583d18SSepherosa Ziehau 		reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
172262583d18SSepherosa Ziehau 		       E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
17234be59a01SSepherosa Ziehau 
17244be59a01SSepherosa Ziehau 		/* Disable force flow control for autoneg */
17254be59a01SSepherosa Ziehau 		reg &= ~E1000_PCS_LCTL_FORCE_FCTRL;
17264be59a01SSepherosa Ziehau 
17274be59a01SSepherosa Ziehau 		/* Configure flow control advertisement for autoneg */
17284be59a01SSepherosa Ziehau 		anadv_reg = E1000_READ_REG(hw, E1000_PCS_ANADV);
17294be59a01SSepherosa Ziehau 		anadv_reg &= ~(E1000_TXCW_ASM_DIR | E1000_TXCW_PAUSE);
17304be59a01SSepherosa Ziehau 
17314be59a01SSepherosa Ziehau 		switch (hw->fc.requested_mode) {
17324be59a01SSepherosa Ziehau 		case e1000_fc_full:
17334be59a01SSepherosa Ziehau 		case e1000_fc_rx_pause:
17344be59a01SSepherosa Ziehau 			anadv_reg |= E1000_TXCW_ASM_DIR;
17354be59a01SSepherosa Ziehau 			anadv_reg |= E1000_TXCW_PAUSE;
17364be59a01SSepherosa Ziehau 			break;
17374be59a01SSepherosa Ziehau 		case e1000_fc_tx_pause:
17384be59a01SSepherosa Ziehau 			anadv_reg |= E1000_TXCW_ASM_DIR;
17394be59a01SSepherosa Ziehau 			break;
17404be59a01SSepherosa Ziehau 		default:
17414be59a01SSepherosa Ziehau 			break;
17424be59a01SSepherosa Ziehau 		}
17434be59a01SSepherosa Ziehau 
17444be59a01SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_PCS_ANADV, anadv_reg);
17454be59a01SSepherosa Ziehau 
174662583d18SSepherosa Ziehau 		DEBUGOUT1("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg);
174762583d18SSepherosa Ziehau 	} else {
174862583d18SSepherosa Ziehau 		/* Set PCS register for forced link */
174962583d18SSepherosa Ziehau 		reg |= E1000_PCS_LCTL_FSD;	/* Force Speed */
17504be59a01SSepherosa Ziehau 
17514be59a01SSepherosa Ziehau 		/* Force flow control for forced link */
17524be59a01SSepherosa Ziehau 		reg |= E1000_PCS_LCTL_FORCE_FCTRL;
17534be59a01SSepherosa Ziehau 
175462583d18SSepherosa Ziehau 		DEBUGOUT1("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg);
175562583d18SSepherosa Ziehau 	}
175662583d18SSepherosa Ziehau 
175762583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg);
175862583d18SSepherosa Ziehau 
17594be59a01SSepherosa Ziehau 	if (!pcs_autoneg && !e1000_sgmii_active_82575(hw))
176062583d18SSepherosa Ziehau 		e1000_force_mac_fc_generic(hw);
176162583d18SSepherosa Ziehau 
17624be59a01SSepherosa Ziehau 	return ret_val;
17634be59a01SSepherosa Ziehau }
17644be59a01SSepherosa Ziehau 
17654be59a01SSepherosa Ziehau /**
17664be59a01SSepherosa Ziehau  *  e1000_get_media_type_82575 - derives current media type.
17674be59a01SSepherosa Ziehau  *  @hw: pointer to the HW structure
17684be59a01SSepherosa Ziehau  *
17694be59a01SSepherosa Ziehau  *  The media type is chosen reflecting few settings.
17704be59a01SSepherosa Ziehau  *  The following are taken into account:
17714be59a01SSepherosa Ziehau  *  - link mode set in the current port Init Control Word #3
17724be59a01SSepherosa Ziehau  *  - current link mode settings in CSR register
17734be59a01SSepherosa Ziehau  *  - MDIO vs. I2C PHY control interface chosen
17744be59a01SSepherosa Ziehau  *  - SFP module media type
17754be59a01SSepherosa Ziehau  **/
e1000_get_media_type_82575(struct e1000_hw * hw)17764be59a01SSepherosa Ziehau static s32 e1000_get_media_type_82575(struct e1000_hw *hw)
17774be59a01SSepherosa Ziehau {
17784be59a01SSepherosa Ziehau 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
1779379ebbe7SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
17804be59a01SSepherosa Ziehau 	u32 ctrl_ext = 0;
1781379ebbe7SSepherosa Ziehau 	u32 link_mode = 0;
17824be59a01SSepherosa Ziehau 
17834be59a01SSepherosa Ziehau 	/* Set internal phy as default */
17844be59a01SSepherosa Ziehau 	dev_spec->sgmii_active = FALSE;
17854be59a01SSepherosa Ziehau 	dev_spec->module_plugged = FALSE;
17864be59a01SSepherosa Ziehau 
17874be59a01SSepherosa Ziehau 	/* Get CSR setting */
17884be59a01SSepherosa Ziehau 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
17894be59a01SSepherosa Ziehau 
1790379ebbe7SSepherosa Ziehau 	/* extract link mode setting */
1791379ebbe7SSepherosa Ziehau 	link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK;
17924be59a01SSepherosa Ziehau 
1793379ebbe7SSepherosa Ziehau 	switch (link_mode) {
17944be59a01SSepherosa Ziehau 	case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
17954be59a01SSepherosa Ziehau 		hw->phy.media_type = e1000_media_type_internal_serdes;
17964be59a01SSepherosa Ziehau 		break;
17974be59a01SSepherosa Ziehau 	case E1000_CTRL_EXT_LINK_MODE_GMII:
17984be59a01SSepherosa Ziehau 		hw->phy.media_type = e1000_media_type_copper;
17994be59a01SSepherosa Ziehau 		break;
18004be59a01SSepherosa Ziehau 	case E1000_CTRL_EXT_LINK_MODE_SGMII:
18014be59a01SSepherosa Ziehau 		/* Get phy control interface type set (MDIO vs. I2C)*/
18024be59a01SSepherosa Ziehau 		if (e1000_sgmii_uses_mdio_82575(hw)) {
18034be59a01SSepherosa Ziehau 			hw->phy.media_type = e1000_media_type_copper;
18044be59a01SSepherosa Ziehau 			dev_spec->sgmii_active = TRUE;
18054be59a01SSepherosa Ziehau 			break;
18064be59a01SSepherosa Ziehau 		}
1807379ebbe7SSepherosa Ziehau 		/* fall through for I2C based SGMII */
1808379ebbe7SSepherosa Ziehau 	case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
1809379ebbe7SSepherosa Ziehau 		/* read media type from SFP EEPROM */
1810379ebbe7SSepherosa Ziehau 		ret_val = e1000_set_sfp_media_type_82575(hw);
1811379ebbe7SSepherosa Ziehau 		if ((ret_val != E1000_SUCCESS) ||
1812379ebbe7SSepherosa Ziehau 		    (hw->phy.media_type == e1000_media_type_unknown)) {
18134be59a01SSepherosa Ziehau 			/*
1814379ebbe7SSepherosa Ziehau 			 * If media type was not identified then return media
1815379ebbe7SSepherosa Ziehau 			 * type defined by the CTRL_EXT settings.
18164be59a01SSepherosa Ziehau 			 */
1817379ebbe7SSepherosa Ziehau 			hw->phy.media_type = e1000_media_type_internal_serdes;
1818379ebbe7SSepherosa Ziehau 
1819379ebbe7SSepherosa Ziehau 			if (link_mode == E1000_CTRL_EXT_LINK_MODE_SGMII) {
1820379ebbe7SSepherosa Ziehau 				hw->phy.media_type = e1000_media_type_copper;
1821379ebbe7SSepherosa Ziehau 				dev_spec->sgmii_active = TRUE;
18224be59a01SSepherosa Ziehau 			}
18234be59a01SSepherosa Ziehau 
1824379ebbe7SSepherosa Ziehau 			break;
1825379ebbe7SSepherosa Ziehau 		}
1826379ebbe7SSepherosa Ziehau 
1827379ebbe7SSepherosa Ziehau 		/* do not change link mode for 100BaseFX */
1828379ebbe7SSepherosa Ziehau 		if (dev_spec->eth_flags.e100_base_fx)
1829379ebbe7SSepherosa Ziehau 			break;
1830379ebbe7SSepherosa Ziehau 
1831379ebbe7SSepherosa Ziehau 		/* change current link mode setting */
1832379ebbe7SSepherosa Ziehau 		ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK;
1833379ebbe7SSepherosa Ziehau 
1834379ebbe7SSepherosa Ziehau 		if (hw->phy.media_type == e1000_media_type_copper)
1835379ebbe7SSepherosa Ziehau 			ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_SGMII;
18364be59a01SSepherosa Ziehau 		else
1837379ebbe7SSepherosa Ziehau 			ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
1838379ebbe7SSepherosa Ziehau 
1839379ebbe7SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
1840379ebbe7SSepherosa Ziehau 
1841379ebbe7SSepherosa Ziehau 		break;
18424be59a01SSepherosa Ziehau 	}
18434be59a01SSepherosa Ziehau 
18444be59a01SSepherosa Ziehau 	return ret_val;
18454be59a01SSepherosa Ziehau }
18464be59a01SSepherosa Ziehau 
18474be59a01SSepherosa Ziehau /**
18484be59a01SSepherosa Ziehau  *  e1000_set_sfp_media_type_82575 - derives SFP module media type.
18494be59a01SSepherosa Ziehau  *  @hw: pointer to the HW structure
18504be59a01SSepherosa Ziehau  *
18514be59a01SSepherosa Ziehau  *  The media type is chosen based on SFP module.
18524be59a01SSepherosa Ziehau  *  compatibility flags retrieved from SFP ID EEPROM.
18534be59a01SSepherosa Ziehau  **/
e1000_set_sfp_media_type_82575(struct e1000_hw * hw)18544be59a01SSepherosa Ziehau static s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw)
18554be59a01SSepherosa Ziehau {
18564be59a01SSepherosa Ziehau 	s32 ret_val = E1000_ERR_CONFIG;
18574be59a01SSepherosa Ziehau 	u32 ctrl_ext = 0;
18584be59a01SSepherosa Ziehau 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
18594be59a01SSepherosa Ziehau 	struct sfp_e1000_flags *eth_flags = &dev_spec->eth_flags;
18604be59a01SSepherosa Ziehau 	u8 tranceiver_type = 0;
18614be59a01SSepherosa Ziehau 	s32 timeout = 3;
18624be59a01SSepherosa Ziehau 
18634be59a01SSepherosa Ziehau 	/* Turn I2C interface ON and power on sfp cage */
18644be59a01SSepherosa Ziehau 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
18654be59a01SSepherosa Ziehau 	ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
18664be59a01SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_I2C_ENA);
18674be59a01SSepherosa Ziehau 
18684be59a01SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
18694be59a01SSepherosa Ziehau 
18704be59a01SSepherosa Ziehau 	/* Read SFP module data */
18714be59a01SSepherosa Ziehau 	while (timeout) {
18724be59a01SSepherosa Ziehau 		ret_val = e1000_read_sfp_data_byte(hw,
18734be59a01SSepherosa Ziehau 			E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET),
18744be59a01SSepherosa Ziehau 			&tranceiver_type);
18754be59a01SSepherosa Ziehau 		if (ret_val == E1000_SUCCESS)
18764be59a01SSepherosa Ziehau 			break;
18774be59a01SSepherosa Ziehau 		msec_delay(100);
18784be59a01SSepherosa Ziehau 		timeout--;
18794be59a01SSepherosa Ziehau 	}
18804be59a01SSepherosa Ziehau 	if (ret_val != E1000_SUCCESS)
18814be59a01SSepherosa Ziehau 		goto out;
1882379ebbe7SSepherosa Ziehau 
18834be59a01SSepherosa Ziehau 	ret_val = e1000_read_sfp_data_byte(hw,
18844be59a01SSepherosa Ziehau 			E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET),
18854be59a01SSepherosa Ziehau 			(u8 *)eth_flags);
18864be59a01SSepherosa Ziehau 	if (ret_val != E1000_SUCCESS)
18874be59a01SSepherosa Ziehau 		goto out;
1888379ebbe7SSepherosa Ziehau 
1889379ebbe7SSepherosa Ziehau 	/* Check if there is some SFP module plugged and powered */
18904be59a01SSepherosa Ziehau 	if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) ||
18914be59a01SSepherosa Ziehau 	    (tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) {
18924be59a01SSepherosa Ziehau 		dev_spec->module_plugged = TRUE;
18934be59a01SSepherosa Ziehau 		if (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) {
18944be59a01SSepherosa Ziehau 			hw->phy.media_type = e1000_media_type_internal_serdes;
18954be59a01SSepherosa Ziehau 		} else if (eth_flags->e100_base_fx) {
18964be59a01SSepherosa Ziehau 			dev_spec->sgmii_active = TRUE;
18974be59a01SSepherosa Ziehau 			hw->phy.media_type = e1000_media_type_internal_serdes;
18984be59a01SSepherosa Ziehau 		} else if (eth_flags->e1000_base_t) {
18994be59a01SSepherosa Ziehau 			dev_spec->sgmii_active = TRUE;
19004be59a01SSepherosa Ziehau 			hw->phy.media_type = e1000_media_type_copper;
19014be59a01SSepherosa Ziehau 		} else {
19024be59a01SSepherosa Ziehau 			hw->phy.media_type = e1000_media_type_unknown;
19034be59a01SSepherosa Ziehau 			DEBUGOUT("PHY module has not been recognized\n");
19044be59a01SSepherosa Ziehau 			goto out;
19054be59a01SSepherosa Ziehau 		}
19064be59a01SSepherosa Ziehau 	} else {
19074be59a01SSepherosa Ziehau 		hw->phy.media_type = e1000_media_type_unknown;
19084be59a01SSepherosa Ziehau 	}
19094be59a01SSepherosa Ziehau 	ret_val = E1000_SUCCESS;
19104be59a01SSepherosa Ziehau out:
19114be59a01SSepherosa Ziehau 	/* Restore I2C interface setting */
19124be59a01SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
19134be59a01SSepherosa Ziehau 	return ret_val;
191462583d18SSepherosa Ziehau }
191562583d18SSepherosa Ziehau 
191662583d18SSepherosa Ziehau /**
191762583d18SSepherosa Ziehau  *  e1000_valid_led_default_82575 - Verify a valid default LED config
191862583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
191962583d18SSepherosa Ziehau  *  @data: pointer to the NVM (EEPROM)
192062583d18SSepherosa Ziehau  *
192162583d18SSepherosa Ziehau  *  Read the EEPROM for the current default LED configuration.  If the
192262583d18SSepherosa Ziehau  *  LED configuration is not valid, set to a valid LED configuration.
192362583d18SSepherosa Ziehau  **/
e1000_valid_led_default_82575(struct e1000_hw * hw,u16 * data)192462583d18SSepherosa Ziehau static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data)
192562583d18SSepherosa Ziehau {
192662583d18SSepherosa Ziehau 	s32 ret_val;
192762583d18SSepherosa Ziehau 
192862583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_valid_led_default_82575");
192962583d18SSepherosa Ziehau 
193062583d18SSepherosa Ziehau 	ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
193162583d18SSepherosa Ziehau 	if (ret_val) {
193262583d18SSepherosa Ziehau 		DEBUGOUT("NVM Read Error\n");
193362583d18SSepherosa Ziehau 		goto out;
193462583d18SSepherosa Ziehau 	}
193562583d18SSepherosa Ziehau 
193662583d18SSepherosa Ziehau 	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
193762583d18SSepherosa Ziehau 		switch (hw->phy.media_type) {
193862583d18SSepherosa Ziehau 		case e1000_media_type_internal_serdes:
193962583d18SSepherosa Ziehau 			*data = ID_LED_DEFAULT_82575_SERDES;
194062583d18SSepherosa Ziehau 			break;
194162583d18SSepherosa Ziehau 		case e1000_media_type_copper:
194262583d18SSepherosa Ziehau 		default:
194362583d18SSepherosa Ziehau 			*data = ID_LED_DEFAULT;
194462583d18SSepherosa Ziehau 			break;
194562583d18SSepherosa Ziehau 		}
194662583d18SSepherosa Ziehau 	}
194762583d18SSepherosa Ziehau out:
194862583d18SSepherosa Ziehau 	return ret_val;
194962583d18SSepherosa Ziehau }
195062583d18SSepherosa Ziehau 
195162583d18SSepherosa Ziehau /**
195262583d18SSepherosa Ziehau  *  e1000_sgmii_active_82575 - Return sgmii state
195362583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
195462583d18SSepherosa Ziehau  *
195562583d18SSepherosa Ziehau  *  82575 silicon has a serialized gigabit media independent interface (sgmii)
195662583d18SSepherosa Ziehau  *  which can be enabled for use in the embedded applications.  Simply
195762583d18SSepherosa Ziehau  *  return the current state of the sgmii interface.
195862583d18SSepherosa Ziehau  **/
e1000_sgmii_active_82575(struct e1000_hw * hw)195962583d18SSepherosa Ziehau static bool e1000_sgmii_active_82575(struct e1000_hw *hw)
196062583d18SSepherosa Ziehau {
196162583d18SSepherosa Ziehau 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
196262583d18SSepherosa Ziehau 	return dev_spec->sgmii_active;
196362583d18SSepherosa Ziehau }
196462583d18SSepherosa Ziehau 
196562583d18SSepherosa Ziehau /**
196662583d18SSepherosa Ziehau  *  e1000_reset_init_script_82575 - Inits HW defaults after reset
196762583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
196862583d18SSepherosa Ziehau  *
196962583d18SSepherosa Ziehau  *  Inits recommended HW defaults after a reset when there is no EEPROM
197062583d18SSepherosa Ziehau  *  detected. This is only for the 82575.
197162583d18SSepherosa Ziehau  **/
e1000_reset_init_script_82575(struct e1000_hw * hw)197262583d18SSepherosa Ziehau static s32 e1000_reset_init_script_82575(struct e1000_hw *hw)
197362583d18SSepherosa Ziehau {
197462583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_reset_init_script_82575");
197562583d18SSepherosa Ziehau 
197662583d18SSepherosa Ziehau 	if (hw->mac.type == e1000_82575) {
197762583d18SSepherosa Ziehau 		DEBUGOUT("Running reset init script for 82575\n");
197862583d18SSepherosa Ziehau 		/* SerDes configuration via SERDESCTRL */
197962583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x00, 0x0C);
198062583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x01, 0x78);
198162583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x1B, 0x23);
198262583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x23, 0x15);
198362583d18SSepherosa Ziehau 
198462583d18SSepherosa Ziehau 		/* CCM configuration via CCMCTL register */
198562583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x14, 0x00);
198662583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x10, 0x00);
198762583d18SSepherosa Ziehau 
198862583d18SSepherosa Ziehau 		/* PCIe lanes configuration */
198962583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x00, 0xEC);
199062583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x61, 0xDF);
199162583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x34, 0x05);
199262583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x2F, 0x81);
199362583d18SSepherosa Ziehau 
199462583d18SSepherosa Ziehau 		/* PCIe PLL Configuration */
199562583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x02, 0x47);
199662583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x14, 0x00);
199762583d18SSepherosa Ziehau 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x10, 0x00);
199862583d18SSepherosa Ziehau 	}
199962583d18SSepherosa Ziehau 
200062583d18SSepherosa Ziehau 	return E1000_SUCCESS;
200162583d18SSepherosa Ziehau }
200262583d18SSepherosa Ziehau 
200362583d18SSepherosa Ziehau /**
200462583d18SSepherosa Ziehau  *  e1000_read_mac_addr_82575 - Read device MAC address
200562583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
200662583d18SSepherosa Ziehau  **/
e1000_read_mac_addr_82575(struct e1000_hw * hw)200762583d18SSepherosa Ziehau static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw)
200862583d18SSepherosa Ziehau {
2009ba0123e0SSepherosa Ziehau 	s32 ret_val;
201062583d18SSepherosa Ziehau 
201162583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_read_mac_addr_82575");
201262583d18SSepherosa Ziehau 
201362583d18SSepherosa Ziehau 	/*
201462583d18SSepherosa Ziehau 	 * If there's an alternate MAC address place it in RAR0
201562583d18SSepherosa Ziehau 	 * so that it will override the Si installed default perm
201662583d18SSepherosa Ziehau 	 * address.
201762583d18SSepherosa Ziehau 	 */
201862583d18SSepherosa Ziehau 	ret_val = e1000_check_alt_mac_addr_generic(hw);
201962583d18SSepherosa Ziehau 	if (ret_val)
202062583d18SSepherosa Ziehau 		goto out;
202162583d18SSepherosa Ziehau 
202262583d18SSepherosa Ziehau 	ret_val = e1000_read_mac_addr_generic(hw);
202362583d18SSepherosa Ziehau 
202462583d18SSepherosa Ziehau out:
202562583d18SSepherosa Ziehau 	return ret_val;
202662583d18SSepherosa Ziehau }
202762583d18SSepherosa Ziehau 
202862583d18SSepherosa Ziehau /**
202962583d18SSepherosa Ziehau  *  e1000_config_collision_dist_82575 - Configure collision distance
203062583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
203162583d18SSepherosa Ziehau  *
203262583d18SSepherosa Ziehau  *  Configures the collision distance to the default value and is used
203362583d18SSepherosa Ziehau  *  during link setup.
203462583d18SSepherosa Ziehau  **/
e1000_config_collision_dist_82575(struct e1000_hw * hw)203562583d18SSepherosa Ziehau static void e1000_config_collision_dist_82575(struct e1000_hw *hw)
203662583d18SSepherosa Ziehau {
203762583d18SSepherosa Ziehau 	u32 tctl_ext;
203862583d18SSepherosa Ziehau 
203962583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_config_collision_dist_82575");
204062583d18SSepherosa Ziehau 
204162583d18SSepherosa Ziehau 	tctl_ext = E1000_READ_REG(hw, E1000_TCTL_EXT);
204262583d18SSepherosa Ziehau 
204362583d18SSepherosa Ziehau 	tctl_ext &= ~E1000_TCTL_EXT_COLD;
204462583d18SSepherosa Ziehau 	tctl_ext |= E1000_COLLISION_DISTANCE << E1000_TCTL_EXT_COLD_SHIFT;
204562583d18SSepherosa Ziehau 
204662583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_TCTL_EXT, tctl_ext);
204762583d18SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
204862583d18SSepherosa Ziehau }
204962583d18SSepherosa Ziehau 
205062583d18SSepherosa Ziehau /**
205162583d18SSepherosa Ziehau  * e1000_power_down_phy_copper_82575 - Remove link during PHY power down
205262583d18SSepherosa Ziehau  * @hw: pointer to the HW structure
205362583d18SSepherosa Ziehau  *
205462583d18SSepherosa Ziehau  * In the case of a PHY power down to save power, or to turn off link during a
205562583d18SSepherosa Ziehau  * driver unload, or wake on lan is not enabled, remove the link.
205662583d18SSepherosa Ziehau  **/
e1000_power_down_phy_copper_82575(struct e1000_hw * hw)205762583d18SSepherosa Ziehau static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
205862583d18SSepherosa Ziehau {
205962583d18SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
206062583d18SSepherosa Ziehau 
206162583d18SSepherosa Ziehau 	if (!(phy->ops.check_reset_block))
206262583d18SSepherosa Ziehau 		return;
206362583d18SSepherosa Ziehau 
206462583d18SSepherosa Ziehau 	/* If the management interface is not enabled, then power down */
206562583d18SSepherosa Ziehau 	if (!(e1000_enable_mng_pass_thru(hw) || phy->ops.check_reset_block(hw)))
206662583d18SSepherosa Ziehau 		e1000_power_down_phy_copper(hw);
206762583d18SSepherosa Ziehau 
206862583d18SSepherosa Ziehau 	return;
206962583d18SSepherosa Ziehau }
207062583d18SSepherosa Ziehau 
207162583d18SSepherosa Ziehau /**
207262583d18SSepherosa Ziehau  *  e1000_clear_hw_cntrs_82575 - Clear device specific hardware counters
207362583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
207462583d18SSepherosa Ziehau  *
207562583d18SSepherosa Ziehau  *  Clears the hardware counters by reading the counter registers.
207662583d18SSepherosa Ziehau  **/
e1000_clear_hw_cntrs_82575(struct e1000_hw * hw)207762583d18SSepherosa Ziehau static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
207862583d18SSepherosa Ziehau {
207962583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_clear_hw_cntrs_82575");
208062583d18SSepherosa Ziehau 
208162583d18SSepherosa Ziehau 	e1000_clear_hw_cntrs_base_generic(hw);
208262583d18SSepherosa Ziehau 
208362583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PRC64);
208462583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PRC127);
208562583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PRC255);
208662583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PRC511);
208762583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PRC1023);
208862583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PRC1522);
208962583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PTC64);
209062583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PTC127);
209162583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PTC255);
209262583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PTC511);
209362583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PTC1023);
209462583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_PTC1522);
209562583d18SSepherosa Ziehau 
209662583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ALGNERRC);
209762583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_RXERRC);
209862583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_TNCRS);
209962583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_CEXTERR);
210062583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_TSCTC);
210162583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_TSCTFC);
210262583d18SSepherosa Ziehau 
210362583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_MGTPRC);
210462583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_MGTPDC);
210562583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_MGTPTC);
210662583d18SSepherosa Ziehau 
210762583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_IAC);
210862583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ICRXOC);
210962583d18SSepherosa Ziehau 
211062583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ICRXPTC);
211162583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ICRXATC);
211262583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ICTXPTC);
211362583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ICTXATC);
211462583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ICTXQEC);
211562583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ICTXQMTC);
211662583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ICRXDMTC);
211762583d18SSepherosa Ziehau 
211862583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_CBTMPC);
211962583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_HTDPMC);
212062583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_CBRMPC);
212162583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_RPTHC);
212262583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_HGPTC);
212362583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_HTCBDPC);
212462583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_HGORCL);
212562583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_HGORCH);
212662583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_HGOTCL);
212762583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_HGOTCH);
212862583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_LENERRS);
212962583d18SSepherosa Ziehau 
213062583d18SSepherosa Ziehau 	/* This register should not be read in copper configurations */
213162583d18SSepherosa Ziehau 	if ((hw->phy.media_type == e1000_media_type_internal_serdes) ||
213262583d18SSepherosa Ziehau 	    e1000_sgmii_active_82575(hw))
213362583d18SSepherosa Ziehau 		E1000_READ_REG(hw, E1000_SCVPC);
213462583d18SSepherosa Ziehau }
213562583d18SSepherosa Ziehau 
213662583d18SSepherosa Ziehau /**
213762583d18SSepherosa Ziehau  *  e1000_rx_fifo_flush_82575 - Clean rx fifo after Rx enable
213862583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
213962583d18SSepherosa Ziehau  *
2140ba0123e0SSepherosa Ziehau  *  After Rx enable, if manageability is enabled then there is likely some
214162583d18SSepherosa Ziehau  *  bad data at the start of the fifo and possibly in the DMA fifo.  This
214262583d18SSepherosa Ziehau  *  function clears the fifos and flushes any packets that came in as rx was
214362583d18SSepherosa Ziehau  *  being enabled.
214462583d18SSepherosa Ziehau  **/
e1000_rx_fifo_flush_82575(struct e1000_hw * hw)214562583d18SSepherosa Ziehau void e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
214662583d18SSepherosa Ziehau {
214762583d18SSepherosa Ziehau 	u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
214862583d18SSepherosa Ziehau 	int i, ms_wait;
214962583d18SSepherosa Ziehau 
2150ba0123e0SSepherosa Ziehau 	DEBUGFUNC("e1000_rx_fifo_flush_82575");
2151ba0123e0SSepherosa Ziehau 
2152ba0123e0SSepherosa Ziehau 	/* disable IPv6 options as per hardware errata */
2153ba0123e0SSepherosa Ziehau 	rfctl = E1000_READ_REG(hw, E1000_RFCTL);
2154ba0123e0SSepherosa Ziehau 	rfctl |= E1000_RFCTL_IPV6_EX_DIS;
2155ba0123e0SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
2156ba0123e0SSepherosa Ziehau 
215762583d18SSepherosa Ziehau 	if (hw->mac.type != e1000_82575 ||
215862583d18SSepherosa Ziehau 	    !(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
215962583d18SSepherosa Ziehau 		return;
216062583d18SSepherosa Ziehau 
216162583d18SSepherosa Ziehau 	/* Disable all Rx queues */
216262583d18SSepherosa Ziehau 	for (i = 0; i < 4; i++) {
216362583d18SSepherosa Ziehau 		rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i));
216462583d18SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_RXDCTL(i),
216562583d18SSepherosa Ziehau 				rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
216662583d18SSepherosa Ziehau 	}
216762583d18SSepherosa Ziehau 	/* Poll all queues to verify they have shut down */
216862583d18SSepherosa Ziehau 	for (ms_wait = 0; ms_wait < 10; ms_wait++) {
216962583d18SSepherosa Ziehau 		msec_delay(1);
217062583d18SSepherosa Ziehau 		rx_enabled = 0;
217162583d18SSepherosa Ziehau 		for (i = 0; i < 4; i++)
217262583d18SSepherosa Ziehau 			rx_enabled |= E1000_READ_REG(hw, E1000_RXDCTL(i));
217362583d18SSepherosa Ziehau 		if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
217462583d18SSepherosa Ziehau 			break;
217562583d18SSepherosa Ziehau 	}
217662583d18SSepherosa Ziehau 
217762583d18SSepherosa Ziehau 	if (ms_wait == 10)
217862583d18SSepherosa Ziehau 		DEBUGOUT("Queue disable timed out after 10ms\n");
217962583d18SSepherosa Ziehau 
218062583d18SSepherosa Ziehau 	/* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
218162583d18SSepherosa Ziehau 	 * incoming packets are rejected.  Set enable and wait 2ms so that
218262583d18SSepherosa Ziehau 	 * any packet that was coming in as RCTL.EN was set is flushed
218362583d18SSepherosa Ziehau 	 */
218462583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
218562583d18SSepherosa Ziehau 
218662583d18SSepherosa Ziehau 	rlpml = E1000_READ_REG(hw, E1000_RLPML);
218762583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_RLPML, 0);
218862583d18SSepherosa Ziehau 
218962583d18SSepherosa Ziehau 	rctl = E1000_READ_REG(hw, E1000_RCTL);
219062583d18SSepherosa Ziehau 	temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
219162583d18SSepherosa Ziehau 	temp_rctl |= E1000_RCTL_LPE;
219262583d18SSepherosa Ziehau 
219362583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl);
219462583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl | E1000_RCTL_EN);
219562583d18SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
219662583d18SSepherosa Ziehau 	msec_delay(2);
219762583d18SSepherosa Ziehau 
219862583d18SSepherosa Ziehau 	/* Enable Rx queues that were previously enabled and restore our
219962583d18SSepherosa Ziehau 	 * previous state
220062583d18SSepherosa Ziehau 	 */
220162583d18SSepherosa Ziehau 	for (i = 0; i < 4; i++)
220262583d18SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl[i]);
220362583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_RCTL, rctl);
220462583d18SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
220562583d18SSepherosa Ziehau 
220662583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_RLPML, rlpml);
220762583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
220862583d18SSepherosa Ziehau 
220962583d18SSepherosa Ziehau 	/* Flush receive errors generated by workaround */
221062583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ROC);
221162583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_RNBC);
221262583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_MPC);
221362583d18SSepherosa Ziehau }
221462583d18SSepherosa Ziehau 
221562583d18SSepherosa Ziehau /**
221662583d18SSepherosa Ziehau  *  e1000_set_pcie_completion_timeout - set pci-e completion timeout
221762583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
221862583d18SSepherosa Ziehau  *
221962583d18SSepherosa Ziehau  *  The defaults for 82575 and 82576 should be in the range of 50us to 50ms,
222062583d18SSepherosa Ziehau  *  however the hardware default for these parts is 500us to 1ms which is less
222162583d18SSepherosa Ziehau  *  than the 10ms recommended by the pci-e spec.  To address this we need to
222262583d18SSepherosa Ziehau  *  increase the value to either 10ms to 200ms for capability version 1 config,
222362583d18SSepherosa Ziehau  *  or 16ms to 55ms for version 2.
222462583d18SSepherosa Ziehau  **/
e1000_set_pcie_completion_timeout(struct e1000_hw * hw)222562583d18SSepherosa Ziehau static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw)
222662583d18SSepherosa Ziehau {
222762583d18SSepherosa Ziehau 	u32 gcr = E1000_READ_REG(hw, E1000_GCR);
222862583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
222962583d18SSepherosa Ziehau 	u16 pcie_devctl2;
223062583d18SSepherosa Ziehau 
223162583d18SSepherosa Ziehau 	/* only take action if timeout value is defaulted to 0 */
223262583d18SSepherosa Ziehau 	if (gcr & E1000_GCR_CMPL_TMOUT_MASK)
223362583d18SSepherosa Ziehau 		goto out;
223462583d18SSepherosa Ziehau 
223562583d18SSepherosa Ziehau 	/*
223662583d18SSepherosa Ziehau 	 * if capababilities version is type 1 we can write the
223762583d18SSepherosa Ziehau 	 * timeout of 10ms to 200ms through the GCR register
223862583d18SSepherosa Ziehau 	 */
223962583d18SSepherosa Ziehau 	if (!(gcr & E1000_GCR_CAP_VER2)) {
224062583d18SSepherosa Ziehau 		gcr |= E1000_GCR_CMPL_TMOUT_10ms;
224162583d18SSepherosa Ziehau 		goto out;
224262583d18SSepherosa Ziehau 	}
224362583d18SSepherosa Ziehau 
224462583d18SSepherosa Ziehau 	/*
224562583d18SSepherosa Ziehau 	 * for version 2 capabilities we need to write the config space
224662583d18SSepherosa Ziehau 	 * directly in order to set the completion timeout value for
224762583d18SSepherosa Ziehau 	 * 16ms to 55ms
224862583d18SSepherosa Ziehau 	 */
224962583d18SSepherosa Ziehau 	ret_val = e1000_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
225062583d18SSepherosa Ziehau 					  &pcie_devctl2);
225162583d18SSepherosa Ziehau 	if (ret_val)
225262583d18SSepherosa Ziehau 		goto out;
225362583d18SSepherosa Ziehau 
225462583d18SSepherosa Ziehau 	pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
225562583d18SSepherosa Ziehau 
225662583d18SSepherosa Ziehau 	ret_val = e1000_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
225762583d18SSepherosa Ziehau 					   &pcie_devctl2);
225862583d18SSepherosa Ziehau out:
225962583d18SSepherosa Ziehau 	/* disable completion timeout resend */
226062583d18SSepherosa Ziehau 	gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
226162583d18SSepherosa Ziehau 
226262583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_GCR, gcr);
226362583d18SSepherosa Ziehau 	return ret_val;
226462583d18SSepherosa Ziehau }
226562583d18SSepherosa Ziehau 
226662583d18SSepherosa Ziehau /**
226762583d18SSepherosa Ziehau  *  e1000_vmdq_set_anti_spoofing_pf - enable or disable anti-spoofing
226862583d18SSepherosa Ziehau  *  @hw: pointer to the hardware struct
226962583d18SSepherosa Ziehau  *  @enable: state to enter, either enabled or disabled
227062583d18SSepherosa Ziehau  *  @pf: Physical Function pool - do not set anti-spoofing for the PF
227162583d18SSepherosa Ziehau  *
227262583d18SSepherosa Ziehau  *  enables/disables L2 switch anti-spoofing functionality.
227362583d18SSepherosa Ziehau  **/
e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw * hw,bool enable,int pf)227462583d18SSepherosa Ziehau void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
227562583d18SSepherosa Ziehau {
2276ba0123e0SSepherosa Ziehau 	u32 reg_val, reg_offset;
227762583d18SSepherosa Ziehau 
227862583d18SSepherosa Ziehau 	switch (hw->mac.type) {
227962583d18SSepherosa Ziehau 	case e1000_82576:
2280ba0123e0SSepherosa Ziehau 		reg_offset = E1000_DTXSWC;
228162583d18SSepherosa Ziehau 		break;
228262583d18SSepherosa Ziehau 	case e1000_i350:
2283379ebbe7SSepherosa Ziehau 	case e1000_i354:
2284ba0123e0SSepherosa Ziehau 		reg_offset = E1000_TXSWC;
2285ba0123e0SSepherosa Ziehau 		break;
2286ba0123e0SSepherosa Ziehau 	default:
2287ba0123e0SSepherosa Ziehau 		return;
2288ba0123e0SSepherosa Ziehau 	}
2289ba0123e0SSepherosa Ziehau 
2290ba0123e0SSepherosa Ziehau 	reg_val = E1000_READ_REG(hw, reg_offset);
229162583d18SSepherosa Ziehau 	if (enable) {
2292ba0123e0SSepherosa Ziehau 		reg_val |= (E1000_DTXSWC_MAC_SPOOF_MASK |
229362583d18SSepherosa Ziehau 			     E1000_DTXSWC_VLAN_SPOOF_MASK);
229462583d18SSepherosa Ziehau 		/* The PF can spoof - it has to in order to
229562583d18SSepherosa Ziehau 		 * support emulation mode NICs
229662583d18SSepherosa Ziehau 		 */
2297ba0123e0SSepherosa Ziehau 		reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
229862583d18SSepherosa Ziehau 	} else {
2299ba0123e0SSepherosa Ziehau 		reg_val &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
230062583d18SSepherosa Ziehau 			     E1000_DTXSWC_VLAN_SPOOF_MASK);
230162583d18SSepherosa Ziehau 	}
2302ba0123e0SSepherosa Ziehau 	E1000_WRITE_REG(hw, reg_offset, reg_val);
230362583d18SSepherosa Ziehau }
230462583d18SSepherosa Ziehau 
230562583d18SSepherosa Ziehau /**
230662583d18SSepherosa Ziehau  *  e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback
230762583d18SSepherosa Ziehau  *  @hw: pointer to the hardware struct
230862583d18SSepherosa Ziehau  *  @enable: state to enter, either enabled or disabled
230962583d18SSepherosa Ziehau  *
231062583d18SSepherosa Ziehau  *  enables/disables L2 switch loopback functionality.
231162583d18SSepherosa Ziehau  **/
e1000_vmdq_set_loopback_pf(struct e1000_hw * hw,bool enable)231262583d18SSepherosa Ziehau void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
231362583d18SSepherosa Ziehau {
231462583d18SSepherosa Ziehau 	u32 dtxswc;
231562583d18SSepherosa Ziehau 
231662583d18SSepherosa Ziehau 	switch (hw->mac.type) {
231762583d18SSepherosa Ziehau 	case e1000_82576:
231862583d18SSepherosa Ziehau 		dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
231962583d18SSepherosa Ziehau 		if (enable)
232062583d18SSepherosa Ziehau 			dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
232162583d18SSepherosa Ziehau 		else
232262583d18SSepherosa Ziehau 			dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
232362583d18SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
232462583d18SSepherosa Ziehau 		break;
232562583d18SSepherosa Ziehau 	case e1000_i350:
2326379ebbe7SSepherosa Ziehau 	case e1000_i354:
232762583d18SSepherosa Ziehau 		dtxswc = E1000_READ_REG(hw, E1000_TXSWC);
232862583d18SSepherosa Ziehau 		if (enable)
232962583d18SSepherosa Ziehau 			dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
233062583d18SSepherosa Ziehau 		else
233162583d18SSepherosa Ziehau 			dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
233262583d18SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_TXSWC, dtxswc);
233362583d18SSepherosa Ziehau 		break;
233462583d18SSepherosa Ziehau 	default:
233562583d18SSepherosa Ziehau 		/* Currently no other hardware supports loopback */
233662583d18SSepherosa Ziehau 		break;
233762583d18SSepherosa Ziehau 	}
233862583d18SSepherosa Ziehau 
233962583d18SSepherosa Ziehau 
234062583d18SSepherosa Ziehau }
234162583d18SSepherosa Ziehau 
234262583d18SSepherosa Ziehau /**
234362583d18SSepherosa Ziehau  *  e1000_vmdq_set_replication_pf - enable or disable vmdq replication
234462583d18SSepherosa Ziehau  *  @hw: pointer to the hardware struct
234562583d18SSepherosa Ziehau  *  @enable: state to enter, either enabled or disabled
234662583d18SSepherosa Ziehau  *
234762583d18SSepherosa Ziehau  *  enables/disables replication of packets across multiple pools.
234862583d18SSepherosa Ziehau  **/
e1000_vmdq_set_replication_pf(struct e1000_hw * hw,bool enable)234962583d18SSepherosa Ziehau void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
235062583d18SSepherosa Ziehau {
235162583d18SSepherosa Ziehau 	u32 vt_ctl = E1000_READ_REG(hw, E1000_VT_CTL);
235262583d18SSepherosa Ziehau 
235362583d18SSepherosa Ziehau 	if (enable)
235462583d18SSepherosa Ziehau 		vt_ctl |= E1000_VT_CTL_VM_REPL_EN;
235562583d18SSepherosa Ziehau 	else
235662583d18SSepherosa Ziehau 		vt_ctl &= ~E1000_VT_CTL_VM_REPL_EN;
235762583d18SSepherosa Ziehau 
235862583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_VT_CTL, vt_ctl);
235962583d18SSepherosa Ziehau }
236062583d18SSepherosa Ziehau 
236162583d18SSepherosa Ziehau /**
236262583d18SSepherosa Ziehau  *  e1000_read_phy_reg_82580 - Read 82580 MDI control register
236362583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
236462583d18SSepherosa Ziehau  *  @offset: register offset to be read
236562583d18SSepherosa Ziehau  *  @data: pointer to the read data
236662583d18SSepherosa Ziehau  *
236762583d18SSepherosa Ziehau  *  Reads the MDI control register in the PHY at offset and stores the
236862583d18SSepherosa Ziehau  *  information read to data.
236962583d18SSepherosa Ziehau  **/
e1000_read_phy_reg_82580(struct e1000_hw * hw,u32 offset,u16 * data)237062583d18SSepherosa Ziehau static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data)
237162583d18SSepherosa Ziehau {
237262583d18SSepherosa Ziehau 	s32 ret_val;
237362583d18SSepherosa Ziehau 
237462583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_read_phy_reg_82580");
237562583d18SSepherosa Ziehau 
237662583d18SSepherosa Ziehau 	ret_val = hw->phy.ops.acquire(hw);
237762583d18SSepherosa Ziehau 	if (ret_val)
237862583d18SSepherosa Ziehau 		goto out;
237962583d18SSepherosa Ziehau 
238062583d18SSepherosa Ziehau 	ret_val = e1000_read_phy_reg_mdic(hw, offset, data);
238162583d18SSepherosa Ziehau 
238262583d18SSepherosa Ziehau 	hw->phy.ops.release(hw);
238362583d18SSepherosa Ziehau 
238462583d18SSepherosa Ziehau out:
238562583d18SSepherosa Ziehau 	return ret_val;
238662583d18SSepherosa Ziehau }
238762583d18SSepherosa Ziehau 
238862583d18SSepherosa Ziehau /**
238962583d18SSepherosa Ziehau  *  e1000_write_phy_reg_82580 - Write 82580 MDI control register
239062583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
239162583d18SSepherosa Ziehau  *  @offset: register offset to write to
239262583d18SSepherosa Ziehau  *  @data: data to write to register at offset
239362583d18SSepherosa Ziehau  *
239462583d18SSepherosa Ziehau  *  Writes data to MDI control register in the PHY at offset.
239562583d18SSepherosa Ziehau  **/
e1000_write_phy_reg_82580(struct e1000_hw * hw,u32 offset,u16 data)239662583d18SSepherosa Ziehau static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data)
239762583d18SSepherosa Ziehau {
239862583d18SSepherosa Ziehau 	s32 ret_val;
239962583d18SSepherosa Ziehau 
240062583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_write_phy_reg_82580");
240162583d18SSepherosa Ziehau 
240262583d18SSepherosa Ziehau 	ret_val = hw->phy.ops.acquire(hw);
240362583d18SSepherosa Ziehau 	if (ret_val)
240462583d18SSepherosa Ziehau 		goto out;
240562583d18SSepherosa Ziehau 
240662583d18SSepherosa Ziehau 	ret_val = e1000_write_phy_reg_mdic(hw, offset, data);
240762583d18SSepherosa Ziehau 
240862583d18SSepherosa Ziehau 	hw->phy.ops.release(hw);
240962583d18SSepherosa Ziehau 
241062583d18SSepherosa Ziehau out:
241162583d18SSepherosa Ziehau 	return ret_val;
241262583d18SSepherosa Ziehau }
241362583d18SSepherosa Ziehau 
241462583d18SSepherosa Ziehau /**
241562583d18SSepherosa Ziehau  *  e1000_reset_mdicnfg_82580 - Reset MDICNFG destination and com_mdio bits
241662583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
241762583d18SSepherosa Ziehau  *
241862583d18SSepherosa Ziehau  *  This resets the the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on
241962583d18SSepherosa Ziehau  *  the values found in the EEPROM.  This addresses an issue in which these
242062583d18SSepherosa Ziehau  *  bits are not restored from EEPROM after reset.
242162583d18SSepherosa Ziehau  **/
e1000_reset_mdicnfg_82580(struct e1000_hw * hw)242262583d18SSepherosa Ziehau static s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw)
242362583d18SSepherosa Ziehau {
242462583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
242562583d18SSepherosa Ziehau 	u32 mdicnfg;
242662583d18SSepherosa Ziehau 	u16 nvm_data = 0;
242762583d18SSepherosa Ziehau 
242862583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_reset_mdicnfg_82580");
242962583d18SSepherosa Ziehau 
243062583d18SSepherosa Ziehau 	if (hw->mac.type != e1000_82580)
243162583d18SSepherosa Ziehau 		goto out;
243262583d18SSepherosa Ziehau 	if (!e1000_sgmii_active_82575(hw))
243362583d18SSepherosa Ziehau 		goto out;
243462583d18SSepherosa Ziehau 
243562583d18SSepherosa Ziehau 	ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
243662583d18SSepherosa Ziehau 				   NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
243762583d18SSepherosa Ziehau 				   &nvm_data);
243862583d18SSepherosa Ziehau 	if (ret_val) {
243962583d18SSepherosa Ziehau 		DEBUGOUT("NVM Read Error\n");
244062583d18SSepherosa Ziehau 		goto out;
244162583d18SSepherosa Ziehau 	}
244262583d18SSepherosa Ziehau 
244362583d18SSepherosa Ziehau 	mdicnfg = E1000_READ_REG(hw, E1000_MDICNFG);
244462583d18SSepherosa Ziehau 	if (nvm_data & NVM_WORD24_EXT_MDIO)
244562583d18SSepherosa Ziehau 		mdicnfg |= E1000_MDICNFG_EXT_MDIO;
244662583d18SSepherosa Ziehau 	if (nvm_data & NVM_WORD24_COM_MDIO)
244762583d18SSepherosa Ziehau 		mdicnfg |= E1000_MDICNFG_COM_MDIO;
244862583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_MDICNFG, mdicnfg);
244962583d18SSepherosa Ziehau out:
245062583d18SSepherosa Ziehau 	return ret_val;
245162583d18SSepherosa Ziehau }
245262583d18SSepherosa Ziehau 
245362583d18SSepherosa Ziehau /**
245462583d18SSepherosa Ziehau  *  e1000_reset_hw_82580 - Reset hardware
245562583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
245662583d18SSepherosa Ziehau  *
245762583d18SSepherosa Ziehau  *  This resets function or entire device (all ports, etc.)
245862583d18SSepherosa Ziehau  *  to a known state.
245962583d18SSepherosa Ziehau  **/
e1000_reset_hw_82580(struct e1000_hw * hw)246062583d18SSepherosa Ziehau static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
246162583d18SSepherosa Ziehau {
246262583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
246362583d18SSepherosa Ziehau 	/* BH SW mailbox bit in SW_FW_SYNC */
246462583d18SSepherosa Ziehau 	u16 swmbsw_mask = E1000_SW_SYNCH_MB;
246562583d18SSepherosa Ziehau 	u32 ctrl;
246662583d18SSepherosa Ziehau 	bool global_device_reset = hw->dev_spec._82575.global_device_reset;
246762583d18SSepherosa Ziehau 
246862583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_reset_hw_82580");
246962583d18SSepherosa Ziehau 
247062583d18SSepherosa Ziehau 	hw->dev_spec._82575.global_device_reset = FALSE;
247162583d18SSepherosa Ziehau 
2472379ebbe7SSepherosa Ziehau 	/* 82580 does not reliably do global_device_reset due to hw errata */
2473379ebbe7SSepherosa Ziehau 	if (hw->mac.type == e1000_82580)
2474379ebbe7SSepherosa Ziehau 		global_device_reset = FALSE;
2475379ebbe7SSepherosa Ziehau 
247662583d18SSepherosa Ziehau 	/* Get current control state. */
247762583d18SSepherosa Ziehau 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
247862583d18SSepherosa Ziehau 
247962583d18SSepherosa Ziehau 	/*
248062583d18SSepherosa Ziehau 	 * Prevent the PCI-E bus from sticking if there is no TLP connection
248162583d18SSepherosa Ziehau 	 * on the last TLP read/write transaction when MAC is reset.
248262583d18SSepherosa Ziehau 	 */
248362583d18SSepherosa Ziehau 	ret_val = e1000_disable_pcie_master_generic(hw);
248462583d18SSepherosa Ziehau 	if (ret_val)
248562583d18SSepherosa Ziehau 		DEBUGOUT("PCI-E Master disable polling has failed.\n");
248662583d18SSepherosa Ziehau 
248762583d18SSepherosa Ziehau 	DEBUGOUT("Masking off all interrupts\n");
248862583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
248962583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
249062583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
249162583d18SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
249262583d18SSepherosa Ziehau 
249362583d18SSepherosa Ziehau 	msec_delay(10);
249462583d18SSepherosa Ziehau 
249562583d18SSepherosa Ziehau 	/* Determine whether or not a global dev reset is requested */
24964be59a01SSepherosa Ziehau 	if (global_device_reset && hw->mac.ops.acquire_swfw_sync(hw,
24974be59a01SSepherosa Ziehau 	    swmbsw_mask))
249862583d18SSepherosa Ziehau 			global_device_reset = FALSE;
249962583d18SSepherosa Ziehau 
25004be59a01SSepherosa Ziehau 	if (global_device_reset && !(E1000_READ_REG(hw, E1000_STATUS) &
25014be59a01SSepherosa Ziehau 	    E1000_STAT_DEV_RST_SET))
250262583d18SSepherosa Ziehau 		ctrl |= E1000_CTRL_DEV_RST;
250362583d18SSepherosa Ziehau 	else
250462583d18SSepherosa Ziehau 		ctrl |= E1000_CTRL_RST;
250562583d18SSepherosa Ziehau 
250662583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
250762583d18SSepherosa Ziehau 
2508ba0123e0SSepherosa Ziehau 	switch (hw->device_id) {
2509ba0123e0SSepherosa Ziehau 	case E1000_DEV_ID_DH89XXCC_SGMII:
2510ba0123e0SSepherosa Ziehau 		break;
2511ba0123e0SSepherosa Ziehau 	default:
2512ba0123e0SSepherosa Ziehau 		E1000_WRITE_FLUSH(hw);
2513ba0123e0SSepherosa Ziehau 		break;
2514ba0123e0SSepherosa Ziehau 	}
2515ba0123e0SSepherosa Ziehau 
2516ba0123e0SSepherosa Ziehau 	/* Add delay to insure DEV_RST or RST has time to complete */
251762583d18SSepherosa Ziehau 	msec_delay(5);
251862583d18SSepherosa Ziehau 
251962583d18SSepherosa Ziehau 	ret_val = e1000_get_auto_rd_done_generic(hw);
252062583d18SSepherosa Ziehau 	if (ret_val) {
252162583d18SSepherosa Ziehau 		/*
252262583d18SSepherosa Ziehau 		 * When auto config read does not complete, do not
252362583d18SSepherosa Ziehau 		 * return with an error. This can happen in situations
252462583d18SSepherosa Ziehau 		 * where there is no eeprom and prevents getting link.
252562583d18SSepherosa Ziehau 		 */
252662583d18SSepherosa Ziehau 		DEBUGOUT("Auto Read Done did not complete\n");
252762583d18SSepherosa Ziehau 	}
252862583d18SSepherosa Ziehau 
252962583d18SSepherosa Ziehau 	/* clear global device reset status bit */
253062583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_STATUS, E1000_STAT_DEV_RST_SET);
253162583d18SSepherosa Ziehau 
253262583d18SSepherosa Ziehau 	/* Clear any pending interrupt events. */
253362583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
253462583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_ICR);
253562583d18SSepherosa Ziehau 
253662583d18SSepherosa Ziehau 	ret_val = e1000_reset_mdicnfg_82580(hw);
253762583d18SSepherosa Ziehau 	if (ret_val)
253862583d18SSepherosa Ziehau 		DEBUGOUT("Could not reset MDICNFG based on EEPROM\n");
253962583d18SSepherosa Ziehau 
254062583d18SSepherosa Ziehau 	/* Install any alternate MAC address into RAR0 */
254162583d18SSepherosa Ziehau 	ret_val = e1000_check_alt_mac_addr_generic(hw);
254262583d18SSepherosa Ziehau 
254362583d18SSepherosa Ziehau 	/* Release semaphore */
254462583d18SSepherosa Ziehau 	if (global_device_reset)
25454be59a01SSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, swmbsw_mask);
254662583d18SSepherosa Ziehau 
254762583d18SSepherosa Ziehau 	return ret_val;
254862583d18SSepherosa Ziehau }
254962583d18SSepherosa Ziehau 
255062583d18SSepherosa Ziehau /**
255162583d18SSepherosa Ziehau  *  e1000_rxpbs_adjust_82580 - adjust RXPBS value to reflect actual Rx PBA size
255262583d18SSepherosa Ziehau  *  @data: data received by reading RXPBS register
255362583d18SSepherosa Ziehau  *
255462583d18SSepherosa Ziehau  *  The 82580 uses a table based approach for packet buffer allocation sizes.
255562583d18SSepherosa Ziehau  *  This function converts the retrieved value into the correct table value
255662583d18SSepherosa Ziehau  *     0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
255762583d18SSepherosa Ziehau  *  0x0 36  72 144   1   2   4   8  16
255862583d18SSepherosa Ziehau  *  0x8 35  70 140 rsv rsv rsv rsv rsv
255962583d18SSepherosa Ziehau  */
e1000_rxpbs_adjust_82580(u32 data)256062583d18SSepherosa Ziehau u16 e1000_rxpbs_adjust_82580(u32 data)
256162583d18SSepherosa Ziehau {
256262583d18SSepherosa Ziehau 	u16 ret_val = 0;
256362583d18SSepherosa Ziehau 
256462583d18SSepherosa Ziehau 	if (data < E1000_82580_RXPBS_TABLE_SIZE)
256562583d18SSepherosa Ziehau 		ret_val = e1000_82580_rxpbs_table[data];
256662583d18SSepherosa Ziehau 
256762583d18SSepherosa Ziehau 	return ret_val;
256862583d18SSepherosa Ziehau }
256962583d18SSepherosa Ziehau 
257062583d18SSepherosa Ziehau /**
257162583d18SSepherosa Ziehau  *  e1000_validate_nvm_checksum_with_offset - Validate EEPROM
257262583d18SSepherosa Ziehau  *  checksum
257362583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
257462583d18SSepherosa Ziehau  *  @offset: offset in words of the checksum protected region
257562583d18SSepherosa Ziehau  *
257662583d18SSepherosa Ziehau  *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
257762583d18SSepherosa Ziehau  *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
257862583d18SSepherosa Ziehau  **/
e1000_validate_nvm_checksum_with_offset(struct e1000_hw * hw,u16 offset)257962583d18SSepherosa Ziehau s32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset)
258062583d18SSepherosa Ziehau {
258162583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
258262583d18SSepherosa Ziehau 	u16 checksum = 0;
258362583d18SSepherosa Ziehau 	u16 i, nvm_data;
258462583d18SSepherosa Ziehau 
258562583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_validate_nvm_checksum_with_offset");
258662583d18SSepherosa Ziehau 
258762583d18SSepherosa Ziehau 	for (i = offset; i < ((NVM_CHECKSUM_REG + offset) + 1); i++) {
258862583d18SSepherosa Ziehau 		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
258962583d18SSepherosa Ziehau 		if (ret_val) {
259062583d18SSepherosa Ziehau 			DEBUGOUT("NVM Read Error\n");
259162583d18SSepherosa Ziehau 			goto out;
259262583d18SSepherosa Ziehau 		}
259362583d18SSepherosa Ziehau 		checksum += nvm_data;
259462583d18SSepherosa Ziehau 	}
259562583d18SSepherosa Ziehau 
259662583d18SSepherosa Ziehau 	if (checksum != (u16) NVM_SUM) {
259762583d18SSepherosa Ziehau 		DEBUGOUT("NVM Checksum Invalid\n");
259862583d18SSepherosa Ziehau 		ret_val = -E1000_ERR_NVM;
259962583d18SSepherosa Ziehau 		goto out;
260062583d18SSepherosa Ziehau 	}
260162583d18SSepherosa Ziehau 
260262583d18SSepherosa Ziehau out:
260362583d18SSepherosa Ziehau 	return ret_val;
260462583d18SSepherosa Ziehau }
260562583d18SSepherosa Ziehau 
260662583d18SSepherosa Ziehau /**
260762583d18SSepherosa Ziehau  *  e1000_update_nvm_checksum_with_offset - Update EEPROM
260862583d18SSepherosa Ziehau  *  checksum
260962583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
261062583d18SSepherosa Ziehau  *  @offset: offset in words of the checksum protected region
261162583d18SSepherosa Ziehau  *
261262583d18SSepherosa Ziehau  *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
261362583d18SSepherosa Ziehau  *  up to the checksum.  Then calculates the EEPROM checksum and writes the
261462583d18SSepherosa Ziehau  *  value to the EEPROM.
261562583d18SSepherosa Ziehau  **/
e1000_update_nvm_checksum_with_offset(struct e1000_hw * hw,u16 offset)261662583d18SSepherosa Ziehau s32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset)
261762583d18SSepherosa Ziehau {
261862583d18SSepherosa Ziehau 	s32 ret_val;
261962583d18SSepherosa Ziehau 	u16 checksum = 0;
262062583d18SSepherosa Ziehau 	u16 i, nvm_data;
262162583d18SSepherosa Ziehau 
262262583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_update_nvm_checksum_with_offset");
262362583d18SSepherosa Ziehau 
262462583d18SSepherosa Ziehau 	for (i = offset; i < (NVM_CHECKSUM_REG + offset); i++) {
262562583d18SSepherosa Ziehau 		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
262662583d18SSepherosa Ziehau 		if (ret_val) {
262762583d18SSepherosa Ziehau 			DEBUGOUT("NVM Read Error while updating checksum.\n");
262862583d18SSepherosa Ziehau 			goto out;
262962583d18SSepherosa Ziehau 		}
263062583d18SSepherosa Ziehau 		checksum += nvm_data;
263162583d18SSepherosa Ziehau 	}
263262583d18SSepherosa Ziehau 	checksum = (u16) NVM_SUM - checksum;
263362583d18SSepherosa Ziehau 	ret_val = hw->nvm.ops.write(hw, (NVM_CHECKSUM_REG + offset), 1,
263462583d18SSepherosa Ziehau 				    &checksum);
263562583d18SSepherosa Ziehau 	if (ret_val)
263662583d18SSepherosa Ziehau 		DEBUGOUT("NVM Write Error while updating checksum.\n");
263762583d18SSepherosa Ziehau 
263862583d18SSepherosa Ziehau out:
263962583d18SSepherosa Ziehau 	return ret_val;
264062583d18SSepherosa Ziehau }
264162583d18SSepherosa Ziehau 
264262583d18SSepherosa Ziehau /**
264362583d18SSepherosa Ziehau  *  e1000_validate_nvm_checksum_82580 - Validate EEPROM checksum
264462583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
264562583d18SSepherosa Ziehau  *
264662583d18SSepherosa Ziehau  *  Calculates the EEPROM section checksum by reading/adding each word of
264762583d18SSepherosa Ziehau  *  the EEPROM and then verifies that the sum of the EEPROM is
264862583d18SSepherosa Ziehau  *  equal to 0xBABA.
264962583d18SSepherosa Ziehau  **/
e1000_validate_nvm_checksum_82580(struct e1000_hw * hw)265062583d18SSepherosa Ziehau static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw)
265162583d18SSepherosa Ziehau {
2652ba0123e0SSepherosa Ziehau 	s32 ret_val;
265362583d18SSepherosa Ziehau 	u16 eeprom_regions_count = 1;
265462583d18SSepherosa Ziehau 	u16 j, nvm_data;
265562583d18SSepherosa Ziehau 	u16 nvm_offset;
265662583d18SSepherosa Ziehau 
265762583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_validate_nvm_checksum_82580");
265862583d18SSepherosa Ziehau 
265962583d18SSepherosa Ziehau 	ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data);
266062583d18SSepherosa Ziehau 	if (ret_val) {
266162583d18SSepherosa Ziehau 		DEBUGOUT("NVM Read Error\n");
266262583d18SSepherosa Ziehau 		goto out;
266362583d18SSepherosa Ziehau 	}
266462583d18SSepherosa Ziehau 
266562583d18SSepherosa Ziehau 	if (nvm_data & NVM_COMPATIBILITY_BIT_MASK) {
266662583d18SSepherosa Ziehau 		/* if chekcsums compatibility bit is set validate checksums
266762583d18SSepherosa Ziehau 		 * for all 4 ports. */
266862583d18SSepherosa Ziehau 		eeprom_regions_count = 4;
266962583d18SSepherosa Ziehau 	}
267062583d18SSepherosa Ziehau 
267162583d18SSepherosa Ziehau 	for (j = 0; j < eeprom_regions_count; j++) {
267262583d18SSepherosa Ziehau 		nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
267362583d18SSepherosa Ziehau 		ret_val = e1000_validate_nvm_checksum_with_offset(hw,
267462583d18SSepherosa Ziehau 								  nvm_offset);
267562583d18SSepherosa Ziehau 		if (ret_val != E1000_SUCCESS)
267662583d18SSepherosa Ziehau 			goto out;
267762583d18SSepherosa Ziehau 	}
267862583d18SSepherosa Ziehau 
267962583d18SSepherosa Ziehau out:
268062583d18SSepherosa Ziehau 	return ret_val;
268162583d18SSepherosa Ziehau }
268262583d18SSepherosa Ziehau 
268362583d18SSepherosa Ziehau /**
268462583d18SSepherosa Ziehau  *  e1000_update_nvm_checksum_82580 - Update EEPROM checksum
268562583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
268662583d18SSepherosa Ziehau  *
268762583d18SSepherosa Ziehau  *  Updates the EEPROM section checksums for all 4 ports by reading/adding
268862583d18SSepherosa Ziehau  *  each word of the EEPROM up to the checksum.  Then calculates the EEPROM
268962583d18SSepherosa Ziehau  *  checksum and writes the value to the EEPROM.
269062583d18SSepherosa Ziehau  **/
e1000_update_nvm_checksum_82580(struct e1000_hw * hw)269162583d18SSepherosa Ziehau static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw)
269262583d18SSepherosa Ziehau {
269362583d18SSepherosa Ziehau 	s32 ret_val;
269462583d18SSepherosa Ziehau 	u16 j, nvm_data;
269562583d18SSepherosa Ziehau 	u16 nvm_offset;
269662583d18SSepherosa Ziehau 
269762583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_update_nvm_checksum_82580");
269862583d18SSepherosa Ziehau 
269962583d18SSepherosa Ziehau 	ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data);
270062583d18SSepherosa Ziehau 	if (ret_val) {
27014be59a01SSepherosa Ziehau 		DEBUGOUT("NVM Read Error while updating checksum compatibility bit.\n");
270262583d18SSepherosa Ziehau 		goto out;
270362583d18SSepherosa Ziehau 	}
270462583d18SSepherosa Ziehau 
27054be59a01SSepherosa Ziehau 	if (!(nvm_data & NVM_COMPATIBILITY_BIT_MASK)) {
270662583d18SSepherosa Ziehau 		/* set compatibility bit to validate checksums appropriately */
270762583d18SSepherosa Ziehau 		nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK;
270862583d18SSepherosa Ziehau 		ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1,
270962583d18SSepherosa Ziehau 					    &nvm_data);
271062583d18SSepherosa Ziehau 		if (ret_val) {
27114be59a01SSepherosa Ziehau 			DEBUGOUT("NVM Write Error while updating checksum compatibility bit.\n");
271262583d18SSepherosa Ziehau 			goto out;
271362583d18SSepherosa Ziehau 		}
271462583d18SSepherosa Ziehau 	}
271562583d18SSepherosa Ziehau 
271662583d18SSepherosa Ziehau 	for (j = 0; j < 4; j++) {
271762583d18SSepherosa Ziehau 		nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
271862583d18SSepherosa Ziehau 		ret_val = e1000_update_nvm_checksum_with_offset(hw, nvm_offset);
27194be59a01SSepherosa Ziehau 		if (ret_val)
272062583d18SSepherosa Ziehau 			goto out;
272162583d18SSepherosa Ziehau 	}
272262583d18SSepherosa Ziehau 
272362583d18SSepherosa Ziehau out:
272462583d18SSepherosa Ziehau 	return ret_val;
272562583d18SSepherosa Ziehau }
272662583d18SSepherosa Ziehau 
272762583d18SSepherosa Ziehau /**
272862583d18SSepherosa Ziehau  *  e1000_validate_nvm_checksum_i350 - Validate EEPROM checksum
272962583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
273062583d18SSepherosa Ziehau  *
273162583d18SSepherosa Ziehau  *  Calculates the EEPROM section checksum by reading/adding each word of
273262583d18SSepherosa Ziehau  *  the EEPROM and then verifies that the sum of the EEPROM is
273362583d18SSepherosa Ziehau  *  equal to 0xBABA.
273462583d18SSepherosa Ziehau  **/
e1000_validate_nvm_checksum_i350(struct e1000_hw * hw)273562583d18SSepherosa Ziehau static s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw)
273662583d18SSepherosa Ziehau {
273762583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
273862583d18SSepherosa Ziehau 	u16 j;
273962583d18SSepherosa Ziehau 	u16 nvm_offset;
274062583d18SSepherosa Ziehau 
274162583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_validate_nvm_checksum_i350");
274262583d18SSepherosa Ziehau 
274362583d18SSepherosa Ziehau 	for (j = 0; j < 4; j++) {
274462583d18SSepherosa Ziehau 		nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
274562583d18SSepherosa Ziehau 		ret_val = e1000_validate_nvm_checksum_with_offset(hw,
274662583d18SSepherosa Ziehau 								  nvm_offset);
274762583d18SSepherosa Ziehau 		if (ret_val != E1000_SUCCESS)
274862583d18SSepherosa Ziehau 			goto out;
274962583d18SSepherosa Ziehau 	}
275062583d18SSepherosa Ziehau 
275162583d18SSepherosa Ziehau out:
275262583d18SSepherosa Ziehau 	return ret_val;
275362583d18SSepherosa Ziehau }
275462583d18SSepherosa Ziehau 
275562583d18SSepherosa Ziehau /**
275662583d18SSepherosa Ziehau  *  e1000_update_nvm_checksum_i350 - Update EEPROM checksum
275762583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
275862583d18SSepherosa Ziehau  *
275962583d18SSepherosa Ziehau  *  Updates the EEPROM section checksums for all 4 ports by reading/adding
276062583d18SSepherosa Ziehau  *  each word of the EEPROM up to the checksum.  Then calculates the EEPROM
276162583d18SSepherosa Ziehau  *  checksum and writes the value to the EEPROM.
276262583d18SSepherosa Ziehau  **/
e1000_update_nvm_checksum_i350(struct e1000_hw * hw)276362583d18SSepherosa Ziehau static s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw)
276462583d18SSepherosa Ziehau {
276562583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
276662583d18SSepherosa Ziehau 	u16 j;
276762583d18SSepherosa Ziehau 	u16 nvm_offset;
276862583d18SSepherosa Ziehau 
276962583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_update_nvm_checksum_i350");
277062583d18SSepherosa Ziehau 
277162583d18SSepherosa Ziehau 	for (j = 0; j < 4; j++) {
277262583d18SSepherosa Ziehau 		nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
277362583d18SSepherosa Ziehau 		ret_val = e1000_update_nvm_checksum_with_offset(hw, nvm_offset);
277462583d18SSepherosa Ziehau 		if (ret_val != E1000_SUCCESS)
277562583d18SSepherosa Ziehau 			goto out;
277662583d18SSepherosa Ziehau 	}
277762583d18SSepherosa Ziehau 
277862583d18SSepherosa Ziehau out:
277962583d18SSepherosa Ziehau 	return ret_val;
278062583d18SSepherosa Ziehau }
278162583d18SSepherosa Ziehau 
278262583d18SSepherosa Ziehau /**
2783379ebbe7SSepherosa Ziehau  *  __e1000_access_emi_reg - Read/write EMI register
2784379ebbe7SSepherosa Ziehau  *  @hw: pointer to the HW structure
2785379ebbe7SSepherosa Ziehau  *  @addr: EMI address to program
2786379ebbe7SSepherosa Ziehau  *  @data: pointer to value to read/write from/to the EMI address
2787379ebbe7SSepherosa Ziehau  *  @read: boolean flag to indicate read or write
2788379ebbe7SSepherosa Ziehau  **/
__e1000_access_emi_reg(struct e1000_hw * hw,u16 address,u16 * data,bool read)2789379ebbe7SSepherosa Ziehau static s32 __e1000_access_emi_reg(struct e1000_hw *hw, u16 address,
2790379ebbe7SSepherosa Ziehau 				  u16 *data, bool read)
2791379ebbe7SSepherosa Ziehau {
2792ba0123e0SSepherosa Ziehau 	s32 ret_val;
2793379ebbe7SSepherosa Ziehau 
2794379ebbe7SSepherosa Ziehau 	DEBUGFUNC("__e1000_access_emi_reg");
2795379ebbe7SSepherosa Ziehau 
2796379ebbe7SSepherosa Ziehau 	ret_val = hw->phy.ops.write_reg(hw, E1000_EMIADD, address);
2797379ebbe7SSepherosa Ziehau 	if (ret_val)
2798379ebbe7SSepherosa Ziehau 		return ret_val;
2799379ebbe7SSepherosa Ziehau 
2800379ebbe7SSepherosa Ziehau 	if (read)
2801379ebbe7SSepherosa Ziehau 		ret_val = hw->phy.ops.read_reg(hw, E1000_EMIDATA, data);
2802379ebbe7SSepherosa Ziehau 	else
2803379ebbe7SSepherosa Ziehau 		ret_val = hw->phy.ops.write_reg(hw, E1000_EMIDATA, *data);
2804379ebbe7SSepherosa Ziehau 
2805379ebbe7SSepherosa Ziehau 	return ret_val;
2806379ebbe7SSepherosa Ziehau }
2807379ebbe7SSepherosa Ziehau 
2808379ebbe7SSepherosa Ziehau /**
2809379ebbe7SSepherosa Ziehau  *  e1000_read_emi_reg - Read Extended Management Interface register
2810379ebbe7SSepherosa Ziehau  *  @hw: pointer to the HW structure
2811379ebbe7SSepherosa Ziehau  *  @addr: EMI address to program
2812379ebbe7SSepherosa Ziehau  *  @data: value to be read from the EMI address
2813379ebbe7SSepherosa Ziehau  **/
e1000_read_emi_reg(struct e1000_hw * hw,u16 addr,u16 * data)2814379ebbe7SSepherosa Ziehau s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data)
2815379ebbe7SSepherosa Ziehau {
2816379ebbe7SSepherosa Ziehau 	DEBUGFUNC("e1000_read_emi_reg");
2817379ebbe7SSepherosa Ziehau 
2818379ebbe7SSepherosa Ziehau 	return __e1000_access_emi_reg(hw, addr, data, TRUE);
2819379ebbe7SSepherosa Ziehau }
2820379ebbe7SSepherosa Ziehau 
2821379ebbe7SSepherosa Ziehau /**
2822ba0123e0SSepherosa Ziehau  *  e1000_initialize_M88E1512_phy - Initialize M88E1512 PHY
2823ba0123e0SSepherosa Ziehau  *  @hw: pointer to the HW structure
2824ba0123e0SSepherosa Ziehau  *
2825a40fda39SSepherosa Ziehau  *  Initialize Marvell 1512 to work correctly with Avoton.
2826ba0123e0SSepherosa Ziehau  **/
e1000_initialize_M88E1512_phy(struct e1000_hw * hw)2827ba0123e0SSepherosa Ziehau s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw)
2828ba0123e0SSepherosa Ziehau {
2829ba0123e0SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
2830ba0123e0SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
2831ba0123e0SSepherosa Ziehau 
2832ba0123e0SSepherosa Ziehau 	DEBUGFUNC("e1000_initialize_M88E1512_phy");
2833ba0123e0SSepherosa Ziehau 
2834ba0123e0SSepherosa Ziehau 	/* Check if this is correct PHY. */
2835ba0123e0SSepherosa Ziehau 	if (phy->id != M88E1512_E_PHY_ID)
2836ba0123e0SSepherosa Ziehau 		goto out;
2837ba0123e0SSepherosa Ziehau 
2838ba0123e0SSepherosa Ziehau 	/* Switch to PHY page 0xFF. */
2839ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
2840ba0123e0SSepherosa Ziehau 	if (ret_val)
2841ba0123e0SSepherosa Ziehau 		goto out;
2842ba0123e0SSepherosa Ziehau 
2843ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
2844ba0123e0SSepherosa Ziehau 	if (ret_val)
2845ba0123e0SSepherosa Ziehau 		goto out;
2846ba0123e0SSepherosa Ziehau 
2847ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
2848ba0123e0SSepherosa Ziehau 	if (ret_val)
2849ba0123e0SSepherosa Ziehau 		goto out;
2850ba0123e0SSepherosa Ziehau 
2851ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
2852ba0123e0SSepherosa Ziehau 	if (ret_val)
2853ba0123e0SSepherosa Ziehau 		goto out;
2854ba0123e0SSepherosa Ziehau 
2855ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
2856ba0123e0SSepherosa Ziehau 	if (ret_val)
2857ba0123e0SSepherosa Ziehau 		goto out;
2858ba0123e0SSepherosa Ziehau 
2859ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
2860ba0123e0SSepherosa Ziehau 	if (ret_val)
2861ba0123e0SSepherosa Ziehau 		goto out;
2862ba0123e0SSepherosa Ziehau 
2863ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
2864ba0123e0SSepherosa Ziehau 	if (ret_val)
2865ba0123e0SSepherosa Ziehau 		goto out;
2866ba0123e0SSepherosa Ziehau 
2867ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xCC0C);
2868ba0123e0SSepherosa Ziehau 	if (ret_val)
2869ba0123e0SSepherosa Ziehau 		goto out;
2870ba0123e0SSepherosa Ziehau 
2871ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
2872ba0123e0SSepherosa Ziehau 	if (ret_val)
2873ba0123e0SSepherosa Ziehau 		goto out;
2874ba0123e0SSepherosa Ziehau 
2875ba0123e0SSepherosa Ziehau 	/* Switch to PHY page 0xFB. */
2876ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
2877ba0123e0SSepherosa Ziehau 	if (ret_val)
2878ba0123e0SSepherosa Ziehau 		goto out;
2879ba0123e0SSepherosa Ziehau 
2880ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0x000D);
2881ba0123e0SSepherosa Ziehau 	if (ret_val)
2882ba0123e0SSepherosa Ziehau 		goto out;
2883ba0123e0SSepherosa Ziehau 
2884ba0123e0SSepherosa Ziehau 	/* Switch to PHY page 0x12. */
2885ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
2886ba0123e0SSepherosa Ziehau 	if (ret_val)
2887ba0123e0SSepherosa Ziehau 		goto out;
2888ba0123e0SSepherosa Ziehau 
2889ba0123e0SSepherosa Ziehau 	/* Change mode to SGMII-to-Copper */
2890ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
2891ba0123e0SSepherosa Ziehau 	if (ret_val)
2892ba0123e0SSepherosa Ziehau 		goto out;
2893ba0123e0SSepherosa Ziehau 
2894ba0123e0SSepherosa Ziehau 	/* Return the PHY to page 0. */
2895ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
2896ba0123e0SSepherosa Ziehau 	if (ret_val)
2897ba0123e0SSepherosa Ziehau 		goto out;
2898ba0123e0SSepherosa Ziehau 
2899ba0123e0SSepherosa Ziehau 	ret_val = phy->ops.commit(hw);
2900ba0123e0SSepherosa Ziehau 	if (ret_val) {
2901ba0123e0SSepherosa Ziehau 		DEBUGOUT("Error committing the PHY changes\n");
2902ba0123e0SSepherosa Ziehau 		return ret_val;
2903ba0123e0SSepherosa Ziehau 	}
2904ba0123e0SSepherosa Ziehau 
2905ba0123e0SSepherosa Ziehau 	msec_delay(1000);
2906ba0123e0SSepherosa Ziehau out:
2907ba0123e0SSepherosa Ziehau 	return ret_val;
2908ba0123e0SSepherosa Ziehau }
2909ba0123e0SSepherosa Ziehau 
2910ba0123e0SSepherosa Ziehau /**
2911a40fda39SSepherosa Ziehau  *  e1000_initialize_M88E1543_phy - Initialize M88E1543 PHY
2912a40fda39SSepherosa Ziehau  *  @hw: pointer to the HW structure
2913a40fda39SSepherosa Ziehau  *
2914a40fda39SSepherosa Ziehau  *  Initialize Marvell 1543 to work correctly with Avoton.
2915a40fda39SSepherosa Ziehau  **/
e1000_initialize_M88E1543_phy(struct e1000_hw * hw)2916a40fda39SSepherosa Ziehau s32 e1000_initialize_M88E1543_phy(struct e1000_hw *hw)
2917a40fda39SSepherosa Ziehau {
2918a40fda39SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
2919a40fda39SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
2920a40fda39SSepherosa Ziehau 
2921a40fda39SSepherosa Ziehau 	DEBUGFUNC("e1000_initialize_M88E1543_phy");
2922a40fda39SSepherosa Ziehau 
2923a40fda39SSepherosa Ziehau 	/* Check if this is correct PHY. */
2924a40fda39SSepherosa Ziehau 	if (phy->id != M88E1543_E_PHY_ID)
2925a40fda39SSepherosa Ziehau 		goto out;
2926a40fda39SSepherosa Ziehau 
2927a40fda39SSepherosa Ziehau 	/* Switch to PHY page 0xFF. */
2928a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
2929a40fda39SSepherosa Ziehau 	if (ret_val)
2930a40fda39SSepherosa Ziehau 		goto out;
2931a40fda39SSepherosa Ziehau 
2932a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
2933a40fda39SSepherosa Ziehau 	if (ret_val)
2934a40fda39SSepherosa Ziehau 		goto out;
2935a40fda39SSepherosa Ziehau 
2936a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
2937a40fda39SSepherosa Ziehau 	if (ret_val)
2938a40fda39SSepherosa Ziehau 		goto out;
2939a40fda39SSepherosa Ziehau 
2940a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
2941a40fda39SSepherosa Ziehau 	if (ret_val)
2942a40fda39SSepherosa Ziehau 		goto out;
2943a40fda39SSepherosa Ziehau 
2944a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
2945a40fda39SSepherosa Ziehau 	if (ret_val)
2946a40fda39SSepherosa Ziehau 		goto out;
2947a40fda39SSepherosa Ziehau 
2948a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
2949a40fda39SSepherosa Ziehau 	if (ret_val)
2950a40fda39SSepherosa Ziehau 		goto out;
2951a40fda39SSepherosa Ziehau 
2952a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
2953a40fda39SSepherosa Ziehau 	if (ret_val)
2954a40fda39SSepherosa Ziehau 		goto out;
2955a40fda39SSepherosa Ziehau 
2956a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xDC0C);
2957a40fda39SSepherosa Ziehau 	if (ret_val)
2958a40fda39SSepherosa Ziehau 		goto out;
2959a40fda39SSepherosa Ziehau 
2960a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
2961a40fda39SSepherosa Ziehau 	if (ret_val)
2962a40fda39SSepherosa Ziehau 		goto out;
2963a40fda39SSepherosa Ziehau 
2964a40fda39SSepherosa Ziehau 	/* Switch to PHY page 0xFB. */
2965a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
2966a40fda39SSepherosa Ziehau 	if (ret_val)
2967a40fda39SSepherosa Ziehau 		goto out;
2968a40fda39SSepherosa Ziehau 
2969a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0xC00D);
2970a40fda39SSepherosa Ziehau 	if (ret_val)
2971a40fda39SSepherosa Ziehau 		goto out;
2972a40fda39SSepherosa Ziehau 
2973a40fda39SSepherosa Ziehau 	/* Switch to PHY page 0x12. */
2974a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
2975a40fda39SSepherosa Ziehau 	if (ret_val)
2976a40fda39SSepherosa Ziehau 		goto out;
2977a40fda39SSepherosa Ziehau 
2978a40fda39SSepherosa Ziehau 	/* Change mode to SGMII-to-Copper */
2979a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
2980a40fda39SSepherosa Ziehau 	if (ret_val)
2981a40fda39SSepherosa Ziehau 		goto out;
2982a40fda39SSepherosa Ziehau 
2983a40fda39SSepherosa Ziehau 	/* Switch to PHY page 1. */
2984a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x1);
2985a40fda39SSepherosa Ziehau 	if (ret_val)
2986a40fda39SSepherosa Ziehau 		goto out;
2987a40fda39SSepherosa Ziehau 
2988a40fda39SSepherosa Ziehau 	/* Change mode to 1000BASE-X/SGMII and autoneg enable; reset */
2989a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_FIBER_CTRL, 0x9140);
2990a40fda39SSepherosa Ziehau 	if (ret_val)
2991a40fda39SSepherosa Ziehau 		goto out;
2992a40fda39SSepherosa Ziehau 
2993a40fda39SSepherosa Ziehau 	/* Return the PHY to page 0. */
2994a40fda39SSepherosa Ziehau 	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
2995a40fda39SSepherosa Ziehau 	if (ret_val)
2996a40fda39SSepherosa Ziehau 		goto out;
2997a40fda39SSepherosa Ziehau 
2998a40fda39SSepherosa Ziehau 	ret_val = phy->ops.commit(hw);
2999a40fda39SSepherosa Ziehau 	if (ret_val) {
3000a40fda39SSepherosa Ziehau 		DEBUGOUT("Error committing the PHY changes\n");
3001a40fda39SSepherosa Ziehau 		return ret_val;
3002a40fda39SSepherosa Ziehau 	}
3003a40fda39SSepherosa Ziehau 
3004a40fda39SSepherosa Ziehau 	msec_delay(1000);
3005a40fda39SSepherosa Ziehau out:
3006a40fda39SSepherosa Ziehau 	return ret_val;
3007a40fda39SSepherosa Ziehau }
3008a40fda39SSepherosa Ziehau 
3009a40fda39SSepherosa Ziehau /**
301062583d18SSepherosa Ziehau  *  e1000_set_eee_i350 - Enable/disable EEE support
301162583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
3012ba0123e0SSepherosa Ziehau  *  @adv1g: boolean flag enabling 1G EEE advertisement
3013ba0123e0SSepherosa Ziehau  *  @adv100m: boolean flag enabling 100M EEE advertisement
301462583d18SSepherosa Ziehau  *
301562583d18SSepherosa Ziehau  *  Enable/disable EEE based on setting in dev_spec structure.
301662583d18SSepherosa Ziehau  *
301762583d18SSepherosa Ziehau  **/
e1000_set_eee_i350(struct e1000_hw * hw,bool adv1G,bool adv100M)3018ba0123e0SSepherosa Ziehau s32 e1000_set_eee_i350(struct e1000_hw *hw, bool adv1G, bool adv100M)
301962583d18SSepherosa Ziehau {
30204be59a01SSepherosa Ziehau 	u32 ipcnfg, eeer;
302162583d18SSepherosa Ziehau 
302262583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_set_eee_i350");
302362583d18SSepherosa Ziehau 
30244be59a01SSepherosa Ziehau 	if ((hw->mac.type < e1000_i350) ||
30254be59a01SSepherosa Ziehau 	    (hw->phy.media_type != e1000_media_type_copper))
302662583d18SSepherosa Ziehau 		goto out;
302762583d18SSepherosa Ziehau 	ipcnfg = E1000_READ_REG(hw, E1000_IPCNFG);
302862583d18SSepherosa Ziehau 	eeer = E1000_READ_REG(hw, E1000_EEER);
302962583d18SSepherosa Ziehau 
303062583d18SSepherosa Ziehau 	/* enable or disable per user setting */
303162583d18SSepherosa Ziehau 	if (!(hw->dev_spec._82575.eee_disable)) {
3032379ebbe7SSepherosa Ziehau 		u32 eee_su = E1000_READ_REG(hw, E1000_EEE_SU);
3033379ebbe7SSepherosa Ziehau 
3034ba0123e0SSepherosa Ziehau 		if (adv100M)
3035ba0123e0SSepherosa Ziehau 			ipcnfg |= E1000_IPCNFG_EEE_100M_AN;
3036ba0123e0SSepherosa Ziehau 		else
3037ba0123e0SSepherosa Ziehau 			ipcnfg &= ~E1000_IPCNFG_EEE_100M_AN;
3038ba0123e0SSepherosa Ziehau 
3039ba0123e0SSepherosa Ziehau 		if (adv1G)
3040ba0123e0SSepherosa Ziehau 			ipcnfg |= E1000_IPCNFG_EEE_1G_AN;
3041ba0123e0SSepherosa Ziehau 		else
3042ba0123e0SSepherosa Ziehau 			ipcnfg &= ~E1000_IPCNFG_EEE_1G_AN;
3043ba0123e0SSepherosa Ziehau 
30444be59a01SSepherosa Ziehau 		eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
304562583d18SSepherosa Ziehau 			 E1000_EEER_LPI_FC);
304662583d18SSepherosa Ziehau 
3047379ebbe7SSepherosa Ziehau 		/* This bit should not be set in normal operation. */
3048379ebbe7SSepherosa Ziehau 		if (eee_su & E1000_EEE_SU_LPI_CLK_STP)
3049379ebbe7SSepherosa Ziehau 			DEBUGOUT("LPI Clock Stop Bit should not be set!\n");
305062583d18SSepherosa Ziehau 	} else {
30514be59a01SSepherosa Ziehau 		ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
30524be59a01SSepherosa Ziehau 		eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
305362583d18SSepherosa Ziehau 			  E1000_EEER_LPI_FC);
305462583d18SSepherosa Ziehau 	}
305562583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_IPCNFG, ipcnfg);
305662583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_EEER, eeer);
305762583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_IPCNFG);
305862583d18SSepherosa Ziehau 	E1000_READ_REG(hw, E1000_EEER);
305962583d18SSepherosa Ziehau out:
306062583d18SSepherosa Ziehau 
3061ba0123e0SSepherosa Ziehau 	return E1000_SUCCESS;
306262583d18SSepherosa Ziehau }
30634be59a01SSepherosa Ziehau 
3064379ebbe7SSepherosa Ziehau /**
3065379ebbe7SSepherosa Ziehau  *  e1000_set_eee_i354 - Enable/disable EEE support
3066379ebbe7SSepherosa Ziehau  *  @hw: pointer to the HW structure
3067ba0123e0SSepherosa Ziehau  *  @adv1g: boolean flag enabling 1G EEE advertisement
3068ba0123e0SSepherosa Ziehau  *  @adv100m: boolean flag enabling 100M EEE advertisement
3069379ebbe7SSepherosa Ziehau  *
3070379ebbe7SSepherosa Ziehau  *  Enable/disable EEE legacy mode based on setting in dev_spec structure.
3071379ebbe7SSepherosa Ziehau  *
3072379ebbe7SSepherosa Ziehau  **/
e1000_set_eee_i354(struct e1000_hw * hw,bool adv1G,bool adv100M)3073ba0123e0SSepherosa Ziehau s32 e1000_set_eee_i354(struct e1000_hw *hw, bool adv1G, bool adv100M)
3074379ebbe7SSepherosa Ziehau {
3075379ebbe7SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
3076379ebbe7SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
3077379ebbe7SSepherosa Ziehau 	u16 phy_data;
3078379ebbe7SSepherosa Ziehau 
3079379ebbe7SSepherosa Ziehau 	DEBUGFUNC("e1000_set_eee_i354");
3080379ebbe7SSepherosa Ziehau 
3081379ebbe7SSepherosa Ziehau 	if ((hw->phy.media_type != e1000_media_type_copper) ||
3082ba0123e0SSepherosa Ziehau 	    ((phy->id != M88E1543_E_PHY_ID) &&
3083ba0123e0SSepherosa Ziehau 	    (phy->id != M88E1512_E_PHY_ID)))
3084379ebbe7SSepherosa Ziehau 		goto out;
3085379ebbe7SSepherosa Ziehau 
3086379ebbe7SSepherosa Ziehau 	if (!hw->dev_spec._82575.eee_disable) {
3087379ebbe7SSepherosa Ziehau 		/* Switch to PHY page 18. */
3088ba0123e0SSepherosa Ziehau 		ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 18);
3089379ebbe7SSepherosa Ziehau 		if (ret_val)
3090379ebbe7SSepherosa Ziehau 			goto out;
3091379ebbe7SSepherosa Ziehau 
3092ba0123e0SSepherosa Ziehau 		ret_val = phy->ops.read_reg(hw, E1000_M88E1543_EEE_CTRL_1,
3093379ebbe7SSepherosa Ziehau 					    &phy_data);
3094379ebbe7SSepherosa Ziehau 		if (ret_val)
3095379ebbe7SSepherosa Ziehau 			goto out;
3096379ebbe7SSepherosa Ziehau 
3097ba0123e0SSepherosa Ziehau 		phy_data |= E1000_M88E1543_EEE_CTRL_1_MS;
3098ba0123e0SSepherosa Ziehau 		ret_val = phy->ops.write_reg(hw, E1000_M88E1543_EEE_CTRL_1,
3099379ebbe7SSepherosa Ziehau 					     phy_data);
3100379ebbe7SSepherosa Ziehau 		if (ret_val)
3101379ebbe7SSepherosa Ziehau 			goto out;
3102379ebbe7SSepherosa Ziehau 
3103379ebbe7SSepherosa Ziehau 		/* Return the PHY to page 0. */
3104ba0123e0SSepherosa Ziehau 		ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
3105379ebbe7SSepherosa Ziehau 		if (ret_val)
3106379ebbe7SSepherosa Ziehau 			goto out;
3107379ebbe7SSepherosa Ziehau 
3108379ebbe7SSepherosa Ziehau 		/* Turn on EEE advertisement. */
3109379ebbe7SSepherosa Ziehau 		ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
3110379ebbe7SSepherosa Ziehau 					       E1000_EEE_ADV_DEV_I354,
3111379ebbe7SSepherosa Ziehau 					       &phy_data);
3112379ebbe7SSepherosa Ziehau 		if (ret_val)
3113379ebbe7SSepherosa Ziehau 			goto out;
3114379ebbe7SSepherosa Ziehau 
3115ba0123e0SSepherosa Ziehau 		if (adv100M)
3116ba0123e0SSepherosa Ziehau 			phy_data |= E1000_EEE_ADV_100_SUPPORTED;
3117ba0123e0SSepherosa Ziehau 		else
3118ba0123e0SSepherosa Ziehau 			phy_data &= ~E1000_EEE_ADV_100_SUPPORTED;
3119ba0123e0SSepherosa Ziehau 
3120ba0123e0SSepherosa Ziehau 		if (adv1G)
3121ba0123e0SSepherosa Ziehau 			phy_data |= E1000_EEE_ADV_1000_SUPPORTED;
3122ba0123e0SSepherosa Ziehau 		else
3123ba0123e0SSepherosa Ziehau 			phy_data &= ~E1000_EEE_ADV_1000_SUPPORTED;
3124ba0123e0SSepherosa Ziehau 
3125379ebbe7SSepherosa Ziehau 		ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
3126379ebbe7SSepherosa Ziehau 						E1000_EEE_ADV_DEV_I354,
3127379ebbe7SSepherosa Ziehau 						phy_data);
3128379ebbe7SSepherosa Ziehau 	} else {
3129379ebbe7SSepherosa Ziehau 		/* Turn off EEE advertisement. */
3130379ebbe7SSepherosa Ziehau 		ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
3131379ebbe7SSepherosa Ziehau 					       E1000_EEE_ADV_DEV_I354,
3132379ebbe7SSepherosa Ziehau 					       &phy_data);
3133379ebbe7SSepherosa Ziehau 		if (ret_val)
3134379ebbe7SSepherosa Ziehau 			goto out;
3135379ebbe7SSepherosa Ziehau 
3136379ebbe7SSepherosa Ziehau 		phy_data &= ~(E1000_EEE_ADV_100_SUPPORTED |
3137379ebbe7SSepherosa Ziehau 			      E1000_EEE_ADV_1000_SUPPORTED);
3138379ebbe7SSepherosa Ziehau 		ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
3139379ebbe7SSepherosa Ziehau 						E1000_EEE_ADV_DEV_I354,
3140379ebbe7SSepherosa Ziehau 						phy_data);
3141379ebbe7SSepherosa Ziehau 	}
3142379ebbe7SSepherosa Ziehau 
3143379ebbe7SSepherosa Ziehau out:
3144379ebbe7SSepherosa Ziehau 	return ret_val;
3145379ebbe7SSepherosa Ziehau }
3146379ebbe7SSepherosa Ziehau 
3147379ebbe7SSepherosa Ziehau /**
3148379ebbe7SSepherosa Ziehau  *  e1000_get_eee_status_i354 - Get EEE status
3149379ebbe7SSepherosa Ziehau  *  @hw: pointer to the HW structure
3150379ebbe7SSepherosa Ziehau  *  @status: EEE status
3151379ebbe7SSepherosa Ziehau  *
3152379ebbe7SSepherosa Ziehau  *  Get EEE status by guessing based on whether Tx or Rx LPI indications have
3153379ebbe7SSepherosa Ziehau  *  been received.
3154379ebbe7SSepherosa Ziehau  **/
e1000_get_eee_status_i354(struct e1000_hw * hw,bool * status)3155379ebbe7SSepherosa Ziehau s32 e1000_get_eee_status_i354(struct e1000_hw *hw, bool *status)
3156379ebbe7SSepherosa Ziehau {
3157379ebbe7SSepherosa Ziehau 	struct e1000_phy_info *phy = &hw->phy;
3158379ebbe7SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
3159379ebbe7SSepherosa Ziehau 	u16 phy_data;
3160379ebbe7SSepherosa Ziehau 
3161379ebbe7SSepherosa Ziehau 	DEBUGFUNC("e1000_get_eee_status_i354");
3162379ebbe7SSepherosa Ziehau 
3163379ebbe7SSepherosa Ziehau 	/* Check if EEE is supported on this device. */
3164379ebbe7SSepherosa Ziehau 	if ((hw->phy.media_type != e1000_media_type_copper) ||
3165ba0123e0SSepherosa Ziehau 	    ((phy->id != M88E1543_E_PHY_ID) &&
3166ba0123e0SSepherosa Ziehau 	    (phy->id != M88E1512_E_PHY_ID)))
3167379ebbe7SSepherosa Ziehau 		goto out;
3168379ebbe7SSepherosa Ziehau 
3169379ebbe7SSepherosa Ziehau 	ret_val = e1000_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354,
3170379ebbe7SSepherosa Ziehau 				       E1000_PCS_STATUS_DEV_I354,
3171379ebbe7SSepherosa Ziehau 				       &phy_data);
3172379ebbe7SSepherosa Ziehau 	if (ret_val)
3173379ebbe7SSepherosa Ziehau 		goto out;
3174379ebbe7SSepherosa Ziehau 
3175379ebbe7SSepherosa Ziehau 	*status = phy_data & (E1000_PCS_STATUS_TX_LPI_RCVD |
3176379ebbe7SSepherosa Ziehau 			      E1000_PCS_STATUS_RX_LPI_RCVD) ? TRUE : FALSE;
3177379ebbe7SSepherosa Ziehau 
3178379ebbe7SSepherosa Ziehau out:
3179379ebbe7SSepherosa Ziehau 	return ret_val;
3180379ebbe7SSepherosa Ziehau }
3181379ebbe7SSepherosa Ziehau 
31824be59a01SSepherosa Ziehau /* Due to a hw errata, if the host tries to  configure the VFTA register
31834be59a01SSepherosa Ziehau  * while performing queries from the BMC or DMA, then the VFTA in some
31844be59a01SSepherosa Ziehau  * cases won't be written.
31854be59a01SSepherosa Ziehau  */
31864be59a01SSepherosa Ziehau 
31874be59a01SSepherosa Ziehau /**
31884be59a01SSepherosa Ziehau  *  e1000_clear_vfta_i350 - Clear VLAN filter table
31894be59a01SSepherosa Ziehau  *  @hw: pointer to the HW structure
31904be59a01SSepherosa Ziehau  *
31914be59a01SSepherosa Ziehau  *  Clears the register array which contains the VLAN filter table by
31924be59a01SSepherosa Ziehau  *  setting all the values to 0.
31934be59a01SSepherosa Ziehau  **/
e1000_clear_vfta_i350(struct e1000_hw * hw)31944be59a01SSepherosa Ziehau void e1000_clear_vfta_i350(struct e1000_hw *hw)
31954be59a01SSepherosa Ziehau {
31964be59a01SSepherosa Ziehau 	u32 offset;
31974be59a01SSepherosa Ziehau 	int i;
31984be59a01SSepherosa Ziehau 
31994be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_clear_vfta_350");
32004be59a01SSepherosa Ziehau 
32014be59a01SSepherosa Ziehau 	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
32024be59a01SSepherosa Ziehau 		for (i = 0; i < 10; i++)
32034be59a01SSepherosa Ziehau 			E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
32044be59a01SSepherosa Ziehau 
32054be59a01SSepherosa Ziehau 		E1000_WRITE_FLUSH(hw);
32064be59a01SSepherosa Ziehau 	}
32074be59a01SSepherosa Ziehau }
32084be59a01SSepherosa Ziehau 
32094be59a01SSepherosa Ziehau /**
32104be59a01SSepherosa Ziehau  *  e1000_write_vfta_i350 - Write value to VLAN filter table
32114be59a01SSepherosa Ziehau  *  @hw: pointer to the HW structure
32124be59a01SSepherosa Ziehau  *  @offset: register offset in VLAN filter table
32134be59a01SSepherosa Ziehau  *  @value: register value written to VLAN filter table
32144be59a01SSepherosa Ziehau  *
32154be59a01SSepherosa Ziehau  *  Writes value at the given offset in the register array which stores
32164be59a01SSepherosa Ziehau  *  the VLAN filter table.
32174be59a01SSepherosa Ziehau  **/
e1000_write_vfta_i350(struct e1000_hw * hw,u32 offset,u32 value)32184be59a01SSepherosa Ziehau void e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value)
32194be59a01SSepherosa Ziehau {
32204be59a01SSepherosa Ziehau 	int i;
32214be59a01SSepherosa Ziehau 
32224be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_write_vfta_350");
32234be59a01SSepherosa Ziehau 
32244be59a01SSepherosa Ziehau 	for (i = 0; i < 10; i++)
32254be59a01SSepherosa Ziehau 		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
32264be59a01SSepherosa Ziehau 
32274be59a01SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
32284be59a01SSepherosa Ziehau }
32294be59a01SSepherosa Ziehau 
32304be59a01SSepherosa Ziehau 
32314be59a01SSepherosa Ziehau /**
32324be59a01SSepherosa Ziehau  *  e1000_set_i2c_bb - Enable I2C bit-bang
32334be59a01SSepherosa Ziehau  *  @hw: pointer to the HW structure
32344be59a01SSepherosa Ziehau  *
32354be59a01SSepherosa Ziehau  *  Enable I2C bit-bang interface
32364be59a01SSepherosa Ziehau  *
32374be59a01SSepherosa Ziehau  **/
e1000_set_i2c_bb(struct e1000_hw * hw)32384be59a01SSepherosa Ziehau s32 e1000_set_i2c_bb(struct e1000_hw *hw)
32394be59a01SSepherosa Ziehau {
32404be59a01SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
32414be59a01SSepherosa Ziehau 	u32 ctrl_ext, i2cparams;
32424be59a01SSepherosa Ziehau 
32434be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_set_i2c_bb");
32444be59a01SSepherosa Ziehau 
32454be59a01SSepherosa Ziehau 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
32464be59a01SSepherosa Ziehau 	ctrl_ext |= E1000_CTRL_I2C_ENA;
32474be59a01SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
32484be59a01SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
32494be59a01SSepherosa Ziehau 
32504be59a01SSepherosa Ziehau 	i2cparams = E1000_READ_REG(hw, E1000_I2CPARAMS);
32514be59a01SSepherosa Ziehau 	i2cparams |= E1000_I2CBB_EN;
32524be59a01SSepherosa Ziehau 	i2cparams |= E1000_I2C_DATA_OE_N;
32534be59a01SSepherosa Ziehau 	i2cparams |= E1000_I2C_CLK_OE_N;
32544be59a01SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cparams);
32554be59a01SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
32564be59a01SSepherosa Ziehau 
32574be59a01SSepherosa Ziehau 	return ret_val;
32584be59a01SSepherosa Ziehau }
32594be59a01SSepherosa Ziehau 
32604be59a01SSepherosa Ziehau /**
32614be59a01SSepherosa Ziehau  *  e1000_read_i2c_byte_generic - Reads 8 bit word over I2C
32624be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
32634be59a01SSepherosa Ziehau  *  @byte_offset: byte offset to read
32644be59a01SSepherosa Ziehau  *  @dev_addr: device address
32654be59a01SSepherosa Ziehau  *  @data: value read
32664be59a01SSepherosa Ziehau  *
32674be59a01SSepherosa Ziehau  *  Performs byte read operation over I2C interface at
32684be59a01SSepherosa Ziehau  *  a specified device address.
32694be59a01SSepherosa Ziehau  **/
e1000_read_i2c_byte_generic(struct e1000_hw * hw,u8 byte_offset,u8 dev_addr,u8 * data)32704be59a01SSepherosa Ziehau s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
32714be59a01SSepherosa Ziehau 				u8 dev_addr, u8 *data)
32724be59a01SSepherosa Ziehau {
32734be59a01SSepherosa Ziehau 	s32 status = E1000_SUCCESS;
32744be59a01SSepherosa Ziehau 	u32 max_retry = 10;
32754be59a01SSepherosa Ziehau 	u32 retry = 1;
32764be59a01SSepherosa Ziehau 	u16 swfw_mask = 0;
32774be59a01SSepherosa Ziehau 
32784be59a01SSepherosa Ziehau 	bool nack = TRUE;
32794be59a01SSepherosa Ziehau 
32804be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_read_i2c_byte_generic");
32814be59a01SSepherosa Ziehau 
32824be59a01SSepherosa Ziehau 	swfw_mask = E1000_SWFW_PHY0_SM;
32834be59a01SSepherosa Ziehau 
32844be59a01SSepherosa Ziehau 	do {
32854be59a01SSepherosa Ziehau 		if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)
32864be59a01SSepherosa Ziehau 		    != E1000_SUCCESS) {
32874be59a01SSepherosa Ziehau 			status = E1000_ERR_SWFW_SYNC;
32884be59a01SSepherosa Ziehau 			goto read_byte_out;
32894be59a01SSepherosa Ziehau 		}
32904be59a01SSepherosa Ziehau 
32914be59a01SSepherosa Ziehau 		e1000_i2c_start(hw);
32924be59a01SSepherosa Ziehau 
32934be59a01SSepherosa Ziehau 		/* Device Address and write indication */
32944be59a01SSepherosa Ziehau 		status = e1000_clock_out_i2c_byte(hw, dev_addr);
32954be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
32964be59a01SSepherosa Ziehau 			goto fail;
32974be59a01SSepherosa Ziehau 
32984be59a01SSepherosa Ziehau 		status = e1000_get_i2c_ack(hw);
32994be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33004be59a01SSepherosa Ziehau 			goto fail;
33014be59a01SSepherosa Ziehau 
33024be59a01SSepherosa Ziehau 		status = e1000_clock_out_i2c_byte(hw, byte_offset);
33034be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33044be59a01SSepherosa Ziehau 			goto fail;
33054be59a01SSepherosa Ziehau 
33064be59a01SSepherosa Ziehau 		status = e1000_get_i2c_ack(hw);
33074be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33084be59a01SSepherosa Ziehau 			goto fail;
33094be59a01SSepherosa Ziehau 
33104be59a01SSepherosa Ziehau 		e1000_i2c_start(hw);
33114be59a01SSepherosa Ziehau 
33124be59a01SSepherosa Ziehau 		/* Device Address and read indication */
33134be59a01SSepherosa Ziehau 		status = e1000_clock_out_i2c_byte(hw, (dev_addr | 0x1));
33144be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33154be59a01SSepherosa Ziehau 			goto fail;
33164be59a01SSepherosa Ziehau 
33174be59a01SSepherosa Ziehau 		status = e1000_get_i2c_ack(hw);
33184be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33194be59a01SSepherosa Ziehau 			goto fail;
33204be59a01SSepherosa Ziehau 
33214be59a01SSepherosa Ziehau 		status = e1000_clock_in_i2c_byte(hw, data);
33224be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33234be59a01SSepherosa Ziehau 			goto fail;
33244be59a01SSepherosa Ziehau 
33254be59a01SSepherosa Ziehau 		status = e1000_clock_out_i2c_bit(hw, nack);
33264be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33274be59a01SSepherosa Ziehau 			goto fail;
33284be59a01SSepherosa Ziehau 
33294be59a01SSepherosa Ziehau 		e1000_i2c_stop(hw);
33304be59a01SSepherosa Ziehau 		break;
33314be59a01SSepherosa Ziehau 
33324be59a01SSepherosa Ziehau fail:
33334be59a01SSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
33344be59a01SSepherosa Ziehau 		msec_delay(100);
33354be59a01SSepherosa Ziehau 		e1000_i2c_bus_clear(hw);
33364be59a01SSepherosa Ziehau 		retry++;
33374be59a01SSepherosa Ziehau 		if (retry < max_retry)
33384be59a01SSepherosa Ziehau 			DEBUGOUT("I2C byte read error - Retrying.\n");
33394be59a01SSepherosa Ziehau 		else
33404be59a01SSepherosa Ziehau 			DEBUGOUT("I2C byte read error.\n");
33414be59a01SSepherosa Ziehau 
33424be59a01SSepherosa Ziehau 	} while (retry < max_retry);
33434be59a01SSepherosa Ziehau 
33444be59a01SSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
33454be59a01SSepherosa Ziehau 
33464be59a01SSepherosa Ziehau read_byte_out:
33474be59a01SSepherosa Ziehau 
33484be59a01SSepherosa Ziehau 	return status;
33494be59a01SSepherosa Ziehau }
33504be59a01SSepherosa Ziehau 
33514be59a01SSepherosa Ziehau /**
33524be59a01SSepherosa Ziehau  *  e1000_write_i2c_byte_generic - Writes 8 bit word over I2C
33534be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
33544be59a01SSepherosa Ziehau  *  @byte_offset: byte offset to write
33554be59a01SSepherosa Ziehau  *  @dev_addr: device address
33564be59a01SSepherosa Ziehau  *  @data: value to write
33574be59a01SSepherosa Ziehau  *
33584be59a01SSepherosa Ziehau  *  Performs byte write operation over I2C interface at
33594be59a01SSepherosa Ziehau  *  a specified device address.
33604be59a01SSepherosa Ziehau  **/
e1000_write_i2c_byte_generic(struct e1000_hw * hw,u8 byte_offset,u8 dev_addr,u8 data)33614be59a01SSepherosa Ziehau s32 e1000_write_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
33624be59a01SSepherosa Ziehau 				 u8 dev_addr, u8 data)
33634be59a01SSepherosa Ziehau {
33644be59a01SSepherosa Ziehau 	s32 status = E1000_SUCCESS;
33654be59a01SSepherosa Ziehau 	u32 max_retry = 1;
33664be59a01SSepherosa Ziehau 	u32 retry = 0;
33674be59a01SSepherosa Ziehau 	u16 swfw_mask = 0;
33684be59a01SSepherosa Ziehau 
33694be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_write_i2c_byte_generic");
33704be59a01SSepherosa Ziehau 
33714be59a01SSepherosa Ziehau 	swfw_mask = E1000_SWFW_PHY0_SM;
33724be59a01SSepherosa Ziehau 
33734be59a01SSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != E1000_SUCCESS) {
33744be59a01SSepherosa Ziehau 		status = E1000_ERR_SWFW_SYNC;
33754be59a01SSepherosa Ziehau 		goto write_byte_out;
33764be59a01SSepherosa Ziehau 	}
33774be59a01SSepherosa Ziehau 
33784be59a01SSepherosa Ziehau 	do {
33794be59a01SSepherosa Ziehau 		e1000_i2c_start(hw);
33804be59a01SSepherosa Ziehau 
33814be59a01SSepherosa Ziehau 		status = e1000_clock_out_i2c_byte(hw, dev_addr);
33824be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33834be59a01SSepherosa Ziehau 			goto fail;
33844be59a01SSepherosa Ziehau 
33854be59a01SSepherosa Ziehau 		status = e1000_get_i2c_ack(hw);
33864be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33874be59a01SSepherosa Ziehau 			goto fail;
33884be59a01SSepherosa Ziehau 
33894be59a01SSepherosa Ziehau 		status = e1000_clock_out_i2c_byte(hw, byte_offset);
33904be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33914be59a01SSepherosa Ziehau 			goto fail;
33924be59a01SSepherosa Ziehau 
33934be59a01SSepherosa Ziehau 		status = e1000_get_i2c_ack(hw);
33944be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33954be59a01SSepherosa Ziehau 			goto fail;
33964be59a01SSepherosa Ziehau 
33974be59a01SSepherosa Ziehau 		status = e1000_clock_out_i2c_byte(hw, data);
33984be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
33994be59a01SSepherosa Ziehau 			goto fail;
34004be59a01SSepherosa Ziehau 
34014be59a01SSepherosa Ziehau 		status = e1000_get_i2c_ack(hw);
34024be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
34034be59a01SSepherosa Ziehau 			goto fail;
34044be59a01SSepherosa Ziehau 
34054be59a01SSepherosa Ziehau 		e1000_i2c_stop(hw);
34064be59a01SSepherosa Ziehau 		break;
34074be59a01SSepherosa Ziehau 
34084be59a01SSepherosa Ziehau fail:
34094be59a01SSepherosa Ziehau 		e1000_i2c_bus_clear(hw);
34104be59a01SSepherosa Ziehau 		retry++;
34114be59a01SSepherosa Ziehau 		if (retry < max_retry)
34124be59a01SSepherosa Ziehau 			DEBUGOUT("I2C byte write error - Retrying.\n");
34134be59a01SSepherosa Ziehau 		else
34144be59a01SSepherosa Ziehau 			DEBUGOUT("I2C byte write error.\n");
34154be59a01SSepherosa Ziehau 	} while (retry < max_retry);
34164be59a01SSepherosa Ziehau 
34174be59a01SSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
34184be59a01SSepherosa Ziehau 
34194be59a01SSepherosa Ziehau write_byte_out:
34204be59a01SSepherosa Ziehau 
34214be59a01SSepherosa Ziehau 	return status;
34224be59a01SSepherosa Ziehau }
34234be59a01SSepherosa Ziehau 
34244be59a01SSepherosa Ziehau /**
34254be59a01SSepherosa Ziehau  *  e1000_i2c_start - Sets I2C start condition
34264be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
34274be59a01SSepherosa Ziehau  *
34284be59a01SSepherosa Ziehau  *  Sets I2C start condition (High -> Low on SDA while SCL is High)
34294be59a01SSepherosa Ziehau  **/
e1000_i2c_start(struct e1000_hw * hw)34304be59a01SSepherosa Ziehau static void e1000_i2c_start(struct e1000_hw *hw)
34314be59a01SSepherosa Ziehau {
34324be59a01SSepherosa Ziehau 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
34334be59a01SSepherosa Ziehau 
34344be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_i2c_start");
34354be59a01SSepherosa Ziehau 
34364be59a01SSepherosa Ziehau 	/* Start condition must begin with data and clock high */
34374be59a01SSepherosa Ziehau 	e1000_set_i2c_data(hw, &i2cctl, 1);
34384be59a01SSepherosa Ziehau 	e1000_raise_i2c_clk(hw, &i2cctl);
34394be59a01SSepherosa Ziehau 
34404be59a01SSepherosa Ziehau 	/* Setup time for start condition (4.7us) */
34414be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_SU_STA);
34424be59a01SSepherosa Ziehau 
34434be59a01SSepherosa Ziehau 	e1000_set_i2c_data(hw, &i2cctl, 0);
34444be59a01SSepherosa Ziehau 
34454be59a01SSepherosa Ziehau 	/* Hold time for start condition (4us) */
34464be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_HD_STA);
34474be59a01SSepherosa Ziehau 
34484be59a01SSepherosa Ziehau 	e1000_lower_i2c_clk(hw, &i2cctl);
34494be59a01SSepherosa Ziehau 
34504be59a01SSepherosa Ziehau 	/* Minimum low period of clock is 4.7 us */
34514be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_LOW);
34524be59a01SSepherosa Ziehau 
34534be59a01SSepherosa Ziehau }
34544be59a01SSepherosa Ziehau 
34554be59a01SSepherosa Ziehau /**
34564be59a01SSepherosa Ziehau  *  e1000_i2c_stop - Sets I2C stop condition
34574be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
34584be59a01SSepherosa Ziehau  *
34594be59a01SSepherosa Ziehau  *  Sets I2C stop condition (Low -> High on SDA while SCL is High)
34604be59a01SSepherosa Ziehau  **/
e1000_i2c_stop(struct e1000_hw * hw)34614be59a01SSepherosa Ziehau static void e1000_i2c_stop(struct e1000_hw *hw)
34624be59a01SSepherosa Ziehau {
34634be59a01SSepherosa Ziehau 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
34644be59a01SSepherosa Ziehau 
34654be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_i2c_stop");
34664be59a01SSepherosa Ziehau 
34674be59a01SSepherosa Ziehau 	/* Stop condition must begin with data low and clock high */
34684be59a01SSepherosa Ziehau 	e1000_set_i2c_data(hw, &i2cctl, 0);
34694be59a01SSepherosa Ziehau 	e1000_raise_i2c_clk(hw, &i2cctl);
34704be59a01SSepherosa Ziehau 
34714be59a01SSepherosa Ziehau 	/* Setup time for stop condition (4us) */
34724be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_SU_STO);
34734be59a01SSepherosa Ziehau 
34744be59a01SSepherosa Ziehau 	e1000_set_i2c_data(hw, &i2cctl, 1);
34754be59a01SSepherosa Ziehau 
34764be59a01SSepherosa Ziehau 	/* bus free time between stop and start (4.7us)*/
34774be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_BUF);
34784be59a01SSepherosa Ziehau }
34794be59a01SSepherosa Ziehau 
34804be59a01SSepherosa Ziehau /**
34814be59a01SSepherosa Ziehau  *  e1000_clock_in_i2c_byte - Clocks in one byte via I2C
34824be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
34834be59a01SSepherosa Ziehau  *  @data: data byte to clock in
34844be59a01SSepherosa Ziehau  *
34854be59a01SSepherosa Ziehau  *  Clocks in one byte data via I2C data/clock
34864be59a01SSepherosa Ziehau  **/
e1000_clock_in_i2c_byte(struct e1000_hw * hw,u8 * data)34874be59a01SSepherosa Ziehau static s32 e1000_clock_in_i2c_byte(struct e1000_hw *hw, u8 *data)
34884be59a01SSepherosa Ziehau {
34894be59a01SSepherosa Ziehau 	s32 i;
34904be59a01SSepherosa Ziehau 	bool bit = 0;
34914be59a01SSepherosa Ziehau 
34924be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_clock_in_i2c_byte");
34934be59a01SSepherosa Ziehau 
34944be59a01SSepherosa Ziehau 	*data = 0;
34954be59a01SSepherosa Ziehau 	for (i = 7; i >= 0; i--) {
34964be59a01SSepherosa Ziehau 		e1000_clock_in_i2c_bit(hw, &bit);
34974be59a01SSepherosa Ziehau 		*data |= bit << i;
34984be59a01SSepherosa Ziehau 	}
34994be59a01SSepherosa Ziehau 
35004be59a01SSepherosa Ziehau 	return E1000_SUCCESS;
35014be59a01SSepherosa Ziehau }
35024be59a01SSepherosa Ziehau 
35034be59a01SSepherosa Ziehau /**
35044be59a01SSepherosa Ziehau  *  e1000_clock_out_i2c_byte - Clocks out one byte via I2C
35054be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
35064be59a01SSepherosa Ziehau  *  @data: data byte clocked out
35074be59a01SSepherosa Ziehau  *
35084be59a01SSepherosa Ziehau  *  Clocks out one byte data via I2C data/clock
35094be59a01SSepherosa Ziehau  **/
e1000_clock_out_i2c_byte(struct e1000_hw * hw,u8 data)35104be59a01SSepherosa Ziehau static s32 e1000_clock_out_i2c_byte(struct e1000_hw *hw, u8 data)
35114be59a01SSepherosa Ziehau {
35124be59a01SSepherosa Ziehau 	s32 status = E1000_SUCCESS;
35134be59a01SSepherosa Ziehau 	s32 i;
35144be59a01SSepherosa Ziehau 	u32 i2cctl;
35154be59a01SSepherosa Ziehau 	bool bit = 0;
35164be59a01SSepherosa Ziehau 
35174be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_clock_out_i2c_byte");
35184be59a01SSepherosa Ziehau 
35194be59a01SSepherosa Ziehau 	for (i = 7; i >= 0; i--) {
35204be59a01SSepherosa Ziehau 		bit = (data >> i) & 0x1;
35214be59a01SSepherosa Ziehau 		status = e1000_clock_out_i2c_bit(hw, bit);
35224be59a01SSepherosa Ziehau 
35234be59a01SSepherosa Ziehau 		if (status != E1000_SUCCESS)
35244be59a01SSepherosa Ziehau 			break;
35254be59a01SSepherosa Ziehau 	}
35264be59a01SSepherosa Ziehau 
35274be59a01SSepherosa Ziehau 	/* Release SDA line (set high) */
35284be59a01SSepherosa Ziehau 	i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
35294be59a01SSepherosa Ziehau 
35304be59a01SSepherosa Ziehau 	i2cctl |= E1000_I2C_DATA_OE_N;
35314be59a01SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cctl);
35324be59a01SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
35334be59a01SSepherosa Ziehau 
35344be59a01SSepherosa Ziehau 	return status;
35354be59a01SSepherosa Ziehau }
35364be59a01SSepherosa Ziehau 
35374be59a01SSepherosa Ziehau /**
35384be59a01SSepherosa Ziehau  *  e1000_get_i2c_ack - Polls for I2C ACK
35394be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
35404be59a01SSepherosa Ziehau  *
35414be59a01SSepherosa Ziehau  *  Clocks in/out one bit via I2C data/clock
35424be59a01SSepherosa Ziehau  **/
e1000_get_i2c_ack(struct e1000_hw * hw)35434be59a01SSepherosa Ziehau static s32 e1000_get_i2c_ack(struct e1000_hw *hw)
35444be59a01SSepherosa Ziehau {
35454be59a01SSepherosa Ziehau 	s32 status = E1000_SUCCESS;
35464be59a01SSepherosa Ziehau 	u32 i = 0;
35474be59a01SSepherosa Ziehau 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
35484be59a01SSepherosa Ziehau 	u32 timeout = 10;
35494be59a01SSepherosa Ziehau 	bool ack = TRUE;
35504be59a01SSepherosa Ziehau 
35514be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_get_i2c_ack");
35524be59a01SSepherosa Ziehau 
35534be59a01SSepherosa Ziehau 	e1000_raise_i2c_clk(hw, &i2cctl);
35544be59a01SSepherosa Ziehau 
35554be59a01SSepherosa Ziehau 	/* Minimum high period of clock is 4us */
35564be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_HIGH);
35574be59a01SSepherosa Ziehau 
35584be59a01SSepherosa Ziehau 	/* Wait until SCL returns high */
35594be59a01SSepherosa Ziehau 	for (i = 0; i < timeout; i++) {
35604be59a01SSepherosa Ziehau 		usec_delay(1);
35614be59a01SSepherosa Ziehau 		i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
35624be59a01SSepherosa Ziehau 		if (i2cctl & E1000_I2C_CLK_IN)
35634be59a01SSepherosa Ziehau 			break;
35644be59a01SSepherosa Ziehau 	}
35654be59a01SSepherosa Ziehau 	if (!(i2cctl & E1000_I2C_CLK_IN))
35664be59a01SSepherosa Ziehau 		return E1000_ERR_I2C;
35674be59a01SSepherosa Ziehau 
35684be59a01SSepherosa Ziehau 	ack = e1000_get_i2c_data(&i2cctl);
35694be59a01SSepherosa Ziehau 	if (ack) {
35704be59a01SSepherosa Ziehau 		DEBUGOUT("I2C ack was not received.\n");
35714be59a01SSepherosa Ziehau 		status = E1000_ERR_I2C;
35724be59a01SSepherosa Ziehau 	}
35734be59a01SSepherosa Ziehau 
35744be59a01SSepherosa Ziehau 	e1000_lower_i2c_clk(hw, &i2cctl);
35754be59a01SSepherosa Ziehau 
35764be59a01SSepherosa Ziehau 	/* Minimum low period of clock is 4.7 us */
35774be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_LOW);
35784be59a01SSepherosa Ziehau 
35794be59a01SSepherosa Ziehau 	return status;
35804be59a01SSepherosa Ziehau }
35814be59a01SSepherosa Ziehau 
35824be59a01SSepherosa Ziehau /**
35834be59a01SSepherosa Ziehau  *  e1000_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
35844be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
35854be59a01SSepherosa Ziehau  *  @data: read data value
35864be59a01SSepherosa Ziehau  *
35874be59a01SSepherosa Ziehau  *  Clocks in one bit via I2C data/clock
35884be59a01SSepherosa Ziehau  **/
e1000_clock_in_i2c_bit(struct e1000_hw * hw,bool * data)35894be59a01SSepherosa Ziehau static s32 e1000_clock_in_i2c_bit(struct e1000_hw *hw, bool *data)
35904be59a01SSepherosa Ziehau {
35914be59a01SSepherosa Ziehau 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
35924be59a01SSepherosa Ziehau 
35934be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_clock_in_i2c_bit");
35944be59a01SSepherosa Ziehau 
35954be59a01SSepherosa Ziehau 	e1000_raise_i2c_clk(hw, &i2cctl);
35964be59a01SSepherosa Ziehau 
35974be59a01SSepherosa Ziehau 	/* Minimum high period of clock is 4us */
35984be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_HIGH);
35994be59a01SSepherosa Ziehau 
36004be59a01SSepherosa Ziehau 	i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
36014be59a01SSepherosa Ziehau 	*data = e1000_get_i2c_data(&i2cctl);
36024be59a01SSepherosa Ziehau 
36034be59a01SSepherosa Ziehau 	e1000_lower_i2c_clk(hw, &i2cctl);
36044be59a01SSepherosa Ziehau 
36054be59a01SSepherosa Ziehau 	/* Minimum low period of clock is 4.7 us */
36064be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_LOW);
36074be59a01SSepherosa Ziehau 
36084be59a01SSepherosa Ziehau 	return E1000_SUCCESS;
36094be59a01SSepherosa Ziehau }
36104be59a01SSepherosa Ziehau 
36114be59a01SSepherosa Ziehau /**
36124be59a01SSepherosa Ziehau  *  e1000_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
36134be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
36144be59a01SSepherosa Ziehau  *  @data: data value to write
36154be59a01SSepherosa Ziehau  *
36164be59a01SSepherosa Ziehau  *  Clocks out one bit via I2C data/clock
36174be59a01SSepherosa Ziehau  **/
e1000_clock_out_i2c_bit(struct e1000_hw * hw,bool data)36184be59a01SSepherosa Ziehau static s32 e1000_clock_out_i2c_bit(struct e1000_hw *hw, bool data)
36194be59a01SSepherosa Ziehau {
36204be59a01SSepherosa Ziehau 	s32 status;
36214be59a01SSepherosa Ziehau 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
36224be59a01SSepherosa Ziehau 
36234be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_clock_out_i2c_bit");
36244be59a01SSepherosa Ziehau 
36254be59a01SSepherosa Ziehau 	status = e1000_set_i2c_data(hw, &i2cctl, data);
36264be59a01SSepherosa Ziehau 	if (status == E1000_SUCCESS) {
36274be59a01SSepherosa Ziehau 		e1000_raise_i2c_clk(hw, &i2cctl);
36284be59a01SSepherosa Ziehau 
36294be59a01SSepherosa Ziehau 		/* Minimum high period of clock is 4us */
36304be59a01SSepherosa Ziehau 		usec_delay(E1000_I2C_T_HIGH);
36314be59a01SSepherosa Ziehau 
36324be59a01SSepherosa Ziehau 		e1000_lower_i2c_clk(hw, &i2cctl);
36334be59a01SSepherosa Ziehau 
36344be59a01SSepherosa Ziehau 		/* Minimum low period of clock is 4.7 us.
36354be59a01SSepherosa Ziehau 		 * This also takes care of the data hold time.
36364be59a01SSepherosa Ziehau 		 */
36374be59a01SSepherosa Ziehau 		usec_delay(E1000_I2C_T_LOW);
36384be59a01SSepherosa Ziehau 	} else {
36394be59a01SSepherosa Ziehau 		status = E1000_ERR_I2C;
36404be59a01SSepherosa Ziehau 		DEBUGOUT1("I2C data was not set to %X\n", data);
36414be59a01SSepherosa Ziehau 	}
36424be59a01SSepherosa Ziehau 
36434be59a01SSepherosa Ziehau 	return status;
36444be59a01SSepherosa Ziehau }
36454be59a01SSepherosa Ziehau /**
36464be59a01SSepherosa Ziehau  *  e1000_raise_i2c_clk - Raises the I2C SCL clock
36474be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
36484be59a01SSepherosa Ziehau  *  @i2cctl: Current value of I2CCTL register
36494be59a01SSepherosa Ziehau  *
36504be59a01SSepherosa Ziehau  *  Raises the I2C clock line '0'->'1'
36514be59a01SSepherosa Ziehau  **/
e1000_raise_i2c_clk(struct e1000_hw * hw,u32 * i2cctl)36524be59a01SSepherosa Ziehau static void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl)
36534be59a01SSepherosa Ziehau {
36544be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_raise_i2c_clk");
36554be59a01SSepherosa Ziehau 
36564be59a01SSepherosa Ziehau 	*i2cctl |= E1000_I2C_CLK_OUT;
36574be59a01SSepherosa Ziehau 	*i2cctl &= ~E1000_I2C_CLK_OE_N;
36584be59a01SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
36594be59a01SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
36604be59a01SSepherosa Ziehau 
36614be59a01SSepherosa Ziehau 	/* SCL rise time (1000ns) */
36624be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_RISE);
36634be59a01SSepherosa Ziehau }
36644be59a01SSepherosa Ziehau 
36654be59a01SSepherosa Ziehau /**
36664be59a01SSepherosa Ziehau  *  e1000_lower_i2c_clk - Lowers the I2C SCL clock
36674be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
36684be59a01SSepherosa Ziehau  *  @i2cctl: Current value of I2CCTL register
36694be59a01SSepherosa Ziehau  *
36704be59a01SSepherosa Ziehau  *  Lowers the I2C clock line '1'->'0'
36714be59a01SSepherosa Ziehau  **/
e1000_lower_i2c_clk(struct e1000_hw * hw,u32 * i2cctl)36724be59a01SSepherosa Ziehau static void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl)
36734be59a01SSepherosa Ziehau {
36744be59a01SSepherosa Ziehau 
36754be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_lower_i2c_clk");
36764be59a01SSepherosa Ziehau 
36774be59a01SSepherosa Ziehau 	*i2cctl &= ~E1000_I2C_CLK_OUT;
36784be59a01SSepherosa Ziehau 	*i2cctl &= ~E1000_I2C_CLK_OE_N;
36794be59a01SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
36804be59a01SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
36814be59a01SSepherosa Ziehau 
36824be59a01SSepherosa Ziehau 	/* SCL fall time (300ns) */
36834be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_FALL);
36844be59a01SSepherosa Ziehau }
36854be59a01SSepherosa Ziehau 
36864be59a01SSepherosa Ziehau /**
36874be59a01SSepherosa Ziehau  *  e1000_set_i2c_data - Sets the I2C data bit
36884be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
36894be59a01SSepherosa Ziehau  *  @i2cctl: Current value of I2CCTL register
36904be59a01SSepherosa Ziehau  *  @data: I2C data value (0 or 1) to set
36914be59a01SSepherosa Ziehau  *
36924be59a01SSepherosa Ziehau  *  Sets the I2C data bit
36934be59a01SSepherosa Ziehau  **/
e1000_set_i2c_data(struct e1000_hw * hw,u32 * i2cctl,bool data)36944be59a01SSepherosa Ziehau static s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data)
36954be59a01SSepherosa Ziehau {
36964be59a01SSepherosa Ziehau 	s32 status = E1000_SUCCESS;
36974be59a01SSepherosa Ziehau 
36984be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_set_i2c_data");
36994be59a01SSepherosa Ziehau 
37004be59a01SSepherosa Ziehau 	if (data)
37014be59a01SSepherosa Ziehau 		*i2cctl |= E1000_I2C_DATA_OUT;
37024be59a01SSepherosa Ziehau 	else
37034be59a01SSepherosa Ziehau 		*i2cctl &= ~E1000_I2C_DATA_OUT;
37044be59a01SSepherosa Ziehau 
37054be59a01SSepherosa Ziehau 	*i2cctl &= ~E1000_I2C_DATA_OE_N;
37064be59a01SSepherosa Ziehau 	*i2cctl |= E1000_I2C_CLK_OE_N;
37074be59a01SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
37084be59a01SSepherosa Ziehau 	E1000_WRITE_FLUSH(hw);
37094be59a01SSepherosa Ziehau 
37104be59a01SSepherosa Ziehau 	/* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
37114be59a01SSepherosa Ziehau 	usec_delay(E1000_I2C_T_RISE + E1000_I2C_T_FALL + E1000_I2C_T_SU_DATA);
37124be59a01SSepherosa Ziehau 
37134be59a01SSepherosa Ziehau 	*i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
37144be59a01SSepherosa Ziehau 	if (data != e1000_get_i2c_data(i2cctl)) {
37154be59a01SSepherosa Ziehau 		status = E1000_ERR_I2C;
37164be59a01SSepherosa Ziehau 		DEBUGOUT1("Error - I2C data was not set to %X.\n", data);
37174be59a01SSepherosa Ziehau 	}
37184be59a01SSepherosa Ziehau 
37194be59a01SSepherosa Ziehau 	return status;
37204be59a01SSepherosa Ziehau }
37214be59a01SSepherosa Ziehau 
37224be59a01SSepherosa Ziehau /**
37234be59a01SSepherosa Ziehau  *  e1000_get_i2c_data - Reads the I2C SDA data bit
37244be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
37254be59a01SSepherosa Ziehau  *  @i2cctl: Current value of I2CCTL register
37264be59a01SSepherosa Ziehau  *
37274be59a01SSepherosa Ziehau  *  Returns the I2C data bit value
37284be59a01SSepherosa Ziehau  **/
e1000_get_i2c_data(u32 * i2cctl)37294be59a01SSepherosa Ziehau static bool e1000_get_i2c_data(u32 *i2cctl)
37304be59a01SSepherosa Ziehau {
37314be59a01SSepherosa Ziehau 	bool data;
37324be59a01SSepherosa Ziehau 
37334be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_get_i2c_data");
37344be59a01SSepherosa Ziehau 
37354be59a01SSepherosa Ziehau 	if (*i2cctl & E1000_I2C_DATA_IN)
37364be59a01SSepherosa Ziehau 		data = 1;
37374be59a01SSepherosa Ziehau 	else
37384be59a01SSepherosa Ziehau 		data = 0;
37394be59a01SSepherosa Ziehau 
37404be59a01SSepherosa Ziehau 	return data;
37414be59a01SSepherosa Ziehau }
37424be59a01SSepherosa Ziehau 
37434be59a01SSepherosa Ziehau /**
37444be59a01SSepherosa Ziehau  *  e1000_i2c_bus_clear - Clears the I2C bus
37454be59a01SSepherosa Ziehau  *  @hw: pointer to hardware structure
37464be59a01SSepherosa Ziehau  *
37474be59a01SSepherosa Ziehau  *  Clears the I2C bus by sending nine clock pulses.
37484be59a01SSepherosa Ziehau  *  Used when data line is stuck low.
37494be59a01SSepherosa Ziehau  **/
e1000_i2c_bus_clear(struct e1000_hw * hw)37504be59a01SSepherosa Ziehau void e1000_i2c_bus_clear(struct e1000_hw *hw)
37514be59a01SSepherosa Ziehau {
37524be59a01SSepherosa Ziehau 	u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
37534be59a01SSepherosa Ziehau 	u32 i;
37544be59a01SSepherosa Ziehau 
37554be59a01SSepherosa Ziehau 	DEBUGFUNC("e1000_i2c_bus_clear");
37564be59a01SSepherosa Ziehau 
37574be59a01SSepherosa Ziehau 	e1000_i2c_start(hw);
37584be59a01SSepherosa Ziehau 
37594be59a01SSepherosa Ziehau 	e1000_set_i2c_data(hw, &i2cctl, 1);
37604be59a01SSepherosa Ziehau 
37614be59a01SSepherosa Ziehau 	for (i = 0; i < 9; i++) {
37624be59a01SSepherosa Ziehau 		e1000_raise_i2c_clk(hw, &i2cctl);
37634be59a01SSepherosa Ziehau 
37644be59a01SSepherosa Ziehau 		/* Min high period of clock is 4us */
37654be59a01SSepherosa Ziehau 		usec_delay(E1000_I2C_T_HIGH);
37664be59a01SSepherosa Ziehau 
37674be59a01SSepherosa Ziehau 		e1000_lower_i2c_clk(hw, &i2cctl);
37684be59a01SSepherosa Ziehau 
37694be59a01SSepherosa Ziehau 		/* Min low period of clock is 4.7us*/
37704be59a01SSepherosa Ziehau 		usec_delay(E1000_I2C_T_LOW);
37714be59a01SSepherosa Ziehau 	}
37724be59a01SSepherosa Ziehau 
37734be59a01SSepherosa Ziehau 	e1000_i2c_start(hw);
37744be59a01SSepherosa Ziehau 
37754be59a01SSepherosa Ziehau 	/* Put the i2c bus back to default state */
37764be59a01SSepherosa Ziehau 	e1000_i2c_stop(hw);
37774be59a01SSepherosa Ziehau }
37784be59a01SSepherosa Ziehau 
3779