xref: /freebsd/sys/dev/e1000/e1000_82542.c (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
18cfa0ad2SJack F Vogel /******************************************************************************
27282444bSPedro F. Giffuni   SPDX-License-Identifier: BSD-3-Clause
38cfa0ad2SJack F Vogel 
4*702cac6cSKevin Bowling   Copyright (c) 2001-2020, Intel Corporation
58cfa0ad2SJack F Vogel   All rights reserved.
68cfa0ad2SJack F Vogel 
78cfa0ad2SJack F Vogel   Redistribution and use in source and binary forms, with or without
88cfa0ad2SJack F Vogel   modification, are permitted provided that the following conditions are met:
98cfa0ad2SJack F Vogel 
108cfa0ad2SJack F Vogel    1. Redistributions of source code must retain the above copyright notice,
118cfa0ad2SJack F Vogel       this list of conditions and the following disclaimer.
128cfa0ad2SJack F Vogel 
138cfa0ad2SJack F Vogel    2. Redistributions in binary form must reproduce the above copyright
148cfa0ad2SJack F Vogel       notice, this list of conditions and the following disclaimer in the
158cfa0ad2SJack F Vogel       documentation and/or other materials provided with the distribution.
168cfa0ad2SJack F Vogel 
178cfa0ad2SJack F Vogel    3. Neither the name of the Intel Corporation nor the names of its
188cfa0ad2SJack F Vogel       contributors may be used to endorse or promote products derived from
198cfa0ad2SJack F Vogel       this software without specific prior written permission.
208cfa0ad2SJack F Vogel 
218cfa0ad2SJack F Vogel   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
228cfa0ad2SJack F Vogel   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
238cfa0ad2SJack F Vogel   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
248cfa0ad2SJack F Vogel   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
258cfa0ad2SJack F Vogel   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
268cfa0ad2SJack F Vogel   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
278cfa0ad2SJack F Vogel   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
288cfa0ad2SJack F Vogel   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
298cfa0ad2SJack F Vogel   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
308cfa0ad2SJack F Vogel   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
318cfa0ad2SJack F Vogel   POSSIBILITY OF SUCH DAMAGE.
328cfa0ad2SJack F Vogel 
338cfa0ad2SJack F Vogel ******************************************************************************/
348cfa0ad2SJack F Vogel 
35daf9197cSJack F Vogel /*
36daf9197cSJack F Vogel  * 82542 Gigabit Ethernet Controller
378cfa0ad2SJack F Vogel  */
388cfa0ad2SJack F Vogel 
398cfa0ad2SJack F Vogel #include "e1000_api.h"
408cfa0ad2SJack F Vogel 
418cfa0ad2SJack F Vogel static s32  e1000_init_phy_params_82542(struct e1000_hw *hw);
428cfa0ad2SJack F Vogel static s32  e1000_init_nvm_params_82542(struct e1000_hw *hw);
438cfa0ad2SJack F Vogel static s32  e1000_init_mac_params_82542(struct e1000_hw *hw);
448cfa0ad2SJack F Vogel static s32  e1000_get_bus_info_82542(struct e1000_hw *hw);
458cfa0ad2SJack F Vogel static s32  e1000_reset_hw_82542(struct e1000_hw *hw);
468cfa0ad2SJack F Vogel static s32  e1000_init_hw_82542(struct e1000_hw *hw);
478cfa0ad2SJack F Vogel static s32  e1000_setup_link_82542(struct e1000_hw *hw);
488cfa0ad2SJack F Vogel static s32  e1000_led_on_82542(struct e1000_hw *hw);
498cfa0ad2SJack F Vogel static s32  e1000_led_off_82542(struct e1000_hw *hw);
508cc64f1eSJack F Vogel static int  e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index);
518cfa0ad2SJack F Vogel static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw);
5238537cb9SJack F Vogel static s32  e1000_read_mac_addr_82542(struct e1000_hw *hw);
5338537cb9SJack F Vogel 
548cfa0ad2SJack F Vogel /**
558cfa0ad2SJack F Vogel  *  e1000_init_phy_params_82542 - Init PHY func ptrs.
568cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
578cfa0ad2SJack F Vogel  **/
e1000_init_phy_params_82542(struct e1000_hw * hw)588cfa0ad2SJack F Vogel static s32 e1000_init_phy_params_82542(struct e1000_hw *hw)
598cfa0ad2SJack F Vogel {
608cfa0ad2SJack F Vogel 	struct e1000_phy_info *phy = &hw->phy;
618cfa0ad2SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
628cfa0ad2SJack F Vogel 
638cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_init_phy_params_82542");
648cfa0ad2SJack F Vogel 
658cfa0ad2SJack F Vogel 	phy->type = e1000_phy_none;
668cfa0ad2SJack F Vogel 
678cfa0ad2SJack F Vogel 	return ret_val;
688cfa0ad2SJack F Vogel }
698cfa0ad2SJack F Vogel 
708cfa0ad2SJack F Vogel /**
718cfa0ad2SJack F Vogel  *  e1000_init_nvm_params_82542 - Init NVM func ptrs.
728cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
738cfa0ad2SJack F Vogel  **/
e1000_init_nvm_params_82542(struct e1000_hw * hw)748cfa0ad2SJack F Vogel static s32 e1000_init_nvm_params_82542(struct e1000_hw *hw)
758cfa0ad2SJack F Vogel {
768cfa0ad2SJack F Vogel 	struct e1000_nvm_info *nvm = &hw->nvm;
778cfa0ad2SJack F Vogel 
788cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_init_nvm_params_82542");
798cfa0ad2SJack F Vogel 
808cfa0ad2SJack F Vogel 	nvm->address_bits	=  6;
818cfa0ad2SJack F Vogel 	nvm->delay_usec		= 50;
828cfa0ad2SJack F Vogel 	nvm->opcode_bits	=  3;
838cfa0ad2SJack F Vogel 	nvm->type		= e1000_nvm_eeprom_microwire;
848cfa0ad2SJack F Vogel 	nvm->word_size		= 64;
858cfa0ad2SJack F Vogel 
868cfa0ad2SJack F Vogel 	/* Function Pointers */
878cfa0ad2SJack F Vogel 	nvm->ops.read		= e1000_read_nvm_microwire;
888cfa0ad2SJack F Vogel 	nvm->ops.release	= e1000_stop_nvm;
898cfa0ad2SJack F Vogel 	nvm->ops.write		= e1000_write_nvm_microwire;
908cfa0ad2SJack F Vogel 	nvm->ops.update		= e1000_update_nvm_checksum_generic;
918cfa0ad2SJack F Vogel 	nvm->ops.validate	= e1000_validate_nvm_checksum_generic;
928cfa0ad2SJack F Vogel 
938cfa0ad2SJack F Vogel 	return E1000_SUCCESS;
948cfa0ad2SJack F Vogel }
958cfa0ad2SJack F Vogel 
968cfa0ad2SJack F Vogel /**
978cfa0ad2SJack F Vogel  *  e1000_init_mac_params_82542 - Init MAC func ptrs.
988cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
998cfa0ad2SJack F Vogel  **/
e1000_init_mac_params_82542(struct e1000_hw * hw)1008cfa0ad2SJack F Vogel static s32 e1000_init_mac_params_82542(struct e1000_hw *hw)
1018cfa0ad2SJack F Vogel {
1028cfa0ad2SJack F Vogel 	struct e1000_mac_info *mac = &hw->mac;
1038cfa0ad2SJack F Vogel 
1048cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_init_mac_params_82542");
1058cfa0ad2SJack F Vogel 
1068cfa0ad2SJack F Vogel 	/* Set media type */
1078cfa0ad2SJack F Vogel 	hw->phy.media_type = e1000_media_type_fiber;
1088cfa0ad2SJack F Vogel 
1098cfa0ad2SJack F Vogel 	/* Set mta register count */
1108cfa0ad2SJack F Vogel 	mac->mta_reg_count = 128;
1118cfa0ad2SJack F Vogel 	/* Set rar entry count */
1128cfa0ad2SJack F Vogel 	mac->rar_entry_count = E1000_RAR_ENTRIES;
1138cfa0ad2SJack F Vogel 
1148cfa0ad2SJack F Vogel 	/* Function pointers */
1158cfa0ad2SJack F Vogel 
1168cfa0ad2SJack F Vogel 	/* bus type/speed/width */
1178cfa0ad2SJack F Vogel 	mac->ops.get_bus_info = e1000_get_bus_info_82542;
118daf9197cSJack F Vogel 	/* function id */
119daf9197cSJack F Vogel 	mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pci;
1208cfa0ad2SJack F Vogel 	/* reset */
1218cfa0ad2SJack F Vogel 	mac->ops.reset_hw = e1000_reset_hw_82542;
1228cfa0ad2SJack F Vogel 	/* hw initialization */
1238cfa0ad2SJack F Vogel 	mac->ops.init_hw = e1000_init_hw_82542;
1248cfa0ad2SJack F Vogel 	/* link setup */
1258cfa0ad2SJack F Vogel 	mac->ops.setup_link = e1000_setup_link_82542;
1268cfa0ad2SJack F Vogel 	/* phy/fiber/serdes setup */
12748600901SSean Bruno 	mac->ops.setup_physical_interface =
12848600901SSean Bruno 					e1000_setup_fiber_serdes_link_generic;
1298cfa0ad2SJack F Vogel 	/* check for link */
1308cfa0ad2SJack F Vogel 	mac->ops.check_for_link = e1000_check_for_fiber_link_generic;
1318cfa0ad2SJack F Vogel 	/* multicast address update */
1328cfa0ad2SJack F Vogel 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
1338cfa0ad2SJack F Vogel 	/* writing VFTA */
1348cfa0ad2SJack F Vogel 	mac->ops.write_vfta = e1000_write_vfta_generic;
1358cfa0ad2SJack F Vogel 	/* clearing VFTA */
1368cfa0ad2SJack F Vogel 	mac->ops.clear_vfta = e1000_clear_vfta_generic;
13738537cb9SJack F Vogel 	/* read mac address */
13838537cb9SJack F Vogel 	mac->ops.read_mac_addr = e1000_read_mac_addr_82542;
1398cfa0ad2SJack F Vogel 	/* set RAR */
1408cfa0ad2SJack F Vogel 	mac->ops.rar_set = e1000_rar_set_82542;
1418cfa0ad2SJack F Vogel 	/* turn on/off LED */
1428cfa0ad2SJack F Vogel 	mac->ops.led_on = e1000_led_on_82542;
1438cfa0ad2SJack F Vogel 	mac->ops.led_off = e1000_led_off_82542;
1448cfa0ad2SJack F Vogel 	/* clear hardware counters */
1458cfa0ad2SJack F Vogel 	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82542;
1468cfa0ad2SJack F Vogel 	/* link info */
14748600901SSean Bruno 	mac->ops.get_link_up_info =
14848600901SSean Bruno 				e1000_get_speed_and_duplex_fiber_serdes_generic;
1498cfa0ad2SJack F Vogel 
150daf9197cSJack F Vogel 	return E1000_SUCCESS;
1518cfa0ad2SJack F Vogel }
1528cfa0ad2SJack F Vogel 
1538cfa0ad2SJack F Vogel /**
1548cfa0ad2SJack F Vogel  *  e1000_init_function_pointers_82542 - Init func ptrs.
1558cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
1568cfa0ad2SJack F Vogel  *
157daf9197cSJack F Vogel  *  Called to initialize all function pointers and parameters.
1588cfa0ad2SJack F Vogel  **/
e1000_init_function_pointers_82542(struct e1000_hw * hw)1598cfa0ad2SJack F Vogel void e1000_init_function_pointers_82542(struct e1000_hw *hw)
1608cfa0ad2SJack F Vogel {
1618cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_init_function_pointers_82542");
1628cfa0ad2SJack F Vogel 
1638cfa0ad2SJack F Vogel 	hw->mac.ops.init_params = e1000_init_mac_params_82542;
1648cfa0ad2SJack F Vogel 	hw->nvm.ops.init_params = e1000_init_nvm_params_82542;
1658cfa0ad2SJack F Vogel 	hw->phy.ops.init_params = e1000_init_phy_params_82542;
1668cfa0ad2SJack F Vogel }
1678cfa0ad2SJack F Vogel 
1688cfa0ad2SJack F Vogel /**
1698cfa0ad2SJack F Vogel  *  e1000_get_bus_info_82542 - Obtain bus information for adapter
1708cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
1718cfa0ad2SJack F Vogel  *
1728cfa0ad2SJack F Vogel  *  This will obtain information about the HW bus for which the
173daf9197cSJack F Vogel  *  adapter is attached and stores it in the hw structure.
1748cfa0ad2SJack F Vogel  **/
e1000_get_bus_info_82542(struct e1000_hw * hw)1758cfa0ad2SJack F Vogel static s32 e1000_get_bus_info_82542(struct e1000_hw *hw)
1768cfa0ad2SJack F Vogel {
1778cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_get_bus_info_82542");
1788cfa0ad2SJack F Vogel 
1798cfa0ad2SJack F Vogel 	hw->bus.type = e1000_bus_type_pci;
1808cfa0ad2SJack F Vogel 	hw->bus.speed = e1000_bus_speed_unknown;
1818cfa0ad2SJack F Vogel 	hw->bus.width = e1000_bus_width_unknown;
1828cfa0ad2SJack F Vogel 
1838cfa0ad2SJack F Vogel 	return E1000_SUCCESS;
1848cfa0ad2SJack F Vogel }
1858cfa0ad2SJack F Vogel 
1868cfa0ad2SJack F Vogel /**
1878cfa0ad2SJack F Vogel  *  e1000_reset_hw_82542 - Reset hardware
1888cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
1898cfa0ad2SJack F Vogel  *
190daf9197cSJack F Vogel  *  This resets the hardware into a known state.
1918cfa0ad2SJack F Vogel  **/
e1000_reset_hw_82542(struct e1000_hw * hw)1928cfa0ad2SJack F Vogel static s32 e1000_reset_hw_82542(struct e1000_hw *hw)
1938cfa0ad2SJack F Vogel {
1948cfa0ad2SJack F Vogel 	struct e1000_bus_info *bus = &hw->bus;
1958cfa0ad2SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
196fe954359SJack F Vogel 	u32 ctrl;
1978cfa0ad2SJack F Vogel 
1988cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_reset_hw_82542");
1998cfa0ad2SJack F Vogel 
2008cfa0ad2SJack F Vogel 	if (hw->revision_id == E1000_REVISION_2) {
2018cfa0ad2SJack F Vogel 		DEBUGOUT("Disabling MWI on 82542 rev 2\n");
2028cfa0ad2SJack F Vogel 		e1000_pci_clear_mwi(hw);
2038cfa0ad2SJack F Vogel 	}
2048cfa0ad2SJack F Vogel 
2058cfa0ad2SJack F Vogel 	DEBUGOUT("Masking off all interrupts\n");
2068cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
2078cfa0ad2SJack F Vogel 
2088cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
2098cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
2108cfa0ad2SJack F Vogel 	E1000_WRITE_FLUSH(hw);
2118cfa0ad2SJack F Vogel 
2128cfa0ad2SJack F Vogel 	/*
2138cfa0ad2SJack F Vogel 	 * Delay to allow any outstanding PCI transactions to complete before
2148cfa0ad2SJack F Vogel 	 * resetting the device
2158cfa0ad2SJack F Vogel 	 */
2168cfa0ad2SJack F Vogel 	msec_delay(10);
2178cfa0ad2SJack F Vogel 
2188cfa0ad2SJack F Vogel 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
2198cfa0ad2SJack F Vogel 
2208cfa0ad2SJack F Vogel 	DEBUGOUT("Issuing a global reset to 82542/82543 MAC\n");
2218cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
2228cfa0ad2SJack F Vogel 
2238cfa0ad2SJack F Vogel 	hw->nvm.ops.reload(hw);
2248cfa0ad2SJack F Vogel 	msec_delay(2);
2258cfa0ad2SJack F Vogel 
2268cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
227fe954359SJack F Vogel 	E1000_READ_REG(hw, E1000_ICR);
2288cfa0ad2SJack F Vogel 
2298cfa0ad2SJack F Vogel 	if (hw->revision_id == E1000_REVISION_2) {
2308cfa0ad2SJack F Vogel 		if (bus->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
2318cfa0ad2SJack F Vogel 			e1000_pci_set_mwi(hw);
2328cfa0ad2SJack F Vogel 	}
2338cfa0ad2SJack F Vogel 
2348cfa0ad2SJack F Vogel 	return ret_val;
2358cfa0ad2SJack F Vogel }
2368cfa0ad2SJack F Vogel 
2378cfa0ad2SJack F Vogel /**
2388cfa0ad2SJack F Vogel  *  e1000_init_hw_82542 - Initialize hardware
2398cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
2408cfa0ad2SJack F Vogel  *
241daf9197cSJack F Vogel  *  This inits the hardware readying it for operation.
2428cfa0ad2SJack F Vogel  **/
e1000_init_hw_82542(struct e1000_hw * hw)2438cfa0ad2SJack F Vogel static s32 e1000_init_hw_82542(struct e1000_hw *hw)
2448cfa0ad2SJack F Vogel {
2458cfa0ad2SJack F Vogel 	struct e1000_mac_info *mac = &hw->mac;
246daf9197cSJack F Vogel 	struct e1000_dev_spec_82542 *dev_spec = &hw->dev_spec._82542;
2478cfa0ad2SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
2488cfa0ad2SJack F Vogel 	u32 ctrl;
2498cfa0ad2SJack F Vogel 	u16 i;
2508cfa0ad2SJack F Vogel 
2518cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_init_hw_82542");
2528cfa0ad2SJack F Vogel 
2538cfa0ad2SJack F Vogel 	/* Disabling VLAN filtering */
2548cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_VET, 0);
2558cfa0ad2SJack F Vogel 	mac->ops.clear_vfta(hw);
2568cfa0ad2SJack F Vogel 
2578cfa0ad2SJack F Vogel 	/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
2588cfa0ad2SJack F Vogel 	if (hw->revision_id == E1000_REVISION_2) {
2598cfa0ad2SJack F Vogel 		DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
2608cfa0ad2SJack F Vogel 		e1000_pci_clear_mwi(hw);
2618cfa0ad2SJack F Vogel 		E1000_WRITE_REG(hw, E1000_RCTL, E1000_RCTL_RST);
2628cfa0ad2SJack F Vogel 		E1000_WRITE_FLUSH(hw);
2638cfa0ad2SJack F Vogel 		msec_delay(5);
2648cfa0ad2SJack F Vogel 	}
2658cfa0ad2SJack F Vogel 
2668cfa0ad2SJack F Vogel 	/* Setup the receive address. */
2678cfa0ad2SJack F Vogel 	e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
2688cfa0ad2SJack F Vogel 
2698cfa0ad2SJack F Vogel 	/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
2708cfa0ad2SJack F Vogel 	if (hw->revision_id == E1000_REVISION_2) {
2718cfa0ad2SJack F Vogel 		E1000_WRITE_REG(hw, E1000_RCTL, 0);
2728cfa0ad2SJack F Vogel 		E1000_WRITE_FLUSH(hw);
2738cfa0ad2SJack F Vogel 		msec_delay(1);
2748cfa0ad2SJack F Vogel 		if (hw->bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
2758cfa0ad2SJack F Vogel 			e1000_pci_set_mwi(hw);
2768cfa0ad2SJack F Vogel 	}
2778cfa0ad2SJack F Vogel 
2788cfa0ad2SJack F Vogel 	/* Zero out the Multicast HASH table */
2798cfa0ad2SJack F Vogel 	DEBUGOUT("Zeroing the MTA\n");
2808cfa0ad2SJack F Vogel 	for (i = 0; i < mac->mta_reg_count; i++)
2818cfa0ad2SJack F Vogel 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
2828cfa0ad2SJack F Vogel 
2838cfa0ad2SJack F Vogel 	/*
2848cfa0ad2SJack F Vogel 	 * Set the PCI priority bit correctly in the CTRL register.  This
2858cfa0ad2SJack F Vogel 	 * determines if the adapter gives priority to receives, or if it
2868cfa0ad2SJack F Vogel 	 * gives equal priority to transmits and receives.
2878cfa0ad2SJack F Vogel 	 */
2888cfa0ad2SJack F Vogel 	if (dev_spec->dma_fairness) {
2898cfa0ad2SJack F Vogel 		ctrl = E1000_READ_REG(hw, E1000_CTRL);
2908cfa0ad2SJack F Vogel 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PRIOR);
2918cfa0ad2SJack F Vogel 	}
2928cfa0ad2SJack F Vogel 
2938cfa0ad2SJack F Vogel 	/* Setup link and flow control */
2948cfa0ad2SJack F Vogel 	ret_val = e1000_setup_link_82542(hw);
2958cfa0ad2SJack F Vogel 
2968cfa0ad2SJack F Vogel 	/*
2978cfa0ad2SJack F Vogel 	 * Clear all of the statistics registers (clear on read).  It is
2988cfa0ad2SJack F Vogel 	 * important that we do this after we have tried to establish link
2998cfa0ad2SJack F Vogel 	 * because the symbol error count will increment wildly if there
3008cfa0ad2SJack F Vogel 	 * is no link.
3018cfa0ad2SJack F Vogel 	 */
3028cfa0ad2SJack F Vogel 	e1000_clear_hw_cntrs_82542(hw);
3038cfa0ad2SJack F Vogel 
3048cfa0ad2SJack F Vogel 	return ret_val;
3058cfa0ad2SJack F Vogel }
3068cfa0ad2SJack F Vogel 
3078cfa0ad2SJack F Vogel /**
3088cfa0ad2SJack F Vogel  *  e1000_setup_link_82542 - Setup flow control and link settings
3098cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
3108cfa0ad2SJack F Vogel  *
3118cfa0ad2SJack F Vogel  *  Determines which flow control settings to use, then configures flow
3128cfa0ad2SJack F Vogel  *  control.  Calls the appropriate media-specific link configuration
3138cfa0ad2SJack F Vogel  *  function.  Assuming the adapter has a valid link partner, a valid link
3148cfa0ad2SJack F Vogel  *  should be established.  Assumes the hardware has previously been reset
315daf9197cSJack F Vogel  *  and the transmitter and receiver are not enabled.
3168cfa0ad2SJack F Vogel  **/
e1000_setup_link_82542(struct e1000_hw * hw)3178cfa0ad2SJack F Vogel static s32 e1000_setup_link_82542(struct e1000_hw *hw)
3188cfa0ad2SJack F Vogel {
3198cfa0ad2SJack F Vogel 	struct e1000_mac_info *mac = &hw->mac;
320c80429ceSEric Joyner 	s32 ret_val;
3218cfa0ad2SJack F Vogel 
3228cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_setup_link_82542");
3238cfa0ad2SJack F Vogel 
3248cfa0ad2SJack F Vogel 	ret_val = e1000_set_default_fc_generic(hw);
3258cfa0ad2SJack F Vogel 	if (ret_val)
3268cfa0ad2SJack F Vogel 		goto out;
3278cfa0ad2SJack F Vogel 
328daf9197cSJack F Vogel 	hw->fc.requested_mode &= ~e1000_fc_tx_pause;
3298cfa0ad2SJack F Vogel 
33048600901SSean Bruno 	if (mac->report_tx_early)
331daf9197cSJack F Vogel 		hw->fc.requested_mode &= ~e1000_fc_rx_pause;
3328cfa0ad2SJack F Vogel 
3338cfa0ad2SJack F Vogel 	/*
334daf9197cSJack F Vogel 	 * Save off the requested flow control mode for use later.  Depending
335daf9197cSJack F Vogel 	 * on the link partner's capabilities, we may or may not use this mode.
3368cfa0ad2SJack F Vogel 	 */
337daf9197cSJack F Vogel 	hw->fc.current_mode = hw->fc.requested_mode;
3388cfa0ad2SJack F Vogel 
339daf9197cSJack F Vogel 	DEBUGOUT1("After fix-ups FlowControl is now = %x\n",
340daf9197cSJack F Vogel 		  hw->fc.current_mode);
3418cfa0ad2SJack F Vogel 
3428cfa0ad2SJack F Vogel 	/* Call the necessary subroutine to configure the link. */
3438cfa0ad2SJack F Vogel 	ret_val = mac->ops.setup_physical_interface(hw);
3448cfa0ad2SJack F Vogel 	if (ret_val)
3458cfa0ad2SJack F Vogel 		goto out;
3468cfa0ad2SJack F Vogel 
3478cfa0ad2SJack F Vogel 	/*
3488cfa0ad2SJack F Vogel 	 * Initialize the flow control address, type, and PAUSE timer
3498cfa0ad2SJack F Vogel 	 * registers to their default values.  This is done even if flow
3508cfa0ad2SJack F Vogel 	 * control is disabled, because it does not hurt anything to
3518cfa0ad2SJack F Vogel 	 * initialize these registers.
3528cfa0ad2SJack F Vogel 	 */
3538cfa0ad2SJack F Vogel 	DEBUGOUT("Initializing Flow Control address, type and timer regs\n");
3548cfa0ad2SJack F Vogel 
3558cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW);
3568cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH);
3578cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_FCT, FLOW_CONTROL_TYPE);
3588cfa0ad2SJack F Vogel 
3598cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time);
3608cfa0ad2SJack F Vogel 
3618cfa0ad2SJack F Vogel 	ret_val = e1000_set_fc_watermarks_generic(hw);
3628cfa0ad2SJack F Vogel 
3638cfa0ad2SJack F Vogel out:
3648cfa0ad2SJack F Vogel 	return ret_val;
3658cfa0ad2SJack F Vogel }
3668cfa0ad2SJack F Vogel 
3678cfa0ad2SJack F Vogel /**
3688cfa0ad2SJack F Vogel  *  e1000_led_on_82542 - Turn on SW controllable LED
3698cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
3708cfa0ad2SJack F Vogel  *
371daf9197cSJack F Vogel  *  Turns the SW defined LED on.
3728cfa0ad2SJack F Vogel  **/
e1000_led_on_82542(struct e1000_hw * hw)3738cfa0ad2SJack F Vogel static s32 e1000_led_on_82542(struct e1000_hw *hw)
3748cfa0ad2SJack F Vogel {
3758cfa0ad2SJack F Vogel 	u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
3768cfa0ad2SJack F Vogel 
3778cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_led_on_82542");
3788cfa0ad2SJack F Vogel 
3798cfa0ad2SJack F Vogel 	ctrl |= E1000_CTRL_SWDPIN0;
3808cfa0ad2SJack F Vogel 	ctrl |= E1000_CTRL_SWDPIO0;
3818cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
3828cfa0ad2SJack F Vogel 
3838cfa0ad2SJack F Vogel 	return E1000_SUCCESS;
3848cfa0ad2SJack F Vogel }
3858cfa0ad2SJack F Vogel 
3868cfa0ad2SJack F Vogel /**
3878cfa0ad2SJack F Vogel  *  e1000_led_off_82542 - Turn off SW controllable LED
3888cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
3898cfa0ad2SJack F Vogel  *
390daf9197cSJack F Vogel  *  Turns the SW defined LED off.
3918cfa0ad2SJack F Vogel  **/
e1000_led_off_82542(struct e1000_hw * hw)3928cfa0ad2SJack F Vogel static s32 e1000_led_off_82542(struct e1000_hw *hw)
3938cfa0ad2SJack F Vogel {
3948cfa0ad2SJack F Vogel 	u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
3958cfa0ad2SJack F Vogel 
3968cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_led_off_82542");
3978cfa0ad2SJack F Vogel 
3988cfa0ad2SJack F Vogel 	ctrl &= ~E1000_CTRL_SWDPIN0;
3998cfa0ad2SJack F Vogel 	ctrl |= E1000_CTRL_SWDPIO0;
4008cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
4018cfa0ad2SJack F Vogel 
4028cfa0ad2SJack F Vogel 	return E1000_SUCCESS;
4038cfa0ad2SJack F Vogel }
4048cfa0ad2SJack F Vogel 
4058cfa0ad2SJack F Vogel /**
4068cfa0ad2SJack F Vogel  *  e1000_rar_set_82542 - Set receive address register
4078cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
4088cfa0ad2SJack F Vogel  *  @addr: pointer to the receive address
4098cfa0ad2SJack F Vogel  *  @index: receive address array register
4108cfa0ad2SJack F Vogel  *
4118cfa0ad2SJack F Vogel  *  Sets the receive address array register at index to the address passed
4128cfa0ad2SJack F Vogel  *  in by addr.
4138cfa0ad2SJack F Vogel  **/
e1000_rar_set_82542(struct e1000_hw * hw,u8 * addr,u32 index)4148cc64f1eSJack F Vogel static int e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index)
4158cfa0ad2SJack F Vogel {
4168cfa0ad2SJack F Vogel 	u32 rar_low, rar_high;
4178cfa0ad2SJack F Vogel 
4188cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_rar_set_82542");
4198cfa0ad2SJack F Vogel 
4208cfa0ad2SJack F Vogel 	/*
4218cfa0ad2SJack F Vogel 	 * HW expects these in little endian so we reverse the byte order
4228cfa0ad2SJack F Vogel 	 * from network order (big endian) to little endian
4238cfa0ad2SJack F Vogel 	 */
42448600901SSean Bruno 	rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
4258cfa0ad2SJack F Vogel 		   ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
4268cfa0ad2SJack F Vogel 
4278cfa0ad2SJack F Vogel 	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
4288cfa0ad2SJack F Vogel 
4298cfa0ad2SJack F Vogel 	/* If MAC address zero, no need to set the AV bit */
430daf9197cSJack F Vogel 	if (rar_low || rar_high)
4318cfa0ad2SJack F Vogel 		rar_high |= E1000_RAH_AV;
4328cfa0ad2SJack F Vogel 
4338cfa0ad2SJack F Vogel 	E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low);
4348cfa0ad2SJack F Vogel 	E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high);
43548600901SSean Bruno 
4368cc64f1eSJack F Vogel 	return E1000_SUCCESS;
4378cfa0ad2SJack F Vogel }
4388cfa0ad2SJack F Vogel 
4398cfa0ad2SJack F Vogel /**
4408cfa0ad2SJack F Vogel  *  e1000_translate_register_82542 - Translate the proper register offset
4418cfa0ad2SJack F Vogel  *  @reg: e1000 register to be read
4428cfa0ad2SJack F Vogel  *
4438cfa0ad2SJack F Vogel  *  Registers in 82542 are located in different offsets than other adapters
4448cfa0ad2SJack F Vogel  *  even though they function in the same manner.  This function takes in
4458cfa0ad2SJack F Vogel  *  the name of the register to read and returns the correct offset for
4468cfa0ad2SJack F Vogel  *  82542 silicon.
4478cfa0ad2SJack F Vogel  **/
e1000_translate_register_82542(u32 reg)4488cfa0ad2SJack F Vogel u32 e1000_translate_register_82542(u32 reg)
4498cfa0ad2SJack F Vogel {
4508cfa0ad2SJack F Vogel 	/*
4518cfa0ad2SJack F Vogel 	 * Some of the 82542 registers are located at different
4528cfa0ad2SJack F Vogel 	 * offsets than they are in newer adapters.
4538cfa0ad2SJack F Vogel 	 * Despite the difference in location, the registers
4548cfa0ad2SJack F Vogel 	 * function in the same manner.
4558cfa0ad2SJack F Vogel 	 */
4568cfa0ad2SJack F Vogel 	switch (reg) {
4578cfa0ad2SJack F Vogel 	case E1000_RA:
4588cfa0ad2SJack F Vogel 		reg = 0x00040;
4598cfa0ad2SJack F Vogel 		break;
4608cfa0ad2SJack F Vogel 	case E1000_RDTR:
4618cfa0ad2SJack F Vogel 		reg = 0x00108;
4628cfa0ad2SJack F Vogel 		break;
4638cfa0ad2SJack F Vogel 	case E1000_RDBAL(0):
4648cfa0ad2SJack F Vogel 		reg = 0x00110;
4658cfa0ad2SJack F Vogel 		break;
4668cfa0ad2SJack F Vogel 	case E1000_RDBAH(0):
4678cfa0ad2SJack F Vogel 		reg = 0x00114;
4688cfa0ad2SJack F Vogel 		break;
4698cfa0ad2SJack F Vogel 	case E1000_RDLEN(0):
4708cfa0ad2SJack F Vogel 		reg = 0x00118;
4718cfa0ad2SJack F Vogel 		break;
4728cfa0ad2SJack F Vogel 	case E1000_RDH(0):
4738cfa0ad2SJack F Vogel 		reg = 0x00120;
4748cfa0ad2SJack F Vogel 		break;
4758cfa0ad2SJack F Vogel 	case E1000_RDT(0):
4768cfa0ad2SJack F Vogel 		reg = 0x00128;
4778cfa0ad2SJack F Vogel 		break;
4788cfa0ad2SJack F Vogel 	case E1000_RDBAL(1):
4798cfa0ad2SJack F Vogel 		reg = 0x00138;
4808cfa0ad2SJack F Vogel 		break;
4818cfa0ad2SJack F Vogel 	case E1000_RDBAH(1):
4828cfa0ad2SJack F Vogel 		reg = 0x0013C;
4838cfa0ad2SJack F Vogel 		break;
4848cfa0ad2SJack F Vogel 	case E1000_RDLEN(1):
4858cfa0ad2SJack F Vogel 		reg = 0x00140;
4868cfa0ad2SJack F Vogel 		break;
4878cfa0ad2SJack F Vogel 	case E1000_RDH(1):
4888cfa0ad2SJack F Vogel 		reg = 0x00148;
4898cfa0ad2SJack F Vogel 		break;
4908cfa0ad2SJack F Vogel 	case E1000_RDT(1):
4918cfa0ad2SJack F Vogel 		reg = 0x00150;
4928cfa0ad2SJack F Vogel 		break;
4938cfa0ad2SJack F Vogel 	case E1000_FCRTH:
4948cfa0ad2SJack F Vogel 		reg = 0x00160;
4958cfa0ad2SJack F Vogel 		break;
4968cfa0ad2SJack F Vogel 	case E1000_FCRTL:
4978cfa0ad2SJack F Vogel 		reg = 0x00168;
4988cfa0ad2SJack F Vogel 		break;
4998cfa0ad2SJack F Vogel 	case E1000_MTA:
5008cfa0ad2SJack F Vogel 		reg = 0x00200;
5018cfa0ad2SJack F Vogel 		break;
5028cfa0ad2SJack F Vogel 	case E1000_TDBAL(0):
5038cfa0ad2SJack F Vogel 		reg = 0x00420;
5048cfa0ad2SJack F Vogel 		break;
5058cfa0ad2SJack F Vogel 	case E1000_TDBAH(0):
5068cfa0ad2SJack F Vogel 		reg = 0x00424;
5078cfa0ad2SJack F Vogel 		break;
5088cfa0ad2SJack F Vogel 	case E1000_TDLEN(0):
5098cfa0ad2SJack F Vogel 		reg = 0x00428;
5108cfa0ad2SJack F Vogel 		break;
5118cfa0ad2SJack F Vogel 	case E1000_TDH(0):
5128cfa0ad2SJack F Vogel 		reg = 0x00430;
5138cfa0ad2SJack F Vogel 		break;
5148cfa0ad2SJack F Vogel 	case E1000_TDT(0):
5158cfa0ad2SJack F Vogel 		reg = 0x00438;
5168cfa0ad2SJack F Vogel 		break;
5178cfa0ad2SJack F Vogel 	case E1000_TIDV:
5188cfa0ad2SJack F Vogel 		reg = 0x00440;
5198cfa0ad2SJack F Vogel 		break;
5208cfa0ad2SJack F Vogel 	case E1000_VFTA:
5218cfa0ad2SJack F Vogel 		reg = 0x00600;
5228cfa0ad2SJack F Vogel 		break;
5238cfa0ad2SJack F Vogel 	case E1000_TDFH:
5248cfa0ad2SJack F Vogel 		reg = 0x08010;
5258cfa0ad2SJack F Vogel 		break;
5268cfa0ad2SJack F Vogel 	case E1000_TDFT:
5278cfa0ad2SJack F Vogel 		reg = 0x08018;
5288cfa0ad2SJack F Vogel 		break;
5298cfa0ad2SJack F Vogel 	default:
5308cfa0ad2SJack F Vogel 		break;
5318cfa0ad2SJack F Vogel 	}
5328cfa0ad2SJack F Vogel 
5338cfa0ad2SJack F Vogel 	return reg;
5348cfa0ad2SJack F Vogel }
5358cfa0ad2SJack F Vogel 
5368cfa0ad2SJack F Vogel /**
5378cfa0ad2SJack F Vogel  *  e1000_clear_hw_cntrs_82542 - Clear device specific hardware counters
5388cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
5398cfa0ad2SJack F Vogel  *
5408cfa0ad2SJack F Vogel  *  Clears the hardware counters by reading the counter registers.
5418cfa0ad2SJack F Vogel  **/
e1000_clear_hw_cntrs_82542(struct e1000_hw * hw)5428cfa0ad2SJack F Vogel static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw)
5438cfa0ad2SJack F Vogel {
5448cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_clear_hw_cntrs_82542");
5458cfa0ad2SJack F Vogel 
5468cfa0ad2SJack F Vogel 	e1000_clear_hw_cntrs_base_generic(hw);
5478cfa0ad2SJack F Vogel 
548daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC64);
549daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC127);
550daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC255);
551daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC511);
552daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC1023);
553daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC1522);
554daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC64);
555daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC127);
556daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC255);
557daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC511);
558daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC1023);
559daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC1522);
5608cfa0ad2SJack F Vogel }
56138537cb9SJack F Vogel 
56238537cb9SJack F Vogel /**
56338537cb9SJack F Vogel  *  e1000_read_mac_addr_82542 - Read device MAC address
56438537cb9SJack F Vogel  *  @hw: pointer to the HW structure
56538537cb9SJack F Vogel  *
56638537cb9SJack F Vogel  *  Reads the device MAC address from the EEPROM and stores the value.
56738537cb9SJack F Vogel  **/
e1000_read_mac_addr_82542(struct e1000_hw * hw)568c80429ceSEric Joyner s32 e1000_read_mac_addr_82542(struct e1000_hw *hw)
56938537cb9SJack F Vogel {
57038537cb9SJack F Vogel 	s32  ret_val = E1000_SUCCESS;
57138537cb9SJack F Vogel 	u16 offset, nvm_data, i;
57238537cb9SJack F Vogel 
57338537cb9SJack F Vogel 	DEBUGFUNC("e1000_read_mac_addr");
57438537cb9SJack F Vogel 
575e81998f4SEric Joyner 	for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
57638537cb9SJack F Vogel 		offset = i >> 1;
57738537cb9SJack F Vogel 		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
57838537cb9SJack F Vogel 		if (ret_val) {
57938537cb9SJack F Vogel 			DEBUGOUT("NVM Read Error\n");
58038537cb9SJack F Vogel 			goto out;
58138537cb9SJack F Vogel 		}
58238537cb9SJack F Vogel 		hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
58338537cb9SJack F Vogel 		hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
58438537cb9SJack F Vogel 	}
58538537cb9SJack F Vogel 
586e81998f4SEric Joyner 	for (i = 0; i < ETHER_ADDR_LEN; i++)
58738537cb9SJack F Vogel 		hw->mac.addr[i] = hw->mac.perm_addr[i];
58838537cb9SJack F Vogel 
58938537cb9SJack F Vogel out:
59038537cb9SJack F Vogel 	return ret_val;
59138537cb9SJack F Vogel }
592