175eba5b6SRobert Mustacchi /******************************************************************************
275eba5b6SRobert Mustacchi 
3*49b78600SRobert 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$*/
34592a4d85Scc 
3525f2d433Sxy /*
36d5c3073dSchenlu chen - Sun Microsystems - Beijing China  * 82543GC Gigabit Ethernet Controller (Fiber)
37d5c3073dSchenlu chen - Sun Microsystems - Beijing China  * 82543GC Gigabit Ethernet Controller (Copper)
38d5c3073dSchenlu chen - Sun Microsystems - Beijing China  * 82544EI Gigabit Ethernet Controller (Copper)
39d5c3073dSchenlu chen - Sun Microsystems - Beijing China  * 82544EI Gigabit Ethernet Controller (Fiber)
40d5c3073dSchenlu chen - Sun Microsystems - Beijing China  * 82544GC Gigabit Ethernet Controller (Copper)
41d5c3073dSchenlu chen - Sun Microsystems - Beijing China  * 82544GC Gigabit Ethernet Controller (LOM)
4225f2d433Sxy  */
4325f2d433Sxy 
4425f2d433Sxy #include "e1000_api.h"
4525f2d433Sxy 
4675eba5b6SRobert Mustacchi static s32  e1000_init_phy_params_82543(struct e1000_hw *hw);
4775eba5b6SRobert Mustacchi static s32  e1000_init_nvm_params_82543(struct e1000_hw *hw);
4875eba5b6SRobert Mustacchi static s32  e1000_init_mac_params_82543(struct e1000_hw *hw);
4975eba5b6SRobert Mustacchi static s32  e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset,
50*49b78600SRobert Mustacchi 				     u16 *data);
5175eba5b6SRobert Mustacchi static s32  e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset,
52*49b78600SRobert Mustacchi 				      u16 data);
5375eba5b6SRobert Mustacchi static s32  e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw);
5475eba5b6SRobert Mustacchi static s32  e1000_phy_hw_reset_82543(struct e1000_hw *hw);
5575eba5b6SRobert Mustacchi static s32  e1000_reset_hw_82543(struct e1000_hw *hw);
5675eba5b6SRobert Mustacchi static s32  e1000_init_hw_82543(struct e1000_hw *hw);
5775eba5b6SRobert Mustacchi static s32  e1000_setup_link_82543(struct e1000_hw *hw);
5875eba5b6SRobert Mustacchi static s32  e1000_setup_copper_link_82543(struct e1000_hw *hw);
5975eba5b6SRobert Mustacchi static s32  e1000_setup_fiber_link_82543(struct e1000_hw *hw);
6075eba5b6SRobert Mustacchi static s32  e1000_check_for_copper_link_82543(struct e1000_hw *hw);
6175eba5b6SRobert Mustacchi static s32  e1000_check_for_fiber_link_82543(struct e1000_hw *hw);
6275eba5b6SRobert Mustacchi static s32  e1000_led_on_82543(struct e1000_hw *hw);
6375eba5b6SRobert Mustacchi static s32  e1000_led_off_82543(struct e1000_hw *hw);
6425f2d433Sxy static void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset,
65*49b78600SRobert Mustacchi 				   u32 value);
6625f2d433Sxy static void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw);
6775eba5b6SRobert Mustacchi static s32  e1000_config_mac_to_phy_82543(struct e1000_hw *hw);
68592a4d85Scc static bool e1000_init_phy_disabled_82543(struct e1000_hw *hw);
6925f2d433Sxy static void e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl);
7075eba5b6SRobert Mustacchi static s32  e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw);
7125f2d433Sxy static void e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl);
7275eba5b6SRobert Mustacchi static u16  e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw);
7325f2d433Sxy static void e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data,
74*49b78600SRobert Mustacchi 					   u16 count);
75592a4d85Scc static bool e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw);
76592a4d85Scc static void e1000_set_tbi_sbp_82543(struct e1000_hw *hw, bool state);
7775eba5b6SRobert Mustacchi static s32  e1000_read_mac_addr_82543(struct e1000_hw *hw);
7825f2d433Sxy 
7975eba5b6SRobert Mustacchi 
8075eba5b6SRobert Mustacchi /**
8175eba5b6SRobert Mustacchi  *  e1000_init_phy_params_82543 - Init PHY func ptrs.
8275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
8375eba5b6SRobert Mustacchi  **/
e1000_init_phy_params_82543(struct e1000_hw * hw)8475eba5b6SRobert Mustacchi static s32 e1000_init_phy_params_82543(struct e1000_hw *hw)
8525f2d433Sxy {
8625f2d433Sxy 	struct e1000_phy_info *phy = &hw->phy;
8725f2d433Sxy 	s32 ret_val = E1000_SUCCESS;
8825f2d433Sxy 
8925f2d433Sxy 	DEBUGFUNC("e1000_init_phy_params_82543");
9025f2d433Sxy 
91592a4d85Scc 	if (hw->phy.media_type != e1000_media_type_copper) {
92*49b78600SRobert Mustacchi 		phy->type = e1000_phy_none;
9325f2d433Sxy 		goto out;
94592a4d85Scc 	} else {
95*49b78600SRobert Mustacchi 		phy->ops.power_up = e1000_power_up_phy_copper;
96*49b78600SRobert Mustacchi 		phy->ops.power_down = e1000_power_down_phy_copper;
9725f2d433Sxy 	}
9825f2d433Sxy 
99*49b78600SRobert Mustacchi 	phy->addr		= 1;
100*49b78600SRobert Mustacchi 	phy->autoneg_mask	= AUTONEG_ADVERTISE_SPEED_DEFAULT;
101*49b78600SRobert Mustacchi 	phy->reset_delay_us	= 10000;
102*49b78600SRobert Mustacchi 	phy->type		= e1000_phy_m88;
10325f2d433Sxy 
10425f2d433Sxy 	/* Function Pointers */
105*49b78600SRobert Mustacchi 	phy->ops.check_polarity	= e1000_check_polarity_m88;
106*49b78600SRobert Mustacchi 	phy->ops.commit		= e1000_phy_sw_reset_generic;
107*49b78600SRobert Mustacchi 	phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_82543;
108*49b78600SRobert Mustacchi 	phy->ops.get_cable_length = e1000_get_cable_length_m88;
109*49b78600SRobert Mustacchi 	phy->ops.get_cfg_done	= e1000_get_cfg_done_generic;
110*49b78600SRobert Mustacchi 	phy->ops.read_reg	= (hw->mac.type == e1000_82543)
111*49b78600SRobert Mustacchi 				  ? e1000_read_phy_reg_82543
112*49b78600SRobert Mustacchi 				  : e1000_read_phy_reg_m88;
113*49b78600SRobert Mustacchi 	phy->ops.reset		= (hw->mac.type == e1000_82543)
114*49b78600SRobert Mustacchi 				  ? e1000_phy_hw_reset_82543
115*49b78600SRobert Mustacchi 				  : e1000_phy_hw_reset_generic;
116*49b78600SRobert Mustacchi 	phy->ops.write_reg	= (hw->mac.type == e1000_82543)
117*49b78600SRobert Mustacchi 				  ? e1000_write_phy_reg_82543
118*49b78600SRobert Mustacchi 				  : e1000_write_phy_reg_m88;
119*49b78600SRobert Mustacchi 	phy->ops.get_info	= e1000_get_phy_info_m88;
12025f2d433Sxy 
12125f2d433Sxy 	/*
12225f2d433Sxy 	 * The external PHY of the 82543 can be in a funky state.
12325f2d433Sxy 	 * Resetting helps us read the PHY registers for acquiring
12425f2d433Sxy 	 * the PHY ID.
12525f2d433Sxy 	 */
12625f2d433Sxy 	if (!e1000_init_phy_disabled_82543(hw)) {
127592a4d85Scc 		ret_val = phy->ops.reset(hw);
12825f2d433Sxy 		if (ret_val) {
12925f2d433Sxy 			DEBUGOUT("Resetting PHY during init failed.\n");
13025f2d433Sxy 			goto out;
13125f2d433Sxy 		}
13225f2d433Sxy 		msec_delay(20);
13325f2d433Sxy 	}
13425f2d433Sxy 
13525f2d433Sxy 	ret_val = e1000_get_phy_id(hw);
13625f2d433Sxy 	if (ret_val)
13725f2d433Sxy 		goto out;
13825f2d433Sxy 
13925f2d433Sxy 	/* Verify phy id */
14025f2d433Sxy 	switch (hw->mac.type) {
14125f2d433Sxy 	case e1000_82543:
14225f2d433Sxy 		if (phy->id != M88E1000_E_PHY_ID) {
14325f2d433Sxy 			ret_val = -E1000_ERR_PHY;
14425f2d433Sxy 			goto out;
14525f2d433Sxy 		}
14625f2d433Sxy 		break;
14725f2d433Sxy 	case e1000_82544:
14825f2d433Sxy 		if (phy->id != M88E1000_I_PHY_ID) {
14925f2d433Sxy 			ret_val = -E1000_ERR_PHY;
15025f2d433Sxy 			goto out;
15125f2d433Sxy 		}
15225f2d433Sxy 		break;
15325f2d433Sxy 	default:
15425f2d433Sxy 		ret_val = -E1000_ERR_PHY;
15525f2d433Sxy 		goto out;
15675eba5b6SRobert Mustacchi 		break;
15725f2d433Sxy 	}
15825f2d433Sxy 
15925f2d433Sxy out:
16075eba5b6SRobert Mustacchi 	return ret_val;
16125f2d433Sxy }
16225f2d433Sxy 
16375eba5b6SRobert Mustacchi /**
16475eba5b6SRobert Mustacchi  *  e1000_init_nvm_params_82543 - Init NVM func ptrs.
16575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
16675eba5b6SRobert Mustacchi  **/
e1000_init_nvm_params_82543(struct e1000_hw * hw)16775eba5b6SRobert Mustacchi static s32 e1000_init_nvm_params_82543(struct e1000_hw *hw)
16825f2d433Sxy {
16925f2d433Sxy 	struct e1000_nvm_info *nvm = &hw->nvm;
17025f2d433Sxy 
17125f2d433Sxy 	DEBUGFUNC("e1000_init_nvm_params_82543");
17225f2d433Sxy 
173*49b78600SRobert Mustacchi 	nvm->type		= e1000_nvm_eeprom_microwire;
174*49b78600SRobert Mustacchi 	nvm->word_size		= 64;
175*49b78600SRobert Mustacchi 	nvm->delay_usec		= 50;
176*49b78600SRobert Mustacchi 	nvm->address_bits	=  6;
177*49b78600SRobert Mustacchi 	nvm->opcode_bits	=  3;
17825f2d433Sxy 
17925f2d433Sxy 	/* Function Pointers */
180*49b78600SRobert Mustacchi 	nvm->ops.read		= e1000_read_nvm_microwire;
181*49b78600SRobert Mustacchi 	nvm->ops.update		= e1000_update_nvm_checksum_generic;
182592a4d85Scc 	nvm->ops.valid_led_default = e1000_valid_led_default_generic;
183*49b78600SRobert Mustacchi 	nvm->ops.validate	= e1000_validate_nvm_checksum_generic;
184*49b78600SRobert Mustacchi 	nvm->ops.write		= e1000_write_nvm_microwire;
18525f2d433Sxy 
18675eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
18725f2d433Sxy }
18825f2d433Sxy 
18975eba5b6SRobert Mustacchi /**
19075eba5b6SRobert Mustacchi  *  e1000_init_mac_params_82543 - Init MAC func ptrs.
19175eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
19275eba5b6SRobert Mustacchi  **/
e1000_init_mac_params_82543(struct e1000_hw * hw)19375eba5b6SRobert Mustacchi static s32 e1000_init_mac_params_82543(struct e1000_hw *hw)
19425f2d433Sxy {
19525f2d433Sxy 	struct e1000_mac_info *mac = &hw->mac;
19625f2d433Sxy 
19725f2d433Sxy 	DEBUGFUNC("e1000_init_mac_params_82543");
19825f2d433Sxy 
19925f2d433Sxy 	/* Set media type */
20025f2d433Sxy 	switch (hw->device_id) {
20125f2d433Sxy 	case E1000_DEV_ID_82543GC_FIBER:
20225f2d433Sxy 	case E1000_DEV_ID_82544EI_FIBER:
203592a4d85Scc 		hw->phy.media_type = e1000_media_type_fiber;
20425f2d433Sxy 		break;
20525f2d433Sxy 	default:
206592a4d85Scc 		hw->phy.media_type = e1000_media_type_copper;
20725f2d433Sxy 		break;
20825f2d433Sxy 	}
20925f2d433Sxy 
21025f2d433Sxy 	/* Set mta register count */
21125f2d433Sxy 	mac->mta_reg_count = 128;
21225f2d433Sxy 	/* Set rar entry count */
21325f2d433Sxy 	mac->rar_entry_count = E1000_RAR_ENTRIES;
21425f2d433Sxy 
21525f2d433Sxy 	/* Function pointers */
21625f2d433Sxy 
21725f2d433Sxy 	/* bus type/speed/width */
218592a4d85Scc 	mac->ops.get_bus_info = e1000_get_bus_info_pci_generic;
219caf05df5SMiles Xu, Sun Microsystems 	/* function id */
220caf05df5SMiles Xu, Sun Microsystems 	mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pci;
22125f2d433Sxy 	/* reset */
222592a4d85Scc 	mac->ops.reset_hw = e1000_reset_hw_82543;
22325f2d433Sxy 	/* hw initialization */
224592a4d85Scc 	mac->ops.init_hw = e1000_init_hw_82543;
22525f2d433Sxy 	/* link setup */
226592a4d85Scc 	mac->ops.setup_link = e1000_setup_link_82543;
22725f2d433Sxy 	/* physical interface setup */
228592a4d85Scc 	mac->ops.setup_physical_interface =
229*49b78600SRobert Mustacchi 		(hw->phy.media_type == e1000_media_type_copper)
230*49b78600SRobert Mustacchi 		 ? e1000_setup_copper_link_82543 : e1000_setup_fiber_link_82543;
23125f2d433Sxy 	/* check for link */
232592a4d85Scc 	mac->ops.check_for_link =
233*49b78600SRobert Mustacchi 		(hw->phy.media_type == e1000_media_type_copper)
234*49b78600SRobert Mustacchi 		 ? e1000_check_for_copper_link_82543
235*49b78600SRobert Mustacchi 		 : e1000_check_for_fiber_link_82543;
23625f2d433Sxy 	/* link info */
237592a4d85Scc 	mac->ops.get_link_up_info =
238*49b78600SRobert Mustacchi 		(hw->phy.media_type == e1000_media_type_copper)
239*49b78600SRobert Mustacchi 		 ? e1000_get_speed_and_duplex_copper_generic
240*49b78600SRobert Mustacchi 		 : e1000_get_speed_and_duplex_fiber_serdes_generic;
24125f2d433Sxy 	/* multicast address update */
242592a4d85Scc 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
24325f2d433Sxy 	/* writing VFTA */
244592a4d85Scc 	mac->ops.write_vfta = e1000_write_vfta_82543;
24525f2d433Sxy 	/* clearing VFTA */
246592a4d85Scc 	mac->ops.clear_vfta = e1000_clear_vfta_generic;
24775eba5b6SRobert Mustacchi 	/* read mac address */
24875eba5b6SRobert Mustacchi 	mac->ops.read_mac_addr = e1000_read_mac_addr_82543;
24925f2d433Sxy 	/* turn on/off LED */
250592a4d85Scc 	mac->ops.led_on = e1000_led_on_82543;
251592a4d85Scc 	mac->ops.led_off = e1000_led_off_82543;
25225f2d433Sxy 	/* clear hardware counters */
253592a4d85Scc 	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82543;
25425f2d433Sxy 
25525f2d433Sxy 	/* Set tbi compatibility */
25625f2d433Sxy 	if ((hw->mac.type != e1000_82543) ||
257592a4d85Scc 	    (hw->phy.media_type == e1000_media_type_fiber))
25875eba5b6SRobert Mustacchi 		e1000_set_tbi_compatibility_82543(hw, FALSE);
25925f2d433Sxy 
26075eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
26125f2d433Sxy }
26225f2d433Sxy 
26375eba5b6SRobert Mustacchi /**
26475eba5b6SRobert Mustacchi  *  e1000_init_function_pointers_82543 - Init func ptrs.
26575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
26625f2d433Sxy  *
26775eba5b6SRobert Mustacchi  *  Called to initialize all function pointers and parameters.
26875eba5b6SRobert Mustacchi  **/
e1000_init_function_pointers_82543(struct e1000_hw * hw)26975eba5b6SRobert Mustacchi void e1000_init_function_pointers_82543(struct e1000_hw *hw)
27025f2d433Sxy {
27125f2d433Sxy 	DEBUGFUNC("e1000_init_function_pointers_82543");
27225f2d433Sxy 
273592a4d85Scc 	hw->mac.ops.init_params = e1000_init_mac_params_82543;
274592a4d85Scc 	hw->nvm.ops.init_params = e1000_init_nvm_params_82543;
275592a4d85Scc 	hw->phy.ops.init_params = e1000_init_phy_params_82543;
27625f2d433Sxy }
27725f2d433Sxy 
27875eba5b6SRobert Mustacchi /**
27975eba5b6SRobert Mustacchi  *  e1000_tbi_compatibility_enabled_82543 - Returns TBI compat status
28075eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
28125f2d433Sxy  *
28275eba5b6SRobert Mustacchi  *  Returns the current status of 10-bit Interface (TBI) compatibility
28375eba5b6SRobert Mustacchi  *  (enabled/disabled).
28475eba5b6SRobert Mustacchi  **/
e1000_tbi_compatibility_enabled_82543(struct e1000_hw * hw)28575eba5b6SRobert Mustacchi static bool e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw)
28625f2d433Sxy {
287d5c3073dSchenlu chen - Sun Microsystems - Beijing China 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
28875eba5b6SRobert Mustacchi 	bool state = FALSE;
28925f2d433Sxy 
29025f2d433Sxy 	DEBUGFUNC("e1000_tbi_compatibility_enabled_82543");
29125f2d433Sxy 
29225f2d433Sxy 	if (hw->mac.type != e1000_82543) {
29325f2d433Sxy 		DEBUGOUT("TBI compatibility workaround for 82543 only.\n");
29425f2d433Sxy 		goto out;
29525f2d433Sxy 	}
29625f2d433Sxy 
297*49b78600SRobert Mustacchi 	state = !!(dev_spec->tbi_compatibility & TBI_COMPAT_ENABLED);
29825f2d433Sxy 
29925f2d433Sxy out:
30075eba5b6SRobert Mustacchi 	return state;
30125f2d433Sxy }
30225f2d433Sxy 
30375eba5b6SRobert Mustacchi /**
30475eba5b6SRobert Mustacchi  *  e1000_set_tbi_compatibility_82543 - Set TBI compatibility
30575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
30675eba5b6SRobert Mustacchi  *  @state: enable/disable TBI compatibility
30725f2d433Sxy  *
30875eba5b6SRobert Mustacchi  *  Enables or disabled 10-bit Interface (TBI) compatibility.
30975eba5b6SRobert Mustacchi  **/
e1000_set_tbi_compatibility_82543(struct e1000_hw * hw,bool state)31075eba5b6SRobert Mustacchi void e1000_set_tbi_compatibility_82543(struct e1000_hw *hw, bool state)
31125f2d433Sxy {
312d5c3073dSchenlu chen - Sun Microsystems - Beijing China 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
31325f2d433Sxy 
31425f2d433Sxy 	DEBUGFUNC("e1000_set_tbi_compatibility_82543");
31525f2d433Sxy 
31625f2d433Sxy 	if (hw->mac.type != e1000_82543) {
31725f2d433Sxy 		DEBUGOUT("TBI compatibility workaround for 82543 only.\n");
31875eba5b6SRobert Mustacchi 		goto out;
31925f2d433Sxy 	}
32025f2d433Sxy 
32125f2d433Sxy 	if (state)
32225f2d433Sxy 		dev_spec->tbi_compatibility |= TBI_COMPAT_ENABLED;
32325f2d433Sxy 	else
32425f2d433Sxy 		dev_spec->tbi_compatibility &= ~TBI_COMPAT_ENABLED;
32575eba5b6SRobert Mustacchi 
32675eba5b6SRobert Mustacchi out:
32775eba5b6SRobert Mustacchi 	return;
32825f2d433Sxy }
32925f2d433Sxy 
33075eba5b6SRobert Mustacchi /**
33175eba5b6SRobert Mustacchi  *  e1000_tbi_sbp_enabled_82543 - Returns TBI SBP status
33275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
33325f2d433Sxy  *
33475eba5b6SRobert Mustacchi  *  Returns the current status of 10-bit Interface (TBI) store bad packet (SBP)
33575eba5b6SRobert Mustacchi  *  (enabled/disabled).
33675eba5b6SRobert Mustacchi  **/
e1000_tbi_sbp_enabled_82543(struct e1000_hw * hw)33775eba5b6SRobert Mustacchi bool e1000_tbi_sbp_enabled_82543(struct e1000_hw *hw)
33825f2d433Sxy {
339d5c3073dSchenlu chen - Sun Microsystems - Beijing China 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
34075eba5b6SRobert Mustacchi 	bool state = FALSE;
34125f2d433Sxy 
34225f2d433Sxy 	DEBUGFUNC("e1000_tbi_sbp_enabled_82543");
34325f2d433Sxy 
34425f2d433Sxy 	if (hw->mac.type != e1000_82543) {
34525f2d433Sxy 		DEBUGOUT("TBI compatibility workaround for 82543 only.\n");
34625f2d433Sxy 		goto out;
34725f2d433Sxy 	}
34825f2d433Sxy 
349*49b78600SRobert Mustacchi 	state = !!(dev_spec->tbi_compatibility & TBI_SBP_ENABLED);
35025f2d433Sxy 
35125f2d433Sxy out:
35275eba5b6SRobert Mustacchi 	return state;
35325f2d433Sxy }
35425f2d433Sxy 
35575eba5b6SRobert Mustacchi /**
35675eba5b6SRobert Mustacchi  *  e1000_set_tbi_sbp_82543 - Set TBI SBP
35775eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
35875eba5b6SRobert Mustacchi  *  @state: enable/disable TBI store bad packet
35925f2d433Sxy  *
36075eba5b6SRobert Mustacchi  *  Enables or disabled 10-bit Interface (TBI) store bad packet (SBP).
36175eba5b6SRobert Mustacchi  **/
e1000_set_tbi_sbp_82543(struct e1000_hw * hw,bool state)36275eba5b6SRobert Mustacchi static void e1000_set_tbi_sbp_82543(struct e1000_hw *hw, bool state)
36325f2d433Sxy {
364d5c3073dSchenlu chen - Sun Microsystems - Beijing China 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
36525f2d433Sxy 
36625f2d433Sxy 	DEBUGFUNC("e1000_set_tbi_sbp_82543");
36725f2d433Sxy 
36825f2d433Sxy 	if (state && e1000_tbi_compatibility_enabled_82543(hw))
36925f2d433Sxy 		dev_spec->tbi_compatibility |= TBI_SBP_ENABLED;
37025f2d433Sxy 	else
37125f2d433Sxy 		dev_spec->tbi_compatibility &= ~TBI_SBP_ENABLED;
37275eba5b6SRobert Mustacchi 
37375eba5b6SRobert Mustacchi 	return;
37425f2d433Sxy }
37525f2d433Sxy 
37675eba5b6SRobert Mustacchi /**
37775eba5b6SRobert Mustacchi  *  e1000_init_phy_disabled_82543 - Returns init PHY status
37875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
37925f2d433Sxy  *
38075eba5b6SRobert Mustacchi  *  Returns the current status of whether PHY initialization is disabled.
38175eba5b6SRobert Mustacchi  *  True if PHY initialization is disabled else FALSE.
38275eba5b6SRobert Mustacchi  **/
e1000_init_phy_disabled_82543(struct e1000_hw * hw)38375eba5b6SRobert Mustacchi static bool e1000_init_phy_disabled_82543(struct e1000_hw *hw)
38425f2d433Sxy {
385d5c3073dSchenlu chen - Sun Microsystems - Beijing China 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
386592a4d85Scc 	bool ret_val;
38725f2d433Sxy 
38825f2d433Sxy 	DEBUGFUNC("e1000_init_phy_disabled_82543");
38925f2d433Sxy 
39025f2d433Sxy 	if (hw->mac.type != e1000_82543) {
39175eba5b6SRobert Mustacchi 		ret_val = FALSE;
39225f2d433Sxy 		goto out;
39325f2d433Sxy 	}
39425f2d433Sxy 
39525f2d433Sxy 	ret_val = dev_spec->init_phy_disabled;
39625f2d433Sxy 
39725f2d433Sxy out:
39875eba5b6SRobert Mustacchi 	return ret_val;
39925f2d433Sxy }
40025f2d433Sxy 
40175eba5b6SRobert Mustacchi /**
40275eba5b6SRobert Mustacchi  *  e1000_tbi_adjust_stats_82543 - Adjust stats when TBI enabled
40375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
40475eba5b6SRobert Mustacchi  *  @stats: Struct containing statistic register values
40575eba5b6SRobert Mustacchi  *  @frame_len: The length of the frame in question
40675eba5b6SRobert Mustacchi  *  @mac_addr: The Ethernet destination address of the frame in question
40775eba5b6SRobert Mustacchi  *  @max_frame_size: The maximum frame size
40825f2d433Sxy  *
40975eba5b6SRobert Mustacchi  *  Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
41075eba5b6SRobert Mustacchi  **/
e1000_tbi_adjust_stats_82543(struct e1000_hw * hw,struct e1000_hw_stats * stats,u32 frame_len,u8 * mac_addr,u32 max_frame_size)41175eba5b6SRobert Mustacchi void e1000_tbi_adjust_stats_82543(struct e1000_hw *hw,
412*49b78600SRobert Mustacchi 				  struct e1000_hw_stats *stats, u32 frame_len,
413*49b78600SRobert Mustacchi 				  u8 *mac_addr, u32 max_frame_size)
41425f2d433Sxy {
41525f2d433Sxy 	if (!(e1000_tbi_sbp_enabled_82543(hw)))
41675eba5b6SRobert Mustacchi 		goto out;
41725f2d433Sxy 
41825f2d433Sxy 	/* First adjust the frame length. */
41925f2d433Sxy 	frame_len--;
42025f2d433Sxy 	/*
42125f2d433Sxy 	 * We need to adjust the statistics counters, since the hardware
42225f2d433Sxy 	 * counters overcount this packet as a CRC error and undercount
42325f2d433Sxy 	 * the packet as a good packet
42425f2d433Sxy 	 */
425*49b78600SRobert Mustacchi 	/* This packet should not be counted as a CRC error. */
42625f2d433Sxy 	stats->crcerrs--;
427*49b78600SRobert Mustacchi 	/* This packet does count as a Good Packet Received. */
42825f2d433Sxy 	stats->gprc++;
42925f2d433Sxy 
430*49b78600SRobert Mustacchi 	/* Adjust the Good Octets received counters */
431592a4d85Scc 	stats->gorc += frame_len;
432592a4d85Scc 
43325f2d433Sxy 	/*
43475eba5b6SRobert Mustacchi 	 * Is this a broadcast or multicast?  Check broadcast first,
43575eba5b6SRobert Mustacchi 	 * since the test for a multicast frame will test positive on
43675eba5b6SRobert Mustacchi 	 * a broadcast frame.
43725f2d433Sxy 	 */
43825f2d433Sxy 	if ((mac_addr[0] == 0xff) && (mac_addr[1] == 0xff))
43925f2d433Sxy 		/* Broadcast packet */
44025f2d433Sxy 		stats->bprc++;
44125f2d433Sxy 	else if (*mac_addr & 0x01)
44225f2d433Sxy 		/* Multicast packet */
44325f2d433Sxy 		stats->mprc++;
44425f2d433Sxy 
44525f2d433Sxy 	/*
446*49b78600SRobert Mustacchi 	 * In this case, the hardware has over counted the number of
44725f2d433Sxy 	 * oversize frames.
44825f2d433Sxy 	 */
449592a4d85Scc 	if ((frame_len == max_frame_size) && (stats->roc > 0))
45025f2d433Sxy 		stats->roc--;
45125f2d433Sxy 
45225f2d433Sxy 	/*
45325f2d433Sxy 	 * Adjust the bin counters when the extra byte put the frame in the
45425f2d433Sxy 	 * wrong bin. Remember that the frame_len was adjusted above.
45525f2d433Sxy 	 */
45625f2d433Sxy 	if (frame_len == 64) {
45725f2d433Sxy 		stats->prc64++;
45825f2d433Sxy 		stats->prc127--;
45925f2d433Sxy 	} else if (frame_len == 127) {
46025f2d433Sxy 		stats->prc127++;
46125f2d433Sxy 		stats->prc255--;
46225f2d433Sxy 	} else if (frame_len == 255) {
46325f2d433Sxy 		stats->prc255++;
46425f2d433Sxy 		stats->prc511--;
46525f2d433Sxy 	} else if (frame_len == 511) {
46625f2d433Sxy 		stats->prc511++;
46725f2d433Sxy 		stats->prc1023--;
46825f2d433Sxy 	} else if (frame_len == 1023) {
46925f2d433Sxy 		stats->prc1023++;
47025f2d433Sxy 		stats->prc1522--;
47125f2d433Sxy 	} else if (frame_len == 1522) {
47225f2d433Sxy 		stats->prc1522++;
47325f2d433Sxy 	}
47475eba5b6SRobert Mustacchi 
47575eba5b6SRobert Mustacchi out:
47675eba5b6SRobert Mustacchi 	return;
47725f2d433Sxy }
47825f2d433Sxy 
47975eba5b6SRobert Mustacchi /**
48075eba5b6SRobert Mustacchi  *  e1000_read_phy_reg_82543 - Read PHY register
48175eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
48275eba5b6SRobert Mustacchi  *  @offset: register offset to be read
48375eba5b6SRobert Mustacchi  *  @data: pointer to the read data
48425f2d433Sxy  *
48575eba5b6SRobert Mustacchi  *  Reads the PHY at offset and stores the information read to data.
48675eba5b6SRobert Mustacchi  **/
e1000_read_phy_reg_82543(struct e1000_hw * hw,u32 offset,u16 * data)48775eba5b6SRobert Mustacchi static s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 *data)
48825f2d433Sxy {
48925f2d433Sxy 	u32 mdic;
49025f2d433Sxy 	s32 ret_val = E1000_SUCCESS;
49125f2d433Sxy 
49225f2d433Sxy 	DEBUGFUNC("e1000_read_phy_reg_82543");
49325f2d433Sxy 
49425f2d433Sxy 	if (offset > MAX_PHY_REG_ADDRESS) {
49525f2d433Sxy 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
49625f2d433Sxy 		ret_val = -E1000_ERR_PARAM;
49725f2d433Sxy 		goto out;
49825f2d433Sxy 	}
49925f2d433Sxy 
50025f2d433Sxy 	/*
50125f2d433Sxy 	 * We must first send a preamble through the MDIO pin to signal the
50225f2d433Sxy 	 * beginning of an MII instruction.  This is done by sending 32
50325f2d433Sxy 	 * consecutive "1" bits.
50425f2d433Sxy 	 */
50525f2d433Sxy 	e1000_shift_out_mdi_bits_82543(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
50625f2d433Sxy 
50725f2d433Sxy 	/*
50825f2d433Sxy 	 * Now combine the next few fields that are required for a read
50925f2d433Sxy 	 * operation.  We use this method instead of calling the
51025f2d433Sxy 	 * e1000_shift_out_mdi_bits routine five different times.  The format
51125f2d433Sxy 	 * of an MII read instruction consists of a shift out of 14 bits and
51225f2d433Sxy 	 * is defined as follows:
513*49b78600SRobert Mustacchi 	 *         <Preamble><SOF><Op Code><Phy Addr><Offset>
51425f2d433Sxy 	 * followed by a shift in of 18 bits.  This first two bits shifted in
51525f2d433Sxy 	 * are TurnAround bits used to avoid contention on the MDIO pin when a
51625f2d433Sxy 	 * READ operation is performed.  These two bits are thrown away
51725f2d433Sxy 	 * followed by a shift in of 16 bits which contains the desired data.
51825f2d433Sxy 	 */
51925f2d433Sxy 	mdic = (offset | (hw->phy.addr << 5) |
52075eba5b6SRobert Mustacchi 		(PHY_OP_READ << 10) | (PHY_SOF << 12));
52125f2d433Sxy 
52225f2d433Sxy 	e1000_shift_out_mdi_bits_82543(hw, mdic, 14);
52325f2d433Sxy 
52425f2d433Sxy 	/*
52525f2d433Sxy 	 * Now that we've shifted out the read command to the MII, we need to
52625f2d433Sxy 	 * "shift in" the 16-bit value (18 total bits) of the requested PHY
52725f2d433Sxy 	 * register address.
52825f2d433Sxy 	 */
52925f2d433Sxy 	*data = e1000_shift_in_mdi_bits_82543(hw);
53025f2d433Sxy 
53125f2d433Sxy out:
53275eba5b6SRobert Mustacchi 	return ret_val;
53325f2d433Sxy }
53425f2d433Sxy 
53575eba5b6SRobert Mustacchi /**
53675eba5b6SRobert Mustacchi  *  e1000_write_phy_reg_82543 - Write PHY register
53775eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
53875eba5b6SRobert Mustacchi  *  @offset: register offset to be written
53975eba5b6SRobert Mustacchi  *  @data: pointer to the data to be written at offset
54025f2d433Sxy  *
54175eba5b6SRobert Mustacchi  *  Writes data to the PHY at offset.
54275eba5b6SRobert Mustacchi  **/
e1000_write_phy_reg_82543(struct e1000_hw * hw,u32 offset,u16 data)54375eba5b6SRobert Mustacchi static s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 data)
54425f2d433Sxy {
54525f2d433Sxy 	u32 mdic;
54625f2d433Sxy 	s32 ret_val = E1000_SUCCESS;
54725f2d433Sxy 
54825f2d433Sxy 	DEBUGFUNC("e1000_write_phy_reg_82543");
54925f2d433Sxy 
55025f2d433Sxy 	if (offset > MAX_PHY_REG_ADDRESS) {
55125f2d433Sxy 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
55225f2d433Sxy 		ret_val = -E1000_ERR_PARAM;
55325f2d433Sxy 		goto out;
55425f2d433Sxy 	}
55525f2d433Sxy 
55625f2d433Sxy 	/*
55725f2d433Sxy 	 * We'll need to use the SW defined pins to shift the write command
55825f2d433Sxy 	 * out to the PHY. We first send a preamble to the PHY to signal the
55925f2d433Sxy 	 * beginning of the MII instruction.  This is done by sending 32
56025f2d433Sxy 	 * consecutive "1" bits.
56125f2d433Sxy 	 */
56225f2d433Sxy 	e1000_shift_out_mdi_bits_82543(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
56325f2d433Sxy 
56425f2d433Sxy 	/*
56525f2d433Sxy 	 * Now combine the remaining required fields that will indicate a
56625f2d433Sxy 	 * write operation. We use this method instead of calling the
56725f2d433Sxy 	 * e1000_shift_out_mdi_bits routine for each field in the command. The
56825f2d433Sxy 	 * format of a MII write instruction is as follows:
56925f2d433Sxy 	 * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
57025f2d433Sxy 	 */
57125f2d433Sxy 	mdic = ((PHY_TURNAROUND) | (offset << 2) | (hw->phy.addr << 7) |
572*49b78600SRobert Mustacchi 		(PHY_OP_WRITE << 12) | (PHY_SOF << 14));
57325f2d433Sxy 	mdic <<= 16;
574*49b78600SRobert Mustacchi 	mdic |= (u32)data;
57525f2d433Sxy 
57625f2d433Sxy 	e1000_shift_out_mdi_bits_82543(hw, mdic, 32);
57725f2d433Sxy 
57825f2d433Sxy out:
57975eba5b6SRobert Mustacchi 	return ret_val;
58025f2d433Sxy }
58125f2d433Sxy 
58275eba5b6SRobert Mustacchi /**
58375eba5b6SRobert Mustacchi  *  e1000_raise_mdi_clk_82543 - Raise Management Data Input clock
58475eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
58575eba5b6SRobert Mustacchi  *  @ctrl: pointer to the control register
58625f2d433Sxy  *
58775eba5b6SRobert Mustacchi  *  Raise the management data input clock by setting the MDC bit in the control
58875eba5b6SRobert Mustacchi  *  register.
58975eba5b6SRobert Mustacchi  **/
e1000_raise_mdi_clk_82543(struct e1000_hw * hw,u32 * ctrl)59075eba5b6SRobert Mustacchi static void e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl)
59125f2d433Sxy {
59225f2d433Sxy 	/*
59325f2d433Sxy 	 * Raise the clock input to the Management Data Clock (by setting the
59425f2d433Sxy 	 * MDC bit), and then delay a sufficient amount of time.
59525f2d433Sxy 	 */
59625f2d433Sxy 	E1000_WRITE_REG(hw, E1000_CTRL, (*ctrl | E1000_CTRL_MDC));
59725f2d433Sxy 	E1000_WRITE_FLUSH(hw);
59825f2d433Sxy 	usec_delay(10);
59925f2d433Sxy }
60025f2d433Sxy 
60175eba5b6SRobert Mustacchi /**
60275eba5b6SRobert Mustacchi  *  e1000_lower_mdi_clk_82543 - Lower Management Data Input clock
60375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
60475eba5b6SRobert Mustacchi  *  @ctrl: pointer to the control register
60525f2d433Sxy  *
60675eba5b6SRobert Mustacchi  *  Lower the management data input clock by clearing the MDC bit in the
60775eba5b6SRobert Mustacchi  *  control register.
60875eba5b6SRobert Mustacchi  **/
e1000_lower_mdi_clk_82543(struct e1000_hw * hw,u32 * ctrl)60975eba5b6SRobert Mustacchi static void e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl)
61025f2d433Sxy {
61125f2d433Sxy 	/*
61225f2d433Sxy 	 * Lower the clock input to the Management Data Clock (by clearing the
61325f2d433Sxy 	 * MDC bit), and then delay a sufficient amount of time.
61425f2d433Sxy 	 */
61525f2d433Sxy 	E1000_WRITE_REG(hw, E1000_CTRL, (*ctrl & ~E1000_CTRL_MDC));
61625f2d433Sxy 	E1000_WRITE_FLUSH(hw);
61725f2d433Sxy 	usec_delay(10);
61825f2d433Sxy }
61925f2d433Sxy 
62075eba5b6SRobert Mustacchi /**
62175eba5b6SRobert Mustacchi  *  e1000_shift_out_mdi_bits_82543 - Shift data bits our to the PHY
62275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
62375eba5b6SRobert Mustacchi  *  @data: data to send to the PHY
62475eba5b6SRobert Mustacchi  *  @count: number of bits to shift out
62525f2d433Sxy  *
62675eba5b6SRobert Mustacchi  *  We need to shift 'count' bits out to the PHY.  So, the value in the
62775eba5b6SRobert Mustacchi  *  "data" parameter will be shifted out to the PHY one bit at a time.
62875eba5b6SRobert Mustacchi  *  In order to do this, "data" must be broken down into bits.
62975eba5b6SRobert Mustacchi  **/
e1000_shift_out_mdi_bits_82543(struct e1000_hw * hw,u32 data,u16 count)63075eba5b6SRobert Mustacchi static void e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data,
631*49b78600SRobert Mustacchi 					   u16 count)
63225f2d433Sxy {
63325f2d433Sxy 	u32 ctrl, mask;
63425f2d433Sxy 
63525f2d433Sxy 	/*
63625f2d433Sxy 	 * We need to shift "count" number of bits out to the PHY.  So, the
63725f2d433Sxy 	 * value in the "data" parameter will be shifted out to the PHY one
63825f2d433Sxy 	 * bit at a time.  In order to do this, "data" must be broken down
63925f2d433Sxy 	 * into bits.
64025f2d433Sxy 	 */
64125f2d433Sxy 	mask = 0x01;
642*49b78600SRobert Mustacchi 	mask <<= (count - 1);
64325f2d433Sxy 
64425f2d433Sxy 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
64525f2d433Sxy 
64625f2d433Sxy 	/* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
64725f2d433Sxy 	ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
64825f2d433Sxy 
64925f2d433Sxy 	while (mask) {
65025f2d433Sxy 		/*
65125f2d433Sxy 		 * A "1" is shifted out to the PHY by setting the MDIO bit to
65225f2d433Sxy 		 * "1" and then raising and lowering the Management Data Clock.
65325f2d433Sxy 		 * A "0" is shifted out to the PHY by setting the MDIO bit to
65425f2d433Sxy 		 * "0" and then raising and lowering the clock.
65525f2d433Sxy 		 */
656*49b78600SRobert Mustacchi 		if (data & mask)
657*49b78600SRobert Mustacchi 			ctrl |= E1000_CTRL_MDIO;
658*49b78600SRobert Mustacchi 		else
659*49b78600SRobert Mustacchi 			ctrl &= ~E1000_CTRL_MDIO;
66025f2d433Sxy 
66125f2d433Sxy 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
66225f2d433Sxy 		E1000_WRITE_FLUSH(hw);
66325f2d433Sxy 
66425f2d433Sxy 		usec_delay(10);
66525f2d433Sxy 
66625f2d433Sxy 		e1000_raise_mdi_clk_82543(hw, &ctrl);
66725f2d433Sxy 		e1000_lower_mdi_clk_82543(hw, &ctrl);
66825f2d433Sxy 
66925f2d433Sxy 		mask >>= 1;
67025f2d433Sxy 	}
67125f2d433Sxy }
67225f2d433Sxy 
67375eba5b6SRobert Mustacchi /**
67475eba5b6SRobert Mustacchi  *  e1000_shift_in_mdi_bits_82543 - Shift data bits in from the PHY
67575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
67625f2d433Sxy  *
67775eba5b6SRobert Mustacchi  *  In order to read a register from the PHY, we need to shift 18 bits
67875eba5b6SRobert Mustacchi  *  in from the PHY.  Bits are "shifted in" by raising the clock input to
67975eba5b6SRobert Mustacchi  *  the PHY (setting the MDC bit), and then reading the value of the data out
68075eba5b6SRobert Mustacchi  *  MDIO bit.
68175eba5b6SRobert Mustacchi  **/
e1000_shift_in_mdi_bits_82543(struct e1000_hw * hw)68275eba5b6SRobert Mustacchi static u16 e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw)
68325f2d433Sxy {
68425f2d433Sxy 	u32 ctrl;
68525f2d433Sxy 	u16 data = 0;
68625f2d433Sxy 	u8 i;
68725f2d433Sxy 
68825f2d433Sxy 	/*
68925f2d433Sxy 	 * In order to read a register from the PHY, we need to shift in a
69025f2d433Sxy 	 * total of 18 bits from the PHY.  The first two bit (turnaround)
69125f2d433Sxy 	 * times are used to avoid contention on the MDIO pin when a read
69225f2d433Sxy 	 * operation is performed.  These two bits are ignored by us and
69325f2d433Sxy 	 * thrown away.  Bits are "shifted in" by raising the input to the
69425f2d433Sxy 	 * Management Data Clock (setting the MDC bit) and then reading the
69525f2d433Sxy 	 * value of the MDIO bit.
69625f2d433Sxy 	 */
69725f2d433Sxy 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
69825f2d433Sxy 
69925f2d433Sxy 	/*
70025f2d433Sxy 	 * Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as
70125f2d433Sxy 	 * input.
70225f2d433Sxy 	 */
70325f2d433Sxy 	ctrl &= ~E1000_CTRL_MDIO_DIR;
70425f2d433Sxy 	ctrl &= ~E1000_CTRL_MDIO;
70525f2d433Sxy 
70625f2d433Sxy 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
70725f2d433Sxy 	E1000_WRITE_FLUSH(hw);
70825f2d433Sxy 
70925f2d433Sxy 	/*
71025f2d433Sxy 	 * Raise and lower the clock before reading in the data.  This accounts
71125f2d433Sxy 	 * for the turnaround bits.  The first clock occurred when we clocked
71225f2d433Sxy 	 * out the last bit of the Register Address.
71325f2d433Sxy 	 */
71425f2d433Sxy 	e1000_raise_mdi_clk_82543(hw, &ctrl);
71525f2d433Sxy 	e1000_lower_mdi_clk_82543(hw, &ctrl);
71625f2d433Sxy 
71725f2d433Sxy 	for (data = 0, i = 0; i < 16; i++) {
71825f2d433Sxy 		data <<= 1;
71925f2d433Sxy 		e1000_raise_mdi_clk_82543(hw, &ctrl);
72025f2d433Sxy 		ctrl = E1000_READ_REG(hw, E1000_CTRL);
72125f2d433Sxy 		/* Check to see if we shifted in a "1". */
72225f2d433Sxy 		if (ctrl & E1000_CTRL_MDIO)
72325f2d433Sxy 			data |= 1;
72425f2d433Sxy 		e1000_lower_mdi_clk_82543(hw, &ctrl);
72525f2d433Sxy 	}
72625f2d433Sxy 
72725f2d433Sxy 	e1000_raise_mdi_clk_82543(hw, &ctrl);
72825f2d433Sxy 	e1000_lower_mdi_clk_82543(hw, &ctrl);
72925f2d433Sxy 
73075eba5b6SRobert Mustacchi 	return data;
73125f2d433Sxy }
73225f2d433Sxy 
73375eba5b6SRobert Mustacchi /**
73475eba5b6SRobert Mustacchi  *  e1000_phy_force_speed_duplex_82543 - Force speed/duplex for PHY
73575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
73625f2d433Sxy  *
73775eba5b6SRobert Mustacchi  *  Calls the function to force speed and duplex for the m88 PHY, and
73875eba5b6SRobert Mustacchi  *  if the PHY is not auto-negotiating and the speed is forced to 10Mbit,
73975eba5b6SRobert Mustacchi  *  then call the function for polarity reversal workaround.
74075eba5b6SRobert Mustacchi  **/
e1000_phy_force_speed_duplex_82543(struct e1000_hw * hw)74175eba5b6SRobert Mustacchi static s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw)
74225f2d433Sxy {
74325f2d433Sxy 	s32 ret_val;
74425f2d433Sxy 
74525f2d433Sxy 	DEBUGFUNC("e1000_phy_force_speed_duplex_82543");
74625f2d433Sxy 
74725f2d433Sxy 	ret_val = e1000_phy_force_speed_duplex_m88(hw);
74825f2d433Sxy 	if (ret_val)
74925f2d433Sxy 		goto out;
75025f2d433Sxy 
751*49b78600SRobert Mustacchi 	if (!hw->mac.autoneg && (hw->mac.forced_speed_duplex &
752*49b78600SRobert Mustacchi 	    E1000_ALL_10_SPEED))
75325f2d433Sxy 		ret_val = e1000_polarity_reversal_workaround_82543(hw);
75425f2d433Sxy 
75525f2d433Sxy out:
75675eba5b6SRobert Mustacchi 	return ret_val;
75725f2d433Sxy }
75825f2d433Sxy 
75975eba5b6SRobert Mustacchi /**
76075eba5b6SRobert Mustacchi  *  e1000_polarity_reversal_workaround_82543 - Workaround polarity reversal
76175eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
76225f2d433Sxy  *
76375eba5b6SRobert Mustacchi  *  When forcing link to 10 Full or 10 Half, the PHY can reverse the polarity
76475eba5b6SRobert Mustacchi  *  inadvertently.  To workaround the issue, we disable the transmitter on
76575eba5b6SRobert Mustacchi  *  the PHY until we have established the link partner's link parameters.
76675eba5b6SRobert Mustacchi  **/
e1000_polarity_reversal_workaround_82543(struct e1000_hw * hw)76775eba5b6SRobert Mustacchi static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw)
76825f2d433Sxy {
769592a4d85Scc 	s32 ret_val = E1000_SUCCESS;
77025f2d433Sxy 	u16 mii_status_reg;
77125f2d433Sxy 	u16 i;
772592a4d85Scc 	bool link;
773592a4d85Scc 
774592a4d85Scc 	if (!(hw->phy.ops.write_reg))
775592a4d85Scc 		goto out;
77625f2d433Sxy 
77725f2d433Sxy 	/* Polarity reversal workaround for forced 10F/10H links. */
77825f2d433Sxy 
77925f2d433Sxy 	/* Disable the transmitter on the PHY */
78025f2d433Sxy 
781592a4d85Scc 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
78225f2d433Sxy 	if (ret_val)
78325f2d433Sxy 		goto out;
784592a4d85Scc 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
78525f2d433Sxy 	if (ret_val)
78625f2d433Sxy 		goto out;
78725f2d433Sxy 
788592a4d85Scc 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
78925f2d433Sxy 	if (ret_val)
79025f2d433Sxy 		goto out;
79125f2d433Sxy 
79225f2d433Sxy 	/*
79325f2d433Sxy 	 * This loop will early-out if the NO link condition has been met.
79425f2d433Sxy 	 * In other words, DO NOT use e1000_phy_has_link_generic() here.
79525f2d433Sxy 	 */
79625f2d433Sxy 	for (i = PHY_FORCE_TIME; i > 0; i--) {
79725f2d433Sxy 		/*
79825f2d433Sxy 		 * Read the MII Status Register and wait for Link Status bit
79925f2d433Sxy 		 * to be clear.
80025f2d433Sxy 		 */
80125f2d433Sxy 
802592a4d85Scc 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
80325f2d433Sxy 		if (ret_val)
80425f2d433Sxy 			goto out;
80525f2d433Sxy 
806592a4d85Scc 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
80725f2d433Sxy 		if (ret_val)
80825f2d433Sxy 			goto out;
80925f2d433Sxy 
810*49b78600SRobert Mustacchi 		if (!(mii_status_reg & ~MII_SR_LINK_STATUS))
81125f2d433Sxy 			break;
81225f2d433Sxy 		msec_delay_irq(100);
81325f2d433Sxy 	}
81425f2d433Sxy 
81525f2d433Sxy 	/* Recommended delay time after link has been lost */
81625f2d433Sxy 	msec_delay_irq(1000);
81725f2d433Sxy 
81825f2d433Sxy 	/* Now we will re-enable the transmitter on the PHY */
81925f2d433Sxy 
820592a4d85Scc 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
82125f2d433Sxy 	if (ret_val)
82225f2d433Sxy 		goto out;
82325f2d433Sxy 	msec_delay_irq(50);
824592a4d85Scc 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
82525f2d433Sxy 	if (ret_val)
82625f2d433Sxy 		goto out;
82725f2d433Sxy 	msec_delay_irq(50);
828592a4d85Scc 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
82925f2d433Sxy 	if (ret_val)
83025f2d433Sxy 		goto out;
83125f2d433Sxy 	msec_delay_irq(50);
832592a4d85Scc 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
83325f2d433Sxy 	if (ret_val)
83425f2d433Sxy 		goto out;
83525f2d433Sxy 
836592a4d85Scc 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
83725f2d433Sxy 	if (ret_val)
83825f2d433Sxy 		goto out;
83925f2d433Sxy 
84025f2d433Sxy 	/*
84125f2d433Sxy 	 * Read the MII Status Register and wait for Link Status bit
84225f2d433Sxy 	 * to be set.
84325f2d433Sxy 	 */
84425f2d433Sxy 	ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_TIME, 100000, &link);
84525f2d433Sxy 	if (ret_val)
84625f2d433Sxy 		goto out;
84725f2d433Sxy 
84825f2d433Sxy out:
84975eba5b6SRobert Mustacchi 	return ret_val;
85025f2d433Sxy }
85125f2d433Sxy 
85275eba5b6SRobert Mustacchi /**
85375eba5b6SRobert Mustacchi  *  e1000_phy_hw_reset_82543 - PHY hardware reset
85475eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
85525f2d433Sxy  *
85675eba5b6SRobert Mustacchi  *  Sets the PHY_RESET_DIR bit in the extended device control register
85775eba5b6SRobert Mustacchi  *  to put the PHY into a reset and waits for completion.  Once the reset
85875eba5b6SRobert Mustacchi  *  has been accomplished, clear the PHY_RESET_DIR bit to take the PHY out
85975eba5b6SRobert Mustacchi  *  of reset.
86075eba5b6SRobert Mustacchi  **/
e1000_phy_hw_reset_82543(struct e1000_hw * hw)86175eba5b6SRobert Mustacchi static s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw)
86225f2d433Sxy {
86325f2d433Sxy 	u32 ctrl_ext;
86425f2d433Sxy 	s32 ret_val;
86525f2d433Sxy 
86625f2d433Sxy 	DEBUGFUNC("e1000_phy_hw_reset_82543");
86725f2d433Sxy 
86825f2d433Sxy 	/*
86925f2d433Sxy 	 * Read the Extended Device Control Register, assert the PHY_RESET_DIR
87025f2d433Sxy 	 * bit to put the PHY into reset...
87125f2d433Sxy 	 */
87225f2d433Sxy 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
87325f2d433Sxy 	ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
87425f2d433Sxy 	ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
87525f2d433Sxy 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
87625f2d433Sxy 	E1000_WRITE_FLUSH(hw);
87725f2d433Sxy 
87825f2d433Sxy 	msec_delay(10);
87925f2d433Sxy 
88025f2d433Sxy 	/* ...then take it out of reset. */
88125f2d433Sxy 	ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
88225f2d433Sxy 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
88325f2d433Sxy 	E1000_WRITE_FLUSH(hw);
88425f2d433Sxy 
88525f2d433Sxy 	usec_delay(150);
88625f2d433Sxy 
887592a4d85Scc 	if (!(hw->phy.ops.get_cfg_done))
88875eba5b6SRobert Mustacchi 		return E1000_SUCCESS;
889592a4d85Scc 
890592a4d85Scc 	ret_val = hw->phy.ops.get_cfg_done(hw);
89125f2d433Sxy 
89275eba5b6SRobert Mustacchi 	return ret_val;
89325f2d433Sxy }
89425f2d433Sxy 
89575eba5b6SRobert Mustacchi /**
89675eba5b6SRobert Mustacchi  *  e1000_reset_hw_82543 - Reset hardware
89775eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
89825f2d433Sxy  *
89975eba5b6SRobert Mustacchi  *  This resets the hardware into a known state.
90075eba5b6SRobert Mustacchi  **/
e1000_reset_hw_82543(struct e1000_hw * hw)90175eba5b6SRobert Mustacchi static s32 e1000_reset_hw_82543(struct e1000_hw *hw)
90225f2d433Sxy {
903*49b78600SRobert Mustacchi 	u32 ctrl;
90425f2d433Sxy 	s32 ret_val = E1000_SUCCESS;
90525f2d433Sxy 
90625f2d433Sxy 	DEBUGFUNC("e1000_reset_hw_82543");
90725f2d433Sxy 
90825f2d433Sxy 	DEBUGOUT("Masking off all interrupts\n");
90925f2d433Sxy 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
91025f2d433Sxy 
91125f2d433Sxy 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
91225f2d433Sxy 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
91325f2d433Sxy 	E1000_WRITE_FLUSH(hw);
91425f2d433Sxy 
91575eba5b6SRobert Mustacchi 	e1000_set_tbi_sbp_82543(hw, FALSE);
91625f2d433Sxy 
91725f2d433Sxy 	/*
91825f2d433Sxy 	 * Delay to allow any outstanding PCI transactions to complete before
91925f2d433Sxy 	 * resetting the device
92025f2d433Sxy 	 */
92125f2d433Sxy 	msec_delay(10);
92225f2d433Sxy 
92325f2d433Sxy 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
92425f2d433Sxy 
92525f2d433Sxy 	DEBUGOUT("Issuing a global reset to 82543/82544 MAC\n");
92625f2d433Sxy 	if (hw->mac.type == e1000_82543) {
92725f2d433Sxy 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
92825f2d433Sxy 	} else {
92925f2d433Sxy 		/*
93025f2d433Sxy 		 * The 82544 can't ACK the 64-bit write when issuing the
93125f2d433Sxy 		 * reset, so use IO-mapping as a workaround.
93225f2d433Sxy 		 */
93325f2d433Sxy 		E1000_WRITE_REG_IO(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
93425f2d433Sxy 	}
93525f2d433Sxy 
93625f2d433Sxy 	/*
93725f2d433Sxy 	 * After MAC reset, force reload of NVM to restore power-on
93825f2d433Sxy 	 * settings to device.
93925f2d433Sxy 	 */
940592a4d85Scc 	hw->nvm.ops.reload(hw);
94125f2d433Sxy 	msec_delay(2);
94225f2d433Sxy 
94325f2d433Sxy 	/* Masking off and clearing any pending interrupts */
94425f2d433Sxy 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
945*49b78600SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICR);
94625f2d433Sxy 
94775eba5b6SRobert Mustacchi 	return ret_val;
94825f2d433Sxy }
94925f2d433Sxy 
95075eba5b6SRobert Mustacchi /**
95175eba5b6SRobert Mustacchi  *  e1000_init_hw_82543 - Initialize hardware
95275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
95325f2d433Sxy  *
95475eba5b6SRobert Mustacchi  *  This inits the hardware readying it for operation.
95575eba5b6SRobert Mustacchi  **/
e1000_init_hw_82543(struct e1000_hw * hw)95675eba5b6SRobert Mustacchi static s32 e1000_init_hw_82543(struct e1000_hw *hw)
95725f2d433Sxy {
95825f2d433Sxy 	struct e1000_mac_info *mac = &hw->mac;
959d5c3073dSchenlu chen - Sun Microsystems - Beijing China 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
96025f2d433Sxy 	u32 ctrl;
96125f2d433Sxy 	s32 ret_val;
96225f2d433Sxy 	u16 i;
96325f2d433Sxy 
96425f2d433Sxy 	DEBUGFUNC("e1000_init_hw_82543");
96525f2d433Sxy 
96625f2d433Sxy 	/* Disabling VLAN filtering */
96725f2d433Sxy 	E1000_WRITE_REG(hw, E1000_VET, 0);
968592a4d85Scc 	mac->ops.clear_vfta(hw);
96925f2d433Sxy 
97025f2d433Sxy 	/* Setup the receive address. */
97125f2d433Sxy 	e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
97225f2d433Sxy 
97325f2d433Sxy 	/* Zero out the Multicast HASH table */
97425f2d433Sxy 	DEBUGOUT("Zeroing the MTA\n");
97525f2d433Sxy 	for (i = 0; i < mac->mta_reg_count; i++) {
97625f2d433Sxy 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
97725f2d433Sxy 		E1000_WRITE_FLUSH(hw);
97825f2d433Sxy 	}
97925f2d433Sxy 
98025f2d433Sxy 	/*
98125f2d433Sxy 	 * Set the PCI priority bit correctly in the CTRL register.  This
98225f2d433Sxy 	 * determines if the adapter gives priority to receives, or if it
98325f2d433Sxy 	 * gives equal priority to transmits and receives.
98425f2d433Sxy 	 */
98525f2d433Sxy 	if (hw->mac.type == e1000_82543 && dev_spec->dma_fairness) {
98625f2d433Sxy 		ctrl = E1000_READ_REG(hw, E1000_CTRL);
98725f2d433Sxy 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PRIOR);
98825f2d433Sxy 	}
98925f2d433Sxy 
99025f2d433Sxy 	e1000_pcix_mmrbc_workaround_generic(hw);
99125f2d433Sxy 
99225f2d433Sxy 	/* Setup link and flow control */
993592a4d85Scc 	ret_val = mac->ops.setup_link(hw);
99425f2d433Sxy 
99525f2d433Sxy 	/*
99625f2d433Sxy 	 * Clear all of the statistics registers (clear on read).  It is
99725f2d433Sxy 	 * important that we do this after we have tried to establish link
99825f2d433Sxy 	 * because the symbol error count will increment wildly if there
99925f2d433Sxy 	 * is no link.
100025f2d433Sxy 	 */
100125f2d433Sxy 	e1000_clear_hw_cntrs_82543(hw);
100225f2d433Sxy 
100375eba5b6SRobert Mustacchi 	return ret_val;
100425f2d433Sxy }
100525f2d433Sxy 
100675eba5b6SRobert Mustacchi /**
100775eba5b6SRobert Mustacchi  *  e1000_setup_link_82543 - Setup flow control and link settings
100875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
100925f2d433Sxy  *
101075eba5b6SRobert Mustacchi  *  Read the EEPROM to determine the initial polarity value and write the
101175eba5b6SRobert Mustacchi  *  extended device control register with the information before calling
101275eba5b6SRobert Mustacchi  *  the generic setup link function, which does the following:
101375eba5b6SRobert Mustacchi  *  Determines which flow control settings to use, then configures flow
101475eba5b6SRobert Mustacchi  *  control.  Calls the appropriate media-specific link configuration
101575eba5b6SRobert Mustacchi  *  function.  Assuming the adapter has a valid link partner, a valid link
101675eba5b6SRobert Mustacchi  *  should be established.  Assumes the hardware has previously been reset
101775eba5b6SRobert Mustacchi  *  and the transmitter and receiver are not enabled.
101875eba5b6SRobert Mustacchi  **/
e1000_setup_link_82543(struct e1000_hw * hw)101975eba5b6SRobert Mustacchi static s32 e1000_setup_link_82543(struct e1000_hw *hw)
102025f2d433Sxy {
102125f2d433Sxy 	u32 ctrl_ext;
102275eba5b6SRobert Mustacchi 	s32  ret_val;
102325f2d433Sxy 	u16 data;
102425f2d433Sxy 
102525f2d433Sxy 	DEBUGFUNC("e1000_setup_link_82543");
102625f2d433Sxy 
102725f2d433Sxy 	/*
102825f2d433Sxy 	 * Take the 4 bits from NVM word 0xF that determine the initial
102925f2d433Sxy 	 * polarity value for the SW controlled pins, and setup the
103025f2d433Sxy 	 * Extended Device Control reg with that info.
103125f2d433Sxy 	 * This is needed because one of the SW controlled pins is used for
103225f2d433Sxy 	 * signal detection.  So this should be done before phy setup.
103325f2d433Sxy 	 */
103425f2d433Sxy 	if (hw->mac.type == e1000_82543) {
1035592a4d85Scc 		ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &data);
103625f2d433Sxy 		if (ret_val) {
103725f2d433Sxy 			DEBUGOUT("NVM Read Error\n");
103825f2d433Sxy 			ret_val = -E1000_ERR_NVM;
103925f2d433Sxy 			goto out;
104025f2d433Sxy 		}
104125f2d433Sxy 		ctrl_ext = ((data & NVM_WORD0F_SWPDIO_EXT_MASK) <<
1042*49b78600SRobert Mustacchi 			    NVM_SWDPIO_EXT_SHIFT);
104325f2d433Sxy 		E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
104425f2d433Sxy 	}
104525f2d433Sxy 
104625f2d433Sxy 	ret_val = e1000_setup_link_generic(hw);
104725f2d433Sxy 
104825f2d433Sxy out:
104975eba5b6SRobert Mustacchi 	return ret_val;
105025f2d433Sxy }
105125f2d433Sxy 
105275eba5b6SRobert Mustacchi /**
105375eba5b6SRobert Mustacchi  *  e1000_setup_copper_link_82543 - Configure copper link settings
105475eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
105525f2d433Sxy  *
105675eba5b6SRobert Mustacchi  *  Configures the link for auto-neg or forced speed and duplex.  Then we check
105775eba5b6SRobert Mustacchi  *  for link, once link is established calls to configure collision distance
105875eba5b6SRobert Mustacchi  *  and flow control are called.
105975eba5b6SRobert Mustacchi  **/
e1000_setup_copper_link_82543(struct e1000_hw * hw)106075eba5b6SRobert Mustacchi static s32 e1000_setup_copper_link_82543(struct e1000_hw *hw)
106125f2d433Sxy {
106225f2d433Sxy 	u32 ctrl;
106325f2d433Sxy 	s32 ret_val;
1064592a4d85Scc 	bool link;
106525f2d433Sxy 
106625f2d433Sxy 	DEBUGFUNC("e1000_setup_copper_link_82543");
106725f2d433Sxy 
106825f2d433Sxy 	ctrl = E1000_READ_REG(hw, E1000_CTRL) | E1000_CTRL_SLU;
106925f2d433Sxy 	/*
107025f2d433Sxy 	 * With 82543, we need to force speed and duplex on the MAC
107125f2d433Sxy 	 * equal to what the PHY speed and duplex configuration is.
107225f2d433Sxy 	 * In addition, we need to perform a hardware reset on the
107325f2d433Sxy 	 * PHY to take it out of reset.
107425f2d433Sxy 	 */
107525f2d433Sxy 	if (hw->mac.type == e1000_82543) {
107625f2d433Sxy 		ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
107725f2d433Sxy 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
1078592a4d85Scc 		ret_val = hw->phy.ops.reset(hw);
107925f2d433Sxy 		if (ret_val)
108025f2d433Sxy 			goto out;
108125f2d433Sxy 	} else {
108225f2d433Sxy 		ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
108325f2d433Sxy 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
108425f2d433Sxy 	}
108525f2d433Sxy 
108625f2d433Sxy 	/* Set MDI/MDI-X, Polarity Reversal, and downshift settings */
108725f2d433Sxy 	ret_val = e1000_copper_link_setup_m88(hw);
108825f2d433Sxy 	if (ret_val)
108925f2d433Sxy 		goto out;
109025f2d433Sxy 
109125f2d433Sxy 	if (hw->mac.autoneg) {
109225f2d433Sxy 		/*
109325f2d433Sxy 		 * Setup autoneg and flow control advertisement and perform
109425f2d433Sxy 		 * autonegotiation.
109525f2d433Sxy 		 */
109625f2d433Sxy 		ret_val = e1000_copper_link_autoneg(hw);
109725f2d433Sxy 		if (ret_val)
109825f2d433Sxy 			goto out;
109925f2d433Sxy 	} else {
110025f2d433Sxy 		/*
110125f2d433Sxy 		 * PHY will be set to 10H, 10F, 100H or 100F
110225f2d433Sxy 		 * depending on user settings.
110325f2d433Sxy 		 */
110425f2d433Sxy 		DEBUGOUT("Forcing Speed and Duplex\n");
110525f2d433Sxy 		ret_val = e1000_phy_force_speed_duplex_82543(hw);
110625f2d433Sxy 		if (ret_val) {
110725f2d433Sxy 			DEBUGOUT("Error Forcing Speed and Duplex\n");
110825f2d433Sxy 			goto out;
110925f2d433Sxy 		}
111025f2d433Sxy 	}
111125f2d433Sxy 
111225f2d433Sxy 	/*
111325f2d433Sxy 	 * Check link status. Wait up to 100 microseconds for link to become
111425f2d433Sxy 	 * valid.
111525f2d433Sxy 	 */
1116*49b78600SRobert Mustacchi 	ret_val = e1000_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10,
1117*49b78600SRobert Mustacchi 					     &link);
111825f2d433Sxy 	if (ret_val)
111925f2d433Sxy 		goto out;
112025f2d433Sxy 
112125f2d433Sxy 
112225f2d433Sxy 	if (link) {
112325f2d433Sxy 		DEBUGOUT("Valid link established!!!\n");
112425f2d433Sxy 		/* Config the MAC and PHY after link is up */
112525f2d433Sxy 		if (hw->mac.type == e1000_82544) {
112675eba5b6SRobert Mustacchi 			hw->mac.ops.config_collision_dist(hw);
112725f2d433Sxy 		} else {
112825f2d433Sxy 			ret_val = e1000_config_mac_to_phy_82543(hw);
112925f2d433Sxy 			if (ret_val)
113025f2d433Sxy 				goto out;
113125f2d433Sxy 		}
113225f2d433Sxy 		ret_val = e1000_config_fc_after_link_up_generic(hw);
113325f2d433Sxy 	} else {
113425f2d433Sxy 		DEBUGOUT("Unable to establish link!!!\n");
113525f2d433Sxy 	}
113625f2d433Sxy 
113725f2d433Sxy out:
113875eba5b6SRobert Mustacchi 	return ret_val;
113925f2d433Sxy }
114025f2d433Sxy 
114175eba5b6SRobert Mustacchi /**
114275eba5b6SRobert Mustacchi  *  e1000_setup_fiber_link_82543 - Setup link for fiber
114375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
114425f2d433Sxy  *
114575eba5b6SRobert Mustacchi  *  Configures collision distance and flow control for fiber links.  Upon
114675eba5b6SRobert Mustacchi  *  successful setup, poll for link.
114775eba5b6SRobert Mustacchi  **/
e1000_setup_fiber_link_82543(struct e1000_hw * hw)114875eba5b6SRobert Mustacchi static s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw)
114925f2d433Sxy {
115025f2d433Sxy 	u32 ctrl;
115125f2d433Sxy 	s32 ret_val;
115225f2d433Sxy 
115325f2d433Sxy 	DEBUGFUNC("e1000_setup_fiber_link_82543");
115425f2d433Sxy 
115525f2d433Sxy 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
115625f2d433Sxy 
115725f2d433Sxy 	/* Take the link out of reset */
115825f2d433Sxy 	ctrl &= ~E1000_CTRL_LRST;
115925f2d433Sxy 
116075eba5b6SRobert Mustacchi 	hw->mac.ops.config_collision_dist(hw);
116125f2d433Sxy 
116225f2d433Sxy 	ret_val = e1000_commit_fc_settings_generic(hw);
116325f2d433Sxy 	if (ret_val)
116425f2d433Sxy 		goto out;
116525f2d433Sxy 
116625f2d433Sxy 	DEBUGOUT("Auto-negotiation enabled\n");
116725f2d433Sxy 
116825f2d433Sxy 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
116925f2d433Sxy 	E1000_WRITE_FLUSH(hw);
117025f2d433Sxy 	msec_delay(1);
117125f2d433Sxy 
117225f2d433Sxy 	/*
1173592a4d85Scc 	 * For these adapters, the SW definable pin 1 is cleared when the
117425f2d433Sxy 	 * optics detect a signal.  If we have a signal, then poll for a
117525f2d433Sxy 	 * "Link-Up" indication.
117625f2d433Sxy 	 */
1177*49b78600SRobert Mustacchi 	if (!(E1000_READ_REG(hw, E1000_CTRL) & E1000_CTRL_SWDPIN1))
117825f2d433Sxy 		ret_val = e1000_poll_fiber_serdes_link_generic(hw);
1179*49b78600SRobert Mustacchi 	else
118025f2d433Sxy 		DEBUGOUT("No signal detected\n");
118125f2d433Sxy 
118225f2d433Sxy out:
118375eba5b6SRobert Mustacchi 	return ret_val;
118425f2d433Sxy }
118525f2d433Sxy 
118675eba5b6SRobert Mustacchi /**
118775eba5b6SRobert Mustacchi  *  e1000_check_for_copper_link_82543 - Check for link (Copper)
118875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
118925f2d433Sxy  *
119075eba5b6SRobert Mustacchi  *  Checks the phy for link, if link exists, do the following:
119175eba5b6SRobert Mustacchi  *   - check for downshift
119275eba5b6SRobert Mustacchi  *   - do polarity workaround (if necessary)
119375eba5b6SRobert Mustacchi  *   - configure collision distance
119475eba5b6SRobert Mustacchi  *   - configure flow control after link up
119575eba5b6SRobert Mustacchi  *   - configure tbi compatibility
119675eba5b6SRobert Mustacchi  **/
e1000_check_for_copper_link_82543(struct e1000_hw * hw)119775eba5b6SRobert Mustacchi static s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw)
119825f2d433Sxy {
119925f2d433Sxy 	struct e1000_mac_info *mac = &hw->mac;
120025f2d433Sxy 	u32 icr, rctl;
120125f2d433Sxy 	s32 ret_val;
120225f2d433Sxy 	u16 speed, duplex;
1203592a4d85Scc 	bool link;
120425f2d433Sxy 
120525f2d433Sxy 	DEBUGFUNC("e1000_check_for_copper_link_82543");
120625f2d433Sxy 
120725f2d433Sxy 	if (!mac->get_link_status) {
120825f2d433Sxy 		ret_val = E1000_SUCCESS;
120925f2d433Sxy 		goto out;
121025f2d433Sxy 	}
121125f2d433Sxy 
121225f2d433Sxy 	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
121325f2d433Sxy 	if (ret_val)
121425f2d433Sxy 		goto out;
121525f2d433Sxy 
121625f2d433Sxy 	if (!link)
121775eba5b6SRobert Mustacchi 		goto out; /* No link detected */
121825f2d433Sxy 
121975eba5b6SRobert Mustacchi 	mac->get_link_status = FALSE;
122025f2d433Sxy 
122175eba5b6SRobert Mustacchi 	e1000_check_downshift_generic(hw);
122225f2d433Sxy 
122325f2d433Sxy 	/*
122425f2d433Sxy 	 * If we are forcing speed/duplex, then we can return since
122525f2d433Sxy 	 * we have already determined whether we have link or not.
122625f2d433Sxy 	 */
122725f2d433Sxy 	if (!mac->autoneg) {
122825f2d433Sxy 		/*
122925f2d433Sxy 		 * If speed and duplex are forced to 10H or 10F, then we will
123025f2d433Sxy 		 * implement the polarity reversal workaround.  We disable
123125f2d433Sxy 		 * interrupts first, and upon returning, place the devices
123225f2d433Sxy 		 * interrupt state to its previous value except for the link
123325f2d433Sxy 		 * status change interrupt which will happened due to the
123425f2d433Sxy 		 * execution of this workaround.
123525f2d433Sxy 		 */
123625f2d433Sxy 		if (mac->forced_speed_duplex & E1000_ALL_10_SPEED) {
123725f2d433Sxy 			E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF);
123825f2d433Sxy 			ret_val = e1000_polarity_reversal_workaround_82543(hw);
123925f2d433Sxy 			icr = E1000_READ_REG(hw, E1000_ICR);
124025f2d433Sxy 			E1000_WRITE_REG(hw, E1000_ICS, (icr & ~E1000_ICS_LSC));
124125f2d433Sxy 			E1000_WRITE_REG(hw, E1000_IMS, IMS_ENABLE_MASK);
124225f2d433Sxy 		}
124325f2d433Sxy 
124425f2d433Sxy 		ret_val = -E1000_ERR_CONFIG;
124525f2d433Sxy 		goto out;
124625f2d433Sxy 	}
124725f2d433Sxy 
124825f2d433Sxy 	/*
124925f2d433Sxy 	 * We have a M88E1000 PHY and Auto-Neg is enabled.  If we
125025f2d433Sxy 	 * have Si on board that is 82544 or newer, Auto
125125f2d433Sxy 	 * Speed Detection takes care of MAC speed/duplex
125225f2d433Sxy 	 * configuration.  So we only need to configure Collision
125325f2d433Sxy 	 * Distance in the MAC.  Otherwise, we need to force
125425f2d433Sxy 	 * speed/duplex on the MAC to the current PHY speed/duplex
125525f2d433Sxy 	 * settings.
125625f2d433Sxy 	 */
125725f2d433Sxy 	if (mac->type == e1000_82544)
125875eba5b6SRobert Mustacchi 		hw->mac.ops.config_collision_dist(hw);
125925f2d433Sxy 	else {
126025f2d433Sxy 		ret_val = e1000_config_mac_to_phy_82543(hw);
126125f2d433Sxy 		if (ret_val) {
126225f2d433Sxy 			DEBUGOUT("Error configuring MAC to PHY settings\n");
126325f2d433Sxy 			goto out;
126425f2d433Sxy 		}
126525f2d433Sxy 	}
126625f2d433Sxy 
126725f2d433Sxy 	/*
126825f2d433Sxy 	 * Configure Flow Control now that Auto-Neg has completed.
126925f2d433Sxy 	 * First, we need to restore the desired flow control
127025f2d433Sxy 	 * settings because we may have had to re-autoneg with a
127125f2d433Sxy 	 * different link partner.
127225f2d433Sxy 	 */
127325f2d433Sxy 	ret_val = e1000_config_fc_after_link_up_generic(hw);
1274*49b78600SRobert Mustacchi 	if (ret_val)
127525f2d433Sxy 		DEBUGOUT("Error configuring flow control\n");
127625f2d433Sxy 
127725f2d433Sxy 	/*
127825f2d433Sxy 	 * At this point we know that we are on copper and we have
127925f2d433Sxy 	 * auto-negotiated link.  These are conditions for checking the link
128025f2d433Sxy 	 * partner capability register.  We use the link speed to determine if
128125f2d433Sxy 	 * TBI compatibility needs to be turned on or off.  If the link is not
128225f2d433Sxy 	 * at gigabit speed, then TBI compatibility is not needed.  If we are
128325f2d433Sxy 	 * at gigabit speed, we turn on TBI compatibility.
128425f2d433Sxy 	 */
128525f2d433Sxy 	if (e1000_tbi_compatibility_enabled_82543(hw)) {
1286592a4d85Scc 		ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
128725f2d433Sxy 		if (ret_val) {
128825f2d433Sxy 			DEBUGOUT("Error getting link speed and duplex\n");
128975eba5b6SRobert Mustacchi 			return ret_val;
129025f2d433Sxy 		}
129125f2d433Sxy 		if (speed != SPEED_1000) {
129225f2d433Sxy 			/*
129325f2d433Sxy 			 * If link speed is not set to gigabit speed,
129425f2d433Sxy 			 * we do not need to enable TBI compatibility.
129525f2d433Sxy 			 */
129625f2d433Sxy 			if (e1000_tbi_sbp_enabled_82543(hw)) {
129725f2d433Sxy 				/*
129825f2d433Sxy 				 * If we previously were in the mode,
129925f2d433Sxy 				 * turn it off.
130025f2d433Sxy 				 */
130175eba5b6SRobert Mustacchi 				e1000_set_tbi_sbp_82543(hw, FALSE);
130225f2d433Sxy 				rctl = E1000_READ_REG(hw, E1000_RCTL);
130325f2d433Sxy 				rctl &= ~E1000_RCTL_SBP;
130425f2d433Sxy 				E1000_WRITE_REG(hw, E1000_RCTL, rctl);
130525f2d433Sxy 			}
130625f2d433Sxy 		} else {
130725f2d433Sxy 			/*
130825f2d433Sxy 			 * If TBI compatibility is was previously off,
130925f2d433Sxy 			 * turn it on. For compatibility with a TBI link
131025f2d433Sxy 			 * partner, we will store bad packets. Some
131125f2d433Sxy 			 * frames have an additional byte on the end and
131225f2d433Sxy 			 * will look like CRC errors to to the hardware.
131325f2d433Sxy 			 */
131425f2d433Sxy 			if (!e1000_tbi_sbp_enabled_82543(hw)) {
131575eba5b6SRobert Mustacchi 				e1000_set_tbi_sbp_82543(hw, TRUE);
131625f2d433Sxy 				rctl = E1000_READ_REG(hw, E1000_RCTL);
131725f2d433Sxy 				rctl |= E1000_RCTL_SBP;
131825f2d433Sxy 				E1000_WRITE_REG(hw, E1000_RCTL, rctl);
131925f2d433Sxy 			}
132025f2d433Sxy 		}
132125f2d433Sxy 	}
132225f2d433Sxy out:
132375eba5b6SRobert Mustacchi 	return ret_val;
132425f2d433Sxy }
132525f2d433Sxy 
132675eba5b6SRobert Mustacchi /**
132775eba5b6SRobert Mustacchi  *  e1000_check_for_fiber_link_82543 - Check for link (Fiber)
132875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
132925f2d433Sxy  *
133075eba5b6SRobert Mustacchi  *  Checks for link up on the hardware.  If link is not up and we have
133175eba5b6SRobert Mustacchi  *  a signal, then we need to force link up.
133275eba5b6SRobert Mustacchi  **/
e1000_check_for_fiber_link_82543(struct e1000_hw * hw)133375eba5b6SRobert Mustacchi static s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw)
133425f2d433Sxy {
133525f2d433Sxy 	struct e1000_mac_info *mac = &hw->mac;
133625f2d433Sxy 	u32 rxcw, ctrl, status;
133725f2d433Sxy 	s32 ret_val = E1000_SUCCESS;
133825f2d433Sxy 
133925f2d433Sxy 	DEBUGFUNC("e1000_check_for_fiber_link_82543");
134025f2d433Sxy 
134125f2d433Sxy 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
134225f2d433Sxy 	status = E1000_READ_REG(hw, E1000_STATUS);
134325f2d433Sxy 	rxcw = E1000_READ_REG(hw, E1000_RXCW);
134425f2d433Sxy 
134525f2d433Sxy 	/*
134625f2d433Sxy 	 * If we don't have link (auto-negotiation failed or link partner
134725f2d433Sxy 	 * cannot auto-negotiate), the cable is plugged in (we have signal),
134825f2d433Sxy 	 * and our link partner is not trying to auto-negotiate with us (we
134925f2d433Sxy 	 * are receiving idles or data), we need to force link up. We also
135025f2d433Sxy 	 * need to give auto-negotiation time to complete, in case the cable
135125f2d433Sxy 	 * was just plugged in. The autoneg_failed flag does this.
135225f2d433Sxy 	 */
135325f2d433Sxy 	/* (ctrl & E1000_CTRL_SWDPIN1) == 0 == have signal */
135425f2d433Sxy 	if ((!(ctrl & E1000_CTRL_SWDPIN1)) &&
135525f2d433Sxy 	    (!(status & E1000_STATUS_LU)) &&
135625f2d433Sxy 	    (!(rxcw & E1000_RXCW_C))) {
1357*49b78600SRobert Mustacchi 		if (!mac->autoneg_failed) {
1358*49b78600SRobert Mustacchi 			mac->autoneg_failed = TRUE;
135925f2d433Sxy 			ret_val = 0;
136025f2d433Sxy 			goto out;
136125f2d433Sxy 		}
136225f2d433Sxy 		DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");
136325f2d433Sxy 
136425f2d433Sxy 		/* Disable auto-negotiation in the TXCW register */
136525f2d433Sxy 		E1000_WRITE_REG(hw, E1000_TXCW, (mac->txcw & ~E1000_TXCW_ANE));
136625f2d433Sxy 
136725f2d433Sxy 		/* Force link-up and also force full-duplex. */
136825f2d433Sxy 		ctrl = E1000_READ_REG(hw, E1000_CTRL);
136925f2d433Sxy 		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
137025f2d433Sxy 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
137125f2d433Sxy 
137225f2d433Sxy 		/* Configure Flow Control after forcing link up. */
137325f2d433Sxy 		ret_val = e1000_config_fc_after_link_up_generic(hw);
137425f2d433Sxy 		if (ret_val) {
137525f2d433Sxy 			DEBUGOUT("Error configuring flow control\n");
137625f2d433Sxy 			goto out;
137725f2d433Sxy 		}
137825f2d433Sxy 	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
137925f2d433Sxy 		/*
138025f2d433Sxy 		 * If we are forcing link and we are receiving /C/ ordered
138125f2d433Sxy 		 * sets, re-enable auto-negotiation in the TXCW register
138225f2d433Sxy 		 * and disable forced link in the Device Control register
138325f2d433Sxy 		 * in an attempt to auto-negotiate with our link partner.
138425f2d433Sxy 		 */
138525f2d433Sxy 		DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
138625f2d433Sxy 		E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
138725f2d433Sxy 		E1000_WRITE_REG(hw, E1000_CTRL, (ctrl & ~E1000_CTRL_SLU));
138825f2d433Sxy 
138975eba5b6SRobert Mustacchi 		mac->serdes_has_link = TRUE;
139025f2d433Sxy 	}
139125f2d433Sxy 
139225f2d433Sxy out:
139375eba5b6SRobert Mustacchi 	return ret_val;
139425f2d433Sxy }
139525f2d433Sxy 
139675eba5b6SRobert Mustacchi /**
139775eba5b6SRobert Mustacchi  *  e1000_config_mac_to_phy_82543 - Configure MAC to PHY settings
139875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
139925f2d433Sxy  *
140075eba5b6SRobert Mustacchi  *  For the 82543 silicon, we need to set the MAC to match the settings
140175eba5b6SRobert Mustacchi  *  of the PHY, even if the PHY is auto-negotiating.
140275eba5b6SRobert Mustacchi  **/
e1000_config_mac_to_phy_82543(struct e1000_hw * hw)140375eba5b6SRobert Mustacchi static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw)
140425f2d433Sxy {
140525f2d433Sxy 	u32 ctrl;
1406592a4d85Scc 	s32 ret_val = E1000_SUCCESS;
140725f2d433Sxy 	u16 phy_data;
140825f2d433Sxy 
140925f2d433Sxy 	DEBUGFUNC("e1000_config_mac_to_phy_82543");
141025f2d433Sxy 
1411592a4d85Scc 	if (!(hw->phy.ops.read_reg))
1412592a4d85Scc 		goto out;
1413592a4d85Scc 
141425f2d433Sxy 	/* Set the bits to force speed and duplex */
141525f2d433Sxy 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
141625f2d433Sxy 	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
141725f2d433Sxy 	ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
141825f2d433Sxy 
141925f2d433Sxy 	/*
142025f2d433Sxy 	 * Set up duplex in the Device Control and Transmit Control
142125f2d433Sxy 	 * registers depending on negotiated values.
142225f2d433Sxy 	 */
1423592a4d85Scc 	ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
142425f2d433Sxy 	if (ret_val)
142525f2d433Sxy 		goto out;
142625f2d433Sxy 
142725f2d433Sxy 	ctrl &= ~E1000_CTRL_FD;
142825f2d433Sxy 	if (phy_data & M88E1000_PSSR_DPLX)
142925f2d433Sxy 		ctrl |= E1000_CTRL_FD;
143025f2d433Sxy 
143175eba5b6SRobert Mustacchi 	hw->mac.ops.config_collision_dist(hw);
143225f2d433Sxy 
143325f2d433Sxy 	/*
143425f2d433Sxy 	 * Set up speed in the Device Control register depending on
143525f2d433Sxy 	 * negotiated values.
143625f2d433Sxy 	 */
143725f2d433Sxy 	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
143825f2d433Sxy 		ctrl |= E1000_CTRL_SPD_1000;
143925f2d433Sxy 	else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
144025f2d433Sxy 		ctrl |= E1000_CTRL_SPD_100;
144125f2d433Sxy 
144225f2d433Sxy 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
144325f2d433Sxy 
144425f2d433Sxy out:
144575eba5b6SRobert Mustacchi 	return ret_val;
144625f2d433Sxy }
144725f2d433Sxy 
144875eba5b6SRobert Mustacchi /**
144975eba5b6SRobert Mustacchi  *  e1000_write_vfta_82543 - Write value to VLAN filter table
145075eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
145175eba5b6SRobert Mustacchi  *  @offset: the 32-bit offset in which to write the value to.
145275eba5b6SRobert Mustacchi  *  @value: the 32-bit value to write at location offset.
145325f2d433Sxy  *
145475eba5b6SRobert Mustacchi  *  This writes a 32-bit value to a 32-bit offset in the VLAN filter
145575eba5b6SRobert Mustacchi  *  table.
145675eba5b6SRobert Mustacchi  **/
e1000_write_vfta_82543(struct e1000_hw * hw,u32 offset,u32 value)145775eba5b6SRobert Mustacchi static void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value)
145825f2d433Sxy {
145925f2d433Sxy 	u32 temp;
146025f2d433Sxy 
146125f2d433Sxy 	DEBUGFUNC("e1000_write_vfta_82543");
146225f2d433Sxy 
146325f2d433Sxy 	if ((hw->mac.type == e1000_82544) && (offset & 1)) {
146425f2d433Sxy 		temp = E1000_READ_REG_ARRAY(hw, E1000_VFTA, offset - 1);
146525f2d433Sxy 		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
146625f2d433Sxy 		E1000_WRITE_FLUSH(hw);
146725f2d433Sxy 		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset - 1, temp);
146825f2d433Sxy 		E1000_WRITE_FLUSH(hw);
146925f2d433Sxy 	} else {
147025f2d433Sxy 		e1000_write_vfta_generic(hw, offset, value);
147125f2d433Sxy 	}
147225f2d433Sxy }
147325f2d433Sxy 
147475eba5b6SRobert Mustacchi /**
147575eba5b6SRobert Mustacchi  *  e1000_led_on_82543 - Turn on SW controllable LED
147675eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
147725f2d433Sxy  *
147875eba5b6SRobert Mustacchi  *  Turns the SW defined LED on.
147975eba5b6SRobert Mustacchi  **/
e1000_led_on_82543(struct e1000_hw * hw)148075eba5b6SRobert Mustacchi static s32 e1000_led_on_82543(struct e1000_hw *hw)
148125f2d433Sxy {
148225f2d433Sxy 	u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
148325f2d433Sxy 
148425f2d433Sxy 	DEBUGFUNC("e1000_led_on_82543");
148525f2d433Sxy 
148625f2d433Sxy 	if (hw->mac.type == e1000_82544 &&
1487592a4d85Scc 	    hw->phy.media_type == e1000_media_type_copper) {
1488592a4d85Scc 		/* Clear SW-definable Pin 0 to turn on the LED */
148925f2d433Sxy 		ctrl &= ~E1000_CTRL_SWDPIN0;
149025f2d433Sxy 		ctrl |= E1000_CTRL_SWDPIO0;
149125f2d433Sxy 	} else {
149225f2d433Sxy 		/* Fiber 82544 and all 82543 use this method */
149325f2d433Sxy 		ctrl |= E1000_CTRL_SWDPIN0;
149425f2d433Sxy 		ctrl |= E1000_CTRL_SWDPIO0;
149525f2d433Sxy 	}
149625f2d433Sxy 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
149725f2d433Sxy 
149875eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
149925f2d433Sxy }
150025f2d433Sxy 
150175eba5b6SRobert Mustacchi /**
150275eba5b6SRobert Mustacchi  *  e1000_led_off_82543 - Turn off SW controllable LED
150375eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
150425f2d433Sxy  *
150575eba5b6SRobert Mustacchi  *  Turns the SW defined LED off.
150675eba5b6SRobert Mustacchi  **/
e1000_led_off_82543(struct e1000_hw * hw)150775eba5b6SRobert Mustacchi static s32 e1000_led_off_82543(struct e1000_hw *hw)
150825f2d433Sxy {
150925f2d433Sxy 	u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
151025f2d433Sxy 
151125f2d433Sxy 	DEBUGFUNC("e1000_led_off_82543");
151225f2d433Sxy 
151325f2d433Sxy 	if (hw->mac.type == e1000_82544 &&
1514592a4d85Scc 	    hw->phy.media_type == e1000_media_type_copper) {
1515592a4d85Scc 		/* Set SW-definable Pin 0 to turn off the LED */
151625f2d433Sxy 		ctrl |= E1000_CTRL_SWDPIN0;
151725f2d433Sxy 		ctrl |= E1000_CTRL_SWDPIO0;
151825f2d433Sxy 	} else {
151925f2d433Sxy 		ctrl &= ~E1000_CTRL_SWDPIN0;
152025f2d433Sxy 		ctrl |= E1000_CTRL_SWDPIO0;
152125f2d433Sxy 	}
152225f2d433Sxy 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
152325f2d433Sxy 
152475eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
152525f2d433Sxy }
152625f2d433Sxy 
152775eba5b6SRobert Mustacchi /**
152875eba5b6SRobert Mustacchi  *  e1000_clear_hw_cntrs_82543 - Clear device specific hardware counters
152975eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
153025f2d433Sxy  *
153175eba5b6SRobert Mustacchi  *  Clears the hardware counters by reading the counter registers.
153275eba5b6SRobert Mustacchi  **/
e1000_clear_hw_cntrs_82543(struct e1000_hw * hw)153375eba5b6SRobert Mustacchi static void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw)
153425f2d433Sxy {
153525f2d433Sxy 	DEBUGFUNC("e1000_clear_hw_cntrs_82543");
153625f2d433Sxy 
153725f2d433Sxy 	e1000_clear_hw_cntrs_base_generic(hw);
153825f2d433Sxy 
153975eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC64);
154075eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC127);
154175eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC255);
154275eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC511);
154375eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC1023);
154475eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC1522);
154575eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC64);
154675eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC127);
154775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC255);
154875eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC511);
154975eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC1023);
155075eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC1522);
155175eba5b6SRobert Mustacchi 
155275eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ALGNERRC);
155375eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_RXERRC);
155475eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_TNCRS);
155575eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_CEXTERR);
155675eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_TSCTC);
155775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_TSCTFC);
155875eba5b6SRobert Mustacchi }
155975eba5b6SRobert Mustacchi 
156075eba5b6SRobert Mustacchi /**
156175eba5b6SRobert Mustacchi  *  e1000_read_mac_addr_82543 - Read device MAC address
156275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
156375eba5b6SRobert Mustacchi  *
156475eba5b6SRobert Mustacchi  *  Reads the device MAC address from the EEPROM and stores the value.
156575eba5b6SRobert Mustacchi  *  Since devices with two ports use the same EEPROM, we increment the
156675eba5b6SRobert Mustacchi  *  last bit in the MAC address for the second port.
156775eba5b6SRobert Mustacchi  *
156875eba5b6SRobert Mustacchi  **/
e1000_read_mac_addr_82543(struct e1000_hw * hw)156975eba5b6SRobert Mustacchi s32 e1000_read_mac_addr_82543(struct e1000_hw *hw)
157075eba5b6SRobert Mustacchi {
157175eba5b6SRobert Mustacchi 	s32  ret_val = E1000_SUCCESS;
157275eba5b6SRobert Mustacchi 	u16 offset, nvm_data, i;
157375eba5b6SRobert Mustacchi 
157475eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_read_mac_addr");
157575eba5b6SRobert Mustacchi 
157675eba5b6SRobert Mustacchi 	for (i = 0; i < ETH_ADDR_LEN; i += 2) {
157775eba5b6SRobert Mustacchi 		offset = i >> 1;
157875eba5b6SRobert Mustacchi 		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
157975eba5b6SRobert Mustacchi 		if (ret_val) {
158075eba5b6SRobert Mustacchi 			DEBUGOUT("NVM Read Error\n");
158175eba5b6SRobert Mustacchi 			goto out;
158275eba5b6SRobert Mustacchi 		}
158375eba5b6SRobert Mustacchi 		hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
158475eba5b6SRobert Mustacchi 		hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
158575eba5b6SRobert Mustacchi 	}
158675eba5b6SRobert Mustacchi 
158775eba5b6SRobert Mustacchi 	/* Flip last bit of mac address if we're on second port */
158875eba5b6SRobert Mustacchi 	if (hw->bus.func == E1000_FUNC_1)
158975eba5b6SRobert Mustacchi 		hw->mac.perm_addr[5] ^= 1;
159075eba5b6SRobert Mustacchi 
159175eba5b6SRobert Mustacchi 	for (i = 0; i < ETH_ADDR_LEN; i++)
159275eba5b6SRobert Mustacchi 		hw->mac.addr[i] = hw->mac.perm_addr[i];
159375eba5b6SRobert Mustacchi 
159475eba5b6SRobert Mustacchi out:
159575eba5b6SRobert Mustacchi 	return ret_val;
159625f2d433Sxy }
1597