xref: /onnv-gate/usr/src/uts/common/io/igb/igb_82575.c (revision 5779:e875a8701bfc)
1*5779Sxy150489 /*
2*5779Sxy150489  * CDDL HEADER START
3*5779Sxy150489  *
4*5779Sxy150489  * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
5*5779Sxy150489  * The contents of this file are subject to the terms of the
6*5779Sxy150489  * Common Development and Distribution License (the "License").
7*5779Sxy150489  * You may not use this file except in compliance with the License.
8*5779Sxy150489  *
9*5779Sxy150489  * You can obtain a copy of the license at:
10*5779Sxy150489  *	http://www.opensolaris.org/os/licensing.
11*5779Sxy150489  * See the License for the specific language governing permissions
12*5779Sxy150489  * and limitations under the License.
13*5779Sxy150489  *
14*5779Sxy150489  * When using or redistributing this file, you may do so under the
15*5779Sxy150489  * License only. No other modification of this header is permitted.
16*5779Sxy150489  *
17*5779Sxy150489  * If applicable, add the following below this CDDL HEADER, with the
18*5779Sxy150489  * fields enclosed by brackets "[]" replaced with your own identifying
19*5779Sxy150489  * information: Portions Copyright [yyyy] [name of copyright owner]
20*5779Sxy150489  *
21*5779Sxy150489  * CDDL HEADER END
22*5779Sxy150489  */
23*5779Sxy150489 
24*5779Sxy150489 /*
25*5779Sxy150489  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
26*5779Sxy150489  * Use is subject to license terms of the CDDL.
27*5779Sxy150489  */
28*5779Sxy150489 
29*5779Sxy150489 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*5779Sxy150489 
31*5779Sxy150489 /*
32*5779Sxy150489  * e1000_82575
33*5779Sxy150489  * e1000_82576
34*5779Sxy150489  */
35*5779Sxy150489 
36*5779Sxy150489 #include "igb_api.h"
37*5779Sxy150489 #include "igb_82575.h"
38*5779Sxy150489 
39*5779Sxy150489 static s32 e1000_init_phy_params_82575(struct e1000_hw *hw);
40*5779Sxy150489 static s32 e1000_init_nvm_params_82575(struct e1000_hw *hw);
41*5779Sxy150489 static s32 e1000_init_mac_params_82575(struct e1000_hw *hw);
42*5779Sxy150489 static s32 e1000_acquire_phy_82575(struct e1000_hw *hw);
43*5779Sxy150489 static void e1000_release_phy_82575(struct e1000_hw *hw);
44*5779Sxy150489 static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw);
45*5779Sxy150489 static void e1000_release_nvm_82575(struct e1000_hw *hw);
46*5779Sxy150489 static s32 e1000_check_for_link_82575(struct e1000_hw *hw);
47*5779Sxy150489 static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw);
48*5779Sxy150489 static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
49*5779Sxy150489     u16 *duplex);
50*5779Sxy150489 static s32 e1000_init_hw_82575(struct e1000_hw *hw);
51*5779Sxy150489 static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
52*5779Sxy150489 static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
53*5779Sxy150489     u16 *data);
54*5779Sxy150489 static void e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index);
55*5779Sxy150489 static s32 e1000_reset_hw_82575(struct e1000_hw *hw);
56*5779Sxy150489 static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw,
57*5779Sxy150489     bool active);
58*5779Sxy150489 static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw);
59*5779Sxy150489 static s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw);
60*5779Sxy150489 static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
61*5779Sxy150489     u32 offset, u16 data);
62*5779Sxy150489 static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
63*5779Sxy150489 static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
64*5779Sxy150489 static s32 e1000_configure_pcs_link_82575(struct e1000_hw *hw);
65*5779Sxy150489 static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
66*5779Sxy150489     u16 *speed, u16 *duplex);
67*5779Sxy150489 static s32 e1000_get_phy_id_82575(struct e1000_hw *hw);
68*5779Sxy150489 static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
69*5779Sxy150489 static bool e1000_sgmii_active_82575(struct e1000_hw *hw);
70*5779Sxy150489 static s32 e1000_reset_init_script_82575(struct e1000_hw *hw);
71*5779Sxy150489 static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw);
72*5779Sxy150489 static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
73*5779Sxy150489 
74*5779Sxy150489 
75*5779Sxy150489 struct e1000_dev_spec_82575 {
76*5779Sxy150489 	bool sgmii_active;
77*5779Sxy150489 };
78*5779Sxy150489 
79*5779Sxy150489 /*
80*5779Sxy150489  * e1000_init_phy_params_82575 - Init PHY func ptrs.
81*5779Sxy150489  * @hw: pointer to the HW structure
82*5779Sxy150489  *
83*5779Sxy150489  * This is a function pointer entry point called by the api module.
84*5779Sxy150489  */
85*5779Sxy150489 static s32
86*5779Sxy150489 e1000_init_phy_params_82575(struct e1000_hw *hw)
87*5779Sxy150489 {
88*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
89*5779Sxy150489 	struct e1000_functions *func = &hw->func;
90*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
91*5779Sxy150489 
92*5779Sxy150489 	DEBUGFUNC("e1000_init_phy_params_82575");
93*5779Sxy150489 
94*5779Sxy150489 	if (hw->phy.media_type != e1000_media_type_copper) {
95*5779Sxy150489 		phy->type = e1000_phy_none;
96*5779Sxy150489 		goto out;
97*5779Sxy150489 	} else {
98*5779Sxy150489 		func->power_up_phy = e1000_power_up_phy_copper;
99*5779Sxy150489 		func->power_down_phy = e1000_power_down_phy_copper_82575;
100*5779Sxy150489 	}
101*5779Sxy150489 
102*5779Sxy150489 	phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
103*5779Sxy150489 	phy->reset_delay_us = 100;
104*5779Sxy150489 
105*5779Sxy150489 	func->acquire_phy = e1000_acquire_phy_82575;
106*5779Sxy150489 	func->check_reset_block = e1000_check_reset_block_generic;
107*5779Sxy150489 	func->commit_phy = e1000_phy_sw_reset_generic;
108*5779Sxy150489 	func->get_cfg_done = e1000_get_cfg_done_82575;
109*5779Sxy150489 	func->release_phy = e1000_release_phy_82575;
110*5779Sxy150489 
111*5779Sxy150489 	if (e1000_sgmii_active_82575(hw)) {
112*5779Sxy150489 		func->reset_phy = e1000_phy_hw_reset_sgmii_82575;
113*5779Sxy150489 		func->read_phy_reg = e1000_read_phy_reg_sgmii_82575;
114*5779Sxy150489 		func->write_phy_reg = e1000_write_phy_reg_sgmii_82575;
115*5779Sxy150489 	} else {
116*5779Sxy150489 		func->reset_phy = e1000_phy_hw_reset_generic;
117*5779Sxy150489 		func->read_phy_reg = e1000_read_phy_reg_igp;
118*5779Sxy150489 		func->write_phy_reg = e1000_write_phy_reg_igp;
119*5779Sxy150489 	}
120*5779Sxy150489 
121*5779Sxy150489 	/* Set phy->phy_addr and phy->id. */
122*5779Sxy150489 	ret_val = e1000_get_phy_id_82575(hw);
123*5779Sxy150489 
124*5779Sxy150489 	/* Verify phy id and set remaining function pointers */
125*5779Sxy150489 	switch (phy->id) {
126*5779Sxy150489 	case M88E1111_I_PHY_ID:
127*5779Sxy150489 		phy->type = e1000_phy_m88;
128*5779Sxy150489 		func->check_polarity = e1000_check_polarity_m88;
129*5779Sxy150489 		func->get_phy_info = e1000_get_phy_info_m88;
130*5779Sxy150489 		func->get_cable_length = e1000_get_cable_length_m88;
131*5779Sxy150489 		func->force_speed_duplex = e1000_phy_force_speed_duplex_m88;
132*5779Sxy150489 		break;
133*5779Sxy150489 	case IGP03E1000_E_PHY_ID:
134*5779Sxy150489 		phy->type = e1000_phy_igp_3;
135*5779Sxy150489 		func->check_polarity = e1000_check_polarity_igp;
136*5779Sxy150489 		func->get_phy_info = e1000_get_phy_info_igp;
137*5779Sxy150489 		func->get_cable_length = e1000_get_cable_length_igp_2;
138*5779Sxy150489 		func->force_speed_duplex = e1000_phy_force_speed_duplex_igp;
139*5779Sxy150489 		func->set_d0_lplu_state = e1000_set_d0_lplu_state_82575;
140*5779Sxy150489 		func->set_d3_lplu_state = e1000_set_d3_lplu_state_generic;
141*5779Sxy150489 		break;
142*5779Sxy150489 	default:
143*5779Sxy150489 		ret_val = -E1000_ERR_PHY;
144*5779Sxy150489 		goto out;
145*5779Sxy150489 	}
146*5779Sxy150489 
147*5779Sxy150489 out:
148*5779Sxy150489 	return (ret_val);
149*5779Sxy150489 }
150*5779Sxy150489 
151*5779Sxy150489 /*
152*5779Sxy150489  * e1000_init_nvm_params_82575 - Init NVM func ptrs.
153*5779Sxy150489  * @hw: pointer to the HW structure
154*5779Sxy150489  *
155*5779Sxy150489  * This is a function pointer entry point called by the api module.
156*5779Sxy150489  */
157*5779Sxy150489 static s32
158*5779Sxy150489 e1000_init_nvm_params_82575(struct e1000_hw *hw)
159*5779Sxy150489 {
160*5779Sxy150489 	struct e1000_nvm_info *nvm = &hw->nvm;
161*5779Sxy150489 	struct e1000_functions *func = &hw->func;
162*5779Sxy150489 	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
163*5779Sxy150489 	u16 size;
164*5779Sxy150489 
165*5779Sxy150489 	DEBUGFUNC("e1000_init_nvm_params_82575");
166*5779Sxy150489 
167*5779Sxy150489 	nvm->opcode_bits = 8;
168*5779Sxy150489 	nvm->delay_usec = 1;
169*5779Sxy150489 	switch (nvm->override) {
170*5779Sxy150489 	case e1000_nvm_override_spi_large:
171*5779Sxy150489 		nvm->page_size = 32;
172*5779Sxy150489 		nvm->address_bits = 16;
173*5779Sxy150489 		break;
174*5779Sxy150489 	case e1000_nvm_override_spi_small:
175*5779Sxy150489 		nvm->page_size = 8;
176*5779Sxy150489 		nvm->address_bits = 8;
177*5779Sxy150489 		break;
178*5779Sxy150489 	default:
179*5779Sxy150489 		nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
180*5779Sxy150489 		nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8;
181*5779Sxy150489 		break;
182*5779Sxy150489 	}
183*5779Sxy150489 
184*5779Sxy150489 	nvm->type = e1000_nvm_eeprom_spi;
185*5779Sxy150489 
186*5779Sxy150489 	size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
187*5779Sxy150489 	    E1000_EECD_SIZE_EX_SHIFT);
188*5779Sxy150489 
189*5779Sxy150489 	/*
190*5779Sxy150489 	 * Added to a constant, "size" becomes the left-shift value
191*5779Sxy150489 	 * for setting word_size.
192*5779Sxy150489 	 */
193*5779Sxy150489 	size += NVM_WORD_SIZE_BASE_SHIFT;
194*5779Sxy150489 
195*5779Sxy150489 	/* EEPROM access above 16k is unsupported */
196*5779Sxy150489 	if (size > 14)
197*5779Sxy150489 		size = 14;
198*5779Sxy150489 	nvm->word_size = 1 << size;
199*5779Sxy150489 
200*5779Sxy150489 	/* Function Pointers */
201*5779Sxy150489 	func->acquire_nvm = e1000_acquire_nvm_82575;
202*5779Sxy150489 	func->read_nvm = e1000_read_nvm_eerd;
203*5779Sxy150489 	func->release_nvm = e1000_release_nvm_82575;
204*5779Sxy150489 	func->update_nvm = e1000_update_nvm_checksum_generic;
205*5779Sxy150489 	func->valid_led_default = e1000_valid_led_default_generic;
206*5779Sxy150489 	func->validate_nvm = e1000_validate_nvm_checksum_generic;
207*5779Sxy150489 	func->write_nvm = e1000_write_nvm_spi;
208*5779Sxy150489 
209*5779Sxy150489 	return (E1000_SUCCESS);
210*5779Sxy150489 }
211*5779Sxy150489 
212*5779Sxy150489 /*
213*5779Sxy150489  * e1000_init_mac_params_82575 - Init MAC func ptrs.
214*5779Sxy150489  * @hw: pointer to the HW structure
215*5779Sxy150489  *
216*5779Sxy150489  * This is a function pointer entry point called by the api module.
217*5779Sxy150489  */
218*5779Sxy150489 static s32
219*5779Sxy150489 e1000_init_mac_params_82575(struct e1000_hw *hw)
220*5779Sxy150489 {
221*5779Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
222*5779Sxy150489 	struct e1000_functions *func = &hw->func;
223*5779Sxy150489 	struct e1000_dev_spec_82575 *dev_spec;
224*5779Sxy150489 	u32 ctrl_ext = 0;
225*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
226*5779Sxy150489 
227*5779Sxy150489 	DEBUGFUNC("e1000_init_mac_params_82575");
228*5779Sxy150489 
229*5779Sxy150489 	hw->dev_spec_size = sizeof (struct e1000_dev_spec_82575);
230*5779Sxy150489 
231*5779Sxy150489 	/* Device-specific structure allocation */
232*5779Sxy150489 	ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size);
233*5779Sxy150489 	if (ret_val)
234*5779Sxy150489 		goto out;
235*5779Sxy150489 
236*5779Sxy150489 	dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
237*5779Sxy150489 
238*5779Sxy150489 	/* Set media type */
239*5779Sxy150489 	/*
240*5779Sxy150489 	 * The 82575 uses bits 22:23 for link mode. The mode can be changed
241*5779Sxy150489 	 * based on the EEPROM. We cannot rely upon device ID. There
242*5779Sxy150489 	 * is no distinguishable difference between fiber and internal
243*5779Sxy150489 	 * SerDes mode on the 82575. There can be an external PHY attached
244*5779Sxy150489 	 * on the SGMII interface. For this, we'll set sgmii_active to TRUE.
245*5779Sxy150489 	 */
246*5779Sxy150489 	hw->phy.media_type = e1000_media_type_copper;
247*5779Sxy150489 	dev_spec->sgmii_active = FALSE;
248*5779Sxy150489 
249*5779Sxy150489 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
250*5779Sxy150489 	if ((ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) ==
251*5779Sxy150489 	    E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES) {
252*5779Sxy150489 		hw->phy.media_type = e1000_media_type_internal_serdes;
253*5779Sxy150489 		ctrl_ext |= E1000_CTRL_I2C_ENA;
254*5779Sxy150489 	} else if (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_SGMII) {
255*5779Sxy150489 		dev_spec->sgmii_active = TRUE;
256*5779Sxy150489 		ctrl_ext |= E1000_CTRL_I2C_ENA;
257*5779Sxy150489 	} else {
258*5779Sxy150489 		ctrl_ext &= ~E1000_CTRL_I2C_ENA;
259*5779Sxy150489 	}
260*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
261*5779Sxy150489 
262*5779Sxy150489 	/* Set mta register count */
263*5779Sxy150489 	mac->mta_reg_count = 128;
264*5779Sxy150489 	/* Set rar entry count */
265*5779Sxy150489 	mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
266*5779Sxy150489 	/* Set if part includes ASF firmware */
267*5779Sxy150489 	mac->asf_firmware_present = TRUE;
268*5779Sxy150489 	/* Set if manageability features are enabled. */
269*5779Sxy150489 	mac->arc_subsystem_valid =
270*5779Sxy150489 	    (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
271*5779Sxy150489 	    ? TRUE : FALSE;
272*5779Sxy150489 
273*5779Sxy150489 	/* Function pointers */
274*5779Sxy150489 
275*5779Sxy150489 	/* bus type/speed/width */
276*5779Sxy150489 	func->get_bus_info = e1000_get_bus_info_pcie_generic;
277*5779Sxy150489 	/* reset */
278*5779Sxy150489 	func->reset_hw = e1000_reset_hw_82575;
279*5779Sxy150489 	/* hw initialization */
280*5779Sxy150489 	func->init_hw = e1000_init_hw_82575;
281*5779Sxy150489 	/* link setup */
282*5779Sxy150489 	func->setup_link = e1000_setup_link_generic;
283*5779Sxy150489 	/* physical interface link setup */
284*5779Sxy150489 	func->setup_physical_interface =
285*5779Sxy150489 	    (hw->phy.media_type == e1000_media_type_copper)
286*5779Sxy150489 	    ? e1000_setup_copper_link_82575
287*5779Sxy150489 	    : e1000_setup_fiber_serdes_link_82575;
288*5779Sxy150489 	/* check for link */
289*5779Sxy150489 	func->check_for_link = e1000_check_for_link_82575;
290*5779Sxy150489 	/* receive address register setting */
291*5779Sxy150489 	func->rar_set = e1000_rar_set_82575;
292*5779Sxy150489 	/* read mac address */
293*5779Sxy150489 	func->read_mac_addr = e1000_read_mac_addr_82575;
294*5779Sxy150489 	/* multicast address update */
295*5779Sxy150489 	func->update_mc_addr_list = e1000_update_mc_addr_list_generic;
296*5779Sxy150489 	/* writing VFTA */
297*5779Sxy150489 	func->write_vfta = e1000_write_vfta_generic;
298*5779Sxy150489 	/* clearing VFTA */
299*5779Sxy150489 	func->clear_vfta = e1000_clear_vfta_generic;
300*5779Sxy150489 	/* setting MTA */
301*5779Sxy150489 	func->mta_set = e1000_mta_set_generic;
302*5779Sxy150489 	/* blink LED */
303*5779Sxy150489 	func->blink_led = e1000_blink_led_generic;
304*5779Sxy150489 	/* setup LED */
305*5779Sxy150489 	func->setup_led = e1000_setup_led_generic;
306*5779Sxy150489 	/* cleanup LED */
307*5779Sxy150489 	func->cleanup_led = e1000_cleanup_led_generic;
308*5779Sxy150489 	/* turn on/off LED */
309*5779Sxy150489 	func->led_on = e1000_led_on_generic;
310*5779Sxy150489 	func->led_off = e1000_led_off_generic;
311*5779Sxy150489 	/* remove device */
312*5779Sxy150489 	func->remove_device = e1000_remove_device_generic;
313*5779Sxy150489 	/* clear hardware counters */
314*5779Sxy150489 	func->clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
315*5779Sxy150489 	/* link info */
316*5779Sxy150489 	func->get_link_up_info = e1000_get_link_up_info_82575;
317*5779Sxy150489 
318*5779Sxy150489 out:
319*5779Sxy150489 	return (ret_val);
320*5779Sxy150489 }
321*5779Sxy150489 
322*5779Sxy150489 /*
323*5779Sxy150489  * e1000_init_function_pointers_82575 - Init func ptrs.
324*5779Sxy150489  * @hw: pointer to the HW structure
325*5779Sxy150489  *
326*5779Sxy150489  * The only function explicitly called by the api module to initialize
327*5779Sxy150489  * all function pointers and parameters.
328*5779Sxy150489  */
329*5779Sxy150489 void
330*5779Sxy150489 e1000_init_function_pointers_82575(struct e1000_hw *hw)
331*5779Sxy150489 {
332*5779Sxy150489 	DEBUGFUNC("e1000_init_function_pointers_82575");
333*5779Sxy150489 
334*5779Sxy150489 	hw->func.init_mac_params = e1000_init_mac_params_82575;
335*5779Sxy150489 	hw->func.init_nvm_params = e1000_init_nvm_params_82575;
336*5779Sxy150489 	hw->func.init_phy_params = e1000_init_phy_params_82575;
337*5779Sxy150489 }
338*5779Sxy150489 
339*5779Sxy150489 /*
340*5779Sxy150489  * e1000_acquire_phy_82575 - Acquire rights to access PHY
341*5779Sxy150489  * @hw: pointer to the HW structure
342*5779Sxy150489  *
343*5779Sxy150489  * Acquire access rights to the correct PHY.  This is a
344*5779Sxy150489  * function pointer entry point called by the api module.
345*5779Sxy150489  */
346*5779Sxy150489 static s32
347*5779Sxy150489 e1000_acquire_phy_82575(struct e1000_hw *hw)
348*5779Sxy150489 {
349*5779Sxy150489 	u16 mask;
350*5779Sxy150489 
351*5779Sxy150489 	DEBUGFUNC("e1000_acquire_phy_82575");
352*5779Sxy150489 
353*5779Sxy150489 	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
354*5779Sxy150489 
355*5779Sxy150489 	return (e1000_acquire_swfw_sync_82575(hw, mask));
356*5779Sxy150489 }
357*5779Sxy150489 
358*5779Sxy150489 /*
359*5779Sxy150489  * e1000_release_phy_82575 - Release rights to access PHY
360*5779Sxy150489  * @hw: pointer to the HW structure
361*5779Sxy150489  *
362*5779Sxy150489  * A wrapper to release access rights to the correct PHY.  This is a
363*5779Sxy150489  * function pointer entry point called by the api module.
364*5779Sxy150489  */
365*5779Sxy150489 static void
366*5779Sxy150489 e1000_release_phy_82575(struct e1000_hw *hw)
367*5779Sxy150489 {
368*5779Sxy150489 	u16 mask;
369*5779Sxy150489 
370*5779Sxy150489 	DEBUGFUNC("e1000_release_phy_82575");
371*5779Sxy150489 
372*5779Sxy150489 	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
373*5779Sxy150489 	e1000_release_swfw_sync_82575(hw, mask);
374*5779Sxy150489 }
375*5779Sxy150489 
376*5779Sxy150489 /*
377*5779Sxy150489  * e1000_read_phy_reg_sgmii_82575 - Read PHY register using sgmii
378*5779Sxy150489  * @hw: pointer to the HW structure
379*5779Sxy150489  * @offset: register offset to be read
380*5779Sxy150489  * @data: pointer to the read data
381*5779Sxy150489  *
382*5779Sxy150489  * Reads the PHY register at offset using the serial gigabit media independent
383*5779Sxy150489  * interface and stores the retrieved information in data.
384*5779Sxy150489  */
385*5779Sxy150489 static s32
386*5779Sxy150489 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 *data)
387*5779Sxy150489 {
388*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
389*5779Sxy150489 	u32 i, i2ccmd = 0;
390*5779Sxy150489 
391*5779Sxy150489 	DEBUGFUNC("e1000_read_phy_reg_sgmii_82575");
392*5779Sxy150489 
393*5779Sxy150489 	if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
394*5779Sxy150489 		DEBUGOUT1("PHY Address %u is out of range\n", offset);
395*5779Sxy150489 		return (-E1000_ERR_PARAM);
396*5779Sxy150489 	}
397*5779Sxy150489 
398*5779Sxy150489 	/*
399*5779Sxy150489 	 * Set up Op-code, Phy Address, and register address in the I2CCMD
400*5779Sxy150489 	 * register.  The MAC will take care of interfacing with the
401*5779Sxy150489 	 * PHY to retrieve the desired data.
402*5779Sxy150489 	 */
403*5779Sxy150489 	i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
404*5779Sxy150489 	    (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
405*5779Sxy150489 	    (E1000_I2CCMD_OPCODE_READ));
406*5779Sxy150489 
407*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
408*5779Sxy150489 
409*5779Sxy150489 	/* Poll the ready bit to see if the I2C read completed */
410*5779Sxy150489 	for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
411*5779Sxy150489 		usec_delay(50);
412*5779Sxy150489 		i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD);
413*5779Sxy150489 		if (i2ccmd & E1000_I2CCMD_READY)
414*5779Sxy150489 			break;
415*5779Sxy150489 	}
416*5779Sxy150489 	if (!(i2ccmd & E1000_I2CCMD_READY)) {
417*5779Sxy150489 		DEBUGOUT("I2CCMD Read did not complete\n");
418*5779Sxy150489 		return (-E1000_ERR_PHY);
419*5779Sxy150489 	}
420*5779Sxy150489 	if (i2ccmd & E1000_I2CCMD_ERROR) {
421*5779Sxy150489 		DEBUGOUT("I2CCMD Error bit set\n");
422*5779Sxy150489 		return (-E1000_ERR_PHY);
423*5779Sxy150489 	}
424*5779Sxy150489 
425*5779Sxy150489 	/* Need to byte-swap the 16-bit value. */
426*5779Sxy150489 	*data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00);
427*5779Sxy150489 
428*5779Sxy150489 	return (E1000_SUCCESS);
429*5779Sxy150489 }
430*5779Sxy150489 
431*5779Sxy150489 /*
432*5779Sxy150489  * e1000_write_phy_reg_sgmii_82575 - Write PHY register using sgmii
433*5779Sxy150489  * @hw: pointer to the HW structure
434*5779Sxy150489  * @offset: register offset to write to
435*5779Sxy150489  * @data: data to write at register offset
436*5779Sxy150489  *
437*5779Sxy150489  * Writes the data to PHY register at the offset using the serial gigabit
438*5779Sxy150489  * media independent interface.
439*5779Sxy150489  */
440*5779Sxy150489 static s32
441*5779Sxy150489 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 data)
442*5779Sxy150489 {
443*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
444*5779Sxy150489 	u32 i, i2ccmd = 0;
445*5779Sxy150489 	u16 phy_data_swapped;
446*5779Sxy150489 
447*5779Sxy150489 	DEBUGFUNC("e1000_write_phy_reg_sgmii_82575");
448*5779Sxy150489 
449*5779Sxy150489 	if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
450*5779Sxy150489 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
451*5779Sxy150489 		return (-E1000_ERR_PARAM);
452*5779Sxy150489 	}
453*5779Sxy150489 
454*5779Sxy150489 	/* Swap the data bytes for the I2C interface */
455*5779Sxy150489 	phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
456*5779Sxy150489 
457*5779Sxy150489 	/*
458*5779Sxy150489 	 * Set up Op-code, Phy Address, and register address in the I2CCMD
459*5779Sxy150489 	 * register.  The MAC will take care of interfacing with the
460*5779Sxy150489 	 * PHY to retrieve the desired data.
461*5779Sxy150489 	 */
462*5779Sxy150489 	i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
463*5779Sxy150489 	    (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
464*5779Sxy150489 	    E1000_I2CCMD_OPCODE_WRITE |
465*5779Sxy150489 	    phy_data_swapped);
466*5779Sxy150489 
467*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
468*5779Sxy150489 
469*5779Sxy150489 	/* Poll the ready bit to see if the I2C read completed */
470*5779Sxy150489 	for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
471*5779Sxy150489 		usec_delay(50);
472*5779Sxy150489 		i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD);
473*5779Sxy150489 		if (i2ccmd & E1000_I2CCMD_READY)
474*5779Sxy150489 			break;
475*5779Sxy150489 	}
476*5779Sxy150489 	if (!(i2ccmd & E1000_I2CCMD_READY)) {
477*5779Sxy150489 		DEBUGOUT("I2CCMD Write did not complete\n");
478*5779Sxy150489 		return (-E1000_ERR_PHY);
479*5779Sxy150489 	}
480*5779Sxy150489 	if (i2ccmd & E1000_I2CCMD_ERROR) {
481*5779Sxy150489 		DEBUGOUT("I2CCMD Error bit set\n");
482*5779Sxy150489 		return (-E1000_ERR_PHY);
483*5779Sxy150489 	}
484*5779Sxy150489 
485*5779Sxy150489 	return (E1000_SUCCESS);
486*5779Sxy150489 }
487*5779Sxy150489 
488*5779Sxy150489 /*
489*5779Sxy150489  * e1000_get_phy_id_82575 - Retreive PHY addr and id
490*5779Sxy150489  * @hw: pointer to the HW structure
491*5779Sxy150489  *
492*5779Sxy150489  * Retreives the PHY address and ID for both PHY's which do and do not use
493*5779Sxy150489  * sgmi interface.
494*5779Sxy150489  */
495*5779Sxy150489 static s32
496*5779Sxy150489 e1000_get_phy_id_82575(struct e1000_hw *hw)
497*5779Sxy150489 {
498*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
499*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
500*5779Sxy150489 	u16 phy_id;
501*5779Sxy150489 
502*5779Sxy150489 	DEBUGFUNC("e1000_get_phy_id_82575");
503*5779Sxy150489 
504*5779Sxy150489 	/*
505*5779Sxy150489 	 * For SGMII PHYs, we try the list of possible addresses until
506*5779Sxy150489 	 * we find one that works.  For non-SGMII PHYs
507*5779Sxy150489 	 * (e.g. integrated copper PHYs), an address of 1 should
508*5779Sxy150489 	 * work.  The result of this function should mean phy->phy_addr
509*5779Sxy150489 	 * and phy->id are set correctly.
510*5779Sxy150489 	 */
511*5779Sxy150489 	if (!(e1000_sgmii_active_82575(hw))) {
512*5779Sxy150489 		phy->addr = 1;
513*5779Sxy150489 		ret_val = e1000_get_phy_id(hw);
514*5779Sxy150489 		goto out;
515*5779Sxy150489 	}
516*5779Sxy150489 
517*5779Sxy150489 	/*
518*5779Sxy150489 	 * The address field in the I2CCMD register is 3 bits and 0 is invalid.
519*5779Sxy150489 	 * Therefore, we need to test 1-7
520*5779Sxy150489 	 */
521*5779Sxy150489 	for (phy->addr = 1; phy->addr < 8; phy->addr++) {
522*5779Sxy150489 		ret_val = e1000_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id);
523*5779Sxy150489 		if (ret_val == E1000_SUCCESS) {
524*5779Sxy150489 			DEBUGOUT2("Vendor ID 0x%08X read at address %u\n",
525*5779Sxy150489 			    phy_id,
526*5779Sxy150489 			    phy->addr);
527*5779Sxy150489 			/*
528*5779Sxy150489 			 * At the time of this writing, The M88 part is
529*5779Sxy150489 			 * the only supported SGMII PHY product.
530*5779Sxy150489 			 */
531*5779Sxy150489 			if (phy_id == M88_VENDOR)
532*5779Sxy150489 				break;
533*5779Sxy150489 		} else {
534*5779Sxy150489 			DEBUGOUT1("PHY address %u was unreadable\n",
535*5779Sxy150489 			    phy->addr);
536*5779Sxy150489 		}
537*5779Sxy150489 	}
538*5779Sxy150489 
539*5779Sxy150489 	/* A valid PHY type couldn't be found. */
540*5779Sxy150489 	if (phy->addr == 8) {
541*5779Sxy150489 		phy->addr = 0;
542*5779Sxy150489 		ret_val = -E1000_ERR_PHY;
543*5779Sxy150489 		goto out;
544*5779Sxy150489 	}
545*5779Sxy150489 
546*5779Sxy150489 	ret_val = e1000_get_phy_id(hw);
547*5779Sxy150489 
548*5779Sxy150489 out:
549*5779Sxy150489 	return (ret_val);
550*5779Sxy150489 }
551*5779Sxy150489 
552*5779Sxy150489 /*
553*5779Sxy150489  * e1000_phy_hw_reset_sgmii_82575 - Performs a PHY reset
554*5779Sxy150489  * @hw: pointer to the HW structure
555*5779Sxy150489  *
556*5779Sxy150489  * Resets the PHY using the serial gigabit media independent interface.
557*5779Sxy150489  */
558*5779Sxy150489 static s32
559*5779Sxy150489 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
560*5779Sxy150489 {
561*5779Sxy150489 	s32 ret_val;
562*5779Sxy150489 
563*5779Sxy150489 	DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
564*5779Sxy150489 
565*5779Sxy150489 	/*
566*5779Sxy150489 	 * This isn't a true "hard" reset, but is the only reset
567*5779Sxy150489 	 * available to us at this time.
568*5779Sxy150489 	 */
569*5779Sxy150489 
570*5779Sxy150489 	DEBUGOUT("Soft resetting SGMII attached PHY...\n");
571*5779Sxy150489 
572*5779Sxy150489 	/*
573*5779Sxy150489 	 * SFP documentation requires the following to configure the SPF module
574*5779Sxy150489 	 * to work on SGMII.  No further documentation is given.
575*5779Sxy150489 	 */
576*5779Sxy150489 	ret_val = e1000_write_phy_reg(hw, 0x1B, 0x8084);
577*5779Sxy150489 	if (ret_val)
578*5779Sxy150489 		goto out;
579*5779Sxy150489 
580*5779Sxy150489 	ret_val = e1000_phy_commit(hw);
581*5779Sxy150489 
582*5779Sxy150489 out:
583*5779Sxy150489 	return (ret_val);
584*5779Sxy150489 }
585*5779Sxy150489 
586*5779Sxy150489 /*
587*5779Sxy150489  * e1000_set_d0_lplu_state_82575 - Set Low Power Linkup D0 state
588*5779Sxy150489  * @hw: pointer to the HW structure
589*5779Sxy150489  * @active: TRUE to enable LPLU, FALSE to disable
590*5779Sxy150489  *
591*5779Sxy150489  * Sets the LPLU D0 state according to the active flag.  When
592*5779Sxy150489  * activating LPLU this function also disables smart speed
593*5779Sxy150489  * and vice versa.  LPLU will not be activated unless the
594*5779Sxy150489  * device autonegotiation advertisement meets standards of
595*5779Sxy150489  * either 10 or 10/100 or 10/100/1000 at all duplexes.
596*5779Sxy150489  * This is a function pointer entry point only called by
597*5779Sxy150489  * PHY setup routines.
598*5779Sxy150489  */
599*5779Sxy150489 static s32
600*5779Sxy150489 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
601*5779Sxy150489 {
602*5779Sxy150489 	struct e1000_phy_info *phy = &hw->phy;
603*5779Sxy150489 	s32 ret_val;
604*5779Sxy150489 	u16 data;
605*5779Sxy150489 
606*5779Sxy150489 	DEBUGFUNC("e1000_set_d0_lplu_state_82575");
607*5779Sxy150489 
608*5779Sxy150489 	ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
609*5779Sxy150489 	if (ret_val)
610*5779Sxy150489 		goto out;
611*5779Sxy150489 
612*5779Sxy150489 	if (active) {
613*5779Sxy150489 		data |= IGP02E1000_PM_D0_LPLU;
614*5779Sxy150489 		ret_val = e1000_write_phy_reg(hw,
615*5779Sxy150489 		    IGP02E1000_PHY_POWER_MGMT,
616*5779Sxy150489 		    data);
617*5779Sxy150489 		if (ret_val)
618*5779Sxy150489 			goto out;
619*5779Sxy150489 
620*5779Sxy150489 		/* When LPLU is enabled, we should disable SmartSpeed */
621*5779Sxy150489 		ret_val = e1000_read_phy_reg(hw,
622*5779Sxy150489 		    IGP01E1000_PHY_PORT_CONFIG,
623*5779Sxy150489 		    &data);
624*5779Sxy150489 		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
625*5779Sxy150489 		ret_val = e1000_write_phy_reg(hw,
626*5779Sxy150489 		    IGP01E1000_PHY_PORT_CONFIG,
627*5779Sxy150489 		    data);
628*5779Sxy150489 		if (ret_val)
629*5779Sxy150489 			goto out;
630*5779Sxy150489 	} else {
631*5779Sxy150489 		data &= ~IGP02E1000_PM_D0_LPLU;
632*5779Sxy150489 		ret_val = e1000_write_phy_reg(hw,
633*5779Sxy150489 		    IGP02E1000_PHY_POWER_MGMT,
634*5779Sxy150489 		    data);
635*5779Sxy150489 		/*
636*5779Sxy150489 		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
637*5779Sxy150489 		 * during Dx states where the power conservation is most
638*5779Sxy150489 		 * important.  During driver activity we should enable
639*5779Sxy150489 		 * SmartSpeed, so performance is maintained.
640*5779Sxy150489 		 */
641*5779Sxy150489 		if (phy->smart_speed == e1000_smart_speed_on) {
642*5779Sxy150489 			ret_val = e1000_read_phy_reg(hw,
643*5779Sxy150489 			    IGP01E1000_PHY_PORT_CONFIG,
644*5779Sxy150489 			    &data);
645*5779Sxy150489 			if (ret_val)
646*5779Sxy150489 				goto out;
647*5779Sxy150489 
648*5779Sxy150489 			data |= IGP01E1000_PSCFR_SMART_SPEED;
649*5779Sxy150489 			ret_val = e1000_write_phy_reg(hw,
650*5779Sxy150489 			    IGP01E1000_PHY_PORT_CONFIG,
651*5779Sxy150489 			    data);
652*5779Sxy150489 			if (ret_val)
653*5779Sxy150489 				goto out;
654*5779Sxy150489 		} else if (phy->smart_speed == e1000_smart_speed_off) {
655*5779Sxy150489 			ret_val = e1000_read_phy_reg(hw,
656*5779Sxy150489 			    IGP01E1000_PHY_PORT_CONFIG,
657*5779Sxy150489 			    &data);
658*5779Sxy150489 			if (ret_val)
659*5779Sxy150489 				goto out;
660*5779Sxy150489 
661*5779Sxy150489 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
662*5779Sxy150489 			ret_val = e1000_write_phy_reg(hw,
663*5779Sxy150489 			    IGP01E1000_PHY_PORT_CONFIG,
664*5779Sxy150489 			    data);
665*5779Sxy150489 			if (ret_val)
666*5779Sxy150489 				goto out;
667*5779Sxy150489 		}
668*5779Sxy150489 	}
669*5779Sxy150489 
670*5779Sxy150489 out:
671*5779Sxy150489 	return (ret_val);
672*5779Sxy150489 }
673*5779Sxy150489 
674*5779Sxy150489 /*
675*5779Sxy150489  * e1000_acquire_nvm_82575 - Request for access to EEPROM
676*5779Sxy150489  * @hw: pointer to the HW structure
677*5779Sxy150489  *
678*5779Sxy150489  * Acquire the necessary semaphores for exclussive access to the EEPROM.
679*5779Sxy150489  * Set the EEPROM access request bit and wait for EEPROM access grant bit.
680*5779Sxy150489  * Return successful if access grant bit set, else clear the request for
681*5779Sxy150489  * EEPROM access and return -E1000_ERR_NVM (-1).
682*5779Sxy150489  */
683*5779Sxy150489 static s32
684*5779Sxy150489 e1000_acquire_nvm_82575(struct e1000_hw *hw)
685*5779Sxy150489 {
686*5779Sxy150489 	s32 ret_val;
687*5779Sxy150489 
688*5779Sxy150489 	DEBUGFUNC("e1000_acquire_nvm_82575");
689*5779Sxy150489 
690*5779Sxy150489 	ret_val = e1000_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
691*5779Sxy150489 	if (ret_val)
692*5779Sxy150489 		goto out;
693*5779Sxy150489 
694*5779Sxy150489 	ret_val = e1000_acquire_nvm_generic(hw);
695*5779Sxy150489 
696*5779Sxy150489 	if (ret_val)
697*5779Sxy150489 		e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
698*5779Sxy150489 
699*5779Sxy150489 out:
700*5779Sxy150489 	return (ret_val);
701*5779Sxy150489 }
702*5779Sxy150489 
703*5779Sxy150489 /*
704*5779Sxy150489  * e1000_release_nvm_82575 - Release exclusive access to EEPROM
705*5779Sxy150489  * @hw: pointer to the HW structure
706*5779Sxy150489  *
707*5779Sxy150489  * Stop any current commands to the EEPROM and clear the EEPROM request bit,
708*5779Sxy150489  * then release the semaphores acquired.
709*5779Sxy150489  */
710*5779Sxy150489 static void
711*5779Sxy150489 e1000_release_nvm_82575(struct e1000_hw *hw)
712*5779Sxy150489 {
713*5779Sxy150489 	DEBUGFUNC("e1000_release_nvm_82575");
714*5779Sxy150489 
715*5779Sxy150489 	e1000_release_nvm_generic(hw);
716*5779Sxy150489 	e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
717*5779Sxy150489 }
718*5779Sxy150489 
719*5779Sxy150489 /*
720*5779Sxy150489  * e1000_acquire_swfw_sync_82575 - Acquire SW/FW semaphore
721*5779Sxy150489  * @hw: pointer to the HW structure
722*5779Sxy150489  * @mask: specifies which semaphore to acquire
723*5779Sxy150489  *
724*5779Sxy150489  * Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
725*5779Sxy150489  * will also specify which port we're acquiring the lock for.
726*5779Sxy150489  */
727*5779Sxy150489 static s32
728*5779Sxy150489 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
729*5779Sxy150489 {
730*5779Sxy150489 	u32 swfw_sync;
731*5779Sxy150489 	u32 swmask = mask;
732*5779Sxy150489 	u32 fwmask = mask << 16;
733*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
734*5779Sxy150489 	s32 i = 0, timeout = 200;	/* FIXME: find real value to use here */
735*5779Sxy150489 
736*5779Sxy150489 	DEBUGFUNC("e1000_acquire_swfw_sync_82575");
737*5779Sxy150489 
738*5779Sxy150489 	while (i < timeout) {
739*5779Sxy150489 		if (e1000_get_hw_semaphore_generic(hw)) {
740*5779Sxy150489 			ret_val = -E1000_ERR_SWFW_SYNC;
741*5779Sxy150489 			goto out;
742*5779Sxy150489 		}
743*5779Sxy150489 
744*5779Sxy150489 		swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
745*5779Sxy150489 		if (!(swfw_sync & (fwmask | swmask)))
746*5779Sxy150489 			break;
747*5779Sxy150489 
748*5779Sxy150489 		/*
749*5779Sxy150489 		 * Firmware currently using resource (fwmask)
750*5779Sxy150489 		 * or other software thread using resource (swmask)
751*5779Sxy150489 		 */
752*5779Sxy150489 		e1000_put_hw_semaphore_generic(hw);
753*5779Sxy150489 		msec_delay_irq(5);
754*5779Sxy150489 		i++;
755*5779Sxy150489 	}
756*5779Sxy150489 
757*5779Sxy150489 	if (i == timeout) {
758*5779Sxy150489 		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
759*5779Sxy150489 		ret_val = -E1000_ERR_SWFW_SYNC;
760*5779Sxy150489 		goto out;
761*5779Sxy150489 	}
762*5779Sxy150489 
763*5779Sxy150489 	swfw_sync |= swmask;
764*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
765*5779Sxy150489 
766*5779Sxy150489 	e1000_put_hw_semaphore_generic(hw);
767*5779Sxy150489 
768*5779Sxy150489 out:
769*5779Sxy150489 	return (ret_val);
770*5779Sxy150489 }
771*5779Sxy150489 
772*5779Sxy150489 /*
773*5779Sxy150489  * e1000_release_swfw_sync_82575 - Release SW/FW semaphore
774*5779Sxy150489  * @hw: pointer to the HW structure
775*5779Sxy150489  * @mask: specifies which semaphore to acquire
776*5779Sxy150489  *
777*5779Sxy150489  * Release the SW/FW semaphore used to access the PHY or NVM.  The mask
778*5779Sxy150489  * will also specify which port we're releasing the lock for.
779*5779Sxy150489  */
780*5779Sxy150489 static void
781*5779Sxy150489 e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
782*5779Sxy150489 {
783*5779Sxy150489 	u32 swfw_sync;
784*5779Sxy150489 
785*5779Sxy150489 	DEBUGFUNC("e1000_release_swfw_sync_82575");
786*5779Sxy150489 
787*5779Sxy150489 	while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS) {
788*5779Sxy150489 		/* Empty */
789*5779Sxy150489 	}
790*5779Sxy150489 
791*5779Sxy150489 	swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
792*5779Sxy150489 	swfw_sync &= ~mask;
793*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
794*5779Sxy150489 
795*5779Sxy150489 	e1000_put_hw_semaphore_generic(hw);
796*5779Sxy150489 }
797*5779Sxy150489 
798*5779Sxy150489 /*
799*5779Sxy150489  * e1000_get_cfg_done_82575 - Read config done bit
800*5779Sxy150489  * @hw: pointer to the HW structure
801*5779Sxy150489  *
802*5779Sxy150489  * Read the management control register for the config done bit for
803*5779Sxy150489  * completion status.  NOTE: silicon which is EEPROM-less will fail trying
804*5779Sxy150489  * to read the config done bit, so an error is *ONLY* logged and returns
805*5779Sxy150489  * E1000_SUCCESS.  If we were to return with error, EEPROM-less silicon
806*5779Sxy150489  * would not be able to be reset or change link.
807*5779Sxy150489  */
808*5779Sxy150489 static s32
809*5779Sxy150489 e1000_get_cfg_done_82575(struct e1000_hw *hw)
810*5779Sxy150489 {
811*5779Sxy150489 	s32 timeout = PHY_CFG_TIMEOUT;
812*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
813*5779Sxy150489 	u32 mask = E1000_NVM_CFG_DONE_PORT_0;
814*5779Sxy150489 
815*5779Sxy150489 	DEBUGFUNC("e1000_get_cfg_done_82575");
816*5779Sxy150489 
817*5779Sxy150489 	if (hw->bus.func == 1)
818*5779Sxy150489 		mask = E1000_NVM_CFG_DONE_PORT_1;
819*5779Sxy150489 
820*5779Sxy150489 	while (timeout) {
821*5779Sxy150489 		if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask)
822*5779Sxy150489 			break;
823*5779Sxy150489 		msec_delay(1);
824*5779Sxy150489 		timeout--;
825*5779Sxy150489 	}
826*5779Sxy150489 	if (!timeout) {
827*5779Sxy150489 		DEBUGOUT("MNG configuration cycle has not completed.\n");
828*5779Sxy150489 	}
829*5779Sxy150489 
830*5779Sxy150489 	/* If EEPROM is not marked present, init the PHY manually */
831*5779Sxy150489 	if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) &&
832*5779Sxy150489 	    (hw->phy.type == e1000_phy_igp_3)) {
833*5779Sxy150489 		(void) e1000_phy_init_script_igp3(hw);
834*5779Sxy150489 	}
835*5779Sxy150489 	return (ret_val);
836*5779Sxy150489 }
837*5779Sxy150489 
838*5779Sxy150489 /*
839*5779Sxy150489  * e1000_get_link_up_info_82575 - Get link speed/duplex info
840*5779Sxy150489  * @hw: pointer to the HW structure
841*5779Sxy150489  * @speed: stores the current speed
842*5779Sxy150489  * @duplex: stores the current duplex
843*5779Sxy150489  *
844*5779Sxy150489  * This is a wrapper function, if using the serial gigabit media independent
845*5779Sxy150489  * interface, use pcs to retreive the link speed and duplex information.
846*5779Sxy150489  * Otherwise, use the generic function to get the link speed and duplex info.
847*5779Sxy150489  */
848*5779Sxy150489 static s32
849*5779Sxy150489 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, u16 *duplex)
850*5779Sxy150489 {
851*5779Sxy150489 	s32 ret_val;
852*5779Sxy150489 
853*5779Sxy150489 	DEBUGFUNC("e1000_get_link_up_info_82575");
854*5779Sxy150489 
855*5779Sxy150489 	if (hw->phy.media_type != e1000_media_type_copper ||
856*5779Sxy150489 	    e1000_sgmii_active_82575(hw)) {
857*5779Sxy150489 		ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, speed,
858*5779Sxy150489 		    duplex);
859*5779Sxy150489 	} else {
860*5779Sxy150489 		ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed,
861*5779Sxy150489 		    duplex);
862*5779Sxy150489 	}
863*5779Sxy150489 
864*5779Sxy150489 	return (ret_val);
865*5779Sxy150489 }
866*5779Sxy150489 
867*5779Sxy150489 /*
868*5779Sxy150489  * e1000_check_for_link_82575 - Check for link
869*5779Sxy150489  * @hw: pointer to the HW structure
870*5779Sxy150489  *
871*5779Sxy150489  * If sgmii is enabled, then use the pcs register to determine link, otherwise
872*5779Sxy150489  * use the generic interface for determining link.
873*5779Sxy150489  */
874*5779Sxy150489 static s32
875*5779Sxy150489 e1000_check_for_link_82575(struct e1000_hw *hw)
876*5779Sxy150489 {
877*5779Sxy150489 	s32 ret_val;
878*5779Sxy150489 	u16 speed, duplex;
879*5779Sxy150489 
880*5779Sxy150489 	DEBUGFUNC("e1000_check_for_link_82575");
881*5779Sxy150489 
882*5779Sxy150489 	/* SGMII link check is done through the PCS register. */
883*5779Sxy150489 	if ((hw->phy.media_type != e1000_media_type_copper) ||
884*5779Sxy150489 	    (e1000_sgmii_active_82575(hw)))
885*5779Sxy150489 		ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed,
886*5779Sxy150489 		    &duplex);
887*5779Sxy150489 	else
888*5779Sxy150489 		ret_val = e1000_check_for_copper_link_generic(hw);
889*5779Sxy150489 
890*5779Sxy150489 	return (ret_val);
891*5779Sxy150489 }
892*5779Sxy150489 
893*5779Sxy150489 /*
894*5779Sxy150489  * e1000_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
895*5779Sxy150489  * @hw: pointer to the HW structure
896*5779Sxy150489  * @speed: stores the current speed
897*5779Sxy150489  * @duplex: stores the current duplex
898*5779Sxy150489  *
899*5779Sxy150489  * Using the physical coding sub-layer (PCS), retreive the current speed and
900*5779Sxy150489  * duplex, then store the values in the pointers provided.
901*5779Sxy150489  */
902*5779Sxy150489 static s32
903*5779Sxy150489 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
904*5779Sxy150489     u16 *speed, u16 *duplex)
905*5779Sxy150489 {
906*5779Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
907*5779Sxy150489 	u32 pcs;
908*5779Sxy150489 
909*5779Sxy150489 	DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575");
910*5779Sxy150489 
911*5779Sxy150489 	/* Set up defaults for the return values of this function */
912*5779Sxy150489 	mac->serdes_has_link = FALSE;
913*5779Sxy150489 	*speed = 0;
914*5779Sxy150489 	*duplex = 0;
915*5779Sxy150489 
916*5779Sxy150489 	/*
917*5779Sxy150489 	 * Read the PCS Status register for link state. For non-copper mode,
918*5779Sxy150489 	 * the status register is not accurate. The PCS status register is
919*5779Sxy150489 	 * used instead.
920*5779Sxy150489 	 */
921*5779Sxy150489 	pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT);
922*5779Sxy150489 
923*5779Sxy150489 	/*
924*5779Sxy150489 	 * The link up bit determines when link is up on autoneg. The sync ok
925*5779Sxy150489 	 * gets set once both sides sync up and agree upon link. Stable link
926*5779Sxy150489 	 * can be determined by checking for both link up and link sync ok
927*5779Sxy150489 	 */
928*5779Sxy150489 	if ((pcs & E1000_PCS_LSTS_LINK_OK) && (pcs & E1000_PCS_LSTS_SYNK_OK)) {
929*5779Sxy150489 		mac->serdes_has_link = TRUE;
930*5779Sxy150489 
931*5779Sxy150489 		/* Detect and store PCS speed */
932*5779Sxy150489 		if (pcs & E1000_PCS_LSTS_SPEED_1000) {
933*5779Sxy150489 			*speed = SPEED_1000;
934*5779Sxy150489 		} else if (pcs & E1000_PCS_LSTS_SPEED_100) {
935*5779Sxy150489 			*speed = SPEED_100;
936*5779Sxy150489 		} else {
937*5779Sxy150489 			*speed = SPEED_10;
938*5779Sxy150489 		}
939*5779Sxy150489 
940*5779Sxy150489 		/* Detect and store PCS duplex */
941*5779Sxy150489 		if (pcs & E1000_PCS_LSTS_DUPLEX_FULL) {
942*5779Sxy150489 			*duplex = FULL_DUPLEX;
943*5779Sxy150489 		} else {
944*5779Sxy150489 			*duplex = HALF_DUPLEX;
945*5779Sxy150489 		}
946*5779Sxy150489 	}
947*5779Sxy150489 	return (E1000_SUCCESS);
948*5779Sxy150489 }
949*5779Sxy150489 
950*5779Sxy150489 /*
951*5779Sxy150489  * e1000_rar_set_82575 - Set receive address register
952*5779Sxy150489  * @hw: pointer to the HW structure
953*5779Sxy150489  * @addr: pointer to the receive address
954*5779Sxy150489  * @index: receive address array register
955*5779Sxy150489  *
956*5779Sxy150489  * Sets the receive address array register at index to the address passed
957*5779Sxy150489  * in by addr.
958*5779Sxy150489  */
959*5779Sxy150489 static void
960*5779Sxy150489 e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index)
961*5779Sxy150489 {
962*5779Sxy150489 	DEBUGFUNC("e1000_rar_set_82575");
963*5779Sxy150489 
964*5779Sxy150489 	if (index < E1000_RAR_ENTRIES_82575) {
965*5779Sxy150489 		e1000_rar_set_generic(hw, addr, index);
966*5779Sxy150489 	}
967*5779Sxy150489 }
968*5779Sxy150489 
969*5779Sxy150489 /*
970*5779Sxy150489  * e1000_reset_hw_82575 - Reset hardware
971*5779Sxy150489  * @hw: pointer to the HW structure
972*5779Sxy150489  *
973*5779Sxy150489  * This resets the hardware into a known state.  This is a
974*5779Sxy150489  * function pointer entry point called by the api module.
975*5779Sxy150489  */
976*5779Sxy150489 static s32
977*5779Sxy150489 e1000_reset_hw_82575(struct e1000_hw *hw)
978*5779Sxy150489 {
979*5779Sxy150489 	u32 ctrl;
980*5779Sxy150489 	s32 ret_val;
981*5779Sxy150489 
982*5779Sxy150489 	DEBUGFUNC("e1000_reset_hw_82575");
983*5779Sxy150489 
984*5779Sxy150489 	/*
985*5779Sxy150489 	 * Prevent the PCI-E bus from sticking if there is no TLP connection
986*5779Sxy150489 	 * on the last TLP read/write transaction when MAC is reset.
987*5779Sxy150489 	 */
988*5779Sxy150489 	ret_val = e1000_disable_pcie_master_generic(hw);
989*5779Sxy150489 	if (ret_val) {
990*5779Sxy150489 		DEBUGOUT("PCI-E Master disable polling has failed.\n");
991*5779Sxy150489 	}
992*5779Sxy150489 
993*5779Sxy150489 	DEBUGOUT("Masking off all interrupts\n");
994*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
995*5779Sxy150489 
996*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
997*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
998*5779Sxy150489 	E1000_WRITE_FLUSH(hw);
999*5779Sxy150489 
1000*5779Sxy150489 	msec_delay(10);
1001*5779Sxy150489 
1002*5779Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
1003*5779Sxy150489 
1004*5779Sxy150489 	DEBUGOUT("Issuing a global reset to MAC\n");
1005*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
1006*5779Sxy150489 
1007*5779Sxy150489 	ret_val = e1000_get_auto_rd_done_generic(hw);
1008*5779Sxy150489 	if (ret_val) {
1009*5779Sxy150489 		/*
1010*5779Sxy150489 		 * When auto config read does not complete, do not
1011*5779Sxy150489 		 * return with an error. This can happen in situations
1012*5779Sxy150489 		 * where there is no eeprom and prevents getting link.
1013*5779Sxy150489 		 */
1014*5779Sxy150489 		DEBUGOUT("Auto Read Done did not complete\n");
1015*5779Sxy150489 	}
1016*5779Sxy150489 
1017*5779Sxy150489 	/* If EEPROM is not present, run manual init scripts */
1018*5779Sxy150489 	if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0)
1019*5779Sxy150489 		(void) e1000_reset_init_script_82575(hw);
1020*5779Sxy150489 
1021*5779Sxy150489 	/* Clear any pending interrupt events. */
1022*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
1023*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_ICR);
1024*5779Sxy150489 
1025*5779Sxy150489 	(void) e1000_check_alt_mac_addr_generic(hw);
1026*5779Sxy150489 
1027*5779Sxy150489 	return (ret_val);
1028*5779Sxy150489 }
1029*5779Sxy150489 
1030*5779Sxy150489 /*
1031*5779Sxy150489  * e1000_init_hw_82575 - Initialize hardware
1032*5779Sxy150489  * @hw: pointer to the HW structure
1033*5779Sxy150489  *
1034*5779Sxy150489  * This inits the hardware readying it for operation.
1035*5779Sxy150489  */
1036*5779Sxy150489 static s32
1037*5779Sxy150489 e1000_init_hw_82575(struct e1000_hw *hw)
1038*5779Sxy150489 {
1039*5779Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
1040*5779Sxy150489 	s32 ret_val;
1041*5779Sxy150489 	u16 i, rar_count = mac->rar_entry_count;
1042*5779Sxy150489 
1043*5779Sxy150489 	DEBUGFUNC("e1000_init_hw_82575");
1044*5779Sxy150489 
1045*5779Sxy150489 	/* Initialize identification LED */
1046*5779Sxy150489 	ret_val = e1000_id_led_init_generic(hw);
1047*5779Sxy150489 	if (ret_val) {
1048*5779Sxy150489 		DEBUGOUT("Error initializing identification LED\n");
1049*5779Sxy150489 		/* This is not fatal and we should not stop init due to this */
1050*5779Sxy150489 	}
1051*5779Sxy150489 
1052*5779Sxy150489 	/* Disabling VLAN filtering */
1053*5779Sxy150489 	DEBUGOUT("Initializing the IEEE VLAN\n");
1054*5779Sxy150489 	e1000_clear_vfta(hw);
1055*5779Sxy150489 
1056*5779Sxy150489 	/* Setup the receive address */
1057*5779Sxy150489 	e1000_init_rx_addrs_generic(hw, rar_count);
1058*5779Sxy150489 	/* Zero out the Multicast HASH table */
1059*5779Sxy150489 	DEBUGOUT("Zeroing the MTA\n");
1060*5779Sxy150489 	for (i = 0; i < mac->mta_reg_count; i++)
1061*5779Sxy150489 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
1062*5779Sxy150489 
1063*5779Sxy150489 	/* Setup link and flow control */
1064*5779Sxy150489 	ret_val = e1000_setup_link(hw);
1065*5779Sxy150489 
1066*5779Sxy150489 	/*
1067*5779Sxy150489 	 * Clear all of the statistics registers (clear on read).  It is
1068*5779Sxy150489 	 * important that we do this after we have tried to establish link
1069*5779Sxy150489 	 * because the symbol error count will increment wildly if there
1070*5779Sxy150489 	 * is no link.
1071*5779Sxy150489 	 */
1072*5779Sxy150489 	e1000_clear_hw_cntrs_82575(hw);
1073*5779Sxy150489 
1074*5779Sxy150489 	return (ret_val);
1075*5779Sxy150489 }
1076*5779Sxy150489 
1077*5779Sxy150489 /*
1078*5779Sxy150489  * e1000_setup_copper_link_82575 - Configure copper link settings
1079*5779Sxy150489  * @hw: pointer to the HW structure
1080*5779Sxy150489  *
1081*5779Sxy150489  * Configures the link for auto-neg or forced speed and duplex.  Then we check
1082*5779Sxy150489  * for link, once link is established calls to configure collision distance
1083*5779Sxy150489  * and flow control are called.
1084*5779Sxy150489  */
1085*5779Sxy150489 static s32
1086*5779Sxy150489 e1000_setup_copper_link_82575(struct e1000_hw *hw)
1087*5779Sxy150489 {
1088*5779Sxy150489 	u32 ctrl, led_ctrl;
1089*5779Sxy150489 	s32 ret_val;
1090*5779Sxy150489 	bool link;
1091*5779Sxy150489 
1092*5779Sxy150489 	DEBUGFUNC("e1000_setup_copper_link_82575");
1093*5779Sxy150489 
1094*5779Sxy150489 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
1095*5779Sxy150489 	ctrl |= E1000_CTRL_SLU;
1096*5779Sxy150489 	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
1097*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
1098*5779Sxy150489 
1099*5779Sxy150489 	switch (hw->phy.type) {
1100*5779Sxy150489 	case e1000_phy_m88:
1101*5779Sxy150489 		ret_val = e1000_copper_link_setup_m88(hw);
1102*5779Sxy150489 		break;
1103*5779Sxy150489 	case e1000_phy_igp_3:
1104*5779Sxy150489 		ret_val = e1000_copper_link_setup_igp(hw);
1105*5779Sxy150489 		/* Setup activity LED */
1106*5779Sxy150489 		led_ctrl = E1000_READ_REG(hw, E1000_LEDCTL);
1107*5779Sxy150489 		led_ctrl &= IGP_ACTIVITY_LED_MASK;
1108*5779Sxy150489 		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
1109*5779Sxy150489 		E1000_WRITE_REG(hw, E1000_LEDCTL, led_ctrl);
1110*5779Sxy150489 		break;
1111*5779Sxy150489 	default:
1112*5779Sxy150489 		ret_val = -E1000_ERR_PHY;
1113*5779Sxy150489 		break;
1114*5779Sxy150489 	}
1115*5779Sxy150489 
1116*5779Sxy150489 	if (ret_val)
1117*5779Sxy150489 		goto out;
1118*5779Sxy150489 
1119*5779Sxy150489 	if (hw->mac.autoneg) {
1120*5779Sxy150489 		/*
1121*5779Sxy150489 		 * Setup autoneg and flow control advertisement
1122*5779Sxy150489 		 * and perform autonegotiation.
1123*5779Sxy150489 		 */
1124*5779Sxy150489 		ret_val = e1000_copper_link_autoneg(hw);
1125*5779Sxy150489 		if (ret_val)
1126*5779Sxy150489 			goto out;
1127*5779Sxy150489 	} else {
1128*5779Sxy150489 		/*
1129*5779Sxy150489 		 * PHY will be set to 10H, 10F, 100H or 100F
1130*5779Sxy150489 		 * depending on user settings.
1131*5779Sxy150489 		 */
1132*5779Sxy150489 		DEBUGOUT("Forcing Speed and Duplex\n");
1133*5779Sxy150489 		ret_val = e1000_phy_force_speed_duplex(hw);
1134*5779Sxy150489 		if (ret_val) {
1135*5779Sxy150489 			DEBUGOUT("Error Forcing Speed and Duplex\n");
1136*5779Sxy150489 			goto out;
1137*5779Sxy150489 		}
1138*5779Sxy150489 	}
1139*5779Sxy150489 
1140*5779Sxy150489 	ret_val = e1000_configure_pcs_link_82575(hw);
1141*5779Sxy150489 	if (ret_val)
1142*5779Sxy150489 		goto out;
1143*5779Sxy150489 
1144*5779Sxy150489 	/*
1145*5779Sxy150489 	 * Check link status. Wait up to 100 microseconds for link to become
1146*5779Sxy150489 	 * valid.
1147*5779Sxy150489 	 */
1148*5779Sxy150489 	ret_val = e1000_phy_has_link_generic(hw,
1149*5779Sxy150489 	    COPPER_LINK_UP_LIMIT,
1150*5779Sxy150489 	    10,
1151*5779Sxy150489 	    &link);
1152*5779Sxy150489 	if (ret_val)
1153*5779Sxy150489 		goto out;
1154*5779Sxy150489 
1155*5779Sxy150489 	if (link) {
1156*5779Sxy150489 		DEBUGOUT("Valid link established!!!\n");
1157*5779Sxy150489 		/* Config the MAC and PHY after link is up */
1158*5779Sxy150489 		e1000_config_collision_dist_generic(hw);
1159*5779Sxy150489 		ret_val = e1000_config_fc_after_link_up_generic(hw);
1160*5779Sxy150489 	} else {
1161*5779Sxy150489 		DEBUGOUT("Unable to establish link!!!\n");
1162*5779Sxy150489 	}
1163*5779Sxy150489 
1164*5779Sxy150489 out:
1165*5779Sxy150489 	return (ret_val);
1166*5779Sxy150489 }
1167*5779Sxy150489 
1168*5779Sxy150489 /*
1169*5779Sxy150489  * e1000_setup_fiber_serdes_link_82575 - Setup link for fiber/serdes
1170*5779Sxy150489  * @hw: pointer to the HW structure
1171*5779Sxy150489  *
1172*5779Sxy150489  * Configures speed and duplex for fiber and serdes links.
1173*5779Sxy150489  */
1174*5779Sxy150489 static s32
1175*5779Sxy150489 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
1176*5779Sxy150489 {
1177*5779Sxy150489 	u32 reg;
1178*5779Sxy150489 
1179*5779Sxy150489 	DEBUGFUNC("e1000_setup_fiber_serdes_link_82575");
1180*5779Sxy150489 
1181*5779Sxy150489 	/*
1182*5779Sxy150489 	 * On the 82575, SerDes loopback mode persists until it is
1183*5779Sxy150489 	 * explicitly turned off or a power cycle is performed.  A read to
1184*5779Sxy150489 	 * the register does not indicate its status.  Therefore, we ensure
1185*5779Sxy150489 	 * loopback mode is disabled during initialization.
1186*5779Sxy150489 	 */
1187*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
1188*5779Sxy150489 
1189*5779Sxy150489 	/* Force link up, set 1gb, set both sw defined pins */
1190*5779Sxy150489 	reg = E1000_READ_REG(hw, E1000_CTRL);
1191*5779Sxy150489 	reg |= E1000_CTRL_SLU |
1192*5779Sxy150489 	    E1000_CTRL_SPD_1000 |
1193*5779Sxy150489 	    E1000_CTRL_FRCSPD |
1194*5779Sxy150489 	    E1000_CTRL_SWDPIN0 |
1195*5779Sxy150489 	    E1000_CTRL_SWDPIN1;
1196*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_CTRL, reg);
1197*5779Sxy150489 
1198*5779Sxy150489 	/* Set switch control to serdes energy detect */
1199*5779Sxy150489 	reg = E1000_READ_REG(hw, E1000_CONNSW);
1200*5779Sxy150489 	reg |= E1000_CONNSW_ENRGSRC;
1201*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_CONNSW, reg);
1202*5779Sxy150489 
1203*5779Sxy150489 	/*
1204*5779Sxy150489 	 * New SerDes mode allows for forcing speed or autonegotiating speed
1205*5779Sxy150489 	 * at 1gb. Autoneg should be default set by most drivers. This is the
1206*5779Sxy150489 	 * mode that will be compatible with older link partners and switches.
1207*5779Sxy150489 	 * However, both are supported by the hardware and some drivers/tools.
1208*5779Sxy150489 	 */
1209*5779Sxy150489 	reg = E1000_READ_REG(hw, E1000_PCS_LCTL);
1210*5779Sxy150489 
1211*5779Sxy150489 	reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
1212*5779Sxy150489 	    E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
1213*5779Sxy150489 
1214*5779Sxy150489 	if (hw->mac.autoneg) {
1215*5779Sxy150489 		/* Set PCS register for autoneg */
1216*5779Sxy150489 		reg |= E1000_PCS_LCTL_FSV_1000 |	/* Force 1000    */
1217*5779Sxy150489 		    E1000_PCS_LCTL_FDV_FULL |	/* SerDes Full duplex */
1218*5779Sxy150489 		    E1000_PCS_LCTL_AN_ENABLE |	/* Enable Autoneg */
1219*5779Sxy150489 		    E1000_PCS_LCTL_AN_RESTART;	/* Restart autoneg */
1220*5779Sxy150489 		DEBUGOUT1("Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
1221*5779Sxy150489 	} else {
1222*5779Sxy150489 		/* Set PCS register for forced speed */
1223*5779Sxy150489 		reg |= E1000_PCS_LCTL_FLV_LINK_UP |	/* Force link up */
1224*5779Sxy150489 		    E1000_PCS_LCTL_FSV_1000 |	/* Force 1000    */
1225*5779Sxy150489 		    E1000_PCS_LCTL_FDV_FULL |	/* SerDes Full duplex */
1226*5779Sxy150489 		    E1000_PCS_LCTL_FSD |	/* Force Speed */
1227*5779Sxy150489 		    E1000_PCS_LCTL_FORCE_LINK;	/* Force Link */
1228*5779Sxy150489 		DEBUGOUT1("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
1229*5779Sxy150489 	}
1230*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg);
1231*5779Sxy150489 
1232*5779Sxy150489 	return (E1000_SUCCESS);
1233*5779Sxy150489 }
1234*5779Sxy150489 
1235*5779Sxy150489 /*
1236*5779Sxy150489  * e1000_configure_pcs_link_82575 - Configure PCS link
1237*5779Sxy150489  * @hw: pointer to the HW structure
1238*5779Sxy150489  *
1239*5779Sxy150489  * Configure the physical coding sub-layer (PCS) link.  The PCS link is
1240*5779Sxy150489  * only used on copper connections where the serialized gigabit media
1241*5779Sxy150489  * independent interface (sgmii) is being used.  Configures the link
1242*5779Sxy150489  * for auto-negotiation or forces speed/duplex.
1243*5779Sxy150489  */
1244*5779Sxy150489 static s32
1245*5779Sxy150489 e1000_configure_pcs_link_82575(struct e1000_hw *hw)
1246*5779Sxy150489 {
1247*5779Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
1248*5779Sxy150489 	u32 reg = 0;
1249*5779Sxy150489 
1250*5779Sxy150489 	DEBUGFUNC("e1000_configure_pcs_link_82575");
1251*5779Sxy150489 
1252*5779Sxy150489 	if (hw->phy.media_type != e1000_media_type_copper ||
1253*5779Sxy150489 	    !(e1000_sgmii_active_82575(hw)))
1254*5779Sxy150489 		goto out;
1255*5779Sxy150489 
1256*5779Sxy150489 	/* For SGMII, we need to issue a PCS autoneg restart */
1257*5779Sxy150489 	reg = E1000_READ_REG(hw, E1000_PCS_LCTL);
1258*5779Sxy150489 
1259*5779Sxy150489 	/* AN time out should be disabled for SGMII mode */
1260*5779Sxy150489 	reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
1261*5779Sxy150489 
1262*5779Sxy150489 	if (mac->autoneg) {
1263*5779Sxy150489 		/* Make sure forced speed and force link are not set */
1264*5779Sxy150489 		reg &= ~(E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
1265*5779Sxy150489 
1266*5779Sxy150489 		/*
1267*5779Sxy150489 		 * The PHY should be setup prior to calling this function.
1268*5779Sxy150489 		 * All we need to do is restart autoneg and enable autoneg.
1269*5779Sxy150489 		 */
1270*5779Sxy150489 		reg |= E1000_PCS_LCTL_AN_RESTART | E1000_PCS_LCTL_AN_ENABLE;
1271*5779Sxy150489 	} else {
1272*5779Sxy150489 		/* Set PCS regiseter for forced speed */
1273*5779Sxy150489 
1274*5779Sxy150489 		/* Turn off bits for full duplex, speed, and autoneg */
1275*5779Sxy150489 		reg &= ~(E1000_PCS_LCTL_FSV_1000 |
1276*5779Sxy150489 		    E1000_PCS_LCTL_FSV_100 |
1277*5779Sxy150489 		    E1000_PCS_LCTL_FDV_FULL |
1278*5779Sxy150489 		    E1000_PCS_LCTL_AN_ENABLE);
1279*5779Sxy150489 
1280*5779Sxy150489 		/* Check for duplex first */
1281*5779Sxy150489 		if (mac->forced_speed_duplex & E1000_ALL_FULL_DUPLEX)
1282*5779Sxy150489 			reg |= E1000_PCS_LCTL_FDV_FULL;
1283*5779Sxy150489 
1284*5779Sxy150489 		/* Now set speed */
1285*5779Sxy150489 		if (mac->forced_speed_duplex & E1000_ALL_100_SPEED)
1286*5779Sxy150489 			reg |= E1000_PCS_LCTL_FSV_100;
1287*5779Sxy150489 
1288*5779Sxy150489 		/* Force speed and force link */
1289*5779Sxy150489 		reg |= E1000_PCS_LCTL_FSD |
1290*5779Sxy150489 		    E1000_PCS_LCTL_FORCE_LINK |
1291*5779Sxy150489 		    E1000_PCS_LCTL_FLV_LINK_UP;
1292*5779Sxy150489 
1293*5779Sxy150489 		DEBUGOUT1("Wrote 0x%08X to PCS_LCTL to configure forced link\n",
1294*5779Sxy150489 		    reg);
1295*5779Sxy150489 	}
1296*5779Sxy150489 	E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg);
1297*5779Sxy150489 
1298*5779Sxy150489 out:
1299*5779Sxy150489 	return (E1000_SUCCESS);
1300*5779Sxy150489 }
1301*5779Sxy150489 
1302*5779Sxy150489 /*
1303*5779Sxy150489  * e1000_sgmii_active_82575 - Return sgmii state
1304*5779Sxy150489  * @hw: pointer to the HW structure
1305*5779Sxy150489  *
1306*5779Sxy150489  * 82575 silicon has a serialized gigabit media independent interface (sgmii)
1307*5779Sxy150489  * which can be enabled for use in the embedded applications.  Simply
1308*5779Sxy150489  * return the current state of the sgmii interface.
1309*5779Sxy150489  */
1310*5779Sxy150489 static bool
1311*5779Sxy150489 e1000_sgmii_active_82575(struct e1000_hw *hw)
1312*5779Sxy150489 {
1313*5779Sxy150489 	struct e1000_dev_spec_82575 *dev_spec;
1314*5779Sxy150489 	bool ret_val;
1315*5779Sxy150489 
1316*5779Sxy150489 	DEBUGFUNC("e1000_sgmii_active_82575");
1317*5779Sxy150489 
1318*5779Sxy150489 	if (hw->mac.type != e1000_82575) {
1319*5779Sxy150489 		ret_val = FALSE;
1320*5779Sxy150489 		goto out;
1321*5779Sxy150489 	}
1322*5779Sxy150489 
1323*5779Sxy150489 	dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
1324*5779Sxy150489 
1325*5779Sxy150489 	ret_val = dev_spec->sgmii_active;
1326*5779Sxy150489 
1327*5779Sxy150489 out:
1328*5779Sxy150489 	return (ret_val);
1329*5779Sxy150489 }
1330*5779Sxy150489 
1331*5779Sxy150489 /*
1332*5779Sxy150489  * e1000_reset_init_script_82575 - Inits HW defaults after reset
1333*5779Sxy150489  * @hw: pointer to the HW structure
1334*5779Sxy150489  *
1335*5779Sxy150489  * Inits recommended HW defaults after a reset when there is no EEPROM
1336*5779Sxy150489  * detected. This is only for the 82575.
1337*5779Sxy150489  */
1338*5779Sxy150489 static s32
1339*5779Sxy150489 e1000_reset_init_script_82575(struct e1000_hw *hw)
1340*5779Sxy150489 {
1341*5779Sxy150489 	DEBUGFUNC("e1000_reset_init_script_82575");
1342*5779Sxy150489 
1343*5779Sxy150489 	if (hw->mac.type == e1000_82575) {
1344*5779Sxy150489 		DEBUGOUT("Running reset init script for 82575\n");
1345*5779Sxy150489 		/* SerDes configuration via SERDESCTRL */
1346*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x00, 0x0C);
1347*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x01, 0x78);
1348*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x1B, 0x23);
1349*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x23, 0x15);
1350*5779Sxy150489 
1351*5779Sxy150489 		/* CCM configuration via CCMCTL register */
1352*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_CCMCTL, 0x14, 0x00);
1353*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_CCMCTL, 0x10, 0x00);
1354*5779Sxy150489 
1355*5779Sxy150489 		/* PCIe lanes configuration */
1356*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x00, 0xEC);
1357*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x61, 0xDF);
1358*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x34, 0x05);
1359*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x2F, 0x81);
1360*5779Sxy150489 
1361*5779Sxy150489 		/* PCIe PLL Configuration */
1362*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x02, 0x47);
1363*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x14, 0x00);
1364*5779Sxy150489 		(void) e1000_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x10, 0x00);
1365*5779Sxy150489 	}
1366*5779Sxy150489 
1367*5779Sxy150489 	return (E1000_SUCCESS);
1368*5779Sxy150489 }
1369*5779Sxy150489 
1370*5779Sxy150489 /*
1371*5779Sxy150489  * e1000_read_mac_addr_82575 - Read device MAC address
1372*5779Sxy150489  * @hw: pointer to the HW structure
1373*5779Sxy150489  */
1374*5779Sxy150489 static s32
1375*5779Sxy150489 e1000_read_mac_addr_82575(struct e1000_hw *hw)
1376*5779Sxy150489 {
1377*5779Sxy150489 	s32 ret_val = E1000_SUCCESS;
1378*5779Sxy150489 
1379*5779Sxy150489 	DEBUGFUNC("e1000_read_mac_addr_82575");
1380*5779Sxy150489 	if (e1000_check_alt_mac_addr_generic(hw))
1381*5779Sxy150489 		ret_val = e1000_read_mac_addr_generic(hw);
1382*5779Sxy150489 
1383*5779Sxy150489 	return (ret_val);
1384*5779Sxy150489 }
1385*5779Sxy150489 
1386*5779Sxy150489 /*
1387*5779Sxy150489  * e1000_power_down_phy_copper_82575 - Remove link during PHY power down
1388*5779Sxy150489  * @hw: pointer to the HW structure
1389*5779Sxy150489  *
1390*5779Sxy150489  * In the case of a PHY power down to save power, or to turn off link during a
1391*5779Sxy150489  * driver unload, or wake on lan is not enabled, remove the link.
1392*5779Sxy150489  */
1393*5779Sxy150489 static void
1394*5779Sxy150489 e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
1395*5779Sxy150489 {
1396*5779Sxy150489 	/* If the management interface is not enabled, then power down */
1397*5779Sxy150489 	if (!(e1000_check_mng_mode(hw) || e1000_check_reset_block(hw)))
1398*5779Sxy150489 		e1000_power_down_phy_copper(hw);
1399*5779Sxy150489 }
1400*5779Sxy150489 
1401*5779Sxy150489 /*
1402*5779Sxy150489  * e1000_clear_hw_cntrs_82575 - Clear device specific hardware counters
1403*5779Sxy150489  * @hw: pointer to the HW structure
1404*5779Sxy150489  *
1405*5779Sxy150489  * Clears the hardware counters by reading the counter registers.
1406*5779Sxy150489  */
1407*5779Sxy150489 static void
1408*5779Sxy150489 e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
1409*5779Sxy150489 {
1410*5779Sxy150489 	DEBUGFUNC("e1000_clear_hw_cntrs_82575");
1411*5779Sxy150489 
1412*5779Sxy150489 	e1000_clear_hw_cntrs_base_generic(hw);
1413*5779Sxy150489 
1414*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PRC64);
1415*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PRC127);
1416*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PRC255);
1417*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PRC511);
1418*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PRC1023);
1419*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PRC1522);
1420*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PTC64);
1421*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PTC127);
1422*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PTC255);
1423*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PTC511);
1424*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PTC1023);
1425*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_PTC1522);
1426*5779Sxy150489 
1427*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_ALGNERRC);
1428*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_RXERRC);
1429*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_TNCRS);
1430*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_CEXTERR);
1431*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_TSCTC);
1432*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_TSCTFC);
1433*5779Sxy150489 
1434*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_MGTPRC);
1435*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_MGTPDC);
1436*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_MGTPTC);
1437*5779Sxy150489 
1438*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_IAC);
1439*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_ICRXOC);
1440*5779Sxy150489 
1441*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_ICRXPTC);
1442*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_ICRXATC);
1443*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_ICTXPTC);
1444*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_ICTXATC);
1445*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_ICTXQEC);
1446*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_ICTXQMTC);
1447*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_ICRXDMTC);
1448*5779Sxy150489 
1449*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_CBTMPC);
1450*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_HTDPMC);
1451*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_CBRMPC);
1452*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_RPTHC);
1453*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_HGPTC);
1454*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_HTCBDPC);
1455*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_HGORCL);
1456*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_HGORCH);
1457*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_HGOTCL);
1458*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_HGOTCH);
1459*5779Sxy150489 	(void) E1000_READ_REG(hw, E1000_LENERRS);
1460*5779Sxy150489 
1461*5779Sxy150489 	/* This register should not be read in copper configurations */
1462*5779Sxy150489 	if (hw->phy.media_type == e1000_media_type_internal_serdes)
1463*5779Sxy150489 		(void) E1000_READ_REG(hw, E1000_SCVPC);
1464*5779Sxy150489 }
1465