xref: /titanic_44/usr/src/uts/common/io/e1000api/e1000_82540.c (revision 7c5988f936b3be75c91374b25ee25f68beb40878)
175eba5b6SRobert Mustacchi /******************************************************************************
275eba5b6SRobert Mustacchi 
3*7c5988f9SRobert Mustacchi   Copyright (c) 2001-2015, Intel Corporation
475eba5b6SRobert Mustacchi   All rights reserved.
575eba5b6SRobert Mustacchi 
675eba5b6SRobert Mustacchi   Redistribution and use in source and binary forms, with or without
775eba5b6SRobert Mustacchi   modification, are permitted provided that the following conditions are met:
875eba5b6SRobert Mustacchi 
975eba5b6SRobert Mustacchi    1. Redistributions of source code must retain the above copyright notice,
1075eba5b6SRobert Mustacchi       this list of conditions and the following disclaimer.
1175eba5b6SRobert Mustacchi 
1275eba5b6SRobert Mustacchi    2. Redistributions in binary form must reproduce the above copyright
1375eba5b6SRobert Mustacchi       notice, this list of conditions and the following disclaimer in the
1475eba5b6SRobert Mustacchi       documentation and/or other materials provided with the distribution.
1575eba5b6SRobert Mustacchi 
1675eba5b6SRobert Mustacchi    3. Neither the name of the Intel Corporation nor the names of its
1775eba5b6SRobert Mustacchi       contributors may be used to endorse or promote products derived from
1875eba5b6SRobert Mustacchi       this software without specific prior written permission.
1975eba5b6SRobert Mustacchi 
2075eba5b6SRobert Mustacchi   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2175eba5b6SRobert Mustacchi   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2275eba5b6SRobert Mustacchi   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2375eba5b6SRobert Mustacchi   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2475eba5b6SRobert Mustacchi   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2575eba5b6SRobert Mustacchi   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2675eba5b6SRobert Mustacchi   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2775eba5b6SRobert Mustacchi   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2875eba5b6SRobert Mustacchi   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2975eba5b6SRobert Mustacchi   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3075eba5b6SRobert Mustacchi   POSSIBILITY OF SUCH DAMAGE.
3175eba5b6SRobert Mustacchi 
3275eba5b6SRobert Mustacchi ******************************************************************************/
3375eba5b6SRobert Mustacchi /*$FreeBSD$*/
3475eba5b6SRobert Mustacchi 
3575eba5b6SRobert Mustacchi /*
3675eba5b6SRobert Mustacchi  * 82540EM Gigabit Ethernet Controller
3775eba5b6SRobert Mustacchi  * 82540EP Gigabit Ethernet Controller
3875eba5b6SRobert Mustacchi  * 82545EM Gigabit Ethernet Controller (Copper)
3975eba5b6SRobert Mustacchi  * 82545EM Gigabit Ethernet Controller (Fiber)
4075eba5b6SRobert Mustacchi  * 82545GM Gigabit Ethernet Controller
4175eba5b6SRobert Mustacchi  * 82546EB Gigabit Ethernet Controller (Copper)
4275eba5b6SRobert Mustacchi  * 82546EB Gigabit Ethernet Controller (Fiber)
4375eba5b6SRobert Mustacchi  * 82546GB Gigabit Ethernet Controller
4475eba5b6SRobert Mustacchi  */
4575eba5b6SRobert Mustacchi 
4675eba5b6SRobert Mustacchi #include "e1000_api.h"
4775eba5b6SRobert Mustacchi 
4875eba5b6SRobert Mustacchi static s32  e1000_init_phy_params_82540(struct e1000_hw *hw);
4975eba5b6SRobert Mustacchi static s32  e1000_init_nvm_params_82540(struct e1000_hw *hw);
5075eba5b6SRobert Mustacchi static s32  e1000_init_mac_params_82540(struct e1000_hw *hw);
5175eba5b6SRobert Mustacchi static s32  e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw);
5275eba5b6SRobert Mustacchi static void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw);
5375eba5b6SRobert Mustacchi static s32  e1000_init_hw_82540(struct e1000_hw *hw);
5475eba5b6SRobert Mustacchi static s32  e1000_reset_hw_82540(struct e1000_hw *hw);
5575eba5b6SRobert Mustacchi static s32  e1000_set_phy_mode_82540(struct e1000_hw *hw);
5675eba5b6SRobert Mustacchi static s32  e1000_set_vco_speed_82540(struct e1000_hw *hw);
5775eba5b6SRobert Mustacchi static s32  e1000_setup_copper_link_82540(struct e1000_hw *hw);
5875eba5b6SRobert Mustacchi static s32  e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw);
5975eba5b6SRobert Mustacchi static void e1000_power_down_phy_copper_82540(struct e1000_hw *hw);
6075eba5b6SRobert Mustacchi static s32  e1000_read_mac_addr_82540(struct e1000_hw *hw);
6175eba5b6SRobert Mustacchi 
6275eba5b6SRobert Mustacchi /**
6375eba5b6SRobert Mustacchi  * e1000_init_phy_params_82540 - Init PHY func ptrs.
6475eba5b6SRobert Mustacchi  * @hw: pointer to the HW structure
6575eba5b6SRobert Mustacchi  **/
e1000_init_phy_params_82540(struct e1000_hw * hw)6675eba5b6SRobert Mustacchi static s32 e1000_init_phy_params_82540(struct e1000_hw *hw)
6775eba5b6SRobert Mustacchi {
6875eba5b6SRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
69*7c5988f9SRobert Mustacchi 	s32 ret_val;
7075eba5b6SRobert Mustacchi 
7175eba5b6SRobert Mustacchi 	phy->addr		= 1;
7275eba5b6SRobert Mustacchi 	phy->autoneg_mask	= AUTONEG_ADVERTISE_SPEED_DEFAULT;
7375eba5b6SRobert Mustacchi 	phy->reset_delay_us	= 10000;
7475eba5b6SRobert Mustacchi 	phy->type		= e1000_phy_m88;
7575eba5b6SRobert Mustacchi 
7675eba5b6SRobert Mustacchi 	/* Function Pointers */
7775eba5b6SRobert Mustacchi 	phy->ops.check_polarity	= e1000_check_polarity_m88;
7875eba5b6SRobert Mustacchi 	phy->ops.commit		= e1000_phy_sw_reset_generic;
7975eba5b6SRobert Mustacchi 	phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
8075eba5b6SRobert Mustacchi 	phy->ops.get_cable_length = e1000_get_cable_length_m88;
8175eba5b6SRobert Mustacchi 	phy->ops.get_cfg_done	= e1000_get_cfg_done_generic;
8275eba5b6SRobert Mustacchi 	phy->ops.read_reg	= e1000_read_phy_reg_m88;
8375eba5b6SRobert Mustacchi 	phy->ops.reset		= e1000_phy_hw_reset_generic;
8475eba5b6SRobert Mustacchi 	phy->ops.write_reg	= e1000_write_phy_reg_m88;
8575eba5b6SRobert Mustacchi 	phy->ops.get_info	= e1000_get_phy_info_m88;
8675eba5b6SRobert Mustacchi 	phy->ops.power_up	= e1000_power_up_phy_copper;
8775eba5b6SRobert Mustacchi 	phy->ops.power_down	= e1000_power_down_phy_copper_82540;
8875eba5b6SRobert Mustacchi 
8975eba5b6SRobert Mustacchi 	ret_val = e1000_get_phy_id(hw);
9075eba5b6SRobert Mustacchi 	if (ret_val)
9175eba5b6SRobert Mustacchi 		goto out;
9275eba5b6SRobert Mustacchi 
9375eba5b6SRobert Mustacchi 	/* Verify phy id */
9475eba5b6SRobert Mustacchi 	switch (hw->mac.type) {
9575eba5b6SRobert Mustacchi 	case e1000_82540:
9675eba5b6SRobert Mustacchi 	case e1000_82545:
9775eba5b6SRobert Mustacchi 	case e1000_82545_rev_3:
9875eba5b6SRobert Mustacchi 	case e1000_82546:
9975eba5b6SRobert Mustacchi 	case e1000_82546_rev_3:
10075eba5b6SRobert Mustacchi 		if (phy->id == M88E1011_I_PHY_ID)
10175eba5b6SRobert Mustacchi 			break;
10275eba5b6SRobert Mustacchi 		/* Fall Through */
10375eba5b6SRobert Mustacchi 	default:
10475eba5b6SRobert Mustacchi 		ret_val = -E1000_ERR_PHY;
10575eba5b6SRobert Mustacchi 		goto out;
10675eba5b6SRobert Mustacchi 		break;
10775eba5b6SRobert Mustacchi 	}
10875eba5b6SRobert Mustacchi 
10975eba5b6SRobert Mustacchi out:
11075eba5b6SRobert Mustacchi 	return ret_val;
11175eba5b6SRobert Mustacchi }
11275eba5b6SRobert Mustacchi 
11375eba5b6SRobert Mustacchi /**
11475eba5b6SRobert Mustacchi  * e1000_init_nvm_params_82540 - Init NVM func ptrs.
11575eba5b6SRobert Mustacchi  * @hw: pointer to the HW structure
11675eba5b6SRobert Mustacchi  **/
e1000_init_nvm_params_82540(struct e1000_hw * hw)11775eba5b6SRobert Mustacchi static s32 e1000_init_nvm_params_82540(struct e1000_hw *hw)
11875eba5b6SRobert Mustacchi {
11975eba5b6SRobert Mustacchi 	struct e1000_nvm_info *nvm = &hw->nvm;
12075eba5b6SRobert Mustacchi 	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
12175eba5b6SRobert Mustacchi 
12275eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_nvm_params_82540");
12375eba5b6SRobert Mustacchi 
12475eba5b6SRobert Mustacchi 	nvm->type = e1000_nvm_eeprom_microwire;
12575eba5b6SRobert Mustacchi 	nvm->delay_usec = 50;
12675eba5b6SRobert Mustacchi 	nvm->opcode_bits = 3;
12775eba5b6SRobert Mustacchi 	switch (nvm->override) {
12875eba5b6SRobert Mustacchi 	case e1000_nvm_override_microwire_large:
12975eba5b6SRobert Mustacchi 		nvm->address_bits = 8;
13075eba5b6SRobert Mustacchi 		nvm->word_size = 256;
13175eba5b6SRobert Mustacchi 		break;
13275eba5b6SRobert Mustacchi 	case e1000_nvm_override_microwire_small:
13375eba5b6SRobert Mustacchi 		nvm->address_bits = 6;
13475eba5b6SRobert Mustacchi 		nvm->word_size = 64;
13575eba5b6SRobert Mustacchi 		break;
13675eba5b6SRobert Mustacchi 	default:
13775eba5b6SRobert Mustacchi 		nvm->address_bits = eecd & E1000_EECD_SIZE ? 8 : 6;
13875eba5b6SRobert Mustacchi 		nvm->word_size = eecd & E1000_EECD_SIZE ? 256 : 64;
13975eba5b6SRobert Mustacchi 		break;
14075eba5b6SRobert Mustacchi 	}
14175eba5b6SRobert Mustacchi 
14275eba5b6SRobert Mustacchi 	/* Function Pointers */
14375eba5b6SRobert Mustacchi 	nvm->ops.acquire	= e1000_acquire_nvm_generic;
14475eba5b6SRobert Mustacchi 	nvm->ops.read		= e1000_read_nvm_microwire;
14575eba5b6SRobert Mustacchi 	nvm->ops.release	= e1000_release_nvm_generic;
14675eba5b6SRobert Mustacchi 	nvm->ops.update		= e1000_update_nvm_checksum_generic;
14775eba5b6SRobert Mustacchi 	nvm->ops.valid_led_default = e1000_valid_led_default_generic;
14875eba5b6SRobert Mustacchi 	nvm->ops.validate	= e1000_validate_nvm_checksum_generic;
14975eba5b6SRobert Mustacchi 	nvm->ops.write		= e1000_write_nvm_microwire;
15075eba5b6SRobert Mustacchi 
15175eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
15275eba5b6SRobert Mustacchi }
15375eba5b6SRobert Mustacchi 
15475eba5b6SRobert Mustacchi /**
15575eba5b6SRobert Mustacchi  * e1000_init_mac_params_82540 - Init MAC func ptrs.
15675eba5b6SRobert Mustacchi  * @hw: pointer to the HW structure
15775eba5b6SRobert Mustacchi  **/
e1000_init_mac_params_82540(struct e1000_hw * hw)15875eba5b6SRobert Mustacchi static s32 e1000_init_mac_params_82540(struct e1000_hw *hw)
15975eba5b6SRobert Mustacchi {
16075eba5b6SRobert Mustacchi 	struct e1000_mac_info *mac = &hw->mac;
16175eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
16275eba5b6SRobert Mustacchi 
16375eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_mac_params_82540");
16475eba5b6SRobert Mustacchi 
16575eba5b6SRobert Mustacchi 	/* Set media type */
16675eba5b6SRobert Mustacchi 	switch (hw->device_id) {
16775eba5b6SRobert Mustacchi 	case E1000_DEV_ID_82545EM_FIBER:
16875eba5b6SRobert Mustacchi 	case E1000_DEV_ID_82545GM_FIBER:
16975eba5b6SRobert Mustacchi 	case E1000_DEV_ID_82546EB_FIBER:
17075eba5b6SRobert Mustacchi 	case E1000_DEV_ID_82546GB_FIBER:
17175eba5b6SRobert Mustacchi 		hw->phy.media_type = e1000_media_type_fiber;
17275eba5b6SRobert Mustacchi 		break;
17375eba5b6SRobert Mustacchi 	case E1000_DEV_ID_82545GM_SERDES:
17475eba5b6SRobert Mustacchi 	case E1000_DEV_ID_82546GB_SERDES:
17575eba5b6SRobert Mustacchi 		hw->phy.media_type = e1000_media_type_internal_serdes;
17675eba5b6SRobert Mustacchi 		break;
17775eba5b6SRobert Mustacchi 	default:
17875eba5b6SRobert Mustacchi 		hw->phy.media_type = e1000_media_type_copper;
17975eba5b6SRobert Mustacchi 		break;
18075eba5b6SRobert Mustacchi 	}
18175eba5b6SRobert Mustacchi 
18275eba5b6SRobert Mustacchi 	/* Set mta register count */
18375eba5b6SRobert Mustacchi 	mac->mta_reg_count = 128;
18475eba5b6SRobert Mustacchi 	/* Set rar entry count */
18575eba5b6SRobert Mustacchi 	mac->rar_entry_count = E1000_RAR_ENTRIES;
18675eba5b6SRobert Mustacchi 
18775eba5b6SRobert Mustacchi 	/* Function pointers */
18875eba5b6SRobert Mustacchi 
18975eba5b6SRobert Mustacchi 	/* bus type/speed/width */
19075eba5b6SRobert Mustacchi 	mac->ops.get_bus_info = e1000_get_bus_info_pci_generic;
19175eba5b6SRobert Mustacchi 	/* function id */
19275eba5b6SRobert Mustacchi 	mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pci;
19375eba5b6SRobert Mustacchi 	/* reset */
19475eba5b6SRobert Mustacchi 	mac->ops.reset_hw = e1000_reset_hw_82540;
19575eba5b6SRobert Mustacchi 	/* hw initialization */
19675eba5b6SRobert Mustacchi 	mac->ops.init_hw = e1000_init_hw_82540;
19775eba5b6SRobert Mustacchi 	/* link setup */
19875eba5b6SRobert Mustacchi 	mac->ops.setup_link = e1000_setup_link_generic;
19975eba5b6SRobert Mustacchi 	/* physical interface setup */
20075eba5b6SRobert Mustacchi 	mac->ops.setup_physical_interface =
20175eba5b6SRobert Mustacchi 		(hw->phy.media_type == e1000_media_type_copper)
20275eba5b6SRobert Mustacchi 			? e1000_setup_copper_link_82540
20375eba5b6SRobert Mustacchi 			: e1000_setup_fiber_serdes_link_82540;
20475eba5b6SRobert Mustacchi 	/* check for link */
20575eba5b6SRobert Mustacchi 	switch (hw->phy.media_type) {
20675eba5b6SRobert Mustacchi 	case e1000_media_type_copper:
20775eba5b6SRobert Mustacchi 		mac->ops.check_for_link = e1000_check_for_copper_link_generic;
20875eba5b6SRobert Mustacchi 		break;
20975eba5b6SRobert Mustacchi 	case e1000_media_type_fiber:
21075eba5b6SRobert Mustacchi 		mac->ops.check_for_link = e1000_check_for_fiber_link_generic;
21175eba5b6SRobert Mustacchi 		break;
21275eba5b6SRobert Mustacchi 	case e1000_media_type_internal_serdes:
21375eba5b6SRobert Mustacchi 		mac->ops.check_for_link = e1000_check_for_serdes_link_generic;
21475eba5b6SRobert Mustacchi 		break;
21575eba5b6SRobert Mustacchi 	default:
21675eba5b6SRobert Mustacchi 		ret_val = -E1000_ERR_CONFIG;
21775eba5b6SRobert Mustacchi 		goto out;
21875eba5b6SRobert Mustacchi 		break;
21975eba5b6SRobert Mustacchi 	}
22075eba5b6SRobert Mustacchi 	/* link info */
22175eba5b6SRobert Mustacchi 	mac->ops.get_link_up_info =
22275eba5b6SRobert Mustacchi 		(hw->phy.media_type == e1000_media_type_copper)
22375eba5b6SRobert Mustacchi 			? e1000_get_speed_and_duplex_copper_generic
22475eba5b6SRobert Mustacchi 			: e1000_get_speed_and_duplex_fiber_serdes_generic;
22575eba5b6SRobert Mustacchi 	/* multicast address update */
22675eba5b6SRobert Mustacchi 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
22775eba5b6SRobert Mustacchi 	/* writing VFTA */
22875eba5b6SRobert Mustacchi 	mac->ops.write_vfta = e1000_write_vfta_generic;
22975eba5b6SRobert Mustacchi 	/* clearing VFTA */
23075eba5b6SRobert Mustacchi 	mac->ops.clear_vfta = e1000_clear_vfta_generic;
23175eba5b6SRobert Mustacchi 	/* read mac address */
23275eba5b6SRobert Mustacchi 	mac->ops.read_mac_addr = e1000_read_mac_addr_82540;
23375eba5b6SRobert Mustacchi 	/* ID LED init */
23475eba5b6SRobert Mustacchi 	mac->ops.id_led_init = e1000_id_led_init_generic;
23575eba5b6SRobert Mustacchi 	/* setup LED */
23675eba5b6SRobert Mustacchi 	mac->ops.setup_led = e1000_setup_led_generic;
23775eba5b6SRobert Mustacchi 	/* cleanup LED */
23875eba5b6SRobert Mustacchi 	mac->ops.cleanup_led = e1000_cleanup_led_generic;
23975eba5b6SRobert Mustacchi 	/* turn on/off LED */
24075eba5b6SRobert Mustacchi 	mac->ops.led_on = e1000_led_on_generic;
24175eba5b6SRobert Mustacchi 	mac->ops.led_off = e1000_led_off_generic;
24275eba5b6SRobert Mustacchi 	/* clear hardware counters */
24375eba5b6SRobert Mustacchi 	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82540;
24475eba5b6SRobert Mustacchi 
24575eba5b6SRobert Mustacchi out:
24675eba5b6SRobert Mustacchi 	return ret_val;
24775eba5b6SRobert Mustacchi }
24875eba5b6SRobert Mustacchi 
24975eba5b6SRobert Mustacchi /**
25075eba5b6SRobert Mustacchi  * e1000_init_function_pointers_82540 - Init func ptrs.
25175eba5b6SRobert Mustacchi  * @hw: pointer to the HW structure
25275eba5b6SRobert Mustacchi  *
25375eba5b6SRobert Mustacchi  * Called to initialize all function pointers and parameters.
25475eba5b6SRobert Mustacchi  **/
e1000_init_function_pointers_82540(struct e1000_hw * hw)25575eba5b6SRobert Mustacchi void e1000_init_function_pointers_82540(struct e1000_hw *hw)
25675eba5b6SRobert Mustacchi {
25775eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_function_pointers_82540");
25875eba5b6SRobert Mustacchi 
25975eba5b6SRobert Mustacchi 	hw->mac.ops.init_params = e1000_init_mac_params_82540;
26075eba5b6SRobert Mustacchi 	hw->nvm.ops.init_params = e1000_init_nvm_params_82540;
26175eba5b6SRobert Mustacchi 	hw->phy.ops.init_params = e1000_init_phy_params_82540;
26275eba5b6SRobert Mustacchi }
26375eba5b6SRobert Mustacchi 
26475eba5b6SRobert Mustacchi /**
26575eba5b6SRobert Mustacchi  *  e1000_reset_hw_82540 - Reset hardware
26675eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
26775eba5b6SRobert Mustacchi  *
26875eba5b6SRobert Mustacchi  *  This resets the hardware into a known state.
26975eba5b6SRobert Mustacchi  **/
e1000_reset_hw_82540(struct e1000_hw * hw)27075eba5b6SRobert Mustacchi static s32 e1000_reset_hw_82540(struct e1000_hw *hw)
27175eba5b6SRobert Mustacchi {
27275eba5b6SRobert Mustacchi 	u32 ctrl, manc;
27375eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
27475eba5b6SRobert Mustacchi 
27575eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_reset_hw_82540");
27675eba5b6SRobert Mustacchi 
27775eba5b6SRobert Mustacchi 	DEBUGOUT("Masking off all interrupts\n");
27875eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF);
27975eba5b6SRobert Mustacchi 
28075eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
28175eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
28275eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
28375eba5b6SRobert Mustacchi 
28475eba5b6SRobert Mustacchi 	/*
28575eba5b6SRobert Mustacchi 	 * Delay to allow any outstanding PCI transactions to complete
28675eba5b6SRobert Mustacchi 	 * before resetting the device.
28775eba5b6SRobert Mustacchi 	 */
28875eba5b6SRobert Mustacchi 	msec_delay(10);
28975eba5b6SRobert Mustacchi 
29075eba5b6SRobert Mustacchi 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
29175eba5b6SRobert Mustacchi 
29275eba5b6SRobert Mustacchi 	DEBUGOUT("Issuing a global reset to 82540/82545/82546 MAC\n");
29375eba5b6SRobert Mustacchi 	switch (hw->mac.type) {
29475eba5b6SRobert Mustacchi 	case e1000_82545_rev_3:
29575eba5b6SRobert Mustacchi 	case e1000_82546_rev_3:
29675eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_CTRL_DUP, ctrl | E1000_CTRL_RST);
29775eba5b6SRobert Mustacchi 		break;
29875eba5b6SRobert Mustacchi 	default:
29975eba5b6SRobert Mustacchi 		/*
30075eba5b6SRobert Mustacchi 		 * These controllers can't ack the 64-bit write when
30175eba5b6SRobert Mustacchi 		 * issuing the reset, so we use IO-mapping as a
30275eba5b6SRobert Mustacchi 		 * workaround to issue the reset.
30375eba5b6SRobert Mustacchi 		 */
30475eba5b6SRobert Mustacchi 		E1000_WRITE_REG_IO(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
30575eba5b6SRobert Mustacchi 		break;
30675eba5b6SRobert Mustacchi 	}
30775eba5b6SRobert Mustacchi 
30875eba5b6SRobert Mustacchi 	/* Wait for EEPROM reload */
30975eba5b6SRobert Mustacchi 	msec_delay(5);
31075eba5b6SRobert Mustacchi 
31175eba5b6SRobert Mustacchi 	/* Disable HW ARPs on ASF enabled adapters */
31275eba5b6SRobert Mustacchi 	manc = E1000_READ_REG(hw, E1000_MANC);
31375eba5b6SRobert Mustacchi 	manc &= ~E1000_MANC_ARP_EN;
31475eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_MANC, manc);
31575eba5b6SRobert Mustacchi 
31675eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
31775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICR);
31875eba5b6SRobert Mustacchi 
31975eba5b6SRobert Mustacchi 	return ret_val;
32075eba5b6SRobert Mustacchi }
32175eba5b6SRobert Mustacchi 
32275eba5b6SRobert Mustacchi /**
32375eba5b6SRobert Mustacchi  *  e1000_init_hw_82540 - Initialize hardware
32475eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
32575eba5b6SRobert Mustacchi  *
32675eba5b6SRobert Mustacchi  *  This inits the hardware readying it for operation.
32775eba5b6SRobert Mustacchi  **/
e1000_init_hw_82540(struct e1000_hw * hw)32875eba5b6SRobert Mustacchi static s32 e1000_init_hw_82540(struct e1000_hw *hw)
32975eba5b6SRobert Mustacchi {
33075eba5b6SRobert Mustacchi 	struct e1000_mac_info *mac = &hw->mac;
33175eba5b6SRobert Mustacchi 	u32 txdctl, ctrl_ext;
332*7c5988f9SRobert Mustacchi 	s32 ret_val;
33375eba5b6SRobert Mustacchi 	u16 i;
33475eba5b6SRobert Mustacchi 
33575eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_hw_82540");
33675eba5b6SRobert Mustacchi 
33775eba5b6SRobert Mustacchi 	/* Initialize identification LED */
33875eba5b6SRobert Mustacchi 	ret_val = mac->ops.id_led_init(hw);
33975eba5b6SRobert Mustacchi 	if (ret_val) {
34075eba5b6SRobert Mustacchi 		DEBUGOUT("Error initializing identification LED\n");
34175eba5b6SRobert Mustacchi 		/* This is not fatal and we should not stop init due to this */
34275eba5b6SRobert Mustacchi 	}
34375eba5b6SRobert Mustacchi 
34475eba5b6SRobert Mustacchi 	/* Disabling VLAN filtering */
34575eba5b6SRobert Mustacchi 	DEBUGOUT("Initializing the IEEE VLAN\n");
34675eba5b6SRobert Mustacchi 	if (mac->type < e1000_82545_rev_3)
34775eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_VET, 0);
34875eba5b6SRobert Mustacchi 
34975eba5b6SRobert Mustacchi 	mac->ops.clear_vfta(hw);
35075eba5b6SRobert Mustacchi 
35175eba5b6SRobert Mustacchi 	/* Setup the receive address. */
35275eba5b6SRobert Mustacchi 	e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
35375eba5b6SRobert Mustacchi 
35475eba5b6SRobert Mustacchi 	/* Zero out the Multicast HASH table */
35575eba5b6SRobert Mustacchi 	DEBUGOUT("Zeroing the MTA\n");
35675eba5b6SRobert Mustacchi 	for (i = 0; i < mac->mta_reg_count; i++) {
35775eba5b6SRobert Mustacchi 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
35875eba5b6SRobert Mustacchi 		/*
35975eba5b6SRobert Mustacchi 		 * Avoid back to back register writes by adding the register
36075eba5b6SRobert Mustacchi 		 * read (flush).  This is to protect against some strange
36175eba5b6SRobert Mustacchi 		 * bridge configurations that may issue Memory Write Block
36275eba5b6SRobert Mustacchi 		 * (MWB) to our register space.  The *_rev_3 hardware at
36375eba5b6SRobert Mustacchi 		 * least doesn't respond correctly to every other dword in an
36475eba5b6SRobert Mustacchi 		 * MWB to our register space.
36575eba5b6SRobert Mustacchi 		 */
36675eba5b6SRobert Mustacchi 		E1000_WRITE_FLUSH(hw);
36775eba5b6SRobert Mustacchi 	}
36875eba5b6SRobert Mustacchi 
36975eba5b6SRobert Mustacchi 	if (mac->type < e1000_82545_rev_3)
37075eba5b6SRobert Mustacchi 		e1000_pcix_mmrbc_workaround_generic(hw);
37175eba5b6SRobert Mustacchi 
37275eba5b6SRobert Mustacchi 	/* Setup link and flow control */
37375eba5b6SRobert Mustacchi 	ret_val = mac->ops.setup_link(hw);
37475eba5b6SRobert Mustacchi 
37575eba5b6SRobert Mustacchi 	txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0));
37675eba5b6SRobert Mustacchi 	txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
37775eba5b6SRobert Mustacchi 		  E1000_TXDCTL_FULL_TX_DESC_WB;
37875eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl);
37975eba5b6SRobert Mustacchi 
38075eba5b6SRobert Mustacchi 	/*
38175eba5b6SRobert Mustacchi 	 * Clear all of the statistics registers (clear on read).  It is
38275eba5b6SRobert Mustacchi 	 * important that we do this after we have tried to establish link
38375eba5b6SRobert Mustacchi 	 * because the symbol error count will increment wildly if there
38475eba5b6SRobert Mustacchi 	 * is no link.
38575eba5b6SRobert Mustacchi 	 */
38675eba5b6SRobert Mustacchi 	e1000_clear_hw_cntrs_82540(hw);
38775eba5b6SRobert Mustacchi 
38875eba5b6SRobert Mustacchi 	if ((hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER) ||
38975eba5b6SRobert Mustacchi 	    (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3)) {
39075eba5b6SRobert Mustacchi 		ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
39175eba5b6SRobert Mustacchi 		/*
39275eba5b6SRobert Mustacchi 		 * Relaxed ordering must be disabled to avoid a parity
39375eba5b6SRobert Mustacchi 		 * error crash in a PCI slot.
39475eba5b6SRobert Mustacchi 		 */
39575eba5b6SRobert Mustacchi 		ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
39675eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
39775eba5b6SRobert Mustacchi 	}
39875eba5b6SRobert Mustacchi 
39975eba5b6SRobert Mustacchi 	return ret_val;
40075eba5b6SRobert Mustacchi }
40175eba5b6SRobert Mustacchi 
40275eba5b6SRobert Mustacchi /**
40375eba5b6SRobert Mustacchi  *  e1000_setup_copper_link_82540 - Configure copper link settings
40475eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
40575eba5b6SRobert Mustacchi  *
40675eba5b6SRobert Mustacchi  *  Calls the appropriate function to configure the link for auto-neg or forced
40775eba5b6SRobert Mustacchi  *  speed and duplex.  Then we check for link, once link is established calls
40875eba5b6SRobert Mustacchi  *  to configure collision distance and flow control are called.  If link is
40975eba5b6SRobert Mustacchi  *  not established, we return -E1000_ERR_PHY (-2).
41075eba5b6SRobert Mustacchi  **/
e1000_setup_copper_link_82540(struct e1000_hw * hw)41175eba5b6SRobert Mustacchi static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw)
41275eba5b6SRobert Mustacchi {
41375eba5b6SRobert Mustacchi 	u32 ctrl;
414*7c5988f9SRobert Mustacchi 	s32 ret_val;
41575eba5b6SRobert Mustacchi 	u16 data;
41675eba5b6SRobert Mustacchi 
41775eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_setup_copper_link_82540");
41875eba5b6SRobert Mustacchi 
41975eba5b6SRobert Mustacchi 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
42075eba5b6SRobert Mustacchi 	ctrl |= E1000_CTRL_SLU;
42175eba5b6SRobert Mustacchi 	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
42275eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
42375eba5b6SRobert Mustacchi 
42475eba5b6SRobert Mustacchi 	ret_val = e1000_set_phy_mode_82540(hw);
42575eba5b6SRobert Mustacchi 	if (ret_val)
42675eba5b6SRobert Mustacchi 		goto out;
42775eba5b6SRobert Mustacchi 
42875eba5b6SRobert Mustacchi 	if (hw->mac.type == e1000_82545_rev_3 ||
42975eba5b6SRobert Mustacchi 	    hw->mac.type == e1000_82546_rev_3) {
43075eba5b6SRobert Mustacchi 		ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL,
43175eba5b6SRobert Mustacchi 					       &data);
43275eba5b6SRobert Mustacchi 		if (ret_val)
43375eba5b6SRobert Mustacchi 			goto out;
43475eba5b6SRobert Mustacchi 		data |= 0x00000008;
43575eba5b6SRobert Mustacchi 		ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL,
43675eba5b6SRobert Mustacchi 						data);
43775eba5b6SRobert Mustacchi 		if (ret_val)
43875eba5b6SRobert Mustacchi 			goto out;
43975eba5b6SRobert Mustacchi 	}
44075eba5b6SRobert Mustacchi 
44175eba5b6SRobert Mustacchi 	ret_val = e1000_copper_link_setup_m88(hw);
44275eba5b6SRobert Mustacchi 	if (ret_val)
44375eba5b6SRobert Mustacchi 		goto out;
44475eba5b6SRobert Mustacchi 
44575eba5b6SRobert Mustacchi 	ret_val = e1000_setup_copper_link_generic(hw);
44675eba5b6SRobert Mustacchi 
44775eba5b6SRobert Mustacchi out:
44875eba5b6SRobert Mustacchi 	return ret_val;
44975eba5b6SRobert Mustacchi }
45075eba5b6SRobert Mustacchi 
45175eba5b6SRobert Mustacchi /**
45275eba5b6SRobert Mustacchi  *  e1000_setup_fiber_serdes_link_82540 - Setup link for fiber/serdes
45375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
45475eba5b6SRobert Mustacchi  *
45575eba5b6SRobert Mustacchi  *  Set the output amplitude to the value in the EEPROM and adjust the VCO
45675eba5b6SRobert Mustacchi  *  speed to improve Bit Error Rate (BER) performance.  Configures collision
45775eba5b6SRobert Mustacchi  *  distance and flow control for fiber and serdes links.  Upon successful
45875eba5b6SRobert Mustacchi  *  setup, poll for link.
45975eba5b6SRobert Mustacchi  **/
e1000_setup_fiber_serdes_link_82540(struct e1000_hw * hw)46075eba5b6SRobert Mustacchi static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw)
46175eba5b6SRobert Mustacchi {
46275eba5b6SRobert Mustacchi 	struct e1000_mac_info *mac = &hw->mac;
46375eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
46475eba5b6SRobert Mustacchi 
46575eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_setup_fiber_serdes_link_82540");
46675eba5b6SRobert Mustacchi 
46775eba5b6SRobert Mustacchi 	switch (mac->type) {
46875eba5b6SRobert Mustacchi 	case e1000_82545_rev_3:
46975eba5b6SRobert Mustacchi 	case e1000_82546_rev_3:
47075eba5b6SRobert Mustacchi 		if (hw->phy.media_type == e1000_media_type_internal_serdes) {
47175eba5b6SRobert Mustacchi 			/*
47275eba5b6SRobert Mustacchi 			 * If we're on serdes media, adjust the output
47375eba5b6SRobert Mustacchi 			 * amplitude to value set in the EEPROM.
47475eba5b6SRobert Mustacchi 			 */
47575eba5b6SRobert Mustacchi 			ret_val = e1000_adjust_serdes_amplitude_82540(hw);
47675eba5b6SRobert Mustacchi 			if (ret_val)
47775eba5b6SRobert Mustacchi 				goto out;
47875eba5b6SRobert Mustacchi 		}
47975eba5b6SRobert Mustacchi 		/* Adjust VCO speed to improve BER performance */
48075eba5b6SRobert Mustacchi 		ret_val = e1000_set_vco_speed_82540(hw);
48175eba5b6SRobert Mustacchi 		if (ret_val)
48275eba5b6SRobert Mustacchi 			goto out;
48375eba5b6SRobert Mustacchi 	default:
48475eba5b6SRobert Mustacchi 		break;
48575eba5b6SRobert Mustacchi 	}
48675eba5b6SRobert Mustacchi 
48775eba5b6SRobert Mustacchi 	ret_val = e1000_setup_fiber_serdes_link_generic(hw);
48875eba5b6SRobert Mustacchi 
48975eba5b6SRobert Mustacchi out:
49075eba5b6SRobert Mustacchi 	return ret_val;
49175eba5b6SRobert Mustacchi }
49275eba5b6SRobert Mustacchi 
49375eba5b6SRobert Mustacchi /**
49475eba5b6SRobert Mustacchi  *  e1000_adjust_serdes_amplitude_82540 - Adjust amplitude based on EEPROM
49575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
49675eba5b6SRobert Mustacchi  *
49775eba5b6SRobert Mustacchi  *  Adjust the SERDES output amplitude based on the EEPROM settings.
49875eba5b6SRobert Mustacchi  **/
e1000_adjust_serdes_amplitude_82540(struct e1000_hw * hw)49975eba5b6SRobert Mustacchi static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw)
50075eba5b6SRobert Mustacchi {
501*7c5988f9SRobert Mustacchi 	s32 ret_val;
50275eba5b6SRobert Mustacchi 	u16 nvm_data;
50375eba5b6SRobert Mustacchi 
50475eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_adjust_serdes_amplitude_82540");
50575eba5b6SRobert Mustacchi 
50675eba5b6SRobert Mustacchi 	ret_val = hw->nvm.ops.read(hw, NVM_SERDES_AMPLITUDE, 1, &nvm_data);
50775eba5b6SRobert Mustacchi 	if (ret_val)
50875eba5b6SRobert Mustacchi 		goto out;
50975eba5b6SRobert Mustacchi 
51075eba5b6SRobert Mustacchi 	if (nvm_data != NVM_RESERVED_WORD) {
51175eba5b6SRobert Mustacchi 		/* Adjust serdes output amplitude only. */
51275eba5b6SRobert Mustacchi 		nvm_data &= NVM_SERDES_AMPLITUDE_MASK;
51375eba5b6SRobert Mustacchi 		ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_EXT_CTRL,
51475eba5b6SRobert Mustacchi 						nvm_data);
51575eba5b6SRobert Mustacchi 		if (ret_val)
51675eba5b6SRobert Mustacchi 			goto out;
51775eba5b6SRobert Mustacchi 	}
51875eba5b6SRobert Mustacchi 
51975eba5b6SRobert Mustacchi out:
52075eba5b6SRobert Mustacchi 	return ret_val;
52175eba5b6SRobert Mustacchi }
52275eba5b6SRobert Mustacchi 
52375eba5b6SRobert Mustacchi /**
52475eba5b6SRobert Mustacchi  *  e1000_set_vco_speed_82540 - Set VCO speed for better performance
52575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
52675eba5b6SRobert Mustacchi  *
52775eba5b6SRobert Mustacchi  *  Set the VCO speed to improve Bit Error Rate (BER) performance.
52875eba5b6SRobert Mustacchi  **/
e1000_set_vco_speed_82540(struct e1000_hw * hw)52975eba5b6SRobert Mustacchi static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw)
53075eba5b6SRobert Mustacchi {
531*7c5988f9SRobert Mustacchi 	s32  ret_val;
53275eba5b6SRobert Mustacchi 	u16 default_page = 0;
53375eba5b6SRobert Mustacchi 	u16 phy_data;
53475eba5b6SRobert Mustacchi 
53575eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_set_vco_speed_82540");
53675eba5b6SRobert Mustacchi 
53775eba5b6SRobert Mustacchi 	/* Set PHY register 30, page 5, bit 8 to 0 */
53875eba5b6SRobert Mustacchi 
53975eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_PAGE_SELECT,
54075eba5b6SRobert Mustacchi 				       &default_page);
54175eba5b6SRobert Mustacchi 	if (ret_val)
54275eba5b6SRobert Mustacchi 		goto out;
54375eba5b6SRobert Mustacchi 
54475eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
54575eba5b6SRobert Mustacchi 	if (ret_val)
54675eba5b6SRobert Mustacchi 		goto out;
54775eba5b6SRobert Mustacchi 
54875eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
54975eba5b6SRobert Mustacchi 	if (ret_val)
55075eba5b6SRobert Mustacchi 		goto out;
55175eba5b6SRobert Mustacchi 
55275eba5b6SRobert Mustacchi 	phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
55375eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
55475eba5b6SRobert Mustacchi 	if (ret_val)
55575eba5b6SRobert Mustacchi 		goto out;
55675eba5b6SRobert Mustacchi 
55775eba5b6SRobert Mustacchi 	/* Set PHY register 30, page 4, bit 11 to 1 */
55875eba5b6SRobert Mustacchi 
55975eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
56075eba5b6SRobert Mustacchi 	if (ret_val)
56175eba5b6SRobert Mustacchi 		goto out;
56275eba5b6SRobert Mustacchi 
56375eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
56475eba5b6SRobert Mustacchi 	if (ret_val)
56575eba5b6SRobert Mustacchi 		goto out;
56675eba5b6SRobert Mustacchi 
56775eba5b6SRobert Mustacchi 	phy_data |= M88E1000_PHY_VCO_REG_BIT11;
56875eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
56975eba5b6SRobert Mustacchi 	if (ret_val)
57075eba5b6SRobert Mustacchi 		goto out;
57175eba5b6SRobert Mustacchi 
57275eba5b6SRobert Mustacchi 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT,
57375eba5b6SRobert Mustacchi 					default_page);
57475eba5b6SRobert Mustacchi 
57575eba5b6SRobert Mustacchi out:
57675eba5b6SRobert Mustacchi 	return ret_val;
57775eba5b6SRobert Mustacchi }
57875eba5b6SRobert Mustacchi 
57975eba5b6SRobert Mustacchi /**
58075eba5b6SRobert Mustacchi  *  e1000_set_phy_mode_82540 - Set PHY to class A mode
58175eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
58275eba5b6SRobert Mustacchi  *
58375eba5b6SRobert Mustacchi  *  Sets the PHY to class A mode and assumes the following operations will
58475eba5b6SRobert Mustacchi  *  follow to enable the new class mode:
58575eba5b6SRobert Mustacchi  *    1.  Do a PHY soft reset.
58675eba5b6SRobert Mustacchi  *    2.  Restart auto-negotiation or force link.
58775eba5b6SRobert Mustacchi  **/
e1000_set_phy_mode_82540(struct e1000_hw * hw)58875eba5b6SRobert Mustacchi static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw)
58975eba5b6SRobert Mustacchi {
59075eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
59175eba5b6SRobert Mustacchi 	u16 nvm_data;
59275eba5b6SRobert Mustacchi 
59375eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_set_phy_mode_82540");
59475eba5b6SRobert Mustacchi 
59575eba5b6SRobert Mustacchi 	if (hw->mac.type != e1000_82545_rev_3)
59675eba5b6SRobert Mustacchi 		goto out;
59775eba5b6SRobert Mustacchi 
59875eba5b6SRobert Mustacchi 	ret_val = hw->nvm.ops.read(hw, NVM_PHY_CLASS_WORD, 1, &nvm_data);
59975eba5b6SRobert Mustacchi 	if (ret_val) {
60075eba5b6SRobert Mustacchi 		ret_val = -E1000_ERR_PHY;
60175eba5b6SRobert Mustacchi 		goto out;
60275eba5b6SRobert Mustacchi 	}
60375eba5b6SRobert Mustacchi 
60475eba5b6SRobert Mustacchi 	if ((nvm_data != NVM_RESERVED_WORD) && (nvm_data & NVM_PHY_CLASS_A)) {
60575eba5b6SRobert Mustacchi 		ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT,
60675eba5b6SRobert Mustacchi 						0x000B);
60775eba5b6SRobert Mustacchi 		if (ret_val) {
60875eba5b6SRobert Mustacchi 			ret_val = -E1000_ERR_PHY;
60975eba5b6SRobert Mustacchi 			goto out;
61075eba5b6SRobert Mustacchi 		}
61175eba5b6SRobert Mustacchi 		ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL,
61275eba5b6SRobert Mustacchi 						0x8104);
61375eba5b6SRobert Mustacchi 		if (ret_val) {
61475eba5b6SRobert Mustacchi 			ret_val = -E1000_ERR_PHY;
61575eba5b6SRobert Mustacchi 			goto out;
61675eba5b6SRobert Mustacchi 		}
61775eba5b6SRobert Mustacchi 
61875eba5b6SRobert Mustacchi 	}
61975eba5b6SRobert Mustacchi 
62075eba5b6SRobert Mustacchi out:
62175eba5b6SRobert Mustacchi 	return ret_val;
62275eba5b6SRobert Mustacchi }
62375eba5b6SRobert Mustacchi 
62475eba5b6SRobert Mustacchi /**
62575eba5b6SRobert Mustacchi  * e1000_power_down_phy_copper_82540 - Remove link in case of PHY power down
62675eba5b6SRobert Mustacchi  * @hw: pointer to the HW structure
62775eba5b6SRobert Mustacchi  *
62875eba5b6SRobert Mustacchi  * In the case of a PHY power down to save power, or to turn off link during a
62975eba5b6SRobert Mustacchi  * driver unload, or wake on lan is not enabled, remove the link.
63075eba5b6SRobert Mustacchi  **/
e1000_power_down_phy_copper_82540(struct e1000_hw * hw)63175eba5b6SRobert Mustacchi static void e1000_power_down_phy_copper_82540(struct e1000_hw *hw)
63275eba5b6SRobert Mustacchi {
63375eba5b6SRobert Mustacchi 	/* If the management interface is not enabled, then power down */
63475eba5b6SRobert Mustacchi 	if (!(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_SMBUS_EN))
63575eba5b6SRobert Mustacchi 		e1000_power_down_phy_copper(hw);
63675eba5b6SRobert Mustacchi 
63775eba5b6SRobert Mustacchi 	return;
63875eba5b6SRobert Mustacchi }
63975eba5b6SRobert Mustacchi 
64075eba5b6SRobert Mustacchi /**
64175eba5b6SRobert Mustacchi  *  e1000_clear_hw_cntrs_82540 - Clear device specific hardware counters
64275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
64375eba5b6SRobert Mustacchi  *
64475eba5b6SRobert Mustacchi  *  Clears the hardware counters by reading the counter registers.
64575eba5b6SRobert Mustacchi  **/
e1000_clear_hw_cntrs_82540(struct e1000_hw * hw)64675eba5b6SRobert Mustacchi static void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw)
64775eba5b6SRobert Mustacchi {
64875eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_clear_hw_cntrs_82540");
64975eba5b6SRobert Mustacchi 
65075eba5b6SRobert Mustacchi 	e1000_clear_hw_cntrs_base_generic(hw);
65175eba5b6SRobert Mustacchi 
65275eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC64);
65375eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC127);
65475eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC255);
65575eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC511);
65675eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC1023);
65775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC1522);
65875eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC64);
65975eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC127);
66075eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC255);
66175eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC511);
66275eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC1023);
66375eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC1522);
66475eba5b6SRobert Mustacchi 
66575eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ALGNERRC);
66675eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_RXERRC);
66775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_TNCRS);
66875eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_CEXTERR);
66975eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_TSCTC);
67075eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_TSCTFC);
67175eba5b6SRobert Mustacchi 
67275eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_MGTPRC);
67375eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_MGTPDC);
67475eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_MGTPTC);
67575eba5b6SRobert Mustacchi }
67675eba5b6SRobert Mustacchi 
67775eba5b6SRobert Mustacchi /**
67875eba5b6SRobert Mustacchi  *  e1000_read_mac_addr_82540 - Read device MAC address
67975eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
68075eba5b6SRobert Mustacchi  *
68175eba5b6SRobert Mustacchi  *  Reads the device MAC address from the EEPROM and stores the value.
68275eba5b6SRobert Mustacchi  *  Since devices with two ports use the same EEPROM, we increment the
68375eba5b6SRobert Mustacchi  *  last bit in the MAC address for the second port.
68475eba5b6SRobert Mustacchi  *
68575eba5b6SRobert Mustacchi  *  This version is being used over generic because of customer issues
68675eba5b6SRobert Mustacchi  *  with VmWare and Virtual Box when using generic. It seems in
68775eba5b6SRobert Mustacchi  *  the emulated 82545, RAR[0] does NOT have a valid address after a
68875eba5b6SRobert Mustacchi  *  reset, this older method works and using this breaks nothing for
68975eba5b6SRobert Mustacchi  *  these legacy adapters.
69075eba5b6SRobert Mustacchi  **/
e1000_read_mac_addr_82540(struct e1000_hw * hw)69175eba5b6SRobert Mustacchi s32 e1000_read_mac_addr_82540(struct e1000_hw *hw)
69275eba5b6SRobert Mustacchi {
69375eba5b6SRobert Mustacchi 	s32  ret_val = E1000_SUCCESS;
69475eba5b6SRobert Mustacchi 	u16 offset, nvm_data, i;
69575eba5b6SRobert Mustacchi 
69675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_read_mac_addr");
69775eba5b6SRobert Mustacchi 
69875eba5b6SRobert Mustacchi 	for (i = 0; i < ETH_ADDR_LEN; i += 2) {
69975eba5b6SRobert Mustacchi 		offset = i >> 1;
70075eba5b6SRobert Mustacchi 		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
70175eba5b6SRobert Mustacchi 		if (ret_val) {
70275eba5b6SRobert Mustacchi 			DEBUGOUT("NVM Read Error\n");
70375eba5b6SRobert Mustacchi 			goto out;
70475eba5b6SRobert Mustacchi 		}
70575eba5b6SRobert Mustacchi 		hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
70675eba5b6SRobert Mustacchi 		hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
70775eba5b6SRobert Mustacchi 	}
70875eba5b6SRobert Mustacchi 
70975eba5b6SRobert Mustacchi 	/* Flip last bit of mac address if we're on second port */
71075eba5b6SRobert Mustacchi 	if (hw->bus.func == E1000_FUNC_1)
71175eba5b6SRobert Mustacchi 		hw->mac.perm_addr[5] ^= 1;
71275eba5b6SRobert Mustacchi 
71375eba5b6SRobert Mustacchi 	for (i = 0; i < ETH_ADDR_LEN; i++)
71475eba5b6SRobert Mustacchi 		hw->mac.addr[i] = hw->mac.perm_addr[i];
71575eba5b6SRobert Mustacchi 
71675eba5b6SRobert Mustacchi out:
71775eba5b6SRobert Mustacchi 	return ret_val;
71875eba5b6SRobert Mustacchi }
719