e1000_80003es2lan.c revision 190872
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 190872 2009-04-10 00:05:46Z 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
174169240Sjfv	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	s32 ret_val = E1000_SUCCESS;
210169240Sjfv
211169240Sjfv	DEBUGFUNC("e1000_init_mac_params_80003es2lan");
212169240Sjfv
213169240Sjfv	/* Set media type */
214169240Sjfv	switch (hw->device_id) {
215169240Sjfv	case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
216173788Sjfv		hw->phy.media_type = e1000_media_type_internal_serdes;
217169240Sjfv		break;
218169240Sjfv	default:
219173788Sjfv		hw->phy.media_type = e1000_media_type_copper;
220169240Sjfv		break;
221169240Sjfv	}
222169240Sjfv
223169240Sjfv	/* Set mta register count */
224169240Sjfv	mac->mta_reg_count = 128;
225169240Sjfv	/* Set rar entry count */
226169240Sjfv	mac->rar_entry_count = E1000_RAR_ENTRIES;
227169240Sjfv	/* Set if part includes ASF firmware */
228169240Sjfv	mac->asf_firmware_present = TRUE;
229169240Sjfv	/* Set if manageability features are enabled. */
230169240Sjfv	mac->arc_subsystem_valid =
231169240Sjfv	        (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
232169240Sjfv	                ? TRUE : FALSE;
233169240Sjfv
234169240Sjfv	/* Function pointers */
235169240Sjfv
236169240Sjfv	/* bus type/speed/width */
237177867Sjfv	mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic;
238169240Sjfv	/* reset */
239177867Sjfv	mac->ops.reset_hw = e1000_reset_hw_80003es2lan;
240169240Sjfv	/* hw initialization */
241177867Sjfv	mac->ops.init_hw = e1000_init_hw_80003es2lan;
242169240Sjfv	/* link setup */
243177867Sjfv	mac->ops.setup_link = e1000_setup_link_generic;
244169240Sjfv	/* physical interface link setup */
245177867Sjfv	mac->ops.setup_physical_interface =
246173788Sjfv	        (hw->phy.media_type == e1000_media_type_copper)
247169240Sjfv	                ? e1000_setup_copper_link_80003es2lan
248169240Sjfv	                : e1000_setup_fiber_serdes_link_generic;
249169240Sjfv	/* check for link */
250173788Sjfv	switch (hw->phy.media_type) {
251169240Sjfv	case e1000_media_type_copper:
252177867Sjfv		mac->ops.check_for_link = e1000_check_for_copper_link_generic;
253169240Sjfv		break;
254169240Sjfv	case e1000_media_type_fiber:
255177867Sjfv		mac->ops.check_for_link = e1000_check_for_fiber_link_generic;
256169240Sjfv		break;
257169240Sjfv	case e1000_media_type_internal_serdes:
258177867Sjfv		mac->ops.check_for_link = e1000_check_for_serdes_link_generic;
259169240Sjfv		break;
260169240Sjfv	default:
261169240Sjfv		ret_val = -E1000_ERR_CONFIG;
262169240Sjfv		goto out;
263169240Sjfv		break;
264169240Sjfv	}
265169240Sjfv	/* check management mode */
266177867Sjfv	mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
267169240Sjfv	/* multicast address update */
268177867Sjfv	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
269169240Sjfv	/* writing VFTA */
270177867Sjfv	mac->ops.write_vfta = e1000_write_vfta_generic;
271169240Sjfv	/* clearing VFTA */
272177867Sjfv	mac->ops.clear_vfta = e1000_clear_vfta_generic;
273169240Sjfv	/* setting MTA */
274177867Sjfv	mac->ops.mta_set = e1000_mta_set_generic;
275176667Sjfv	/* read mac address */
276177867Sjfv	mac->ops.read_mac_addr = e1000_read_mac_addr_80003es2lan;
277190872Sjfv	/* ID LED init */
278190872Sjfv	mac->ops.id_led_init = e1000_id_led_init_generic;
279169240Sjfv	/* blink LED */
280177867Sjfv	mac->ops.blink_led = e1000_blink_led_generic;
281169240Sjfv	/* setup LED */
282177867Sjfv	mac->ops.setup_led = e1000_setup_led_generic;
283169240Sjfv	/* cleanup LED */
284177867Sjfv	mac->ops.cleanup_led = e1000_cleanup_led_generic;
285169240Sjfv	/* turn on/off LED */
286177867Sjfv	mac->ops.led_on = e1000_led_on_generic;
287177867Sjfv	mac->ops.led_off = e1000_led_off_generic;
288169240Sjfv	/* clear hardware counters */
289177867Sjfv	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan;
290169240Sjfv	/* link info */
291177867Sjfv	mac->ops.get_link_up_info = e1000_get_link_up_info_80003es2lan;
292169240Sjfv
293169240Sjfvout:
294169240Sjfv	return ret_val;
295169240Sjfv}
296169240Sjfv
297169240Sjfv/**
298169240Sjfv *  e1000_init_function_pointers_80003es2lan - Init ESB2 func ptrs.
299169589Sjfv *  @hw: pointer to the HW structure
300169240Sjfv *
301185353Sjfv *  Called to initialize all function pointers and parameters.
302169240Sjfv **/
303173788Sjfvvoid e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw)
304169240Sjfv{
305169240Sjfv	DEBUGFUNC("e1000_init_function_pointers_80003es2lan");
306169240Sjfv
307177867Sjfv	hw->mac.ops.init_params = e1000_init_mac_params_80003es2lan;
308177867Sjfv	hw->nvm.ops.init_params = e1000_init_nvm_params_80003es2lan;
309177867Sjfv	hw->phy.ops.init_params = e1000_init_phy_params_80003es2lan;
310185353Sjfv	e1000_get_bus_info_pcie_generic(hw);
311169240Sjfv}
312169240Sjfv
313169240Sjfv/**
314169240Sjfv *  e1000_acquire_phy_80003es2lan - Acquire rights to access PHY
315169589Sjfv *  @hw: pointer to the HW structure
316169240Sjfv *
317185353Sjfv *  A wrapper to acquire access rights to the correct PHY.
318169240Sjfv **/
319177867Sjfvstatic s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw)
320169240Sjfv{
321169240Sjfv	u16 mask;
322169240Sjfv
323169240Sjfv	DEBUGFUNC("e1000_acquire_phy_80003es2lan");
324169240Sjfv
325169240Sjfv	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
326169240Sjfv	return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
327169240Sjfv}
328169240Sjfv
329169240Sjfv/**
330169240Sjfv *  e1000_release_phy_80003es2lan - Release rights to access PHY
331169589Sjfv *  @hw: pointer to the HW structure
332169240Sjfv *
333185353Sjfv *  A wrapper to release access rights to the correct PHY.
334169240Sjfv **/
335177867Sjfvstatic void e1000_release_phy_80003es2lan(struct e1000_hw *hw)
336169240Sjfv{
337169240Sjfv	u16 mask;
338169240Sjfv
339169240Sjfv	DEBUGFUNC("e1000_release_phy_80003es2lan");
340169240Sjfv
341169240Sjfv	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
342185353Sjfv	e1000_release_swfw_sync_80003es2lan(hw, mask);
343185353Sjfv}
344176667Sjfv
345185353Sjfv
346185353Sjfv/**
347185353Sjfv *  e1000_acquire_mac_csr_80003es2lan - Acquire rights to access Kumeran register
348185353Sjfv *  @hw: pointer to the HW structure
349185353Sjfv *
350185353Sjfv *  Acquire the semaphore to access the Kumeran interface.
351185353Sjfv *
352185353Sjfv **/
353185353Sjfvstatic s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw)
354185353Sjfv{
355185353Sjfv	u16 mask;
356185353Sjfv
357185353Sjfv	DEBUGFUNC("e1000_acquire_mac_csr_80003es2lan");
358185353Sjfv
359185353Sjfv	mask = E1000_SWFW_CSR_SM;
360185353Sjfv
361185353Sjfv	return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
362185353Sjfv}
363185353Sjfv
364185353Sjfv/**
365185353Sjfv *  e1000_release_mac_csr_80003es2lan - Release rights to access Kumeran Register
366185353Sjfv *  @hw: pointer to the HW structure
367185353Sjfv *
368185353Sjfv *  Release the semaphore used to access the Kumeran interface
369185353Sjfv **/
370185353Sjfvstatic void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw)
371185353Sjfv{
372185353Sjfv	u16 mask;
373185353Sjfv
374185353Sjfv	DEBUGFUNC("e1000_release_mac_csr_80003es2lan");
375185353Sjfv
376185353Sjfv	mask = E1000_SWFW_CSR_SM;
377185353Sjfv
378169240Sjfv	e1000_release_swfw_sync_80003es2lan(hw, mask);
379169240Sjfv}
380169240Sjfv
381169240Sjfv/**
382169240Sjfv *  e1000_acquire_nvm_80003es2lan - Acquire rights to access NVM
383169589Sjfv *  @hw: pointer to the HW structure
384169240Sjfv *
385185353Sjfv *  Acquire the semaphore to access the EEPROM.
386169240Sjfv **/
387177867Sjfvstatic s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw)
388169240Sjfv{
389169240Sjfv	s32 ret_val;
390169240Sjfv
391169240Sjfv	DEBUGFUNC("e1000_acquire_nvm_80003es2lan");
392169240Sjfv
393169240Sjfv	ret_val = e1000_acquire_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);
394169240Sjfv	if (ret_val)
395169240Sjfv		goto out;
396169240Sjfv
397169240Sjfv	ret_val = e1000_acquire_nvm_generic(hw);
398169240Sjfv
399169240Sjfv	if (ret_val)
400169240Sjfv		e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);
401169240Sjfv
402169240Sjfvout:
403169240Sjfv	return ret_val;
404169240Sjfv}
405169240Sjfv
406169240Sjfv/**
407169240Sjfv *  e1000_release_nvm_80003es2lan - Relinquish rights to access NVM
408169589Sjfv *  @hw: pointer to the HW structure
409169240Sjfv *
410185353Sjfv *  Release the semaphore used to access the EEPROM.
411169240Sjfv **/
412177867Sjfvstatic void e1000_release_nvm_80003es2lan(struct e1000_hw *hw)
413169240Sjfv{
414169240Sjfv	DEBUGFUNC("e1000_release_nvm_80003es2lan");
415169240Sjfv
416169240Sjfv	e1000_release_nvm_generic(hw);
417169240Sjfv	e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);
418169240Sjfv}
419169240Sjfv
420169240Sjfv/**
421169240Sjfv *  e1000_acquire_swfw_sync_80003es2lan - Acquire SW/FW semaphore
422169589Sjfv *  @hw: pointer to the HW structure
423169589Sjfv *  @mask: specifies which semaphore to acquire
424169240Sjfv *
425169240Sjfv *  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
426169240Sjfv *  will also specify which port we're acquiring the lock for.
427169240Sjfv **/
428173788Sjfvstatic s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask)
429169240Sjfv{
430169240Sjfv	u32 swfw_sync;
431169240Sjfv	u32 swmask = mask;
432169240Sjfv	u32 fwmask = mask << 16;
433169240Sjfv	s32 ret_val = E1000_SUCCESS;
434185353Sjfv	s32 i = 0, timeout = 50;
435169240Sjfv
436169240Sjfv	DEBUGFUNC("e1000_acquire_swfw_sync_80003es2lan");
437169240Sjfv
438169240Sjfv	while (i < timeout) {
439169589Sjfv		if (e1000_get_hw_semaphore_generic(hw)) {
440169240Sjfv			ret_val = -E1000_ERR_SWFW_SYNC;
441169240Sjfv			goto out;
442169240Sjfv		}
443169240Sjfv
444169240Sjfv		swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
445169240Sjfv		if (!(swfw_sync & (fwmask | swmask)))
446169240Sjfv			break;
447169240Sjfv
448173788Sjfv		/*
449173788Sjfv		 * Firmware currently using resource (fwmask)
450173788Sjfv		 * or other software thread using resource (swmask)
451173788Sjfv		 */
452169589Sjfv		e1000_put_hw_semaphore_generic(hw);
453169240Sjfv		msec_delay_irq(5);
454169240Sjfv		i++;
455169240Sjfv	}
456169240Sjfv
457169240Sjfv	if (i == timeout) {
458169240Sjfv		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
459169240Sjfv		ret_val = -E1000_ERR_SWFW_SYNC;
460169240Sjfv		goto out;
461169240Sjfv	}
462169240Sjfv
463169240Sjfv	swfw_sync |= swmask;
464169240Sjfv	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
465169240Sjfv
466169589Sjfv	e1000_put_hw_semaphore_generic(hw);
467169240Sjfv
468169240Sjfvout:
469169240Sjfv	return ret_val;
470169240Sjfv}
471169240Sjfv
472169240Sjfv/**
473169240Sjfv *  e1000_release_swfw_sync_80003es2lan - Release SW/FW semaphore
474169589Sjfv *  @hw: pointer to the HW structure
475169589Sjfv *  @mask: specifies which semaphore to acquire
476169240Sjfv *
477169240Sjfv *  Release the SW/FW semaphore used to access the PHY or NVM.  The mask
478169240Sjfv *  will also specify which port we're releasing the lock for.
479169240Sjfv **/
480173788Sjfvstatic void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask)
481169240Sjfv{
482169240Sjfv	u32 swfw_sync;
483169240Sjfv
484169240Sjfv	DEBUGFUNC("e1000_release_swfw_sync_80003es2lan");
485169240Sjfv
486185353Sjfv	while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS)
487185353Sjfv		; /* Empty */
488169240Sjfv
489169240Sjfv	swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
490169240Sjfv	swfw_sync &= ~mask;
491169240Sjfv	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
492169240Sjfv
493169589Sjfv	e1000_put_hw_semaphore_generic(hw);
494169240Sjfv}
495169240Sjfv
496169240Sjfv/**
497169240Sjfv *  e1000_read_phy_reg_gg82563_80003es2lan - Read GG82563 PHY register
498169589Sjfv *  @hw: pointer to the HW structure
499169589Sjfv *  @offset: offset of the register to read
500169589Sjfv *  @data: pointer to the data returned from the operation
501169240Sjfv *
502185353Sjfv *  Read the GG82563 PHY register.
503169240Sjfv **/
504177867Sjfvstatic s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
505173788Sjfv                                                  u32 offset, u16 *data)
506169240Sjfv{
507169240Sjfv	s32 ret_val;
508169240Sjfv	u32 page_select;
509169240Sjfv	u16 temp;
510169240Sjfv
511169240Sjfv	DEBUGFUNC("e1000_read_phy_reg_gg82563_80003es2lan");
512169240Sjfv
513176667Sjfv	ret_val = e1000_acquire_phy_80003es2lan(hw);
514176667Sjfv	if (ret_val)
515176667Sjfv		goto out;
516176667Sjfv
517169240Sjfv	/* Select Configuration Page */
518173788Sjfv	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
519169240Sjfv		page_select = GG82563_PHY_PAGE_SELECT;
520173788Sjfv	} else {
521173788Sjfv		/*
522173788Sjfv		 * Use Alternative Page Select register to access
523169240Sjfv		 * registers 30 and 31
524169240Sjfv		 */
525169240Sjfv		page_select = GG82563_PHY_PAGE_SELECT_ALT;
526169240Sjfv	}
527169240Sjfv
528169240Sjfv	temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT);
529176667Sjfv	ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp);
530176667Sjfv	if (ret_val) {
531176667Sjfv		e1000_release_phy_80003es2lan(hw);
532169240Sjfv		goto out;
533176667Sjfv	}
534169240Sjfv
535173788Sjfv	/*
536173788Sjfv	 * The "ready" bit in the MDIC register may be incorrectly set
537169240Sjfv	 * before the device has completed the "Page Select" MDI
538169240Sjfv	 * transaction.  So we wait 200us after each MDI command...
539169240Sjfv	 */
540169240Sjfv	usec_delay(200);
541169240Sjfv
542169240Sjfv	/* ...and verify the command was successful. */
543176667Sjfv	ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
544169240Sjfv
545169240Sjfv	if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
546169240Sjfv		ret_val = -E1000_ERR_PHY;
547176667Sjfv		e1000_release_phy_80003es2lan(hw);
548169240Sjfv		goto out;
549169240Sjfv	}
550169240Sjfv
551169240Sjfv	usec_delay(200);
552169240Sjfv
553185353Sjfv	ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
554185353Sjfv	                                   data);
555169240Sjfv
556169240Sjfv	usec_delay(200);
557176667Sjfv	e1000_release_phy_80003es2lan(hw);
558169240Sjfv
559169240Sjfvout:
560169240Sjfv	return ret_val;
561169240Sjfv}
562169240Sjfv
563169240Sjfv/**
564169240Sjfv *  e1000_write_phy_reg_gg82563_80003es2lan - Write GG82563 PHY register
565169589Sjfv *  @hw: pointer to the HW structure
566169589Sjfv *  @offset: offset of the register to read
567169589Sjfv *  @data: value to write to the register
568169240Sjfv *
569185353Sjfv *  Write to the GG82563 PHY register.
570169240Sjfv **/
571177867Sjfvstatic s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
572173788Sjfv                                                   u32 offset, u16 data)
573169240Sjfv{
574169240Sjfv	s32 ret_val;
575169240Sjfv	u32 page_select;
576169240Sjfv	u16 temp;
577169240Sjfv
578169240Sjfv	DEBUGFUNC("e1000_write_phy_reg_gg82563_80003es2lan");
579169240Sjfv
580176667Sjfv	ret_val = e1000_acquire_phy_80003es2lan(hw);
581176667Sjfv	if (ret_val)
582176667Sjfv		goto out;
583176667Sjfv
584169240Sjfv	/* Select Configuration Page */
585173788Sjfv	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
586169240Sjfv		page_select = GG82563_PHY_PAGE_SELECT;
587173788Sjfv	} else {
588173788Sjfv		/*
589173788Sjfv		 * Use Alternative Page Select register to access
590169240Sjfv		 * registers 30 and 31
591169240Sjfv		 */
592169240Sjfv		page_select = GG82563_PHY_PAGE_SELECT_ALT;
593169240Sjfv	}
594169240Sjfv
595169240Sjfv	temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT);
596176667Sjfv	ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp);
597176667Sjfv	if (ret_val) {
598176667Sjfv		e1000_release_phy_80003es2lan(hw);
599169240Sjfv		goto out;
600176667Sjfv	}
601169240Sjfv
602169240Sjfv
603173788Sjfv	/*
604173788Sjfv	 * The "ready" bit in the MDIC register may be incorrectly set
605169240Sjfv	 * before the device has completed the "Page Select" MDI
606169240Sjfv	 * transaction.  So we wait 200us after each MDI command...
607169240Sjfv	 */
608169240Sjfv	usec_delay(200);
609169240Sjfv
610169240Sjfv	/* ...and verify the command was successful. */
611176667Sjfv	ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
612169240Sjfv
613169240Sjfv	if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
614169240Sjfv		ret_val = -E1000_ERR_PHY;
615176667Sjfv		e1000_release_phy_80003es2lan(hw);
616169240Sjfv		goto out;
617169240Sjfv	}
618169240Sjfv
619169240Sjfv	usec_delay(200);
620169240Sjfv
621185353Sjfv	ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
622169240Sjfv	                                  data);
623169240Sjfv
624169240Sjfv	usec_delay(200);
625176667Sjfv	e1000_release_phy_80003es2lan(hw);
626169240Sjfv
627169240Sjfvout:
628169240Sjfv	return ret_val;
629169240Sjfv}
630169240Sjfv
631169240Sjfv/**
632169240Sjfv *  e1000_write_nvm_80003es2lan - Write to ESB2 NVM
633169589Sjfv *  @hw: pointer to the HW structure
634169589Sjfv *  @offset: offset of the register to read
635169589Sjfv *  @words: number of words to write
636169589Sjfv *  @data: buffer of data to write to the NVM
637169240Sjfv *
638185353Sjfv *  Write "words" of data to the ESB2 NVM.
639169240Sjfv **/
640177867Sjfvstatic s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset,
641169240Sjfv                            u16 words, u16 *data)
642169240Sjfv{
643169240Sjfv	DEBUGFUNC("e1000_write_nvm_80003es2lan");
644169240Sjfv
645169240Sjfv	return e1000_write_nvm_spi(hw, offset, words, data);
646169240Sjfv}
647169240Sjfv
648169240Sjfv/**
649169240Sjfv *  e1000_get_cfg_done_80003es2lan - Wait for configuration to complete
650169589Sjfv *  @hw: pointer to the HW structure
651169240Sjfv *
652169240Sjfv *  Wait a specific amount of time for manageability processes to complete.
653169240Sjfv *  This is a function pointer entry point called by the phy module.
654169240Sjfv **/
655177867Sjfvstatic s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw)
656169240Sjfv{
657169240Sjfv	s32 timeout = PHY_CFG_TIMEOUT;
658169240Sjfv	s32 ret_val = E1000_SUCCESS;
659169240Sjfv	u32 mask = E1000_NVM_CFG_DONE_PORT_0;
660169240Sjfv
661169240Sjfv	DEBUGFUNC("e1000_get_cfg_done_80003es2lan");
662169240Sjfv
663169240Sjfv	if (hw->bus.func == 1)
664169240Sjfv		mask = E1000_NVM_CFG_DONE_PORT_1;
665169240Sjfv
666169240Sjfv	while (timeout) {
667169240Sjfv		if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask)
668169240Sjfv			break;
669169240Sjfv		msec_delay(1);
670169240Sjfv		timeout--;
671169240Sjfv	}
672169240Sjfv	if (!timeout) {
673169240Sjfv		DEBUGOUT("MNG configuration cycle has not completed.\n");
674169240Sjfv		ret_val = -E1000_ERR_RESET;
675169240Sjfv		goto out;
676169240Sjfv	}
677169240Sjfv
678169240Sjfvout:
679169240Sjfv	return ret_val;
680169240Sjfv}
681169240Sjfv
682169240Sjfv/**
683169240Sjfv *  e1000_phy_force_speed_duplex_80003es2lan - Force PHY speed and duplex
684169589Sjfv *  @hw: pointer to the HW structure
685169240Sjfv *
686169240Sjfv *  Force the speed and duplex settings onto the PHY.  This is a
687169240Sjfv *  function pointer entry point called by the phy module.
688169240Sjfv **/
689177867Sjfvstatic s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
690169240Sjfv{
691177867Sjfv	s32 ret_val = E1000_SUCCESS;
692169240Sjfv	u16 phy_data;
693173788Sjfv	bool link;
694169240Sjfv
695169240Sjfv	DEBUGFUNC("e1000_phy_force_speed_duplex_80003es2lan");
696169240Sjfv
697177867Sjfv	if (!(hw->phy.ops.read_reg))
698177867Sjfv		goto out;
699177867Sjfv
700173788Sjfv	/*
701173788Sjfv	 * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
702169240Sjfv	 * forced whenever speed and duplex are forced.
703169240Sjfv	 */
704177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
705169240Sjfv	if (ret_val)
706169240Sjfv		goto out;
707169240Sjfv
708169240Sjfv	phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO;
709177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data);
710169240Sjfv	if (ret_val)
711169240Sjfv		goto out;
712169240Sjfv
713169240Sjfv	DEBUGOUT1("GG82563 PSCR: %X\n", phy_data);
714169240Sjfv
715177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_data);
716169240Sjfv	if (ret_val)
717169240Sjfv		goto out;
718169240Sjfv
719169240Sjfv	e1000_phy_force_speed_duplex_setup(hw, &phy_data);
720169240Sjfv
721169240Sjfv	/* Reset the phy to commit changes. */
722169240Sjfv	phy_data |= MII_CR_RESET;
723169240Sjfv
724177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_data);
725169240Sjfv	if (ret_val)
726169240Sjfv		goto out;
727169240Sjfv
728169240Sjfv	usec_delay(1);
729169240Sjfv
730173788Sjfv	if (hw->phy.autoneg_wait_to_complete) {
731169240Sjfv		DEBUGOUT("Waiting for forced speed/duplex link "
732169240Sjfv		         "on GG82563 phy.\n");
733169240Sjfv
734169240Sjfv		ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
735169240Sjfv		                                     100000, &link);
736169240Sjfv		if (ret_val)
737169240Sjfv			goto out;
738169240Sjfv
739169240Sjfv		if (!link) {
740173788Sjfv			/*
741173788Sjfv			 * We didn't get link.
742169240Sjfv			 * Reset the DSP and cross our fingers.
743169240Sjfv			 */
744169240Sjfv			ret_val = e1000_phy_reset_dsp_generic(hw);
745169240Sjfv			if (ret_val)
746169240Sjfv				goto out;
747169240Sjfv		}
748169240Sjfv
749169240Sjfv		/* Try once more */
750169240Sjfv		ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
751169240Sjfv		                                     100000, &link);
752169240Sjfv		if (ret_val)
753169240Sjfv			goto out;
754169240Sjfv	}
755169240Sjfv
756177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data);
757169240Sjfv	if (ret_val)
758169240Sjfv		goto out;
759169240Sjfv
760173788Sjfv	/*
761173788Sjfv	 * Resetting the phy means we need to verify the TX_CLK corresponds
762169240Sjfv	 * to the link speed.  10Mbps -> 2.5MHz, else 25MHz.
763169240Sjfv	 */
764169240Sjfv	phy_data &= ~GG82563_MSCR_TX_CLK_MASK;
765169240Sjfv	if (hw->mac.forced_speed_duplex & E1000_ALL_10_SPEED)
766169240Sjfv		phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5;
767169240Sjfv	else
768169240Sjfv		phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25;
769169240Sjfv
770173788Sjfv	/*
771173788Sjfv	 * In addition, we must re-enable CRS on Tx for both half and full
772169240Sjfv	 * duplex.
773169240Sjfv	 */
774169240Sjfv	phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
775177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
776169240Sjfv
777169240Sjfvout:
778169240Sjfv	return ret_val;
779169240Sjfv}
780169240Sjfv
781169240Sjfv/**
782169240Sjfv *  e1000_get_cable_length_80003es2lan - Set approximate cable length
783169589Sjfv *  @hw: pointer to the HW structure
784169240Sjfv *
785169240Sjfv *  Find the approximate cable length as measured by the GG82563 PHY.
786169240Sjfv *  This is a function pointer entry point called by the phy module.
787169240Sjfv **/
788177867Sjfvstatic s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw)
789169240Sjfv{
790169240Sjfv	struct e1000_phy_info *phy = &hw->phy;
791177867Sjfv	s32 ret_val = E1000_SUCCESS;
792169240Sjfv	u16 phy_data, index;
793169240Sjfv
794169240Sjfv	DEBUGFUNC("e1000_get_cable_length_80003es2lan");
795169240Sjfv
796177867Sjfv	if (!(hw->phy.ops.read_reg))
797177867Sjfv		goto out;
798177867Sjfv
799177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_DSP_DISTANCE, &phy_data);
800169240Sjfv	if (ret_val)
801169240Sjfv		goto out;
802169240Sjfv
803169240Sjfv	index = phy_data & GG82563_DSPD_CABLE_LENGTH;
804169240Sjfv
805190872Sjfv	if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE + 5) {
806185353Sjfv		ret_val = E1000_ERR_PHY;
807190872Sjfv		goto out;
808185353Sjfv	}
809185353Sjfv
810190872Sjfv	phy->min_cable_length = e1000_gg82563_cable_length_table[index];
811190872Sjfv	phy->max_cable_length = e1000_gg82563_cable_length_table[index+5];
812190872Sjfv
813190872Sjfv	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
814190872Sjfv
815169240Sjfvout:
816169240Sjfv	return ret_val;
817169240Sjfv}
818169240Sjfv
819169240Sjfv/**
820169240Sjfv *  e1000_get_link_up_info_80003es2lan - Report speed and duplex
821169589Sjfv *  @hw: pointer to the HW structure
822169589Sjfv *  @speed: pointer to speed buffer
823169589Sjfv *  @duplex: pointer to duplex buffer
824169240Sjfv *
825169240Sjfv *  Retrieve the current speed and duplex configuration.
826169240Sjfv **/
827177867Sjfvstatic s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
828173788Sjfv                                              u16 *duplex)
829169240Sjfv{
830169240Sjfv	s32 ret_val;
831169240Sjfv
832169240Sjfv	DEBUGFUNC("e1000_get_link_up_info_80003es2lan");
833169240Sjfv
834173788Sjfv	if (hw->phy.media_type == e1000_media_type_copper) {
835169240Sjfv		ret_val = e1000_get_speed_and_duplex_copper_generic(hw,
836169240Sjfv		                                                    speed,
837169240Sjfv		                                                    duplex);
838185353Sjfv		hw->phy.ops.cfg_on_link_up(hw);
839173788Sjfv	} else {
840169240Sjfv		ret_val = e1000_get_speed_and_duplex_fiber_serdes_generic(hw,
841169240Sjfv		                                                  speed,
842169240Sjfv		                                                  duplex);
843173788Sjfv	}
844169240Sjfv
845169240Sjfv	return ret_val;
846169240Sjfv}
847169240Sjfv
848169240Sjfv/**
849169240Sjfv *  e1000_reset_hw_80003es2lan - Reset the ESB2 controller
850169589Sjfv *  @hw: pointer to the HW structure
851169240Sjfv *
852169240Sjfv *  Perform a global reset to the ESB2 controller.
853169240Sjfv **/
854177867Sjfvstatic s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
855169240Sjfv{
856169240Sjfv	u32 ctrl, icr;
857169240Sjfv	s32 ret_val;
858169240Sjfv
859169240Sjfv	DEBUGFUNC("e1000_reset_hw_80003es2lan");
860169240Sjfv
861173788Sjfv	/*
862173788Sjfv	 * Prevent the PCI-E bus from sticking if there is no TLP connection
863169240Sjfv	 * on the last TLP read/write transaction when MAC is reset.
864169240Sjfv	 */
865169240Sjfv	ret_val = e1000_disable_pcie_master_generic(hw);
866185353Sjfv	if (ret_val)
867169240Sjfv		DEBUGOUT("PCI-E Master disable polling has failed.\n");
868169240Sjfv
869169240Sjfv	DEBUGOUT("Masking off all interrupts\n");
870169240Sjfv	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
871169240Sjfv
872169240Sjfv	E1000_WRITE_REG(hw, E1000_RCTL, 0);
873169240Sjfv	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
874169240Sjfv	E1000_WRITE_FLUSH(hw);
875169240Sjfv
876169240Sjfv	msec_delay(10);
877169240Sjfv
878169240Sjfv	ctrl = E1000_READ_REG(hw, E1000_CTRL);
879169240Sjfv
880185353Sjfv	ret_val = e1000_acquire_phy_80003es2lan(hw);
881169240Sjfv	DEBUGOUT("Issuing a global reset to MAC\n");
882169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
883185353Sjfv	e1000_release_phy_80003es2lan(hw);
884169240Sjfv
885169240Sjfv	ret_val = e1000_get_auto_rd_done_generic(hw);
886169240Sjfv	if (ret_val)
887169240Sjfv		/* We don't want to continue accessing MAC registers. */
888169240Sjfv		goto out;
889169240Sjfv
890169240Sjfv	/* Clear any pending interrupt events. */
891169240Sjfv	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
892169240Sjfv	icr = E1000_READ_REG(hw, E1000_ICR);
893169240Sjfv
894190872Sjfv	ret_val = e1000_check_alt_mac_addr_generic(hw);
895176667Sjfv
896169240Sjfvout:
897169240Sjfv	return ret_val;
898169240Sjfv}
899169240Sjfv
900169240Sjfv/**
901169240Sjfv *  e1000_init_hw_80003es2lan - Initialize the ESB2 controller
902169589Sjfv *  @hw: pointer to the HW structure
903169240Sjfv *
904169240Sjfv *  Initialize the hw bits, LED, VFTA, MTA, link and hw counters.
905169240Sjfv **/
906177867Sjfvstatic s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw)
907169240Sjfv{
908169240Sjfv	struct e1000_mac_info *mac = &hw->mac;
909169240Sjfv	u32 reg_data;
910169240Sjfv	s32 ret_val;
911169240Sjfv	u16 i;
912169240Sjfv
913169240Sjfv	DEBUGFUNC("e1000_init_hw_80003es2lan");
914169240Sjfv
915169240Sjfv	e1000_initialize_hw_bits_80003es2lan(hw);
916169240Sjfv
917169240Sjfv	/* Initialize identification LED */
918190872Sjfv	ret_val = mac->ops.id_led_init(hw);
919169240Sjfv	if (ret_val) {
920169240Sjfv		DEBUGOUT("Error initializing identification LED\n");
921173788Sjfv		/* This is not fatal and we should not stop init due to this */
922169240Sjfv	}
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
972173788Sjfv	/*
973173788Sjfv	 * Clear all of the statistics registers (clear on read).  It is
974169240Sjfv	 * important that we do this after we have tried to establish link
975169240Sjfv	 * because the symbol error count will increment wildly if there
976169240Sjfv	 * is no link.
977169240Sjfv	 */
978169240Sjfv	e1000_clear_hw_cntrs_80003es2lan(hw);
979169240Sjfv
980169240Sjfv	return ret_val;
981169240Sjfv}
982169240Sjfv
983169240Sjfv/**
984169240Sjfv *  e1000_initialize_hw_bits_80003es2lan - Init hw bits of ESB2
985169589Sjfv *  @hw: pointer to the HW structure
986169240Sjfv *
987169240Sjfv *  Initializes required hardware-dependent bits needed for normal operation.
988169240Sjfv **/
989173788Sjfvstatic void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw)
990169240Sjfv{
991169240Sjfv	u32 reg;
992169240Sjfv
993169240Sjfv	DEBUGFUNC("e1000_initialize_hw_bits_80003es2lan");
994169240Sjfv
995169240Sjfv	/* Transmit Descriptor Control 0 */
996173788Sjfv	reg = E1000_READ_REG(hw, E1000_TXDCTL(0));
997169240Sjfv	reg |= (1 << 22);
998173788Sjfv	E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg);
999169240Sjfv
1000169240Sjfv	/* Transmit Descriptor Control 1 */
1001173788Sjfv	reg = E1000_READ_REG(hw, E1000_TXDCTL(1));
1002169240Sjfv	reg |= (1 << 22);
1003173788Sjfv	E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg);
1004169240Sjfv
1005169240Sjfv	/* Transmit Arbitration Control 0 */
1006173788Sjfv	reg = E1000_READ_REG(hw, E1000_TARC(0));
1007169240Sjfv	reg &= ~(0xF << 27); /* 30:27 */
1008173788Sjfv	if (hw->phy.media_type != e1000_media_type_copper)
1009169240Sjfv		reg &= ~(1 << 20);
1010173788Sjfv	E1000_WRITE_REG(hw, E1000_TARC(0), reg);
1011169240Sjfv
1012169240Sjfv	/* Transmit Arbitration Control 1 */
1013173788Sjfv	reg = E1000_READ_REG(hw, E1000_TARC(1));
1014169240Sjfv	if (E1000_READ_REG(hw, E1000_TCTL) & E1000_TCTL_MULR)
1015169240Sjfv		reg &= ~(1 << 28);
1016169240Sjfv	else
1017169240Sjfv		reg |= (1 << 28);
1018173788Sjfv	E1000_WRITE_REG(hw, E1000_TARC(1), reg);
1019169240Sjfv
1020169240Sjfv	return;
1021169240Sjfv}
1022169240Sjfv
1023169240Sjfv/**
1024169240Sjfv *  e1000_copper_link_setup_gg82563_80003es2lan - Configure GG82563 Link
1025169589Sjfv *  @hw: pointer to the HW structure
1026169240Sjfv *
1027169240Sjfv *  Setup some GG82563 PHY registers for obtaining link
1028169240Sjfv **/
1029173788Sjfvstatic s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
1030169240Sjfv{
1031176667Sjfv	struct e1000_phy_info *phy = &hw->phy;
1032176667Sjfv	s32 ret_val;
1033169240Sjfv	u32 ctrl_ext;
1034185353Sjfv	u16 data;
1035169240Sjfv
1036169240Sjfv	DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan");
1037169240Sjfv
1038169240Sjfv	if (!phy->reset_disable) {
1039177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
1040169240Sjfv		                             &data);
1041169240Sjfv		if (ret_val)
1042169240Sjfv			goto out;
1043169240Sjfv
1044169240Sjfv		data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
1045169240Sjfv		/* Use 25MHz for both link down and 1000Base-T for Tx clock. */
1046169240Sjfv		data |= GG82563_MSCR_TX_CLK_1000MBPS_25;
1047169240Sjfv
1048177867Sjfv		ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
1049169240Sjfv		                              data);
1050169240Sjfv		if (ret_val)
1051169240Sjfv			goto out;
1052169240Sjfv
1053173788Sjfv		/*
1054173788Sjfv		 * Options:
1055169240Sjfv		 *   MDI/MDI-X = 0 (default)
1056169240Sjfv		 *   0 - Auto for all speeds
1057169240Sjfv		 *   1 - MDI mode
1058169240Sjfv		 *   2 - MDI-X mode
1059169240Sjfv		 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
1060169240Sjfv		 */
1061177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data);
1062169240Sjfv		if (ret_val)
1063169240Sjfv			goto out;
1064169240Sjfv
1065169240Sjfv		data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK;
1066169240Sjfv
1067169240Sjfv		switch (phy->mdix) {
1068169240Sjfv		case 1:
1069169240Sjfv			data |= GG82563_PSCR_CROSSOVER_MODE_MDI;
1070169240Sjfv			break;
1071169240Sjfv		case 2:
1072169240Sjfv			data |= GG82563_PSCR_CROSSOVER_MODE_MDIX;
1073169240Sjfv			break;
1074169240Sjfv		case 0:
1075169240Sjfv		default:
1076169240Sjfv			data |= GG82563_PSCR_CROSSOVER_MODE_AUTO;
1077169240Sjfv			break;
1078169240Sjfv		}
1079169240Sjfv
1080173788Sjfv		/*
1081173788Sjfv		 * Options:
1082169240Sjfv		 *   disable_polarity_correction = 0 (default)
1083169240Sjfv		 *       Automatic Correction for Reversed Cable Polarity
1084169240Sjfv		 *   0 - Disabled
1085169240Sjfv		 *   1 - Enabled
1086169240Sjfv		 */
1087169240Sjfv		data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
1088173788Sjfv		if (phy->disable_polarity_correction)
1089169240Sjfv			data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
1090169240Sjfv
1091177867Sjfv		ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data);
1092169240Sjfv		if (ret_val)
1093169240Sjfv			goto out;
1094169240Sjfv
1095169240Sjfv		/* SW Reset the PHY so all changes take effect */
1096177867Sjfv		ret_val = hw->phy.ops.commit(hw);
1097169240Sjfv		if (ret_val) {
1098169240Sjfv			DEBUGOUT("Error Resetting the PHY\n");
1099169240Sjfv			goto out;
1100169240Sjfv		}
1101169240Sjfv
1102169240Sjfv	}
1103169240Sjfv
1104173788Sjfv	/* Bypass Rx and Tx FIFO's */
1105185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
1106190872Sjfv					E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL,
1107190872Sjfv					E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS |
1108190872Sjfv					E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS);
1109169240Sjfv	if (ret_val)
1110169240Sjfv		goto out;
1111169240Sjfv
1112185353Sjfv	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
1113176667Sjfv	                              E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
1114176667Sjfv	                              &data);
1115173788Sjfv	if (ret_val)
1116173788Sjfv		goto out;
1117173788Sjfv	data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE;
1118185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
1119176667Sjfv	                               E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
1120176667Sjfv	                               data);
1121173788Sjfv	if (ret_val)
1122173788Sjfv		goto out;
1123173788Sjfv
1124177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL_2, &data);
1125169240Sjfv	if (ret_val)
1126169240Sjfv		goto out;
1127169240Sjfv
1128169240Sjfv	data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG;
1129177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL_2, data);
1130169240Sjfv	if (ret_val)
1131169240Sjfv		goto out;
1132169240Sjfv
1133169240Sjfv	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
1134169240Sjfv	ctrl_ext &= ~(E1000_CTRL_EXT_LINK_MODE_MASK);
1135169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
1136169240Sjfv
1137177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, &data);
1138169240Sjfv	if (ret_val)
1139169240Sjfv		goto out;
1140169240Sjfv
1141173788Sjfv	/*
1142173788Sjfv	 * Do not init these registers when the HW is in IAMT mode, since the
1143169240Sjfv	 * firmware will have already initialized them.  We only initialize
1144169240Sjfv	 * them if the HW is not in IAMT mode.
1145169240Sjfv	 */
1146177867Sjfv	if (!(hw->mac.ops.check_mng_mode(hw))) {
1147169240Sjfv		/* Enable Electrical Idle on the PHY */
1148169240Sjfv		data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;
1149190872Sjfv		ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_PWR_MGMT_CTRL,
1150185353Sjfv		                                data);
1151169240Sjfv		if (ret_val)
1152169240Sjfv			goto out;
1153169240Sjfv
1154190872Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1155190872Sjfv		                               &data);
1156190872Sjfv		if (ret_val)
1157190872Sjfv			goto out;
1158190872Sjfv
1159169240Sjfv		data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
1160190872Sjfv		ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1161185353Sjfv		                                data);
1162169240Sjfv		if (ret_val)
1163169240Sjfv			goto out;
1164169240Sjfv	}
1165169240Sjfv
1166173788Sjfv	/*
1167173788Sjfv	 * Workaround: Disable padding in Kumeran interface in the MAC
1168169240Sjfv	 * and in the PHY to avoid CRC errors.
1169169240Sjfv	 */
1170177867Sjfv	ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_INBAND_CTRL, &data);
1171169240Sjfv	if (ret_val)
1172169240Sjfv		goto out;
1173169240Sjfv
1174169240Sjfv	data |= GG82563_ICR_DIS_PADDING;
1175177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_INBAND_CTRL, data);
1176169240Sjfv	if (ret_val)
1177169240Sjfv		goto out;
1178169240Sjfv
1179169240Sjfvout:
1180169240Sjfv	return ret_val;
1181169240Sjfv}
1182169240Sjfv
1183169240Sjfv/**
1184169240Sjfv *  e1000_setup_copper_link_80003es2lan - Setup Copper Link for ESB2
1185169589Sjfv *  @hw: pointer to the HW structure
1186169240Sjfv *
1187169240Sjfv *  Essentially a wrapper for setting up all things "copper" related.
1188169240Sjfv *  This is a function pointer entry point called by the mac module.
1189169240Sjfv **/
1190177867Sjfvstatic s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
1191169240Sjfv{
1192169240Sjfv	u32 ctrl;
1193185353Sjfv	s32 ret_val;
1194169240Sjfv	u16 reg_data;
1195169240Sjfv
1196169240Sjfv	DEBUGFUNC("e1000_setup_copper_link_80003es2lan");
1197169240Sjfv
1198169240Sjfv	ctrl = E1000_READ_REG(hw, E1000_CTRL);
1199169240Sjfv	ctrl |= E1000_CTRL_SLU;
1200169240Sjfv	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
1201169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
1202169240Sjfv
1203173788Sjfv	/*
1204173788Sjfv	 * Set the mac to wait the maximum time between each
1205169240Sjfv	 * iteration and increase the max iterations when
1206173788Sjfv	 * polling the phy; this fixes erroneous timeouts at 10Mbps.
1207173788Sjfv	 */
1208185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4),
1209185353Sjfv	                                           0xFFFF);
1210169240Sjfv	if (ret_val)
1211169240Sjfv		goto out;
1212185353Sjfv	ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),
1213185353Sjfv	                                          &reg_data);
1214169240Sjfv	if (ret_val)
1215169240Sjfv		goto out;
1216169240Sjfv	reg_data |= 0x3F;
1217185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),
1218185353Sjfv	                                           reg_data);
1219169240Sjfv	if (ret_val)
1220169240Sjfv		goto out;
1221185353Sjfv	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
1222169240Sjfv	                              E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
1223169240Sjfv	                              &reg_data);
1224169240Sjfv	if (ret_val)
1225169240Sjfv		goto out;
1226169240Sjfv	reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING;
1227185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
1228169240Sjfv	                               E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
1229169240Sjfv	                               reg_data);
1230169240Sjfv	if (ret_val)
1231169240Sjfv		goto out;
1232169240Sjfv
1233169240Sjfv	ret_val = e1000_copper_link_setup_gg82563_80003es2lan(hw);
1234169240Sjfv	if (ret_val)
1235169240Sjfv		goto out;
1236169240Sjfv
1237169240Sjfv	ret_val = e1000_setup_copper_link_generic(hw);
1238169240Sjfv
1239169240Sjfvout:
1240169240Sjfv	return ret_val;
1241169240Sjfv}
1242169240Sjfv
1243169240Sjfv/**
1244185353Sjfv *  e1000_cfg_on_link_up_80003es2lan - es2 link configuration after link-up
1245185353Sjfv *  @hw: pointer to the HW structure
1246185353Sjfv *  @duplex: current duplex setting
1247185353Sjfv *
1248185353Sjfv *  Configure the KMRN interface by applying last minute quirks for
1249185353Sjfv *  10/100 operation.
1250185353Sjfv **/
1251185353Sjfvstatic s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw)
1252185353Sjfv{
1253185353Sjfv	s32 ret_val = E1000_SUCCESS;
1254185353Sjfv	u16 speed;
1255185353Sjfv	u16 duplex;
1256185353Sjfv
1257185353Sjfv	DEBUGFUNC("e1000_configure_on_link_up");
1258185353Sjfv
1259185353Sjfv	if (hw->phy.media_type == e1000_media_type_copper) {
1260185353Sjfv		ret_val = e1000_get_speed_and_duplex_copper_generic(hw,
1261185353Sjfv		                                                    &speed,
1262185353Sjfv		                                                    &duplex);
1263185353Sjfv		if (ret_val)
1264185353Sjfv			goto out;
1265185353Sjfv
1266185353Sjfv		if (speed == SPEED_1000)
1267185353Sjfv			ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw);
1268185353Sjfv		else
1269185353Sjfv			ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, duplex);
1270185353Sjfv	}
1271185353Sjfv
1272185353Sjfvout:
1273185353Sjfv	return ret_val;
1274185353Sjfv}
1275185353Sjfv
1276185353Sjfv/**
1277169240Sjfv *  e1000_cfg_kmrn_10_100_80003es2lan - Apply "quirks" for 10/100 operation
1278169589Sjfv *  @hw: pointer to the HW structure
1279169589Sjfv *  @duplex: current duplex setting
1280169240Sjfv *
1281169240Sjfv *  Configure the KMRN interface by applying last minute quirks for
1282169240Sjfv *  10/100 operation.
1283169240Sjfv **/
1284173788Sjfvstatic s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex)
1285169240Sjfv{
1286169240Sjfv	s32 ret_val = E1000_SUCCESS;
1287169240Sjfv	u32 tipg;
1288169589Sjfv	u32 i = 0;
1289169589Sjfv	u16 reg_data, reg_data2;
1290169240Sjfv
1291169240Sjfv	DEBUGFUNC("e1000_configure_kmrn_for_10_100");
1292169240Sjfv
1293169240Sjfv	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT;
1294185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
1295169240Sjfv	                               E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
1296169240Sjfv	                               reg_data);
1297169240Sjfv	if (ret_val)
1298169240Sjfv		goto out;
1299169240Sjfv
1300169240Sjfv	/* Configure Transmit Inter-Packet Gap */
1301169240Sjfv	tipg = E1000_READ_REG(hw, E1000_TIPG);
1302169240Sjfv	tipg &= ~E1000_TIPG_IPGT_MASK;
1303169240Sjfv	tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN;
1304169240Sjfv	E1000_WRITE_REG(hw, E1000_TIPG, tipg);
1305169240Sjfv
1306169240Sjfv
1307169589Sjfv	do {
1308177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1309185353Sjfv		                               &reg_data);
1310169589Sjfv		if (ret_val)
1311169589Sjfv			goto out;
1312169589Sjfv
1313177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1314185353Sjfv		                               &reg_data2);
1315169589Sjfv		if (ret_val)
1316169589Sjfv			goto out;
1317169589Sjfv		i++;
1318169589Sjfv	} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));
1319169589Sjfv
1320169240Sjfv	if (duplex == HALF_DUPLEX)
1321169240Sjfv		reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER;
1322169240Sjfv	else
1323169240Sjfv		reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
1324169240Sjfv
1325177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
1326169240Sjfv
1327169240Sjfvout:
1328169240Sjfv	return ret_val;
1329169240Sjfv}
1330169240Sjfv
1331169240Sjfv/**
1332169240Sjfv *  e1000_cfg_kmrn_1000_80003es2lan - Apply "quirks" for gigabit operation
1333169589Sjfv *  @hw: pointer to the HW structure
1334169240Sjfv *
1335169240Sjfv *  Configure the KMRN interface by applying last minute quirks for
1336169240Sjfv *  gigabit operation.
1337169240Sjfv **/
1338173788Sjfvstatic s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
1339169240Sjfv{
1340169240Sjfv	s32 ret_val = E1000_SUCCESS;
1341169589Sjfv	u16 reg_data, reg_data2;
1342169240Sjfv	u32 tipg;
1343169589Sjfv	u32 i = 0;
1344169240Sjfv
1345169240Sjfv	DEBUGFUNC("e1000_configure_kmrn_for_1000");
1346169240Sjfv
1347169240Sjfv	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT;
1348185353Sjfv	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
1349169240Sjfv	                               E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
1350169240Sjfv	                               reg_data);
1351169240Sjfv	if (ret_val)
1352169240Sjfv		goto out;
1353169240Sjfv
1354169240Sjfv	/* Configure Transmit Inter-Packet Gap */
1355169240Sjfv	tipg = E1000_READ_REG(hw, E1000_TIPG);
1356169240Sjfv	tipg &= ~E1000_TIPG_IPGT_MASK;
1357169240Sjfv	tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN;
1358169240Sjfv	E1000_WRITE_REG(hw, E1000_TIPG, tipg);
1359169240Sjfv
1360169240Sjfv
1361169589Sjfv	do {
1362177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1363185353Sjfv		                               &reg_data);
1364169589Sjfv		if (ret_val)
1365169589Sjfv			goto out;
1366169589Sjfv
1367177867Sjfv		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
1368185353Sjfv		                               &reg_data2);
1369169589Sjfv		if (ret_val)
1370169589Sjfv			goto out;
1371169589Sjfv		i++;
1372169589Sjfv	} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));
1373169589Sjfv
1374169240Sjfv	reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
1375177867Sjfv	ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
1376169240Sjfv
1377169240Sjfvout:
1378169240Sjfv	return ret_val;
1379169240Sjfv}
1380169240Sjfv
1381169240Sjfv/**
1382185353Sjfv *  e1000_read_kmrn_reg_80003es2lan - Read kumeran register
1383185353Sjfv *  @hw: pointer to the HW structure
1384185353Sjfv *  @offset: register offset to be read
1385185353Sjfv *  @data: pointer to the read data
1386185353Sjfv *
1387185353Sjfv *  Acquire semaphore, then read the PHY register at offset
1388185353Sjfv *  using the kumeran interface.  The information retrieved is stored in data.
1389185353Sjfv *  Release the semaphore before exiting.
1390185353Sjfv **/
1391190872Sjfvstatic s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
1392190872Sjfv                                           u16 *data)
1393185353Sjfv{
1394185353Sjfv	u32 kmrnctrlsta;
1395185353Sjfv	s32 ret_val = E1000_SUCCESS;
1396185353Sjfv
1397185353Sjfv	DEBUGFUNC("e1000_read_kmrn_reg_80003es2lan");
1398185353Sjfv
1399185353Sjfv	ret_val = e1000_acquire_mac_csr_80003es2lan(hw);
1400185353Sjfv	if (ret_val)
1401185353Sjfv		goto out;
1402185353Sjfv
1403185353Sjfv	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
1404185353Sjfv	               E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
1405185353Sjfv	E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
1406185353Sjfv
1407185353Sjfv	usec_delay(2);
1408185353Sjfv
1409185353Sjfv	kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA);
1410185353Sjfv	*data = (u16)kmrnctrlsta;
1411185353Sjfv
1412185353Sjfv	e1000_release_mac_csr_80003es2lan(hw);
1413185353Sjfv
1414185353Sjfvout:
1415185353Sjfv	return ret_val;
1416185353Sjfv}
1417185353Sjfv
1418185353Sjfv/**
1419185353Sjfv *  e1000_write_kmrn_reg_80003es2lan - Write kumeran register
1420185353Sjfv *  @hw: pointer to the HW structure
1421185353Sjfv *  @offset: register offset to write to
1422185353Sjfv *  @data: data to write at register offset
1423185353Sjfv *
1424185353Sjfv *  Acquire semaphore, then write the data to PHY register
1425185353Sjfv *  at the offset using the kumeran interface.  Release semaphore
1426185353Sjfv *  before exiting.
1427185353Sjfv **/
1428190872Sjfvstatic s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
1429190872Sjfv                                            u16 data)
1430185353Sjfv{
1431185353Sjfv	u32 kmrnctrlsta;
1432185353Sjfv	s32 ret_val = E1000_SUCCESS;
1433185353Sjfv
1434185353Sjfv	DEBUGFUNC("e1000_write_kmrn_reg_80003es2lan");
1435185353Sjfv
1436185353Sjfv	ret_val = e1000_acquire_mac_csr_80003es2lan(hw);
1437185353Sjfv	if (ret_val)
1438185353Sjfv		goto out;
1439185353Sjfv
1440185353Sjfv	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
1441185353Sjfv	               E1000_KMRNCTRLSTA_OFFSET) | data;
1442185353Sjfv	E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
1443185353Sjfv
1444185353Sjfv	usec_delay(2);
1445185353Sjfv
1446185353Sjfv	e1000_release_mac_csr_80003es2lan(hw);
1447185353Sjfv
1448185353Sjfvout:
1449185353Sjfv	return ret_val;
1450185353Sjfv}
1451185353Sjfv
1452185353Sjfv/**
1453176667Sjfv *  e1000_read_mac_addr_80003es2lan - Read device MAC address
1454176667Sjfv *  @hw: pointer to the HW structure
1455176667Sjfv **/
1456177867Sjfvstatic s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw)
1457176667Sjfv{
1458176667Sjfv	s32 ret_val = E1000_SUCCESS;
1459176667Sjfv
1460176667Sjfv	DEBUGFUNC("e1000_read_mac_addr_80003es2lan");
1461176667Sjfv
1462190872Sjfv	/*
1463190872Sjfv	 * If there's an alternate MAC address place it in RAR0
1464190872Sjfv	 * so that it will override the Si installed default perm
1465190872Sjfv	 * address.
1466190872Sjfv	 */
1467190872Sjfv	ret_val = e1000_check_alt_mac_addr_generic(hw);
1468190872Sjfv	if (ret_val)
1469190872Sjfv		goto out;
1470190872Sjfv
1471190872Sjfv	ret_val = e1000_read_mac_addr_generic(hw);
1472190872Sjfv
1473190872Sjfvout:
1474176667Sjfv	return ret_val;
1475176667Sjfv}
1476176667Sjfv
1477176667Sjfv/**
1478173788Sjfv * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down
1479173788Sjfv * @hw: pointer to the HW structure
1480173788Sjfv *
1481173788Sjfv * In the case of a PHY power down to save power, or to turn off link during a
1482173788Sjfv * driver unload, or wake on lan is not enabled, remove the link.
1483173788Sjfv **/
1484177867Sjfvstatic void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw)
1485173788Sjfv{
1486173788Sjfv	/* If the management interface is not enabled, then power down */
1487177867Sjfv	if (!(hw->mac.ops.check_mng_mode(hw) ||
1488177867Sjfv	      hw->phy.ops.check_reset_block(hw)))
1489173788Sjfv		e1000_power_down_phy_copper(hw);
1490173788Sjfv
1491173788Sjfv	return;
1492173788Sjfv}
1493173788Sjfv
1494173788Sjfv/**
1495169240Sjfv *  e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters
1496169589Sjfv *  @hw: pointer to the HW structure
1497169240Sjfv *
1498169240Sjfv *  Clears the hardware counters by reading the counter registers.
1499169240Sjfv **/
1500177867Sjfvstatic void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
1501169240Sjfv{
1502169240Sjfv	DEBUGFUNC("e1000_clear_hw_cntrs_80003es2lan");
1503169240Sjfv
1504169240Sjfv	e1000_clear_hw_cntrs_base_generic(hw);
1505169240Sjfv
1506185353Sjfv	E1000_READ_REG(hw, E1000_PRC64);
1507185353Sjfv	E1000_READ_REG(hw, E1000_PRC127);
1508185353Sjfv	E1000_READ_REG(hw, E1000_PRC255);
1509185353Sjfv	E1000_READ_REG(hw, E1000_PRC511);
1510185353Sjfv	E1000_READ_REG(hw, E1000_PRC1023);
1511185353Sjfv	E1000_READ_REG(hw, E1000_PRC1522);
1512185353Sjfv	E1000_READ_REG(hw, E1000_PTC64);
1513185353Sjfv	E1000_READ_REG(hw, E1000_PTC127);
1514185353Sjfv	E1000_READ_REG(hw, E1000_PTC255);
1515185353Sjfv	E1000_READ_REG(hw, E1000_PTC511);
1516185353Sjfv	E1000_READ_REG(hw, E1000_PTC1023);
1517185353Sjfv	E1000_READ_REG(hw, E1000_PTC1522);
1518169240Sjfv
1519185353Sjfv	E1000_READ_REG(hw, E1000_ALGNERRC);
1520185353Sjfv	E1000_READ_REG(hw, E1000_RXERRC);
1521185353Sjfv	E1000_READ_REG(hw, E1000_TNCRS);
1522185353Sjfv	E1000_READ_REG(hw, E1000_CEXTERR);
1523185353Sjfv	E1000_READ_REG(hw, E1000_TSCTC);
1524185353Sjfv	E1000_READ_REG(hw, E1000_TSCTFC);
1525169240Sjfv
1526185353Sjfv	E1000_READ_REG(hw, E1000_MGTPRC);
1527185353Sjfv	E1000_READ_REG(hw, E1000_MGTPDC);
1528185353Sjfv	E1000_READ_REG(hw, E1000_MGTPTC);
1529169240Sjfv
1530185353Sjfv	E1000_READ_REG(hw, E1000_IAC);
1531185353Sjfv	E1000_READ_REG(hw, E1000_ICRXOC);
1532169240Sjfv
1533185353Sjfv	E1000_READ_REG(hw, E1000_ICRXPTC);
1534185353Sjfv	E1000_READ_REG(hw, E1000_ICRXATC);
1535185353Sjfv	E1000_READ_REG(hw, E1000_ICTXPTC);
1536185353Sjfv	E1000_READ_REG(hw, E1000_ICTXATC);
1537185353Sjfv	E1000_READ_REG(hw, E1000_ICTXQEC);
1538185353Sjfv	E1000_READ_REG(hw, E1000_ICTXQMTC);
1539185353Sjfv	E1000_READ_REG(hw, E1000_ICRXDMTC);
1540169240Sjfv}
1541