e1000_80003es2lan.c revision 200243
1177867Sjfv/******************************************************************************
2169240Sjfv
3190872Sjfv  Copyright (c) 2001-2009, Intel Corporation
4169240Sjfv  All rights reserved.
5169240Sjfv
6169240Sjfv  Redistribution and use in source and binary forms, with or without
7169240Sjfv  modification, are permitted provided that the following conditions are met:
8169240Sjfv
9169240Sjfv   1. Redistributions of source code must retain the above copyright notice,
10169240Sjfv      this list of conditions and the following disclaimer.
11169240Sjfv
12169240Sjfv   2. Redistributions in binary form must reproduce the above copyright
13169240Sjfv      notice, this list of conditions and the following disclaimer in the
14169240Sjfv      documentation and/or other materials provided with the distribution.
15169240Sjfv
16169240Sjfv   3. Neither the name of the Intel Corporation nor the names of its
17169240Sjfv      contributors may be used to endorse or promote products derived from
18169240Sjfv      this software without specific prior written permission.
19169240Sjfv
20169240Sjfv  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21169240Sjfv  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22169240Sjfv  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23169240Sjfv  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24169240Sjfv  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25169240Sjfv  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26169240Sjfv  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27169240Sjfv  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28169240Sjfv  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29169240Sjfv  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30169240Sjfv  POSSIBILITY OF SUCH DAMAGE.
31169240Sjfv
32177867Sjfv******************************************************************************/
33177867Sjfv/*$FreeBSD: head/sys/dev/e1000/e1000_80003es2lan.c 200243 2009-12-08 01:07:44Z jfv $*/
34169240Sjfv
35185353Sjfv/*
36185353Sjfv * 80003ES2LAN Gigabit Ethernet Controller (Copper)
37185353Sjfv * 80003ES2LAN Gigabit Ethernet Controller (Serdes)
38169240Sjfv */
39169240Sjfv
40169589Sjfv#include "e1000_api.h"
41169240Sjfv
42177867Sjfvstatic s32  e1000_init_phy_params_80003es2lan(struct e1000_hw *hw);
43177867Sjfvstatic s32  e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw);
44177867Sjfvstatic s32  e1000_init_mac_params_80003es2lan(struct e1000_hw *hw);
45177867Sjfvstatic s32  e1000_acquire_phy_80003es2lan(struct e1000_hw *hw);
46177867Sjfvstatic void e1000_release_phy_80003es2lan(struct e1000_hw *hw);
47177867Sjfvstatic s32  e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw);
48177867Sjfvstatic void e1000_release_nvm_80003es2lan(struct e1000_hw *hw);
49177867Sjfvstatic s32  e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
50169240Sjfv                                                   u32 offset,
51169240Sjfv                                                   u16 *data);
52177867Sjfvstatic s32  e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
53169240Sjfv                                                    u32 offset,
54169240Sjfv                                                    u16 data);
55177867Sjfvstatic s32  e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset,
56169240Sjfv                                        u16 words, u16 *data);
57177867Sjfvstatic s32  e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw);
58177867Sjfvstatic s32  e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw);
59177867Sjfvstatic s32  e1000_get_cable_length_80003es2lan(struct e1000_hw *hw);
60177867Sjfvstatic s32  e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
61169240Sjfv                                               u16 *duplex);
62177867Sjfvstatic s32  e1000_reset_hw_80003es2lan(struct e1000_hw *hw);
63177867Sjfvstatic s32  e1000_init_hw_80003es2lan(struct e1000_hw *hw);
64177867Sjfvstatic s32  e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw);
65177867Sjfvstatic void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw);
66169240Sjfvstatic s32  e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);
67169240Sjfvstatic s32  e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex);
68169240Sjfvstatic s32  e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw);
69185353Sjfvstatic s32  e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw);
70185353Sjfvstatic s32  e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
71185353Sjfv                                            u16 *data);
72185353Sjfvstatic s32  e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
73185353Sjfv                                             u16 data);
74169240Sjfvstatic s32  e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw);
75169240Sjfvstatic void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw);
76169240Sjfvstatic void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);
77177867Sjfvstatic s32  e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw);
78177867Sjfvstatic void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw);
79169240Sjfv
80173788Sjfv/*
81173788Sjfv * A table for the GG82563 cable length where the range is defined
82169240Sjfv * with a lower bound at "index" and the upper bound at
83169240Sjfv * "index + 5".
84169240Sjfv */
85173788Sjfvstatic const u16 e1000_gg82563_cable_length_table[] =
86169240Sjfv         { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF };
87169240Sjfv#define GG82563_CABLE_LENGTH_TABLE_SIZE \
88169240Sjfv                (sizeof(e1000_gg82563_cable_length_table) / \
89169240Sjfv                 sizeof(e1000_gg82563_cable_length_table[0]))
90169240Sjfv
91169240Sjfv/**
92169240Sjfv *  e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs.
93169589Sjfv *  @hw: pointer to the HW structure
94169240Sjfv **/
95177867Sjfvstatic s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw)
96169240Sjfv{
97169240Sjfv	struct e1000_phy_info *phy = &hw->phy;
98169240Sjfv	s32 ret_val = E1000_SUCCESS;
99169240Sjfv
100169240Sjfv	DEBUGFUNC("e1000_init_phy_params_80003es2lan");
101169240Sjfv
102173788Sjfv	if (hw->phy.media_type != e1000_media_type_copper) {
103169240Sjfv		phy->type        = e1000_phy_none;
104169240Sjfv		goto out;
105173788Sjfv	} else {
106177867Sjfv		phy->ops.power_up = e1000_power_up_phy_copper;
107177867Sjfv		phy->ops.power_down = e1000_power_down_phy_copper_80003es2lan;
108169240Sjfv	}
109169240Sjfv
110169240Sjfv	phy->addr                = 1;
111169240Sjfv	phy->autoneg_mask        = AUTONEG_ADVERTISE_SPEED_DEFAULT;
112169240Sjfv	phy->reset_delay_us      = 100;
113169240Sjfv	phy->type                = e1000_phy_gg82563;
114169240Sjfv
115177867Sjfv	phy->ops.acquire            = e1000_acquire_phy_80003es2lan;
116177867Sjfv	phy->ops.check_polarity     = e1000_check_polarity_m88;
117177867Sjfv	phy->ops.check_reset_block  = e1000_check_reset_block_generic;
118177867Sjfv	phy->ops.commit             = e1000_phy_sw_reset_generic;
119177867Sjfv	phy->ops.get_cfg_done       = e1000_get_cfg_done_80003es2lan;
120177867Sjfv	phy->ops.get_info           = e1000_get_phy_info_m88;
121177867Sjfv	phy->ops.release            = e1000_release_phy_80003es2lan;
122177867Sjfv	phy->ops.reset              = e1000_phy_hw_reset_generic;
123177867Sjfv	phy->ops.set_d3_lplu_state  = e1000_set_d3_lplu_state_generic;
124169240Sjfv
125177867Sjfv	phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_80003es2lan;
126177867Sjfv	phy->ops.get_cable_length   = e1000_get_cable_length_80003es2lan;
127177867Sjfv	phy->ops.read_reg           = e1000_read_phy_reg_gg82563_80003es2lan;
128177867Sjfv	phy->ops.write_reg          = e1000_write_phy_reg_gg82563_80003es2lan;
129169240Sjfv
130185353Sjfv	phy->ops.cfg_on_link_up    = e1000_cfg_on_link_up_80003es2lan;
131185353Sjfv
132169240Sjfv	/* This can only be done after all function pointers are setup. */
133169240Sjfv	ret_val = e1000_get_phy_id(hw);
134169240Sjfv
135169240Sjfv	/* Verify phy id */
136169240Sjfv	if (phy->id != GG82563_E_PHY_ID) {
137169240Sjfv		ret_val = -E1000_ERR_PHY;
138169240Sjfv		goto out;
139169240Sjfv	}
140169240Sjfv
141169240Sjfvout:
142169240Sjfv	return ret_val;
143169240Sjfv}
144169240Sjfv
145169240Sjfv/**
146169240Sjfv *  e1000_init_nvm_params_80003es2lan - Init ESB2 NVM func ptrs.
147169589Sjfv *  @hw: pointer to the HW structure
148169240Sjfv **/
149177867Sjfvstatic s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw)
150169240Sjfv{
151169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
152169240Sjfv	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
153169240Sjfv	u16 size;
154169240Sjfv
155169240Sjfv	DEBUGFUNC("e1000_init_nvm_params_80003es2lan");
156169240Sjfv
157169240Sjfv	nvm->opcode_bits        = 8;
158169240Sjfv	nvm->delay_usec         = 1;
159169240Sjfv	switch (nvm->override) {
160169240Sjfv	case e1000_nvm_override_spi_large:
161169240Sjfv		nvm->page_size    = 32;
162169240Sjfv		nvm->address_bits = 16;
163169240Sjfv		break;
164169240Sjfv	case e1000_nvm_override_spi_small:
165169240Sjfv		nvm->page_size    = 8;
166169240Sjfv		nvm->address_bits = 8;
167169240Sjfv		break;
168169240Sjfv	default:
169169240Sjfv		nvm->page_size    = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
170169240Sjfv		nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8;
171169240Sjfv		break;
172169240Sjfv	}
173169240Sjfv
174200243Sjfv	nvm->type = e1000_nvm_eeprom_spi;
175169240Sjfv
176169240Sjfv	size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
177169240Sjfv	                  E1000_EECD_SIZE_EX_SHIFT);
178169240Sjfv
179173788Sjfv	/*
180173788Sjfv	 * Added to a constant, "size" becomes the left-shift value
181169240Sjfv	 * for setting word_size.
182169240Sjfv	 */
183169240Sjfv	size += NVM_WORD_SIZE_BASE_SHIFT;
184173788Sjfv
185173788Sjfv	/* EEPROM access above 16k is unsupported */
186173788Sjfv	if (size > 14)
187173788Sjfv		size = 14;
188169240Sjfv	nvm->word_size	= 1 << size;
189169240Sjfv
190169240Sjfv	/* Function Pointers */
191177867Sjfv	nvm->ops.acquire           = e1000_acquire_nvm_80003es2lan;
192177867Sjfv	nvm->ops.read              = e1000_read_nvm_eerd;
193177867Sjfv	nvm->ops.release           = e1000_release_nvm_80003es2lan;
194177867Sjfv	nvm->ops.update            = e1000_update_nvm_checksum_generic;
195177867Sjfv	nvm->ops.valid_led_default = e1000_valid_led_default_generic;
196177867Sjfv	nvm->ops.validate          = e1000_validate_nvm_checksum_generic;
197177867Sjfv	nvm->ops.write             = e1000_write_nvm_80003es2lan;
198169240Sjfv
199169240Sjfv	return E1000_SUCCESS;
200169240Sjfv}
201169240Sjfv
202169240Sjfv/**
203169240Sjfv *  e1000_init_mac_params_80003es2lan - Init ESB2 MAC func ptrs.
204169589Sjfv *  @hw: pointer to the HW structure
205169240Sjfv **/
206177867Sjfvstatic s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw)
207169240Sjfv{
208169240Sjfv	struct e1000_mac_info *mac = &hw->mac;
209169240Sjfv
210169240Sjfv	DEBUGFUNC("e1000_init_mac_params_80003es2lan");
211169240Sjfv
212200243Sjfv	/* Set media type and media-dependent function pointers */
213169240Sjfv	switch (hw->device_id) {
214169240Sjfv	case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
215173788Sjfv		hw->phy.media_type = e1000_media_type_internal_serdes;
216200243Sjfv		mac->ops.check_for_link = e1000_check_for_serdes_link_generic;
217200243Sjfv		mac->ops.setup_physical_interface =
218200243Sjfv			e1000_setup_fiber_serdes_link_generic;
219169240Sjfv		break;
220169240Sjfv	default:
221173788Sjfv		hw->phy.media_type = e1000_media_type_copper;
222200243Sjfv		mac->ops.check_for_link = e1000_check_for_copper_link_generic;
223200243Sjfv		mac->ops.setup_physical_interface =
224200243Sjfv			e1000_setup_copper_link_80003es2lan;
225169240Sjfv		break;
226169240Sjfv	}
227169240Sjfv
228169240Sjfv	/* Set mta register count */
229169240Sjfv	mac->mta_reg_count = 128;
230169240Sjfv	/* Set rar entry count */
231169240Sjfv	mac->rar_entry_count = E1000_RAR_ENTRIES;
232169240Sjfv	/* Set if part includes ASF firmware */
233169240Sjfv	mac->asf_firmware_present = TRUE;
234169240Sjfv	/* Set if manageability features are enabled. */
235169240Sjfv	mac->arc_subsystem_valid =
236169240Sjfv	        (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
237169240Sjfv	                ? TRUE : FALSE;
238200243Sjfv	/* Adaptive IFS not supported */
239200243Sjfv	mac->adaptive_ifs = FALSE;
240169240Sjfv
241169240Sjfv	/* Function pointers */
242169240Sjfv
243169240Sjfv	/* bus type/speed/width */
244177867Sjfv	mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic;
245169240Sjfv	/* reset */
246177867Sjfv	mac->ops.reset_hw = e1000_reset_hw_80003es2lan;
247169240Sjfv	/* hw initialization */
248177867Sjfv	mac->ops.init_hw = e1000_init_hw_80003es2lan;
249169240Sjfv	/* link setup */
250177867Sjfv	mac->ops.setup_link = e1000_setup_link_generic;
251169240Sjfv	/* check management mode */
252177867Sjfv	mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
253169240Sjfv	/* multicast address update */
254177867Sjfv	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
255169240Sjfv	/* writing VFTA */
256177867Sjfv	mac->ops.write_vfta = e1000_write_vfta_generic;
257169240Sjfv	/* clearing VFTA */
258177867Sjfv	mac->ops.clear_vfta = e1000_clear_vfta_generic;
259169240Sjfv	/* setting MTA */
260177867Sjfv	mac->ops.mta_set = e1000_mta_set_generic;
261176667Sjfv	/* read mac address */
262177867Sjfv	mac->ops.read_mac_addr = e1000_read_mac_addr_80003es2lan;
263190872Sjfv	/* ID LED init */
264190872Sjfv	mac->ops.id_led_init = e1000_id_led_init_generic;
265169240Sjfv	/* blink LED */
266177867Sjfv	mac->ops.blink_led = e1000_blink_led_generic;
267169240Sjfv	/* setup LED */
268177867Sjfv	mac->ops.setup_led = e1000_setup_led_generic;
269169240Sjfv	/* cleanup LED */
270177867Sjfv	mac->ops.cleanup_led = e1000_cleanup_led_generic;
271169240Sjfv	/* turn on/off LED */
272177867Sjfv	mac->ops.led_on = e1000_led_on_generic;
273177867Sjfv	mac->ops.led_off = e1000_led_off_generic;
274169240Sjfv	/* clear hardware counters */
275177867Sjfv	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan;
276169240Sjfv	/* link info */
277177867Sjfv	mac->ops.get_link_up_info = e1000_get_link_up_info_80003es2lan;
278169240Sjfv
279200243Sjfv	/* set lan id for port to determine which phy lock to use */
280200243Sjfv	hw->mac.ops.set_lan_id(hw);
281200243Sjfv
282200243Sjfv	return E1000_SUCCESS;
283169240Sjfv}
284169240Sjfv
285169240Sjfv/**
286169240Sjfv *  e1000_init_function_pointers_80003es2lan - Init ESB2 func ptrs.
287169589Sjfv *  @hw: pointer to the HW structure
288169240Sjfv *
289185353Sjfv *  Called to initialize all function pointers and parameters.
290169240Sjfv **/
291173788Sjfvvoid e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw)
292169240Sjfv{
293169240Sjfv	DEBUGFUNC("e1000_init_function_pointers_80003es2lan");
294169240Sjfv
295177867Sjfv	hw->mac.ops.init_params = e1000_init_mac_params_80003es2lan;
296177867Sjfv	hw->nvm.ops.init_params = e1000_init_nvm_params_80003es2lan;
297177867Sjfv	hw->phy.ops.init_params = e1000_init_phy_params_80003es2lan;
298169240Sjfv}
299169240Sjfv
300169240Sjfv/**
301169240Sjfv *  e1000_acquire_phy_80003es2lan - Acquire rights to access PHY
302169589Sjfv *  @hw: pointer to the HW structure
303169240Sjfv *
304185353Sjfv *  A wrapper to acquire access rights to the correct PHY.
305169240Sjfv **/
306177867Sjfvstatic s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw)
307169240Sjfv{
308169240Sjfv	u16 mask;
309169240Sjfv
310169240Sjfv	DEBUGFUNC("e1000_acquire_phy_80003es2lan");
311169240Sjfv
312169240Sjfv	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
313169240Sjfv	return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
314169240Sjfv}
315169240Sjfv
316169240Sjfv/**
317169240Sjfv *  e1000_release_phy_80003es2lan - Release rights to access PHY
318169589Sjfv *  @hw: pointer to the HW structure
319169240Sjfv *
320185353Sjfv *  A wrapper to release access rights to the correct PHY.
321169240Sjfv **/
322177867Sjfvstatic void e1000_release_phy_80003es2lan(struct e1000_hw *hw)
323169240Sjfv{
324169240Sjfv	u16 mask;
325169240Sjfv
326169240Sjfv	DEBUGFUNC("e1000_release_phy_80003es2lan");
327169240Sjfv
328169240Sjfv	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
329185353Sjfv	e1000_release_swfw_sync_80003es2lan(hw, mask);
330185353Sjfv}
331176667Sjfv
332185353Sjfv/**
333185353Sjfv *  e1000_acquire_mac_csr_80003es2lan - Acquire rights to access Kumeran register
334185353Sjfv *  @hw: pointer to the HW structure
335185353Sjfv *
336185353Sjfv *  Acquire the semaphore to access the Kumeran interface.
337185353Sjfv *
338185353Sjfv **/
339185353Sjfvstatic s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw)
340185353Sjfv{
341185353Sjfv	u16 mask;
342185353Sjfv
343185353Sjfv	DEBUGFUNC("e1000_acquire_mac_csr_80003es2lan");
344185353Sjfv
345185353Sjfv	mask = E1000_SWFW_CSR_SM;
346185353Sjfv
347185353Sjfv	return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
348185353Sjfv}
349185353Sjfv
350185353Sjfv/**
351185353Sjfv *  e1000_release_mac_csr_80003es2lan - Release rights to access Kumeran Register
352185353Sjfv *  @hw: pointer to the HW structure
353185353Sjfv *
354185353Sjfv *  Release the semaphore used to access the Kumeran interface
355185353Sjfv **/
356185353Sjfvstatic void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw)
357185353Sjfv{
358185353Sjfv	u16 mask;
359185353Sjfv
360185353Sjfv	DEBUGFUNC("e1000_release_mac_csr_80003es2lan");
361185353Sjfv
362185353Sjfv	mask = E1000_SWFW_CSR_SM;
363185353Sjfv
364169240Sjfv	e1000_release_swfw_sync_80003es2lan(hw, mask);
365169240Sjfv}
366169240Sjfv
367169240Sjfv/**
368169240Sjfv *  e1000_acquire_nvm_80003es2lan - Acquire rights to access NVM
369169589Sjfv *  @hw: pointer to the HW structure
370169240Sjfv *
371185353Sjfv *  Acquire the semaphore to access the EEPROM.
372169240Sjfv **/
373177867Sjfvstatic s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw)
374169240Sjfv{
375169240Sjfv	s32 ret_val;
376169240Sjfv
377169240Sjfv	DEBUGFUNC("e1000_acquire_nvm_80003es2lan");
378169240Sjfv
379169240Sjfv	ret_val = e1000_acquire_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);
380169240Sjfv	if (ret_val)
381169240Sjfv		goto out;
382169240Sjfv
383169240Sjfv	ret_val = e1000_acquire_nvm_generic(hw);
384169240Sjfv
385169240Sjfv	if (ret_val)
386169240Sjfv		e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);
387169240Sjfv
388169240Sjfvout:
389169240Sjfv	return ret_val;
390169240Sjfv}
391169240Sjfv
392169240Sjfv/**
393169240Sjfv *  e1000_release_nvm_80003es2lan - Relinquish rights to access NVM
394169589Sjfv *  @hw: pointer to the HW structure
395169240Sjfv *
396185353Sjfv *  Release the semaphore used to access the EEPROM.
397169240Sjfv **/
398177867Sjfvstatic void e1000_release_nvm_80003es2lan(struct e1000_hw *hw)
399169240Sjfv{
400169240Sjfv	DEBUGFUNC("e1000_release_nvm_80003es2lan");
401169240Sjfv
402169240Sjfv	e1000_release_nvm_generic(hw);
403169240Sjfv	e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);
404169240Sjfv}
405169240Sjfv
406169240Sjfv/**
407169240Sjfv *  e1000_acquire_swfw_sync_80003es2lan - Acquire SW/FW semaphore
408169589Sjfv *  @hw: pointer to the HW structure
409169589Sjfv *  @mask: specifies which semaphore to acquire
410169240Sjfv *
411169240Sjfv *  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
412169240Sjfv *  will also specify which port we're acquiring the lock for.
413169240Sjfv **/
414173788Sjfvstatic s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask)
415169240Sjfv{
416169240Sjfv	u32 swfw_sync;
417169240Sjfv	u32 swmask = mask;
418169240Sjfv	u32 fwmask = mask << 16;
419169240Sjfv	s32 ret_val = E1000_SUCCESS;
420185353Sjfv	s32 i = 0, timeout = 50;
421169240Sjfv
422169240Sjfv	DEBUGFUNC("e1000_acquire_swfw_sync_80003es2lan");
423169240Sjfv
424169240Sjfv	while (i < timeout) {
425169589Sjfv		if (e1000_get_hw_semaphore_generic(hw)) {
426169240Sjfv			ret_val = -E1000_ERR_SWFW_SYNC;
427169240Sjfv			goto out;
428169240Sjfv		}
429169240Sjfv
430169240Sjfv		swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
431169240Sjfv		if (!(swfw_sync & (fwmask | swmask)))
432169240Sjfv			break;
433169240Sjfv
434173788Sjfv		/*
435173788Sjfv		 * Firmware currently using resource (fwmask)
436173788Sjfv		 * or other software thread using resource (swmask)
437173788Sjfv		 */
438169589Sjfv		e1000_put_hw_semaphore_generic(hw);
439169240Sjfv		msec_delay_irq(5);
440169240Sjfv		i++;
441169240Sjfv	}
442169240Sjfv
443169240Sjfv	if (i == timeout) {
444169240Sjfv		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
445169240Sjfv		ret_val = -E1000_ERR_SWFW_SYNC;
446169240Sjfv		goto out;
447169240Sjfv	}
448169240Sjfv
449169240Sjfv	swfw_sync |= swmask;
450169240Sjfv	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
451169240Sjfv
452169589Sjfv	e1000_put_hw_semaphore_generic(hw);
453169240Sjfv
454169240Sjfvout:
455169240Sjfv	return ret_val;
456169240Sjfv}
457169240Sjfv
458169240Sjfv/**
459169240Sjfv *  e1000_release_swfw_sync_80003es2lan - Release SW/FW semaphore
460169589Sjfv *  @hw: pointer to the HW structure
461169589Sjfv *  @mask: specifies which semaphore to acquire
462169240Sjfv *
463169240Sjfv *  Release the SW/FW semaphore used to access the PHY or NVM.  The mask
464169240Sjfv *  will also specify which port we're releasing the lock for.
465169240Sjfv **/
466173788Sjfvstatic void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask)
467169240Sjfv{
468169240Sjfv	u32 swfw_sync;
469169240Sjfv
470169240Sjfv	DEBUGFUNC("e1000_release_swfw_sync_80003es2lan");
471169240Sjfv
472185353Sjfv	while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS)
473185353Sjfv		; /* Empty */
474169240Sjfv
475169240Sjfv	swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
476169240Sjfv	swfw_sync &= ~mask;
477169240Sjfv	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
478169240Sjfv
479169589Sjfv	e1000_put_hw_semaphore_generic(hw);
480169240Sjfv}
481169240Sjfv
482169240Sjfv/**
483169240Sjfv *  e1000_read_phy_reg_gg82563_80003es2lan - Read GG82563 PHY register
484169589Sjfv *  @hw: pointer to the HW structure
485169589Sjfv *  @offset: offset of the register to read
486169589Sjfv *  @data: pointer to the data returned from the operation
487169240Sjfv *
488185353Sjfv *  Read the GG82563 PHY register.
489169240Sjfv **/
490177867Sjfvstatic s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
491173788Sjfv                                                  u32 offset, u16 *data)
492169240Sjfv{
493169240Sjfv	s32 ret_val;
494169240Sjfv	u32 page_select;
495169240Sjfv	u16 temp;
496169240Sjfv
497169240Sjfv	DEBUGFUNC("e1000_read_phy_reg_gg82563_80003es2lan");
498169240Sjfv
499176667Sjfv	ret_val = e1000_acquire_phy_80003es2lan(hw);
500176667Sjfv	if (ret_val)
501176667Sjfv		goto out;
502176667Sjfv
503169240Sjfv	/* Select Configuration Page */
504173788Sjfv	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
505169240Sjfv		page_select = GG82563_PHY_PAGE_SELECT;
506173788Sjfv	} else {
507173788Sjfv		/*
508173788Sjfv		 * Use Alternative Page Select register to access
509169240Sjfv		 * registers 30 and 31
510169240Sjfv		 */
511169240Sjfv		page_select = GG82563_PHY_PAGE_SELECT_ALT;
512169240Sjfv	}
513169240Sjfv
514169240Sjfv	temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT);
515176667Sjfv	ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp);
516176667Sjfv	if (ret_val) {
517176667Sjfv		e1000_release_phy_80003es2lan(hw);
518169240Sjfv		goto out;
519176667Sjfv	}
520169240Sjfv
521200243Sjfv	if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) {
522200243Sjfv		/*
523200243Sjfv		 * The "ready" bit in the MDIC register may be incorrectly set
524200243Sjfv		 * before the device has completed the "Page Select" MDI
525200243Sjfv		 * transaction.  So we wait 200us after each MDI command...
526200243Sjfv		 */
527200243Sjfv		usec_delay(200);
528169240Sjfv
529200243Sjfv		/* ...and verify the command was successful. */
530200243Sjfv		ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
531169240Sjfv
532200243Sjfv		if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
533200243Sjfv			ret_val = -E1000_ERR_PHY;
534200243Sjfv			e1000_release_phy_80003es2lan(hw);
535200243Sjfv			goto out;
536200243Sjfv		}
537169240Sjfv
538200243Sjfv		usec_delay(200);
539169240Sjfv
540200243Sjfv		ret_val = e1000_read_phy_reg_mdic(hw,
541200243Sjfv		                                  MAX_PHY_REG_ADDRESS & offset,
542200243Sjfv		                                  data);
543169240Sjfv
544200243Sjfv		usec_delay(200);
545200243Sjfv	} else {
546200243Sjfv		ret_val = e1000_read_phy_reg_mdic(hw,
547200243Sjfv		                                  MAX_PHY_REG_ADDRESS & offset,
548200243Sjfv		                                  data);
549200243Sjfv	}
550200243Sjfv
551176667Sjfv	e1000_release_phy_80003es2lan(hw);
552169240Sjfv
553169240Sjfvout:
554169240Sjfv	return ret_val;
555169240Sjfv}
556169240Sjfv
557169240Sjfv/**
558169240Sjfv *  e1000_write_phy_reg_gg82563_80003es2lan - Write GG82563 PHY register
559169589Sjfv *  @hw: pointer to the HW structure
560169589Sjfv *  @offset: offset of the register to read
561169589Sjfv *  @data: value to write to the register
562169240Sjfv *
563185353Sjfv *  Write to the GG82563 PHY register.
564169240Sjfv **/
565177867Sjfvstatic s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
566173788Sjfv                                                   u32 offset, u16 data)
567169240Sjfv{
568169240Sjfv	s32 ret_val;
569169240Sjfv	u32 page_select;
570169240Sjfv	u16 temp;
571169240Sjfv
572169240Sjfv	DEBUGFUNC("e1000_write_phy_reg_gg82563_80003es2lan");
573169240Sjfv
574176667Sjfv	ret_val = e1000_acquire_phy_80003es2lan(hw);
575176667Sjfv	if (ret_val)
576176667Sjfv		goto out;
577176667Sjfv
578169240Sjfv	/* Select Configuration Page */
579173788Sjfv	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
580169240Sjfv		page_select = GG82563_PHY_PAGE_SELECT;
581173788Sjfv	} else {
582173788Sjfv		/*
583173788Sjfv		 * Use Alternative Page Select register to access
584169240Sjfv		 * registers 30 and 31
585169240Sjfv		 */
586169240Sjfv		page_select = GG82563_PHY_PAGE_SELECT_ALT;
587169240Sjfv	}
588169240Sjfv
589169240Sjfv	temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT);
590176667Sjfv	ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp);
591176667Sjfv	if (ret_val) {
592176667Sjfv		e1000_release_phy_80003es2lan(hw);
593169240Sjfv		goto out;
594176667Sjfv	}
595169240Sjfv
596200243Sjfv	if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) {
597200243Sjfv		/*
598200243Sjfv		 * The "ready" bit in the MDIC register may be incorrectly set
599200243Sjfv		 * before the device has completed the "Page Select" MDI
600200243Sjfv		 * transaction.  So we wait 200us after each MDI command...
601200243Sjfv		 */
602200243Sjfv		usec_delay(200);
603169240Sjfv
604200243Sjfv		/* ...and verify the command was successful. */
605200243Sjfv		ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
606169240Sjfv
607200243Sjfv		if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
608200243Sjfv			ret_val = -E1000_ERR_PHY;
609200243Sjfv			e1000_release_phy_80003es2lan(hw);
610200243Sjfv			goto out;
611200243Sjfv		}
612169240Sjfv
613200243Sjfv		usec_delay(200);
614169240Sjfv
615200243Sjfv		ret_val = e1000_write_phy_reg_mdic(hw,
616200243Sjfv		                                  MAX_PHY_REG_ADDRESS & offset,
617200243Sjfv		                                  data);
618169240Sjfv
619200243Sjfv		usec_delay(200);
620200243Sjfv	} else {
621200243Sjfv		ret_val = e1000_write_phy_reg_mdic(hw,
622200243Sjfv		                                  MAX_PHY_REG_ADDRESS & offset,
623200243Sjfv		                                  data);
624200243Sjfv	}
625169240Sjfv
626176667Sjfv	e1000_release_phy_80003es2lan(hw);
627169240Sjfv
628169240Sjfvout:
629169240Sjfv	return ret_val;
630169240Sjfv}
631169240Sjfv
632169240Sjfv/**
633169240Sjfv *  e1000_write_nvm_80003es2lan - Write to ESB2 NVM
634169589Sjfv *  @hw: pointer to the HW structure
635169589Sjfv *  @offset: offset of the register to read
636169589Sjfv *  @words: number of words to write
637169589Sjfv *  @data: buffer of data to write to the NVM
638169240Sjfv *
639185353Sjfv *  Write "words" of data to the ESB2 NVM.
640169240Sjfv **/
641177867Sjfvstatic s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset,
642169240Sjfv                            u16 words, u16 *data)
643169240Sjfv{
644169240Sjfv	DEBUGFUNC("e1000_write_nvm_80003es2lan");
645169240Sjfv
646169240Sjfv	return e1000_write_nvm_spi(hw, offset, words, data);
647169240Sjfv}
648169240Sjfv
649169240Sjfv/**
650169240Sjfv *  e1000_get_cfg_done_80003es2lan - Wait for configuration to complete
651169589Sjfv *  @hw: pointer to the HW structure
652169240Sjfv *
653169240Sjfv *  Wait a specific amount of time for manageability processes to complete.
654169240Sjfv *  This is a function pointer entry point called by the phy module.
655169240Sjfv **/
656177867Sjfvstatic s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw)
657169240Sjfv{
658169240Sjfv	s32 timeout = PHY_CFG_TIMEOUT;
659169240Sjfv	s32 ret_val = E1000_SUCCESS;
660169240Sjfv	u32 mask = E1000_NVM_CFG_DONE_PORT_0;
661169240Sjfv
662169240Sjfv	DEBUGFUNC("e1000_get_cfg_done_80003es2lan");
663169240Sjfv
664169240Sjfv	if (hw->bus.func == 1)
665169240Sjfv		mask = E1000_NVM_CFG_DONE_PORT_1;
666169240Sjfv
667169240Sjfv	while (timeout) {
668169240Sjfv		if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask)
669169240Sjfv			break;
670169240Sjfv		msec_delay(1);
671169240Sjfv		timeout--;
672169240Sjfv	}
673169240Sjfv	if (!timeout) {
674169240Sjfv		DEBUGOUT("MNG configuration cycle has not completed.\n");
675169240Sjfv		ret_val = -E1000_ERR_RESET;
676169240Sjfv		goto out;
677169240Sjfv	}
678169240Sjfv
679169240Sjfvout:
680169240Sjfv	return ret_val;
681169240Sjfv}
682169240Sjfv
683169240Sjfv/**
684169240Sjfv *  e1000_phy_force_speed_duplex_80003es2lan - Force PHY speed and duplex
685169589Sjfv *  @hw: pointer to the HW structure
686169240Sjfv *
687169240Sjfv *  Force the speed and duplex settings onto the PHY.  This is a
688169240Sjfv *  function pointer entry point called by the phy module.
689169240Sjfv **/
690177867Sjfvstatic s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
691169240Sjfv{
692177867Sjfv	s32 ret_val = E1000_SUCCESS;
693169240Sjfv	u16 phy_data;
694173788Sjfv	bool link;
695169240Sjfv
696169240Sjfv	DEBUGFUNC("e1000_phy_force_speed_duplex_80003es2lan");
697169240Sjfv
698177867Sjfv	if (!(hw->phy.ops.read_reg))
699177867Sjfv		goto out;
700177867Sjfv
701173788Sjfv	/*
702173788Sjfv	 * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
703169240Sjfv	 * forced whenever speed and duplex are forced.
704169240Sjfv	 */
705177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
706169240Sjfv	if (ret_val)
707169240Sjfv		goto out;
708169240Sjfv
709169240Sjfv	phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO;
710177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data);
711169240Sjfv	if (ret_val)
712169240Sjfv		goto out;
713169240Sjfv
714169240Sjfv	DEBUGOUT1("GG82563 PSCR: %X\n", phy_data);
715169240Sjfv
716177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_data);
717169240Sjfv	if (ret_val)
718169240Sjfv		goto out;
719169240Sjfv
720169240Sjfv	e1000_phy_force_speed_duplex_setup(hw, &phy_data);
721169240Sjfv
722169240Sjfv	/* Reset the phy to commit changes. */
723169240Sjfv	phy_data |= MII_CR_RESET;
724169240Sjfv
725177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_data);
726169240Sjfv	if (ret_val)
727169240Sjfv		goto out;
728169240Sjfv
729169240Sjfv	usec_delay(1);
730169240Sjfv
731173788Sjfv	if (hw->phy.autoneg_wait_to_complete) {
732169240Sjfv		DEBUGOUT("Waiting for forced speed/duplex link "
733169240Sjfv		         "on GG82563 phy.\n");
734169240Sjfv
735169240Sjfv		ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
736169240Sjfv		                                     100000, &link);
737169240Sjfv		if (ret_val)
738169240Sjfv			goto out;
739169240Sjfv
740169240Sjfv		if (!link) {
741173788Sjfv			/*
742173788Sjfv			 * We didn't get link.
743169240Sjfv			 * Reset the DSP and cross our fingers.
744169240Sjfv			 */
745169240Sjfv			ret_val = e1000_phy_reset_dsp_generic(hw);
746169240Sjfv			if (ret_val)
747169240Sjfv				goto out;
748169240Sjfv		}
749169240Sjfv
750169240Sjfv		/* Try once more */
751169240Sjfv		ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
752169240Sjfv		                                     100000, &link);
753169240Sjfv		if (ret_val)
754169240Sjfv			goto out;
755169240Sjfv	}
756169240Sjfv
757177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data);
758169240Sjfv	if (ret_val)
759169240Sjfv		goto out;
760169240Sjfv
761173788Sjfv	/*
762173788Sjfv	 * Resetting the phy means we need to verify the TX_CLK corresponds
763169240Sjfv	 * to the link speed.  10Mbps -> 2.5MHz, else 25MHz.
764169240Sjfv	 */
765169240Sjfv	phy_data &= ~GG82563_MSCR_TX_CLK_MASK;
766169240Sjfv	if (hw->mac.forced_speed_duplex & E1000_ALL_10_SPEED)
767169240Sjfv		phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5;
768169240Sjfv	else
769169240Sjfv		phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25;
770169240Sjfv
771173788Sjfv	/*
772173788Sjfv	 * In addition, we must re-enable CRS on Tx for both half and full
773169240Sjfv	 * duplex.
774169240Sjfv	 */
775169240Sjfv	phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
776177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
777169240Sjfv
778169240Sjfvout:
779169240Sjfv	return ret_val;
780169240Sjfv}
781169240Sjfv
782169240Sjfv/**
783169240Sjfv *  e1000_get_cable_length_80003es2lan - Set approximate cable length
784169589Sjfv *  @hw: pointer to the HW structure
785169240Sjfv *
786169240Sjfv *  Find the approximate cable length as measured by the GG82563 PHY.
787169240Sjfv *  This is a function pointer entry point called by the phy module.
788169240Sjfv **/
789177867Sjfvstatic s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw)
790169240Sjfv{
791169240Sjfv	struct e1000_phy_info *phy = &hw->phy;
792177867Sjfv	s32 ret_val = E1000_SUCCESS;
793169240Sjfv	u16 phy_data, index;
794169240Sjfv
795169240Sjfv	DEBUGFUNC("e1000_get_cable_length_80003es2lan");
796169240Sjfv
797177867Sjfv	if (!(hw->phy.ops.read_reg))
798177867Sjfv		goto out;
799177867Sjfv
800177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_DSP_DISTANCE, &phy_data);
801169240Sjfv	if (ret_val)
802169240Sjfv		goto out;
803169240Sjfv
804169240Sjfv	index = phy_data & GG82563_DSPD_CABLE_LENGTH;
805169240Sjfv
806200243Sjfv	if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) {
807200243Sjfv		ret_val = -E1000_ERR_PHY;
808190872Sjfv		goto out;
809185353Sjfv	}
810185353Sjfv
811190872Sjfv	phy->min_cable_length = e1000_gg82563_cable_length_table[index];
812200243Sjfv	phy->max_cable_length = e1000_gg82563_cable_length_table[index + 5];
813190872Sjfv
814190872Sjfv	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
815190872Sjfv
816169240Sjfvout:
817169240Sjfv	return ret_val;
818169240Sjfv}
819169240Sjfv
820169240Sjfv/**
821169240Sjfv *  e1000_get_link_up_info_80003es2lan - Report speed and duplex
822169589Sjfv *  @hw: pointer to the HW structure
823169589Sjfv *  @speed: pointer to speed buffer
824169589Sjfv *  @duplex: pointer to duplex buffer
825169240Sjfv *
826169240Sjfv *  Retrieve the current speed and duplex configuration.
827169240Sjfv **/
828177867Sjfvstatic s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
829173788Sjfv                                              u16 *duplex)
830169240Sjfv{
831169240Sjfv	s32 ret_val;
832169240Sjfv
833169240Sjfv	DEBUGFUNC("e1000_get_link_up_info_80003es2lan");
834169240Sjfv
835173788Sjfv	if (hw->phy.media_type == e1000_media_type_copper) {
836169240Sjfv		ret_val = e1000_get_speed_and_duplex_copper_generic(hw,
837169240Sjfv		                                                    speed,
838169240Sjfv		                                                    duplex);
839185353Sjfv		hw->phy.ops.cfg_on_link_up(hw);
840173788Sjfv	} else {
841169240Sjfv		ret_val = e1000_get_speed_and_duplex_fiber_serdes_generic(hw,
842169240Sjfv		                                                  speed,
843169240Sjfv		                                                  duplex);
844173788Sjfv	}
845169240Sjfv
846169240Sjfv	return ret_val;
847169240Sjfv}
848169240Sjfv
849169240Sjfv/**
850169240Sjfv *  e1000_reset_hw_80003es2lan - Reset the ESB2 controller
851169589Sjfv *  @hw: pointer to the HW structure
852169240Sjfv *
853169240Sjfv *  Perform a global reset to the ESB2 controller.
854169240Sjfv **/
855177867Sjfvstatic s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
856169240Sjfv{
857169240Sjfv	u32 ctrl, icr;
858169240Sjfv	s32 ret_val;
859169240Sjfv
860169240Sjfv	DEBUGFUNC("e1000_reset_hw_80003es2lan");
861169240Sjfv
862173788Sjfv	/*
863173788Sjfv	 * Prevent the PCI-E bus from sticking if there is no TLP connection
864169240Sjfv	 * on the last TLP read/write transaction when MAC is reset.
865169240Sjfv	 */
866169240Sjfv	ret_val = e1000_disable_pcie_master_generic(hw);
867185353Sjfv	if (ret_val)
868169240Sjfv		DEBUGOUT("PCI-E Master disable polling has failed.\n");
869169240Sjfv
870169240Sjfv	DEBUGOUT("Masking off all interrupts\n");
871169240Sjfv	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
872169240Sjfv
873169240Sjfv	E1000_WRITE_REG(hw, E1000_RCTL, 0);
874169240Sjfv	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
875169240Sjfv	E1000_WRITE_FLUSH(hw);
876169240Sjfv
877169240Sjfv	msec_delay(10);
878169240Sjfv
879169240Sjfv	ctrl = E1000_READ_REG(hw, E1000_CTRL);
880169240Sjfv
881185353Sjfv	ret_val = e1000_acquire_phy_80003es2lan(hw);
882169240Sjfv	DEBUGOUT("Issuing a global reset to MAC\n");
883169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
884185353Sjfv	e1000_release_phy_80003es2lan(hw);
885169240Sjfv
886169240Sjfv	ret_val = e1000_get_auto_rd_done_generic(hw);
887169240Sjfv	if (ret_val)
888169240Sjfv		/* We don't want to continue accessing MAC registers. */
889169240Sjfv		goto out;
890169240Sjfv
891169240Sjfv	/* Clear any pending interrupt events. */
892169240Sjfv	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
893169240Sjfv	icr = E1000_READ_REG(hw, E1000_ICR);
894169240Sjfv
895190872Sjfv	ret_val = e1000_check_alt_mac_addr_generic(hw);
896176667Sjfv
897169240Sjfvout:
898169240Sjfv	return ret_val;
899169240Sjfv}
900169240Sjfv
901169240Sjfv/**
902169240Sjfv *  e1000_init_hw_80003es2lan - Initialize the ESB2 controller
903169589Sjfv *  @hw: pointer to the HW structure
904169240Sjfv *
905169240Sjfv *  Initialize the hw bits, LED, VFTA, MTA, link and hw counters.
906169240Sjfv **/
907177867Sjfvstatic s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw)
908169240Sjfv{
909169240Sjfv	struct e1000_mac_info *mac = &hw->mac;
910169240Sjfv	u32 reg_data;
911169240Sjfv	s32 ret_val;
912169240Sjfv	u16 i;
913169240Sjfv
914169240Sjfv	DEBUGFUNC("e1000_init_hw_80003es2lan");
915169240Sjfv
916169240Sjfv	e1000_initialize_hw_bits_80003es2lan(hw);
917169240Sjfv
918169240Sjfv	/* Initialize identification LED */
919190872Sjfv	ret_val = mac->ops.id_led_init(hw);
920200243Sjfv	if (ret_val)
921169240Sjfv		DEBUGOUT("Error initializing identification LED\n");
922173788Sjfv		/* This is not fatal and we should not stop init due to this */
923169240Sjfv
924169240Sjfv	/* Disabling VLAN filtering */
925169240Sjfv	DEBUGOUT("Initializing the IEEE VLAN\n");
926177867Sjfv	mac->ops.clear_vfta(hw);
927169240Sjfv
928169240Sjfv	/* Setup the receive address. */
929169240Sjfv	e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
930169240Sjfv
931169240Sjfv	/* Zero out the Multicast HASH table */
932169240Sjfv	DEBUGOUT("Zeroing the MTA\n");
933169240Sjfv	for (i = 0; i < mac->mta_reg_count; i++)
934169240Sjfv		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
935169240Sjfv
936169240Sjfv	/* Setup link and flow control */
937177867Sjfv	ret_val = mac->ops.setup_link(hw);
938169240Sjfv
939169240Sjfv	/* Set the transmit descriptor write-back policy */
940173788Sjfv	reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0));
941169240Sjfv	reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
942169240Sjfv	           E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC;
943173788Sjfv	E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data);
944169240Sjfv
945169240Sjfv	/* ...for both queues. */
946173788Sjfv	reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1));
947169240Sjfv	reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
948169240Sjfv	           E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC;
949173788Sjfv	E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data);
950169240Sjfv
951169240Sjfv	/* Enable retransmit on late collisions */
952169240Sjfv	reg_data = E1000_READ_REG(hw, E1000_TCTL);
953169240Sjfv	reg_data |= E1000_TCTL_RTLC;
954169240Sjfv	E1000_WRITE_REG(hw, E1000_TCTL, reg_data);
955169240Sjfv
956169240Sjfv	/* Configure Gigabit Carry Extend Padding */
957169240Sjfv	reg_data = E1000_READ_REG(hw, E1000_TCTL_EXT);
958169240Sjfv	reg_data &= ~E1000_TCTL_EXT_GCEX_MASK;
959169240Sjfv	reg_data |= DEFAULT_TCTL_EXT_GCEX_80003ES2LAN;
960169240Sjfv	E1000_WRITE_REG(hw, E1000_TCTL_EXT, reg_data);
961169240Sjfv
962169240Sjfv	/* Configure Transmit Inter-Packet Gap */
963169240Sjfv	reg_data = E1000_READ_REG(hw, E1000_TIPG);
964169240Sjfv	reg_data &= ~E1000_TIPG_IPGT_MASK;
965169240Sjfv	reg_data |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN;
966169240Sjfv	E1000_WRITE_REG(hw, E1000_TIPG, reg_data);
967169240Sjfv
968169240Sjfv	reg_data = E1000_READ_REG_ARRAY(hw, E1000_FFLT, 0x0001);
969169240Sjfv	reg_data &= ~0x00100000;
970169240Sjfv	E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data);
971169240Sjfv
972200243Sjfv	/* default to TRUE to enable the MDIC W/A */
973200243Sjfv	hw->dev_spec._80003es2lan.mdic_wa_enable = TRUE;
974200243Sjfv
975200243Sjfv	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
976200243Sjfv	                              E1000_KMRNCTRLSTA_OFFSET >>
977200243Sjfv	                              E1000_KMRNCTRLSTA_OFFSET_SHIFT,
978200243Sjfv	                              &i);
979200243Sjfv	if (!ret_val) {
980200243Sjfv		if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) ==
981200243Sjfv		     E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO)
982200243Sjfv			hw->dev_spec._80003es2lan.mdic_wa_enable = FALSE;
983200243Sjfv	}
984200243Sjfv
985173788Sjfv	/*
986173788Sjfv	 * Clear all of the statistics registers (clear on read).  It is
987169240Sjfv	 * important that we do this after we have tried to establish link
988169240Sjfv	 * because the symbol error count will increment wildly if there
989169240Sjfv	 * is no link.
990169240Sjfv	 */
991169240Sjfv	e1000_clear_hw_cntrs_80003es2lan(hw);
992169240Sjfv
993169240Sjfv	return ret_val;
994169240Sjfv}
995169240Sjfv
996169240Sjfv/**
997169240Sjfv *  e1000_initialize_hw_bits_80003es2lan - Init hw bits of ESB2
998169589Sjfv *  @hw: pointer to the HW structure
999169240Sjfv *
1000169240Sjfv *  Initializes required hardware-dependent bits needed for normal operation.
1001169240Sjfv **/
1002173788Sjfvstatic void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw)
1003169240Sjfv{
1004169240Sjfv	u32 reg;
1005169240Sjfv
1006169240Sjfv	DEBUGFUNC("e1000_initialize_hw_bits_80003es2lan");
1007169240Sjfv
1008169240Sjfv	/* Transmit Descriptor Control 0 */
1009173788Sjfv	reg = E1000_READ_REG(hw, E1000_TXDCTL(0));
1010169240Sjfv	reg |= (1 << 22);
1011173788Sjfv	E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg);
1012169240Sjfv
1013169240Sjfv	/* Transmit Descriptor Control 1 */
1014173788Sjfv	reg = E1000_READ_REG(hw, E1000_TXDCTL(1));
1015169240Sjfv	reg |= (1 << 22);
1016173788Sjfv	E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg);
1017169240Sjfv
1018169240Sjfv	/* Transmit Arbitration Control 0 */
1019173788Sjfv	reg = E1000_READ_REG(hw, E1000_TARC(0));
1020169240Sjfv	reg &= ~(0xF << 27); /* 30:27 */
1021173788Sjfv	if (hw->phy.media_type != e1000_media_type_copper)
1022169240Sjfv		reg &= ~(1 << 20);
1023173788Sjfv	E1000_WRITE_REG(hw, E1000_TARC(0), reg);
1024169240Sjfv
1025169240Sjfv	/* Transmit Arbitration Control 1 */
1026173788Sjfv	reg = E1000_READ_REG(hw, E1000_TARC(1));
1027169240Sjfv	if (E1000_READ_REG(hw, E1000_TCTL) & E1000_TCTL_MULR)
1028169240Sjfv		reg &= ~(1 << 28);
1029169240Sjfv	else
1030169240Sjfv		reg |= (1 << 28);
1031173788Sjfv	E1000_WRITE_REG(hw, E1000_TARC(1), reg);
1032169240Sjfv
1033169240Sjfv	return;
1034169240Sjfv}
1035169240Sjfv
1036169240Sjfv/**
1037169240Sjfv *  e1000_copper_link_setup_gg82563_80003es2lan - Configure GG82563 Link
1038169589Sjfv *  @hw: pointer to the HW structure
1039169240Sjfv *
1040169240Sjfv *  Setup some GG82563 PHY registers for obtaining link
1041169240Sjfv **/
1042173788Sjfvstatic s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
1043169240Sjfv{
1044176667Sjfv	struct e1000_phy_info *phy = &hw->phy;
1045176667Sjfv	s32 ret_val;
1046169240Sjfv	u32 ctrl_ext;
1047185353Sjfv	u16 data;
1048169240Sjfv
1049169240Sjfv	DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan");
1050169240Sjfv
1051169240Sjfv	if (!phy->reset_disable) {
1052177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
1053169240Sjfv		                             &data);
1054169240Sjfv		if (ret_val)
1055169240Sjfv			goto out;
1056169240Sjfv
1057169240Sjfv		data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
1058169240Sjfv		/* Use 25MHz for both link down and 1000Base-T for Tx clock. */
1059169240Sjfv		data |= GG82563_MSCR_TX_CLK_1000MBPS_25;
1060169240Sjfv
1061177867Sjfv		ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
1062169240Sjfv		                              data);
1063169240Sjfv		if (ret_val)
1064169240Sjfv			goto out;
1065169240Sjfv
1066173788Sjfv		/*
1067173788Sjfv		 * Options:
1068169240Sjfv		 *   MDI/MDI-X = 0 (default)
1069169240Sjfv		 *   0 - Auto for all speeds
1070169240Sjfv		 *   1 - MDI mode
1071169240Sjfv		 *   2 - MDI-X mode
1072169240Sjfv		 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
1073169240Sjfv		 */
1074177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data);
1075169240Sjfv		if (ret_val)
1076169240Sjfv			goto out;
1077169240Sjfv
1078169240Sjfv		data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK;
1079169240Sjfv
1080169240Sjfv		switch (phy->mdix) {
1081169240Sjfv		case 1:
1082169240Sjfv			data |= GG82563_PSCR_CROSSOVER_MODE_MDI;
1083169240Sjfv			break;
1084169240Sjfv		case 2:
1085169240Sjfv			data |= GG82563_PSCR_CROSSOVER_MODE_MDIX;
1086169240Sjfv			break;
1087169240Sjfv		case 0:
1088169240Sjfv		default:
1089169240Sjfv			data |= GG82563_PSCR_CROSSOVER_MODE_AUTO;
1090169240Sjfv			break;
1091169240Sjfv		}
1092169240Sjfv
1093173788Sjfv		/*
1094173788Sjfv		 * Options:
1095169240Sjfv		 *   disable_polarity_correction = 0 (default)
1096169240Sjfv		 *       Automatic Correction for Reversed Cable Polarity
1097169240Sjfv		 *   0 - Disabled
1098169240Sjfv		 *   1 - Enabled
1099169240Sjfv		 */
1100169240Sjfv		data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
1101173788Sjfv		if (phy->disable_polarity_correction)
1102169240Sjfv			data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
1103169240Sjfv
1104177867Sjfv		ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data);
1105169240Sjfv		if (ret_val)
1106169240Sjfv			goto out;
1107169240Sjfv
1108169240Sjfv		/* SW Reset the PHY so all changes take effect */
1109177867Sjfv		ret_val = hw->phy.ops.commit(hw);
1110169240Sjfv		if (ret_val) {
1111169240Sjfv			DEBUGOUT("Error Resetting the PHY\n");
1112169240Sjfv			goto out;
1113169240Sjfv		}
1114169240Sjfv
1115169240Sjfv	}
1116169240Sjfv
1117173788Sjfv	/* Bypass Rx and Tx FIFO's */
1118185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
1119190872Sjfv					E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL,
1120190872Sjfv					E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS |
1121190872Sjfv					E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS);
1122169240Sjfv	if (ret_val)
1123169240Sjfv		goto out;
1124169240Sjfv
1125185353Sjfv	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
1126176667Sjfv	                              E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
1127176667Sjfv	                              &data);
1128173788Sjfv	if (ret_val)
1129173788Sjfv		goto out;
1130173788Sjfv	data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE;
1131185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
1132176667Sjfv	                               E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
1133176667Sjfv	                               data);
1134173788Sjfv	if (ret_val)
1135173788Sjfv		goto out;
1136173788Sjfv
1137177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL_2, &data);
1138169240Sjfv	if (ret_val)
1139169240Sjfv		goto out;
1140169240Sjfv
1141169240Sjfv	data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG;
1142177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL_2, data);
1143169240Sjfv	if (ret_val)
1144169240Sjfv		goto out;
1145169240Sjfv
1146169240Sjfv	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
1147169240Sjfv	ctrl_ext &= ~(E1000_CTRL_EXT_LINK_MODE_MASK);
1148169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
1149169240Sjfv
1150177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, &data);
1151169240Sjfv	if (ret_val)
1152169240Sjfv		goto out;
1153169240Sjfv
1154173788Sjfv	/*
1155173788Sjfv	 * Do not init these registers when the HW is in IAMT mode, since the
1156169240Sjfv	 * firmware will have already initialized them.  We only initialize
1157169240Sjfv	 * them if the HW is not in IAMT mode.
1158169240Sjfv	 */
1159177867Sjfv	if (!(hw->mac.ops.check_mng_mode(hw))) {
1160169240Sjfv		/* Enable Electrical Idle on the PHY */
1161169240Sjfv		data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;
1162190872Sjfv		ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_PWR_MGMT_CTRL,
1163185353Sjfv		                                data);
1164169240Sjfv		if (ret_val)
1165169240Sjfv			goto out;
1166169240Sjfv
1167190872Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1168190872Sjfv		                               &data);
1169190872Sjfv		if (ret_val)
1170190872Sjfv			goto out;
1171190872Sjfv
1172169240Sjfv		data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
1173190872Sjfv		ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1174185353Sjfv		                                data);
1175169240Sjfv		if (ret_val)
1176169240Sjfv			goto out;
1177169240Sjfv	}
1178169240Sjfv
1179173788Sjfv	/*
1180173788Sjfv	 * Workaround: Disable padding in Kumeran interface in the MAC
1181169240Sjfv	 * and in the PHY to avoid CRC errors.
1182169240Sjfv	 */
1183177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_INBAND_CTRL, &data);
1184169240Sjfv	if (ret_val)
1185169240Sjfv		goto out;
1186169240Sjfv
1187169240Sjfv	data |= GG82563_ICR_DIS_PADDING;
1188177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_INBAND_CTRL, data);
1189169240Sjfv	if (ret_val)
1190169240Sjfv		goto out;
1191169240Sjfv
1192169240Sjfvout:
1193169240Sjfv	return ret_val;
1194169240Sjfv}
1195169240Sjfv
1196169240Sjfv/**
1197169240Sjfv *  e1000_setup_copper_link_80003es2lan - Setup Copper Link for ESB2
1198169589Sjfv *  @hw: pointer to the HW structure
1199169240Sjfv *
1200169240Sjfv *  Essentially a wrapper for setting up all things "copper" related.
1201169240Sjfv *  This is a function pointer entry point called by the mac module.
1202169240Sjfv **/
1203177867Sjfvstatic s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
1204169240Sjfv{
1205169240Sjfv	u32 ctrl;
1206185353Sjfv	s32 ret_val;
1207169240Sjfv	u16 reg_data;
1208169240Sjfv
1209169240Sjfv	DEBUGFUNC("e1000_setup_copper_link_80003es2lan");
1210169240Sjfv
1211169240Sjfv	ctrl = E1000_READ_REG(hw, E1000_CTRL);
1212169240Sjfv	ctrl |= E1000_CTRL_SLU;
1213169240Sjfv	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
1214169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
1215169240Sjfv
1216173788Sjfv	/*
1217173788Sjfv	 * Set the mac to wait the maximum time between each
1218169240Sjfv	 * iteration and increase the max iterations when
1219173788Sjfv	 * polling the phy; this fixes erroneous timeouts at 10Mbps.
1220173788Sjfv	 */
1221185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4),
1222185353Sjfv	                                           0xFFFF);
1223169240Sjfv	if (ret_val)
1224169240Sjfv		goto out;
1225185353Sjfv	ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),
1226185353Sjfv	                                          &reg_data);
1227169240Sjfv	if (ret_val)
1228169240Sjfv		goto out;
1229169240Sjfv	reg_data |= 0x3F;
1230185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),
1231185353Sjfv	                                           reg_data);
1232169240Sjfv	if (ret_val)
1233169240Sjfv		goto out;
1234185353Sjfv	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
1235169240Sjfv	                              E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
1236169240Sjfv	                              &reg_data);
1237169240Sjfv	if (ret_val)
1238169240Sjfv		goto out;
1239169240Sjfv	reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING;
1240185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
1241169240Sjfv	                               E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
1242169240Sjfv	                               reg_data);
1243169240Sjfv	if (ret_val)
1244169240Sjfv		goto out;
1245169240Sjfv
1246169240Sjfv	ret_val = e1000_copper_link_setup_gg82563_80003es2lan(hw);
1247169240Sjfv	if (ret_val)
1248169240Sjfv		goto out;
1249169240Sjfv
1250169240Sjfv	ret_val = e1000_setup_copper_link_generic(hw);
1251169240Sjfv
1252169240Sjfvout:
1253169240Sjfv	return ret_val;
1254169240Sjfv}
1255169240Sjfv
1256169240Sjfv/**
1257185353Sjfv *  e1000_cfg_on_link_up_80003es2lan - es2 link configuration after link-up
1258185353Sjfv *  @hw: pointer to the HW structure
1259185353Sjfv *  @duplex: current duplex setting
1260185353Sjfv *
1261185353Sjfv *  Configure the KMRN interface by applying last minute quirks for
1262185353Sjfv *  10/100 operation.
1263185353Sjfv **/
1264185353Sjfvstatic s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw)
1265185353Sjfv{
1266185353Sjfv	s32 ret_val = E1000_SUCCESS;
1267185353Sjfv	u16 speed;
1268185353Sjfv	u16 duplex;
1269185353Sjfv
1270185353Sjfv	DEBUGFUNC("e1000_configure_on_link_up");
1271185353Sjfv
1272185353Sjfv	if (hw->phy.media_type == e1000_media_type_copper) {
1273185353Sjfv		ret_val = e1000_get_speed_and_duplex_copper_generic(hw,
1274185353Sjfv		                                                    &speed,
1275185353Sjfv		                                                    &duplex);
1276185353Sjfv		if (ret_val)
1277185353Sjfv			goto out;
1278185353Sjfv
1279185353Sjfv		if (speed == SPEED_1000)
1280185353Sjfv			ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw);
1281185353Sjfv		else
1282185353Sjfv			ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, duplex);
1283185353Sjfv	}
1284185353Sjfv
1285185353Sjfvout:
1286185353Sjfv	return ret_val;
1287185353Sjfv}
1288185353Sjfv
1289185353Sjfv/**
1290169240Sjfv *  e1000_cfg_kmrn_10_100_80003es2lan - Apply "quirks" for 10/100 operation
1291169589Sjfv *  @hw: pointer to the HW structure
1292169589Sjfv *  @duplex: current duplex setting
1293169240Sjfv *
1294169240Sjfv *  Configure the KMRN interface by applying last minute quirks for
1295169240Sjfv *  10/100 operation.
1296169240Sjfv **/
1297173788Sjfvstatic s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex)
1298169240Sjfv{
1299169240Sjfv	s32 ret_val = E1000_SUCCESS;
1300169240Sjfv	u32 tipg;
1301169589Sjfv	u32 i = 0;
1302169589Sjfv	u16 reg_data, reg_data2;
1303169240Sjfv
1304169240Sjfv	DEBUGFUNC("e1000_configure_kmrn_for_10_100");
1305169240Sjfv
1306169240Sjfv	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT;
1307185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
1308169240Sjfv	                               E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
1309169240Sjfv	                               reg_data);
1310169240Sjfv	if (ret_val)
1311169240Sjfv		goto out;
1312169240Sjfv
1313169240Sjfv	/* Configure Transmit Inter-Packet Gap */
1314169240Sjfv	tipg = E1000_READ_REG(hw, E1000_TIPG);
1315169240Sjfv	tipg &= ~E1000_TIPG_IPGT_MASK;
1316169240Sjfv	tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN;
1317169240Sjfv	E1000_WRITE_REG(hw, E1000_TIPG, tipg);
1318169240Sjfv
1319169589Sjfv	do {
1320177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1321185353Sjfv		                               &reg_data);
1322169589Sjfv		if (ret_val)
1323169589Sjfv			goto out;
1324169589Sjfv
1325177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1326185353Sjfv		                               &reg_data2);
1327169589Sjfv		if (ret_val)
1328169589Sjfv			goto out;
1329169589Sjfv		i++;
1330169589Sjfv	} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));
1331169589Sjfv
1332169240Sjfv	if (duplex == HALF_DUPLEX)
1333169240Sjfv		reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER;
1334169240Sjfv	else
1335169240Sjfv		reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
1336169240Sjfv
1337177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
1338169240Sjfv
1339169240Sjfvout:
1340169240Sjfv	return ret_val;
1341169240Sjfv}
1342169240Sjfv
1343169240Sjfv/**
1344169240Sjfv *  e1000_cfg_kmrn_1000_80003es2lan - Apply "quirks" for gigabit operation
1345169589Sjfv *  @hw: pointer to the HW structure
1346169240Sjfv *
1347169240Sjfv *  Configure the KMRN interface by applying last minute quirks for
1348169240Sjfv *  gigabit operation.
1349169240Sjfv **/
1350173788Sjfvstatic s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
1351169240Sjfv{
1352169240Sjfv	s32 ret_val = E1000_SUCCESS;
1353169589Sjfv	u16 reg_data, reg_data2;
1354169240Sjfv	u32 tipg;
1355169589Sjfv	u32 i = 0;
1356169240Sjfv
1357169240Sjfv	DEBUGFUNC("e1000_configure_kmrn_for_1000");
1358169240Sjfv
1359169240Sjfv	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT;
1360185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
1361169240Sjfv	                               E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
1362169240Sjfv	                               reg_data);
1363169240Sjfv	if (ret_val)
1364169240Sjfv		goto out;
1365169240Sjfv
1366169240Sjfv	/* Configure Transmit Inter-Packet Gap */
1367169240Sjfv	tipg = E1000_READ_REG(hw, E1000_TIPG);
1368169240Sjfv	tipg &= ~E1000_TIPG_IPGT_MASK;
1369169240Sjfv	tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN;
1370169240Sjfv	E1000_WRITE_REG(hw, E1000_TIPG, tipg);
1371169240Sjfv
1372169589Sjfv	do {
1373177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1374185353Sjfv		                               &reg_data);
1375169589Sjfv		if (ret_val)
1376169589Sjfv			goto out;
1377169589Sjfv
1378177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1379185353Sjfv		                               &reg_data2);
1380169589Sjfv		if (ret_val)
1381169589Sjfv			goto out;
1382169589Sjfv		i++;
1383169589Sjfv	} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));
1384169589Sjfv
1385169240Sjfv	reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
1386177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
1387169240Sjfv
1388169240Sjfvout:
1389169240Sjfv	return ret_val;
1390169240Sjfv}
1391169240Sjfv
1392169240Sjfv/**
1393185353Sjfv *  e1000_read_kmrn_reg_80003es2lan - Read kumeran register
1394185353Sjfv *  @hw: pointer to the HW structure
1395185353Sjfv *  @offset: register offset to be read
1396185353Sjfv *  @data: pointer to the read data
1397185353Sjfv *
1398185353Sjfv *  Acquire semaphore, then read the PHY register at offset
1399185353Sjfv *  using the kumeran interface.  The information retrieved is stored in data.
1400185353Sjfv *  Release the semaphore before exiting.
1401185353Sjfv **/
1402190872Sjfvstatic s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
1403190872Sjfv                                           u16 *data)
1404185353Sjfv{
1405185353Sjfv	u32 kmrnctrlsta;
1406185353Sjfv	s32 ret_val = E1000_SUCCESS;
1407185353Sjfv
1408185353Sjfv	DEBUGFUNC("e1000_read_kmrn_reg_80003es2lan");
1409185353Sjfv
1410185353Sjfv	ret_val = e1000_acquire_mac_csr_80003es2lan(hw);
1411185353Sjfv	if (ret_val)
1412185353Sjfv		goto out;
1413185353Sjfv
1414185353Sjfv	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
1415185353Sjfv	               E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
1416185353Sjfv	E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
1417185353Sjfv
1418185353Sjfv	usec_delay(2);
1419185353Sjfv
1420185353Sjfv	kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA);
1421185353Sjfv	*data = (u16)kmrnctrlsta;
1422185353Sjfv
1423185353Sjfv	e1000_release_mac_csr_80003es2lan(hw);
1424185353Sjfv
1425185353Sjfvout:
1426185353Sjfv	return ret_val;
1427185353Sjfv}
1428185353Sjfv
1429185353Sjfv/**
1430185353Sjfv *  e1000_write_kmrn_reg_80003es2lan - Write kumeran register
1431185353Sjfv *  @hw: pointer to the HW structure
1432185353Sjfv *  @offset: register offset to write to
1433185353Sjfv *  @data: data to write at register offset
1434185353Sjfv *
1435185353Sjfv *  Acquire semaphore, then write the data to PHY register
1436185353Sjfv *  at the offset using the kumeran interface.  Release semaphore
1437185353Sjfv *  before exiting.
1438185353Sjfv **/
1439190872Sjfvstatic s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
1440190872Sjfv                                            u16 data)
1441185353Sjfv{
1442185353Sjfv	u32 kmrnctrlsta;
1443185353Sjfv	s32 ret_val = E1000_SUCCESS;
1444185353Sjfv
1445185353Sjfv	DEBUGFUNC("e1000_write_kmrn_reg_80003es2lan");
1446185353Sjfv
1447185353Sjfv	ret_val = e1000_acquire_mac_csr_80003es2lan(hw);
1448185353Sjfv	if (ret_val)
1449185353Sjfv		goto out;
1450185353Sjfv
1451185353Sjfv	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
1452185353Sjfv	               E1000_KMRNCTRLSTA_OFFSET) | data;
1453185353Sjfv	E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
1454185353Sjfv
1455185353Sjfv	usec_delay(2);
1456185353Sjfv
1457185353Sjfv	e1000_release_mac_csr_80003es2lan(hw);
1458185353Sjfv
1459185353Sjfvout:
1460185353Sjfv	return ret_val;
1461185353Sjfv}
1462185353Sjfv
1463185353Sjfv/**
1464176667Sjfv *  e1000_read_mac_addr_80003es2lan - Read device MAC address
1465176667Sjfv *  @hw: pointer to the HW structure
1466176667Sjfv **/
1467177867Sjfvstatic s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw)
1468176667Sjfv{
1469176667Sjfv	s32 ret_val = E1000_SUCCESS;
1470176667Sjfv
1471176667Sjfv	DEBUGFUNC("e1000_read_mac_addr_80003es2lan");
1472176667Sjfv
1473190872Sjfv	/*
1474190872Sjfv	 * If there's an alternate MAC address place it in RAR0
1475190872Sjfv	 * so that it will override the Si installed default perm
1476190872Sjfv	 * address.
1477190872Sjfv	 */
1478190872Sjfv	ret_val = e1000_check_alt_mac_addr_generic(hw);
1479190872Sjfv	if (ret_val)
1480190872Sjfv		goto out;
1481190872Sjfv
1482190872Sjfv	ret_val = e1000_read_mac_addr_generic(hw);
1483190872Sjfv
1484190872Sjfvout:
1485176667Sjfv	return ret_val;
1486176667Sjfv}
1487176667Sjfv
1488176667Sjfv/**
1489173788Sjfv * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down
1490173788Sjfv * @hw: pointer to the HW structure
1491173788Sjfv *
1492173788Sjfv * In the case of a PHY power down to save power, or to turn off link during a
1493173788Sjfv * driver unload, or wake on lan is not enabled, remove the link.
1494173788Sjfv **/
1495177867Sjfvstatic void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw)
1496173788Sjfv{
1497173788Sjfv	/* If the management interface is not enabled, then power down */
1498177867Sjfv	if (!(hw->mac.ops.check_mng_mode(hw) ||
1499177867Sjfv	      hw->phy.ops.check_reset_block(hw)))
1500173788Sjfv		e1000_power_down_phy_copper(hw);
1501173788Sjfv
1502173788Sjfv	return;
1503173788Sjfv}
1504173788Sjfv
1505173788Sjfv/**
1506169240Sjfv *  e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters
1507169589Sjfv *  @hw: pointer to the HW structure
1508169240Sjfv *
1509169240Sjfv *  Clears the hardware counters by reading the counter registers.
1510169240Sjfv **/
1511177867Sjfvstatic void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
1512169240Sjfv{
1513169240Sjfv	DEBUGFUNC("e1000_clear_hw_cntrs_80003es2lan");
1514169240Sjfv
1515169240Sjfv	e1000_clear_hw_cntrs_base_generic(hw);
1516169240Sjfv
1517185353Sjfv	E1000_READ_REG(hw, E1000_PRC64);
1518185353Sjfv	E1000_READ_REG(hw, E1000_PRC127);
1519185353Sjfv	E1000_READ_REG(hw, E1000_PRC255);
1520185353Sjfv	E1000_READ_REG(hw, E1000_PRC511);
1521185353Sjfv	E1000_READ_REG(hw, E1000_PRC1023);
1522185353Sjfv	E1000_READ_REG(hw, E1000_PRC1522);
1523185353Sjfv	E1000_READ_REG(hw, E1000_PTC64);
1524185353Sjfv	E1000_READ_REG(hw, E1000_PTC127);
1525185353Sjfv	E1000_READ_REG(hw, E1000_PTC255);
1526185353Sjfv	E1000_READ_REG(hw, E1000_PTC511);
1527185353Sjfv	E1000_READ_REG(hw, E1000_PTC1023);
1528185353Sjfv	E1000_READ_REG(hw, E1000_PTC1522);
1529169240Sjfv
1530185353Sjfv	E1000_READ_REG(hw, E1000_ALGNERRC);
1531185353Sjfv	E1000_READ_REG(hw, E1000_RXERRC);
1532185353Sjfv	E1000_READ_REG(hw, E1000_TNCRS);
1533185353Sjfv	E1000_READ_REG(hw, E1000_CEXTERR);
1534185353Sjfv	E1000_READ_REG(hw, E1000_TSCTC);
1535185353Sjfv	E1000_READ_REG(hw, E1000_TSCTFC);
1536169240Sjfv
1537185353Sjfv	E1000_READ_REG(hw, E1000_MGTPRC);
1538185353Sjfv	E1000_READ_REG(hw, E1000_MGTPDC);
1539185353Sjfv	E1000_READ_REG(hw, E1000_MGTPTC);
1540169240Sjfv
1541185353Sjfv	E1000_READ_REG(hw, E1000_IAC);
1542185353Sjfv	E1000_READ_REG(hw, E1000_ICRXOC);
1543169240Sjfv
1544185353Sjfv	E1000_READ_REG(hw, E1000_ICRXPTC);
1545185353Sjfv	E1000_READ_REG(hw, E1000_ICRXATC);
1546185353Sjfv	E1000_READ_REG(hw, E1000_ICTXPTC);
1547185353Sjfv	E1000_READ_REG(hw, E1000_ICTXATC);
1548185353Sjfv	E1000_READ_REG(hw, E1000_ICTXQEC);
1549185353Sjfv	E1000_READ_REG(hw, E1000_ICTXQMTC);
1550185353Sjfv	E1000_READ_REG(hw, E1000_ICRXDMTC);
1551169240Sjfv}
1552