163b3bba8SJerry Jelinek /******************************************************************************
263b3bba8SJerry Jelinek 
3*dc0cb1cdSDale Ghent   Copyright (c) 2001-2015, Intel Corporation
463b3bba8SJerry Jelinek   All rights reserved.
563b3bba8SJerry Jelinek 
663b3bba8SJerry Jelinek   Redistribution and use in source and binary forms, with or without
763b3bba8SJerry Jelinek   modification, are permitted provided that the following conditions are met:
863b3bba8SJerry Jelinek 
963b3bba8SJerry Jelinek    1. Redistributions of source code must retain the above copyright notice,
1063b3bba8SJerry Jelinek       this list of conditions and the following disclaimer.
1163b3bba8SJerry Jelinek 
1263b3bba8SJerry Jelinek    2. Redistributions in binary form must reproduce the above copyright
1363b3bba8SJerry Jelinek       notice, this list of conditions and the following disclaimer in the
1463b3bba8SJerry Jelinek       documentation and/or other materials provided with the distribution.
1563b3bba8SJerry Jelinek 
1663b3bba8SJerry Jelinek    3. Neither the name of the Intel Corporation nor the names of its
1763b3bba8SJerry Jelinek       contributors may be used to endorse or promote products derived from
1863b3bba8SJerry Jelinek       this software without specific prior written permission.
1963b3bba8SJerry Jelinek 
2063b3bba8SJerry Jelinek   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2163b3bba8SJerry Jelinek   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2263b3bba8SJerry Jelinek   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2363b3bba8SJerry Jelinek   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2463b3bba8SJerry Jelinek   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2563b3bba8SJerry Jelinek   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2663b3bba8SJerry Jelinek   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2763b3bba8SJerry Jelinek   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2863b3bba8SJerry Jelinek   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2963b3bba8SJerry Jelinek   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3063b3bba8SJerry Jelinek   POSSIBILITY OF SUCH DAMAGE.
3163b3bba8SJerry Jelinek 
3263b3bba8SJerry Jelinek ******************************************************************************/
33*dc0cb1cdSDale Ghent /*$FreeBSD$*/
349da57d7bSbt 
359da57d7bSbt #include "ixgbe_type.h"
3669b5a878SDan McDonald #include "ixgbe_82598.h"
379da57d7bSbt #include "ixgbe_api.h"
389da57d7bSbt #include "ixgbe_common.h"
399da57d7bSbt #include "ixgbe_phy.h"
409da57d7bSbt 
41*dc0cb1cdSDale Ghent #define IXGBE_82598_MAX_TX_QUEUES 32
42*dc0cb1cdSDale Ghent #define IXGBE_82598_MAX_RX_QUEUES 64
43*dc0cb1cdSDale Ghent #define IXGBE_82598_RAR_ENTRIES   16
44*dc0cb1cdSDale Ghent #define IXGBE_82598_MC_TBL_SIZE  128
45*dc0cb1cdSDale Ghent #define IXGBE_82598_VFT_TBL_SIZE 128
46*dc0cb1cdSDale Ghent #define IXGBE_82598_RX_PB_SIZE   512
47*dc0cb1cdSDale Ghent 
4813740cb2SPaul Guo static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
4969b5a878SDan McDonald 					     ixgbe_link_speed *speed,
5069b5a878SDan McDonald 					     bool *autoneg);
5113740cb2SPaul Guo static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw);
523cfa0eb9Schenlu chen - Sun Microsystems - Beijing China static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
5369b5a878SDan McDonald 				      bool autoneg_wait_to_complete);
5413740cb2SPaul Guo static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
5569b5a878SDan McDonald 				      ixgbe_link_speed *speed, bool *link_up,
5669b5a878SDan McDonald 				      bool link_up_wait_to_complete);
573cfa0eb9Schenlu chen - Sun Microsystems - Beijing China static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
5869b5a878SDan McDonald 				      ixgbe_link_speed speed,
5969b5a878SDan McDonald 				      bool autoneg_wait_to_complete);
603cfa0eb9Schenlu chen - Sun Microsystems - Beijing China static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
6169b5a878SDan McDonald 					 ixgbe_link_speed speed,
6269b5a878SDan McDonald 					 bool autoneg_wait_to_complete);
6313740cb2SPaul Guo static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
6413740cb2SPaul Guo static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
6513740cb2SPaul Guo static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw);
6669b5a878SDan McDonald static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
6769b5a878SDan McDonald 				  u32 headroom, int strategy);
68*dc0cb1cdSDale Ghent static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
69*dc0cb1cdSDale Ghent 					u8 *sff8472_data);
7063b3bba8SJerry Jelinek /**
7163b3bba8SJerry Jelinek  *  ixgbe_set_pcie_completion_timeout - set pci-e completion timeout
7263b3bba8SJerry Jelinek  *  @hw: pointer to the HW structure
733cfa0eb9Schenlu chen - Sun Microsystems - Beijing China  *
7463b3bba8SJerry Jelinek  *  The defaults for 82598 should be in the range of 50us to 50ms,
7563b3bba8SJerry Jelinek  *  however the hardware default for these parts is 500us to 1ms which is less
7663b3bba8SJerry Jelinek  *  than the 10ms recommended by the pci-e spec.  To address this we need to
7763b3bba8SJerry Jelinek  *  increase the value to either 10ms to 250ms for capability version 1 config,
7863b3bba8SJerry Jelinek  *  or 16ms to 55ms for version 2.
7963b3bba8SJerry Jelinek  **/
8063b3bba8SJerry Jelinek void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
813cfa0eb9Schenlu chen - Sun Microsystems - Beijing China {
823cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR);
833cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	u16 pcie_devctl2;
843cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
853cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	/* only take action if timeout value is defaulted to 0 */
863cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK)
873cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		goto out;
883cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
893cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	/*
903cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 * if capababilities version is type 1 we can write the
913cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 * timeout of 10ms to 250ms through the GCR register
923cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 */
933cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	if (!(gcr & IXGBE_GCR_CAP_VER2)) {
943cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		gcr |= IXGBE_GCR_CMPL_TMOUT_10ms;
953cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		goto out;
963cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	}
973cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
983cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	/*
993cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 * for version 2 capabilities we need to write the config space
1003cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 * directly in order to set the completion timeout value for
1013cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 * 16ms to 55ms
1023cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 */
1033cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	pcie_devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2);
1043cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms;
1053cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	IXGBE_WRITE_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2);
1063cfa0eb9Schenlu chen - Sun Microsystems - Beijing China out:
1073cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	/* disable completion timeout resend */
1083cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	gcr &= ~IXGBE_GCR_CMPL_TMOUT_RESEND;
1093cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	IXGBE_WRITE_REG(hw, IXGBE_GCR, gcr);
1103cfa0eb9Schenlu chen - Sun Microsystems - Beijing China }
11173cd555cSBin Tu - Sun Microsystems - Beijing China 
11263b3bba8SJerry Jelinek /**
11363b3bba8SJerry Jelinek  *  ixgbe_init_ops_82598 - Inits func ptrs and MAC type
11463b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
1159da57d7bSbt  *
11663b3bba8SJerry Jelinek  *  Initialize the function pointers and assign the MAC type for 82598.
11763b3bba8SJerry Jelinek  *  Does not touch the hardware.
11863b3bba8SJerry Jelinek  **/
11963b3bba8SJerry Jelinek s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw)
1209da57d7bSbt {
1219da57d7bSbt 	struct ixgbe_mac_info *mac = &hw->mac;
12213740cb2SPaul Guo 	struct ixgbe_phy_info *phy = &hw->phy;
12373cd555cSBin Tu - Sun Microsystems - Beijing China 	s32 ret_val;
1249da57d7bSbt 
1253cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_init_ops_82598");
1263cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
12773cd555cSBin Tu - Sun Microsystems - Beijing China 	ret_val = ixgbe_init_phy_ops_generic(hw);
12873cd555cSBin Tu - Sun Microsystems - Beijing China 	ret_val = ixgbe_init_ops_generic(hw);
12973cd555cSBin Tu - Sun Microsystems - Beijing China 
13073cd555cSBin Tu - Sun Microsystems - Beijing China 	/* PHY */
131*dc0cb1cdSDale Ghent 	phy->ops.init = ixgbe_init_phy_ops_82598;
1329da57d7bSbt 
1339da57d7bSbt 	/* MAC */
134*dc0cb1cdSDale Ghent 	mac->ops.start_hw = ixgbe_start_hw_82598;
135*dc0cb1cdSDale Ghent 	mac->ops.enable_relaxed_ordering = ixgbe_enable_relaxed_ordering_82598;
136*dc0cb1cdSDale Ghent 	mac->ops.reset_hw = ixgbe_reset_hw_82598;
137*dc0cb1cdSDale Ghent 	mac->ops.get_media_type = ixgbe_get_media_type_82598;
13813740cb2SPaul Guo 	mac->ops.get_supported_physical_layer =
139*dc0cb1cdSDale Ghent 				ixgbe_get_supported_physical_layer_82598;
140*dc0cb1cdSDale Ghent 	mac->ops.read_analog_reg8 = ixgbe_read_analog_reg8_82598;
141*dc0cb1cdSDale Ghent 	mac->ops.write_analog_reg8 = ixgbe_write_analog_reg8_82598;
142*dc0cb1cdSDale Ghent 	mac->ops.set_lan_id = ixgbe_set_lan_id_multi_port_pcie_82598;
143*dc0cb1cdSDale Ghent 	mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_82598;
1449da57d7bSbt 
1459da57d7bSbt 	/* RAR, Multicast, VLAN */
146*dc0cb1cdSDale Ghent 	mac->ops.set_vmdq = ixgbe_set_vmdq_82598;
147*dc0cb1cdSDale Ghent 	mac->ops.clear_vmdq = ixgbe_clear_vmdq_82598;
148*dc0cb1cdSDale Ghent 	mac->ops.set_vfta = ixgbe_set_vfta_82598;
14969b5a878SDan McDonald 	mac->ops.set_vlvf = NULL;
150*dc0cb1cdSDale Ghent 	mac->ops.clear_vfta = ixgbe_clear_vfta_82598;
1519da57d7bSbt 
1529da57d7bSbt 	/* Flow Control */
153*dc0cb1cdSDale Ghent 	mac->ops.fc_enable = ixgbe_fc_enable_82598;
154*dc0cb1cdSDale Ghent 
155*dc0cb1cdSDale Ghent 	mac->mcft_size		= IXGBE_82598_MC_TBL_SIZE;
156*dc0cb1cdSDale Ghent 	mac->vft_size		= IXGBE_82598_VFT_TBL_SIZE;
157*dc0cb1cdSDale Ghent 	mac->num_rar_entries	= IXGBE_82598_RAR_ENTRIES;
158*dc0cb1cdSDale Ghent 	mac->rx_pb_size		= IXGBE_82598_RX_PB_SIZE;
159*dc0cb1cdSDale Ghent 	mac->max_rx_queues	= IXGBE_82598_MAX_RX_QUEUES;
160*dc0cb1cdSDale Ghent 	mac->max_tx_queues	= IXGBE_82598_MAX_TX_QUEUES;
16169b5a878SDan McDonald 	mac->max_msix_vectors	= ixgbe_get_pcie_msix_count_generic(hw);
1629da57d7bSbt 
16313740cb2SPaul Guo 	/* SFP+ Module */
164*dc0cb1cdSDale Ghent 	phy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_82598;
165*dc0cb1cdSDale Ghent 	phy->ops.read_i2c_sff8472 = ixgbe_read_i2c_sff8472_82598;
16613740cb2SPaul Guo 
16773cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Link */
168*dc0cb1cdSDale Ghent 	mac->ops.check_link = ixgbe_check_mac_link_82598;
169*dc0cb1cdSDale Ghent 	mac->ops.setup_link = ixgbe_setup_mac_link_82598;
1705b6dd21fSchenlu chen - Sun Microsystems - Beijing China 	mac->ops.flap_tx_laser = NULL;
171*dc0cb1cdSDale Ghent 	mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_82598;
172*dc0cb1cdSDale Ghent 	mac->ops.setup_rxpba = ixgbe_set_rxpba_82598;
17369b5a878SDan McDonald 
17469b5a878SDan McDonald 	/* Manageability interface */
17569b5a878SDan McDonald 	mac->ops.set_fw_drv_ver = NULL;
17673cd555cSBin Tu - Sun Microsystems - Beijing China 
177*dc0cb1cdSDale Ghent 	mac->ops.get_rtrup2tc = NULL;
178*dc0cb1cdSDale Ghent 
17963b3bba8SJerry Jelinek 	return ret_val;
18073cd555cSBin Tu - Sun Microsystems - Beijing China }
18173cd555cSBin Tu - Sun Microsystems - Beijing China 
18263b3bba8SJerry Jelinek /**
18363b3bba8SJerry Jelinek  *  ixgbe_init_phy_ops_82598 - PHY/SFP specific init
18463b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
18573cd555cSBin Tu - Sun Microsystems - Beijing China  *
18663b3bba8SJerry Jelinek  *  Initialize any function pointers that were not able to be
18763b3bba8SJerry Jelinek  *  set during init_shared_code because the PHY/SFP type was
18863b3bba8SJerry Jelinek  *  not known.  Perform the SFP init if necessary.
18973cd555cSBin Tu - Sun Microsystems - Beijing China  *
19063b3bba8SJerry Jelinek  **/
19163b3bba8SJerry Jelinek s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
19273cd555cSBin Tu - Sun Microsystems - Beijing China {
19373cd555cSBin Tu - Sun Microsystems - Beijing China 	struct ixgbe_mac_info *mac = &hw->mac;
19473cd555cSBin Tu - Sun Microsystems - Beijing China 	struct ixgbe_phy_info *phy = &hw->phy;
19573cd555cSBin Tu - Sun Microsystems - Beijing China 	s32 ret_val = IXGBE_SUCCESS;
19673cd555cSBin Tu - Sun Microsystems - Beijing China 	u16 list_offset, data_offset;
19773cd555cSBin Tu - Sun Microsystems - Beijing China 
1983cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_init_phy_ops_82598");
1993cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
20073cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Identify the PHY */
20173cd555cSBin Tu - Sun Microsystems - Beijing China 	phy->ops.identify(hw);
20273cd555cSBin Tu - Sun Microsystems - Beijing China 
20373cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Overwrite the link function pointers if copper PHY */
20473cd555cSBin Tu - Sun Microsystems - Beijing China 	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
205*dc0cb1cdSDale Ghent 		mac->ops.setup_link = ixgbe_setup_copper_link_82598;
20673cd555cSBin Tu - Sun Microsystems - Beijing China 		mac->ops.get_link_capabilities =
207*dc0cb1cdSDale Ghent 				ixgbe_get_copper_link_capabilities_generic;
20873cd555cSBin Tu - Sun Microsystems - Beijing China 	}
20973cd555cSBin Tu - Sun Microsystems - Beijing China 
21013740cb2SPaul Guo 	switch (hw->phy.type) {
21113740cb2SPaul Guo 	case ixgbe_phy_tn:
212*dc0cb1cdSDale Ghent 		phy->ops.setup_link = ixgbe_setup_phy_link_tnx;
213*dc0cb1cdSDale Ghent 		phy->ops.check_link = ixgbe_check_phy_link_tnx;
21413740cb2SPaul Guo 		phy->ops.get_firmware_version =
215*dc0cb1cdSDale Ghent 					ixgbe_get_phy_firmware_version_tnx;
216185c5677SPaul Guo 		break;
21713740cb2SPaul Guo 	case ixgbe_phy_nl:
218*dc0cb1cdSDale Ghent 		phy->ops.reset = ixgbe_reset_phy_nl;
21913740cb2SPaul Guo 
22013740cb2SPaul Guo 		/* Call SFP+ identify routine to get the SFP+ module type */
22113740cb2SPaul Guo 		ret_val = phy->ops.identify_sfp(hw);
22213740cb2SPaul Guo 		if (ret_val != IXGBE_SUCCESS)
22313740cb2SPaul Guo 			goto out;
22413740cb2SPaul Guo 		else if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) {
22513740cb2SPaul Guo 			ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
22613740cb2SPaul Guo 			goto out;
22713740cb2SPaul Guo 		}
22813740cb2SPaul Guo 
22913740cb2SPaul Guo 		/* Check to see if SFP+ module is supported */
23013740cb2SPaul Guo 		ret_val = ixgbe_get_sfp_init_sequence_offsets(hw,
23169b5a878SDan McDonald 							      &list_offset,
23269b5a878SDan McDonald 							      &data_offset);
23313740cb2SPaul Guo 		if (ret_val != IXGBE_SUCCESS) {
23413740cb2SPaul Guo 			ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
23513740cb2SPaul Guo 			goto out;
23613740cb2SPaul Guo 		}
23713740cb2SPaul Guo 		break;
23813740cb2SPaul Guo 	default:
23913740cb2SPaul Guo 		break;
24013740cb2SPaul Guo 	}
24163b3bba8SJerry Jelinek 
24213740cb2SPaul Guo out:
24363b3bba8SJerry Jelinek 	return ret_val;
2449da57d7bSbt }
2459da57d7bSbt 
24663b3bba8SJerry Jelinek /**
24763b3bba8SJerry Jelinek  *  ixgbe_start_hw_82598 - Prepare hardware for Tx/Rx
24863b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
24963b3bba8SJerry Jelinek  *
25063b3bba8SJerry Jelinek  *  Starts the hardware using the generic start_hw function.
25163b3bba8SJerry Jelinek  *  Disables relaxed ordering Then set pcie completion timeout
2523cfa0eb9Schenlu chen - Sun Microsystems - Beijing China  *
25363b3bba8SJerry Jelinek  **/
25463b3bba8SJerry Jelinek s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
2553cfa0eb9Schenlu chen - Sun Microsystems - Beijing China {
25619843f01SPaul Guo 	u32 regval;
25719843f01SPaul Guo 	u32 i;
2583cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	s32 ret_val = IXGBE_SUCCESS;
2593cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
2603cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_start_hw_82598");
2613cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
2623cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	ret_val = ixgbe_start_hw_generic(hw);
263*dc0cb1cdSDale Ghent 	if (ret_val)
264*dc0cb1cdSDale Ghent 		return ret_val;
2653cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
26663b3bba8SJerry Jelinek 	/* Disable relaxed ordering */
26719843f01SPaul Guo 	for (i = 0; ((i < hw->mac.max_tx_queues) &&
26863b3bba8SJerry Jelinek 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
26919843f01SPaul Guo 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
27069b5a878SDan McDonald 		regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
27119843f01SPaul Guo 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
27219843f01SPaul Guo 	}
27319843f01SPaul Guo 
27419843f01SPaul Guo 	for (i = 0; ((i < hw->mac.max_rx_queues) &&
27563b3bba8SJerry Jelinek 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
27619843f01SPaul Guo 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
27769b5a878SDan McDonald 		regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
27869b5a878SDan McDonald 			    IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
27919843f01SPaul Guo 		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
28019843f01SPaul Guo 	}
28119843f01SPaul Guo 
2823cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	/* set the completion timeout for interface */
283*dc0cb1cdSDale Ghent 	ixgbe_set_pcie_completion_timeout(hw);
2843cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
28563b3bba8SJerry Jelinek 	return ret_val;
2863cfa0eb9Schenlu chen - Sun Microsystems - Beijing China }
2873cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
28863b3bba8SJerry Jelinek /**
28963b3bba8SJerry Jelinek  *  ixgbe_get_link_capabilities_82598 - Determines link capabilities
29063b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
29163b3bba8SJerry Jelinek  *  @speed: pointer to link speed
29263b3bba8SJerry Jelinek  *  @autoneg: boolean auto-negotiation value
2939da57d7bSbt  *
29463b3bba8SJerry Jelinek  *  Determines the link capabilities by reading the AUTOC register.
29563b3bba8SJerry Jelinek  **/
29663b3bba8SJerry Jelinek static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
29769b5a878SDan McDonald 					     ixgbe_link_speed *speed,
29869b5a878SDan McDonald 					     bool *autoneg)
2999da57d7bSbt {
3009da57d7bSbt 	s32 status = IXGBE_SUCCESS;
30173cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 autoc = 0;
3029da57d7bSbt 
3033cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_get_link_capabilities_82598");
3043cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
30573cd555cSBin Tu - Sun Microsystems - Beijing China 	/*
30673cd555cSBin Tu - Sun Microsystems - Beijing China 	 * Determine link capabilities based on the stored value of AUTOC,
30773cd555cSBin Tu - Sun Microsystems - Beijing China 	 * which represents EEPROM defaults.  If AUTOC value has not been
30873cd555cSBin Tu - Sun Microsystems - Beijing China 	 * stored, use the current register value.
30973cd555cSBin Tu - Sun Microsystems - Beijing China 	 */
31073cd555cSBin Tu - Sun Microsystems - Beijing China 	if (hw->mac.orig_link_settings_stored)
31173cd555cSBin Tu - Sun Microsystems - Beijing China 		autoc = hw->mac.orig_autoc;
31273cd555cSBin Tu - Sun Microsystems - Beijing China 	else
31373cd555cSBin Tu - Sun Microsystems - Beijing China 		autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
3149da57d7bSbt 
31573cd555cSBin Tu - Sun Microsystems - Beijing China 	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
3169da57d7bSbt 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
3179da57d7bSbt 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
31863b3bba8SJerry Jelinek 		*autoneg = FALSE;
3199da57d7bSbt 		break;
3209da57d7bSbt 
3219da57d7bSbt 	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
3229da57d7bSbt 		*speed = IXGBE_LINK_SPEED_10GB_FULL;
32363b3bba8SJerry Jelinek 		*autoneg = FALSE;
3249da57d7bSbt 		break;
3259da57d7bSbt 
3269da57d7bSbt 	case IXGBE_AUTOC_LMS_1G_AN:
3279da57d7bSbt 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
32863b3bba8SJerry Jelinek 		*autoneg = TRUE;
3299da57d7bSbt 		break;
3309da57d7bSbt 
3319da57d7bSbt 	case IXGBE_AUTOC_LMS_KX4_AN:
3329da57d7bSbt 	case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
3339da57d7bSbt 		*speed = IXGBE_LINK_SPEED_UNKNOWN;
33473cd555cSBin Tu - Sun Microsystems - Beijing China 		if (autoc & IXGBE_AUTOC_KX4_SUPP)
3359da57d7bSbt 			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
33673cd555cSBin Tu - Sun Microsystems - Beijing China 		if (autoc & IXGBE_AUTOC_KX_SUPP)
3379da57d7bSbt 			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
33863b3bba8SJerry Jelinek 		*autoneg = TRUE;
3399da57d7bSbt 		break;
3409da57d7bSbt 
3419da57d7bSbt 	default:
3429da57d7bSbt 		status = IXGBE_ERR_LINK_SETUP;
3439da57d7bSbt 		break;
3449da57d7bSbt 	}
3459da57d7bSbt 
34663b3bba8SJerry Jelinek 	return status;
3479da57d7bSbt }
3489da57d7bSbt 
34963b3bba8SJerry Jelinek /**
35063b3bba8SJerry Jelinek  *  ixgbe_get_media_type_82598 - Determines media type
35163b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
3529da57d7bSbt  *
35363b3bba8SJerry Jelinek  *  Returns the media type (fiber, copper, backplane)
35463b3bba8SJerry Jelinek  **/
35563b3bba8SJerry Jelinek static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
3569da57d7bSbt {
3579da57d7bSbt 	enum ixgbe_media_type media_type;
3589da57d7bSbt 
3593cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_get_media_type_82598");
3603cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
36173cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Detect if there is a copper PHY attached. */
36263b3bba8SJerry Jelinek 	switch (hw->phy.type) {
36363b3bba8SJerry Jelinek 	case ixgbe_phy_cu_unknown:
36463b3bba8SJerry Jelinek 	case ixgbe_phy_tn:
36573cd555cSBin Tu - Sun Microsystems - Beijing China 		media_type = ixgbe_media_type_copper;
36673cd555cSBin Tu - Sun Microsystems - Beijing China 		goto out;
36763b3bba8SJerry Jelinek 	default:
36863b3bba8SJerry Jelinek 		break;
36973cd555cSBin Tu - Sun Microsystems - Beijing China 	}
37073cd555cSBin Tu - Sun Microsystems - Beijing China 
3719da57d7bSbt 	/* Media type for I82598 is based on device ID */
3729da57d7bSbt 	switch (hw->device_id) {
37373cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598:
37473cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598_BX:
37573cd555cSBin Tu - Sun Microsystems - Beijing China 		/* Default device ID is mezzanine card KX/KX4 */
37673cd555cSBin Tu - Sun Microsystems - Beijing China 		media_type = ixgbe_media_type_backplane;
37773cd555cSBin Tu - Sun Microsystems - Beijing China 		break;
3789da57d7bSbt 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
3799da57d7bSbt 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
38013740cb2SPaul Guo 	case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
38113740cb2SPaul Guo 	case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
3829da57d7bSbt 	case IXGBE_DEV_ID_82598EB_XF_LR:
38313740cb2SPaul Guo 	case IXGBE_DEV_ID_82598EB_SFP_LOM:
3849da57d7bSbt 		media_type = ixgbe_media_type_fiber;
3859da57d7bSbt 		break;
3863cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598EB_CX4:
3873cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
3883cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		media_type = ixgbe_media_type_cx4;
3893cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		break;
39013740cb2SPaul Guo 	case IXGBE_DEV_ID_82598AT:
3913cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598AT2:
39213740cb2SPaul Guo 		media_type = ixgbe_media_type_copper;
39313740cb2SPaul Guo 		break;
3949da57d7bSbt 	default:
3959da57d7bSbt 		media_type = ixgbe_media_type_unknown;
3969da57d7bSbt 		break;
3979da57d7bSbt 	}
39873cd555cSBin Tu - Sun Microsystems - Beijing China out:
39963b3bba8SJerry Jelinek 	return media_type;
4009da57d7bSbt }
4019da57d7bSbt 
40263b3bba8SJerry Jelinek /**
40363b3bba8SJerry Jelinek  *  ixgbe_fc_enable_82598 - Enable flow control
40463b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
4059da57d7bSbt  *
40663b3bba8SJerry Jelinek  *  Enable flow control according to the current settings.
40763b3bba8SJerry Jelinek  **/
40869b5a878SDan McDonald s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
4099da57d7bSbt {
41073cd555cSBin Tu - Sun Microsystems - Beijing China 	s32 ret_val = IXGBE_SUCCESS;
41173cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 fctrl_reg;
4129da57d7bSbt 	u32 rmcs_reg;
41373cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 reg;
41469b5a878SDan McDonald 	u32 fcrtl, fcrth;
41519843f01SPaul Guo 	u32 link_speed = 0;
41669b5a878SDan McDonald 	int i;
41719843f01SPaul Guo 	bool link_up;
4189da57d7bSbt 
41973cd555cSBin Tu - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_fc_enable_82598");
42073cd555cSBin Tu - Sun Microsystems - Beijing China 
42169b5a878SDan McDonald 	/* Validate the water mark configuration */
42269b5a878SDan McDonald 	if (!hw->fc.pause_time) {
42369b5a878SDan McDonald 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
42469b5a878SDan McDonald 		goto out;
42569b5a878SDan McDonald 	}
42669b5a878SDan McDonald 
42769b5a878SDan McDonald 	/* Low water mark of zero causes XOFF floods */
42869b5a878SDan McDonald 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
42969b5a878SDan McDonald 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
43069b5a878SDan McDonald 		    hw->fc.high_water[i]) {
43169b5a878SDan McDonald 			if (!hw->fc.low_water[i] ||
43269b5a878SDan McDonald 			    hw->fc.low_water[i] >= hw->fc.high_water[i]) {
43369b5a878SDan McDonald 				DEBUGOUT("Invalid water mark configuration\n");
43469b5a878SDan McDonald 				ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
43569b5a878SDan McDonald 				goto out;
43669b5a878SDan McDonald 			}
43769b5a878SDan McDonald 		}
43869b5a878SDan McDonald 	}
43969b5a878SDan McDonald 
44019843f01SPaul Guo 	/*
4415b6dd21fSchenlu chen - Sun Microsystems - Beijing China 	 * On 82598 having Rx FC on causes resets while doing 1G
4425b6dd21fSchenlu chen - Sun Microsystems - Beijing China 	 * so if it's on turn it off once we know link_speed. For
4435b6dd21fSchenlu chen - Sun Microsystems - Beijing China 	 * more details see 82598 Specification update.
44419843f01SPaul Guo 	 */
44563b3bba8SJerry Jelinek 	hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
4465b6dd21fSchenlu chen - Sun Microsystems - Beijing China 	if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) {
4475b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		switch (hw->fc.requested_mode) {
4485b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		case ixgbe_fc_full:
4495b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			hw->fc.requested_mode = ixgbe_fc_tx_pause;
4505b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			break;
4515b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		case ixgbe_fc_rx_pause:
4525b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			hw->fc.requested_mode = ixgbe_fc_none;
4535b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			break;
4545b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		default:
4555b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			/* no change */
4565b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			break;
4575b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		}
45819843f01SPaul Guo 	}
45919843f01SPaul Guo 
46073cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Negotiate the fc mode to use */
46169b5a878SDan McDonald 	ixgbe_fc_autoneg(hw);
4629da57d7bSbt 
46373cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Disable any previous flow control settings */
46473cd555cSBin Tu - Sun Microsystems - Beijing China 	fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
46573cd555cSBin Tu - Sun Microsystems - Beijing China 	fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
4669da57d7bSbt 
4679da57d7bSbt 	rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
4689da57d7bSbt 	rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
4699da57d7bSbt 
4709da57d7bSbt 	/*
47173cd555cSBin Tu - Sun Microsystems - Beijing China 	 * The possible values of fc.current_mode are:
4729da57d7bSbt 	 * 0: Flow control is completely disabled
47373cd555cSBin Tu - Sun Microsystems - Beijing China 	 * 1: Rx flow control is enabled (we can receive pause frames,
47473cd555cSBin Tu - Sun Microsystems - Beijing China 	 *    but not send pause frames).
47573cd555cSBin Tu - Sun Microsystems - Beijing China 	 * 2: Tx flow control is enabled (we can send pause frames but
47663b3bba8SJerry Jelinek 	 *     we do not support receiving pause frames).
4779da57d7bSbt 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
4789da57d7bSbt 	 * other: Invalid.
4799da57d7bSbt 	 */
48073cd555cSBin Tu - Sun Microsystems - Beijing China 	switch (hw->fc.current_mode) {
4819da57d7bSbt 	case ixgbe_fc_none:
48273cd555cSBin Tu - Sun Microsystems - Beijing China 		/*
48373cd555cSBin Tu - Sun Microsystems - Beijing China 		 * Flow control is disabled by software override or autoneg.
48473cd555cSBin Tu - Sun Microsystems - Beijing China 		 * The code below will actually disable it in the HW.
48573cd555cSBin Tu - Sun Microsystems - Beijing China 		 */
4869da57d7bSbt 		break;
4879da57d7bSbt 	case ixgbe_fc_rx_pause:
4889da57d7bSbt 		/*
48973cd555cSBin Tu - Sun Microsystems - Beijing China 		 * Rx Flow control is enabled and Tx Flow control is
49073cd555cSBin Tu - Sun Microsystems - Beijing China 		 * disabled by software override. Since there really
49173cd555cSBin Tu - Sun Microsystems - Beijing China 		 * isn't a way to advertise that we are capable of RX
49273cd555cSBin Tu - Sun Microsystems - Beijing China 		 * Pause ONLY, we will advertise that we support both
49373cd555cSBin Tu - Sun Microsystems - Beijing China 		 * symmetric and asymmetric Rx PAUSE.  Later, we will
49473cd555cSBin Tu - Sun Microsystems - Beijing China 		 * disable the adapter's ability to send PAUSE frames.
4959da57d7bSbt 		 */
49673cd555cSBin Tu - Sun Microsystems - Beijing China 		fctrl_reg |= IXGBE_FCTRL_RFCE;
4979da57d7bSbt 		break;
4989da57d7bSbt 	case ixgbe_fc_tx_pause:
4999da57d7bSbt 		/*
50073cd555cSBin Tu - Sun Microsystems - Beijing China 		 * Tx Flow control is enabled, and Rx Flow control is
50173cd555cSBin Tu - Sun Microsystems - Beijing China 		 * disabled by software override.
5029da57d7bSbt 		 */
5039da57d7bSbt 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
5049da57d7bSbt 		break;
5059da57d7bSbt 	case ixgbe_fc_full:
50673cd555cSBin Tu - Sun Microsystems - Beijing China 		/* Flow control (both Rx and Tx) is enabled by SW override. */
50773cd555cSBin Tu - Sun Microsystems - Beijing China 		fctrl_reg |= IXGBE_FCTRL_RFCE;
5089da57d7bSbt 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
5099da57d7bSbt 		break;
5109da57d7bSbt 	default:
5119da57d7bSbt 		DEBUGOUT("Flow control param set incorrectly\n");
5123cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		ret_val = IXGBE_ERR_CONFIG;
51373cd555cSBin Tu - Sun Microsystems - Beijing China 		goto out;
514*dc0cb1cdSDale Ghent 		break;
5159da57d7bSbt 	}
5169da57d7bSbt 
51773cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Set 802.3x based flow control settings. */
51873cd555cSBin Tu - Sun Microsystems - Beijing China 	fctrl_reg |= IXGBE_FCTRL_DPF;
51973cd555cSBin Tu - Sun Microsystems - Beijing China 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
5209da57d7bSbt 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
5219da57d7bSbt 
52273cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
52369b5a878SDan McDonald 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
52469b5a878SDan McDonald 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
52569b5a878SDan McDonald 		    hw->fc.high_water[i]) {
52669b5a878SDan McDonald 			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
52769b5a878SDan McDonald 			fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
52869b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
52969b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth);
53069b5a878SDan McDonald 		} else {
53169b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
53269b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
53369b5a878SDan McDonald 		}
53463b3bba8SJerry Jelinek 
5359da57d7bSbt 	}
5369da57d7bSbt 
53773cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Configure pause time (2 TCs per register) */
53869b5a878SDan McDonald 	reg = hw->fc.pause_time * 0x00010001;
53969b5a878SDan McDonald 	for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
54069b5a878SDan McDonald 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
54173cd555cSBin Tu - Sun Microsystems - Beijing China 
54269b5a878SDan McDonald 	/* Configure flow control refresh threshold value */
54369b5a878SDan McDonald 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
5449da57d7bSbt 
54573cd555cSBin Tu - Sun Microsystems - Beijing China out:
54663b3bba8SJerry Jelinek 	return ret_val;
5479da57d7bSbt }
5489da57d7bSbt 
54963b3bba8SJerry Jelinek /**
55063b3bba8SJerry Jelinek  *  ixgbe_start_mac_link_82598 - Configures MAC link settings
55163b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
5529da57d7bSbt  *
55363b3bba8SJerry Jelinek  *  Configures link settings based on values in the ixgbe_hw struct.
55463b3bba8SJerry Jelinek  *  Restarts the link.  Performs autonegotiation if needed.
55563b3bba8SJerry Jelinek  **/
55663b3bba8SJerry Jelinek static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
55769b5a878SDan McDonald 				      bool autoneg_wait_to_complete)
5589da57d7bSbt {
5599da57d7bSbt 	u32 autoc_reg;
5609da57d7bSbt 	u32 links_reg;
5619da57d7bSbt 	u32 i;
5629da57d7bSbt 	s32 status = IXGBE_SUCCESS;
5639da57d7bSbt 
5643cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_start_mac_link_82598");
5653cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
5669da57d7bSbt 	/* Restart link */
56773cd555cSBin Tu - Sun Microsystems - Beijing China 	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
5689da57d7bSbt 	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
5699da57d7bSbt 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
5709da57d7bSbt 
5719da57d7bSbt 	/* Only poll for autoneg to complete if specified to do so */
5723cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	if (autoneg_wait_to_complete) {
57373cd555cSBin Tu - Sun Microsystems - Beijing China 		if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
57463b3bba8SJerry Jelinek 		     IXGBE_AUTOC_LMS_KX4_AN ||
57573cd555cSBin Tu - Sun Microsystems - Beijing China 		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
57663b3bba8SJerry Jelinek 		     IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
5779da57d7bSbt 			links_reg = 0; /* Just in case Autoneg time = 0 */
5789da57d7bSbt 			for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
5799da57d7bSbt 				links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
5809da57d7bSbt 				if (links_reg & IXGBE_LINKS_KX_AN_COMP)
5819da57d7bSbt 					break;
5829da57d7bSbt 				msec_delay(100);
5839da57d7bSbt 			}
5849da57d7bSbt 			if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
5859da57d7bSbt 				status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
5869da57d7bSbt 				DEBUGOUT("Autonegotiation did not complete.\n");
5879da57d7bSbt 			}
5889da57d7bSbt 		}
5899da57d7bSbt 	}
5909da57d7bSbt 
5919da57d7bSbt 	/* Add delay to filter out noises during initial link setup */
5929da57d7bSbt 	msec_delay(50);
5939da57d7bSbt 
59463b3bba8SJerry Jelinek 	return status;
5959da57d7bSbt }
5969da57d7bSbt 
59763b3bba8SJerry Jelinek /**
59863b3bba8SJerry Jelinek  *  ixgbe_validate_link_ready - Function looks for phy link
59963b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
6009da57d7bSbt  *
60163b3bba8SJerry Jelinek  *  Function indicates success when phy link is available. If phy is not ready
60263b3bba8SJerry Jelinek  *  within 5 seconds of MAC indicating link, the function returns error.
60363b3bba8SJerry Jelinek  **/
60463b3bba8SJerry Jelinek static s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw)
60563b3bba8SJerry Jelinek {
60663b3bba8SJerry Jelinek 	u32 timeout;
60763b3bba8SJerry Jelinek 	u16 an_reg;
60863b3bba8SJerry Jelinek 
60963b3bba8SJerry Jelinek 	if (hw->device_id != IXGBE_DEV_ID_82598AT2)
61063b3bba8SJerry Jelinek 		return IXGBE_SUCCESS;
61163b3bba8SJerry Jelinek 
61263b3bba8SJerry Jelinek 	for (timeout = 0;
61363b3bba8SJerry Jelinek 	     timeout < IXGBE_VALIDATE_LINK_READY_TIMEOUT; timeout++) {
61463b3bba8SJerry Jelinek 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
61569b5a878SDan McDonald 				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &an_reg);
61663b3bba8SJerry Jelinek 
61763b3bba8SJerry Jelinek 		if ((an_reg & IXGBE_MII_AUTONEG_COMPLETE) &&
61863b3bba8SJerry Jelinek 		    (an_reg & IXGBE_MII_AUTONEG_LINK_UP))
61963b3bba8SJerry Jelinek 			break;
62063b3bba8SJerry Jelinek 
62163b3bba8SJerry Jelinek 		msec_delay(100);
62263b3bba8SJerry Jelinek 	}
62363b3bba8SJerry Jelinek 
62463b3bba8SJerry Jelinek 	if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) {
62563b3bba8SJerry Jelinek 		DEBUGOUT("Link was indicated but link is down\n");
62663b3bba8SJerry Jelinek 		return IXGBE_ERR_LINK_SETUP;
62763b3bba8SJerry Jelinek 	}
62863b3bba8SJerry Jelinek 
62963b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
63063b3bba8SJerry Jelinek }
63163b3bba8SJerry Jelinek 
63263b3bba8SJerry Jelinek /**
63363b3bba8SJerry Jelinek  *  ixgbe_check_mac_link_82598 - Get link/speed status
63463b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
63563b3bba8SJerry Jelinek  *  @speed: pointer to link speed
63663b3bba8SJerry Jelinek  *  @link_up: TRUE is link is up, FALSE otherwise
63763b3bba8SJerry Jelinek  *  @link_up_wait_to_complete: bool used to wait for link up or not
63863b3bba8SJerry Jelinek  *
63963b3bba8SJerry Jelinek  *  Reads the links register to determine if link is up and the current speed
64063b3bba8SJerry Jelinek  **/
64163b3bba8SJerry Jelinek static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
64269b5a878SDan McDonald 				      ixgbe_link_speed *speed, bool *link_up,
64369b5a878SDan McDonald 				      bool link_up_wait_to_complete)
6449da57d7bSbt {
6459da57d7bSbt 	u32 links_reg;
64613740cb2SPaul Guo 	u32 i;
64713740cb2SPaul Guo 	u16 link_reg, adapt_comp_reg;
6489da57d7bSbt 
6493cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_check_mac_link_82598");
6503cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
65113740cb2SPaul Guo 	/*
65213740cb2SPaul Guo 	 * SERDES PHY requires us to read link status from undocumented
65313740cb2SPaul Guo 	 * register 0xC79F.  Bit 0 set indicates link is up/ready; clear
65413740cb2SPaul Guo 	 * indicates link down.  OxC00C is read to check that the XAUI lanes
65513740cb2SPaul Guo 	 * are active.  Bit 0 clear indicates active; set indicates inactive.
65613740cb2SPaul Guo 	 */
65713740cb2SPaul Guo 	if (hw->phy.type == ixgbe_phy_nl) {
65813740cb2SPaul Guo 		hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
65913740cb2SPaul Guo 		hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
66013740cb2SPaul Guo 		hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV,
66169b5a878SDan McDonald 				     &adapt_comp_reg);
66213740cb2SPaul Guo 		if (link_up_wait_to_complete) {
663*dc0cb1cdSDale Ghent 			for (i = 0; i < hw->mac.max_link_up_time; i++) {
66413740cb2SPaul Guo 				if ((link_reg & 1) &&
66513740cb2SPaul Guo 				    ((adapt_comp_reg & 1) == 0)) {
66663b3bba8SJerry Jelinek 					*link_up = TRUE;
66713740cb2SPaul Guo 					break;
66813740cb2SPaul Guo 				} else {
66963b3bba8SJerry Jelinek 					*link_up = FALSE;
67013740cb2SPaul Guo 				}
67113740cb2SPaul Guo 				msec_delay(100);
67213740cb2SPaul Guo 				hw->phy.ops.read_reg(hw, 0xC79F,
67369b5a878SDan McDonald 						     IXGBE_TWINAX_DEV,
67469b5a878SDan McDonald 						     &link_reg);
67513740cb2SPaul Guo 				hw->phy.ops.read_reg(hw, 0xC00C,
67669b5a878SDan McDonald 						     IXGBE_TWINAX_DEV,
67769b5a878SDan McDonald 						     &adapt_comp_reg);
67813740cb2SPaul Guo 			}
67913740cb2SPaul Guo 		} else {
68063b3bba8SJerry Jelinek 			if ((link_reg & 1) && ((adapt_comp_reg & 1) == 0))
68163b3bba8SJerry Jelinek 				*link_up = TRUE;
68213740cb2SPaul Guo 			else
68363b3bba8SJerry Jelinek 				*link_up = FALSE;
68413740cb2SPaul Guo 		}
6859da57d7bSbt 
68663b3bba8SJerry Jelinek 		if (*link_up == FALSE)
68713740cb2SPaul Guo 			goto out;
68813740cb2SPaul Guo 	}
68913740cb2SPaul Guo 
69013740cb2SPaul Guo 	links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
69113740cb2SPaul Guo 	if (link_up_wait_to_complete) {
692*dc0cb1cdSDale Ghent 		for (i = 0; i < hw->mac.max_link_up_time; i++) {
69313740cb2SPaul Guo 			if (links_reg & IXGBE_LINKS_UP) {
69463b3bba8SJerry Jelinek 				*link_up = TRUE;
69513740cb2SPaul Guo 				break;
69613740cb2SPaul Guo 			} else {
69763b3bba8SJerry Jelinek 				*link_up = FALSE;
69813740cb2SPaul Guo 			}
69913740cb2SPaul Guo 			msec_delay(100);
70013740cb2SPaul Guo 			links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
70113740cb2SPaul Guo 		}
70213740cb2SPaul Guo 	} else {
70313740cb2SPaul Guo 		if (links_reg & IXGBE_LINKS_UP)
70463b3bba8SJerry Jelinek 			*link_up = TRUE;
70513740cb2SPaul Guo 		else
70663b3bba8SJerry Jelinek 			*link_up = FALSE;
70713740cb2SPaul Guo 	}
7089da57d7bSbt 
7099da57d7bSbt 	if (links_reg & IXGBE_LINKS_SPEED)
7109da57d7bSbt 		*speed = IXGBE_LINK_SPEED_10GB_FULL;
7119da57d7bSbt 	else
7129da57d7bSbt 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
7139da57d7bSbt 
71463b3bba8SJerry Jelinek 	if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && (*link_up == TRUE) &&
71519843f01SPaul Guo 	    (ixgbe_validate_link_ready(hw) != IXGBE_SUCCESS))
71663b3bba8SJerry Jelinek 		*link_up = FALSE;
71719843f01SPaul Guo 
71813740cb2SPaul Guo out:
71963b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
7209da57d7bSbt }
7219da57d7bSbt 
72263b3bba8SJerry Jelinek /**
72363b3bba8SJerry Jelinek  *  ixgbe_setup_mac_link_82598 - Set MAC link speed
72463b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
72563b3bba8SJerry Jelinek  *  @speed: new link speed
72663b3bba8SJerry Jelinek  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
7279da57d7bSbt  *
72863b3bba8SJerry Jelinek  *  Set the link speed in the AUTOC register and restarts link.
72963b3bba8SJerry Jelinek  **/
73063b3bba8SJerry Jelinek static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
731*dc0cb1cdSDale Ghent 				      ixgbe_link_speed speed,
73269b5a878SDan McDonald 				      bool autoneg_wait_to_complete)
7339da57d7bSbt {
734*dc0cb1cdSDale Ghent 	bool autoneg = FALSE;
735*dc0cb1cdSDale Ghent 	s32 status = IXGBE_SUCCESS;
73673cd555cSBin Tu - Sun Microsystems - Beijing China 	ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
73769b5a878SDan McDonald 	u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
73869b5a878SDan McDonald 	u32 autoc = curr_autoc;
73969b5a878SDan McDonald 	u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
7409da57d7bSbt 
7413cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_setup_mac_link_82598");
7423cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
74373cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Check to see if speed passed in is supported. */
744*dc0cb1cdSDale Ghent 	ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
74573cd555cSBin Tu - Sun Microsystems - Beijing China 	speed &= link_capabilities;
74673cd555cSBin Tu - Sun Microsystems - Beijing China 
74763b3bba8SJerry Jelinek 	if (speed == IXGBE_LINK_SPEED_UNKNOWN)
7489da57d7bSbt 		status = IXGBE_ERR_LINK_SETUP;
74963b3bba8SJerry Jelinek 
75063b3bba8SJerry Jelinek 	/* Set KX4/KX support according to speed requested */
75163b3bba8SJerry Jelinek 	else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
75269b5a878SDan McDonald 		 link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
75373cd555cSBin Tu - Sun Microsystems - Beijing China 		autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK;
75473cd555cSBin Tu - Sun Microsystems - Beijing China 		if (speed & IXGBE_LINK_SPEED_10GB_FULL)
75573cd555cSBin Tu - Sun Microsystems - Beijing China 			autoc |= IXGBE_AUTOC_KX4_SUPP;
75673cd555cSBin Tu - Sun Microsystems - Beijing China 		if (speed & IXGBE_LINK_SPEED_1GB_FULL)
75773cd555cSBin Tu - Sun Microsystems - Beijing China 			autoc |= IXGBE_AUTOC_KX_SUPP;
75873cd555cSBin Tu - Sun Microsystems - Beijing China 		if (autoc != curr_autoc)
75973cd555cSBin Tu - Sun Microsystems - Beijing China 			IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
7609da57d7bSbt 	}
7619da57d7bSbt 
7629da57d7bSbt 	if (status == IXGBE_SUCCESS) {
7639da57d7bSbt 		/*
7649da57d7bSbt 		 * Setup and restart the link based on the new values in
7659da57d7bSbt 		 * ixgbe_hw This will write the AUTOC register based on the new
7669da57d7bSbt 		 * stored values
7679da57d7bSbt 		 */
7683cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		status = ixgbe_start_mac_link_82598(hw,
76969b5a878SDan McDonald 						    autoneg_wait_to_complete);
7709da57d7bSbt 	}
7719da57d7bSbt 
77263b3bba8SJerry Jelinek 	return status;
7739da57d7bSbt }
7749da57d7bSbt 
77563b3bba8SJerry Jelinek 
77663b3bba8SJerry Jelinek /**
77763b3bba8SJerry Jelinek  *  ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field
77863b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
77963b3bba8SJerry Jelinek  *  @speed: new link speed
78063b3bba8SJerry Jelinek  *  @autoneg_wait_to_complete: TRUE if waiting is needed to complete
7819da57d7bSbt  *
78263b3bba8SJerry Jelinek  *  Sets the link speed in the AUTOC register in the MAC and restarts link.
78363b3bba8SJerry Jelinek  **/
78463b3bba8SJerry Jelinek static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
78569b5a878SDan McDonald 					 ixgbe_link_speed speed,
78669b5a878SDan McDonald 					 bool autoneg_wait_to_complete)
7879da57d7bSbt {
7889da57d7bSbt 	s32 status;
7899da57d7bSbt 
7903cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_setup_copper_link_82598");
7913cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
7929da57d7bSbt 	/* Setup the PHY according to input speed */
793*dc0cb1cdSDale Ghent 	status = hw->phy.ops.setup_link_speed(hw, speed,
79469b5a878SDan McDonald 					      autoneg_wait_to_complete);
795*dc0cb1cdSDale Ghent 	/* Set up MAC */
796*dc0cb1cdSDale Ghent 	ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
7979da57d7bSbt 
79863b3bba8SJerry Jelinek 	return status;
7999da57d7bSbt }
8009da57d7bSbt 
80163b3bba8SJerry Jelinek /**
80263b3bba8SJerry Jelinek  *  ixgbe_reset_hw_82598 - Performs hardware reset
80363b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
8049da57d7bSbt  *
80563b3bba8SJerry Jelinek  *  Resets the hardware by resetting the transmit and receive units, masks and
80663b3bba8SJerry Jelinek  *  clears all interrupts, performing a PHY reset, and performing a link (MAC)
80763b3bba8SJerry Jelinek  *  reset.
80863b3bba8SJerry Jelinek  **/
80963b3bba8SJerry Jelinek static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
8109da57d7bSbt {
8119da57d7bSbt 	s32 status = IXGBE_SUCCESS;
812185c5677SPaul Guo 	s32 phy_status = IXGBE_SUCCESS;
8139da57d7bSbt 	u32 ctrl;
8149da57d7bSbt 	u32 gheccr;
8159da57d7bSbt 	u32 i;
8169da57d7bSbt 	u32 autoc;
8179da57d7bSbt 	u8  analog_val;
8189da57d7bSbt 
8193cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_reset_hw_82598");
8203cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
8219da57d7bSbt 	/* Call adapter stop to disable tx/rx and clear interrupts */
82269b5a878SDan McDonald 	status = hw->mac.ops.stop_adapter(hw);
82369b5a878SDan McDonald 	if (status != IXGBE_SUCCESS)
82469b5a878SDan McDonald 		goto reset_hw_out;
8259da57d7bSbt 
8269da57d7bSbt 	/*
8279da57d7bSbt 	 * Power up the Atlas Tx lanes if they are currently powered down.
8289da57d7bSbt 	 * Atlas Tx lanes are powered down for MAC loopback tests, but
8299da57d7bSbt 	 * they are not automatically restored on reset.
8309da57d7bSbt 	 */
8319da57d7bSbt 	hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
8329da57d7bSbt 	if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) {
8339da57d7bSbt 		/* Enable Tx Atlas so packets can be transmitted again */
8349da57d7bSbt 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
83569b5a878SDan McDonald 					     &analog_val);
8369da57d7bSbt 		analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN;
8379da57d7bSbt 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
83869b5a878SDan McDonald 					      analog_val);
8399da57d7bSbt 
8409da57d7bSbt 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
84169b5a878SDan McDonald 					     &analog_val);
84213740cb2SPaul Guo 		analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
8439da57d7bSbt 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
84469b5a878SDan McDonald 					      analog_val);
8459da57d7bSbt 
8469da57d7bSbt 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
84769b5a878SDan McDonald 					     &analog_val);
8489da57d7bSbt 		analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
8499da57d7bSbt 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
85069b5a878SDan McDonald 					      analog_val);
8519da57d7bSbt 
8529da57d7bSbt 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
85369b5a878SDan McDonald 					     &analog_val);
8549da57d7bSbt 		analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
8559da57d7bSbt 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
85669b5a878SDan McDonald 					      analog_val);
8579da57d7bSbt 	}
8589da57d7bSbt 
8599da57d7bSbt 	/* Reset PHY */
86063b3bba8SJerry Jelinek 	if (hw->phy.reset_disable == FALSE) {
86173cd555cSBin Tu - Sun Microsystems - Beijing China 		/* PHY ops must be identified and initialized prior to reset */
86273cd555cSBin Tu - Sun Microsystems - Beijing China 
86373cd555cSBin Tu - Sun Microsystems - Beijing China 		/* Init PHY and function pointers, perform SFP setup */
864185c5677SPaul Guo 		phy_status = hw->phy.ops.init(hw);
865185c5677SPaul Guo 		if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
866185c5677SPaul Guo 			goto reset_hw_out;
86769b5a878SDan McDonald 		if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT)
86869b5a878SDan McDonald 			goto mac_reset_top;
86973cd555cSBin Tu - Sun Microsystems - Beijing China 
87013740cb2SPaul Guo 		hw->phy.ops.reset(hw);
87173cd555cSBin Tu - Sun Microsystems - Beijing China 	}
8729da57d7bSbt 
87319843f01SPaul Guo mac_reset_top:
8749da57d7bSbt 	/*
8759da57d7bSbt 	 * Issue global reset to the MAC.  This needs to be a SW reset.
8769da57d7bSbt 	 * If link reset is used, it might reset the MAC when mng is using it
8779da57d7bSbt 	 */
87869b5a878SDan McDonald 	ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL) | IXGBE_CTRL_RST;
87969b5a878SDan McDonald 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
8809da57d7bSbt 	IXGBE_WRITE_FLUSH(hw);
8819da57d7bSbt 
8829da57d7bSbt 	/* Poll for reset bit to self-clear indicating reset is complete */
8839da57d7bSbt 	for (i = 0; i < 10; i++) {
8849da57d7bSbt 		usec_delay(1);
8859da57d7bSbt 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
8869da57d7bSbt 		if (!(ctrl & IXGBE_CTRL_RST))
8879da57d7bSbt 			break;
8889da57d7bSbt 	}
8899da57d7bSbt 	if (ctrl & IXGBE_CTRL_RST) {
8909da57d7bSbt 		status = IXGBE_ERR_RESET_FAILED;
8919da57d7bSbt 		DEBUGOUT("Reset polling failed to complete.\n");
8929da57d7bSbt 	}
8939da57d7bSbt 
89469b5a878SDan McDonald 	msec_delay(50);
89569b5a878SDan McDonald 
89619843f01SPaul Guo 	/*
89719843f01SPaul Guo 	 * Double resets are required for recovery from certain error
89819843f01SPaul Guo 	 * conditions.  Between resets, it is necessary to stall to allow time
89969b5a878SDan McDonald 	 * for any pending HW events to complete.
90019843f01SPaul Guo 	 */
90119843f01SPaul Guo 	if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
90219843f01SPaul Guo 		hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
90319843f01SPaul Guo 		goto mac_reset_top;
90419843f01SPaul Guo 	}
90563b3bba8SJerry Jelinek 
9069da57d7bSbt 	gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR);
9079da57d7bSbt 	gheccr &= ~((1 << 21) | (1 << 18) | (1 << 9) | (1 << 6));
9089da57d7bSbt 	IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
9099da57d7bSbt 
9109da57d7bSbt 	/*
91173cd555cSBin Tu - Sun Microsystems - Beijing China 	 * Store the original AUTOC value if it has not been
91273cd555cSBin Tu - Sun Microsystems - Beijing China 	 * stored off yet.  Otherwise restore the stored original
91373cd555cSBin Tu - Sun Microsystems - Beijing China 	 * AUTOC value since the reset operation sets back to deaults.
9149da57d7bSbt 	 */
9159da57d7bSbt 	autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
91663b3bba8SJerry Jelinek 	if (hw->mac.orig_link_settings_stored == FALSE) {
91773cd555cSBin Tu - Sun Microsystems - Beijing China 		hw->mac.orig_autoc = autoc;
91863b3bba8SJerry Jelinek 		hw->mac.orig_link_settings_stored = TRUE;
91973cd555cSBin Tu - Sun Microsystems - Beijing China 	} else if (autoc != hw->mac.orig_autoc) {
92073cd555cSBin Tu - Sun Microsystems - Beijing China 		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
9219da57d7bSbt 	}
9229da57d7bSbt 
923185c5677SPaul Guo 	/* Store the permanent mac address */
924185c5677SPaul Guo 	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
925185c5677SPaul Guo 
92673cd555cSBin Tu - Sun Microsystems - Beijing China 	/*
92773cd555cSBin Tu - Sun Microsystems - Beijing China 	 * Store MAC address from RAR0, clear receive address registers, and
92873cd555cSBin Tu - Sun Microsystems - Beijing China 	 * clear the multicast table
92973cd555cSBin Tu - Sun Microsystems - Beijing China 	 */
93073cd555cSBin Tu - Sun Microsystems - Beijing China 	hw->mac.ops.init_rx_addrs(hw);
93173cd555cSBin Tu - Sun Microsystems - Beijing China 
932185c5677SPaul Guo reset_hw_out:
933185c5677SPaul Guo 	if (phy_status != IXGBE_SUCCESS)
934185c5677SPaul Guo 		status = phy_status;
9359da57d7bSbt 
93663b3bba8SJerry Jelinek 	return status;
9379da57d7bSbt }
9389da57d7bSbt 
93963b3bba8SJerry Jelinek /**
94063b3bba8SJerry Jelinek  *  ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address
94163b3bba8SJerry Jelinek  *  @hw: pointer to hardware struct
94263b3bba8SJerry Jelinek  *  @rar: receive address register index to associate with a VMDq index
94363b3bba8SJerry Jelinek  *  @vmdq: VMDq set index
94463b3bba8SJerry Jelinek  **/
94563b3bba8SJerry Jelinek s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
9469da57d7bSbt {
9479da57d7bSbt 	u32 rar_high;
94863b3bba8SJerry Jelinek 	u32 rar_entries = hw->mac.num_rar_entries;
9499da57d7bSbt 
9503cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_set_vmdq_82598");
9513cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
95263b3bba8SJerry Jelinek 	/* Make sure we are using a valid rar index range */
95363b3bba8SJerry Jelinek 	if (rar >= rar_entries) {
95463b3bba8SJerry Jelinek 		DEBUGOUT1("RAR index %d is out of range.\n", rar);
95563b3bba8SJerry Jelinek 		return IXGBE_ERR_INVALID_ARGUMENT;
95663b3bba8SJerry Jelinek 	}
95763b3bba8SJerry Jelinek 
9589da57d7bSbt 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
9599da57d7bSbt 	rar_high &= ~IXGBE_RAH_VIND_MASK;
9609da57d7bSbt 	rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK);
9619da57d7bSbt 	IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
96263b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
9639da57d7bSbt }
9649da57d7bSbt 
96563b3bba8SJerry Jelinek /**
96663b3bba8SJerry Jelinek  *  ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address
96763b3bba8SJerry Jelinek  *  @hw: pointer to hardware struct
96863b3bba8SJerry Jelinek  *  @rar: receive address register index to associate with a VMDq index
96963b3bba8SJerry Jelinek  *  @vmdq: VMDq clear index (not used in 82598, but elsewhere)
97063b3bba8SJerry Jelinek  **/
97163b3bba8SJerry Jelinek static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
97213740cb2SPaul Guo {
97313740cb2SPaul Guo 	u32 rar_high;
97413740cb2SPaul Guo 	u32 rar_entries = hw->mac.num_rar_entries;
97513740cb2SPaul Guo 
97669b5a878SDan McDonald 	UNREFERENCED_1PARAMETER(vmdq);
97713740cb2SPaul Guo 
97863b3bba8SJerry Jelinek 	/* Make sure we are using a valid rar index range */
97963b3bba8SJerry Jelinek 	if (rar >= rar_entries) {
98013740cb2SPaul Guo 		DEBUGOUT1("RAR index %d is out of range.\n", rar);
98163b3bba8SJerry Jelinek 		return IXGBE_ERR_INVALID_ARGUMENT;
98263b3bba8SJerry Jelinek 	}
98363b3bba8SJerry Jelinek 
98463b3bba8SJerry Jelinek 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
98563b3bba8SJerry Jelinek 	if (rar_high & IXGBE_RAH_VIND_MASK) {
98663b3bba8SJerry Jelinek 		rar_high &= ~IXGBE_RAH_VIND_MASK;
98763b3bba8SJerry Jelinek 		IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
98813740cb2SPaul Guo 	}
98913740cb2SPaul Guo 
99063b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
99113740cb2SPaul Guo }
99213740cb2SPaul Guo 
99363b3bba8SJerry Jelinek /**
99463b3bba8SJerry Jelinek  *  ixgbe_set_vfta_82598 - Set VLAN filter table
99563b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
99663b3bba8SJerry Jelinek  *  @vlan: VLAN id to write to VLAN filter
99763b3bba8SJerry Jelinek  *  @vind: VMDq output index that maps queue to VLAN id in VFTA
99863b3bba8SJerry Jelinek  *  @vlan_on: boolean flag to turn on/off VLAN in VFTA
99913740cb2SPaul Guo  *
100063b3bba8SJerry Jelinek  *  Turn on/off specified VLAN in the VLAN filter table.
100163b3bba8SJerry Jelinek  **/
100263b3bba8SJerry Jelinek s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind,
100369b5a878SDan McDonald 			 bool vlan_on)
100413740cb2SPaul Guo {
100513740cb2SPaul Guo 	u32 regindex;
100613740cb2SPaul Guo 	u32 bitindex;
100713740cb2SPaul Guo 	u32 bits;
100813740cb2SPaul Guo 	u32 vftabyte;
100913740cb2SPaul Guo 
10103cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_set_vfta_82598");
10113cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
101213740cb2SPaul Guo 	if (vlan > 4095)
101363b3bba8SJerry Jelinek 		return IXGBE_ERR_PARAM;
101413740cb2SPaul Guo 
101513740cb2SPaul Guo 	/* Determine 32-bit word position in array */
101613740cb2SPaul Guo 	regindex = (vlan >> 5) & 0x7F;   /* upper seven bits */
101713740cb2SPaul Guo 
101813740cb2SPaul Guo 	/* Determine the location of the (VMD) queue index */
101913740cb2SPaul Guo 	vftabyte =  ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
102013740cb2SPaul Guo 	bitindex = (vlan & 0x7) << 2;    /* lower 3 bits indicate nibble */
102113740cb2SPaul Guo 
102213740cb2SPaul Guo 	/* Set the nibble for VMD queue index */
102313740cb2SPaul Guo 	bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex));
102413740cb2SPaul Guo 	bits &= (~(0x0F << bitindex));
102513740cb2SPaul Guo 	bits |= (vind << bitindex);
102613740cb2SPaul Guo 	IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits);
102713740cb2SPaul Guo 
102813740cb2SPaul Guo 	/* Determine the location of the bit for this VLAN id */
102913740cb2SPaul Guo 	bitindex = vlan & 0x1F;   /* lower five bits */
103013740cb2SPaul Guo 
103113740cb2SPaul Guo 	bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
103213740cb2SPaul Guo 	if (vlan_on)
103313740cb2SPaul Guo 		/* Turn on this VLAN id */
103413740cb2SPaul Guo 		bits |= (1 << bitindex);
103513740cb2SPaul Guo 	else
103613740cb2SPaul Guo 		/* Turn off this VLAN id */
103713740cb2SPaul Guo 		bits &= ~(1 << bitindex);
103813740cb2SPaul Guo 	IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
103913740cb2SPaul Guo 
104063b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
104113740cb2SPaul Guo }
104213740cb2SPaul Guo 
104363b3bba8SJerry Jelinek /**
104463b3bba8SJerry Jelinek  *  ixgbe_clear_vfta_82598 - Clear VLAN filter table
104563b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
104613740cb2SPaul Guo  *
104763b3bba8SJerry Jelinek  *  Clears the VLAN filer table, and the VMDq index associated with the filter
104863b3bba8SJerry Jelinek  **/
104963b3bba8SJerry Jelinek static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw)
105013740cb2SPaul Guo {
105113740cb2SPaul Guo 	u32 offset;
105213740cb2SPaul Guo 	u32 vlanbyte;
105313740cb2SPaul Guo 
10543cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_clear_vfta_82598");
10553cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
105613740cb2SPaul Guo 	for (offset = 0; offset < hw->mac.vft_size; offset++)
105713740cb2SPaul Guo 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
105813740cb2SPaul Guo 
105913740cb2SPaul Guo 	for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
106013740cb2SPaul Guo 		for (offset = 0; offset < hw->mac.vft_size; offset++)
106163b3bba8SJerry Jelinek 			IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
106269b5a878SDan McDonald 					0);
106313740cb2SPaul Guo 
106463b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
106513740cb2SPaul Guo }
106613740cb2SPaul Guo 
106763b3bba8SJerry Jelinek /**
106863b3bba8SJerry Jelinek  *  ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
106963b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
107063b3bba8SJerry Jelinek  *  @reg: analog register to read
107163b3bba8SJerry Jelinek  *  @val: read value
107213740cb2SPaul Guo  *
107363b3bba8SJerry Jelinek  *  Performs read operation to Atlas analog register specified.
107463b3bba8SJerry Jelinek  **/
107563b3bba8SJerry Jelinek s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val)
107613740cb2SPaul Guo {
107713740cb2SPaul Guo 	u32  atlas_ctl;
107813740cb2SPaul Guo 
10793cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_read_analog_reg8_82598");
10803cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
108113740cb2SPaul Guo 	IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
108269b5a878SDan McDonald 			IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
108313740cb2SPaul Guo 	IXGBE_WRITE_FLUSH(hw);
108413740cb2SPaul Guo 	usec_delay(10);
108513740cb2SPaul Guo 	atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
108613740cb2SPaul Guo 	*val = (u8)atlas_ctl;
108713740cb2SPaul Guo 
108863b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
108913740cb2SPaul Guo }
109013740cb2SPaul Guo 
109163b3bba8SJerry Jelinek /**
109263b3bba8SJerry Jelinek  *  ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register
109363b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
109463b3bba8SJerry Jelinek  *  @reg: atlas register to write
109563b3bba8SJerry Jelinek  *  @val: value to write
109613740cb2SPaul Guo  *
109763b3bba8SJerry Jelinek  *  Performs write operation to Atlas analog register specified.
109863b3bba8SJerry Jelinek  **/
109963b3bba8SJerry Jelinek s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val)
110013740cb2SPaul Guo {
110113740cb2SPaul Guo 	u32  atlas_ctl;
110213740cb2SPaul Guo 
11033cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_write_analog_reg8_82598");
11043cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
110513740cb2SPaul Guo 	atlas_ctl = (reg << 8) | val;
110613740cb2SPaul Guo 	IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
110713740cb2SPaul Guo 	IXGBE_WRITE_FLUSH(hw);
110813740cb2SPaul Guo 	usec_delay(10);
110913740cb2SPaul Guo 
111063b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
111113740cb2SPaul Guo }
111213740cb2SPaul Guo 
111363b3bba8SJerry Jelinek /**
1114*dc0cb1cdSDale Ghent  *  ixgbe_read_i2c_phy_82598 - Reads 8 bit word over I2C interface.
111563b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
1116*dc0cb1cdSDale Ghent  *  @dev_addr: address to read from
1117*dc0cb1cdSDale Ghent  *  @byte_offset: byte offset to read from dev_addr
111863b3bba8SJerry Jelinek  *  @eeprom_data: value read
111913740cb2SPaul Guo  *
112063b3bba8SJerry Jelinek  *  Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
112163b3bba8SJerry Jelinek  **/
1122*dc0cb1cdSDale Ghent static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr,
1123*dc0cb1cdSDale Ghent 				    u8 byte_offset, u8 *eeprom_data)
112413740cb2SPaul Guo {
112513740cb2SPaul Guo 	s32 status = IXGBE_SUCCESS;
112613740cb2SPaul Guo 	u16 sfp_addr = 0;
112713740cb2SPaul Guo 	u16 sfp_data = 0;
112813740cb2SPaul Guo 	u16 sfp_stat = 0;
1129*dc0cb1cdSDale Ghent 	u16 gssr;
113013740cb2SPaul Guo 	u32 i;
113113740cb2SPaul Guo 
1132*dc0cb1cdSDale Ghent 	DEBUGFUNC("ixgbe_read_i2c_phy_82598");
1133*dc0cb1cdSDale Ghent 
1134*dc0cb1cdSDale Ghent 	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
1135*dc0cb1cdSDale Ghent 		gssr = IXGBE_GSSR_PHY1_SM;
1136*dc0cb1cdSDale Ghent 	else
1137*dc0cb1cdSDale Ghent 		gssr = IXGBE_GSSR_PHY0_SM;
1138*dc0cb1cdSDale Ghent 
1139*dc0cb1cdSDale Ghent 	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != IXGBE_SUCCESS)
1140*dc0cb1cdSDale Ghent 		return IXGBE_ERR_SWFW_SYNC;
11413cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
114213740cb2SPaul Guo 	if (hw->phy.type == ixgbe_phy_nl) {
114313740cb2SPaul Guo 		/*
114413740cb2SPaul Guo 		 * NetLogic phy SDA/SCL registers are at addresses 0xC30A to
114513740cb2SPaul Guo 		 * 0xC30D. These registers are used to talk to the SFP+
114613740cb2SPaul Guo 		 * module's EEPROM through the SDA/SCL (I2C) interface.
114713740cb2SPaul Guo 		 */
1148*dc0cb1cdSDale Ghent 		sfp_addr = (dev_addr << 8) + byte_offset;
114913740cb2SPaul Guo 		sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
1150*dc0cb1cdSDale Ghent 		hw->phy.ops.write_reg_mdi(hw,
1151*dc0cb1cdSDale Ghent 					  IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
1152*dc0cb1cdSDale Ghent 					  IXGBE_MDIO_PMA_PMD_DEV_TYPE,
1153*dc0cb1cdSDale Ghent 					  sfp_addr);
115413740cb2SPaul Guo 
115513740cb2SPaul Guo 		/* Poll status */
115613740cb2SPaul Guo 		for (i = 0; i < 100; i++) {
1157*dc0cb1cdSDale Ghent 			hw->phy.ops.read_reg_mdi(hw,
1158*dc0cb1cdSDale Ghent 						IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
1159*dc0cb1cdSDale Ghent 						IXGBE_MDIO_PMA_PMD_DEV_TYPE,
1160*dc0cb1cdSDale Ghent 						&sfp_stat);
116113740cb2SPaul Guo 			sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
116213740cb2SPaul Guo 			if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
116313740cb2SPaul Guo 				break;
116413740cb2SPaul Guo 			msec_delay(10);
116513740cb2SPaul Guo 		}
116613740cb2SPaul Guo 
116713740cb2SPaul Guo 		if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) {
116813740cb2SPaul Guo 			DEBUGOUT("EEPROM read did not pass.\n");
116913740cb2SPaul Guo 			status = IXGBE_ERR_SFP_NOT_PRESENT;
117013740cb2SPaul Guo 			goto out;
117113740cb2SPaul Guo 		}
117213740cb2SPaul Guo 
117313740cb2SPaul Guo 		/* Read data */
1174*dc0cb1cdSDale Ghent 		hw->phy.ops.read_reg_mdi(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
1175*dc0cb1cdSDale Ghent 					IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
117613740cb2SPaul Guo 
117713740cb2SPaul Guo 		*eeprom_data = (u8)(sfp_data >> 8);
117813740cb2SPaul Guo 	} else {
117913740cb2SPaul Guo 		status = IXGBE_ERR_PHY;
118013740cb2SPaul Guo 	}
118113740cb2SPaul Guo 
118213740cb2SPaul Guo out:
1183*dc0cb1cdSDale Ghent 	hw->mac.ops.release_swfw_sync(hw, gssr);
118463b3bba8SJerry Jelinek 	return status;
118513740cb2SPaul Guo }
118613740cb2SPaul Guo 
1187*dc0cb1cdSDale Ghent /**
1188*dc0cb1cdSDale Ghent  *  ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
1189*dc0cb1cdSDale Ghent  *  @hw: pointer to hardware structure
1190*dc0cb1cdSDale Ghent  *  @byte_offset: EEPROM byte offset to read
1191*dc0cb1cdSDale Ghent  *  @eeprom_data: value read
1192*dc0cb1cdSDale Ghent  *
1193*dc0cb1cdSDale Ghent  *  Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
1194*dc0cb1cdSDale Ghent  **/
1195*dc0cb1cdSDale Ghent s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
1196*dc0cb1cdSDale Ghent 				u8 *eeprom_data)
1197*dc0cb1cdSDale Ghent {
1198*dc0cb1cdSDale Ghent 	return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR,
1199*dc0cb1cdSDale Ghent 					byte_offset, eeprom_data);
1200*dc0cb1cdSDale Ghent }
1201*dc0cb1cdSDale Ghent 
1202*dc0cb1cdSDale Ghent /**
1203*dc0cb1cdSDale Ghent  *  ixgbe_read_i2c_sff8472_82598 - Reads 8 bit word over I2C interface.
1204*dc0cb1cdSDale Ghent  *  @hw: pointer to hardware structure
1205*dc0cb1cdSDale Ghent  *  @byte_offset: byte offset at address 0xA2
1206*dc0cb1cdSDale Ghent  *  @eeprom_data: value read
1207*dc0cb1cdSDale Ghent  *
1208*dc0cb1cdSDale Ghent  *  Performs 8 byte read operation to SFP module's SFF-8472 data over I2C
1209*dc0cb1cdSDale Ghent  **/
1210*dc0cb1cdSDale Ghent static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
1211*dc0cb1cdSDale Ghent 					u8 *sff8472_data)
1212*dc0cb1cdSDale Ghent {
1213*dc0cb1cdSDale Ghent 	return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR2,
1214*dc0cb1cdSDale Ghent 					byte_offset, sff8472_data);
1215*dc0cb1cdSDale Ghent }
1216*dc0cb1cdSDale Ghent 
121763b3bba8SJerry Jelinek /**
121863b3bba8SJerry Jelinek  *  ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
121963b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
122013740cb2SPaul Guo  *
122163b3bba8SJerry Jelinek  *  Determines physical layer capabilities of the current configuration.
122263b3bba8SJerry Jelinek  **/
122363b3bba8SJerry Jelinek u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
122413740cb2SPaul Guo {
122573cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
122673cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
122773cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
122873cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
122973cd555cSBin Tu - Sun Microsystems - Beijing China 	u16 ext_ability = 0;
123013740cb2SPaul Guo 
12313cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_get_supported_physical_layer_82598");
12323cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
123373cd555cSBin Tu - Sun Microsystems - Beijing China 	hw->phy.ops.identify(hw);
123473cd555cSBin Tu - Sun Microsystems - Beijing China 
123563b3bba8SJerry Jelinek 	/* Copper PHY must be checked before AUTOC LMS to determine correct
123663b3bba8SJerry Jelinek 	 * physical layer because 10GBase-T PHYs use LMS = KX4/KX */
123763b3bba8SJerry Jelinek 	switch (hw->phy.type) {
123863b3bba8SJerry Jelinek 	case ixgbe_phy_tn:
123963b3bba8SJerry Jelinek 	case ixgbe_phy_cu_unknown:
124073cd555cSBin Tu - Sun Microsystems - Beijing China 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
124163b3bba8SJerry Jelinek 		IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
124273cd555cSBin Tu - Sun Microsystems - Beijing China 		if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
124373cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
124473cd555cSBin Tu - Sun Microsystems - Beijing China 		if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
124573cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
124673cd555cSBin Tu - Sun Microsystems - Beijing China 		if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
124773cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
124873cd555cSBin Tu - Sun Microsystems - Beijing China 		goto out;
124963b3bba8SJerry Jelinek 	default:
125063b3bba8SJerry Jelinek 		break;
125173cd555cSBin Tu - Sun Microsystems - Beijing China 	}
125273cd555cSBin Tu - Sun Microsystems - Beijing China 
125373cd555cSBin Tu - Sun Microsystems - Beijing China 	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
125473cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_AUTOC_LMS_1G_AN:
125573cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
125673cd555cSBin Tu - Sun Microsystems - Beijing China 		if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
125773cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
125873cd555cSBin Tu - Sun Microsystems - Beijing China 		else
125973cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
126013740cb2SPaul Guo 		break;
126173cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
126273cd555cSBin Tu - Sun Microsystems - Beijing China 		if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
126373cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
126473cd555cSBin Tu - Sun Microsystems - Beijing China 		else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
126573cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
126673cd555cSBin Tu - Sun Microsystems - Beijing China 		else /* XAUI */
126773cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
126813740cb2SPaul Guo 		break;
126973cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_AUTOC_LMS_KX4_AN:
127073cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
127173cd555cSBin Tu - Sun Microsystems - Beijing China 		if (autoc & IXGBE_AUTOC_KX_SUPP)
127273cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
127373cd555cSBin Tu - Sun Microsystems - Beijing China 		if (autoc & IXGBE_AUTOC_KX4_SUPP)
127473cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
127513740cb2SPaul Guo 		break;
127673cd555cSBin Tu - Sun Microsystems - Beijing China 	default:
127713740cb2SPaul Guo 		break;
127873cd555cSBin Tu - Sun Microsystems - Beijing China 	}
127973cd555cSBin Tu - Sun Microsystems - Beijing China 
128073cd555cSBin Tu - Sun Microsystems - Beijing China 	if (hw->phy.type == ixgbe_phy_nl) {
128113740cb2SPaul Guo 		hw->phy.ops.identify_sfp(hw);
128213740cb2SPaul Guo 
128313740cb2SPaul Guo 		switch (hw->phy.sfp_type) {
128413740cb2SPaul Guo 		case ixgbe_sfp_type_da_cu:
128513740cb2SPaul Guo 			physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
128613740cb2SPaul Guo 			break;
128713740cb2SPaul Guo 		case ixgbe_sfp_type_sr:
128813740cb2SPaul Guo 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
128913740cb2SPaul Guo 			break;
129013740cb2SPaul Guo 		case ixgbe_sfp_type_lr:
129113740cb2SPaul Guo 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
129213740cb2SPaul Guo 			break;
129313740cb2SPaul Guo 		default:
129413740cb2SPaul Guo 			physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
129513740cb2SPaul Guo 			break;
129613740cb2SPaul Guo 		}
129773cd555cSBin Tu - Sun Microsystems - Beijing China 	}
129813740cb2SPaul Guo 
129973cd555cSBin Tu - Sun Microsystems - Beijing China 	switch (hw->device_id) {
130073cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
130173cd555cSBin Tu - Sun Microsystems - Beijing China 		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
130273cd555cSBin Tu - Sun Microsystems - Beijing China 		break;
130373cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
130473cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
130573cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
130673cd555cSBin Tu - Sun Microsystems - Beijing China 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
130773cd555cSBin Tu - Sun Microsystems - Beijing China 		break;
130873cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598EB_XF_LR:
130973cd555cSBin Tu - Sun Microsystems - Beijing China 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
131073cd555cSBin Tu - Sun Microsystems - Beijing China 		break;
131113740cb2SPaul Guo 	default:
131213740cb2SPaul Guo 		break;
131313740cb2SPaul Guo 	}
131413740cb2SPaul Guo 
131573cd555cSBin Tu - Sun Microsystems - Beijing China out:
131663b3bba8SJerry Jelinek 	return physical_layer;
131713740cb2SPaul Guo }
1318185c5677SPaul Guo 
131963b3bba8SJerry Jelinek /**
132063b3bba8SJerry Jelinek  *  ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple
132163b3bba8SJerry Jelinek  *  port devices.
132263b3bba8SJerry Jelinek  *  @hw: pointer to the HW structure
1323185c5677SPaul Guo  *
132463b3bba8SJerry Jelinek  *  Calls common function and corrects issue with some single port devices
132563b3bba8SJerry Jelinek  *  that enable LAN1 but not LAN0.
132663b3bba8SJerry Jelinek  **/
132763b3bba8SJerry Jelinek void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw)
1328185c5677SPaul Guo {
1329185c5677SPaul Guo 	struct ixgbe_bus_info *bus = &hw->bus;
133063b3bba8SJerry Jelinek 	u16 pci_gen = 0;
133163b3bba8SJerry Jelinek 	u16 pci_ctrl2 = 0;
1332185c5677SPaul Guo 
13333cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie_82598");
13343cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
1335185c5677SPaul Guo 	ixgbe_set_lan_id_multi_port_pcie(hw);
1336185c5677SPaul Guo 
1337185c5677SPaul Guo 	/* check if LAN0 is disabled */
1338185c5677SPaul Guo 	hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen);
1339185c5677SPaul Guo 	if ((pci_gen != 0) && (pci_gen != 0xFFFF)) {
134063b3bba8SJerry Jelinek 
1341185c5677SPaul Guo 		hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2);
1342185c5677SPaul Guo 
1343185c5677SPaul Guo 		/* if LAN0 is completely disabled force function to 0 */
1344185c5677SPaul Guo 		if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) &&
1345185c5677SPaul Guo 		    !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) &&
1346185c5677SPaul Guo 		    !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) {
134763b3bba8SJerry Jelinek 
1348185c5677SPaul Guo 			bus->func = 0;
1349185c5677SPaul Guo 		}
1350185c5677SPaul Guo 	}
1351185c5677SPaul Guo }
135219843f01SPaul Guo 
135363b3bba8SJerry Jelinek /**
135463b3bba8SJerry Jelinek  *  ixgbe_enable_relaxed_ordering_82598 - enable relaxed ordering
135563b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
135619843f01SPaul Guo  *
135763b3bba8SJerry Jelinek  **/
135863b3bba8SJerry Jelinek void ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw *hw)
135919843f01SPaul Guo {
136019843f01SPaul Guo 	u32 regval;
136119843f01SPaul Guo 	u32 i;
136219843f01SPaul Guo 
136319843f01SPaul Guo 	DEBUGFUNC("ixgbe_enable_relaxed_ordering_82598");
136419843f01SPaul Guo 
136519843f01SPaul Guo 	/* Enable relaxed ordering */
136619843f01SPaul Guo 	for (i = 0; ((i < hw->mac.max_tx_queues) &&
136763b3bba8SJerry Jelinek 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
136819843f01SPaul Guo 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
136969b5a878SDan McDonald 		regval |= IXGBE_DCA_TXCTRL_DESC_WRO_EN;
137019843f01SPaul Guo 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
137119843f01SPaul Guo 	}
137219843f01SPaul Guo 
137319843f01SPaul Guo 	for (i = 0; ((i < hw->mac.max_rx_queues) &&
137463b3bba8SJerry Jelinek 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
137519843f01SPaul Guo 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
137669b5a878SDan McDonald 		regval |= IXGBE_DCA_RXCTRL_DATA_WRO_EN |
137769b5a878SDan McDonald 			  IXGBE_DCA_RXCTRL_HEAD_WRO_EN;
137819843f01SPaul Guo 		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
137919843f01SPaul Guo 	}
138063b3bba8SJerry Jelinek 
138119843f01SPaul Guo }
138269b5a878SDan McDonald 
138369b5a878SDan McDonald /**
138469b5a878SDan McDonald  * ixgbe_set_rxpba_82598 - Initialize RX packet buffer
138569b5a878SDan McDonald  * @hw: pointer to hardware structure
138669b5a878SDan McDonald  * @num_pb: number of packet buffers to allocate
138769b5a878SDan McDonald  * @headroom: reserve n KB of headroom
138869b5a878SDan McDonald  * @strategy: packet buffer allocation strategy
138969b5a878SDan McDonald  **/
139069b5a878SDan McDonald static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
139169b5a878SDan McDonald 				  u32 headroom, int strategy)
139269b5a878SDan McDonald {
139369b5a878SDan McDonald 	u32 rxpktsize = IXGBE_RXPBSIZE_64KB;
139469b5a878SDan McDonald 	u8 i = 0;
139569b5a878SDan McDonald 	UNREFERENCED_1PARAMETER(headroom);
139669b5a878SDan McDonald 
139769b5a878SDan McDonald 	if (!num_pb)
139869b5a878SDan McDonald 		return;
139969b5a878SDan McDonald 
140069b5a878SDan McDonald 	/* Setup Rx packet buffer sizes */
140169b5a878SDan McDonald 	switch (strategy) {
140269b5a878SDan McDonald 	case PBA_STRATEGY_WEIGHTED:
140369b5a878SDan McDonald 		/* Setup the first four at 80KB */
140469b5a878SDan McDonald 		rxpktsize = IXGBE_RXPBSIZE_80KB;
140569b5a878SDan McDonald 		for (; i < 4; i++)
140669b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
140769b5a878SDan McDonald 		/* Setup the last four at 48KB...don't re-init i */
140869b5a878SDan McDonald 		rxpktsize = IXGBE_RXPBSIZE_48KB;
140969b5a878SDan McDonald 		/* Fall Through */
141069b5a878SDan McDonald 	case PBA_STRATEGY_EQUAL:
141169b5a878SDan McDonald 	default:
141269b5a878SDan McDonald 		/* Divide the remaining Rx packet buffer evenly among the TCs */
141369b5a878SDan McDonald 		for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
141469b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
141569b5a878SDan McDonald 		break;
141669b5a878SDan McDonald 	}
141769b5a878SDan McDonald 
141869b5a878SDan McDonald 	/* Setup Tx packet buffer sizes */
141969b5a878SDan McDonald 	for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++)
142069b5a878SDan McDonald 		IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), IXGBE_TXPBSIZE_40KB);
142169b5a878SDan McDonald }
1422*dc0cb1cdSDale Ghent 
1423*dc0cb1cdSDale Ghent /**
1424*dc0cb1cdSDale Ghent  *  ixgbe_enable_rx_dma_82598 - Enable the Rx DMA unit
1425*dc0cb1cdSDale Ghent  *  @hw: pointer to hardware structure
1426*dc0cb1cdSDale Ghent  *  @regval: register value to write to RXCTRL
1427*dc0cb1cdSDale Ghent  *
1428*dc0cb1cdSDale Ghent  *  Enables the Rx DMA unit
1429*dc0cb1cdSDale Ghent  **/
1430*dc0cb1cdSDale Ghent s32 ixgbe_enable_rx_dma_82598(struct ixgbe_hw *hw, u32 regval)
1431*dc0cb1cdSDale Ghent {
1432*dc0cb1cdSDale Ghent 	DEBUGFUNC("ixgbe_enable_rx_dma_82598");
1433*dc0cb1cdSDale Ghent 
1434*dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
1435*dc0cb1cdSDale Ghent 
1436*dc0cb1cdSDale Ghent 	return IXGBE_SUCCESS;
1437*dc0cb1cdSDale Ghent }
1438