xref: /titanic_51/usr/src/uts/common/io/e1000api/e1000_82542.c (revision 42cc51e07cdbcad3b9aca8d9d991fc09b251feb7)
175eba5b6SRobert Mustacchi /******************************************************************************
275eba5b6SRobert Mustacchi 
3*42cc51e0SRobert Mustacchi   Copyright (c) 2001-2015, Intel Corporation
475eba5b6SRobert Mustacchi   All rights reserved.
575eba5b6SRobert Mustacchi 
675eba5b6SRobert Mustacchi   Redistribution and use in source and binary forms, with or without
775eba5b6SRobert Mustacchi   modification, are permitted provided that the following conditions are met:
875eba5b6SRobert Mustacchi 
975eba5b6SRobert Mustacchi    1. Redistributions of source code must retain the above copyright notice,
1075eba5b6SRobert Mustacchi       this list of conditions and the following disclaimer.
1175eba5b6SRobert Mustacchi 
1275eba5b6SRobert Mustacchi    2. Redistributions in binary form must reproduce the above copyright
1375eba5b6SRobert Mustacchi       notice, this list of conditions and the following disclaimer in the
1475eba5b6SRobert Mustacchi       documentation and/or other materials provided with the distribution.
1575eba5b6SRobert Mustacchi 
1675eba5b6SRobert Mustacchi    3. Neither the name of the Intel Corporation nor the names of its
1775eba5b6SRobert Mustacchi       contributors may be used to endorse or promote products derived from
1875eba5b6SRobert Mustacchi       this software without specific prior written permission.
1975eba5b6SRobert Mustacchi 
2075eba5b6SRobert Mustacchi   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2175eba5b6SRobert Mustacchi   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2275eba5b6SRobert Mustacchi   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2375eba5b6SRobert Mustacchi   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2475eba5b6SRobert Mustacchi   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2575eba5b6SRobert Mustacchi   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2675eba5b6SRobert Mustacchi   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2775eba5b6SRobert Mustacchi   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2875eba5b6SRobert Mustacchi   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2975eba5b6SRobert Mustacchi   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3075eba5b6SRobert Mustacchi   POSSIBILITY OF SUCH DAMAGE.
3175eba5b6SRobert Mustacchi 
3275eba5b6SRobert Mustacchi ******************************************************************************/
3375eba5b6SRobert Mustacchi /*$FreeBSD$*/
3475eba5b6SRobert Mustacchi 
3575eba5b6SRobert Mustacchi /*
3675eba5b6SRobert Mustacchi  * 82542 Gigabit Ethernet Controller
3775eba5b6SRobert Mustacchi  */
3875eba5b6SRobert Mustacchi 
3975eba5b6SRobert Mustacchi #include "e1000_api.h"
4075eba5b6SRobert Mustacchi 
4175eba5b6SRobert Mustacchi static s32  e1000_init_phy_params_82542(struct e1000_hw *hw);
4275eba5b6SRobert Mustacchi static s32  e1000_init_nvm_params_82542(struct e1000_hw *hw);
4375eba5b6SRobert Mustacchi static s32  e1000_init_mac_params_82542(struct e1000_hw *hw);
4475eba5b6SRobert Mustacchi static s32  e1000_get_bus_info_82542(struct e1000_hw *hw);
4575eba5b6SRobert Mustacchi static s32  e1000_reset_hw_82542(struct e1000_hw *hw);
4675eba5b6SRobert Mustacchi static s32  e1000_init_hw_82542(struct e1000_hw *hw);
4775eba5b6SRobert Mustacchi static s32  e1000_setup_link_82542(struct e1000_hw *hw);
4875eba5b6SRobert Mustacchi static s32  e1000_led_on_82542(struct e1000_hw *hw);
4975eba5b6SRobert Mustacchi static s32  e1000_led_off_82542(struct e1000_hw *hw);
50c124a83eSRobert Mustacchi static int  e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index);
5175eba5b6SRobert Mustacchi static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw);
5275eba5b6SRobert Mustacchi static s32  e1000_read_mac_addr_82542(struct e1000_hw *hw);
5375eba5b6SRobert Mustacchi 
5475eba5b6SRobert Mustacchi /**
5575eba5b6SRobert Mustacchi  *  e1000_init_phy_params_82542 - Init PHY func ptrs.
5675eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
5775eba5b6SRobert Mustacchi  **/
5875eba5b6SRobert Mustacchi static s32 e1000_init_phy_params_82542(struct e1000_hw *hw)
5975eba5b6SRobert Mustacchi {
6075eba5b6SRobert Mustacchi 	struct e1000_phy_info *phy = &hw->phy;
6175eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
6275eba5b6SRobert Mustacchi 
6375eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_phy_params_82542");
6475eba5b6SRobert Mustacchi 
6575eba5b6SRobert Mustacchi 	phy->type = e1000_phy_none;
6675eba5b6SRobert Mustacchi 
6775eba5b6SRobert Mustacchi 	return ret_val;
6875eba5b6SRobert Mustacchi }
6975eba5b6SRobert Mustacchi 
7075eba5b6SRobert Mustacchi /**
7175eba5b6SRobert Mustacchi  *  e1000_init_nvm_params_82542 - Init NVM func ptrs.
7275eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
7375eba5b6SRobert Mustacchi  **/
7475eba5b6SRobert Mustacchi static s32 e1000_init_nvm_params_82542(struct e1000_hw *hw)
7575eba5b6SRobert Mustacchi {
7675eba5b6SRobert Mustacchi 	struct e1000_nvm_info *nvm = &hw->nvm;
7775eba5b6SRobert Mustacchi 
7875eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_nvm_params_82542");
7975eba5b6SRobert Mustacchi 
8075eba5b6SRobert Mustacchi 	nvm->address_bits	=  6;
8175eba5b6SRobert Mustacchi 	nvm->delay_usec		= 50;
8275eba5b6SRobert Mustacchi 	nvm->opcode_bits	=  3;
8375eba5b6SRobert Mustacchi 	nvm->type		= e1000_nvm_eeprom_microwire;
8475eba5b6SRobert Mustacchi 	nvm->word_size		= 64;
8575eba5b6SRobert Mustacchi 
8675eba5b6SRobert Mustacchi 	/* Function Pointers */
8775eba5b6SRobert Mustacchi 	nvm->ops.read		= e1000_read_nvm_microwire;
8875eba5b6SRobert Mustacchi 	nvm->ops.release	= e1000_stop_nvm;
8975eba5b6SRobert Mustacchi 	nvm->ops.write		= e1000_write_nvm_microwire;
9075eba5b6SRobert Mustacchi 	nvm->ops.update		= e1000_update_nvm_checksum_generic;
9175eba5b6SRobert Mustacchi 	nvm->ops.validate	= e1000_validate_nvm_checksum_generic;
9275eba5b6SRobert Mustacchi 
9375eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
9475eba5b6SRobert Mustacchi }
9575eba5b6SRobert Mustacchi 
9675eba5b6SRobert Mustacchi /**
9775eba5b6SRobert Mustacchi  *  e1000_init_mac_params_82542 - Init MAC func ptrs.
9875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
9975eba5b6SRobert Mustacchi  **/
10075eba5b6SRobert Mustacchi static s32 e1000_init_mac_params_82542(struct e1000_hw *hw)
10175eba5b6SRobert Mustacchi {
10275eba5b6SRobert Mustacchi 	struct e1000_mac_info *mac = &hw->mac;
10375eba5b6SRobert Mustacchi 
10475eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_mac_params_82542");
10575eba5b6SRobert Mustacchi 
10675eba5b6SRobert Mustacchi 	/* Set media type */
10775eba5b6SRobert Mustacchi 	hw->phy.media_type = e1000_media_type_fiber;
10875eba5b6SRobert Mustacchi 
10975eba5b6SRobert Mustacchi 	/* Set mta register count */
11075eba5b6SRobert Mustacchi 	mac->mta_reg_count = 128;
11175eba5b6SRobert Mustacchi 	/* Set rar entry count */
11275eba5b6SRobert Mustacchi 	mac->rar_entry_count = E1000_RAR_ENTRIES;
11375eba5b6SRobert Mustacchi 
11475eba5b6SRobert Mustacchi 	/* Function pointers */
11575eba5b6SRobert Mustacchi 
11675eba5b6SRobert Mustacchi 	/* bus type/speed/width */
11775eba5b6SRobert Mustacchi 	mac->ops.get_bus_info = e1000_get_bus_info_82542;
11875eba5b6SRobert Mustacchi 	/* function id */
11975eba5b6SRobert Mustacchi 	mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pci;
12075eba5b6SRobert Mustacchi 	/* reset */
12175eba5b6SRobert Mustacchi 	mac->ops.reset_hw = e1000_reset_hw_82542;
12275eba5b6SRobert Mustacchi 	/* hw initialization */
12375eba5b6SRobert Mustacchi 	mac->ops.init_hw = e1000_init_hw_82542;
12475eba5b6SRobert Mustacchi 	/* link setup */
12575eba5b6SRobert Mustacchi 	mac->ops.setup_link = e1000_setup_link_82542;
12675eba5b6SRobert Mustacchi 	/* phy/fiber/serdes setup */
127*42cc51e0SRobert Mustacchi 	mac->ops.setup_physical_interface =
128*42cc51e0SRobert Mustacchi 					e1000_setup_fiber_serdes_link_generic;
12975eba5b6SRobert Mustacchi 	/* check for link */
13075eba5b6SRobert Mustacchi 	mac->ops.check_for_link = e1000_check_for_fiber_link_generic;
13175eba5b6SRobert Mustacchi 	/* multicast address update */
13275eba5b6SRobert Mustacchi 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
13375eba5b6SRobert Mustacchi 	/* writing VFTA */
13475eba5b6SRobert Mustacchi 	mac->ops.write_vfta = e1000_write_vfta_generic;
13575eba5b6SRobert Mustacchi 	/* clearing VFTA */
13675eba5b6SRobert Mustacchi 	mac->ops.clear_vfta = e1000_clear_vfta_generic;
13775eba5b6SRobert Mustacchi 	/* read mac address */
13875eba5b6SRobert Mustacchi 	mac->ops.read_mac_addr = e1000_read_mac_addr_82542;
13975eba5b6SRobert Mustacchi 	/* set RAR */
14075eba5b6SRobert Mustacchi 	mac->ops.rar_set = e1000_rar_set_82542;
14175eba5b6SRobert Mustacchi 	/* turn on/off LED */
14275eba5b6SRobert Mustacchi 	mac->ops.led_on = e1000_led_on_82542;
14375eba5b6SRobert Mustacchi 	mac->ops.led_off = e1000_led_off_82542;
14475eba5b6SRobert Mustacchi 	/* clear hardware counters */
14575eba5b6SRobert Mustacchi 	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82542;
14675eba5b6SRobert Mustacchi 	/* link info */
147*42cc51e0SRobert Mustacchi 	mac->ops.get_link_up_info =
148*42cc51e0SRobert Mustacchi 				e1000_get_speed_and_duplex_fiber_serdes_generic;
14975eba5b6SRobert Mustacchi 
15075eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
15175eba5b6SRobert Mustacchi }
15275eba5b6SRobert Mustacchi 
15375eba5b6SRobert Mustacchi /**
15475eba5b6SRobert Mustacchi  *  e1000_init_function_pointers_82542 - Init func ptrs.
15575eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
15675eba5b6SRobert Mustacchi  *
15775eba5b6SRobert Mustacchi  *  Called to initialize all function pointers and parameters.
15875eba5b6SRobert Mustacchi  **/
15975eba5b6SRobert Mustacchi void e1000_init_function_pointers_82542(struct e1000_hw *hw)
16075eba5b6SRobert Mustacchi {
16175eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_function_pointers_82542");
16275eba5b6SRobert Mustacchi 
16375eba5b6SRobert Mustacchi 	hw->mac.ops.init_params = e1000_init_mac_params_82542;
16475eba5b6SRobert Mustacchi 	hw->nvm.ops.init_params = e1000_init_nvm_params_82542;
16575eba5b6SRobert Mustacchi 	hw->phy.ops.init_params = e1000_init_phy_params_82542;
16675eba5b6SRobert Mustacchi }
16775eba5b6SRobert Mustacchi 
16875eba5b6SRobert Mustacchi /**
16975eba5b6SRobert Mustacchi  *  e1000_get_bus_info_82542 - Obtain bus information for adapter
17075eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
17175eba5b6SRobert Mustacchi  *
17275eba5b6SRobert Mustacchi  *  This will obtain information about the HW bus for which the
17375eba5b6SRobert Mustacchi  *  adapter is attached and stores it in the hw structure.
17475eba5b6SRobert Mustacchi  **/
17575eba5b6SRobert Mustacchi static s32 e1000_get_bus_info_82542(struct e1000_hw *hw)
17675eba5b6SRobert Mustacchi {
17775eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_get_bus_info_82542");
17875eba5b6SRobert Mustacchi 
17975eba5b6SRobert Mustacchi 	hw->bus.type = e1000_bus_type_pci;
18075eba5b6SRobert Mustacchi 	hw->bus.speed = e1000_bus_speed_unknown;
18175eba5b6SRobert Mustacchi 	hw->bus.width = e1000_bus_width_unknown;
18275eba5b6SRobert Mustacchi 
18375eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
18475eba5b6SRobert Mustacchi }
18575eba5b6SRobert Mustacchi 
18675eba5b6SRobert Mustacchi /**
18775eba5b6SRobert Mustacchi  *  e1000_reset_hw_82542 - Reset hardware
18875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
18975eba5b6SRobert Mustacchi  *
19075eba5b6SRobert Mustacchi  *  This resets the hardware into a known state.
19175eba5b6SRobert Mustacchi  **/
19275eba5b6SRobert Mustacchi static s32 e1000_reset_hw_82542(struct e1000_hw *hw)
19375eba5b6SRobert Mustacchi {
19475eba5b6SRobert Mustacchi 	struct e1000_bus_info *bus = &hw->bus;
19575eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
19675eba5b6SRobert Mustacchi 	u32 ctrl;
19775eba5b6SRobert Mustacchi 
19875eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_reset_hw_82542");
19975eba5b6SRobert Mustacchi 
20075eba5b6SRobert Mustacchi 	if (hw->revision_id == E1000_REVISION_2) {
20175eba5b6SRobert Mustacchi 		DEBUGOUT("Disabling MWI on 82542 rev 2\n");
20275eba5b6SRobert Mustacchi 		e1000_pci_clear_mwi(hw);
20375eba5b6SRobert Mustacchi 	}
20475eba5b6SRobert Mustacchi 
20575eba5b6SRobert Mustacchi 	DEBUGOUT("Masking off all interrupts\n");
20675eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
20775eba5b6SRobert Mustacchi 
20875eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
20975eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
21075eba5b6SRobert Mustacchi 	E1000_WRITE_FLUSH(hw);
21175eba5b6SRobert Mustacchi 
21275eba5b6SRobert Mustacchi 	/*
21375eba5b6SRobert Mustacchi 	 * Delay to allow any outstanding PCI transactions to complete before
21475eba5b6SRobert Mustacchi 	 * resetting the device
21575eba5b6SRobert Mustacchi 	 */
21675eba5b6SRobert Mustacchi 	msec_delay(10);
21775eba5b6SRobert Mustacchi 
21875eba5b6SRobert Mustacchi 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
21975eba5b6SRobert Mustacchi 
22075eba5b6SRobert Mustacchi 	DEBUGOUT("Issuing a global reset to 82542/82543 MAC\n");
22175eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
22275eba5b6SRobert Mustacchi 
22375eba5b6SRobert Mustacchi 	hw->nvm.ops.reload(hw);
22475eba5b6SRobert Mustacchi 	msec_delay(2);
22575eba5b6SRobert Mustacchi 
22675eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
22775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_ICR);
22875eba5b6SRobert Mustacchi 
22975eba5b6SRobert Mustacchi 	if (hw->revision_id == E1000_REVISION_2) {
23075eba5b6SRobert Mustacchi 		if (bus->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
23175eba5b6SRobert Mustacchi 			e1000_pci_set_mwi(hw);
23275eba5b6SRobert Mustacchi 	}
23375eba5b6SRobert Mustacchi 
23475eba5b6SRobert Mustacchi 	return ret_val;
23575eba5b6SRobert Mustacchi }
23675eba5b6SRobert Mustacchi 
23775eba5b6SRobert Mustacchi /**
23875eba5b6SRobert Mustacchi  *  e1000_init_hw_82542 - Initialize hardware
23975eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
24075eba5b6SRobert Mustacchi  *
24175eba5b6SRobert Mustacchi  *  This inits the hardware readying it for operation.
24275eba5b6SRobert Mustacchi  **/
24375eba5b6SRobert Mustacchi static s32 e1000_init_hw_82542(struct e1000_hw *hw)
24475eba5b6SRobert Mustacchi {
24575eba5b6SRobert Mustacchi 	struct e1000_mac_info *mac = &hw->mac;
24675eba5b6SRobert Mustacchi 	struct e1000_dev_spec_82542 *dev_spec = &hw->dev_spec._82542;
24775eba5b6SRobert Mustacchi 	s32 ret_val = E1000_SUCCESS;
24875eba5b6SRobert Mustacchi 	u32 ctrl;
24975eba5b6SRobert Mustacchi 	u16 i;
25075eba5b6SRobert Mustacchi 
25175eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_init_hw_82542");
25275eba5b6SRobert Mustacchi 
25375eba5b6SRobert Mustacchi 	/* Disabling VLAN filtering */
25475eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_VET, 0);
25575eba5b6SRobert Mustacchi 	mac->ops.clear_vfta(hw);
25675eba5b6SRobert Mustacchi 
25775eba5b6SRobert Mustacchi 	/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
25875eba5b6SRobert Mustacchi 	if (hw->revision_id == E1000_REVISION_2) {
25975eba5b6SRobert Mustacchi 		DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
26075eba5b6SRobert Mustacchi 		e1000_pci_clear_mwi(hw);
26175eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_RCTL, E1000_RCTL_RST);
26275eba5b6SRobert Mustacchi 		E1000_WRITE_FLUSH(hw);
26375eba5b6SRobert Mustacchi 		msec_delay(5);
26475eba5b6SRobert Mustacchi 	}
26575eba5b6SRobert Mustacchi 
26675eba5b6SRobert Mustacchi 	/* Setup the receive address. */
26775eba5b6SRobert Mustacchi 	e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
26875eba5b6SRobert Mustacchi 
26975eba5b6SRobert Mustacchi 	/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
27075eba5b6SRobert Mustacchi 	if (hw->revision_id == E1000_REVISION_2) {
27175eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_RCTL, 0);
27275eba5b6SRobert Mustacchi 		E1000_WRITE_FLUSH(hw);
27375eba5b6SRobert Mustacchi 		msec_delay(1);
27475eba5b6SRobert Mustacchi 		if (hw->bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
27575eba5b6SRobert Mustacchi 			e1000_pci_set_mwi(hw);
27675eba5b6SRobert Mustacchi 	}
27775eba5b6SRobert Mustacchi 
27875eba5b6SRobert Mustacchi 	/* Zero out the Multicast HASH table */
27975eba5b6SRobert Mustacchi 	DEBUGOUT("Zeroing the MTA\n");
28075eba5b6SRobert Mustacchi 	for (i = 0; i < mac->mta_reg_count; i++)
28175eba5b6SRobert Mustacchi 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
28275eba5b6SRobert Mustacchi 
28375eba5b6SRobert Mustacchi 	/*
28475eba5b6SRobert Mustacchi 	 * Set the PCI priority bit correctly in the CTRL register.  This
28575eba5b6SRobert Mustacchi 	 * determines if the adapter gives priority to receives, or if it
28675eba5b6SRobert Mustacchi 	 * gives equal priority to transmits and receives.
28775eba5b6SRobert Mustacchi 	 */
28875eba5b6SRobert Mustacchi 	if (dev_spec->dma_fairness) {
28975eba5b6SRobert Mustacchi 		ctrl = E1000_READ_REG(hw, E1000_CTRL);
29075eba5b6SRobert Mustacchi 		E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PRIOR);
29175eba5b6SRobert Mustacchi 	}
29275eba5b6SRobert Mustacchi 
29375eba5b6SRobert Mustacchi 	/* Setup link and flow control */
29475eba5b6SRobert Mustacchi 	ret_val = e1000_setup_link_82542(hw);
29575eba5b6SRobert Mustacchi 
29675eba5b6SRobert Mustacchi 	/*
29775eba5b6SRobert Mustacchi 	 * Clear all of the statistics registers (clear on read).  It is
29875eba5b6SRobert Mustacchi 	 * important that we do this after we have tried to establish link
29975eba5b6SRobert Mustacchi 	 * because the symbol error count will increment wildly if there
30075eba5b6SRobert Mustacchi 	 * is no link.
30175eba5b6SRobert Mustacchi 	 */
30275eba5b6SRobert Mustacchi 	e1000_clear_hw_cntrs_82542(hw);
30375eba5b6SRobert Mustacchi 
30475eba5b6SRobert Mustacchi 	return ret_val;
30575eba5b6SRobert Mustacchi }
30675eba5b6SRobert Mustacchi 
30775eba5b6SRobert Mustacchi /**
30875eba5b6SRobert Mustacchi  *  e1000_setup_link_82542 - Setup flow control and link settings
30975eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
31075eba5b6SRobert Mustacchi  *
31175eba5b6SRobert Mustacchi  *  Determines which flow control settings to use, then configures flow
31275eba5b6SRobert Mustacchi  *  control.  Calls the appropriate media-specific link configuration
31375eba5b6SRobert Mustacchi  *  function.  Assuming the adapter has a valid link partner, a valid link
31475eba5b6SRobert Mustacchi  *  should be established.  Assumes the hardware has previously been reset
31575eba5b6SRobert Mustacchi  *  and the transmitter and receiver are not enabled.
31675eba5b6SRobert Mustacchi  **/
31775eba5b6SRobert Mustacchi static s32 e1000_setup_link_82542(struct e1000_hw *hw)
31875eba5b6SRobert Mustacchi {
31975eba5b6SRobert Mustacchi 	struct e1000_mac_info *mac = &hw->mac;
320*42cc51e0SRobert Mustacchi 	s32 ret_val;
32175eba5b6SRobert Mustacchi 
32275eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_setup_link_82542");
32375eba5b6SRobert Mustacchi 
32475eba5b6SRobert Mustacchi 	ret_val = e1000_set_default_fc_generic(hw);
32575eba5b6SRobert Mustacchi 	if (ret_val)
32675eba5b6SRobert Mustacchi 		goto out;
32775eba5b6SRobert Mustacchi 
32875eba5b6SRobert Mustacchi 	hw->fc.requested_mode &= ~e1000_fc_tx_pause;
32975eba5b6SRobert Mustacchi 
330*42cc51e0SRobert Mustacchi 	if (mac->report_tx_early)
33175eba5b6SRobert Mustacchi 		hw->fc.requested_mode &= ~e1000_fc_rx_pause;
33275eba5b6SRobert Mustacchi 
33375eba5b6SRobert Mustacchi 	/*
33475eba5b6SRobert Mustacchi 	 * Save off the requested flow control mode for use later.  Depending
33575eba5b6SRobert Mustacchi 	 * on the link partner's capabilities, we may or may not use this mode.
33675eba5b6SRobert Mustacchi 	 */
33775eba5b6SRobert Mustacchi 	hw->fc.current_mode = hw->fc.requested_mode;
33875eba5b6SRobert Mustacchi 
33975eba5b6SRobert Mustacchi 	DEBUGOUT1("After fix-ups FlowControl is now = %x\n",
34075eba5b6SRobert Mustacchi 		  hw->fc.current_mode);
34175eba5b6SRobert Mustacchi 
34275eba5b6SRobert Mustacchi 	/* Call the necessary subroutine to configure the link. */
34375eba5b6SRobert Mustacchi 	ret_val = mac->ops.setup_physical_interface(hw);
34475eba5b6SRobert Mustacchi 	if (ret_val)
34575eba5b6SRobert Mustacchi 		goto out;
34675eba5b6SRobert Mustacchi 
34775eba5b6SRobert Mustacchi 	/*
34875eba5b6SRobert Mustacchi 	 * Initialize the flow control address, type, and PAUSE timer
34975eba5b6SRobert Mustacchi 	 * registers to their default values.  This is done even if flow
35075eba5b6SRobert Mustacchi 	 * control is disabled, because it does not hurt anything to
35175eba5b6SRobert Mustacchi 	 * initialize these registers.
35275eba5b6SRobert Mustacchi 	 */
35375eba5b6SRobert Mustacchi 	DEBUGOUT("Initializing Flow Control address, type and timer regs\n");
35475eba5b6SRobert Mustacchi 
35575eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW);
35675eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH);
35775eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_FCT, FLOW_CONTROL_TYPE);
35875eba5b6SRobert Mustacchi 
35975eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time);
36075eba5b6SRobert Mustacchi 
36175eba5b6SRobert Mustacchi 	ret_val = e1000_set_fc_watermarks_generic(hw);
36275eba5b6SRobert Mustacchi 
36375eba5b6SRobert Mustacchi out:
36475eba5b6SRobert Mustacchi 	return ret_val;
36575eba5b6SRobert Mustacchi }
36675eba5b6SRobert Mustacchi 
36775eba5b6SRobert Mustacchi /**
36875eba5b6SRobert Mustacchi  *  e1000_led_on_82542 - Turn on SW controllable LED
36975eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
37075eba5b6SRobert Mustacchi  *
37175eba5b6SRobert Mustacchi  *  Turns the SW defined LED on.
37275eba5b6SRobert Mustacchi  **/
37375eba5b6SRobert Mustacchi static s32 e1000_led_on_82542(struct e1000_hw *hw)
37475eba5b6SRobert Mustacchi {
37575eba5b6SRobert Mustacchi 	u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
37675eba5b6SRobert Mustacchi 
37775eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_led_on_82542");
37875eba5b6SRobert Mustacchi 
37975eba5b6SRobert Mustacchi 	ctrl |= E1000_CTRL_SWDPIN0;
38075eba5b6SRobert Mustacchi 	ctrl |= E1000_CTRL_SWDPIO0;
38175eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
38275eba5b6SRobert Mustacchi 
38375eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
38475eba5b6SRobert Mustacchi }
38575eba5b6SRobert Mustacchi 
38675eba5b6SRobert Mustacchi /**
38775eba5b6SRobert Mustacchi  *  e1000_led_off_82542 - Turn off SW controllable LED
38875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
38975eba5b6SRobert Mustacchi  *
39075eba5b6SRobert Mustacchi  *  Turns the SW defined LED off.
39175eba5b6SRobert Mustacchi  **/
39275eba5b6SRobert Mustacchi static s32 e1000_led_off_82542(struct e1000_hw *hw)
39375eba5b6SRobert Mustacchi {
39475eba5b6SRobert Mustacchi 	u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
39575eba5b6SRobert Mustacchi 
39675eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_led_off_82542");
39775eba5b6SRobert Mustacchi 
39875eba5b6SRobert Mustacchi 	ctrl &= ~E1000_CTRL_SWDPIN0;
39975eba5b6SRobert Mustacchi 	ctrl |= E1000_CTRL_SWDPIO0;
40075eba5b6SRobert Mustacchi 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
40175eba5b6SRobert Mustacchi 
40275eba5b6SRobert Mustacchi 	return E1000_SUCCESS;
40375eba5b6SRobert Mustacchi }
40475eba5b6SRobert Mustacchi 
40575eba5b6SRobert Mustacchi /**
40675eba5b6SRobert Mustacchi  *  e1000_rar_set_82542 - Set receive address register
40775eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
40875eba5b6SRobert Mustacchi  *  @addr: pointer to the receive address
40975eba5b6SRobert Mustacchi  *  @index: receive address array register
41075eba5b6SRobert Mustacchi  *
41175eba5b6SRobert Mustacchi  *  Sets the receive address array register at index to the address passed
41275eba5b6SRobert Mustacchi  *  in by addr.
41375eba5b6SRobert Mustacchi  **/
414c124a83eSRobert Mustacchi static int e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index)
41575eba5b6SRobert Mustacchi {
41675eba5b6SRobert Mustacchi 	u32 rar_low, rar_high;
41775eba5b6SRobert Mustacchi 
41875eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_rar_set_82542");
41975eba5b6SRobert Mustacchi 
42075eba5b6SRobert Mustacchi 	/*
42175eba5b6SRobert Mustacchi 	 * HW expects these in little endian so we reverse the byte order
42275eba5b6SRobert Mustacchi 	 * from network order (big endian) to little endian
42375eba5b6SRobert Mustacchi 	 */
424*42cc51e0SRobert Mustacchi 	rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
42575eba5b6SRobert Mustacchi 		   ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
42675eba5b6SRobert Mustacchi 
42775eba5b6SRobert Mustacchi 	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
42875eba5b6SRobert Mustacchi 
42975eba5b6SRobert Mustacchi 	/* If MAC address zero, no need to set the AV bit */
43075eba5b6SRobert Mustacchi 	if (rar_low || rar_high)
43175eba5b6SRobert Mustacchi 		rar_high |= E1000_RAH_AV;
43275eba5b6SRobert Mustacchi 
43375eba5b6SRobert Mustacchi 	E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low);
43475eba5b6SRobert Mustacchi 	E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high);
435*42cc51e0SRobert Mustacchi 
436c124a83eSRobert Mustacchi 	return E1000_SUCCESS;
43775eba5b6SRobert Mustacchi }
43875eba5b6SRobert Mustacchi 
43975eba5b6SRobert Mustacchi /**
44075eba5b6SRobert Mustacchi  *  e1000_translate_register_82542 - Translate the proper register offset
44175eba5b6SRobert Mustacchi  *  @reg: e1000 register to be read
44275eba5b6SRobert Mustacchi  *
44375eba5b6SRobert Mustacchi  *  Registers in 82542 are located in different offsets than other adapters
44475eba5b6SRobert Mustacchi  *  even though they function in the same manner.  This function takes in
44575eba5b6SRobert Mustacchi  *  the name of the register to read and returns the correct offset for
44675eba5b6SRobert Mustacchi  *  82542 silicon.
44775eba5b6SRobert Mustacchi  **/
44875eba5b6SRobert Mustacchi u32 e1000_translate_register_82542(u32 reg)
44975eba5b6SRobert Mustacchi {
45075eba5b6SRobert Mustacchi 	/*
45175eba5b6SRobert Mustacchi 	 * Some of the 82542 registers are located at different
45275eba5b6SRobert Mustacchi 	 * offsets than they are in newer adapters.
45375eba5b6SRobert Mustacchi 	 * Despite the difference in location, the registers
45475eba5b6SRobert Mustacchi 	 * function in the same manner.
45575eba5b6SRobert Mustacchi 	 */
45675eba5b6SRobert Mustacchi 	switch (reg) {
45775eba5b6SRobert Mustacchi 	case E1000_RA:
45875eba5b6SRobert Mustacchi 		reg = 0x00040;
45975eba5b6SRobert Mustacchi 		break;
46075eba5b6SRobert Mustacchi 	case E1000_RDTR:
46175eba5b6SRobert Mustacchi 		reg = 0x00108;
46275eba5b6SRobert Mustacchi 		break;
46375eba5b6SRobert Mustacchi 	case E1000_RDBAL(0):
46475eba5b6SRobert Mustacchi 		reg = 0x00110;
46575eba5b6SRobert Mustacchi 		break;
46675eba5b6SRobert Mustacchi 	case E1000_RDBAH(0):
46775eba5b6SRobert Mustacchi 		reg = 0x00114;
46875eba5b6SRobert Mustacchi 		break;
46975eba5b6SRobert Mustacchi 	case E1000_RDLEN(0):
47075eba5b6SRobert Mustacchi 		reg = 0x00118;
47175eba5b6SRobert Mustacchi 		break;
47275eba5b6SRobert Mustacchi 	case E1000_RDH(0):
47375eba5b6SRobert Mustacchi 		reg = 0x00120;
47475eba5b6SRobert Mustacchi 		break;
47575eba5b6SRobert Mustacchi 	case E1000_RDT(0):
47675eba5b6SRobert Mustacchi 		reg = 0x00128;
47775eba5b6SRobert Mustacchi 		break;
47875eba5b6SRobert Mustacchi 	case E1000_RDBAL(1):
47975eba5b6SRobert Mustacchi 		reg = 0x00138;
48075eba5b6SRobert Mustacchi 		break;
48175eba5b6SRobert Mustacchi 	case E1000_RDBAH(1):
48275eba5b6SRobert Mustacchi 		reg = 0x0013C;
48375eba5b6SRobert Mustacchi 		break;
48475eba5b6SRobert Mustacchi 	case E1000_RDLEN(1):
48575eba5b6SRobert Mustacchi 		reg = 0x00140;
48675eba5b6SRobert Mustacchi 		break;
48775eba5b6SRobert Mustacchi 	case E1000_RDH(1):
48875eba5b6SRobert Mustacchi 		reg = 0x00148;
48975eba5b6SRobert Mustacchi 		break;
49075eba5b6SRobert Mustacchi 	case E1000_RDT(1):
49175eba5b6SRobert Mustacchi 		reg = 0x00150;
49275eba5b6SRobert Mustacchi 		break;
49375eba5b6SRobert Mustacchi 	case E1000_FCRTH:
49475eba5b6SRobert Mustacchi 		reg = 0x00160;
49575eba5b6SRobert Mustacchi 		break;
49675eba5b6SRobert Mustacchi 	case E1000_FCRTL:
49775eba5b6SRobert Mustacchi 		reg = 0x00168;
49875eba5b6SRobert Mustacchi 		break;
49975eba5b6SRobert Mustacchi 	case E1000_MTA:
50075eba5b6SRobert Mustacchi 		reg = 0x00200;
50175eba5b6SRobert Mustacchi 		break;
50275eba5b6SRobert Mustacchi 	case E1000_TDBAL(0):
50375eba5b6SRobert Mustacchi 		reg = 0x00420;
50475eba5b6SRobert Mustacchi 		break;
50575eba5b6SRobert Mustacchi 	case E1000_TDBAH(0):
50675eba5b6SRobert Mustacchi 		reg = 0x00424;
50775eba5b6SRobert Mustacchi 		break;
50875eba5b6SRobert Mustacchi 	case E1000_TDLEN(0):
50975eba5b6SRobert Mustacchi 		reg = 0x00428;
51075eba5b6SRobert Mustacchi 		break;
51175eba5b6SRobert Mustacchi 	case E1000_TDH(0):
51275eba5b6SRobert Mustacchi 		reg = 0x00430;
51375eba5b6SRobert Mustacchi 		break;
51475eba5b6SRobert Mustacchi 	case E1000_TDT(0):
51575eba5b6SRobert Mustacchi 		reg = 0x00438;
51675eba5b6SRobert Mustacchi 		break;
51775eba5b6SRobert Mustacchi 	case E1000_TIDV:
51875eba5b6SRobert Mustacchi 		reg = 0x00440;
51975eba5b6SRobert Mustacchi 		break;
52075eba5b6SRobert Mustacchi 	case E1000_VFTA:
52175eba5b6SRobert Mustacchi 		reg = 0x00600;
52275eba5b6SRobert Mustacchi 		break;
52375eba5b6SRobert Mustacchi 	case E1000_TDFH:
52475eba5b6SRobert Mustacchi 		reg = 0x08010;
52575eba5b6SRobert Mustacchi 		break;
52675eba5b6SRobert Mustacchi 	case E1000_TDFT:
52775eba5b6SRobert Mustacchi 		reg = 0x08018;
52875eba5b6SRobert Mustacchi 		break;
52975eba5b6SRobert Mustacchi 	default:
53075eba5b6SRobert Mustacchi 		break;
53175eba5b6SRobert Mustacchi 	}
53275eba5b6SRobert Mustacchi 
53375eba5b6SRobert Mustacchi 	return reg;
53475eba5b6SRobert Mustacchi }
53575eba5b6SRobert Mustacchi 
53675eba5b6SRobert Mustacchi /**
53775eba5b6SRobert Mustacchi  *  e1000_clear_hw_cntrs_82542 - Clear device specific hardware counters
53875eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
53975eba5b6SRobert Mustacchi  *
54075eba5b6SRobert Mustacchi  *  Clears the hardware counters by reading the counter registers.
54175eba5b6SRobert Mustacchi  **/
54275eba5b6SRobert Mustacchi static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw)
54375eba5b6SRobert Mustacchi {
54475eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_clear_hw_cntrs_82542");
54575eba5b6SRobert Mustacchi 
54675eba5b6SRobert Mustacchi 	e1000_clear_hw_cntrs_base_generic(hw);
54775eba5b6SRobert Mustacchi 
54875eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC64);
54975eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC127);
55075eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC255);
55175eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC511);
55275eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC1023);
55375eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PRC1522);
55475eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC64);
55575eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC127);
55675eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC255);
55775eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC511);
55875eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC1023);
55975eba5b6SRobert Mustacchi 	E1000_READ_REG(hw, E1000_PTC1522);
56075eba5b6SRobert Mustacchi }
56175eba5b6SRobert Mustacchi 
56275eba5b6SRobert Mustacchi /**
56375eba5b6SRobert Mustacchi  *  e1000_read_mac_addr_82542 - Read device MAC address
56475eba5b6SRobert Mustacchi  *  @hw: pointer to the HW structure
56575eba5b6SRobert Mustacchi  *
56675eba5b6SRobert Mustacchi  *  Reads the device MAC address from the EEPROM and stores the value.
56775eba5b6SRobert Mustacchi  **/
568*42cc51e0SRobert Mustacchi s32 e1000_read_mac_addr_82542(struct e1000_hw *hw)
56975eba5b6SRobert Mustacchi {
57075eba5b6SRobert Mustacchi 	s32  ret_val = E1000_SUCCESS;
57175eba5b6SRobert Mustacchi 	u16 offset, nvm_data, i;
57275eba5b6SRobert Mustacchi 
57375eba5b6SRobert Mustacchi 	DEBUGFUNC("e1000_read_mac_addr");
57475eba5b6SRobert Mustacchi 
57575eba5b6SRobert Mustacchi 	for (i = 0; i < ETH_ADDR_LEN; i += 2) {
57675eba5b6SRobert Mustacchi 		offset = i >> 1;
57775eba5b6SRobert Mustacchi 		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
57875eba5b6SRobert Mustacchi 		if (ret_val) {
57975eba5b6SRobert Mustacchi 			DEBUGOUT("NVM Read Error\n");
58075eba5b6SRobert Mustacchi 			goto out;
58175eba5b6SRobert Mustacchi 		}
58275eba5b6SRobert Mustacchi 		hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
58375eba5b6SRobert Mustacchi 		hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
58475eba5b6SRobert Mustacchi 	}
58575eba5b6SRobert Mustacchi 
58675eba5b6SRobert Mustacchi 	for (i = 0; i < ETH_ADDR_LEN; i++)
58775eba5b6SRobert Mustacchi 		hw->mac.addr[i] = hw->mac.perm_addr[i];
58875eba5b6SRobert Mustacchi 
58975eba5b6SRobert Mustacchi out:
59075eba5b6SRobert Mustacchi 	return ret_val;
59175eba5b6SRobert Mustacchi }
592