xref: /freebsd/sys/dev/e1000/e1000_82575.c (revision a69ed8dfb381a0f0cb4130ea72c8e1507897a638)
18cfa0ad2SJack F Vogel /******************************************************************************
28cfa0ad2SJack F Vogel 
3a69ed8dfSJack F Vogel   Copyright (c) 2001-2010, Intel Corporation
48cfa0ad2SJack F Vogel   All rights reserved.
58cfa0ad2SJack F Vogel 
68cfa0ad2SJack F Vogel   Redistribution and use in source and binary forms, with or without
78cfa0ad2SJack F Vogel   modification, are permitted provided that the following conditions are met:
88cfa0ad2SJack F Vogel 
98cfa0ad2SJack F Vogel    1. Redistributions of source code must retain the above copyright notice,
108cfa0ad2SJack F Vogel       this list of conditions and the following disclaimer.
118cfa0ad2SJack F Vogel 
128cfa0ad2SJack F Vogel    2. Redistributions in binary form must reproduce the above copyright
138cfa0ad2SJack F Vogel       notice, this list of conditions and the following disclaimer in the
148cfa0ad2SJack F Vogel       documentation and/or other materials provided with the distribution.
158cfa0ad2SJack F Vogel 
168cfa0ad2SJack F Vogel    3. Neither the name of the Intel Corporation nor the names of its
178cfa0ad2SJack F Vogel       contributors may be used to endorse or promote products derived from
188cfa0ad2SJack F Vogel       this software without specific prior written permission.
198cfa0ad2SJack F Vogel 
208cfa0ad2SJack F Vogel   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
218cfa0ad2SJack F Vogel   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
228cfa0ad2SJack F Vogel   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
238cfa0ad2SJack F Vogel   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
248cfa0ad2SJack F Vogel   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
258cfa0ad2SJack F Vogel   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
268cfa0ad2SJack F Vogel   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
278cfa0ad2SJack F Vogel   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
288cfa0ad2SJack F Vogel   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
298cfa0ad2SJack F Vogel   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
308cfa0ad2SJack F Vogel   POSSIBILITY OF SUCH DAMAGE.
318cfa0ad2SJack F Vogel 
328cfa0ad2SJack F Vogel ******************************************************************************/
338cfa0ad2SJack F Vogel /*$FreeBSD$*/
348cfa0ad2SJack F Vogel 
35daf9197cSJack F Vogel /*
36daf9197cSJack F Vogel  * 82575EB Gigabit Network Connection
37daf9197cSJack F Vogel  * 82575EB Gigabit Backplane Connection
38daf9197cSJack F Vogel  * 82575GB Gigabit Network Connection
39d035aa2dSJack F Vogel  * 82575GB Gigabit Network Connection
40daf9197cSJack F Vogel  * 82576 Gigabit Network Connection
419d81738fSJack F Vogel  * 82576 Quad Port Gigabit Mezzanine Adapter
428cfa0ad2SJack F Vogel  */
438cfa0ad2SJack F Vogel 
448cfa0ad2SJack F Vogel #include "e1000_api.h"
458cfa0ad2SJack F Vogel 
468cfa0ad2SJack F Vogel static s32  e1000_init_phy_params_82575(struct e1000_hw *hw);
478cfa0ad2SJack F Vogel static s32  e1000_init_nvm_params_82575(struct e1000_hw *hw);
488cfa0ad2SJack F Vogel static s32  e1000_init_mac_params_82575(struct e1000_hw *hw);
498cfa0ad2SJack F Vogel static s32  e1000_acquire_phy_82575(struct e1000_hw *hw);
508cfa0ad2SJack F Vogel static void e1000_release_phy_82575(struct e1000_hw *hw);
518cfa0ad2SJack F Vogel static s32  e1000_acquire_nvm_82575(struct e1000_hw *hw);
528cfa0ad2SJack F Vogel static void e1000_release_nvm_82575(struct e1000_hw *hw);
538cfa0ad2SJack F Vogel static s32  e1000_check_for_link_82575(struct e1000_hw *hw);
548cfa0ad2SJack F Vogel static s32  e1000_get_cfg_done_82575(struct e1000_hw *hw);
558cfa0ad2SJack F Vogel static s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
568cfa0ad2SJack F Vogel                                          u16 *duplex);
578cfa0ad2SJack F Vogel static s32  e1000_init_hw_82575(struct e1000_hw *hw);
588cfa0ad2SJack F Vogel static s32  e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
598cfa0ad2SJack F Vogel static s32  e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
608cfa0ad2SJack F Vogel                                            u16 *data);
618cfa0ad2SJack F Vogel static s32  e1000_reset_hw_82575(struct e1000_hw *hw);
624edd8523SJack F Vogel static s32  e1000_reset_hw_82580(struct e1000_hw *hw);
634edd8523SJack F Vogel static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw,
644edd8523SJack F Vogel                                     u32 offset, u16 *data);
654edd8523SJack F Vogel static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw,
664edd8523SJack F Vogel                                      u32 offset, u16 data);
678cfa0ad2SJack F Vogel static s32  e1000_set_d0_lplu_state_82575(struct e1000_hw *hw,
688cfa0ad2SJack F Vogel                                           bool active);
698cfa0ad2SJack F Vogel static s32  e1000_setup_copper_link_82575(struct e1000_hw *hw);
704edd8523SJack F Vogel static s32  e1000_setup_serdes_link_82575(struct e1000_hw *hw);
718cfa0ad2SJack F Vogel static s32  e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data);
728cfa0ad2SJack F Vogel static s32  e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
738cfa0ad2SJack F Vogel                                             u32 offset, u16 data);
748cfa0ad2SJack F Vogel static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
758cfa0ad2SJack F Vogel static s32  e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
768cfa0ad2SJack F Vogel static s32  e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
778cfa0ad2SJack F Vogel                                                  u16 *speed, u16 *duplex);
788cfa0ad2SJack F Vogel static s32  e1000_get_phy_id_82575(struct e1000_hw *hw);
798cfa0ad2SJack F Vogel static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
808cfa0ad2SJack F Vogel static bool e1000_sgmii_active_82575(struct e1000_hw *hw);
818cfa0ad2SJack F Vogel static s32  e1000_reset_init_script_82575(struct e1000_hw *hw);
828cfa0ad2SJack F Vogel static s32  e1000_read_mac_addr_82575(struct e1000_hw *hw);
83a69ed8dfSJack F Vogel static void e1000_config_collision_dist_82575(struct e1000_hw *hw);
848cfa0ad2SJack F Vogel static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
854edd8523SJack F Vogel static void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw);
86a69ed8dfSJack F Vogel static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw);
879d81738fSJack F Vogel static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw);
888cfa0ad2SJack F Vogel 
894edd8523SJack F Vogel static const u16 e1000_82580_rxpbs_table[] =
904edd8523SJack F Vogel 	{ 36, 72, 144, 1, 2, 4, 8, 16,
914edd8523SJack F Vogel 	  35, 70, 140 };
924edd8523SJack F Vogel #define E1000_82580_RXPBS_TABLE_SIZE \
934edd8523SJack F Vogel 	(sizeof(e1000_82580_rxpbs_table)/sizeof(u16))
944edd8523SJack F Vogel 
958cfa0ad2SJack F Vogel /**
968cfa0ad2SJack F Vogel  *  e1000_init_phy_params_82575 - Init PHY func ptrs.
978cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
988cfa0ad2SJack F Vogel  **/
998cfa0ad2SJack F Vogel static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
1008cfa0ad2SJack F Vogel {
1018cfa0ad2SJack F Vogel 	struct e1000_phy_info *phy = &hw->phy;
1028cfa0ad2SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
1038cfa0ad2SJack F Vogel 
1048cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_init_phy_params_82575");
1058cfa0ad2SJack F Vogel 
1068cfa0ad2SJack F Vogel 	if (hw->phy.media_type != e1000_media_type_copper) {
1078cfa0ad2SJack F Vogel 		phy->type = e1000_phy_none;
1088cfa0ad2SJack F Vogel 		goto out;
1094edd8523SJack F Vogel 	}
1104edd8523SJack F Vogel 
1118cfa0ad2SJack F Vogel 	phy->ops.power_up   = e1000_power_up_phy_copper;
1128cfa0ad2SJack F Vogel 	phy->ops.power_down = e1000_power_down_phy_copper_82575;
1138cfa0ad2SJack F Vogel 
1148cfa0ad2SJack F Vogel 	phy->autoneg_mask           = AUTONEG_ADVERTISE_SPEED_DEFAULT;
1158cfa0ad2SJack F Vogel 	phy->reset_delay_us         = 100;
1168cfa0ad2SJack F Vogel 
1178cfa0ad2SJack F Vogel 	phy->ops.acquire            = e1000_acquire_phy_82575;
1188cfa0ad2SJack F Vogel 	phy->ops.check_reset_block  = e1000_check_reset_block_generic;
1198cfa0ad2SJack F Vogel 	phy->ops.commit             = e1000_phy_sw_reset_generic;
1208cfa0ad2SJack F Vogel 	phy->ops.get_cfg_done       = e1000_get_cfg_done_82575;
1218cfa0ad2SJack F Vogel 	phy->ops.release            = e1000_release_phy_82575;
1228cfa0ad2SJack F Vogel 
1238cfa0ad2SJack F Vogel 	if (e1000_sgmii_active_82575(hw)) {
1248cfa0ad2SJack F Vogel 		phy->ops.reset      = e1000_phy_hw_reset_sgmii_82575;
1258cfa0ad2SJack F Vogel 		phy->ops.read_reg   = e1000_read_phy_reg_sgmii_82575;
1268cfa0ad2SJack F Vogel 		phy->ops.write_reg  = e1000_write_phy_reg_sgmii_82575;
127a69ed8dfSJack F Vogel 	} else if (hw->mac.type >= e1000_82580) {
1284edd8523SJack F Vogel 		phy->ops.reset      = e1000_phy_hw_reset_generic;
1294edd8523SJack F Vogel 		phy->ops.read_reg   = e1000_read_phy_reg_82580;
1304edd8523SJack F Vogel 		phy->ops.write_reg  = e1000_write_phy_reg_82580;
1318cfa0ad2SJack F Vogel 	} else {
1328cfa0ad2SJack F Vogel 		phy->ops.reset      = e1000_phy_hw_reset_generic;
1338cfa0ad2SJack F Vogel 		phy->ops.read_reg   = e1000_read_phy_reg_igp;
1348cfa0ad2SJack F Vogel 		phy->ops.write_reg  = e1000_write_phy_reg_igp;
1358cfa0ad2SJack F Vogel 	}
1368cfa0ad2SJack F Vogel 
1378cfa0ad2SJack F Vogel 	/* Set phy->phy_addr and phy->id. */
1388cfa0ad2SJack F Vogel 	ret_val = e1000_get_phy_id_82575(hw);
1398cfa0ad2SJack F Vogel 
1408cfa0ad2SJack F Vogel 	/* Verify phy id and set remaining function pointers */
1418cfa0ad2SJack F Vogel 	switch (phy->id) {
1428cfa0ad2SJack F Vogel 	case M88E1111_I_PHY_ID:
1438cfa0ad2SJack F Vogel 		phy->type                   = e1000_phy_m88;
1448cfa0ad2SJack F Vogel 		phy->ops.check_polarity     = e1000_check_polarity_m88;
1458cfa0ad2SJack F Vogel 		phy->ops.get_info           = e1000_get_phy_info_m88;
1468cfa0ad2SJack F Vogel 		phy->ops.get_cable_length   = e1000_get_cable_length_m88;
1478cfa0ad2SJack F Vogel 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
1488cfa0ad2SJack F Vogel 		break;
1498cfa0ad2SJack F Vogel 	case IGP03E1000_E_PHY_ID:
1508cfa0ad2SJack F Vogel 	case IGP04E1000_E_PHY_ID:
1518cfa0ad2SJack F Vogel 		phy->type                   = e1000_phy_igp_3;
1528cfa0ad2SJack F Vogel 		phy->ops.check_polarity     = e1000_check_polarity_igp;
1538cfa0ad2SJack F Vogel 		phy->ops.get_info           = e1000_get_phy_info_igp;
1548cfa0ad2SJack F Vogel 		phy->ops.get_cable_length   = e1000_get_cable_length_igp_2;
1558cfa0ad2SJack F Vogel 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp;
1568cfa0ad2SJack F Vogel 		phy->ops.set_d0_lplu_state  = e1000_set_d0_lplu_state_82575;
1578cfa0ad2SJack F Vogel 		phy->ops.set_d3_lplu_state  = e1000_set_d3_lplu_state_generic;
1588cfa0ad2SJack F Vogel 		break;
1594edd8523SJack F Vogel 	case I82580_I_PHY_ID:
1604edd8523SJack F Vogel 		phy->type                   = e1000_phy_82580;
1614edd8523SJack F Vogel 		phy->ops.check_polarity     = e1000_check_polarity_82577;
1624edd8523SJack F Vogel 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_82577;
1634edd8523SJack F Vogel 		phy->ops.get_cable_length   = e1000_get_cable_length_82577;
1644edd8523SJack F Vogel 		phy->ops.get_info           = e1000_get_phy_info_82577;
1654edd8523SJack F Vogel 		break;
1668cfa0ad2SJack F Vogel 	default:
1678cfa0ad2SJack F Vogel 		ret_val = -E1000_ERR_PHY;
1688cfa0ad2SJack F Vogel 		goto out;
1698cfa0ad2SJack F Vogel 	}
1708cfa0ad2SJack F Vogel 
1718cfa0ad2SJack F Vogel out:
1728cfa0ad2SJack F Vogel 	return ret_val;
1738cfa0ad2SJack F Vogel }
1748cfa0ad2SJack F Vogel 
1758cfa0ad2SJack F Vogel /**
1768cfa0ad2SJack F Vogel  *  e1000_init_nvm_params_82575 - Init NVM func ptrs.
1778cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
1788cfa0ad2SJack F Vogel  **/
1798cfa0ad2SJack F Vogel static s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
1808cfa0ad2SJack F Vogel {
1818cfa0ad2SJack F Vogel 	struct e1000_nvm_info *nvm = &hw->nvm;
1828cfa0ad2SJack F Vogel 	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
1838cfa0ad2SJack F Vogel 	u16 size;
1848cfa0ad2SJack F Vogel 
1858cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_init_nvm_params_82575");
1868cfa0ad2SJack F Vogel 
1878cfa0ad2SJack F Vogel 	nvm->opcode_bits        = 8;
1888cfa0ad2SJack F Vogel 	nvm->delay_usec         = 1;
1898cfa0ad2SJack F Vogel 	switch (nvm->override) {
1908cfa0ad2SJack F Vogel 	case e1000_nvm_override_spi_large:
1918cfa0ad2SJack F Vogel 		nvm->page_size    = 32;
1928cfa0ad2SJack F Vogel 		nvm->address_bits = 16;
1938cfa0ad2SJack F Vogel 		break;
1948cfa0ad2SJack F Vogel 	case e1000_nvm_override_spi_small:
1958cfa0ad2SJack F Vogel 		nvm->page_size    = 8;
1968cfa0ad2SJack F Vogel 		nvm->address_bits = 8;
1978cfa0ad2SJack F Vogel 		break;
1988cfa0ad2SJack F Vogel 	default:
1998cfa0ad2SJack F Vogel 		nvm->page_size    = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
2008cfa0ad2SJack F Vogel 		nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8;
2018cfa0ad2SJack F Vogel 		break;
2028cfa0ad2SJack F Vogel 	}
2038cfa0ad2SJack F Vogel 
2048cfa0ad2SJack F Vogel 	nvm->type              = e1000_nvm_eeprom_spi;
2058cfa0ad2SJack F Vogel 
2068cfa0ad2SJack F Vogel 	size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
2078cfa0ad2SJack F Vogel 	                  E1000_EECD_SIZE_EX_SHIFT);
2088cfa0ad2SJack F Vogel 
2098cfa0ad2SJack F Vogel 	/*
2108cfa0ad2SJack F Vogel 	 * Added to a constant, "size" becomes the left-shift value
2118cfa0ad2SJack F Vogel 	 * for setting word_size.
2128cfa0ad2SJack F Vogel 	 */
2138cfa0ad2SJack F Vogel 	size += NVM_WORD_SIZE_BASE_SHIFT;
2148cfa0ad2SJack F Vogel 
2158cfa0ad2SJack F Vogel 	/* EEPROM access above 16k is unsupported */
2168cfa0ad2SJack F Vogel 	if (size > 14)
2178cfa0ad2SJack F Vogel 		size = 14;
2188cfa0ad2SJack F Vogel 	nvm->word_size = 1 << size;
2198cfa0ad2SJack F Vogel 
2208cfa0ad2SJack F Vogel 	/* Function Pointers */
2218cfa0ad2SJack F Vogel 	nvm->ops.acquire       = e1000_acquire_nvm_82575;
2228cfa0ad2SJack F Vogel 	nvm->ops.read          = e1000_read_nvm_eerd;
2238cfa0ad2SJack F Vogel 	nvm->ops.release       = e1000_release_nvm_82575;
2248cfa0ad2SJack F Vogel 	nvm->ops.update        = e1000_update_nvm_checksum_generic;
2258cfa0ad2SJack F Vogel 	nvm->ops.valid_led_default = e1000_valid_led_default_82575;
2268cfa0ad2SJack F Vogel 	nvm->ops.validate      = e1000_validate_nvm_checksum_generic;
2278cfa0ad2SJack F Vogel 	nvm->ops.write         = e1000_write_nvm_spi;
2288cfa0ad2SJack F Vogel 
2298cfa0ad2SJack F Vogel 	return E1000_SUCCESS;
2308cfa0ad2SJack F Vogel }
2318cfa0ad2SJack F Vogel 
2328cfa0ad2SJack F Vogel /**
2338cfa0ad2SJack F Vogel  *  e1000_init_mac_params_82575 - Init MAC func ptrs.
2348cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
2358cfa0ad2SJack F Vogel  **/
2368cfa0ad2SJack F Vogel static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
2378cfa0ad2SJack F Vogel {
2388cfa0ad2SJack F Vogel 	struct e1000_mac_info *mac = &hw->mac;
239daf9197cSJack F Vogel 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
2408cfa0ad2SJack F Vogel 	u32 ctrl_ext = 0;
2418cfa0ad2SJack F Vogel 
2428cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_init_mac_params_82575");
2438cfa0ad2SJack F Vogel 
2448cfa0ad2SJack F Vogel 	/* Set media type */
2458cfa0ad2SJack F Vogel         /*
2468cfa0ad2SJack F Vogel 	 * The 82575 uses bits 22:23 for link mode. The mode can be changed
2478cfa0ad2SJack F Vogel          * based on the EEPROM. We cannot rely upon device ID. There
2488cfa0ad2SJack F Vogel          * is no distinguishable difference between fiber and internal
2498cfa0ad2SJack F Vogel          * SerDes mode on the 82575. There can be an external PHY attached
2508cfa0ad2SJack F Vogel          * on the SGMII interface. For this, we'll set sgmii_active to TRUE.
2518cfa0ad2SJack F Vogel          */
2528cfa0ad2SJack F Vogel 	hw->phy.media_type = e1000_media_type_copper;
2538cfa0ad2SJack F Vogel 	dev_spec->sgmii_active = FALSE;
2548cfa0ad2SJack F Vogel 
2558cfa0ad2SJack F Vogel 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
2564edd8523SJack F Vogel 	switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
2574edd8523SJack F Vogel 	case E1000_CTRL_EXT_LINK_MODE_SGMII:
2588cfa0ad2SJack F Vogel 		dev_spec->sgmii_active = TRUE;
2598cfa0ad2SJack F Vogel 		ctrl_ext |= E1000_CTRL_I2C_ENA;
2604edd8523SJack F Vogel 		break;
2614edd8523SJack F Vogel 	case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
2624edd8523SJack F Vogel 	case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
2634edd8523SJack F Vogel 		hw->phy.media_type = e1000_media_type_internal_serdes;
2644edd8523SJack F Vogel 		ctrl_ext |= E1000_CTRL_I2C_ENA;
2654edd8523SJack F Vogel 		break;
2664edd8523SJack F Vogel 	default:
2678cfa0ad2SJack F Vogel 		ctrl_ext &= ~E1000_CTRL_I2C_ENA;
2684edd8523SJack F Vogel 		break;
2698cfa0ad2SJack F Vogel 	}
2704edd8523SJack F Vogel 
2718cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
2728cfa0ad2SJack F Vogel 
2734edd8523SJack F Vogel 	/*
2744edd8523SJack F Vogel 	 * if using i2c make certain the MDICNFG register is cleared to prevent
2754edd8523SJack F Vogel 	 * communications from being misrouted to the mdic registers
2764edd8523SJack F Vogel 	 */
277a69ed8dfSJack F Vogel 	if ((ctrl_ext & E1000_CTRL_I2C_ENA) && (hw->mac.type == e1000_82580))
2784edd8523SJack F Vogel 		E1000_WRITE_REG(hw, E1000_MDICNFG, 0);
2794edd8523SJack F Vogel 
2808cfa0ad2SJack F Vogel 	/* Set mta register count */
2818cfa0ad2SJack F Vogel 	mac->mta_reg_count = 128;
2824edd8523SJack F Vogel 	/* Set uta register count */
2834edd8523SJack F Vogel 	mac->uta_reg_count = (hw->mac.type == e1000_82575) ? 0 : 128;
2848cfa0ad2SJack F Vogel 	/* Set rar entry count */
2858cfa0ad2SJack F Vogel 	mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
2868cfa0ad2SJack F Vogel 	if (mac->type == e1000_82576)
2878cfa0ad2SJack F Vogel 		mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
288a69ed8dfSJack F Vogel 	if (mac->type == e1000_82580)
2894edd8523SJack F Vogel 		mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
2908cfa0ad2SJack F Vogel 	/* Set if part includes ASF firmware */
2918cfa0ad2SJack F Vogel 	mac->asf_firmware_present = TRUE;
2928cfa0ad2SJack F Vogel 	/* Set if manageability features are enabled. */
2938cfa0ad2SJack F Vogel 	mac->arc_subsystem_valid =
2948cfa0ad2SJack F Vogel 	        (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
2958cfa0ad2SJack F Vogel 	                ? TRUE : FALSE;
2968cfa0ad2SJack F Vogel 
2978cfa0ad2SJack F Vogel 	/* Function pointers */
2988cfa0ad2SJack F Vogel 
2998cfa0ad2SJack F Vogel 	/* bus type/speed/width */
3008cfa0ad2SJack F Vogel 	mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic;
3018cfa0ad2SJack F Vogel 	/* reset */
302a69ed8dfSJack F Vogel 	if (mac->type >= e1000_82580)
3034edd8523SJack F Vogel 		mac->ops.reset_hw = e1000_reset_hw_82580;
3044edd8523SJack F Vogel 	else
3058cfa0ad2SJack F Vogel 	mac->ops.reset_hw = e1000_reset_hw_82575;
3068cfa0ad2SJack F Vogel 	/* hw initialization */
3078cfa0ad2SJack F Vogel 	mac->ops.init_hw = e1000_init_hw_82575;
3088cfa0ad2SJack F Vogel 	/* link setup */
3098cfa0ad2SJack F Vogel 	mac->ops.setup_link = e1000_setup_link_generic;
3108cfa0ad2SJack F Vogel 	/* physical interface link setup */
3118cfa0ad2SJack F Vogel 	mac->ops.setup_physical_interface =
3128cfa0ad2SJack F Vogel 	        (hw->phy.media_type == e1000_media_type_copper)
3138cfa0ad2SJack F Vogel 	                ? e1000_setup_copper_link_82575
3144edd8523SJack F Vogel 	                : e1000_setup_serdes_link_82575;
3158cfa0ad2SJack F Vogel 	/* physical interface shutdown */
3164edd8523SJack F Vogel 	mac->ops.shutdown_serdes = e1000_shutdown_serdes_link_82575;
317a69ed8dfSJack F Vogel 	/* physical interface power up */
318a69ed8dfSJack F Vogel 	mac->ops.power_up_serdes = e1000_power_up_serdes_link_82575;
3198cfa0ad2SJack F Vogel 	/* check for link */
3208cfa0ad2SJack F Vogel 	mac->ops.check_for_link = e1000_check_for_link_82575;
3218cfa0ad2SJack F Vogel 	/* receive address register setting */
3228cfa0ad2SJack F Vogel 	mac->ops.rar_set = e1000_rar_set_generic;
3238cfa0ad2SJack F Vogel 	/* read mac address */
3248cfa0ad2SJack F Vogel 	mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
325a69ed8dfSJack F Vogel 	/* configure collision distance */
326a69ed8dfSJack F Vogel 	mac->ops.config_collision_dist = e1000_config_collision_dist_82575;
3278cfa0ad2SJack F Vogel 	/* multicast address update */
328d035aa2dSJack F Vogel 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
3298cfa0ad2SJack F Vogel 	/* writing VFTA */
3308cfa0ad2SJack F Vogel 	mac->ops.write_vfta = e1000_write_vfta_generic;
3318cfa0ad2SJack F Vogel 	/* clearing VFTA */
3328cfa0ad2SJack F Vogel 	mac->ops.clear_vfta = e1000_clear_vfta_generic;
333d035aa2dSJack F Vogel 	/* ID LED init */
334d035aa2dSJack F Vogel 	mac->ops.id_led_init = e1000_id_led_init_generic;
3358cfa0ad2SJack F Vogel 	/* blink LED */
3368cfa0ad2SJack F Vogel 	mac->ops.blink_led = e1000_blink_led_generic;
3378cfa0ad2SJack F Vogel 	/* setup LED */
3388cfa0ad2SJack F Vogel 	mac->ops.setup_led = e1000_setup_led_generic;
3398cfa0ad2SJack F Vogel 	/* cleanup LED */
3408cfa0ad2SJack F Vogel 	mac->ops.cleanup_led = e1000_cleanup_led_generic;
3418cfa0ad2SJack F Vogel 	/* turn on/off LED */
3428cfa0ad2SJack F Vogel 	mac->ops.led_on = e1000_led_on_generic;
3438cfa0ad2SJack F Vogel 	mac->ops.led_off = e1000_led_off_generic;
3448cfa0ad2SJack F Vogel 	/* clear hardware counters */
3458cfa0ad2SJack F Vogel 	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
3468cfa0ad2SJack F Vogel 	/* link info */
3478cfa0ad2SJack F Vogel 	mac->ops.get_link_up_info = e1000_get_link_up_info_82575;
3488cfa0ad2SJack F Vogel 
3494edd8523SJack F Vogel 	/* set lan id for port to determine which phy lock to use */
3504edd8523SJack F Vogel 	hw->mac.ops.set_lan_id(hw);
3514edd8523SJack F Vogel 
352daf9197cSJack F Vogel 	return E1000_SUCCESS;
3538cfa0ad2SJack F Vogel }
3548cfa0ad2SJack F Vogel 
3558cfa0ad2SJack F Vogel /**
3568cfa0ad2SJack F Vogel  *  e1000_init_function_pointers_82575 - Init func ptrs.
3578cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
3588cfa0ad2SJack F Vogel  *
359daf9197cSJack F Vogel  *  Called to initialize all function pointers and parameters.
3608cfa0ad2SJack F Vogel  **/
3618cfa0ad2SJack F Vogel void e1000_init_function_pointers_82575(struct e1000_hw *hw)
3628cfa0ad2SJack F Vogel {
3638cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_init_function_pointers_82575");
3648cfa0ad2SJack F Vogel 
3658cfa0ad2SJack F Vogel 	hw->mac.ops.init_params = e1000_init_mac_params_82575;
3668cfa0ad2SJack F Vogel 	hw->nvm.ops.init_params = e1000_init_nvm_params_82575;
3678cfa0ad2SJack F Vogel 	hw->phy.ops.init_params = e1000_init_phy_params_82575;
3688cfa0ad2SJack F Vogel }
3698cfa0ad2SJack F Vogel 
3708cfa0ad2SJack F Vogel /**
3718cfa0ad2SJack F Vogel  *  e1000_acquire_phy_82575 - Acquire rights to access PHY
3728cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
3738cfa0ad2SJack F Vogel  *
374daf9197cSJack F Vogel  *  Acquire access rights to the correct PHY.
3758cfa0ad2SJack F Vogel  **/
3768cfa0ad2SJack F Vogel static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
3778cfa0ad2SJack F Vogel {
3789d81738fSJack F Vogel 	u16 mask = E1000_SWFW_PHY0_SM;
3798cfa0ad2SJack F Vogel 
3808cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_acquire_phy_82575");
3818cfa0ad2SJack F Vogel 
3829d81738fSJack F Vogel 	if (hw->bus.func == E1000_FUNC_1)
3839d81738fSJack F Vogel 		mask = E1000_SWFW_PHY1_SM;
3844edd8523SJack F Vogel 	else if (hw->bus.func == E1000_FUNC_2)
3854edd8523SJack F Vogel 		mask = E1000_SWFW_PHY2_SM;
3864edd8523SJack F Vogel 	else if (hw->bus.func == E1000_FUNC_3)
3874edd8523SJack F Vogel 		mask = E1000_SWFW_PHY3_SM;
3888cfa0ad2SJack F Vogel 
3898cfa0ad2SJack F Vogel 	return e1000_acquire_swfw_sync_82575(hw, mask);
3908cfa0ad2SJack F Vogel }
3918cfa0ad2SJack F Vogel 
3928cfa0ad2SJack F Vogel /**
3938cfa0ad2SJack F Vogel  *  e1000_release_phy_82575 - Release rights to access PHY
3948cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
3958cfa0ad2SJack F Vogel  *
396daf9197cSJack F Vogel  *  A wrapper to release access rights to the correct PHY.
3978cfa0ad2SJack F Vogel  **/
3988cfa0ad2SJack F Vogel static void e1000_release_phy_82575(struct e1000_hw *hw)
3998cfa0ad2SJack F Vogel {
4009d81738fSJack F Vogel 	u16 mask = E1000_SWFW_PHY0_SM;
4018cfa0ad2SJack F Vogel 
4028cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_release_phy_82575");
4038cfa0ad2SJack F Vogel 
4049d81738fSJack F Vogel 	if (hw->bus.func == E1000_FUNC_1)
4059d81738fSJack F Vogel 		mask = E1000_SWFW_PHY1_SM;
4064edd8523SJack F Vogel 	else if (hw->bus.func == E1000_FUNC_2)
4074edd8523SJack F Vogel 		mask = E1000_SWFW_PHY2_SM;
4084edd8523SJack F Vogel 	else if (hw->bus.func == E1000_FUNC_3)
4094edd8523SJack F Vogel 		mask = E1000_SWFW_PHY3_SM;
4109d81738fSJack F Vogel 
4118cfa0ad2SJack F Vogel 	e1000_release_swfw_sync_82575(hw, mask);
4128cfa0ad2SJack F Vogel }
4138cfa0ad2SJack F Vogel 
4148cfa0ad2SJack F Vogel /**
4158cfa0ad2SJack F Vogel  *  e1000_read_phy_reg_sgmii_82575 - Read PHY register using sgmii
4168cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
4178cfa0ad2SJack F Vogel  *  @offset: register offset to be read
4188cfa0ad2SJack F Vogel  *  @data: pointer to the read data
4198cfa0ad2SJack F Vogel  *
4208cfa0ad2SJack F Vogel  *  Reads the PHY register at offset using the serial gigabit media independent
4218cfa0ad2SJack F Vogel  *  interface and stores the retrieved information in data.
4228cfa0ad2SJack F Vogel  **/
4238cfa0ad2SJack F Vogel static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
4248cfa0ad2SJack F Vogel                                           u16 *data)
4258cfa0ad2SJack F Vogel {
4264edd8523SJack F Vogel 	s32 ret_val = -E1000_ERR_PARAM;
4278cfa0ad2SJack F Vogel 
4288cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_read_phy_reg_sgmii_82575");
4298cfa0ad2SJack F Vogel 
4308cfa0ad2SJack F Vogel 	if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
4318cfa0ad2SJack F Vogel 		DEBUGOUT1("PHY Address %u is out of range\n", offset);
4324edd8523SJack F Vogel 		goto out;
4338cfa0ad2SJack F Vogel 	}
4348cfa0ad2SJack F Vogel 
4354edd8523SJack F Vogel 	ret_val = hw->phy.ops.acquire(hw);
4364edd8523SJack F Vogel 	if (ret_val)
4374edd8523SJack F Vogel 		goto out;
4388cfa0ad2SJack F Vogel 
4394edd8523SJack F Vogel 	ret_val = e1000_read_phy_reg_i2c(hw, offset, data);
4408cfa0ad2SJack F Vogel 
4414edd8523SJack F Vogel 	hw->phy.ops.release(hw);
4428cfa0ad2SJack F Vogel 
4434edd8523SJack F Vogel out:
4444edd8523SJack F Vogel 	return ret_val;
4458cfa0ad2SJack F Vogel }
4468cfa0ad2SJack F Vogel 
4478cfa0ad2SJack F Vogel /**
4488cfa0ad2SJack F Vogel  *  e1000_write_phy_reg_sgmii_82575 - Write PHY register using sgmii
4498cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
4508cfa0ad2SJack F Vogel  *  @offset: register offset to write to
4518cfa0ad2SJack F Vogel  *  @data: data to write at register offset
4528cfa0ad2SJack F Vogel  *
4538cfa0ad2SJack F Vogel  *  Writes the data to PHY register at the offset using the serial gigabit
4548cfa0ad2SJack F Vogel  *  media independent interface.
4558cfa0ad2SJack F Vogel  **/
4568cfa0ad2SJack F Vogel static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
4578cfa0ad2SJack F Vogel                                            u16 data)
4588cfa0ad2SJack F Vogel {
4594edd8523SJack F Vogel 	s32 ret_val = -E1000_ERR_PARAM;
4608cfa0ad2SJack F Vogel 
4618cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_write_phy_reg_sgmii_82575");
4628cfa0ad2SJack F Vogel 
4638cfa0ad2SJack F Vogel 	if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
4648cfa0ad2SJack F Vogel 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
4654edd8523SJack F Vogel 		goto out;
4668cfa0ad2SJack F Vogel 	}
4678cfa0ad2SJack F Vogel 
4684edd8523SJack F Vogel 	ret_val = hw->phy.ops.acquire(hw);
4694edd8523SJack F Vogel 	if (ret_val)
4704edd8523SJack F Vogel 		goto out;
4718cfa0ad2SJack F Vogel 
4724edd8523SJack F Vogel 	ret_val = e1000_write_phy_reg_i2c(hw, offset, data);
4738cfa0ad2SJack F Vogel 
4744edd8523SJack F Vogel 	hw->phy.ops.release(hw);
4758cfa0ad2SJack F Vogel 
4764edd8523SJack F Vogel out:
4774edd8523SJack F Vogel 	return ret_val;
4788cfa0ad2SJack F Vogel }
4798cfa0ad2SJack F Vogel 
4808cfa0ad2SJack F Vogel /**
4818cfa0ad2SJack F Vogel  *  e1000_get_phy_id_82575 - Retrieve PHY addr and id
4828cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
4838cfa0ad2SJack F Vogel  *
4848cfa0ad2SJack F Vogel  *  Retrieves the PHY address and ID for both PHY's which do and do not use
4858cfa0ad2SJack F Vogel  *  sgmi interface.
4868cfa0ad2SJack F Vogel  **/
4878cfa0ad2SJack F Vogel static s32 e1000_get_phy_id_82575(struct e1000_hw *hw)
4888cfa0ad2SJack F Vogel {
4898cfa0ad2SJack F Vogel 	struct e1000_phy_info *phy = &hw->phy;
4908cfa0ad2SJack F Vogel 	s32  ret_val = E1000_SUCCESS;
4918cfa0ad2SJack F Vogel 	u16 phy_id;
4924edd8523SJack F Vogel 	u32 ctrl_ext;
4938cfa0ad2SJack F Vogel 
4948cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_get_phy_id_82575");
4958cfa0ad2SJack F Vogel 
4968cfa0ad2SJack F Vogel 	/*
4978cfa0ad2SJack F Vogel 	 * For SGMII PHYs, we try the list of possible addresses until
4988cfa0ad2SJack F Vogel 	 * we find one that works.  For non-SGMII PHYs
4998cfa0ad2SJack F Vogel 	 * (e.g. integrated copper PHYs), an address of 1 should
5008cfa0ad2SJack F Vogel 	 * work.  The result of this function should mean phy->phy_addr
5018cfa0ad2SJack F Vogel 	 * and phy->id are set correctly.
5028cfa0ad2SJack F Vogel 	 */
5034edd8523SJack F Vogel 	if (!e1000_sgmii_active_82575(hw)) {
5048cfa0ad2SJack F Vogel 		phy->addr = 1;
5058cfa0ad2SJack F Vogel 		ret_val = e1000_get_phy_id(hw);
5068cfa0ad2SJack F Vogel 		goto out;
5078cfa0ad2SJack F Vogel 	}
5088cfa0ad2SJack F Vogel 
5094edd8523SJack F Vogel 	/* Power on sgmii phy if it is disabled */
5104edd8523SJack F Vogel 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
5114edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL_EXT,
5124edd8523SJack F Vogel 	                ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA);
5134edd8523SJack F Vogel 	E1000_WRITE_FLUSH(hw);
5144edd8523SJack F Vogel 	msec_delay(300);
5154edd8523SJack F Vogel 
5168cfa0ad2SJack F Vogel 	/*
5178cfa0ad2SJack F Vogel 	 * The address field in the I2CCMD register is 3 bits and 0 is invalid.
5188cfa0ad2SJack F Vogel 	 * Therefore, we need to test 1-7
5198cfa0ad2SJack F Vogel 	 */
5208cfa0ad2SJack F Vogel 	for (phy->addr = 1; phy->addr < 8; phy->addr++) {
5218cfa0ad2SJack F Vogel 		ret_val = e1000_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id);
5228cfa0ad2SJack F Vogel 		if (ret_val == E1000_SUCCESS) {
5238cfa0ad2SJack F Vogel 			DEBUGOUT2("Vendor ID 0x%08X read at address %u\n",
5248cfa0ad2SJack F Vogel 			          phy_id,
5258cfa0ad2SJack F Vogel 			          phy->addr);
5268cfa0ad2SJack F Vogel 			/*
5278cfa0ad2SJack F Vogel 			 * At the time of this writing, The M88 part is
5288cfa0ad2SJack F Vogel 			 * the only supported SGMII PHY product.
5298cfa0ad2SJack F Vogel 			 */
5308cfa0ad2SJack F Vogel 			if (phy_id == M88_VENDOR)
5318cfa0ad2SJack F Vogel 				break;
5328cfa0ad2SJack F Vogel 		} else {
5338cfa0ad2SJack F Vogel 			DEBUGOUT1("PHY address %u was unreadable\n",
5348cfa0ad2SJack F Vogel 			          phy->addr);
5358cfa0ad2SJack F Vogel 		}
5368cfa0ad2SJack F Vogel 	}
5378cfa0ad2SJack F Vogel 
5388cfa0ad2SJack F Vogel 	/* A valid PHY type couldn't be found. */
5398cfa0ad2SJack F Vogel 	if (phy->addr == 8) {
5408cfa0ad2SJack F Vogel 		phy->addr = 0;
5418cfa0ad2SJack F Vogel 		ret_val = -E1000_ERR_PHY;
5424edd8523SJack F Vogel 	} else {
5434edd8523SJack F Vogel 		ret_val = e1000_get_phy_id(hw);
5448cfa0ad2SJack F Vogel 	}
5458cfa0ad2SJack F Vogel 
5464edd8523SJack F Vogel 	/* restore previous sfp cage power state */
5474edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
5488cfa0ad2SJack F Vogel 
5498cfa0ad2SJack F Vogel out:
5508cfa0ad2SJack F Vogel 	return ret_val;
5518cfa0ad2SJack F Vogel }
5528cfa0ad2SJack F Vogel 
5538cfa0ad2SJack F Vogel /**
5548cfa0ad2SJack F Vogel  *  e1000_phy_hw_reset_sgmii_82575 - Performs a PHY reset
5558cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
5568cfa0ad2SJack F Vogel  *
5578cfa0ad2SJack F Vogel  *  Resets the PHY using the serial gigabit media independent interface.
5588cfa0ad2SJack F Vogel  **/
5598cfa0ad2SJack F Vogel static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
5608cfa0ad2SJack F Vogel {
5618cfa0ad2SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
5628cfa0ad2SJack F Vogel 
5638cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
5648cfa0ad2SJack F Vogel 
5658cfa0ad2SJack F Vogel 	/*
5668cfa0ad2SJack F Vogel 	 * This isn't a TRUE "hard" reset, but is the only reset
5678cfa0ad2SJack F Vogel 	 * available to us at this time.
5688cfa0ad2SJack F Vogel 	 */
5698cfa0ad2SJack F Vogel 
5708cfa0ad2SJack F Vogel 	DEBUGOUT("Soft resetting SGMII attached PHY...\n");
5718cfa0ad2SJack F Vogel 
5728cfa0ad2SJack F Vogel 	if (!(hw->phy.ops.write_reg))
5738cfa0ad2SJack F Vogel 		goto out;
5748cfa0ad2SJack F Vogel 
5758cfa0ad2SJack F Vogel 	/*
5768cfa0ad2SJack F Vogel 	 * SFP documentation requires the following to configure the SPF module
5778cfa0ad2SJack F Vogel 	 * to work on SGMII.  No further documentation is given.
5788cfa0ad2SJack F Vogel 	 */
5798cfa0ad2SJack F Vogel 	ret_val = hw->phy.ops.write_reg(hw, 0x1B, 0x8084);
5808cfa0ad2SJack F Vogel 	if (ret_val)
5818cfa0ad2SJack F Vogel 		goto out;
5828cfa0ad2SJack F Vogel 
5838cfa0ad2SJack F Vogel 	ret_val = hw->phy.ops.commit(hw);
5848cfa0ad2SJack F Vogel 
5858cfa0ad2SJack F Vogel out:
5868cfa0ad2SJack F Vogel 	return ret_val;
5878cfa0ad2SJack F Vogel }
5888cfa0ad2SJack F Vogel 
5898cfa0ad2SJack F Vogel /**
5908cfa0ad2SJack F Vogel  *  e1000_set_d0_lplu_state_82575 - Set Low Power Linkup D0 state
5918cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
5928cfa0ad2SJack F Vogel  *  @active: TRUE to enable LPLU, FALSE to disable
5938cfa0ad2SJack F Vogel  *
5948cfa0ad2SJack F Vogel  *  Sets the LPLU D0 state according to the active flag.  When
5958cfa0ad2SJack F Vogel  *  activating LPLU this function also disables smart speed
5968cfa0ad2SJack F Vogel  *  and vice versa.  LPLU will not be activated unless the
5978cfa0ad2SJack F Vogel  *  device autonegotiation advertisement meets standards of
5988cfa0ad2SJack F Vogel  *  either 10 or 10/100 or 10/100/1000 at all duplexes.
5998cfa0ad2SJack F Vogel  *  This is a function pointer entry point only called by
6008cfa0ad2SJack F Vogel  *  PHY setup routines.
6018cfa0ad2SJack F Vogel  **/
6028cfa0ad2SJack F Vogel static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
6038cfa0ad2SJack F Vogel {
6048cfa0ad2SJack F Vogel 	struct e1000_phy_info *phy = &hw->phy;
6058cfa0ad2SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
6068cfa0ad2SJack F Vogel 	u16 data;
6078cfa0ad2SJack F Vogel 
6088cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_set_d0_lplu_state_82575");
6098cfa0ad2SJack F Vogel 
6108cfa0ad2SJack F Vogel 	if (!(hw->phy.ops.read_reg))
6118cfa0ad2SJack F Vogel 		goto out;
6128cfa0ad2SJack F Vogel 
6138cfa0ad2SJack F Vogel 	ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
6148cfa0ad2SJack F Vogel 	if (ret_val)
6158cfa0ad2SJack F Vogel 		goto out;
6168cfa0ad2SJack F Vogel 
6178cfa0ad2SJack F Vogel 	if (active) {
6188cfa0ad2SJack F Vogel 		data |= IGP02E1000_PM_D0_LPLU;
6198cfa0ad2SJack F Vogel 		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
6208cfa0ad2SJack F Vogel 		                             data);
6218cfa0ad2SJack F Vogel 		if (ret_val)
6228cfa0ad2SJack F Vogel 			goto out;
6238cfa0ad2SJack F Vogel 
6248cfa0ad2SJack F Vogel 		/* When LPLU is enabled, we should disable SmartSpeed */
6258cfa0ad2SJack F Vogel 		ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
6268cfa0ad2SJack F Vogel 		                            &data);
6278cfa0ad2SJack F Vogel 		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
6288cfa0ad2SJack F Vogel 		ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
6298cfa0ad2SJack F Vogel 		                             data);
6308cfa0ad2SJack F Vogel 		if (ret_val)
6318cfa0ad2SJack F Vogel 			goto out;
6328cfa0ad2SJack F Vogel 	} else {
6338cfa0ad2SJack F Vogel 		data &= ~IGP02E1000_PM_D0_LPLU;
6348cfa0ad2SJack F Vogel 		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
6358cfa0ad2SJack F Vogel 		                             data);
6368cfa0ad2SJack F Vogel 		/*
6378cfa0ad2SJack F Vogel 		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
6388cfa0ad2SJack F Vogel 		 * during Dx states where the power conservation is most
6398cfa0ad2SJack F Vogel 		 * important.  During driver activity we should enable
6408cfa0ad2SJack F Vogel 		 * SmartSpeed, so performance is maintained.
6418cfa0ad2SJack F Vogel 		 */
6428cfa0ad2SJack F Vogel 		if (phy->smart_speed == e1000_smart_speed_on) {
6438cfa0ad2SJack F Vogel 			ret_val = phy->ops.read_reg(hw,
6448cfa0ad2SJack F Vogel 			                            IGP01E1000_PHY_PORT_CONFIG,
6458cfa0ad2SJack F Vogel 			                            &data);
6468cfa0ad2SJack F Vogel 			if (ret_val)
6478cfa0ad2SJack F Vogel 				goto out;
6488cfa0ad2SJack F Vogel 
6498cfa0ad2SJack F Vogel 			data |= IGP01E1000_PSCFR_SMART_SPEED;
6508cfa0ad2SJack F Vogel 			ret_val = phy->ops.write_reg(hw,
6518cfa0ad2SJack F Vogel 			                             IGP01E1000_PHY_PORT_CONFIG,
6528cfa0ad2SJack F Vogel 			                             data);
6538cfa0ad2SJack F Vogel 			if (ret_val)
6548cfa0ad2SJack F Vogel 				goto out;
6558cfa0ad2SJack F Vogel 		} else if (phy->smart_speed == e1000_smart_speed_off) {
6568cfa0ad2SJack F Vogel 			ret_val = phy->ops.read_reg(hw,
6578cfa0ad2SJack F Vogel 			                            IGP01E1000_PHY_PORT_CONFIG,
6588cfa0ad2SJack F Vogel 			                            &data);
6598cfa0ad2SJack F Vogel 			if (ret_val)
6608cfa0ad2SJack F Vogel 				goto out;
6618cfa0ad2SJack F Vogel 
6628cfa0ad2SJack F Vogel 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
6638cfa0ad2SJack F Vogel 			ret_val = phy->ops.write_reg(hw,
6648cfa0ad2SJack F Vogel 			                             IGP01E1000_PHY_PORT_CONFIG,
6658cfa0ad2SJack F Vogel 			                             data);
6668cfa0ad2SJack F Vogel 			if (ret_val)
6678cfa0ad2SJack F Vogel 				goto out;
6688cfa0ad2SJack F Vogel 		}
6698cfa0ad2SJack F Vogel 	}
6708cfa0ad2SJack F Vogel 
6718cfa0ad2SJack F Vogel out:
6728cfa0ad2SJack F Vogel 	return ret_val;
6738cfa0ad2SJack F Vogel }
6748cfa0ad2SJack F Vogel 
6758cfa0ad2SJack F Vogel /**
6768cfa0ad2SJack F Vogel  *  e1000_acquire_nvm_82575 - Request for access to EEPROM
6778cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
6788cfa0ad2SJack F Vogel  *
6798cfa0ad2SJack F Vogel  *  Acquire the necessary semaphores for exclusive access to the EEPROM.
6808cfa0ad2SJack F Vogel  *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
6818cfa0ad2SJack F Vogel  *  Return successful if access grant bit set, else clear the request for
6828cfa0ad2SJack F Vogel  *  EEPROM access and return -E1000_ERR_NVM (-1).
6838cfa0ad2SJack F Vogel  **/
6848cfa0ad2SJack F Vogel static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
6858cfa0ad2SJack F Vogel {
6868cfa0ad2SJack F Vogel 	s32 ret_val;
6878cfa0ad2SJack F Vogel 
6888cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_acquire_nvm_82575");
6898cfa0ad2SJack F Vogel 
6908cfa0ad2SJack F Vogel 	ret_val = e1000_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
6918cfa0ad2SJack F Vogel 	if (ret_val)
6928cfa0ad2SJack F Vogel 		goto out;
6938cfa0ad2SJack F Vogel 
6948cfa0ad2SJack F Vogel 	ret_val = e1000_acquire_nvm_generic(hw);
6958cfa0ad2SJack F Vogel 
6968cfa0ad2SJack F Vogel 	if (ret_val)
6978cfa0ad2SJack F Vogel 		e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
6988cfa0ad2SJack F Vogel 
6998cfa0ad2SJack F Vogel out:
7008cfa0ad2SJack F Vogel 	return ret_val;
7018cfa0ad2SJack F Vogel }
7028cfa0ad2SJack F Vogel 
7038cfa0ad2SJack F Vogel /**
7048cfa0ad2SJack F Vogel  *  e1000_release_nvm_82575 - Release exclusive access to EEPROM
7058cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
7068cfa0ad2SJack F Vogel  *
7078cfa0ad2SJack F Vogel  *  Stop any current commands to the EEPROM and clear the EEPROM request bit,
7088cfa0ad2SJack F Vogel  *  then release the semaphores acquired.
7098cfa0ad2SJack F Vogel  **/
7108cfa0ad2SJack F Vogel static void e1000_release_nvm_82575(struct e1000_hw *hw)
7118cfa0ad2SJack F Vogel {
7128cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_release_nvm_82575");
7138cfa0ad2SJack F Vogel 
7148cfa0ad2SJack F Vogel 	e1000_release_nvm_generic(hw);
7158cfa0ad2SJack F Vogel 	e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
7168cfa0ad2SJack F Vogel }
7178cfa0ad2SJack F Vogel 
7188cfa0ad2SJack F Vogel /**
7198cfa0ad2SJack F Vogel  *  e1000_acquire_swfw_sync_82575 - Acquire SW/FW semaphore
7208cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
7218cfa0ad2SJack F Vogel  *  @mask: specifies which semaphore to acquire
7228cfa0ad2SJack F Vogel  *
7238cfa0ad2SJack F Vogel  *  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
7248cfa0ad2SJack F Vogel  *  will also specify which port we're acquiring the lock for.
7258cfa0ad2SJack F Vogel  **/
7268cfa0ad2SJack F Vogel static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
7278cfa0ad2SJack F Vogel {
7288cfa0ad2SJack F Vogel 	u32 swfw_sync;
7298cfa0ad2SJack F Vogel 	u32 swmask = mask;
7308cfa0ad2SJack F Vogel 	u32 fwmask = mask << 16;
7318cfa0ad2SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
7328cfa0ad2SJack F Vogel 	s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
7338cfa0ad2SJack F Vogel 
7348cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_acquire_swfw_sync_82575");
7358cfa0ad2SJack F Vogel 
7368cfa0ad2SJack F Vogel 	while (i < timeout) {
7378cfa0ad2SJack F Vogel 		if (e1000_get_hw_semaphore_generic(hw)) {
7388cfa0ad2SJack F Vogel 			ret_val = -E1000_ERR_SWFW_SYNC;
7398cfa0ad2SJack F Vogel 			goto out;
7408cfa0ad2SJack F Vogel 		}
7418cfa0ad2SJack F Vogel 
7428cfa0ad2SJack F Vogel 		swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
7438cfa0ad2SJack F Vogel 		if (!(swfw_sync & (fwmask | swmask)))
7448cfa0ad2SJack F Vogel 			break;
7458cfa0ad2SJack F Vogel 
7468cfa0ad2SJack F Vogel 		/*
7478cfa0ad2SJack F Vogel 		 * Firmware currently using resource (fwmask)
7488cfa0ad2SJack F Vogel 		 * or other software thread using resource (swmask)
7498cfa0ad2SJack F Vogel 		 */
7508cfa0ad2SJack F Vogel 		e1000_put_hw_semaphore_generic(hw);
7518cfa0ad2SJack F Vogel 		msec_delay_irq(5);
7528cfa0ad2SJack F Vogel 		i++;
7538cfa0ad2SJack F Vogel 	}
7548cfa0ad2SJack F Vogel 
7558cfa0ad2SJack F Vogel 	if (i == timeout) {
7568cfa0ad2SJack F Vogel 		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
7578cfa0ad2SJack F Vogel 		ret_val = -E1000_ERR_SWFW_SYNC;
7588cfa0ad2SJack F Vogel 		goto out;
7598cfa0ad2SJack F Vogel 	}
7608cfa0ad2SJack F Vogel 
7618cfa0ad2SJack F Vogel 	swfw_sync |= swmask;
7628cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
7638cfa0ad2SJack F Vogel 
7648cfa0ad2SJack F Vogel 	e1000_put_hw_semaphore_generic(hw);
7658cfa0ad2SJack F Vogel 
7668cfa0ad2SJack F Vogel out:
7678cfa0ad2SJack F Vogel 	return ret_val;
7688cfa0ad2SJack F Vogel }
7698cfa0ad2SJack F Vogel 
7708cfa0ad2SJack F Vogel /**
7718cfa0ad2SJack F Vogel  *  e1000_release_swfw_sync_82575 - Release SW/FW semaphore
7728cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
7738cfa0ad2SJack F Vogel  *  @mask: specifies which semaphore to acquire
7748cfa0ad2SJack F Vogel  *
7758cfa0ad2SJack F Vogel  *  Release the SW/FW semaphore used to access the PHY or NVM.  The mask
7768cfa0ad2SJack F Vogel  *  will also specify which port we're releasing the lock for.
7778cfa0ad2SJack F Vogel  **/
7788cfa0ad2SJack F Vogel static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
7798cfa0ad2SJack F Vogel {
7808cfa0ad2SJack F Vogel 	u32 swfw_sync;
7818cfa0ad2SJack F Vogel 
7828cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_release_swfw_sync_82575");
7838cfa0ad2SJack F Vogel 
7848cfa0ad2SJack F Vogel 	while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS);
7858cfa0ad2SJack F Vogel 	/* Empty */
7868cfa0ad2SJack F Vogel 
7878cfa0ad2SJack F Vogel 	swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
7888cfa0ad2SJack F Vogel 	swfw_sync &= ~mask;
7898cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
7908cfa0ad2SJack F Vogel 
7918cfa0ad2SJack F Vogel 	e1000_put_hw_semaphore_generic(hw);
7928cfa0ad2SJack F Vogel }
7938cfa0ad2SJack F Vogel 
7948cfa0ad2SJack F Vogel /**
7958cfa0ad2SJack F Vogel  *  e1000_get_cfg_done_82575 - Read config done bit
7968cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
7978cfa0ad2SJack F Vogel  *
7988cfa0ad2SJack F Vogel  *  Read the management control register for the config done bit for
7998cfa0ad2SJack F Vogel  *  completion status.  NOTE: silicon which is EEPROM-less will fail trying
8008cfa0ad2SJack F Vogel  *  to read the config done bit, so an error is *ONLY* logged and returns
8018cfa0ad2SJack F Vogel  *  E1000_SUCCESS.  If we were to return with error, EEPROM-less silicon
8028cfa0ad2SJack F Vogel  *  would not be able to be reset or change link.
8038cfa0ad2SJack F Vogel  **/
8048cfa0ad2SJack F Vogel static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
8058cfa0ad2SJack F Vogel {
8068cfa0ad2SJack F Vogel 	s32 timeout = PHY_CFG_TIMEOUT;
8078cfa0ad2SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
8088cfa0ad2SJack F Vogel 	u32 mask = E1000_NVM_CFG_DONE_PORT_0;
8098cfa0ad2SJack F Vogel 
8108cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_get_cfg_done_82575");
8118cfa0ad2SJack F Vogel 
8129d81738fSJack F Vogel 	if (hw->bus.func == E1000_FUNC_1)
8138cfa0ad2SJack F Vogel 		mask = E1000_NVM_CFG_DONE_PORT_1;
8144edd8523SJack F Vogel 	else if (hw->bus.func == E1000_FUNC_2)
8154edd8523SJack F Vogel 		mask = E1000_NVM_CFG_DONE_PORT_2;
8164edd8523SJack F Vogel 	else if (hw->bus.func == E1000_FUNC_3)
8174edd8523SJack F Vogel 		mask = E1000_NVM_CFG_DONE_PORT_3;
8188cfa0ad2SJack F Vogel 	while (timeout) {
8198cfa0ad2SJack F Vogel 		if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask)
8208cfa0ad2SJack F Vogel 			break;
8218cfa0ad2SJack F Vogel 		msec_delay(1);
8228cfa0ad2SJack F Vogel 		timeout--;
8238cfa0ad2SJack F Vogel 	}
8244edd8523SJack F Vogel 	if (!timeout)
8258cfa0ad2SJack F Vogel 		DEBUGOUT("MNG configuration cycle has not completed.\n");
8268cfa0ad2SJack F Vogel 
8278cfa0ad2SJack F Vogel 	/* If EEPROM is not marked present, init the PHY manually */
8288cfa0ad2SJack F Vogel 	if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) &&
8294edd8523SJack F Vogel 	    (hw->phy.type == e1000_phy_igp_3))
8308cfa0ad2SJack F Vogel 		e1000_phy_init_script_igp3(hw);
8318cfa0ad2SJack F Vogel 
8328cfa0ad2SJack F Vogel 	return ret_val;
8338cfa0ad2SJack F Vogel }
8348cfa0ad2SJack F Vogel 
8358cfa0ad2SJack F Vogel /**
8368cfa0ad2SJack F Vogel  *  e1000_get_link_up_info_82575 - Get link speed/duplex info
8378cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
8388cfa0ad2SJack F Vogel  *  @speed: stores the current speed
8398cfa0ad2SJack F Vogel  *  @duplex: stores the current duplex
8408cfa0ad2SJack F Vogel  *
8418cfa0ad2SJack F Vogel  *  This is a wrapper function, if using the serial gigabit media independent
8428cfa0ad2SJack F Vogel  *  interface, use PCS to retrieve the link speed and duplex information.
8438cfa0ad2SJack F Vogel  *  Otherwise, use the generic function to get the link speed and duplex info.
8448cfa0ad2SJack F Vogel  **/
8458cfa0ad2SJack F Vogel static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
8468cfa0ad2SJack F Vogel                                         u16 *duplex)
8478cfa0ad2SJack F Vogel {
8488cfa0ad2SJack F Vogel 	s32 ret_val;
8498cfa0ad2SJack F Vogel 
8508cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_get_link_up_info_82575");
8518cfa0ad2SJack F Vogel 
8524edd8523SJack F Vogel 	if (hw->phy.media_type != e1000_media_type_copper)
8538cfa0ad2SJack F Vogel 		ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, speed,
8548cfa0ad2SJack F Vogel 		                                               duplex);
8554edd8523SJack F Vogel 	else
8568cfa0ad2SJack F Vogel 		ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed,
8578cfa0ad2SJack F Vogel 		                                                    duplex);
8588cfa0ad2SJack F Vogel 
8598cfa0ad2SJack F Vogel 	return ret_val;
8608cfa0ad2SJack F Vogel }
8618cfa0ad2SJack F Vogel 
8628cfa0ad2SJack F Vogel /**
8638cfa0ad2SJack F Vogel  *  e1000_check_for_link_82575 - Check for link
8648cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
8658cfa0ad2SJack F Vogel  *
8668cfa0ad2SJack F Vogel  *  If sgmii is enabled, then use the pcs register to determine link, otherwise
8678cfa0ad2SJack F Vogel  *  use the generic interface for determining link.
8688cfa0ad2SJack F Vogel  **/
8698cfa0ad2SJack F Vogel static s32 e1000_check_for_link_82575(struct e1000_hw *hw)
8708cfa0ad2SJack F Vogel {
8718cfa0ad2SJack F Vogel 	s32 ret_val;
8728cfa0ad2SJack F Vogel 	u16 speed, duplex;
8738cfa0ad2SJack F Vogel 
8748cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_check_for_link_82575");
8758cfa0ad2SJack F Vogel 
8764edd8523SJack F Vogel 	if (hw->phy.media_type != e1000_media_type_copper) {
8778cfa0ad2SJack F Vogel 		ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed,
8788cfa0ad2SJack F Vogel 		                                               &duplex);
879d035aa2dSJack F Vogel 		/*
880d035aa2dSJack F Vogel 		 * Use this flag to determine if link needs to be checked or
881d035aa2dSJack F Vogel 		 * not.  If we have link clear the flag so that we do not
882d035aa2dSJack F Vogel 		 * continue to check for link.
883d035aa2dSJack F Vogel 		 */
884d035aa2dSJack F Vogel 		hw->mac.get_link_status = !hw->mac.serdes_has_link;
885d035aa2dSJack F Vogel 	} else {
8868cfa0ad2SJack F Vogel 		ret_val = e1000_check_for_copper_link_generic(hw);
887d035aa2dSJack F Vogel 	}
8888cfa0ad2SJack F Vogel 
8898cfa0ad2SJack F Vogel 	return ret_val;
8908cfa0ad2SJack F Vogel }
8918cfa0ad2SJack F Vogel 
8928cfa0ad2SJack F Vogel /**
893a69ed8dfSJack F Vogel  *  e1000_power_up_serdes_link_82575 - Power up the serdes link after shutdown
894a69ed8dfSJack F Vogel  *  @hw: pointer to the HW structure
895a69ed8dfSJack F Vogel  **/
896a69ed8dfSJack F Vogel static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw)
897a69ed8dfSJack F Vogel {
898a69ed8dfSJack F Vogel 	u32 reg;
899a69ed8dfSJack F Vogel 
900a69ed8dfSJack F Vogel 	DEBUGFUNC("e1000_power_up_serdes_link_82575");
901a69ed8dfSJack F Vogel 
902a69ed8dfSJack F Vogel 	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
903a69ed8dfSJack F Vogel 	    !e1000_sgmii_active_82575(hw))
904a69ed8dfSJack F Vogel 		return;
905a69ed8dfSJack F Vogel 
906a69ed8dfSJack F Vogel 	/* Enable PCS to turn on link */
907a69ed8dfSJack F Vogel 	reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
908a69ed8dfSJack F Vogel 	reg |= E1000_PCS_CFG_PCS_EN;
909a69ed8dfSJack F Vogel 	E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
910a69ed8dfSJack F Vogel 
911a69ed8dfSJack F Vogel 	/* Power up the laser */
912a69ed8dfSJack F Vogel 	reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
913a69ed8dfSJack F Vogel 	reg &= ~E1000_CTRL_EXT_SDP3_DATA;
914a69ed8dfSJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
915a69ed8dfSJack F Vogel 
916a69ed8dfSJack F Vogel 	/* flush the write to verify completion */
917a69ed8dfSJack F Vogel 	E1000_WRITE_FLUSH(hw);
918a69ed8dfSJack F Vogel 	msec_delay(1);
919a69ed8dfSJack F Vogel }
920a69ed8dfSJack F Vogel 
921a69ed8dfSJack F Vogel /**
9228cfa0ad2SJack F Vogel  *  e1000_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
9238cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
9248cfa0ad2SJack F Vogel  *  @speed: stores the current speed
9258cfa0ad2SJack F Vogel  *  @duplex: stores the current duplex
9268cfa0ad2SJack F Vogel  *
9278cfa0ad2SJack F Vogel  *  Using the physical coding sub-layer (PCS), retrieve the current speed and
9288cfa0ad2SJack F Vogel  *  duplex, then store the values in the pointers provided.
9298cfa0ad2SJack F Vogel  **/
9308cfa0ad2SJack F Vogel static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
9318cfa0ad2SJack F Vogel                                                 u16 *speed, u16 *duplex)
9328cfa0ad2SJack F Vogel {
9338cfa0ad2SJack F Vogel 	struct e1000_mac_info *mac = &hw->mac;
9348cfa0ad2SJack F Vogel 	u32 pcs;
9358cfa0ad2SJack F Vogel 
9368cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575");
9378cfa0ad2SJack F Vogel 
9388cfa0ad2SJack F Vogel 	/* Set up defaults for the return values of this function */
9398cfa0ad2SJack F Vogel 	mac->serdes_has_link = FALSE;
9408cfa0ad2SJack F Vogel 	*speed = 0;
9418cfa0ad2SJack F Vogel 	*duplex = 0;
9428cfa0ad2SJack F Vogel 
9438cfa0ad2SJack F Vogel 	/*
9448cfa0ad2SJack F Vogel 	 * Read the PCS Status register for link state. For non-copper mode,
9458cfa0ad2SJack F Vogel 	 * the status register is not accurate. The PCS status register is
9468cfa0ad2SJack F Vogel 	 * used instead.
9478cfa0ad2SJack F Vogel 	 */
9488cfa0ad2SJack F Vogel 	pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT);
9498cfa0ad2SJack F Vogel 
9508cfa0ad2SJack F Vogel 	/*
9518cfa0ad2SJack F Vogel 	 * The link up bit determines when link is up on autoneg. The sync ok
9528cfa0ad2SJack F Vogel 	 * gets set once both sides sync up and agree upon link. Stable link
9538cfa0ad2SJack F Vogel 	 * can be determined by checking for both link up and link sync ok
9548cfa0ad2SJack F Vogel 	 */
9558cfa0ad2SJack F Vogel 	if ((pcs & E1000_PCS_LSTS_LINK_OK) && (pcs & E1000_PCS_LSTS_SYNK_OK)) {
9568cfa0ad2SJack F Vogel 		mac->serdes_has_link = TRUE;
9578cfa0ad2SJack F Vogel 
9588cfa0ad2SJack F Vogel 		/* Detect and store PCS speed */
9598cfa0ad2SJack F Vogel 		if (pcs & E1000_PCS_LSTS_SPEED_1000) {
9608cfa0ad2SJack F Vogel 			*speed = SPEED_1000;
9618cfa0ad2SJack F Vogel 		} else if (pcs & E1000_PCS_LSTS_SPEED_100) {
9628cfa0ad2SJack F Vogel 			*speed = SPEED_100;
9638cfa0ad2SJack F Vogel 		} else {
9648cfa0ad2SJack F Vogel 			*speed = SPEED_10;
9658cfa0ad2SJack F Vogel 		}
9668cfa0ad2SJack F Vogel 
9678cfa0ad2SJack F Vogel 		/* Detect and store PCS duplex */
9688cfa0ad2SJack F Vogel 		if (pcs & E1000_PCS_LSTS_DUPLEX_FULL) {
9698cfa0ad2SJack F Vogel 			*duplex = FULL_DUPLEX;
9708cfa0ad2SJack F Vogel 		} else {
9718cfa0ad2SJack F Vogel 			*duplex = HALF_DUPLEX;
9728cfa0ad2SJack F Vogel 		}
9738cfa0ad2SJack F Vogel 	}
9748cfa0ad2SJack F Vogel 
9758cfa0ad2SJack F Vogel 	return E1000_SUCCESS;
9768cfa0ad2SJack F Vogel }
9778cfa0ad2SJack F Vogel 
9788cfa0ad2SJack F Vogel /**
9794edd8523SJack F Vogel  *  e1000_shutdown_serdes_link_82575 - Remove link during power down
9808cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
9818cfa0ad2SJack F Vogel  *
9824edd8523SJack F Vogel  *  In the case of serdes shut down sfp and PCS on driver unload
9838cfa0ad2SJack F Vogel  *  when management pass thru is not enabled.
9848cfa0ad2SJack F Vogel  **/
9854edd8523SJack F Vogel void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw)
9868cfa0ad2SJack F Vogel {
9878cfa0ad2SJack F Vogel 	u32 reg;
988a69ed8dfSJack F Vogel 
989a69ed8dfSJack F Vogel 	DEBUGFUNC("e1000_shutdown_serdes_link_82575");
9908cfa0ad2SJack F Vogel 
9914edd8523SJack F Vogel 	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
9924edd8523SJack F Vogel 	    !e1000_sgmii_active_82575(hw))
9938cfa0ad2SJack F Vogel 		return;
9948cfa0ad2SJack F Vogel 
995a69ed8dfSJack F Vogel 	if (!e1000_enable_mng_pass_thru(hw)) {
9968cfa0ad2SJack F Vogel 		/* Disable PCS to turn off link */
9978cfa0ad2SJack F Vogel 		reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
9988cfa0ad2SJack F Vogel 		reg &= ~E1000_PCS_CFG_PCS_EN;
9998cfa0ad2SJack F Vogel 		E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
10008cfa0ad2SJack F Vogel 
10018cfa0ad2SJack F Vogel 		/* shutdown the laser */
10028cfa0ad2SJack F Vogel 		reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
10034edd8523SJack F Vogel 		reg |= E1000_CTRL_EXT_SDP3_DATA;
10048cfa0ad2SJack F Vogel 		E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
10058cfa0ad2SJack F Vogel 
10064edd8523SJack F Vogel 		/* flush the write to verify completion */
10078cfa0ad2SJack F Vogel 		E1000_WRITE_FLUSH(hw);
10088cfa0ad2SJack F Vogel 		msec_delay(1);
10098cfa0ad2SJack F Vogel 	}
10108cfa0ad2SJack F Vogel 
10118cfa0ad2SJack F Vogel 	return;
10128cfa0ad2SJack F Vogel }
10138cfa0ad2SJack F Vogel 
10148cfa0ad2SJack F Vogel /**
10158cfa0ad2SJack F Vogel  *  e1000_reset_hw_82575 - Reset hardware
10168cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
10178cfa0ad2SJack F Vogel  *
1018daf9197cSJack F Vogel  *  This resets the hardware into a known state.
10198cfa0ad2SJack F Vogel  **/
10208cfa0ad2SJack F Vogel static s32 e1000_reset_hw_82575(struct e1000_hw *hw)
10218cfa0ad2SJack F Vogel {
10228cfa0ad2SJack F Vogel 	u32 ctrl, icr;
10238cfa0ad2SJack F Vogel 	s32 ret_val;
10248cfa0ad2SJack F Vogel 
10258cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_reset_hw_82575");
10268cfa0ad2SJack F Vogel 
10278cfa0ad2SJack F Vogel 	/*
10288cfa0ad2SJack F Vogel 	 * Prevent the PCI-E bus from sticking if there is no TLP connection
10298cfa0ad2SJack F Vogel 	 * on the last TLP read/write transaction when MAC is reset.
10308cfa0ad2SJack F Vogel 	 */
10318cfa0ad2SJack F Vogel 	ret_val = e1000_disable_pcie_master_generic(hw);
10328cfa0ad2SJack F Vogel 	if (ret_val) {
10338cfa0ad2SJack F Vogel 		DEBUGOUT("PCI-E Master disable polling has failed.\n");
10348cfa0ad2SJack F Vogel 	}
10358cfa0ad2SJack F Vogel 
10369d81738fSJack F Vogel 	/* set the completion timeout for interface */
10379d81738fSJack F Vogel 	ret_val = e1000_set_pcie_completion_timeout(hw);
10389d81738fSJack F Vogel 	if (ret_val) {
10399d81738fSJack F Vogel 		DEBUGOUT("PCI-E Set completion timeout has failed.\n");
10409d81738fSJack F Vogel 	}
10419d81738fSJack F Vogel 
10428cfa0ad2SJack F Vogel 	DEBUGOUT("Masking off all interrupts\n");
10438cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
10448cfa0ad2SJack F Vogel 
10458cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
10468cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
10478cfa0ad2SJack F Vogel 	E1000_WRITE_FLUSH(hw);
10488cfa0ad2SJack F Vogel 
10498cfa0ad2SJack F Vogel 	msec_delay(10);
10508cfa0ad2SJack F Vogel 
10518cfa0ad2SJack F Vogel 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
10528cfa0ad2SJack F Vogel 
10538cfa0ad2SJack F Vogel 	DEBUGOUT("Issuing a global reset to MAC\n");
10548cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
10558cfa0ad2SJack F Vogel 
10568cfa0ad2SJack F Vogel 	ret_val = e1000_get_auto_rd_done_generic(hw);
10578cfa0ad2SJack F Vogel 	if (ret_val) {
10588cfa0ad2SJack F Vogel 		/*
10598cfa0ad2SJack F Vogel 		 * When auto config read does not complete, do not
10608cfa0ad2SJack F Vogel 		 * return with an error. This can happen in situations
10618cfa0ad2SJack F Vogel 		 * where there is no eeprom and prevents getting link.
10628cfa0ad2SJack F Vogel 		 */
10638cfa0ad2SJack F Vogel 		DEBUGOUT("Auto Read Done did not complete\n");
10648cfa0ad2SJack F Vogel 	}
10658cfa0ad2SJack F Vogel 
10668cfa0ad2SJack F Vogel 	/* If EEPROM is not present, run manual init scripts */
10678cfa0ad2SJack F Vogel 	if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0)
10688cfa0ad2SJack F Vogel 		e1000_reset_init_script_82575(hw);
10698cfa0ad2SJack F Vogel 
10708cfa0ad2SJack F Vogel 	/* Clear any pending interrupt events. */
10718cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
10728cfa0ad2SJack F Vogel 	icr = E1000_READ_REG(hw, E1000_ICR);
10738cfa0ad2SJack F Vogel 
1074d035aa2dSJack F Vogel 	/* Install any alternate MAC address into RAR0 */
1075d035aa2dSJack F Vogel 	ret_val = e1000_check_alt_mac_addr_generic(hw);
10768cfa0ad2SJack F Vogel 
10778cfa0ad2SJack F Vogel 	return ret_val;
10788cfa0ad2SJack F Vogel }
10798cfa0ad2SJack F Vogel 
10808cfa0ad2SJack F Vogel /**
10818cfa0ad2SJack F Vogel  *  e1000_init_hw_82575 - Initialize hardware
10828cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
10838cfa0ad2SJack F Vogel  *
10848cfa0ad2SJack F Vogel  *  This inits the hardware readying it for operation.
10858cfa0ad2SJack F Vogel  **/
10868cfa0ad2SJack F Vogel static s32 e1000_init_hw_82575(struct e1000_hw *hw)
10878cfa0ad2SJack F Vogel {
10888cfa0ad2SJack F Vogel 	struct e1000_mac_info *mac = &hw->mac;
10898cfa0ad2SJack F Vogel 	s32 ret_val;
10908cfa0ad2SJack F Vogel 	u16 i, rar_count = mac->rar_entry_count;
10918cfa0ad2SJack F Vogel 
10928cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_init_hw_82575");
10938cfa0ad2SJack F Vogel 
10948cfa0ad2SJack F Vogel 	/* Initialize identification LED */
1095d035aa2dSJack F Vogel 	ret_val = mac->ops.id_led_init(hw);
10968cfa0ad2SJack F Vogel 	if (ret_val) {
10978cfa0ad2SJack F Vogel 		DEBUGOUT("Error initializing identification LED\n");
10988cfa0ad2SJack F Vogel 		/* This is not fatal and we should not stop init due to this */
10998cfa0ad2SJack F Vogel 	}
11008cfa0ad2SJack F Vogel 
11018cfa0ad2SJack F Vogel 	/* Disabling VLAN filtering */
11028cfa0ad2SJack F Vogel 	DEBUGOUT("Initializing the IEEE VLAN\n");
11038cfa0ad2SJack F Vogel 	mac->ops.clear_vfta(hw);
11048cfa0ad2SJack F Vogel 
11058cfa0ad2SJack F Vogel 	/* Setup the receive address */
1106d035aa2dSJack F Vogel 	e1000_init_rx_addrs_generic(hw, rar_count);
1107d035aa2dSJack F Vogel 
11088cfa0ad2SJack F Vogel 	/* Zero out the Multicast HASH table */
11098cfa0ad2SJack F Vogel 	DEBUGOUT("Zeroing the MTA\n");
11108cfa0ad2SJack F Vogel 	for (i = 0; i < mac->mta_reg_count; i++)
11118cfa0ad2SJack F Vogel 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
11128cfa0ad2SJack F Vogel 
11134edd8523SJack F Vogel 	/* Zero out the Unicast HASH table */
11144edd8523SJack F Vogel 	DEBUGOUT("Zeroing the UTA\n");
11154edd8523SJack F Vogel 	for (i = 0; i < mac->uta_reg_count; i++)
11164edd8523SJack F Vogel 		E1000_WRITE_REG_ARRAY(hw, E1000_UTA, i, 0);
11174edd8523SJack F Vogel 
11188cfa0ad2SJack F Vogel 	/* Setup link and flow control */
11198cfa0ad2SJack F Vogel 	ret_val = mac->ops.setup_link(hw);
11208cfa0ad2SJack F Vogel 
11218cfa0ad2SJack F Vogel 	/*
11228cfa0ad2SJack F Vogel 	 * Clear all of the statistics registers (clear on read).  It is
11238cfa0ad2SJack F Vogel 	 * important that we do this after we have tried to establish link
11248cfa0ad2SJack F Vogel 	 * because the symbol error count will increment wildly if there
11258cfa0ad2SJack F Vogel 	 * is no link.
11268cfa0ad2SJack F Vogel 	 */
11278cfa0ad2SJack F Vogel 	e1000_clear_hw_cntrs_82575(hw);
11288cfa0ad2SJack F Vogel 
11298cfa0ad2SJack F Vogel 	return ret_val;
11308cfa0ad2SJack F Vogel }
11318cfa0ad2SJack F Vogel 
11328cfa0ad2SJack F Vogel /**
11338cfa0ad2SJack F Vogel  *  e1000_setup_copper_link_82575 - Configure copper link settings
11348cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
11358cfa0ad2SJack F Vogel  *
11368cfa0ad2SJack F Vogel  *  Configures the link for auto-neg or forced speed and duplex.  Then we check
11378cfa0ad2SJack F Vogel  *  for link, once link is established calls to configure collision distance
11388cfa0ad2SJack F Vogel  *  and flow control are called.
11398cfa0ad2SJack F Vogel  **/
11408cfa0ad2SJack F Vogel static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
11418cfa0ad2SJack F Vogel {
11429d81738fSJack F Vogel 	u32 ctrl;
11438cfa0ad2SJack F Vogel 	s32  ret_val;
11448cfa0ad2SJack F Vogel 
11458cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_setup_copper_link_82575");
11468cfa0ad2SJack F Vogel 
11478cfa0ad2SJack F Vogel 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
11488cfa0ad2SJack F Vogel 	ctrl |= E1000_CTRL_SLU;
11498cfa0ad2SJack F Vogel 	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
11508cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
11518cfa0ad2SJack F Vogel 
11524edd8523SJack F Vogel 	ret_val = e1000_setup_serdes_link_82575(hw);
11534edd8523SJack F Vogel 	if (ret_val)
11544edd8523SJack F Vogel 		goto out;
11554edd8523SJack F Vogel 
11564edd8523SJack F Vogel 	if (e1000_sgmii_active_82575(hw) && !hw->phy.reset_disable) {
11574edd8523SJack F Vogel 		/* allow time for SFP cage time to power up phy */
11584edd8523SJack F Vogel 		msec_delay(300);
11594edd8523SJack F Vogel 
11604edd8523SJack F Vogel 		ret_val = hw->phy.ops.reset(hw);
11614edd8523SJack F Vogel 		if (ret_val) {
11624edd8523SJack F Vogel 			DEBUGOUT("Error resetting the PHY.\n");
11634edd8523SJack F Vogel 			goto out;
11644edd8523SJack F Vogel 		}
11654edd8523SJack F Vogel 	}
11668cfa0ad2SJack F Vogel 	switch (hw->phy.type) {
11678cfa0ad2SJack F Vogel 	case e1000_phy_m88:
11688cfa0ad2SJack F Vogel 		ret_val = e1000_copper_link_setup_m88(hw);
11698cfa0ad2SJack F Vogel 		break;
11708cfa0ad2SJack F Vogel 	case e1000_phy_igp_3:
11718cfa0ad2SJack F Vogel 		ret_val = e1000_copper_link_setup_igp(hw);
11728cfa0ad2SJack F Vogel 		break;
11734edd8523SJack F Vogel 	case e1000_phy_82580:
11744edd8523SJack F Vogel 		ret_val = e1000_copper_link_setup_82577(hw);
11754edd8523SJack F Vogel 		break;
11768cfa0ad2SJack F Vogel 	default:
11778cfa0ad2SJack F Vogel 		ret_val = -E1000_ERR_PHY;
11788cfa0ad2SJack F Vogel 		break;
11798cfa0ad2SJack F Vogel 	}
11808cfa0ad2SJack F Vogel 
11818cfa0ad2SJack F Vogel 	if (ret_val)
11828cfa0ad2SJack F Vogel 		goto out;
11838cfa0ad2SJack F Vogel 
11844edd8523SJack F Vogel 	ret_val = e1000_setup_copper_link_generic(hw);
11858cfa0ad2SJack F Vogel out:
11868cfa0ad2SJack F Vogel 	return ret_val;
11878cfa0ad2SJack F Vogel }
11888cfa0ad2SJack F Vogel 
11898cfa0ad2SJack F Vogel /**
11904edd8523SJack F Vogel  *  e1000_setup_serdes_link_82575 - Setup link for serdes
11918cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
11928cfa0ad2SJack F Vogel  *
11934edd8523SJack F Vogel  *  Configure the physical coding sub-layer (PCS) link.  The PCS link is
11944edd8523SJack F Vogel  *  used on copper connections where the serialized gigabit media independent
11954edd8523SJack F Vogel  *  interface (sgmii), or serdes fiber is being used.  Configures the link
11964edd8523SJack F Vogel  *  for auto-negotiation or forces speed/duplex.
11978cfa0ad2SJack F Vogel  **/
11984edd8523SJack F Vogel static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw)
11998cfa0ad2SJack F Vogel {
12004edd8523SJack F Vogel 	u32 ctrl_ext, ctrl_reg, reg;
12014edd8523SJack F Vogel 	bool pcs_autoneg;
12028cfa0ad2SJack F Vogel 
12034edd8523SJack F Vogel 	DEBUGFUNC("e1000_setup_serdes_link_82575");
12044edd8523SJack F Vogel 
12054edd8523SJack F Vogel 	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
12064edd8523SJack F Vogel 	    !e1000_sgmii_active_82575(hw))
12074edd8523SJack F Vogel 		return E1000_SUCCESS;
12088cfa0ad2SJack F Vogel 
12098cfa0ad2SJack F Vogel 	/*
12108cfa0ad2SJack F Vogel 	 * On the 82575, SerDes loopback mode persists until it is
12118cfa0ad2SJack F Vogel 	 * explicitly turned off or a power cycle is performed.  A read to
12128cfa0ad2SJack F Vogel 	 * the register does not indicate its status.  Therefore, we ensure
12138cfa0ad2SJack F Vogel 	 * loopback mode is disabled during initialization.
12148cfa0ad2SJack F Vogel 	 */
12158cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
12168cfa0ad2SJack F Vogel 
12174edd8523SJack F Vogel 	/* power on the sfp cage if present */
12184edd8523SJack F Vogel 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
12194edd8523SJack F Vogel 	ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
12204edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
12214edd8523SJack F Vogel 
12224edd8523SJack F Vogel 	ctrl_reg = E1000_READ_REG(hw, E1000_CTRL);
12234edd8523SJack F Vogel 	ctrl_reg |= E1000_CTRL_SLU;
12244edd8523SJack F Vogel 
1225a69ed8dfSJack F Vogel 	/* set both sw defined pins on 82575/82576*/
1226a69ed8dfSJack F Vogel 	if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576)
12274edd8523SJack F Vogel 		ctrl_reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1;
12288cfa0ad2SJack F Vogel 
12294edd8523SJack F Vogel 	reg = E1000_READ_REG(hw, E1000_PCS_LCTL);
12304edd8523SJack F Vogel 
12314edd8523SJack F Vogel 	/* default pcs_autoneg to the same setting as mac autoneg */
12324edd8523SJack F Vogel 	pcs_autoneg = hw->mac.autoneg;
12334edd8523SJack F Vogel 
12344edd8523SJack F Vogel 	switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
12354edd8523SJack F Vogel 	case E1000_CTRL_EXT_LINK_MODE_SGMII:
12364edd8523SJack F Vogel 		/* sgmii mode lets the phy handle forcing speed/duplex */
12374edd8523SJack F Vogel 		pcs_autoneg = TRUE;
12384edd8523SJack F Vogel 		/* autoneg time out should be disabled for SGMII mode */
12394edd8523SJack F Vogel 		reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
12404edd8523SJack F Vogel 		break;
12414edd8523SJack F Vogel 	case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
12424edd8523SJack F Vogel 		/* disable PCS autoneg and support parallel detect only */
12434edd8523SJack F Vogel 		pcs_autoneg = FALSE;
12444edd8523SJack F Vogel 	default:
12454edd8523SJack F Vogel 		/*
12464edd8523SJack F Vogel 		 * non-SGMII modes only supports a speed of 1000/Full for the
12474edd8523SJack F Vogel 		 * link so it is best to just force the MAC and let the pcs
12484edd8523SJack F Vogel 		 * link either autoneg or be forced to 1000/Full
12494edd8523SJack F Vogel 		 */
12504edd8523SJack F Vogel 		ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
12514edd8523SJack F Vogel 		            E1000_CTRL_FD | E1000_CTRL_FRCDPX;
12524edd8523SJack F Vogel 
12534edd8523SJack F Vogel 		/* set speed of 1000/Full if speed/duplex is forced */
12544edd8523SJack F Vogel 		reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL;
12554edd8523SJack F Vogel 		break;
12564edd8523SJack F Vogel 	}
12574edd8523SJack F Vogel 
12584edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl_reg);
12598cfa0ad2SJack F Vogel 
12608cfa0ad2SJack F Vogel 	/*
12618cfa0ad2SJack F Vogel 	 * New SerDes mode allows for forcing speed or autonegotiating speed
12628cfa0ad2SJack F Vogel 	 * at 1gb. Autoneg should be default set by most drivers. This is the
12638cfa0ad2SJack F Vogel 	 * mode that will be compatible with older link partners and switches.
12648cfa0ad2SJack F Vogel 	 * However, both are supported by the hardware and some drivers/tools.
12658cfa0ad2SJack F Vogel 	 */
12668cfa0ad2SJack F Vogel 	reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
12678cfa0ad2SJack F Vogel 	         E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
12688cfa0ad2SJack F Vogel 
12694edd8523SJack F Vogel 	/*
12704edd8523SJack F Vogel 	 * We force flow control to prevent the CTRL register values from being
12714edd8523SJack F Vogel 	 * overwritten by the autonegotiated flow control values
12724edd8523SJack F Vogel 	 */
12738cfa0ad2SJack F Vogel 	reg |= E1000_PCS_LCTL_FORCE_FCTRL;
12744edd8523SJack F Vogel 
12754edd8523SJack F Vogel 	if (pcs_autoneg) {
12764edd8523SJack F Vogel 		/* Set PCS register for autoneg */
12774edd8523SJack F Vogel 		reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
12784edd8523SJack F Vogel 		       E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
12794edd8523SJack F Vogel 		DEBUGOUT1("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg);
12804edd8523SJack F Vogel 	} else {
12814edd8523SJack F Vogel 		/* Set PCS register for forced link */
1282a69ed8dfSJack F Vogel 		reg |= E1000_PCS_LCTL_FSD;        /* Force Speed */
12834edd8523SJack F Vogel 		DEBUGOUT1("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg);
12848cfa0ad2SJack F Vogel 	}
12858cfa0ad2SJack F Vogel 
12868cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg);
12878cfa0ad2SJack F Vogel 
12884edd8523SJack F Vogel 	if (!e1000_sgmii_active_82575(hw))
12894edd8523SJack F Vogel 		e1000_force_mac_fc_generic(hw);
12904edd8523SJack F Vogel 
12918cfa0ad2SJack F Vogel 	return E1000_SUCCESS;
12928cfa0ad2SJack F Vogel }
12938cfa0ad2SJack F Vogel 
12948cfa0ad2SJack F Vogel /**
12958cfa0ad2SJack F Vogel  *  e1000_valid_led_default_82575 - Verify a valid default LED config
12968cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
12978cfa0ad2SJack F Vogel  *  @data: pointer to the NVM (EEPROM)
12988cfa0ad2SJack F Vogel  *
12998cfa0ad2SJack F Vogel  *  Read the EEPROM for the current default LED configuration.  If the
13008cfa0ad2SJack F Vogel  *  LED configuration is not valid, set to a valid LED configuration.
13018cfa0ad2SJack F Vogel  **/
13028cfa0ad2SJack F Vogel static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data)
13038cfa0ad2SJack F Vogel {
13048cfa0ad2SJack F Vogel 	s32 ret_val;
13058cfa0ad2SJack F Vogel 
13068cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_valid_led_default_82575");
13078cfa0ad2SJack F Vogel 
13088cfa0ad2SJack F Vogel 	ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
13098cfa0ad2SJack F Vogel 	if (ret_val) {
13108cfa0ad2SJack F Vogel 		DEBUGOUT("NVM Read Error\n");
13118cfa0ad2SJack F Vogel 		goto out;
13128cfa0ad2SJack F Vogel 	}
13138cfa0ad2SJack F Vogel 
13148cfa0ad2SJack F Vogel 	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
13158cfa0ad2SJack F Vogel 		switch(hw->phy.media_type) {
13168cfa0ad2SJack F Vogel 		case e1000_media_type_internal_serdes:
13178cfa0ad2SJack F Vogel 			*data = ID_LED_DEFAULT_82575_SERDES;
13188cfa0ad2SJack F Vogel 			break;
13198cfa0ad2SJack F Vogel 		case e1000_media_type_copper:
13208cfa0ad2SJack F Vogel 		default:
13218cfa0ad2SJack F Vogel 			*data = ID_LED_DEFAULT;
13228cfa0ad2SJack F Vogel 			break;
13238cfa0ad2SJack F Vogel 		}
13248cfa0ad2SJack F Vogel 	}
13258cfa0ad2SJack F Vogel out:
13268cfa0ad2SJack F Vogel 	return ret_val;
13278cfa0ad2SJack F Vogel }
13288cfa0ad2SJack F Vogel 
13298cfa0ad2SJack F Vogel /**
13308cfa0ad2SJack F Vogel  *  e1000_sgmii_active_82575 - Return sgmii state
13318cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
13328cfa0ad2SJack F Vogel  *
13338cfa0ad2SJack F Vogel  *  82575 silicon has a serialized gigabit media independent interface (sgmii)
13348cfa0ad2SJack F Vogel  *  which can be enabled for use in the embedded applications.  Simply
13358cfa0ad2SJack F Vogel  *  return the current state of the sgmii interface.
13368cfa0ad2SJack F Vogel  **/
13378cfa0ad2SJack F Vogel static bool e1000_sgmii_active_82575(struct e1000_hw *hw)
13388cfa0ad2SJack F Vogel {
1339daf9197cSJack F Vogel 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
1340daf9197cSJack F Vogel 	return dev_spec->sgmii_active;
13418cfa0ad2SJack F Vogel }
13428cfa0ad2SJack F Vogel 
13438cfa0ad2SJack F Vogel /**
13448cfa0ad2SJack F Vogel  *  e1000_reset_init_script_82575 - Inits HW defaults after reset
13458cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
13468cfa0ad2SJack F Vogel  *
13478cfa0ad2SJack F Vogel  *  Inits recommended HW defaults after a reset when there is no EEPROM
13488cfa0ad2SJack F Vogel  *  detected. This is only for the 82575.
13498cfa0ad2SJack F Vogel  **/
13508cfa0ad2SJack F Vogel static s32 e1000_reset_init_script_82575(struct e1000_hw* hw)
13518cfa0ad2SJack F Vogel {
13528cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_reset_init_script_82575");
13538cfa0ad2SJack F Vogel 
13548cfa0ad2SJack F Vogel 	if (hw->mac.type == e1000_82575) {
13558cfa0ad2SJack F Vogel 		DEBUGOUT("Running reset init script for 82575\n");
13568cfa0ad2SJack F Vogel 		/* SerDes configuration via SERDESCTRL */
13578cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x00, 0x0C);
13588cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x01, 0x78);
13598cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x1B, 0x23);
13608cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x23, 0x15);
13618cfa0ad2SJack F Vogel 
13628cfa0ad2SJack F Vogel 		/* CCM configuration via CCMCTL register */
13638cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x14, 0x00);
13648cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x10, 0x00);
13658cfa0ad2SJack F Vogel 
13668cfa0ad2SJack F Vogel 		/* PCIe lanes configuration */
13678cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x00, 0xEC);
13688cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x61, 0xDF);
13698cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x34, 0x05);
13708cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x2F, 0x81);
13718cfa0ad2SJack F Vogel 
13728cfa0ad2SJack F Vogel 		/* PCIe PLL Configuration */
13738cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x02, 0x47);
13748cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x14, 0x00);
13758cfa0ad2SJack F Vogel 		e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x10, 0x00);
13768cfa0ad2SJack F Vogel 	}
13778cfa0ad2SJack F Vogel 
13788cfa0ad2SJack F Vogel 	return E1000_SUCCESS;
13798cfa0ad2SJack F Vogel }
13808cfa0ad2SJack F Vogel 
13818cfa0ad2SJack F Vogel /**
13828cfa0ad2SJack F Vogel  *  e1000_read_mac_addr_82575 - Read device MAC address
13838cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
13848cfa0ad2SJack F Vogel  **/
13858cfa0ad2SJack F Vogel static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw)
13868cfa0ad2SJack F Vogel {
13878cfa0ad2SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
13888cfa0ad2SJack F Vogel 
13898cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_read_mac_addr_82575");
1390d035aa2dSJack F Vogel 
1391d035aa2dSJack F Vogel 	/*
1392d035aa2dSJack F Vogel 	 * If there's an alternate MAC address place it in RAR0
1393d035aa2dSJack F Vogel 	 * so that it will override the Si installed default perm
1394d035aa2dSJack F Vogel 	 * address.
1395d035aa2dSJack F Vogel 	 */
1396d035aa2dSJack F Vogel 	ret_val = e1000_check_alt_mac_addr_generic(hw);
1397d035aa2dSJack F Vogel 	if (ret_val)
1398d035aa2dSJack F Vogel 		goto out;
1399d035aa2dSJack F Vogel 
14008cfa0ad2SJack F Vogel 	ret_val = e1000_read_mac_addr_generic(hw);
14018cfa0ad2SJack F Vogel 
1402d035aa2dSJack F Vogel out:
14038cfa0ad2SJack F Vogel 	return ret_val;
14048cfa0ad2SJack F Vogel }
14058cfa0ad2SJack F Vogel 
14068cfa0ad2SJack F Vogel /**
1407a69ed8dfSJack F Vogel  *  e1000_config_collision_dist_82575 - Configure collision distance
1408a69ed8dfSJack F Vogel  *  @hw: pointer to the HW structure
1409a69ed8dfSJack F Vogel  *
1410a69ed8dfSJack F Vogel  *  Configures the collision distance to the default value and is used
1411a69ed8dfSJack F Vogel  *  during link setup.
1412a69ed8dfSJack F Vogel  **/
1413a69ed8dfSJack F Vogel static void e1000_config_collision_dist_82575(struct e1000_hw *hw)
1414a69ed8dfSJack F Vogel {
1415a69ed8dfSJack F Vogel 	u32 tctl_ext;
1416a69ed8dfSJack F Vogel 
1417a69ed8dfSJack F Vogel 	DEBUGFUNC("e1000_config_collision_dist_82575");
1418a69ed8dfSJack F Vogel 
1419a69ed8dfSJack F Vogel 	tctl_ext = E1000_READ_REG(hw, E1000_TCTL_EXT);
1420a69ed8dfSJack F Vogel 
1421a69ed8dfSJack F Vogel 	tctl_ext &= ~E1000_TCTL_EXT_COLD;
1422a69ed8dfSJack F Vogel 	tctl_ext |= E1000_COLLISION_DISTANCE << E1000_TCTL_EXT_COLD_SHIFT;
1423a69ed8dfSJack F Vogel 
1424a69ed8dfSJack F Vogel 	E1000_WRITE_REG(hw, E1000_TCTL_EXT, tctl_ext);
1425a69ed8dfSJack F Vogel 	E1000_WRITE_FLUSH(hw);
1426a69ed8dfSJack F Vogel }
1427a69ed8dfSJack F Vogel 
1428a69ed8dfSJack F Vogel /**
14298cfa0ad2SJack F Vogel  * e1000_power_down_phy_copper_82575 - Remove link during PHY power down
14308cfa0ad2SJack F Vogel  * @hw: pointer to the HW structure
14318cfa0ad2SJack F Vogel  *
14328cfa0ad2SJack F Vogel  * In the case of a PHY power down to save power, or to turn off link during a
14338cfa0ad2SJack F Vogel  * driver unload, or wake on lan is not enabled, remove the link.
14348cfa0ad2SJack F Vogel  **/
14358cfa0ad2SJack F Vogel static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
14368cfa0ad2SJack F Vogel {
14378cfa0ad2SJack F Vogel 	struct e1000_phy_info *phy = &hw->phy;
14388cfa0ad2SJack F Vogel 	struct e1000_mac_info *mac = &hw->mac;
14398cfa0ad2SJack F Vogel 
14408cfa0ad2SJack F Vogel 	if (!(phy->ops.check_reset_block))
14418cfa0ad2SJack F Vogel 		return;
14428cfa0ad2SJack F Vogel 
14438cfa0ad2SJack F Vogel 	/* If the management interface is not enabled, then power down */
14448cfa0ad2SJack F Vogel 	if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw)))
14458cfa0ad2SJack F Vogel 		e1000_power_down_phy_copper(hw);
14468cfa0ad2SJack F Vogel 
14478cfa0ad2SJack F Vogel 	return;
14488cfa0ad2SJack F Vogel }
14498cfa0ad2SJack F Vogel 
14508cfa0ad2SJack F Vogel /**
14518cfa0ad2SJack F Vogel  *  e1000_clear_hw_cntrs_82575 - Clear device specific hardware counters
14528cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
14538cfa0ad2SJack F Vogel  *
14548cfa0ad2SJack F Vogel  *  Clears the hardware counters by reading the counter registers.
14558cfa0ad2SJack F Vogel  **/
14568cfa0ad2SJack F Vogel static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
14578cfa0ad2SJack F Vogel {
14588cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_clear_hw_cntrs_82575");
14598cfa0ad2SJack F Vogel 
14608cfa0ad2SJack F Vogel 	e1000_clear_hw_cntrs_base_generic(hw);
14618cfa0ad2SJack F Vogel 
1462daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC64);
1463daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC127);
1464daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC255);
1465daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC511);
1466daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC1023);
1467daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PRC1522);
1468daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC64);
1469daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC127);
1470daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC255);
1471daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC511);
1472daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC1023);
1473daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_PTC1522);
14748cfa0ad2SJack F Vogel 
1475daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_ALGNERRC);
1476daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_RXERRC);
1477daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_TNCRS);
1478daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_CEXTERR);
1479daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_TSCTC);
1480daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_TSCTFC);
14818cfa0ad2SJack F Vogel 
1482daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_MGTPRC);
1483daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_MGTPDC);
1484daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_MGTPTC);
14858cfa0ad2SJack F Vogel 
1486daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_IAC);
1487daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_ICRXOC);
14888cfa0ad2SJack F Vogel 
1489daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_ICRXPTC);
1490daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_ICRXATC);
1491daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_ICTXPTC);
1492daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_ICTXATC);
1493daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_ICTXQEC);
1494daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_ICTXQMTC);
1495daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_ICRXDMTC);
14968cfa0ad2SJack F Vogel 
1497daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_CBTMPC);
1498daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_HTDPMC);
1499daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_CBRMPC);
1500daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_RPTHC);
1501daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_HGPTC);
1502daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_HTCBDPC);
1503daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_HGORCL);
1504daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_HGORCH);
1505daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_HGOTCL);
1506daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_HGOTCH);
1507daf9197cSJack F Vogel 	E1000_READ_REG(hw, E1000_LENERRS);
15088cfa0ad2SJack F Vogel 
15098cfa0ad2SJack F Vogel 	/* This register should not be read in copper configurations */
15104edd8523SJack F Vogel 	if ((hw->phy.media_type == e1000_media_type_internal_serdes) ||
15114edd8523SJack F Vogel 	    e1000_sgmii_active_82575(hw))
1512daf9197cSJack F Vogel 		E1000_READ_REG(hw, E1000_SCVPC);
15138cfa0ad2SJack F Vogel }
15149d81738fSJack F Vogel 
15158cfa0ad2SJack F Vogel /**
15168cfa0ad2SJack F Vogel  *  e1000_rx_fifo_flush_82575 - Clean rx fifo after RX enable
15178cfa0ad2SJack F Vogel  *  @hw: pointer to the HW structure
15188cfa0ad2SJack F Vogel  *
15198cfa0ad2SJack F Vogel  *  After rx enable if managability is enabled then there is likely some
15208cfa0ad2SJack F Vogel  *  bad data at the start of the fifo and possibly in the DMA fifo.  This
15218cfa0ad2SJack F Vogel  *  function clears the fifos and flushes any packets that came in as rx was
15228cfa0ad2SJack F Vogel  *  being enabled.
15238cfa0ad2SJack F Vogel  **/
15248cfa0ad2SJack F Vogel void e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
15258cfa0ad2SJack F Vogel {
15268cfa0ad2SJack F Vogel 	u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
15278cfa0ad2SJack F Vogel 	int i, ms_wait;
15288cfa0ad2SJack F Vogel 
15298cfa0ad2SJack F Vogel 	DEBUGFUNC("e1000_rx_fifo_workaround_82575");
15308cfa0ad2SJack F Vogel 	if (hw->mac.type != e1000_82575 ||
15318cfa0ad2SJack F Vogel 	    !(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
15328cfa0ad2SJack F Vogel 		return;
15338cfa0ad2SJack F Vogel 
15348cfa0ad2SJack F Vogel 	/* Disable all RX queues */
15358cfa0ad2SJack F Vogel 	for (i = 0; i < 4; i++) {
15368cfa0ad2SJack F Vogel 		rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i));
15378cfa0ad2SJack F Vogel 		E1000_WRITE_REG(hw, E1000_RXDCTL(i),
15388cfa0ad2SJack F Vogel 		                rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
15398cfa0ad2SJack F Vogel 	}
15408cfa0ad2SJack F Vogel 	/* Poll all queues to verify they have shut down */
15418cfa0ad2SJack F Vogel 	for (ms_wait = 0; ms_wait < 10; ms_wait++) {
15428cfa0ad2SJack F Vogel 		msec_delay(1);
15438cfa0ad2SJack F Vogel 		rx_enabled = 0;
15448cfa0ad2SJack F Vogel 		for (i = 0; i < 4; i++)
15458cfa0ad2SJack F Vogel 			rx_enabled |= E1000_READ_REG(hw, E1000_RXDCTL(i));
15468cfa0ad2SJack F Vogel 		if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
15478cfa0ad2SJack F Vogel 			break;
15488cfa0ad2SJack F Vogel 	}
15498cfa0ad2SJack F Vogel 
15508cfa0ad2SJack F Vogel 	if (ms_wait == 10)
15518cfa0ad2SJack F Vogel 		DEBUGOUT("Queue disable timed out after 10ms\n");
15528cfa0ad2SJack F Vogel 
15538cfa0ad2SJack F Vogel 	/* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
15548cfa0ad2SJack F Vogel 	 * incoming packets are rejected.  Set enable and wait 2ms so that
15558cfa0ad2SJack F Vogel 	 * any packet that was coming in as RCTL.EN was set is flushed
15568cfa0ad2SJack F Vogel 	 */
15578cfa0ad2SJack F Vogel 	rfctl = E1000_READ_REG(hw, E1000_RFCTL);
15588cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
15598cfa0ad2SJack F Vogel 
15608cfa0ad2SJack F Vogel 	rlpml = E1000_READ_REG(hw, E1000_RLPML);
15618cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_RLPML, 0);
15628cfa0ad2SJack F Vogel 
15638cfa0ad2SJack F Vogel 	rctl = E1000_READ_REG(hw, E1000_RCTL);
15648cfa0ad2SJack F Vogel 	temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
15658cfa0ad2SJack F Vogel 	temp_rctl |= E1000_RCTL_LPE;
15668cfa0ad2SJack F Vogel 
15678cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl);
15688cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl | E1000_RCTL_EN);
15698cfa0ad2SJack F Vogel 	E1000_WRITE_FLUSH(hw);
15708cfa0ad2SJack F Vogel 	msec_delay(2);
15718cfa0ad2SJack F Vogel 
15728cfa0ad2SJack F Vogel 	/* Enable RX queues that were previously enabled and restore our
15738cfa0ad2SJack F Vogel 	 * previous state
15748cfa0ad2SJack F Vogel 	 */
15758cfa0ad2SJack F Vogel 	for (i = 0; i < 4; i++)
15768cfa0ad2SJack F Vogel 		E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl[i]);
15778cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_RCTL, rctl);
15788cfa0ad2SJack F Vogel 	E1000_WRITE_FLUSH(hw);
15798cfa0ad2SJack F Vogel 
15808cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_RLPML, rlpml);
15818cfa0ad2SJack F Vogel 	E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
15828cfa0ad2SJack F Vogel 
15838cfa0ad2SJack F Vogel 	/* Flush receive errors generated by workaround */
15848cfa0ad2SJack F Vogel 	E1000_READ_REG(hw, E1000_ROC);
15858cfa0ad2SJack F Vogel 	E1000_READ_REG(hw, E1000_RNBC);
15868cfa0ad2SJack F Vogel 	E1000_READ_REG(hw, E1000_MPC);
15878cfa0ad2SJack F Vogel }
1588daf9197cSJack F Vogel 
15899d81738fSJack F Vogel /**
15909d81738fSJack F Vogel  *  e1000_set_pcie_completion_timeout - set pci-e completion timeout
15919d81738fSJack F Vogel  *  @hw: pointer to the HW structure
15929d81738fSJack F Vogel  *
15939d81738fSJack F Vogel  *  The defaults for 82575 and 82576 should be in the range of 50us to 50ms,
15949d81738fSJack F Vogel  *  however the hardware default for these parts is 500us to 1ms which is less
15959d81738fSJack F Vogel  *  than the 10ms recommended by the pci-e spec.  To address this we need to
15969d81738fSJack F Vogel  *  increase the value to either 10ms to 200ms for capability version 1 config,
15979d81738fSJack F Vogel  *  or 16ms to 55ms for version 2.
15989d81738fSJack F Vogel  **/
15999d81738fSJack F Vogel static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw)
16009d81738fSJack F Vogel {
16019d81738fSJack F Vogel 	u32 gcr = E1000_READ_REG(hw, E1000_GCR);
16029d81738fSJack F Vogel 	s32 ret_val = E1000_SUCCESS;
16039d81738fSJack F Vogel 	u16 pcie_devctl2;
16049d81738fSJack F Vogel 
16059d81738fSJack F Vogel 	/* only take action if timeout value is defaulted to 0 */
16069d81738fSJack F Vogel 	if (gcr & E1000_GCR_CMPL_TMOUT_MASK)
16079d81738fSJack F Vogel 		goto out;
16089d81738fSJack F Vogel 
16099d81738fSJack F Vogel 	/*
16109d81738fSJack F Vogel 	 * if capababilities version is type 1 we can write the
16119d81738fSJack F Vogel 	 * timeout of 10ms to 200ms through the GCR register
16129d81738fSJack F Vogel 	 */
16139d81738fSJack F Vogel 	if (!(gcr & E1000_GCR_CAP_VER2)) {
16149d81738fSJack F Vogel 		gcr |= E1000_GCR_CMPL_TMOUT_10ms;
16159d81738fSJack F Vogel 		goto out;
16169d81738fSJack F Vogel 	}
16179d81738fSJack F Vogel 
16189d81738fSJack F Vogel 	/*
16199d81738fSJack F Vogel 	 * for version 2 capabilities we need to write the config space
16209d81738fSJack F Vogel 	 * directly in order to set the completion timeout value for
16219d81738fSJack F Vogel 	 * 16ms to 55ms
16229d81738fSJack F Vogel 	 */
16239d81738fSJack F Vogel 	ret_val = e1000_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
16249d81738fSJack F Vogel 	                                  &pcie_devctl2);
16259d81738fSJack F Vogel 	if (ret_val)
16269d81738fSJack F Vogel 		goto out;
16279d81738fSJack F Vogel 
16289d81738fSJack F Vogel 	pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
16299d81738fSJack F Vogel 
16309d81738fSJack F Vogel 	ret_val = e1000_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
16319d81738fSJack F Vogel 	                                   &pcie_devctl2);
16329d81738fSJack F Vogel out:
16339d81738fSJack F Vogel 	/* disable completion timeout resend */
16349d81738fSJack F Vogel 	gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
16359d81738fSJack F Vogel 
16369d81738fSJack F Vogel 	E1000_WRITE_REG(hw, E1000_GCR, gcr);
16379d81738fSJack F Vogel 	return ret_val;
16389d81738fSJack F Vogel }
16399d81738fSJack F Vogel 
16404edd8523SJack F Vogel /**
16414edd8523SJack F Vogel  *  e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback
16424edd8523SJack F Vogel  *  @hw: pointer to the hardware struct
16434edd8523SJack F Vogel  *  @enable: state to enter, either enabled or disabled
16444edd8523SJack F Vogel  *
16454edd8523SJack F Vogel  *  enables/disables L2 switch loopback functionality.
16464edd8523SJack F Vogel  **/
16474edd8523SJack F Vogel void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
16484edd8523SJack F Vogel {
16494edd8523SJack F Vogel 	u32 dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
16504edd8523SJack F Vogel 
16514edd8523SJack F Vogel 	if (enable)
16524edd8523SJack F Vogel 		dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
16534edd8523SJack F Vogel 	else
16544edd8523SJack F Vogel 		dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
16554edd8523SJack F Vogel 
16564edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
16574edd8523SJack F Vogel }
16584edd8523SJack F Vogel 
16594edd8523SJack F Vogel /**
16604edd8523SJack F Vogel  *  e1000_vmdq_set_replication_pf - enable or disable vmdq replication
16614edd8523SJack F Vogel  *  @hw: pointer to the hardware struct
16624edd8523SJack F Vogel  *  @enable: state to enter, either enabled or disabled
16634edd8523SJack F Vogel  *
16644edd8523SJack F Vogel  *  enables/disables replication of packets across multiple pools.
16654edd8523SJack F Vogel  **/
16664edd8523SJack F Vogel void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
16674edd8523SJack F Vogel {
16684edd8523SJack F Vogel 	u32 vt_ctl = E1000_READ_REG(hw, E1000_VT_CTL);
16694edd8523SJack F Vogel 
16704edd8523SJack F Vogel 	if (enable)
16714edd8523SJack F Vogel 		vt_ctl |= E1000_VT_CTL_VM_REPL_EN;
16724edd8523SJack F Vogel 	else
16734edd8523SJack F Vogel 		vt_ctl &= ~E1000_VT_CTL_VM_REPL_EN;
16744edd8523SJack F Vogel 
16754edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_VT_CTL, vt_ctl);
16764edd8523SJack F Vogel }
16774edd8523SJack F Vogel 
16784edd8523SJack F Vogel /**
16794edd8523SJack F Vogel  *  e1000_read_phy_reg_82580 - Read 82580 MDI control register
16804edd8523SJack F Vogel  *  @hw: pointer to the HW structure
16814edd8523SJack F Vogel  *  @offset: register offset to be read
16824edd8523SJack F Vogel  *  @data: pointer to the read data
16834edd8523SJack F Vogel  *
16844edd8523SJack F Vogel  *  Reads the MDI control register in the PHY at offset and stores the
16854edd8523SJack F Vogel  *  information read to data.
16864edd8523SJack F Vogel  **/
16874edd8523SJack F Vogel static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data)
16884edd8523SJack F Vogel {
16894edd8523SJack F Vogel 	s32 ret_val;
16904edd8523SJack F Vogel 
16914edd8523SJack F Vogel 	DEBUGFUNC("e1000_read_phy_reg_82580");
16924edd8523SJack F Vogel 
16934edd8523SJack F Vogel 	ret_val = hw->phy.ops.acquire(hw);
16944edd8523SJack F Vogel 	if (ret_val)
16954edd8523SJack F Vogel 		goto out;
16964edd8523SJack F Vogel 
16974edd8523SJack F Vogel 	ret_val = e1000_read_phy_reg_mdic(hw, offset, data);
16984edd8523SJack F Vogel 
16994edd8523SJack F Vogel 	hw->phy.ops.release(hw);
17004edd8523SJack F Vogel 
17014edd8523SJack F Vogel out:
17024edd8523SJack F Vogel 	return ret_val;
17034edd8523SJack F Vogel }
17044edd8523SJack F Vogel 
17054edd8523SJack F Vogel /**
17064edd8523SJack F Vogel  *  e1000_write_phy_reg_82580 - Write 82580 MDI control register
17074edd8523SJack F Vogel  *  @hw: pointer to the HW structure
17084edd8523SJack F Vogel  *  @offset: register offset to write to
17094edd8523SJack F Vogel  *  @data: data to write to register at offset
17104edd8523SJack F Vogel  *
17114edd8523SJack F Vogel  *  Writes data to MDI control register in the PHY at offset.
17124edd8523SJack F Vogel  **/
17134edd8523SJack F Vogel static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data)
17144edd8523SJack F Vogel {
17154edd8523SJack F Vogel 	s32 ret_val;
17164edd8523SJack F Vogel 
17174edd8523SJack F Vogel 	DEBUGFUNC("e1000_write_phy_reg_82580");
17184edd8523SJack F Vogel 
17194edd8523SJack F Vogel 	ret_val = hw->phy.ops.acquire(hw);
17204edd8523SJack F Vogel 	if (ret_val)
17214edd8523SJack F Vogel 		goto out;
17224edd8523SJack F Vogel 
17234edd8523SJack F Vogel 	ret_val = e1000_write_phy_reg_mdic(hw, offset, data);
17244edd8523SJack F Vogel 
17254edd8523SJack F Vogel 	hw->phy.ops.release(hw);
17264edd8523SJack F Vogel 
17274edd8523SJack F Vogel out:
17284edd8523SJack F Vogel 	return ret_val;
17294edd8523SJack F Vogel }
1730a69ed8dfSJack F Vogel 
17314edd8523SJack F Vogel /**
17324edd8523SJack F Vogel  *  e1000_reset_hw_82580 - Reset hardware
17334edd8523SJack F Vogel  *  @hw: pointer to the HW structure
17344edd8523SJack F Vogel  *
17354edd8523SJack F Vogel  *  This resets function or entire device (all ports, etc.)
17364edd8523SJack F Vogel  *  to a known state.
17374edd8523SJack F Vogel  **/
17384edd8523SJack F Vogel static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
17394edd8523SJack F Vogel {
17404edd8523SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
17414edd8523SJack F Vogel 	/* BH SW mailbox bit in SW_FW_SYNC */
17424edd8523SJack F Vogel 	u16 swmbsw_mask = E1000_SW_SYNCH_MB;
17434edd8523SJack F Vogel 	u32 ctrl, icr;
17444edd8523SJack F Vogel 	bool global_device_reset = hw->dev_spec._82575.global_device_reset;
17454edd8523SJack F Vogel 
17464edd8523SJack F Vogel 	DEBUGFUNC("e1000_reset_hw_82580");
17474edd8523SJack F Vogel 
17484edd8523SJack F Vogel 	hw->dev_spec._82575.global_device_reset = FALSE;
17494edd8523SJack F Vogel 
17504edd8523SJack F Vogel 	/* Get current control state. */
17514edd8523SJack F Vogel 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
17524edd8523SJack F Vogel 
17534edd8523SJack F Vogel 	/*
17544edd8523SJack F Vogel 	 * Prevent the PCI-E bus from sticking if there is no TLP connection
17554edd8523SJack F Vogel 	 * on the last TLP read/write transaction when MAC is reset.
17564edd8523SJack F Vogel 	 */
17574edd8523SJack F Vogel 	ret_val = e1000_disable_pcie_master_generic(hw);
17584edd8523SJack F Vogel 	if (ret_val)
17594edd8523SJack F Vogel 		DEBUGOUT("PCI-E Master disable polling has failed.\n");
17604edd8523SJack F Vogel 
17614edd8523SJack F Vogel 	DEBUGOUT("Masking off all interrupts\n");
17624edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
17634edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_RCTL, 0);
17644edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
17654edd8523SJack F Vogel 	E1000_WRITE_FLUSH(hw);
17664edd8523SJack F Vogel 
17674edd8523SJack F Vogel 	msec_delay(10);
17684edd8523SJack F Vogel 
17694edd8523SJack F Vogel 	/* Determine whether or not a global dev reset is requested */
17704edd8523SJack F Vogel 	if (global_device_reset &&
17714edd8523SJack F Vogel 		e1000_acquire_swfw_sync_82575(hw, swmbsw_mask))
17724edd8523SJack F Vogel 			global_device_reset = FALSE;
17734edd8523SJack F Vogel 
17744edd8523SJack F Vogel 	if (global_device_reset &&
17754edd8523SJack F Vogel 		!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STAT_DEV_RST_SET))
17764edd8523SJack F Vogel 		ctrl |= E1000_CTRL_DEV_RST;
17774edd8523SJack F Vogel 	else
17784edd8523SJack F Vogel 		ctrl |= E1000_CTRL_RST;
17794edd8523SJack F Vogel 
17804edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
17814edd8523SJack F Vogel 
17824edd8523SJack F Vogel 	/* Add delay to insure DEV_RST has time to complete */
17834edd8523SJack F Vogel 	if (global_device_reset)
17844edd8523SJack F Vogel 		msec_delay(5);
17854edd8523SJack F Vogel 
17864edd8523SJack F Vogel 	ret_val = e1000_get_auto_rd_done_generic(hw);
17874edd8523SJack F Vogel 	if (ret_val) {
17884edd8523SJack F Vogel 		/*
17894edd8523SJack F Vogel 		 * When auto config read does not complete, do not
17904edd8523SJack F Vogel 		 * return with an error. This can happen in situations
17914edd8523SJack F Vogel 		 * where there is no eeprom and prevents getting link.
17924edd8523SJack F Vogel 		 */
17934edd8523SJack F Vogel 		DEBUGOUT("Auto Read Done did not complete\n");
17944edd8523SJack F Vogel 	}
17954edd8523SJack F Vogel 
17964edd8523SJack F Vogel 	/* If EEPROM is not present, run manual init scripts */
17974edd8523SJack F Vogel 	if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0)
17984edd8523SJack F Vogel 		e1000_reset_init_script_82575(hw);
17994edd8523SJack F Vogel 
18004edd8523SJack F Vogel 	/* clear global device reset status bit */
18014edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_STATUS, E1000_STAT_DEV_RST_SET);
18024edd8523SJack F Vogel 
18034edd8523SJack F Vogel 	/* Clear any pending interrupt events. */
18044edd8523SJack F Vogel 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
18054edd8523SJack F Vogel 	icr = E1000_READ_REG(hw, E1000_ICR);
18064edd8523SJack F Vogel 
18074edd8523SJack F Vogel 	/* Install any alternate MAC address into RAR0 */
18084edd8523SJack F Vogel 	ret_val = e1000_check_alt_mac_addr_generic(hw);
18094edd8523SJack F Vogel 
18104edd8523SJack F Vogel 	/* Release semaphore */
18114edd8523SJack F Vogel 	if (global_device_reset)
18124edd8523SJack F Vogel 		e1000_release_swfw_sync_82575(hw, swmbsw_mask);
18134edd8523SJack F Vogel 
18144edd8523SJack F Vogel 	return ret_val;
18154edd8523SJack F Vogel }
18164edd8523SJack F Vogel 
18174edd8523SJack F Vogel /**
18184edd8523SJack F Vogel  *  e1000_rxpbs_adjust_82580 - adjust RXPBS value to reflect actual RX PBA size
18194edd8523SJack F Vogel  *  @data: data received by reading RXPBS register
18204edd8523SJack F Vogel  *
18214edd8523SJack F Vogel  *  The 82580 uses a table based approach for packet buffer allocation sizes.
18224edd8523SJack F Vogel  *  This function converts the retrieved value into the correct table value
18234edd8523SJack F Vogel  *     0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
18244edd8523SJack F Vogel  *  0x0 36  72 144   1   2   4   8  16
18254edd8523SJack F Vogel  *  0x8 35  70 140 rsv rsv rsv rsv rsv
18264edd8523SJack F Vogel  */
18274edd8523SJack F Vogel u16 e1000_rxpbs_adjust_82580(u32 data)
18284edd8523SJack F Vogel {
18294edd8523SJack F Vogel 	u16 ret_val = 0;
18304edd8523SJack F Vogel 
18314edd8523SJack F Vogel 	if (data < E1000_82580_RXPBS_TABLE_SIZE)
18324edd8523SJack F Vogel 		ret_val = e1000_82580_rxpbs_table[data];
18334edd8523SJack F Vogel 
18344edd8523SJack F Vogel 	return ret_val;
18354edd8523SJack F Vogel }
1836