xref: /onnv-gate/usr/src/uts/common/io/e1000g/e1000_82543.c (revision 11143:f855b68211a7)
14919Sxy150489 /*
24919Sxy150489  * This file is provided under a CDDLv1 license.  When using or
34919Sxy150489  * redistributing this file, you may do so under this license.
44919Sxy150489  * In redistributing this file this license must be included
54919Sxy150489  * and no other modification of this header file is permitted.
64919Sxy150489  *
74919Sxy150489  * CDDL LICENSE SUMMARY
84919Sxy150489  *
98479SChenlu.Chen@Sun.COM  * Copyright(c) 1999 - 2009 Intel Corporation. All rights reserved.
104919Sxy150489  *
114919Sxy150489  * The contents of this file are subject to the terms of Version
124919Sxy150489  * 1.0 of the Common Development and Distribution License (the "License").
134919Sxy150489  *
144919Sxy150489  * You should have received a copy of the License with this software.
154919Sxy150489  * You can obtain a copy of the License at
164919Sxy150489  *	http://www.opensolaris.org/os/licensing.
174919Sxy150489  * See the License for the specific language governing permissions
184919Sxy150489  * and limitations under the License.
194919Sxy150489  */
204919Sxy150489 
214919Sxy150489 /*
228479SChenlu.Chen@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
234919Sxy150489  * Use is subject to license terms of the CDDLv1.
244919Sxy150489  */
254919Sxy150489 
264919Sxy150489 /*
2711020SMin.Xu@Sun.COM  * IntelVersion: 1.68 v3-1-10-1_2009-9-18_Release14-6
284919Sxy150489  */
296735Scc210113 
304919Sxy150489 /*
318479SChenlu.Chen@Sun.COM  * 82543GC Gigabit Ethernet Controller (Fiber)
328479SChenlu.Chen@Sun.COM  * 82543GC Gigabit Ethernet Controller (Copper)
338479SChenlu.Chen@Sun.COM  * 82544EI Gigabit Ethernet Controller (Copper)
348479SChenlu.Chen@Sun.COM  * 82544EI Gigabit Ethernet Controller (Fiber)
358479SChenlu.Chen@Sun.COM  * 82544GC Gigabit Ethernet Controller (Copper)
368479SChenlu.Chen@Sun.COM  * 82544GC Gigabit Ethernet Controller (LOM)
374919Sxy150489  */
384919Sxy150489 
394919Sxy150489 #include "e1000_api.h"
404919Sxy150489 
414919Sxy150489 static s32 e1000_init_phy_params_82543(struct e1000_hw *hw);
424919Sxy150489 static s32 e1000_init_nvm_params_82543(struct e1000_hw *hw);
434919Sxy150489 static s32 e1000_init_mac_params_82543(struct e1000_hw *hw);
444919Sxy150489 static s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset,
454919Sxy150489     u16 *data);
464919Sxy150489 static s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset,
474919Sxy150489     u16 data);
484919Sxy150489 static s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw);
494919Sxy150489 static s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw);
504919Sxy150489 static s32 e1000_reset_hw_82543(struct e1000_hw *hw);
514919Sxy150489 static s32 e1000_init_hw_82543(struct e1000_hw *hw);
524919Sxy150489 static s32 e1000_setup_link_82543(struct e1000_hw *hw);
534919Sxy150489 static s32 e1000_setup_copper_link_82543(struct e1000_hw *hw);
544919Sxy150489 static s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw);
554919Sxy150489 static s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw);
564919Sxy150489 static s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw);
574919Sxy150489 static s32 e1000_led_on_82543(struct e1000_hw *hw);
584919Sxy150489 static s32 e1000_led_off_82543(struct e1000_hw *hw);
594919Sxy150489 static void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset,
604919Sxy150489     u32 value);
614919Sxy150489 static void e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value);
624919Sxy150489 static void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw);
634919Sxy150489 static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw);
646735Scc210113 static bool e1000_init_phy_disabled_82543(struct e1000_hw *hw);
654919Sxy150489 static void e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl);
664919Sxy150489 static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw);
674919Sxy150489 static void e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl);
684919Sxy150489 static u16 e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw);
694919Sxy150489 static void e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data,
704919Sxy150489     u16 count);
716735Scc210113 static bool e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw);
726735Scc210113 static void e1000_set_tbi_sbp_82543(struct e1000_hw *hw, bool state);
734919Sxy150489 
744919Sxy150489 /*
754919Sxy150489  * e1000_init_phy_params_82543 - Init PHY func ptrs.
764919Sxy150489  * @hw: pointer to the HW structure
774919Sxy150489  */
784919Sxy150489 static s32
e1000_init_phy_params_82543(struct e1000_hw * hw)794919Sxy150489 e1000_init_phy_params_82543(struct e1000_hw *hw)
804919Sxy150489 {
814919Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
824919Sxy150489 	s32 ret_val = E1000_SUCCESS;
834919Sxy150489 
844919Sxy150489 	DEBUGFUNC("e1000_init_phy_params_82543");
854919Sxy150489 
866735Scc210113 	if (hw->phy.media_type != e1000_media_type_copper) {
874919Sxy150489 		phy->type = e1000_phy_none;
884919Sxy150489 		goto out;
896735Scc210113 	} else {
906735Scc210113 		phy->ops.power_up = e1000_power_up_phy_copper;
916735Scc210113 		phy->ops.power_down = e1000_power_down_phy_copper;
924919Sxy150489 	}
934919Sxy150489 
944919Sxy150489 	phy->addr = 1;
954919Sxy150489 	phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
964919Sxy150489 	phy->reset_delay_us = 10000;
974919Sxy150489 	phy->type = e1000_phy_m88;
984919Sxy150489 
994919Sxy150489 	/* Function Pointers */
1006735Scc210113 	phy->ops.check_polarity = e1000_check_polarity_m88;
1016735Scc210113 	phy->ops.commit = e1000_phy_sw_reset_generic;
1026735Scc210113 	phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_82543;
1036735Scc210113 	phy->ops.get_cable_length = e1000_get_cable_length_m88;
1046735Scc210113 	phy->ops.get_cfg_done = e1000_get_cfg_done_generic;
1056735Scc210113 	phy->ops.read_reg = (hw->mac.type == e1000_82543)
1064919Sxy150489 	    ? e1000_read_phy_reg_82543
1074919Sxy150489 	    : e1000_read_phy_reg_m88;
1086735Scc210113 	phy->ops.reset = (hw->mac.type == e1000_82543)
1094919Sxy150489 	    ? e1000_phy_hw_reset_82543
1104919Sxy150489 	    : e1000_phy_hw_reset_generic;
1116735Scc210113 	phy->ops.write_reg = (hw->mac.type == e1000_82543)
1124919Sxy150489 	    ? e1000_write_phy_reg_82543
1134919Sxy150489 	    : e1000_write_phy_reg_m88;
1146735Scc210113 	phy->ops.get_info = e1000_get_phy_info_m88;
1154919Sxy150489 
1164919Sxy150489 	/*
1174919Sxy150489 	 * The external PHY of the 82543 can be in a funky state.
1184919Sxy150489 	 * Resetting helps us read the PHY registers for acquiring
1194919Sxy150489 	 * the PHY ID.
1204919Sxy150489 	 */
1214919Sxy150489 	if (!e1000_init_phy_disabled_82543(hw)) {
1226735Scc210113 		ret_val = phy->ops.reset(hw);
1234919Sxy150489 		if (ret_val) {
1244919Sxy150489 			DEBUGOUT("Resetting PHY during init failed.\n");
1254919Sxy150489 			goto out;
1264919Sxy150489 		}
1274919Sxy150489 		msec_delay(20);
1284919Sxy150489 	}
1294919Sxy150489 
1304919Sxy150489 	ret_val = e1000_get_phy_id(hw);
1314919Sxy150489 	if (ret_val)
1324919Sxy150489 		goto out;
1334919Sxy150489 
1344919Sxy150489 	/* Verify phy id */
1354919Sxy150489 	switch (hw->mac.type) {
1364919Sxy150489 	case e1000_82543:
1374919Sxy150489 		if (phy->id != M88E1000_E_PHY_ID) {
1384919Sxy150489 			ret_val = -E1000_ERR_PHY;
1394919Sxy150489 			goto out;
1404919Sxy150489 		}
1414919Sxy150489 		break;
1424919Sxy150489 	case e1000_82544:
1434919Sxy150489 		if (phy->id != M88E1000_I_PHY_ID) {
1444919Sxy150489 			ret_val = -E1000_ERR_PHY;
1454919Sxy150489 			goto out;
1464919Sxy150489 		}
1474919Sxy150489 		break;
1484919Sxy150489 	default:
1494919Sxy150489 		ret_val = -E1000_ERR_PHY;
1504919Sxy150489 		goto out;
1514919Sxy150489 	}
1524919Sxy150489 
1534919Sxy150489 out:
1544919Sxy150489 	return (ret_val);
1554919Sxy150489 }
1564919Sxy150489 
1574919Sxy150489 /*
1584919Sxy150489  * e1000_init_nvm_params_82543 - Init NVM func ptrs.
1594919Sxy150489  * @hw: pointer to the HW structure
1604919Sxy150489  */
1614919Sxy150489 static s32
e1000_init_nvm_params_82543(struct e1000_hw * hw)1624919Sxy150489 e1000_init_nvm_params_82543(struct e1000_hw *hw)
1634919Sxy150489 {
1644919Sxy150489 	struct e1000_nvm_info *nvm = &hw->nvm;
1654919Sxy150489 
1664919Sxy150489 	DEBUGFUNC("e1000_init_nvm_params_82543");
1674919Sxy150489 
1684919Sxy150489 	nvm->type = e1000_nvm_eeprom_microwire;
1694919Sxy150489 	nvm->word_size = 64;
1704919Sxy150489 	nvm->delay_usec = 50;
1714919Sxy150489 	nvm->address_bits = 6;
1724919Sxy150489 	nvm->opcode_bits = 3;
1734919Sxy150489 
1744919Sxy150489 	/* Function Pointers */
1756735Scc210113 	nvm->ops.read = e1000_read_nvm_microwire;
1766735Scc210113 	nvm->ops.update = e1000_update_nvm_checksum_generic;
1776735Scc210113 	nvm->ops.valid_led_default = e1000_valid_led_default_generic;
1786735Scc210113 	nvm->ops.validate = e1000_validate_nvm_checksum_generic;
1796735Scc210113 	nvm->ops.write = e1000_write_nvm_microwire;
1804919Sxy150489 
1814919Sxy150489 	return (E1000_SUCCESS);
1824919Sxy150489 }
1834919Sxy150489 
1844919Sxy150489 /*
1854919Sxy150489  * e1000_init_mac_params_82543 - Init MAC func ptrs.
1864919Sxy150489  * @hw: pointer to the HW structure
1874919Sxy150489  */
1884919Sxy150489 static s32
e1000_init_mac_params_82543(struct e1000_hw * hw)1894919Sxy150489 e1000_init_mac_params_82543(struct e1000_hw *hw)
1904919Sxy150489 {
1914919Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
1924919Sxy150489 
1934919Sxy150489 	DEBUGFUNC("e1000_init_mac_params_82543");
1944919Sxy150489 
1954919Sxy150489 	/* Set media type */
1964919Sxy150489 	switch (hw->device_id) {
1974919Sxy150489 	case E1000_DEV_ID_82543GC_FIBER:
1984919Sxy150489 	case E1000_DEV_ID_82544EI_FIBER:
1996735Scc210113 		hw->phy.media_type = e1000_media_type_fiber;
2004919Sxy150489 		break;
2014919Sxy150489 	default:
2026735Scc210113 		hw->phy.media_type = e1000_media_type_copper;
2034919Sxy150489 		break;
2044919Sxy150489 	}
2054919Sxy150489 
2064919Sxy150489 	/* Set mta register count */
2074919Sxy150489 	mac->mta_reg_count = 128;
2084919Sxy150489 	/* Set rar entry count */
2094919Sxy150489 	mac->rar_entry_count = E1000_RAR_ENTRIES;
2104919Sxy150489 
2114919Sxy150489 	/* Function pointers */
2124919Sxy150489 
2134919Sxy150489 	/* bus type/speed/width */
2146735Scc210113 	mac->ops.get_bus_info = e1000_get_bus_info_pci_generic;
21510680SMin.Xu@Sun.COM 	/* function id */
21610680SMin.Xu@Sun.COM 	mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pci;
2174919Sxy150489 	/* reset */
2186735Scc210113 	mac->ops.reset_hw = e1000_reset_hw_82543;
2194919Sxy150489 	/* hw initialization */
2206735Scc210113 	mac->ops.init_hw = e1000_init_hw_82543;
2214919Sxy150489 	/* link setup */
2226735Scc210113 	mac->ops.setup_link = e1000_setup_link_82543;
2234919Sxy150489 	/* physical interface setup */
2246735Scc210113 	mac->ops.setup_physical_interface =
2256735Scc210113 	    (hw->phy.media_type == e1000_media_type_copper)
2264919Sxy150489 	    ? e1000_setup_copper_link_82543
2274919Sxy150489 	    : e1000_setup_fiber_link_82543;
2284919Sxy150489 	/* check for link */
2296735Scc210113 	mac->ops.check_for_link =
2306735Scc210113 	    (hw->phy.media_type == e1000_media_type_copper)
2314919Sxy150489 	    ? e1000_check_for_copper_link_82543
2324919Sxy150489 	    : e1000_check_for_fiber_link_82543;
2334919Sxy150489 	/* link info */
2346735Scc210113 	mac->ops.get_link_up_info =
2356735Scc210113 	    (hw->phy.media_type == e1000_media_type_copper)
2364919Sxy150489 	    ? e1000_get_speed_and_duplex_copper_generic
2374919Sxy150489 	    : e1000_get_speed_and_duplex_fiber_serdes_generic;
2384919Sxy150489 	/* multicast address update */
2396735Scc210113 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
2404919Sxy150489 	/* writing VFTA */
2416735Scc210113 	mac->ops.write_vfta = e1000_write_vfta_82543;
2424919Sxy150489 	/* clearing VFTA */
2436735Scc210113 	mac->ops.clear_vfta = e1000_clear_vfta_generic;
2444919Sxy150489 	/* setting MTA */
2456735Scc210113 	mac->ops.mta_set = e1000_mta_set_82543;
2464919Sxy150489 	/* turn on/off LED */
2476735Scc210113 	mac->ops.led_on = e1000_led_on_82543;
2486735Scc210113 	mac->ops.led_off = e1000_led_off_82543;
2494919Sxy150489 	/* clear hardware counters */
2506735Scc210113 	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82543;
2514919Sxy150489 
2524919Sxy150489 	/* Set tbi compatibility */
2534919Sxy150489 	if ((hw->mac.type != e1000_82543) ||
2546735Scc210113 	    (hw->phy.media_type == e1000_media_type_fiber))
2557607STed.You@Sun.COM 		e1000_set_tbi_compatibility_82543(hw, false);
2564919Sxy150489 
2578479SChenlu.Chen@Sun.COM 	return (E1000_SUCCESS);
2584919Sxy150489 }
2594919Sxy150489 
2604919Sxy150489 /*
2614919Sxy150489  * e1000_init_function_pointers_82543 - Init func ptrs.
2624919Sxy150489  * @hw: pointer to the HW structure
2634919Sxy150489  *
2648479SChenlu.Chen@Sun.COM  * Called to initialize all function pointers and parameters.
2654919Sxy150489  */
2664919Sxy150489 void
e1000_init_function_pointers_82543(struct e1000_hw * hw)2674919Sxy150489 e1000_init_function_pointers_82543(struct e1000_hw *hw)
2684919Sxy150489 {
2694919Sxy150489 	DEBUGFUNC("e1000_init_function_pointers_82543");
2704919Sxy150489 
2716735Scc210113 	hw->mac.ops.init_params = e1000_init_mac_params_82543;
2726735Scc210113 	hw->nvm.ops.init_params = e1000_init_nvm_params_82543;
2736735Scc210113 	hw->phy.ops.init_params = e1000_init_phy_params_82543;
2744919Sxy150489 }
2754919Sxy150489 
2764919Sxy150489 /*
2774919Sxy150489  * e1000_tbi_compatibility_enabled_82543 - Returns TBI compat status
2784919Sxy150489  * @hw: pointer to the HW structure
2794919Sxy150489  *
2806735Scc210113  * Returns the current status of 10-bit Interface (TBI) compatibility
2814919Sxy150489  * (enabled/disabled).
2824919Sxy150489  */
2836735Scc210113 static bool
e1000_tbi_compatibility_enabled_82543(struct e1000_hw * hw)2844919Sxy150489 e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw)
2854919Sxy150489 {
2868479SChenlu.Chen@Sun.COM 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
2877607STed.You@Sun.COM 	bool state = false;
2884919Sxy150489 
2894919Sxy150489 	DEBUGFUNC("e1000_tbi_compatibility_enabled_82543");
2904919Sxy150489 
2914919Sxy150489 	if (hw->mac.type != e1000_82543) {
2924919Sxy150489 		DEBUGOUT("TBI compatibility workaround for 82543 only.\n");
2934919Sxy150489 		goto out;
2944919Sxy150489 	}
2954919Sxy150489 
2964919Sxy150489 	state = (dev_spec->tbi_compatibility & TBI_COMPAT_ENABLED)
2977607STed.You@Sun.COM 	    ? true : false;
2984919Sxy150489 
2994919Sxy150489 out:
3004919Sxy150489 	return (state);
3014919Sxy150489 }
3024919Sxy150489 
3034919Sxy150489 /*
3044919Sxy150489  * e1000_set_tbi_compatibility_82543 - Set TBI compatibility
3054919Sxy150489  * @hw: pointer to the HW structure
3064919Sxy150489  * @state: enable/disable TBI compatibility
3074919Sxy150489  *
3084919Sxy150489  * Enables or disabled 10-bit Interface (TBI) compatibility.
3094919Sxy150489  */
3104919Sxy150489 void
e1000_set_tbi_compatibility_82543(struct e1000_hw * hw,bool state)3116735Scc210113 e1000_set_tbi_compatibility_82543(struct e1000_hw *hw, bool state)
3124919Sxy150489 {
3138479SChenlu.Chen@Sun.COM 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
3144919Sxy150489 
3154919Sxy150489 	DEBUGFUNC("e1000_set_tbi_compatibility_82543");
3164919Sxy150489 
3174919Sxy150489 	if (hw->mac.type != e1000_82543) {
3184919Sxy150489 		DEBUGOUT("TBI compatibility workaround for 82543 only.\n");
3194919Sxy150489 		return;
3204919Sxy150489 	}
3214919Sxy150489 
3224919Sxy150489 	if (state)
3234919Sxy150489 		dev_spec->tbi_compatibility |= TBI_COMPAT_ENABLED;
3244919Sxy150489 	else
3254919Sxy150489 		dev_spec->tbi_compatibility &= ~TBI_COMPAT_ENABLED;
3264919Sxy150489 }
3274919Sxy150489 
3284919Sxy150489 /*
3294919Sxy150489  * e1000_tbi_sbp_enabled_82543 - Returns TBI SBP status
3304919Sxy150489  * @hw: pointer to the HW structure
3314919Sxy150489  *
3326735Scc210113  * Returns the current status of 10-bit Interface (TBI) store bad packet (SBP)
3334919Sxy150489  * (enabled/disabled).
3344919Sxy150489  */
3356735Scc210113 bool
e1000_tbi_sbp_enabled_82543(struct e1000_hw * hw)3364919Sxy150489 e1000_tbi_sbp_enabled_82543(struct e1000_hw *hw)
3374919Sxy150489 {
3388479SChenlu.Chen@Sun.COM 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
3397607STed.You@Sun.COM 	bool state = false;
3404919Sxy150489 
3414919Sxy150489 	DEBUGFUNC("e1000_tbi_sbp_enabled_82543");
3424919Sxy150489 
3434919Sxy150489 	if (hw->mac.type != e1000_82543) {
3444919Sxy150489 		DEBUGOUT("TBI compatibility workaround for 82543 only.\n");
3454919Sxy150489 		goto out;
3464919Sxy150489 	}
3474919Sxy150489 
3484919Sxy150489 	state = (dev_spec->tbi_compatibility & TBI_SBP_ENABLED)
3497607STed.You@Sun.COM 	    ? true : false;
3504919Sxy150489 
3514919Sxy150489 out:
3524919Sxy150489 	return (state);
3534919Sxy150489 }
3544919Sxy150489 
3554919Sxy150489 /*
3564919Sxy150489  * e1000_set_tbi_sbp_82543 - Set TBI SBP
3574919Sxy150489  * @hw: pointer to the HW structure
3584919Sxy150489  * @state: enable/disable TBI store bad packet
3594919Sxy150489  *
3604919Sxy150489  * Enables or disabled 10-bit Interface (TBI) store bad packet (SBP).
3614919Sxy150489  */
3624919Sxy150489 static void
e1000_set_tbi_sbp_82543(struct e1000_hw * hw,bool state)3636735Scc210113 e1000_set_tbi_sbp_82543(struct e1000_hw *hw, bool state)
3644919Sxy150489 {
3658479SChenlu.Chen@Sun.COM 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
3664919Sxy150489 
3674919Sxy150489 	DEBUGFUNC("e1000_set_tbi_sbp_82543");
3684919Sxy150489 
3694919Sxy150489 	if (state && e1000_tbi_compatibility_enabled_82543(hw))
3704919Sxy150489 		dev_spec->tbi_compatibility |= TBI_SBP_ENABLED;
3714919Sxy150489 	else
3724919Sxy150489 		dev_spec->tbi_compatibility &= ~TBI_SBP_ENABLED;
3734919Sxy150489 }
3744919Sxy150489 
3754919Sxy150489 /*
3764919Sxy150489  * e1000_init_phy_disabled_82543 - Returns init PHY status
3774919Sxy150489  * @hw: pointer to the HW structure
3784919Sxy150489  *
3794919Sxy150489  * Returns the current status of whether PHY initialization is disabled.
3804919Sxy150489  * True if PHY initialization is disabled else false.
3814919Sxy150489  */
3826735Scc210113 static bool
e1000_init_phy_disabled_82543(struct e1000_hw * hw)3834919Sxy150489 e1000_init_phy_disabled_82543(struct e1000_hw *hw)
3844919Sxy150489 {
3858479SChenlu.Chen@Sun.COM 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
3866735Scc210113 	bool ret_val;
3874919Sxy150489 
3884919Sxy150489 	DEBUGFUNC("e1000_init_phy_disabled_82543");
3894919Sxy150489 
3904919Sxy150489 	if (hw->mac.type != e1000_82543) {
3917607STed.You@Sun.COM 		ret_val = false;
3924919Sxy150489 		goto out;
3934919Sxy150489 	}
3944919Sxy150489 
3954919Sxy150489 	ret_val = dev_spec->init_phy_disabled;
3964919Sxy150489 
3974919Sxy150489 out:
3984919Sxy150489 	return (ret_val);
3994919Sxy150489 }
4004919Sxy150489 
4014919Sxy150489 /*
4024919Sxy150489  * e1000_tbi_adjust_stats_82543 - Adjust stats when TBI enabled
4034919Sxy150489  * @hw: pointer to the HW structure
4044919Sxy150489  * @stats: Struct containing statistic register values
4054919Sxy150489  * @frame_len: The length of the frame in question
4064919Sxy150489  * @mac_addr: The Ethernet destination address of the frame in question
4076735Scc210113  * @max_frame_size: The maximum frame size
4084919Sxy150489  *
4094919Sxy150489  * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
4104919Sxy150489  */
4114919Sxy150489 void
e1000_tbi_adjust_stats_82543(struct e1000_hw * hw,struct e1000_hw_stats * stats,u32 frame_len,u8 * mac_addr,u32 max_frame_size)4124919Sxy150489 e1000_tbi_adjust_stats_82543(struct e1000_hw *hw,
4136735Scc210113     struct e1000_hw_stats *stats, u32 frame_len,
4146735Scc210113     u8 *mac_addr, u32 max_frame_size)
4154919Sxy150489 {
4164919Sxy150489 	if (!(e1000_tbi_sbp_enabled_82543(hw)))
4174919Sxy150489 		return;
4184919Sxy150489 
4194919Sxy150489 	/* First adjust the frame length. */
4204919Sxy150489 	frame_len--;
4214919Sxy150489 	/*
4224919Sxy150489 	 * We need to adjust the statistics counters, since the hardware
4234919Sxy150489 	 * counters overcount this packet as a CRC error and undercount
4244919Sxy150489 	 * the packet as a good packet
4254919Sxy150489 	 */
4264919Sxy150489 	/* This packet should not be counted as a CRC error. */
4274919Sxy150489 	stats->crcerrs--;
4284919Sxy150489 	/* This packet does count as a Good Packet Received. */
4294919Sxy150489 	stats->gprc++;
4304919Sxy150489 
4314919Sxy150489 	/* Adjust the Good Octets received counters */
4326735Scc210113 	stats->gorc += frame_len;
4336735Scc210113 
4344919Sxy150489 	/*
4356735Scc210113 	 * Is this a broadcast or multicast?  Check broadcast first, since
4366735Scc210113 	 * the test for a multicast frame will test positive on a broadcast
4376735Scc210113 	 * frame.
4384919Sxy150489 	 */
4394919Sxy150489 	if ((mac_addr[0] == 0xff) && (mac_addr[1] == 0xff))
4404919Sxy150489 		/* Broadcast packet */
4414919Sxy150489 		stats->bprc++;
4424919Sxy150489 	else if (*mac_addr & 0x01)
4434919Sxy150489 		/* Multicast packet */
4444919Sxy150489 		stats->mprc++;
4454919Sxy150489 
4464919Sxy150489 	/*
4474919Sxy150489 	 * In this case, the hardware has overcounted the number of
4484919Sxy150489 	 * oversize frames.
4494919Sxy150489 	 */
4506735Scc210113 	if ((frame_len == max_frame_size) && (stats->roc > 0))
4514919Sxy150489 		stats->roc--;
4524919Sxy150489 
4534919Sxy150489 	/*
4544919Sxy150489 	 * Adjust the bin counters when the extra byte put the frame in the
4554919Sxy150489 	 * wrong bin. Remember that the frame_len was adjusted above.
4564919Sxy150489 	 */
4574919Sxy150489 	if (frame_len == 64) {
4584919Sxy150489 		stats->prc64++;
4594919Sxy150489 		stats->prc127--;
4604919Sxy150489 	} else if (frame_len == 127) {
4614919Sxy150489 		stats->prc127++;
4624919Sxy150489 		stats->prc255--;
4634919Sxy150489 	} else if (frame_len == 255) {
4644919Sxy150489 		stats->prc255++;
4654919Sxy150489 		stats->prc511--;
4664919Sxy150489 	} else if (frame_len == 511) {
4674919Sxy150489 		stats->prc511++;
4684919Sxy150489 		stats->prc1023--;
4694919Sxy150489 	} else if (frame_len == 1023) {
4704919Sxy150489 		stats->prc1023++;
4714919Sxy150489 		stats->prc1522--;
4724919Sxy150489 	} else if (frame_len == 1522) {
4734919Sxy150489 		stats->prc1522++;
4744919Sxy150489 	}
4754919Sxy150489 }
4764919Sxy150489 
4774919Sxy150489 /*
4784919Sxy150489  * e1000_read_phy_reg_82543 - Read PHY register
4794919Sxy150489  * @hw: pointer to the HW structure
4804919Sxy150489  * @offset: register offset to be read
4814919Sxy150489  * @data: pointer to the read data
4824919Sxy150489  *
4834919Sxy150489  * Reads the PHY at offset and stores the information read to data.
4844919Sxy150489  */
4854919Sxy150489 static s32
e1000_read_phy_reg_82543(struct e1000_hw * hw,u32 offset,u16 * data)4864919Sxy150489 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 * data)
4874919Sxy150489 {
4884919Sxy150489 	u32 mdic;
4894919Sxy150489 	s32 ret_val = E1000_SUCCESS;
4904919Sxy150489 
4914919Sxy150489 	DEBUGFUNC("e1000_read_phy_reg_82543");
4924919Sxy150489 
4934919Sxy150489 	if (offset > MAX_PHY_REG_ADDRESS) {
4944919Sxy150489 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
4954919Sxy150489 		ret_val = -E1000_ERR_PARAM;
4964919Sxy150489 		goto out;
4974919Sxy150489 	}
4984919Sxy150489 
4994919Sxy150489 	/*
5004919Sxy150489 	 * We must first send a preamble through the MDIO pin to signal the
5014919Sxy150489 	 * beginning of an MII instruction.  This is done by sending 32
5024919Sxy150489 	 * consecutive "1" bits.
5034919Sxy150489 	 */
5044919Sxy150489 	e1000_shift_out_mdi_bits_82543(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
5054919Sxy150489 
5064919Sxy150489 	/*
5074919Sxy150489 	 * Now combine the next few fields that are required for a read
5084919Sxy150489 	 * operation.  We use this method instead of calling the
5094919Sxy150489 	 * e1000_shift_out_mdi_bits routine five different times.  The format
5104919Sxy150489 	 * of an MII read instruction consists of a shift out of 14 bits and
5114919Sxy150489 	 * is defined as follows:
5124919Sxy150489 	 *	<Preamble><SOF><Op Code><Phy Addr><Offset>
5134919Sxy150489 	 * followed by a shift in of 18 bits.  This first two bits shifted in
5144919Sxy150489 	 * are TurnAround bits used to avoid contention on the MDIO pin when a
5154919Sxy150489 	 * READ operation is performed.  These two bits are thrown away
5164919Sxy150489 	 * followed by a shift in of 16 bits which contains the desired data.
5174919Sxy150489 	 */
5184919Sxy150489 	mdic = (offset | (hw->phy.addr << 5) |
5194919Sxy150489 	    (PHY_OP_READ << 10) | (PHY_SOF << 12));
5204919Sxy150489 
5214919Sxy150489 	e1000_shift_out_mdi_bits_82543(hw, mdic, 14);
5224919Sxy150489 
5234919Sxy150489 	/*
5244919Sxy150489 	 * Now that we've shifted out the read command to the MII, we need to
5254919Sxy150489 	 * "shift in" the 16-bit value (18 total bits) of the requested PHY
5264919Sxy150489 	 * register address.
5274919Sxy150489 	 */
5284919Sxy150489 	*data = e1000_shift_in_mdi_bits_82543(hw);
5294919Sxy150489 
5304919Sxy150489 out:
5314919Sxy150489 	return (ret_val);
5324919Sxy150489 }
5334919Sxy150489 
5344919Sxy150489 /*
5354919Sxy150489  * e1000_write_phy_reg_82543 - Write PHY register
5364919Sxy150489  * @hw: pointer to the HW structure
5374919Sxy150489  * @offset: register offset to be written
5384919Sxy150489  * @data: pointer to the data to be written at offset
5394919Sxy150489  *
5404919Sxy150489  * Writes data to the PHY at offset.
5414919Sxy150489  */
5424919Sxy150489 static s32
e1000_write_phy_reg_82543(struct e1000_hw * hw,u32 offset,u16 data)5434919Sxy150489 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 data)
5444919Sxy150489 {
5454919Sxy150489 	u32 mdic;
5464919Sxy150489 	s32 ret_val = E1000_SUCCESS;
5474919Sxy150489 
5484919Sxy150489 	DEBUGFUNC("e1000_write_phy_reg_82543");
5494919Sxy150489 
5504919Sxy150489 	if (offset > MAX_PHY_REG_ADDRESS) {
5514919Sxy150489 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
5524919Sxy150489 		ret_val = -E1000_ERR_PARAM;
5534919Sxy150489 		goto out;
5544919Sxy150489 	}
5554919Sxy150489 
5564919Sxy150489 	/*
5574919Sxy150489 	 * We'll need to use the SW defined pins to shift the write command
5584919Sxy150489 	 * out to the PHY. We first send a preamble to the PHY to signal the
5594919Sxy150489 	 * beginning of the MII instruction.  This is done by sending 32
5604919Sxy150489 	 * consecutive "1" bits.
5614919Sxy150489 	 */
5624919Sxy150489 	e1000_shift_out_mdi_bits_82543(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
5634919Sxy150489 
5644919Sxy150489 	/*
5654919Sxy150489 	 * Now combine the remaining required fields that will indicate a
5664919Sxy150489 	 * write operation. We use this method instead of calling the
5674919Sxy150489 	 * e1000_shift_out_mdi_bits routine for each field in the command. The
5684919Sxy150489 	 * format of a MII write instruction is as follows:
5694919Sxy150489 	 * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
5704919Sxy150489 	 */
5714919Sxy150489 	mdic = ((PHY_TURNAROUND) | (offset << 2) | (hw->phy.addr << 7) |
5724919Sxy150489 	    (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
5734919Sxy150489 	mdic <<= 16;
5744919Sxy150489 	mdic |= (u32) data;
5754919Sxy150489 
5764919Sxy150489 	e1000_shift_out_mdi_bits_82543(hw, mdic, 32);
5774919Sxy150489 
5784919Sxy150489 out:
5794919Sxy150489 	return (ret_val);
5804919Sxy150489 }
5814919Sxy150489 
5824919Sxy150489 /*
5834919Sxy150489  * e1000_raise_mdi_clk_82543 - Raise Management Data Input clock
5844919Sxy150489  * @hw: pointer to the HW structure
5854919Sxy150489  * @ctrl: pointer to the control register
5864919Sxy150489  *
5874919Sxy150489  * Raise the management data input clock by setting the MDC bit in the control
5884919Sxy150489  * register.
5894919Sxy150489  */
5904919Sxy150489 static void
e1000_raise_mdi_clk_82543(struct e1000_hw * hw,u32 * ctrl)5914919Sxy150489 e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 * ctrl)
5924919Sxy150489 {
5934919Sxy150489 	/*
5944919Sxy150489 	 * Raise the clock input to the Management Data Clock (by setting the
5954919Sxy150489 	 * MDC bit), and then delay a sufficient amount of time.
5964919Sxy150489 	 */
5974919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, (*ctrl | E1000_CTRL_MDC));
5984919Sxy150489 	E1000_WRITE_FLUSH(hw);
5994919Sxy150489 	usec_delay(10);
6004919Sxy150489 }
6014919Sxy150489 
6024919Sxy150489 /*
6034919Sxy150489  * e1000_lower_mdi_clk_82543 - Lower Management Data Input clock
6044919Sxy150489  * @hw: pointer to the HW structure
6054919Sxy150489  * @ctrl: pointer to the control register
6064919Sxy150489  *
6074919Sxy150489  * Lower the management data input clock by clearing the MDC bit in the control
6084919Sxy150489  * register.
6094919Sxy150489  */
6104919Sxy150489 static void
e1000_lower_mdi_clk_82543(struct e1000_hw * hw,u32 * ctrl)6114919Sxy150489 e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 * ctrl)
6124919Sxy150489 {
6134919Sxy150489 	/*
6144919Sxy150489 	 * Lower the clock input to the Management Data Clock (by clearing the
6154919Sxy150489 	 * MDC bit), and then delay a sufficient amount of time.
6164919Sxy150489 	 */
6174919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, (*ctrl & ~E1000_CTRL_MDC));
6184919Sxy150489 	E1000_WRITE_FLUSH(hw);
6194919Sxy150489 	usec_delay(10);
6204919Sxy150489 }
6214919Sxy150489 
6224919Sxy150489 /*
6234919Sxy150489  * e1000_shift_out_mdi_bits_82543 - Shift data bits our to the PHY
6244919Sxy150489  * @hw: pointer to the HW structure
6254919Sxy150489  * @data: data to send to the PHY
6264919Sxy150489  * @count: number of bits to shift out
6274919Sxy150489  *
6284919Sxy150489  * We need to shift 'count' bits out to the PHY.  So, the value in the
6294919Sxy150489  * "data" parameter will be shifted out to the PHY one bit at a time.
6304919Sxy150489  * In order to do this, "data" must be broken down into bits.
6314919Sxy150489  */
6324919Sxy150489 static void
e1000_shift_out_mdi_bits_82543(struct e1000_hw * hw,u32 data,u16 count)6334919Sxy150489 e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data,
6344919Sxy150489     u16 count)
6354919Sxy150489 {
6364919Sxy150489 	u32 ctrl, mask;
6374919Sxy150489 
6384919Sxy150489 	/*
6394919Sxy150489 	 * We need to shift "count" number of bits out to the PHY.  So, the
6404919Sxy150489 	 * value in the "data" parameter will be shifted out to the PHY one
6414919Sxy150489 	 * bit at a time.  In order to do this, "data" must be broken down
6424919Sxy150489 	 * into bits.
6434919Sxy150489 	 */
6444919Sxy150489 	mask = 0x01;
6454919Sxy150489 	mask <<= (count - 1);
6464919Sxy150489 
6474919Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
6484919Sxy150489 
6494919Sxy150489 	/* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
6504919Sxy150489 	ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
6514919Sxy150489 
6524919Sxy150489 	while (mask) {
6534919Sxy150489 		/*
6544919Sxy150489 		 * A "1" is shifted out to the PHY by setting the MDIO bit to
6554919Sxy150489 		 * "1" and then raising and lowering the Management Data Clock.
6564919Sxy150489 		 * A "0" is shifted out to the PHY by setting the MDIO bit to
6574919Sxy150489 		 * "0" and then raising and lowering the clock.
6584919Sxy150489 		 */
6594919Sxy150489 		if (data & mask)
6604919Sxy150489 			ctrl |= E1000_CTRL_MDIO;
6614919Sxy150489 		else
6624919Sxy150489 			ctrl &= ~E1000_CTRL_MDIO;
6634919Sxy150489 
6644919Sxy150489 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
6654919Sxy150489 		E1000_WRITE_FLUSH(hw);
6664919Sxy150489 
6674919Sxy150489 		usec_delay(10);
6684919Sxy150489 
6694919Sxy150489 		e1000_raise_mdi_clk_82543(hw, &ctrl);
6704919Sxy150489 		e1000_lower_mdi_clk_82543(hw, &ctrl);
6714919Sxy150489 
6724919Sxy150489 		mask >>= 1;
6734919Sxy150489 	}
6744919Sxy150489 }
6754919Sxy150489 
6764919Sxy150489 /*
6774919Sxy150489  * e1000_shift_in_mdi_bits_82543 - Shift data bits in from the PHY
6784919Sxy150489  * @hw: pointer to the HW structure
6794919Sxy150489  *
6804919Sxy150489  * In order to read a register from the PHY, we need to shift 18 bits
6814919Sxy150489  * in from the PHY.  Bits are "shifted in" by raising the clock input to
6824919Sxy150489  * the PHY (setting the MDC bit), and then reading the value of the data out
6834919Sxy150489  * MDIO bit.
6844919Sxy150489  */
6854919Sxy150489 static u16
e1000_shift_in_mdi_bits_82543(struct e1000_hw * hw)6864919Sxy150489 e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw)
6874919Sxy150489 {
6884919Sxy150489 	u32 ctrl;
6894919Sxy150489 	u16 data = 0;
6904919Sxy150489 	u8 i;
6914919Sxy150489 
6924919Sxy150489 	/*
6934919Sxy150489 	 * In order to read a register from the PHY, we need to shift in a
6944919Sxy150489 	 * total of 18 bits from the PHY.  The first two bit (turnaround)
6954919Sxy150489 	 * times are used to avoid contention on the MDIO pin when a read
6964919Sxy150489 	 * operation is performed.  These two bits are ignored by us and
6974919Sxy150489 	 * thrown away.  Bits are "shifted in" by raising the input to the
6984919Sxy150489 	 * Management Data Clock (setting the MDC bit) and then reading the
6994919Sxy150489 	 * value of the MDIO bit.
7004919Sxy150489 	 */
7014919Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
7024919Sxy150489 
7034919Sxy150489 	/*
7044919Sxy150489 	 * Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as
7054919Sxy150489 	 * input.
7064919Sxy150489 	 */
7074919Sxy150489 	ctrl &= ~E1000_CTRL_MDIO_DIR;
7084919Sxy150489 	ctrl &= ~E1000_CTRL_MDIO;
7094919Sxy150489 
7104919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
7114919Sxy150489 	E1000_WRITE_FLUSH(hw);
7124919Sxy150489 
7134919Sxy150489 	/*
7144919Sxy150489 	 * Raise and lower the clock before reading in the data.  This accounts
7154919Sxy150489 	 * for the turnaround bits.  The first clock occurred when we clocked
7164919Sxy150489 	 * out the last bit of the Register Address.
7174919Sxy150489 	 */
7184919Sxy150489 	e1000_raise_mdi_clk_82543(hw, &ctrl);
7194919Sxy150489 	e1000_lower_mdi_clk_82543(hw, &ctrl);
7204919Sxy150489 
7214919Sxy150489 	for (data = 0, i = 0; i < 16; i++) {
7224919Sxy150489 		data <<= 1;
7234919Sxy150489 		e1000_raise_mdi_clk_82543(hw, &ctrl);
7244919Sxy150489 		ctrl = E1000_READ_REG(hw, E1000_CTRL);
7254919Sxy150489 		/* Check to see if we shifted in a "1". */
7264919Sxy150489 		if (ctrl & E1000_CTRL_MDIO)
7274919Sxy150489 			data |= 1;
7284919Sxy150489 		e1000_lower_mdi_clk_82543(hw, &ctrl);
7294919Sxy150489 	}
7304919Sxy150489 
7314919Sxy150489 	e1000_raise_mdi_clk_82543(hw, &ctrl);
7324919Sxy150489 	e1000_lower_mdi_clk_82543(hw, &ctrl);
7334919Sxy150489 
7344919Sxy150489 	return (data);
7354919Sxy150489 }
7364919Sxy150489 
7374919Sxy150489 /*
7384919Sxy150489  * e1000_phy_force_speed_duplex_82543 - Force speed/duplex for PHY
7394919Sxy150489  * @hw: pointer to the HW structure
7404919Sxy150489  *
7414919Sxy150489  * Calls the function to force speed and duplex for the m88 PHY, and
7424919Sxy150489  * if the PHY is not auto-negotiating and the speed is forced to 10Mbit,
7434919Sxy150489  * then call the function for polarity reversal workaround.
7444919Sxy150489  */
7454919Sxy150489 static s32
e1000_phy_force_speed_duplex_82543(struct e1000_hw * hw)7464919Sxy150489 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw)
7474919Sxy150489 {
7484919Sxy150489 	s32 ret_val;
7494919Sxy150489 
7504919Sxy150489 	DEBUGFUNC("e1000_phy_force_speed_duplex_82543");
7514919Sxy150489 
7524919Sxy150489 	ret_val = e1000_phy_force_speed_duplex_m88(hw);
7534919Sxy150489 	if (ret_val)
7544919Sxy150489 		goto out;
7554919Sxy150489 
7564919Sxy150489 	if (!hw->mac.autoneg &&
7574919Sxy150489 	    (hw->mac.forced_speed_duplex & E1000_ALL_10_SPEED))
7584919Sxy150489 		ret_val = e1000_polarity_reversal_workaround_82543(hw);
7594919Sxy150489 
7604919Sxy150489 out:
7614919Sxy150489 	return (ret_val);
7624919Sxy150489 }
7634919Sxy150489 
7644919Sxy150489 /*
7654919Sxy150489  * e1000_polarity_reversal_workaround_82543 - Workaround polarity reversal
7664919Sxy150489  * @hw: pointer to the HW structure
7674919Sxy150489  *
7684919Sxy150489  * When forcing link to 10 Full or 10 Half, the PHY can reverse the polarity
7696735Scc210113  * inadvertently.  To workaround the issue, we disable the transmitter on
7704919Sxy150489  * the PHY until we have established the link partner's link parameters.
7714919Sxy150489  */
7724919Sxy150489 static s32
e1000_polarity_reversal_workaround_82543(struct e1000_hw * hw)7734919Sxy150489 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw)
7744919Sxy150489 {
7756735Scc210113 	s32 ret_val = E1000_SUCCESS;
7764919Sxy150489 	u16 mii_status_reg;
7774919Sxy150489 	u16 i;
7786735Scc210113 	bool link;
7796735Scc210113 
7806735Scc210113 	if (!(hw->phy.ops.write_reg))
7816735Scc210113 		goto out;
7824919Sxy150489 
7834919Sxy150489 	/* Polarity reversal workaround for forced 10F/10H links. */
7844919Sxy150489 
7854919Sxy150489 	/* Disable the transmitter on the PHY */
7864919Sxy150489 
7876735Scc210113 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
7884919Sxy150489 	if (ret_val)
7894919Sxy150489 		goto out;
7906735Scc210113 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
7914919Sxy150489 	if (ret_val)
7924919Sxy150489 		goto out;
7934919Sxy150489 
7946735Scc210113 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
7954919Sxy150489 	if (ret_val)
7964919Sxy150489 		goto out;
7974919Sxy150489 
7984919Sxy150489 	/*
7994919Sxy150489 	 * This loop will early-out if the NO link condition has been met.
8004919Sxy150489 	 * In other words, DO NOT use e1000_phy_has_link_generic() here.
8014919Sxy150489 	 */
8024919Sxy150489 	for (i = PHY_FORCE_TIME; i > 0; i--) {
8034919Sxy150489 		/*
8044919Sxy150489 		 * Read the MII Status Register and wait for Link Status bit
8054919Sxy150489 		 * to be clear.
8064919Sxy150489 		 */
8074919Sxy150489 
8086735Scc210113 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
8094919Sxy150489 		if (ret_val)
8104919Sxy150489 			goto out;
8114919Sxy150489 
8126735Scc210113 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
8134919Sxy150489 		if (ret_val)
8144919Sxy150489 			goto out;
8154919Sxy150489 
8164919Sxy150489 		if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0)
8174919Sxy150489 			break;
8184919Sxy150489 		msec_delay_irq(100);
8194919Sxy150489 	}
8204919Sxy150489 
8214919Sxy150489 	/* Recommended delay time after link has been lost */
8224919Sxy150489 	msec_delay_irq(1000);
8234919Sxy150489 
8244919Sxy150489 	/* Now we will re-enable the transmitter on the PHY */
8254919Sxy150489 
8266735Scc210113 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
8274919Sxy150489 	if (ret_val)
8284919Sxy150489 		goto out;
8294919Sxy150489 	msec_delay_irq(50);
8306735Scc210113 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
8314919Sxy150489 	if (ret_val)
8324919Sxy150489 		goto out;
8334919Sxy150489 	msec_delay_irq(50);
8346735Scc210113 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
8354919Sxy150489 	if (ret_val)
8364919Sxy150489 		goto out;
8374919Sxy150489 	msec_delay_irq(50);
8386735Scc210113 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
8394919Sxy150489 	if (ret_val)
8404919Sxy150489 		goto out;
8414919Sxy150489 
8426735Scc210113 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
8434919Sxy150489 	if (ret_val)
8444919Sxy150489 		goto out;
8454919Sxy150489 
8464919Sxy150489 	/*
8474919Sxy150489 	 * Read the MII Status Register and wait for Link Status bit
8484919Sxy150489 	 * to be set.
8494919Sxy150489 	 */
8504919Sxy150489 	ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_TIME, 100000, &link);
8514919Sxy150489 	if (ret_val)
8524919Sxy150489 		goto out;
8534919Sxy150489 
8544919Sxy150489 out:
8554919Sxy150489 	return (ret_val);
8564919Sxy150489 }
8574919Sxy150489 
8584919Sxy150489 /*
8594919Sxy150489  * e1000_phy_hw_reset_82543 - PHY hardware reset
8604919Sxy150489  * @hw: pointer to the HW structure
8614919Sxy150489  *
8624919Sxy150489  * Sets the PHY_RESET_DIR bit in the extended device control register
8634919Sxy150489  * to put the PHY into a reset and waits for completion.  Once the reset
8644919Sxy150489  * has been accomplished, clear the PHY_RESET_DIR bit to take the PHY out
8658479SChenlu.Chen@Sun.COM  * of reset.
8664919Sxy150489  */
8674919Sxy150489 static s32
e1000_phy_hw_reset_82543(struct e1000_hw * hw)8684919Sxy150489 e1000_phy_hw_reset_82543(struct e1000_hw *hw)
8694919Sxy150489 {
8704919Sxy150489 	u32 ctrl_ext;
8714919Sxy150489 	s32 ret_val;
8724919Sxy150489 
8734919Sxy150489 	DEBUGFUNC("e1000_phy_hw_reset_82543");
8744919Sxy150489 
8754919Sxy150489 	/*
8764919Sxy150489 	 * Read the Extended Device Control Register, assert the PHY_RESET_DIR
8774919Sxy150489 	 * bit to put the PHY into reset...
8784919Sxy150489 	 */
8794919Sxy150489 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
8804919Sxy150489 	ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
8814919Sxy150489 	ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
8824919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
8834919Sxy150489 	E1000_WRITE_FLUSH(hw);
8844919Sxy150489 
8854919Sxy150489 	msec_delay(10);
8864919Sxy150489 
8874919Sxy150489 	/* ...then take it out of reset. */
8884919Sxy150489 	ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
8894919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
8904919Sxy150489 	E1000_WRITE_FLUSH(hw);
8914919Sxy150489 
8924919Sxy150489 	usec_delay(150);
8934919Sxy150489 
8946735Scc210113 	if (!(hw->phy.ops.get_cfg_done))
8956735Scc210113 		return (E1000_SUCCESS);
8966735Scc210113 
8976735Scc210113 	ret_val = hw->phy.ops.get_cfg_done(hw);
8984919Sxy150489 
8994919Sxy150489 	return (ret_val);
9004919Sxy150489 }
9014919Sxy150489 
9024919Sxy150489 /*
9034919Sxy150489  * e1000_reset_hw_82543 - Reset hardware
9044919Sxy150489  * @hw: pointer to the HW structure
9054919Sxy150489  *
9068479SChenlu.Chen@Sun.COM  * This resets the hardware into a known state.
9074919Sxy150489  */
9084919Sxy150489 static s32
e1000_reset_hw_82543(struct e1000_hw * hw)9094919Sxy150489 e1000_reset_hw_82543(struct e1000_hw *hw)
9104919Sxy150489 {
9117426SChenliang.Xu@Sun.COM 	u32 ctrl;
9124919Sxy150489 	s32 ret_val = E1000_SUCCESS;
9134919Sxy150489 
9144919Sxy150489 	DEBUGFUNC("e1000_reset_hw_82543");
9154919Sxy150489 
9164919Sxy150489 	DEBUGOUT("Masking off all interrupts\n");
9174919Sxy150489 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
9184919Sxy150489 
9194919Sxy150489 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
9204919Sxy150489 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
9214919Sxy150489 	E1000_WRITE_FLUSH(hw);
9224919Sxy150489 
9237607STed.You@Sun.COM 	e1000_set_tbi_sbp_82543(hw, false);
9244919Sxy150489 
9254919Sxy150489 	/*
9264919Sxy150489 	 * Delay to allow any outstanding PCI transactions to complete before
9274919Sxy150489 	 * resetting the device
9284919Sxy150489 	 */
9294919Sxy150489 	msec_delay(10);
9304919Sxy150489 
9314919Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
9324919Sxy150489 
9334919Sxy150489 	DEBUGOUT("Issuing a global reset to 82543/82544 MAC\n");
9344919Sxy150489 	if (hw->mac.type == e1000_82543) {
9354919Sxy150489 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
9364919Sxy150489 	} else {
9374919Sxy150489 		/*
9384919Sxy150489 		 * The 82544 can't ACK the 64-bit write when issuing the
9394919Sxy150489 		 * reset, so use IO-mapping as a workaround.
9404919Sxy150489 		 */
9414919Sxy150489 		E1000_WRITE_REG_IO(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
9424919Sxy150489 	}
9434919Sxy150489 
9444919Sxy150489 	/*
9454919Sxy150489 	 * After MAC reset, force reload of NVM to restore power-on
9464919Sxy150489 	 * settings to device.
9474919Sxy150489 	 */
9486735Scc210113 	hw->nvm.ops.reload(hw);
9494919Sxy150489 	msec_delay(2);
9504919Sxy150489 
9514919Sxy150489 	/* Masking off and clearing any pending interrupts */
9524919Sxy150489 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
9537426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_ICR);
9544919Sxy150489 
9554919Sxy150489 	return (ret_val);
9564919Sxy150489 }
9574919Sxy150489 
9584919Sxy150489 /*
9594919Sxy150489  * e1000_init_hw_82543 - Initialize hardware
9604919Sxy150489  * @hw: pointer to the HW structure
9614919Sxy150489  *
9624919Sxy150489  * This inits the hardware readying it for operation.
9634919Sxy150489  */
9644919Sxy150489 static s32
e1000_init_hw_82543(struct e1000_hw * hw)9654919Sxy150489 e1000_init_hw_82543(struct e1000_hw *hw)
9664919Sxy150489 {
9674919Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
9688479SChenlu.Chen@Sun.COM 	struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
9694919Sxy150489 	u32 ctrl;
9704919Sxy150489 	s32 ret_val;
9714919Sxy150489 	u16 i;
9724919Sxy150489 
9734919Sxy150489 	DEBUGFUNC("e1000_init_hw_82543");
9744919Sxy150489 
9754919Sxy150489 	/* Disabling VLAN filtering */
9764919Sxy150489 	E1000_WRITE_REG(hw, E1000_VET, 0);
9776735Scc210113 	mac->ops.clear_vfta(hw);
9784919Sxy150489 
9794919Sxy150489 	/* Setup the receive address. */
9804919Sxy150489 	e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
9814919Sxy150489 
9824919Sxy150489 	/* Zero out the Multicast HASH table */
9834919Sxy150489 	DEBUGOUT("Zeroing the MTA\n");
9844919Sxy150489 	for (i = 0; i < mac->mta_reg_count; i++) {
9854919Sxy150489 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
9864919Sxy150489 		E1000_WRITE_FLUSH(hw);
9874919Sxy150489 	}
9884919Sxy150489 
9894919Sxy150489 	/*
9904919Sxy150489 	 * Set the PCI priority bit correctly in the CTRL register.  This
9914919Sxy150489 	 * determines if the adapter gives priority to receives, or if it
9924919Sxy150489 	 * gives equal priority to transmits and receives.
9934919Sxy150489 	 */
9944919Sxy150489 	if (hw->mac.type == e1000_82543 && dev_spec->dma_fairness) {
9954919Sxy150489 		ctrl = E1000_READ_REG(hw, E1000_CTRL);
9964919Sxy150489 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PRIOR);
9974919Sxy150489 	}
9984919Sxy150489 
9994919Sxy150489 	e1000_pcix_mmrbc_workaround_generic(hw);
10004919Sxy150489 
10014919Sxy150489 	/* Setup link and flow control */
10026735Scc210113 	ret_val = mac->ops.setup_link(hw);
10034919Sxy150489 
10044919Sxy150489 	/*
10054919Sxy150489 	 * Clear all of the statistics registers (clear on read).  It is
10064919Sxy150489 	 * important that we do this after we have tried to establish link
10074919Sxy150489 	 * because the symbol error count will increment wildly if there
10084919Sxy150489 	 * is no link.
10094919Sxy150489 	 */
10104919Sxy150489 	e1000_clear_hw_cntrs_82543(hw);
10114919Sxy150489 
10124919Sxy150489 	return (ret_val);
10134919Sxy150489 }
10144919Sxy150489 
10154919Sxy150489 /*
10164919Sxy150489  * e1000_setup_link_82543 - Setup flow control and link settings
10174919Sxy150489  * @hw: pointer to the HW structure
10184919Sxy150489  *
10194919Sxy150489  * Read the EEPROM to determine the initial polarity value and write the
10204919Sxy150489  * extended device control register with the information before calling
10214919Sxy150489  * the generic setup link function, which does the following:
10224919Sxy150489  * Determines which flow control settings to use, then configures flow
10234919Sxy150489  * control.  Calls the appropriate media-specific link configuration
10244919Sxy150489  * function.  Assuming the adapter has a valid link partner, a valid link
10254919Sxy150489  * should be established.  Assumes the hardware has previously been reset
10264919Sxy150489  * and the transmitter and receiver are not enabled.
10274919Sxy150489  */
10284919Sxy150489 static s32
e1000_setup_link_82543(struct e1000_hw * hw)10294919Sxy150489 e1000_setup_link_82543(struct e1000_hw *hw)
10304919Sxy150489 {
10314919Sxy150489 	u32 ctrl_ext;
10324919Sxy150489 	s32 ret_val;
10334919Sxy150489 	u16 data;
10344919Sxy150489 
10354919Sxy150489 	DEBUGFUNC("e1000_setup_link_82543");
10364919Sxy150489 
10374919Sxy150489 	/*
10384919Sxy150489 	 * Take the 4 bits from NVM word 0xF that determine the initial
10394919Sxy150489 	 * polarity value for the SW controlled pins, and setup the
10404919Sxy150489 	 * Extended Device Control reg with that info.
10414919Sxy150489 	 * This is needed because one of the SW controlled pins is used for
10424919Sxy150489 	 * signal detection.  So this should be done before phy setup.
10434919Sxy150489 	 */
10444919Sxy150489 	if (hw->mac.type == e1000_82543) {
10456735Scc210113 		ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &data);
10464919Sxy150489 		if (ret_val) {
10474919Sxy150489 			DEBUGOUT("NVM Read Error\n");
10484919Sxy150489 			ret_val = -E1000_ERR_NVM;
10494919Sxy150489 			goto out;
10504919Sxy150489 		}
10514919Sxy150489 		ctrl_ext = ((data & NVM_WORD0F_SWPDIO_EXT_MASK) <<
10524919Sxy150489 		    NVM_SWDPIO_EXT_SHIFT);
10534919Sxy150489 		E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
10544919Sxy150489 	}
10554919Sxy150489 
10564919Sxy150489 	ret_val = e1000_setup_link_generic(hw);
10574919Sxy150489 
10584919Sxy150489 out:
10594919Sxy150489 	return (ret_val);
10604919Sxy150489 }
10614919Sxy150489 
10624919Sxy150489 /*
10634919Sxy150489  * e1000_setup_copper_link_82543 - Configure copper link settings
10644919Sxy150489  * @hw: pointer to the HW structure
10654919Sxy150489  *
10664919Sxy150489  * Configures the link for auto-neg or forced speed and duplex.  Then we check
10674919Sxy150489  * for link, once link is established calls to configure collision distance
10684919Sxy150489  * and flow control are called.
10694919Sxy150489  */
10704919Sxy150489 static s32
e1000_setup_copper_link_82543(struct e1000_hw * hw)10714919Sxy150489 e1000_setup_copper_link_82543(struct e1000_hw *hw)
10724919Sxy150489 {
10734919Sxy150489 	u32 ctrl;
10744919Sxy150489 	s32 ret_val;
10756735Scc210113 	bool link;
10764919Sxy150489 
10774919Sxy150489 	DEBUGFUNC("e1000_setup_copper_link_82543");
10784919Sxy150489 
10794919Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL) | E1000_CTRL_SLU;
10804919Sxy150489 	/*
10814919Sxy150489 	 * With 82543, we need to force speed and duplex on the MAC
10824919Sxy150489 	 * equal to what the PHY speed and duplex configuration is.
10834919Sxy150489 	 * In addition, we need to perform a hardware reset on the
10844919Sxy150489 	 * PHY to take it out of reset.
10854919Sxy150489 	 */
10864919Sxy150489 	if (hw->mac.type == e1000_82543) {
10874919Sxy150489 		ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
10884919Sxy150489 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
10896735Scc210113 		ret_val = hw->phy.ops.reset(hw);
10904919Sxy150489 		if (ret_val)
10914919Sxy150489 			goto out;
10927607STed.You@Sun.COM 		hw->phy.reset_disable = false;
10934919Sxy150489 	} else {
10944919Sxy150489 		ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
10954919Sxy150489 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
10964919Sxy150489 	}
10974919Sxy150489 
10984919Sxy150489 	/* Set MDI/MDI-X, Polarity Reversal, and downshift settings */
10994919Sxy150489 	ret_val = e1000_copper_link_setup_m88(hw);
11004919Sxy150489 	if (ret_val)
11014919Sxy150489 		goto out;
11024919Sxy150489 
11034919Sxy150489 	if (hw->mac.autoneg) {
11044919Sxy150489 		/*
11054919Sxy150489 		 * Setup autoneg and flow control advertisement and perform
11064919Sxy150489 		 * autonegotiation.
11074919Sxy150489 		 */
11084919Sxy150489 		ret_val = e1000_copper_link_autoneg(hw);
11094919Sxy150489 		if (ret_val)
11104919Sxy150489 			goto out;
11114919Sxy150489 	} else {
11124919Sxy150489 		/*
11134919Sxy150489 		 * PHY will be set to 10H, 10F, 100H or 100F
11144919Sxy150489 		 * depending on user settings.
11154919Sxy150489 		 */
11164919Sxy150489 		DEBUGOUT("Forcing Speed and Duplex\n");
11174919Sxy150489 		ret_val = e1000_phy_force_speed_duplex_82543(hw);
11184919Sxy150489 		if (ret_val) {
11194919Sxy150489 			DEBUGOUT("Error Forcing Speed and Duplex\n");
11204919Sxy150489 			goto out;
11214919Sxy150489 		}
11224919Sxy150489 	}
11234919Sxy150489 
11244919Sxy150489 	/*
11254919Sxy150489 	 * Check link status. Wait up to 100 microseconds for link to become
11264919Sxy150489 	 * valid.
11274919Sxy150489 	 */
11284919Sxy150489 	ret_val = e1000_phy_has_link_generic(hw,
11294919Sxy150489 	    COPPER_LINK_UP_LIMIT,
11304919Sxy150489 	    10,
11314919Sxy150489 	    &link);
11324919Sxy150489 	if (ret_val)
11334919Sxy150489 		goto out;
11344919Sxy150489 
11354919Sxy150489 
11364919Sxy150489 	if (link) {
11374919Sxy150489 		DEBUGOUT("Valid link established!!!\n");
11384919Sxy150489 		/* Config the MAC and PHY after link is up */
11394919Sxy150489 		if (hw->mac.type == e1000_82544) {
11404919Sxy150489 			e1000_config_collision_dist_generic(hw);
11414919Sxy150489 		} else {
11424919Sxy150489 			ret_val = e1000_config_mac_to_phy_82543(hw);
11434919Sxy150489 			if (ret_val)
11444919Sxy150489 				goto out;
11454919Sxy150489 		}
11464919Sxy150489 		ret_val = e1000_config_fc_after_link_up_generic(hw);
11474919Sxy150489 	} else {
1148*11143SGuoqing.Zhu@Sun.COM 		/* EMPTY */
11494919Sxy150489 		DEBUGOUT("Unable to establish link!!!\n");
11504919Sxy150489 	}
11514919Sxy150489 
11524919Sxy150489 out:
11534919Sxy150489 	return (ret_val);
11544919Sxy150489 }
11554919Sxy150489 
11564919Sxy150489 /*
11574919Sxy150489  * e1000_setup_fiber_link_82543 - Setup link for fiber
11584919Sxy150489  * @hw: pointer to the HW structure
11594919Sxy150489  *
11604919Sxy150489  * Configures collision distance and flow control for fiber links.  Upon
11614919Sxy150489  * successful setup, poll for link.
11624919Sxy150489  */
11634919Sxy150489 static s32
e1000_setup_fiber_link_82543(struct e1000_hw * hw)11644919Sxy150489 e1000_setup_fiber_link_82543(struct e1000_hw *hw)
11654919Sxy150489 {
11664919Sxy150489 	u32 ctrl;
11674919Sxy150489 	s32 ret_val;
11684919Sxy150489 
11694919Sxy150489 	DEBUGFUNC("e1000_setup_fiber_link_82543");
11704919Sxy150489 
11714919Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
11724919Sxy150489 
11734919Sxy150489 	/* Take the link out of reset */
11744919Sxy150489 	ctrl &= ~E1000_CTRL_LRST;
11754919Sxy150489 
11764919Sxy150489 	e1000_config_collision_dist_generic(hw);
11774919Sxy150489 
11784919Sxy150489 	ret_val = e1000_commit_fc_settings_generic(hw);
11794919Sxy150489 	if (ret_val)
11804919Sxy150489 		goto out;
11814919Sxy150489 
11824919Sxy150489 	DEBUGOUT("Auto-negotiation enabled\n");
11834919Sxy150489 
11844919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
11854919Sxy150489 	E1000_WRITE_FLUSH(hw);
11864919Sxy150489 	msec_delay(1);
11874919Sxy150489 
11884919Sxy150489 	/*
11896735Scc210113 	 * For these adapters, the SW definable pin 1 is cleared when the
11904919Sxy150489 	 * optics detect a signal.  If we have a signal, then poll for a
11914919Sxy150489 	 * "Link-Up" indication.
11924919Sxy150489 	 */
11934919Sxy150489 	if (!(E1000_READ_REG(hw, E1000_CTRL) & E1000_CTRL_SWDPIN1)) {
11944919Sxy150489 		ret_val = e1000_poll_fiber_serdes_link_generic(hw);
11954919Sxy150489 	} else {
1196*11143SGuoqing.Zhu@Sun.COM 		/* EMPTY */
11974919Sxy150489 		DEBUGOUT("No signal detected\n");
11984919Sxy150489 	}
11994919Sxy150489 
12004919Sxy150489 out:
12014919Sxy150489 	return (ret_val);
12024919Sxy150489 }
12034919Sxy150489 
12044919Sxy150489 /*
12054919Sxy150489  * e1000_check_for_copper_link_82543 - Check for link (Copper)
12064919Sxy150489  * @hw: pointer to the HW structure
12074919Sxy150489  *
12084919Sxy150489  * Checks the phy for link, if link exists, do the following:
12094919Sxy150489  *  - check for downshift
12104919Sxy150489  *  - do polarity workaround (if necessary)
12114919Sxy150489  *  - configure collision distance
12124919Sxy150489  *  - configure flow control after link up
12134919Sxy150489  *  - configure tbi compatibility
12144919Sxy150489  */
12154919Sxy150489 static s32
e1000_check_for_copper_link_82543(struct e1000_hw * hw)12164919Sxy150489 e1000_check_for_copper_link_82543(struct e1000_hw *hw)
12174919Sxy150489 {
12184919Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
12194919Sxy150489 	u32 icr, rctl;
12204919Sxy150489 	s32 ret_val;
12214919Sxy150489 	u16 speed, duplex;
12226735Scc210113 	bool link;
12234919Sxy150489 
12244919Sxy150489 	DEBUGFUNC("e1000_check_for_copper_link_82543");
12254919Sxy150489 
12264919Sxy150489 	if (!mac->get_link_status) {
12274919Sxy150489 		ret_val = E1000_SUCCESS;
12284919Sxy150489 		goto out;
12294919Sxy150489 	}
12304919Sxy150489 
12314919Sxy150489 	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
12324919Sxy150489 	if (ret_val)
12334919Sxy150489 		goto out;
12344919Sxy150489 
12354919Sxy150489 	if (!link)
12364919Sxy150489 		goto out;	/* No link detected */
12374919Sxy150489 
12387607STed.You@Sun.COM 	mac->get_link_status = false;
12394919Sxy150489 
12407426SChenliang.Xu@Sun.COM 	(void) e1000_check_downshift_generic(hw);
12414919Sxy150489 
12424919Sxy150489 	/*
12434919Sxy150489 	 * If we are forcing speed/duplex, then we can return since
12444919Sxy150489 	 * we have already determined whether we have link or not.
12454919Sxy150489 	 */
12464919Sxy150489 	if (!mac->autoneg) {
12474919Sxy150489 		/*
12484919Sxy150489 		 * If speed and duplex are forced to 10H or 10F, then we will
12494919Sxy150489 		 * implement the polarity reversal workaround.  We disable
12504919Sxy150489 		 * interrupts first, and upon returning, place the devices
12514919Sxy150489 		 * interrupt state to its previous value except for the link
12524919Sxy150489 		 * status change interrupt which will happened due to the
12534919Sxy150489 		 * execution of this workaround.
12544919Sxy150489 		 */
12554919Sxy150489 		if (mac->forced_speed_duplex & E1000_ALL_10_SPEED) {
12564919Sxy150489 			E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF);
12574919Sxy150489 			ret_val = e1000_polarity_reversal_workaround_82543(hw);
12584919Sxy150489 			icr = E1000_READ_REG(hw, E1000_ICR);
12594919Sxy150489 			E1000_WRITE_REG(hw, E1000_ICS, (icr & ~E1000_ICS_LSC));
12604919Sxy150489 			E1000_WRITE_REG(hw, E1000_IMS, IMS_ENABLE_MASK);
12614919Sxy150489 		}
12624919Sxy150489 
12634919Sxy150489 		ret_val = -E1000_ERR_CONFIG;
12644919Sxy150489 		goto out;
12654919Sxy150489 	}
12664919Sxy150489 
12674919Sxy150489 	/*
12684919Sxy150489 	 * We have a M88E1000 PHY and Auto-Neg is enabled.  If we
12694919Sxy150489 	 * have Si on board that is 82544 or newer, Auto
12704919Sxy150489 	 * Speed Detection takes care of MAC speed/duplex
12714919Sxy150489 	 * configuration.  So we only need to configure Collision
12724919Sxy150489 	 * Distance in the MAC.  Otherwise, we need to force
12734919Sxy150489 	 * speed/duplex on the MAC to the current PHY speed/duplex
12744919Sxy150489 	 * settings.
12754919Sxy150489 	 */
12764919Sxy150489 	if (mac->type == e1000_82544)
12774919Sxy150489 		e1000_config_collision_dist_generic(hw);
12784919Sxy150489 	else {
12794919Sxy150489 		ret_val = e1000_config_mac_to_phy_82543(hw);
12804919Sxy150489 		if (ret_val) {
12814919Sxy150489 			DEBUGOUT("Error configuring MAC to PHY settings\n");
12824919Sxy150489 			goto out;
12834919Sxy150489 		}
12844919Sxy150489 	}
12854919Sxy150489 
12864919Sxy150489 	/*
12874919Sxy150489 	 * Configure Flow Control now that Auto-Neg has completed.
12884919Sxy150489 	 * First, we need to restore the desired flow control
12894919Sxy150489 	 * settings because we may have had to re-autoneg with a
12904919Sxy150489 	 * different link partner.
12914919Sxy150489 	 */
12924919Sxy150489 	ret_val = e1000_config_fc_after_link_up_generic(hw);
12934919Sxy150489 	if (ret_val) {
1294*11143SGuoqing.Zhu@Sun.COM 		/* EMPTY */
12954919Sxy150489 		DEBUGOUT("Error configuring flow control\n");
12964919Sxy150489 	}
12974919Sxy150489 
12984919Sxy150489 	/*
12994919Sxy150489 	 * At this point we know that we are on copper and we have
13004919Sxy150489 	 * auto-negotiated link.  These are conditions for checking the link
13014919Sxy150489 	 * partner capability register.  We use the link speed to determine if
13024919Sxy150489 	 * TBI compatibility needs to be turned on or off.  If the link is not
13034919Sxy150489 	 * at gigabit speed, then TBI compatibility is not needed.  If we are
13044919Sxy150489 	 * at gigabit speed, we turn on TBI compatibility.
13054919Sxy150489 	 */
13064919Sxy150489 	if (e1000_tbi_compatibility_enabled_82543(hw)) {
13076735Scc210113 		ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
13084919Sxy150489 		if (ret_val) {
13094919Sxy150489 			DEBUGOUT("Error getting link speed and duplex\n");
13104919Sxy150489 			return (ret_val);
13114919Sxy150489 		}
13124919Sxy150489 		if (speed != SPEED_1000) {
13134919Sxy150489 			/*
13144919Sxy150489 			 * If link speed is not set to gigabit speed,
13154919Sxy150489 			 * we do not need to enable TBI compatibility.
13164919Sxy150489 			 */
13174919Sxy150489 			if (e1000_tbi_sbp_enabled_82543(hw)) {
13184919Sxy150489 				/*
13194919Sxy150489 				 * If we previously were in the mode,
13204919Sxy150489 				 * turn it off.
13214919Sxy150489 				 */
13227607STed.You@Sun.COM 				e1000_set_tbi_sbp_82543(hw, false);
13234919Sxy150489 				rctl = E1000_READ_REG(hw, E1000_RCTL);
13244919Sxy150489 				rctl &= ~E1000_RCTL_SBP;
13254919Sxy150489 				E1000_WRITE_REG(hw, E1000_RCTL, rctl);
13264919Sxy150489 			}
13274919Sxy150489 		} else {
13284919Sxy150489 			/*
13294919Sxy150489 			 * If TBI compatibility is was previously off,
13304919Sxy150489 			 * turn it on. For compatibility with a TBI link
13314919Sxy150489 			 * partner, we will store bad packets. Some
13324919Sxy150489 			 * frames have an additional byte on the end and
13334919Sxy150489 			 * will look like CRC errors to to the hardware.
13344919Sxy150489 			 */
13354919Sxy150489 			if (!e1000_tbi_sbp_enabled_82543(hw)) {
13367607STed.You@Sun.COM 				e1000_set_tbi_sbp_82543(hw, true);
13374919Sxy150489 				rctl = E1000_READ_REG(hw, E1000_RCTL);
13384919Sxy150489 				rctl |= E1000_RCTL_SBP;
13394919Sxy150489 				E1000_WRITE_REG(hw, E1000_RCTL, rctl);
13404919Sxy150489 			}
13414919Sxy150489 		}
13424919Sxy150489 	}
13434919Sxy150489 out:
13444919Sxy150489 	return (ret_val);
13454919Sxy150489 }
13464919Sxy150489 
13474919Sxy150489 /*
13484919Sxy150489  * e1000_check_for_fiber_link_82543 - Check for link (Fiber)
13494919Sxy150489  * @hw: pointer to the HW structure
13504919Sxy150489  *
13514919Sxy150489  * Checks for link up on the hardware.  If link is not up and we have
13524919Sxy150489  * a signal, then we need to force link up.
13534919Sxy150489  */
13544919Sxy150489 static s32
e1000_check_for_fiber_link_82543(struct e1000_hw * hw)13554919Sxy150489 e1000_check_for_fiber_link_82543(struct e1000_hw *hw)
13564919Sxy150489 {
13574919Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
13584919Sxy150489 	u32 rxcw, ctrl, status;
13594919Sxy150489 	s32 ret_val = E1000_SUCCESS;
13604919Sxy150489 
13614919Sxy150489 	DEBUGFUNC("e1000_check_for_fiber_link_82543");
13624919Sxy150489 
13634919Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
13644919Sxy150489 	status = E1000_READ_REG(hw, E1000_STATUS);
13654919Sxy150489 	rxcw = E1000_READ_REG(hw, E1000_RXCW);
13664919Sxy150489 
13674919Sxy150489 	/*
13684919Sxy150489 	 * If we don't have link (auto-negotiation failed or link partner
13694919Sxy150489 	 * cannot auto-negotiate), the cable is plugged in (we have signal),
13704919Sxy150489 	 * and our link partner is not trying to auto-negotiate with us (we
13714919Sxy150489 	 * are receiving idles or data), we need to force link up. We also
13724919Sxy150489 	 * need to give auto-negotiation time to complete, in case the cable
13734919Sxy150489 	 * was just plugged in. The autoneg_failed flag does this.
13744919Sxy150489 	 */
13754919Sxy150489 	/* (ctrl & E1000_CTRL_SWDPIN1) == 0 == have signal */
13764919Sxy150489 	if ((!(ctrl & E1000_CTRL_SWDPIN1)) &&
13774919Sxy150489 	    (!(status & E1000_STATUS_LU)) &&
13784919Sxy150489 	    (!(rxcw & E1000_RXCW_C))) {
13794919Sxy150489 		if (mac->autoneg_failed == 0) {
13804919Sxy150489 			mac->autoneg_failed = 1;
13814919Sxy150489 			ret_val = 0;
13824919Sxy150489 			goto out;
13834919Sxy150489 		}
13844919Sxy150489 		DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");
13854919Sxy150489 
13864919Sxy150489 		/* Disable auto-negotiation in the TXCW register */
13874919Sxy150489 		E1000_WRITE_REG(hw, E1000_TXCW, (mac->txcw & ~E1000_TXCW_ANE));
13884919Sxy150489 
13894919Sxy150489 		/* Force link-up and also force full-duplex. */
13904919Sxy150489 		ctrl = E1000_READ_REG(hw, E1000_CTRL);
13914919Sxy150489 		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
13924919Sxy150489 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
13934919Sxy150489 
13944919Sxy150489 		/* Configure Flow Control after forcing link up. */
13954919Sxy150489 		ret_val = e1000_config_fc_after_link_up_generic(hw);
13964919Sxy150489 		if (ret_val) {
13974919Sxy150489 			DEBUGOUT("Error configuring flow control\n");
13984919Sxy150489 			goto out;
13994919Sxy150489 		}
14004919Sxy150489 	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
14014919Sxy150489 		/*
14024919Sxy150489 		 * If we are forcing link and we are receiving /C/ ordered
14034919Sxy150489 		 * sets, re-enable auto-negotiation in the TXCW register
14044919Sxy150489 		 * and disable forced link in the Device Control register
14054919Sxy150489 		 * in an attempt to auto-negotiate with our link partner.
14064919Sxy150489 		 */
14074919Sxy150489 		DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
14084919Sxy150489 		E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
14094919Sxy150489 		E1000_WRITE_REG(hw, E1000_CTRL, (ctrl & ~E1000_CTRL_SLU));
14104919Sxy150489 
14117607STed.You@Sun.COM 		mac->serdes_has_link = true;
14124919Sxy150489 	}
14134919Sxy150489 
14144919Sxy150489 out:
14154919Sxy150489 	return (ret_val);
14164919Sxy150489 }
14174919Sxy150489 
14184919Sxy150489 /*
14194919Sxy150489  * e1000_config_mac_to_phy_82543 - Configure MAC to PHY settings
14204919Sxy150489  * @hw: pointer to the HW structure
14214919Sxy150489  *
14224919Sxy150489  * For the 82543 silicon, we need to set the MAC to match the settings
14234919Sxy150489  * of the PHY, even if the PHY is auto-negotiating.
14244919Sxy150489  */
14254919Sxy150489 static s32
e1000_config_mac_to_phy_82543(struct e1000_hw * hw)14264919Sxy150489 e1000_config_mac_to_phy_82543(struct e1000_hw *hw)
14274919Sxy150489 {
14284919Sxy150489 	u32 ctrl;
14296735Scc210113 	s32 ret_val = E1000_SUCCESS;
14304919Sxy150489 	u16 phy_data;
14314919Sxy150489 
14324919Sxy150489 	DEBUGFUNC("e1000_config_mac_to_phy_82543");
14334919Sxy150489 
14346735Scc210113 	if (!(hw->phy.ops.read_reg))
14356735Scc210113 		goto out;
14366735Scc210113 
14374919Sxy150489 	/* Set the bits to force speed and duplex */
14384919Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
14394919Sxy150489 	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
14404919Sxy150489 	ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
14414919Sxy150489 
14424919Sxy150489 	/*
14434919Sxy150489 	 * Set up duplex in the Device Control and Transmit Control
14444919Sxy150489 	 * registers depending on negotiated values.
14454919Sxy150489 	 */
14466735Scc210113 	ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
14474919Sxy150489 	if (ret_val)
14484919Sxy150489 		goto out;
14494919Sxy150489 
14504919Sxy150489 	ctrl &= ~E1000_CTRL_FD;
14514919Sxy150489 	if (phy_data & M88E1000_PSSR_DPLX)
14524919Sxy150489 		ctrl |= E1000_CTRL_FD;
14534919Sxy150489 
14544919Sxy150489 	e1000_config_collision_dist_generic(hw);
14554919Sxy150489 
14564919Sxy150489 	/*
14574919Sxy150489 	 * Set up speed in the Device Control register depending on
14584919Sxy150489 	 * negotiated values.
14594919Sxy150489 	 */
14604919Sxy150489 	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
14614919Sxy150489 		ctrl |= E1000_CTRL_SPD_1000;
14624919Sxy150489 	else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
14634919Sxy150489 		ctrl |= E1000_CTRL_SPD_100;
14644919Sxy150489 
14654919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
14664919Sxy150489 
14674919Sxy150489 out:
14684919Sxy150489 	return (ret_val);
14694919Sxy150489 }
14704919Sxy150489 
14714919Sxy150489 /*
14724919Sxy150489  * e1000_write_vfta_82543 - Write value to VLAN filter table
14734919Sxy150489  * @hw: pointer to the HW structure
14744919Sxy150489  * @offset: the 32-bit offset in which to write the value to.
14754919Sxy150489  * @value: the 32-bit value to write at location offset.
14764919Sxy150489  *
14774919Sxy150489  * This writes a 32-bit value to a 32-bit offset in the VLAN filter
14784919Sxy150489  * table.
14794919Sxy150489  */
14804919Sxy150489 static void
e1000_write_vfta_82543(struct e1000_hw * hw,u32 offset,u32 value)14814919Sxy150489 e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value)
14824919Sxy150489 {
14834919Sxy150489 	u32 temp;
14844919Sxy150489 
14854919Sxy150489 	DEBUGFUNC("e1000_write_vfta_82543");
14864919Sxy150489 
14874919Sxy150489 	if ((hw->mac.type == e1000_82544) && (offset & 1)) {
14884919Sxy150489 		temp = E1000_READ_REG_ARRAY(hw, E1000_VFTA, offset - 1);
14894919Sxy150489 		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
14904919Sxy150489 		E1000_WRITE_FLUSH(hw);
14914919Sxy150489 		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset - 1, temp);
14924919Sxy150489 		E1000_WRITE_FLUSH(hw);
14934919Sxy150489 	} else {
14944919Sxy150489 		e1000_write_vfta_generic(hw, offset, value);
14954919Sxy150489 	}
14964919Sxy150489 }
14974919Sxy150489 
14984919Sxy150489 /*
14994919Sxy150489  * e1000_mta_set_82543 - Set multicast filter table address
15004919Sxy150489  * @hw: pointer to the HW structure
15014919Sxy150489  * @hash_value: determines the MTA register and bit to set
15024919Sxy150489  *
15034919Sxy150489  * The multicast table address is a register array of 32-bit registers.
15044919Sxy150489  * The hash_value is used to determine what register the bit is in, the
15054919Sxy150489  * current value is read, the new bit is OR'd in and the new value is
15064919Sxy150489  * written back into the register.
15074919Sxy150489  */
15084919Sxy150489 static void
e1000_mta_set_82543(struct e1000_hw * hw,u32 hash_value)15094919Sxy150489 e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value)
15104919Sxy150489 {
15114919Sxy150489 	u32 hash_bit, hash_reg, mta, temp;
15124919Sxy150489 
15134919Sxy150489 	DEBUGFUNC("e1000_mta_set_82543");
15144919Sxy150489 
15154919Sxy150489 	hash_reg = (hash_value >> 5);
15164919Sxy150489 
15174919Sxy150489 	/*
15184919Sxy150489 	 * If we are on an 82544 and we are trying to write an odd offset
15194919Sxy150489 	 * in the MTA, save off the previous entry before writing and
15204919Sxy150489 	 * restore the old value after writing.
15214919Sxy150489 	 */
15224919Sxy150489 	if ((hw->mac.type == e1000_82544) && (hash_reg & 1)) {
15234919Sxy150489 		hash_reg &= (hw->mac.mta_reg_count - 1);
15244919Sxy150489 		hash_bit = hash_value & 0x1F;
15254919Sxy150489 		mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg);
15264919Sxy150489 		mta |= (1 << hash_bit);
15274919Sxy150489 		temp = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg - 1);
15284919Sxy150489 
15294919Sxy150489 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta);
15304919Sxy150489 		E1000_WRITE_FLUSH(hw);
15314919Sxy150489 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg - 1, temp);
15324919Sxy150489 		E1000_WRITE_FLUSH(hw);
15334919Sxy150489 	} else {
15344919Sxy150489 		e1000_mta_set_generic(hw, hash_value);
15354919Sxy150489 	}
15364919Sxy150489 }
15374919Sxy150489 
15384919Sxy150489 /*
15394919Sxy150489  * e1000_led_on_82543 - Turn on SW controllable LED
15404919Sxy150489  * @hw: pointer to the HW structure
15414919Sxy150489  *
15428479SChenlu.Chen@Sun.COM  * Turns the SW defined LED on.
15434919Sxy150489  */
15444919Sxy150489 static s32
e1000_led_on_82543(struct e1000_hw * hw)15454919Sxy150489 e1000_led_on_82543(struct e1000_hw *hw)
15464919Sxy150489 {
15474919Sxy150489 	u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
15484919Sxy150489 
15494919Sxy150489 	DEBUGFUNC("e1000_led_on_82543");
15504919Sxy150489 
15514919Sxy150489 	if (hw->mac.type == e1000_82544 &&
15526735Scc210113 	    hw->phy.media_type == e1000_media_type_copper) {
15536735Scc210113 		/* Clear SW-definable Pin 0 to turn on the LED */
15544919Sxy150489 		ctrl &= ~E1000_CTRL_SWDPIN0;
15554919Sxy150489 		ctrl |= E1000_CTRL_SWDPIO0;
15564919Sxy150489 	} else {
15574919Sxy150489 		/* Fiber 82544 and all 82543 use this method */
15584919Sxy150489 		ctrl |= E1000_CTRL_SWDPIN0;
15594919Sxy150489 		ctrl |= E1000_CTRL_SWDPIO0;
15604919Sxy150489 	}
15614919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
15624919Sxy150489 
15634919Sxy150489 	return (E1000_SUCCESS);
15644919Sxy150489 }
15654919Sxy150489 
15664919Sxy150489 /*
15674919Sxy150489  * e1000_led_off_82543 - Turn off SW controllable LED
15684919Sxy150489  * @hw: pointer to the HW structure
15694919Sxy150489  *
15708479SChenlu.Chen@Sun.COM  * Turns the SW defined LED off.
15714919Sxy150489  */
15724919Sxy150489 static s32
e1000_led_off_82543(struct e1000_hw * hw)15734919Sxy150489 e1000_led_off_82543(struct e1000_hw *hw)
15744919Sxy150489 {
15754919Sxy150489 	u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
15764919Sxy150489 
15774919Sxy150489 	DEBUGFUNC("e1000_led_off_82543");
15784919Sxy150489 
15794919Sxy150489 	if (hw->mac.type == e1000_82544 &&
15806735Scc210113 	    hw->phy.media_type == e1000_media_type_copper) {
15816735Scc210113 		/* Set SW-definable Pin 0 to turn off the LED */
15824919Sxy150489 		ctrl |= E1000_CTRL_SWDPIN0;
15834919Sxy150489 		ctrl |= E1000_CTRL_SWDPIO0;
15844919Sxy150489 	} else {
15854919Sxy150489 		ctrl &= ~E1000_CTRL_SWDPIN0;
15864919Sxy150489 		ctrl |= E1000_CTRL_SWDPIO0;
15874919Sxy150489 	}
15884919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
15894919Sxy150489 
15904919Sxy150489 	return (E1000_SUCCESS);
15914919Sxy150489 }
15924919Sxy150489 
15934919Sxy150489 /*
15944919Sxy150489  * e1000_clear_hw_cntrs_82543 - Clear device specific hardware counters
15954919Sxy150489  * @hw: pointer to the HW structure
15964919Sxy150489  *
15974919Sxy150489  * Clears the hardware counters by reading the counter registers.
15984919Sxy150489  */
15994919Sxy150489 static void
e1000_clear_hw_cntrs_82543(struct e1000_hw * hw)16004919Sxy150489 e1000_clear_hw_cntrs_82543(struct e1000_hw *hw)
16014919Sxy150489 {
16024919Sxy150489 	DEBUGFUNC("e1000_clear_hw_cntrs_82543");
16034919Sxy150489 
16044919Sxy150489 	e1000_clear_hw_cntrs_base_generic(hw);
16054919Sxy150489 
16067426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC64);
16077426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC127);
16087426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC255);
16097426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC511);
16107426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC1023);
16117426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC1522);
16127426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC64);
16137426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC127);
16147426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC255);
16157426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC511);
16167426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC1023);
16177426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC1522);
16184919Sxy150489 
16197426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_ALGNERRC);
16207426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_RXERRC);
16217426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_TNCRS);
16227426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_CEXTERR);
16237426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_TSCTC);
16247426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_TSCTFC);
16254919Sxy150489 }
1626