xref: /onnv-gate/usr/src/uts/common/io/e1000g/e1000_82542.c (revision 11020:e0feef27b61a)
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 /*
27*11020SMin.Xu@Sun.COM  * IntelVersion: 1.53 v3-1-10-1_2009-9-18_Release14-6
284919Sxy150489  */
296735Scc210113 
304919Sxy150489 /*
318479SChenlu.Chen@Sun.COM  * 82542 Gigabit Ethernet Controller
324919Sxy150489  */
334919Sxy150489 
344919Sxy150489 #include "e1000_api.h"
354919Sxy150489 
364919Sxy150489 static s32 e1000_init_phy_params_82542(struct e1000_hw *hw);
374919Sxy150489 static s32 e1000_init_nvm_params_82542(struct e1000_hw *hw);
384919Sxy150489 static s32 e1000_init_mac_params_82542(struct e1000_hw *hw);
394919Sxy150489 static s32 e1000_get_bus_info_82542(struct e1000_hw *hw);
404919Sxy150489 static s32 e1000_reset_hw_82542(struct e1000_hw *hw);
414919Sxy150489 static s32 e1000_init_hw_82542(struct e1000_hw *hw);
424919Sxy150489 static s32 e1000_setup_link_82542(struct e1000_hw *hw);
434919Sxy150489 static s32 e1000_led_on_82542(struct e1000_hw *hw);
444919Sxy150489 static s32 e1000_led_off_82542(struct e1000_hw *hw);
457607STed.You@Sun.COM static void e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index);
464919Sxy150489 static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw);
4710680SMin.Xu@Sun.COM static s32  e1000_read_mac_addr_82542(struct e1000_hw *hw);
484919Sxy150489 
494919Sxy150489 /*
504919Sxy150489  * e1000_init_phy_params_82542 - Init PHY func ptrs.
514919Sxy150489  * @hw: pointer to the HW structure
524919Sxy150489  */
534919Sxy150489 static s32
e1000_init_phy_params_82542(struct e1000_hw * hw)544919Sxy150489 e1000_init_phy_params_82542(struct e1000_hw *hw)
554919Sxy150489 {
564919Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
574919Sxy150489 	s32 ret_val = E1000_SUCCESS;
584919Sxy150489 
594919Sxy150489 	DEBUGFUNC("e1000_init_phy_params_82542");
604919Sxy150489 
614919Sxy150489 	phy->type = e1000_phy_none;
624919Sxy150489 
634919Sxy150489 	return (ret_val);
644919Sxy150489 }
654919Sxy150489 
664919Sxy150489 /*
674919Sxy150489  * e1000_init_nvm_params_82542 - Init NVM func ptrs.
684919Sxy150489  * @hw: pointer to the HW structure
694919Sxy150489  */
704919Sxy150489 static s32
e1000_init_nvm_params_82542(struct e1000_hw * hw)714919Sxy150489 e1000_init_nvm_params_82542(struct e1000_hw *hw)
724919Sxy150489 {
734919Sxy150489 	struct e1000_nvm_info *nvm = &hw->nvm;
744919Sxy150489 
754919Sxy150489 	DEBUGFUNC("e1000_init_nvm_params_82542");
764919Sxy150489 
774919Sxy150489 	nvm->address_bits = 6;
784919Sxy150489 	nvm->delay_usec = 50;
794919Sxy150489 	nvm->opcode_bits = 3;
804919Sxy150489 	nvm->type = e1000_nvm_eeprom_microwire;
814919Sxy150489 	nvm->word_size = 64;
824919Sxy150489 
834919Sxy150489 	/* Function Pointers */
846735Scc210113 	nvm->ops.read = e1000_read_nvm_microwire;
856735Scc210113 	nvm->ops.release = e1000_stop_nvm;
866735Scc210113 	nvm->ops.write = e1000_write_nvm_microwire;
876735Scc210113 	nvm->ops.update = e1000_update_nvm_checksum_generic;
886735Scc210113 	nvm->ops.validate = e1000_validate_nvm_checksum_generic;
894919Sxy150489 
904919Sxy150489 	return (E1000_SUCCESS);
914919Sxy150489 }
924919Sxy150489 
934919Sxy150489 /*
944919Sxy150489  * e1000_init_mac_params_82542 - Init MAC func ptrs.
954919Sxy150489  * @hw: pointer to the HW structure
964919Sxy150489  */
974919Sxy150489 static s32
e1000_init_mac_params_82542(struct e1000_hw * hw)984919Sxy150489 e1000_init_mac_params_82542(struct e1000_hw *hw)
994919Sxy150489 {
1004919Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
1014919Sxy150489 
1024919Sxy150489 	DEBUGFUNC("e1000_init_mac_params_82542");
1034919Sxy150489 
1044919Sxy150489 	/* Set media type */
1056735Scc210113 	hw->phy.media_type = e1000_media_type_fiber;
1064919Sxy150489 
1074919Sxy150489 	/* Set mta register count */
1084919Sxy150489 	mac->mta_reg_count = 128;
1094919Sxy150489 	/* Set rar entry count */
1104919Sxy150489 	mac->rar_entry_count = E1000_RAR_ENTRIES;
1114919Sxy150489 
1124919Sxy150489 	/* Function pointers */
1134919Sxy150489 
1144919Sxy150489 	/* bus type/speed/width */
1156735Scc210113 	mac->ops.get_bus_info = e1000_get_bus_info_82542;
11610680SMin.Xu@Sun.COM 	/* function id */
11710680SMin.Xu@Sun.COM 	mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pci;
1184919Sxy150489 	/* reset */
1196735Scc210113 	mac->ops.reset_hw = e1000_reset_hw_82542;
1204919Sxy150489 	/* hw initialization */
1216735Scc210113 	mac->ops.init_hw = e1000_init_hw_82542;
1224919Sxy150489 	/* link setup */
1236735Scc210113 	mac->ops.setup_link = e1000_setup_link_82542;
1244919Sxy150489 	/* phy/fiber/serdes setup */
1256735Scc210113 	mac->ops.setup_physical_interface =
1266735Scc210113 	    e1000_setup_fiber_serdes_link_generic;
1274919Sxy150489 	/* check for link */
1286735Scc210113 	mac->ops.check_for_link = e1000_check_for_fiber_link_generic;
1294919Sxy150489 	/* multicast address update */
1306735Scc210113 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
1314919Sxy150489 	/* writing VFTA */
1326735Scc210113 	mac->ops.write_vfta = e1000_write_vfta_generic;
1334919Sxy150489 	/* clearing VFTA */
1346735Scc210113 	mac->ops.clear_vfta = e1000_clear_vfta_generic;
1354919Sxy150489 	/* setting MTA */
1366735Scc210113 	mac->ops.mta_set = e1000_mta_set_generic;
13710680SMin.Xu@Sun.COM 	/* read mac address */
13810680SMin.Xu@Sun.COM 	mac->ops.read_mac_addr = e1000_read_mac_addr_82542;
1397607STed.You@Sun.COM 	/* set RAR */
1407607STed.You@Sun.COM 	mac->ops.rar_set = e1000_rar_set_82542;
1414919Sxy150489 	/* turn on/off LED */
1426735Scc210113 	mac->ops.led_on = e1000_led_on_82542;
1436735Scc210113 	mac->ops.led_off = e1000_led_off_82542;
1444919Sxy150489 	/* clear hardware counters */
1456735Scc210113 	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82542;
1464919Sxy150489 	/* link info */
1476735Scc210113 	mac->ops.get_link_up_info =
1484919Sxy150489 	    e1000_get_speed_and_duplex_fiber_serdes_generic;
1494919Sxy150489 
1508479SChenlu.Chen@Sun.COM 	return (E1000_SUCCESS);
1514919Sxy150489 }
1524919Sxy150489 
1534919Sxy150489 /*
1544919Sxy150489  * e1000_init_function_pointers_82542 - Init func ptrs.
1554919Sxy150489  * @hw: pointer to the HW structure
1564919Sxy150489  *
1578479SChenlu.Chen@Sun.COM  * Called to initialize all function pointers and parameters.
1584919Sxy150489  */
1594919Sxy150489 void
e1000_init_function_pointers_82542(struct e1000_hw * hw)1604919Sxy150489 e1000_init_function_pointers_82542(struct e1000_hw *hw)
1614919Sxy150489 {
1624919Sxy150489 	DEBUGFUNC("e1000_init_function_pointers_82542");
1634919Sxy150489 
1646735Scc210113 	hw->mac.ops.init_params = e1000_init_mac_params_82542;
1656735Scc210113 	hw->nvm.ops.init_params = e1000_init_nvm_params_82542;
1666735Scc210113 	hw->phy.ops.init_params = e1000_init_phy_params_82542;
1674919Sxy150489 }
1684919Sxy150489 
1694919Sxy150489 /*
1704919Sxy150489  * e1000_get_bus_info_82542 - Obtain bus information for adapter
1714919Sxy150489  * @hw: pointer to the HW structure
1724919Sxy150489  *
1734919Sxy150489  * This will obtain information about the HW bus for which the
1748479SChenlu.Chen@Sun.COM  * adapter is attached and stores it in the hw structure.
1754919Sxy150489  */
1764919Sxy150489 static s32
e1000_get_bus_info_82542(struct e1000_hw * hw)1774919Sxy150489 e1000_get_bus_info_82542(struct e1000_hw *hw)
1784919Sxy150489 {
1794919Sxy150489 	DEBUGFUNC("e1000_get_bus_info_82542");
1804919Sxy150489 
1814919Sxy150489 	hw->bus.type = e1000_bus_type_pci;
1824919Sxy150489 	hw->bus.speed = e1000_bus_speed_unknown;
1834919Sxy150489 	hw->bus.width = e1000_bus_width_unknown;
1844919Sxy150489 
1854919Sxy150489 	return (E1000_SUCCESS);
1864919Sxy150489 }
1874919Sxy150489 
1884919Sxy150489 /*
1894919Sxy150489  * e1000_reset_hw_82542 - Reset hardware
1904919Sxy150489  * @hw: pointer to the HW structure
1914919Sxy150489  *
1928479SChenlu.Chen@Sun.COM  * This resets the hardware into a known state.
1934919Sxy150489  */
1944919Sxy150489 static s32
e1000_reset_hw_82542(struct e1000_hw * hw)1954919Sxy150489 e1000_reset_hw_82542(struct e1000_hw *hw)
1964919Sxy150489 {
1974919Sxy150489 	struct e1000_bus_info *bus = &hw->bus;
1984919Sxy150489 	s32 ret_val = E1000_SUCCESS;
1997426SChenliang.Xu@Sun.COM 	u32 ctrl;
2004919Sxy150489 
2014919Sxy150489 	DEBUGFUNC("e1000_reset_hw_82542");
2024919Sxy150489 
2034919Sxy150489 	if (hw->revision_id == E1000_REVISION_2) {
2044919Sxy150489 		DEBUGOUT("Disabling MWI on 82542 rev 2\n");
2054919Sxy150489 		e1000_pci_clear_mwi(hw);
2064919Sxy150489 	}
2074919Sxy150489 
2084919Sxy150489 	DEBUGOUT("Masking off all interrupts\n");
2094919Sxy150489 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
2104919Sxy150489 
2114919Sxy150489 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
2124919Sxy150489 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
2134919Sxy150489 	E1000_WRITE_FLUSH(hw);
2144919Sxy150489 
2154919Sxy150489 	/*
2164919Sxy150489 	 * Delay to allow any outstanding PCI transactions to complete before
2174919Sxy150489 	 * resetting the device
2184919Sxy150489 	 */
2194919Sxy150489 	msec_delay(10);
2204919Sxy150489 
2214919Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
2224919Sxy150489 
2234919Sxy150489 	DEBUGOUT("Issuing a global reset to 82542/82543 MAC\n");
2244919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
2254919Sxy150489 
2266735Scc210113 	hw->nvm.ops.reload(hw);
2274919Sxy150489 	msec_delay(2);
2284919Sxy150489 
2294919Sxy150489 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
2307426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_ICR);
2314919Sxy150489 
2324919Sxy150489 	if (hw->revision_id == E1000_REVISION_2) {
2334919Sxy150489 		if (bus->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
2344919Sxy150489 			e1000_pci_set_mwi(hw);
2354919Sxy150489 	}
2364919Sxy150489 	return (ret_val);
2374919Sxy150489 }
2384919Sxy150489 
2394919Sxy150489 /*
2404919Sxy150489  * e1000_init_hw_82542 - Initialize hardware
2414919Sxy150489  * @hw: pointer to the HW structure
2424919Sxy150489  *
2438479SChenlu.Chen@Sun.COM  * This inits the hardware readying it for operation.
2444919Sxy150489  */
2454919Sxy150489 static s32
e1000_init_hw_82542(struct e1000_hw * hw)2464919Sxy150489 e1000_init_hw_82542(struct e1000_hw *hw)
2474919Sxy150489 {
2484919Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
2498479SChenlu.Chen@Sun.COM 	struct e1000_dev_spec_82542 *dev_spec = &hw->dev_spec._82542;
2504919Sxy150489 	s32 ret_val = E1000_SUCCESS;
2514919Sxy150489 	u32 ctrl;
2524919Sxy150489 	u16 i;
2534919Sxy150489 
2544919Sxy150489 	DEBUGFUNC("e1000_init_hw_82542");
2554919Sxy150489 
2564919Sxy150489 	/* Disabling VLAN filtering */
2574919Sxy150489 	E1000_WRITE_REG(hw, E1000_VET, 0);
2586735Scc210113 	mac->ops.clear_vfta(hw);
2594919Sxy150489 
2604919Sxy150489 	/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
2614919Sxy150489 	if (hw->revision_id == E1000_REVISION_2) {
2624919Sxy150489 		DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
2634919Sxy150489 		e1000_pci_clear_mwi(hw);
2644919Sxy150489 		E1000_WRITE_REG(hw, E1000_RCTL, E1000_RCTL_RST);
2654919Sxy150489 		E1000_WRITE_FLUSH(hw);
2664919Sxy150489 		msec_delay(5);
2674919Sxy150489 	}
2684919Sxy150489 
2694919Sxy150489 	/* Setup the receive address. */
2704919Sxy150489 	e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
2714919Sxy150489 
2724919Sxy150489 	/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
2734919Sxy150489 	if (hw->revision_id == E1000_REVISION_2) {
2744919Sxy150489 		E1000_WRITE_REG(hw, E1000_RCTL, 0);
2754919Sxy150489 		E1000_WRITE_FLUSH(hw);
2764919Sxy150489 		msec_delay(1);
2774919Sxy150489 		if (hw->bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
2784919Sxy150489 			e1000_pci_set_mwi(hw);
2794919Sxy150489 	}
2804919Sxy150489 
2814919Sxy150489 	/* Zero out the Multicast HASH table */
2824919Sxy150489 	DEBUGOUT("Zeroing the MTA\n");
2834919Sxy150489 	for (i = 0; i < mac->mta_reg_count; i++)
2844919Sxy150489 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
2854919Sxy150489 
2864919Sxy150489 	/*
2874919Sxy150489 	 * Set the PCI priority bit correctly in the CTRL register.  This
2884919Sxy150489 	 * determines if the adapter gives priority to receives, or if it
2894919Sxy150489 	 * gives equal priority to transmits and receives.
2904919Sxy150489 	 */
2914919Sxy150489 	if (dev_spec->dma_fairness) {
2924919Sxy150489 		ctrl = E1000_READ_REG(hw, E1000_CTRL);
2934919Sxy150489 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PRIOR);
2944919Sxy150489 	}
2954919Sxy150489 
2964919Sxy150489 	/* Setup link and flow control */
2974919Sxy150489 	ret_val = e1000_setup_link_82542(hw);
2984919Sxy150489 
2994919Sxy150489 	/*
3004919Sxy150489 	 * Clear all of the statistics registers (clear on read).  It is
3014919Sxy150489 	 * important that we do this after we have tried to establish link
3024919Sxy150489 	 * because the symbol error count will increment wildly if there
3034919Sxy150489 	 * is no link.
3044919Sxy150489 	 */
3054919Sxy150489 	e1000_clear_hw_cntrs_82542(hw);
3064919Sxy150489 
3074919Sxy150489 	return (ret_val);
3084919Sxy150489 }
3094919Sxy150489 
3104919Sxy150489 /*
3114919Sxy150489  * e1000_setup_link_82542 - Setup flow control and link settings
3124919Sxy150489  * @hw: pointer to the HW structure
3134919Sxy150489  *
3144919Sxy150489  * Determines which flow control settings to use, then configures flow
3154919Sxy150489  * control.  Calls the appropriate media-specific link configuration
3164919Sxy150489  * function.  Assuming the adapter has a valid link partner, a valid link
3174919Sxy150489  * should be established.  Assumes the hardware has previously been reset
3188479SChenlu.Chen@Sun.COM  * and the transmitter and receiver are not enabled.
3194919Sxy150489  */
3204919Sxy150489 static s32
e1000_setup_link_82542(struct e1000_hw * hw)3214919Sxy150489 e1000_setup_link_82542(struct e1000_hw *hw)
3224919Sxy150489 {
3234919Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
3244919Sxy150489 	s32 ret_val = E1000_SUCCESS;
3254919Sxy150489 
3264919Sxy150489 	DEBUGFUNC("e1000_setup_link_82542");
3274919Sxy150489 
3284919Sxy150489 	ret_val = e1000_set_default_fc_generic(hw);
3294919Sxy150489 	if (ret_val)
3304919Sxy150489 		goto out;
3314919Sxy150489 
3328539SChenlu.Chen@Sun.COM 	hw->fc.requested_mode &= ~e1000_fc_tx_pause;
3334919Sxy150489 
3344919Sxy150489 	if (mac->report_tx_early == 1)
3358539SChenlu.Chen@Sun.COM 		hw->fc.requested_mode &= ~e1000_fc_rx_pause;
3364919Sxy150489 
3374919Sxy150489 	/*
3388479SChenlu.Chen@Sun.COM 	 * Save off the requested flow control mode for use later.  Depending
3398479SChenlu.Chen@Sun.COM 	 * on the link partner's capabilities, we may or may not use this mode.
3404919Sxy150489 	 */
3418539SChenlu.Chen@Sun.COM 	hw->fc.current_mode = hw->fc.requested_mode;
3424919Sxy150489 
3438479SChenlu.Chen@Sun.COM 	DEBUGOUT1("After fix-ups FlowControl is now = %x\n",
3448479SChenlu.Chen@Sun.COM 	    hw->fc.current_mode);
3454919Sxy150489 
3464919Sxy150489 	/* Call the necessary subroutine to configure the link. */
3476735Scc210113 	ret_val = mac->ops.setup_physical_interface(hw);
3484919Sxy150489 	if (ret_val)
3494919Sxy150489 		goto out;
3504919Sxy150489 
3514919Sxy150489 	/*
3524919Sxy150489 	 * Initialize the flow control address, type, and PAUSE timer
3534919Sxy150489 	 * registers to their default values.  This is done even if flow
3544919Sxy150489 	 * control is disabled, because it does not hurt anything to
3554919Sxy150489 	 * initialize these registers.
3564919Sxy150489 	 */
3574919Sxy150489 	DEBUGOUT("Initializing Flow Control address, type and timer regs\n");
3584919Sxy150489 
3594919Sxy150489 	E1000_WRITE_REG(hw, E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW);
3604919Sxy150489 	E1000_WRITE_REG(hw, E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH);
3614919Sxy150489 	E1000_WRITE_REG(hw, E1000_FCT, FLOW_CONTROL_TYPE);
3624919Sxy150489 
3636735Scc210113 	E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time);
3644919Sxy150489 
3654919Sxy150489 	ret_val = e1000_set_fc_watermarks_generic(hw);
3664919Sxy150489 
3674919Sxy150489 out:
3684919Sxy150489 	return (ret_val);
3694919Sxy150489 }
3704919Sxy150489 
3714919Sxy150489 /*
3724919Sxy150489  * e1000_led_on_82542 - Turn on SW controllable LED
3734919Sxy150489  * @hw: pointer to the HW structure
3744919Sxy150489  *
3758479SChenlu.Chen@Sun.COM  * Turns the SW defined LED on.
3764919Sxy150489  */
3774919Sxy150489 static s32
e1000_led_on_82542(struct e1000_hw * hw)3784919Sxy150489 e1000_led_on_82542(struct e1000_hw *hw)
3794919Sxy150489 {
3804919Sxy150489 	u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
3814919Sxy150489 
3824919Sxy150489 	DEBUGFUNC("e1000_led_on_82542");
3834919Sxy150489 
3844919Sxy150489 	ctrl |= E1000_CTRL_SWDPIN0;
3854919Sxy150489 	ctrl |= E1000_CTRL_SWDPIO0;
3864919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
3874919Sxy150489 
3884919Sxy150489 	return (E1000_SUCCESS);
3894919Sxy150489 }
3904919Sxy150489 
3914919Sxy150489 /*
3924919Sxy150489  * e1000_led_off_82542 - Turn off SW controllable LED
3934919Sxy150489  * @hw: pointer to the HW structure
3944919Sxy150489  *
3958479SChenlu.Chen@Sun.COM  * Turns the SW defined LED off.
3964919Sxy150489  */
3974919Sxy150489 static s32
e1000_led_off_82542(struct e1000_hw * hw)3984919Sxy150489 e1000_led_off_82542(struct e1000_hw *hw)
3994919Sxy150489 {
4004919Sxy150489 	u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
4014919Sxy150489 
4024919Sxy150489 	DEBUGFUNC("e1000_led_off_82542");
4034919Sxy150489 
4044919Sxy150489 	ctrl &= ~E1000_CTRL_SWDPIN0;
4054919Sxy150489 	ctrl |= E1000_CTRL_SWDPIO0;
4064919Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
4074919Sxy150489 
4084919Sxy150489 	return (E1000_SUCCESS);
4094919Sxy150489 }
4104919Sxy150489 
4114919Sxy150489 /*
4127607STed.You@Sun.COM  * e1000_rar_set_82542 - Set receive address register
4137607STed.You@Sun.COM  * @hw: pointer to the HW structure
4147607STed.You@Sun.COM  * @addr: pointer to the receive address
4157607STed.You@Sun.COM  * @index: receive address array register
4167607STed.You@Sun.COM  *
4177607STed.You@Sun.COM  * Sets the receive address array register at index to the address passed
4187607STed.You@Sun.COM  * in by addr.
4197607STed.You@Sun.COM  */
4207607STed.You@Sun.COM static void
e1000_rar_set_82542(struct e1000_hw * hw,u8 * addr,u32 index)4217607STed.You@Sun.COM e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index)
4227607STed.You@Sun.COM {
4237607STed.You@Sun.COM 	u32 rar_low, rar_high;
4247607STed.You@Sun.COM 
4257607STed.You@Sun.COM 	DEBUGFUNC("e1000_rar_set_82542");
4267607STed.You@Sun.COM 
4277607STed.You@Sun.COM 	/*
4287607STed.You@Sun.COM 	 * HW expects these in little endian so we reverse the byte order
4297607STed.You@Sun.COM 	 * from network order (big endian) to little endian
4307607STed.You@Sun.COM 	 */
4317607STed.You@Sun.COM 	rar_low = ((u32) addr[0] |
4327607STed.You@Sun.COM 	    ((u32) addr[1] << 8) |
4337607STed.You@Sun.COM 	    ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
4347607STed.You@Sun.COM 
4357607STed.You@Sun.COM 	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
4367607STed.You@Sun.COM 
4377607STed.You@Sun.COM 	/* If MAC address zero, no need to set the AV bit */
4388479SChenlu.Chen@Sun.COM 	if (rar_low || rar_high)
4398479SChenlu.Chen@Sun.COM 		rar_high |= E1000_RAH_AV;
4407607STed.You@Sun.COM 
4417607STed.You@Sun.COM 	E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low);
4427607STed.You@Sun.COM 	E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high);
4437607STed.You@Sun.COM }
4447607STed.You@Sun.COM 
4457607STed.You@Sun.COM /*
4466735Scc210113  * e1000_translate_register_82542 - Translate the proper register offset
4474919Sxy150489  * @reg: e1000 register to be read
4484919Sxy150489  *
4494919Sxy150489  * Registers in 82542 are located in different offsets than other adapters
4504919Sxy150489  * even though they function in the same manner.  This function takes in
4514919Sxy150489  * the name of the register to read and returns the correct offset for
4524919Sxy150489  * 82542 silicon.
4534919Sxy150489  */
4544919Sxy150489 u32
e1000_translate_register_82542(u32 reg)4554919Sxy150489 e1000_translate_register_82542(u32 reg)
4564919Sxy150489 {
4574919Sxy150489 	/*
4584919Sxy150489 	 * Some of the 82542 registers are located at different
4594919Sxy150489 	 * offsets than they are in newer adapters.
4604919Sxy150489 	 * Despite the difference in location, the registers
4614919Sxy150489 	 * function in the same manner.
4624919Sxy150489 	 */
4634919Sxy150489 	switch (reg) {
4644919Sxy150489 		case E1000_RA:
4654919Sxy150489 		reg = 0x00040;
4664919Sxy150489 		break;
4674919Sxy150489 	case E1000_RDTR:
4684919Sxy150489 		reg = 0x00108;
4694919Sxy150489 		break;
4706735Scc210113 	case E1000_RDBAL(0):
4714919Sxy150489 		reg = 0x00110;
4724919Sxy150489 		break;
4736735Scc210113 	case E1000_RDBAH(0):
4744919Sxy150489 		reg = 0x00114;
4754919Sxy150489 		break;
4766735Scc210113 	case E1000_RDLEN(0):
4774919Sxy150489 		reg = 0x00118;
4784919Sxy150489 		break;
4796735Scc210113 	case E1000_RDH(0):
4804919Sxy150489 		reg = 0x00120;
4814919Sxy150489 		break;
4826735Scc210113 	case E1000_RDT(0):
4834919Sxy150489 		reg = 0x00128;
4844919Sxy150489 		break;
4856735Scc210113 	case E1000_RDBAL(1):
4864919Sxy150489 		reg = 0x00138;
4874919Sxy150489 		break;
4886735Scc210113 	case E1000_RDBAH(1):
4894919Sxy150489 		reg = 0x0013C;
4904919Sxy150489 		break;
4916735Scc210113 	case E1000_RDLEN(1):
4924919Sxy150489 		reg = 0x00140;
4934919Sxy150489 		break;
4946735Scc210113 	case E1000_RDH(1):
4954919Sxy150489 		reg = 0x00148;
4964919Sxy150489 		break;
4976735Scc210113 	case E1000_RDT(1):
4984919Sxy150489 		reg = 0x00150;
4994919Sxy150489 		break;
5004919Sxy150489 	case E1000_FCRTH:
5014919Sxy150489 		reg = 0x00160;
5024919Sxy150489 		break;
5034919Sxy150489 	case E1000_FCRTL:
5044919Sxy150489 		reg = 0x00168;
5054919Sxy150489 		break;
5064919Sxy150489 	case E1000_MTA:
5074919Sxy150489 		reg = 0x00200;
5084919Sxy150489 		break;
5096735Scc210113 	case E1000_TDBAL(0):
5104919Sxy150489 		reg = 0x00420;
5114919Sxy150489 		break;
5126735Scc210113 	case E1000_TDBAH(0):
5134919Sxy150489 		reg = 0x00424;
5144919Sxy150489 		break;
5156735Scc210113 	case E1000_TDLEN(0):
5164919Sxy150489 		reg = 0x00428;
5174919Sxy150489 		break;
5186735Scc210113 	case E1000_TDH(0):
5194919Sxy150489 		reg = 0x00430;
5204919Sxy150489 		break;
5216735Scc210113 	case E1000_TDT(0):
5224919Sxy150489 		reg = 0x00438;
5234919Sxy150489 		break;
5244919Sxy150489 	case E1000_TIDV:
5254919Sxy150489 		reg = 0x00440;
5264919Sxy150489 		break;
5274919Sxy150489 	case E1000_VFTA:
5284919Sxy150489 		reg = 0x00600;
5294919Sxy150489 		break;
5304919Sxy150489 	case E1000_TDFH:
5314919Sxy150489 		reg = 0x08010;
5324919Sxy150489 		break;
5334919Sxy150489 	case E1000_TDFT:
5344919Sxy150489 		reg = 0x08018;
5354919Sxy150489 		break;
5364919Sxy150489 	default:
5374919Sxy150489 		break;
5384919Sxy150489 	}
5394919Sxy150489 
5404919Sxy150489 	return (reg);
5414919Sxy150489 }
5424919Sxy150489 
5434919Sxy150489 /*
5444919Sxy150489  * e1000_clear_hw_cntrs_82542 - Clear device specific hardware counters
5454919Sxy150489  * @hw: pointer to the HW structure
5464919Sxy150489  *
5474919Sxy150489  * Clears the hardware counters by reading the counter registers.
5484919Sxy150489  */
5494919Sxy150489 static void
e1000_clear_hw_cntrs_82542(struct e1000_hw * hw)5504919Sxy150489 e1000_clear_hw_cntrs_82542(struct e1000_hw *hw)
5514919Sxy150489 {
5524919Sxy150489 	DEBUGFUNC("e1000_clear_hw_cntrs_82542");
5534919Sxy150489 
5544919Sxy150489 	e1000_clear_hw_cntrs_base_generic(hw);
5554919Sxy150489 
5567426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC64);
5577426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC127);
5587426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC255);
5597426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC511);
5607426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC1023);
5617426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PRC1522);
5627426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC64);
5637426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC127);
5647426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC255);
5657426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC511);
5667426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC1023);
5677426SChenliang.Xu@Sun.COM 	(void) E1000_READ_REG(hw, E1000_PTC1522);
5684919Sxy150489 }
56910680SMin.Xu@Sun.COM 
57010680SMin.Xu@Sun.COM /*
57110680SMin.Xu@Sun.COM  * e1000_read_mac_addr_82542 - Read device MAC address
57210680SMin.Xu@Sun.COM  * @hw: pointer to the HW structure
57310680SMin.Xu@Sun.COM  *
57410680SMin.Xu@Sun.COM  * Reads the device MAC address from the EEPROM and stores the value.
57510680SMin.Xu@Sun.COM  */
57610680SMin.Xu@Sun.COM s32
e1000_read_mac_addr_82542(struct e1000_hw * hw)57710680SMin.Xu@Sun.COM e1000_read_mac_addr_82542(struct e1000_hw *hw)
57810680SMin.Xu@Sun.COM {
57910680SMin.Xu@Sun.COM 	s32  ret_val = E1000_SUCCESS;
58010680SMin.Xu@Sun.COM 	u16 offset, nvm_data, i;
58110680SMin.Xu@Sun.COM 
58210680SMin.Xu@Sun.COM 	DEBUGFUNC("e1000_read_mac_addr");
58310680SMin.Xu@Sun.COM 
58410680SMin.Xu@Sun.COM 	for (i = 0; i < ETH_ADDR_LEN; i += 2) {
58510680SMin.Xu@Sun.COM 		offset = i >> 1;
58610680SMin.Xu@Sun.COM 		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
58710680SMin.Xu@Sun.COM 		if (ret_val) {
58810680SMin.Xu@Sun.COM 			DEBUGOUT("NVM Read Error\n");
58910680SMin.Xu@Sun.COM 			goto out;
59010680SMin.Xu@Sun.COM 		}
59110680SMin.Xu@Sun.COM 		hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
59210680SMin.Xu@Sun.COM 		hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
59310680SMin.Xu@Sun.COM 	}
59410680SMin.Xu@Sun.COM 
59510680SMin.Xu@Sun.COM 	for (i = 0; i < ETH_ADDR_LEN; i++)
59610680SMin.Xu@Sun.COM 		hw->mac.addr[i] = hw->mac.perm_addr[i];
59710680SMin.Xu@Sun.COM 
59810680SMin.Xu@Sun.COM 	out:
59910680SMin.Xu@Sun.COM 		return (ret_val);
60010680SMin.Xu@Sun.COM }
601