163b3bba8SJerry Jelinek /******************************************************************************
248ed61a7SRobert Mustacchi   SPDX-License-Identifier: BSD-3-Clause
363b3bba8SJerry Jelinek 
448ed61a7SRobert Mustacchi   Copyright (c) 2001-2017, Intel Corporation
563b3bba8SJerry Jelinek   All rights reserved.
648ed61a7SRobert Mustacchi 
748ed61a7SRobert Mustacchi   Redistribution and use in source and binary forms, with or without
863b3bba8SJerry Jelinek   modification, are permitted provided that the following conditions are met:
948ed61a7SRobert Mustacchi 
1048ed61a7SRobert Mustacchi    1. Redistributions of source code must retain the above copyright notice,
1163b3bba8SJerry Jelinek       this list of conditions and the following disclaimer.
1248ed61a7SRobert Mustacchi 
1348ed61a7SRobert Mustacchi    2. Redistributions in binary form must reproduce the above copyright
1448ed61a7SRobert Mustacchi       notice, this list of conditions and the following disclaimer in the
1563b3bba8SJerry Jelinek       documentation and/or other materials provided with the distribution.
1648ed61a7SRobert Mustacchi 
1748ed61a7SRobert Mustacchi    3. Neither the name of the Intel Corporation nor the names of its
1848ed61a7SRobert Mustacchi       contributors may be used to endorse or promote products derived from
1963b3bba8SJerry Jelinek       this software without specific prior written permission.
2048ed61a7SRobert Mustacchi 
2163b3bba8SJerry Jelinek   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2248ed61a7SRobert Mustacchi   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2348ed61a7SRobert Mustacchi   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2448ed61a7SRobert Mustacchi   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2548ed61a7SRobert Mustacchi   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2648ed61a7SRobert Mustacchi   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2748ed61a7SRobert Mustacchi   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2848ed61a7SRobert Mustacchi   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2948ed61a7SRobert Mustacchi   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3063b3bba8SJerry Jelinek   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3163b3bba8SJerry Jelinek   POSSIBILITY OF SUCH DAMAGE.
3263b3bba8SJerry Jelinek 
3363b3bba8SJerry Jelinek ******************************************************************************/
34dc0cb1cdSDale Ghent /*$FreeBSD$*/
359da57d7bSbt 
369da57d7bSbt #include "ixgbe_type.h"
3769b5a878SDan McDonald #include "ixgbe_82598.h"
389da57d7bSbt #include "ixgbe_api.h"
399da57d7bSbt #include "ixgbe_common.h"
409da57d7bSbt #include "ixgbe_phy.h"
419da57d7bSbt 
42dc0cb1cdSDale Ghent #define IXGBE_82598_MAX_TX_QUEUES 32
43dc0cb1cdSDale Ghent #define IXGBE_82598_MAX_RX_QUEUES 64
44dc0cb1cdSDale Ghent #define IXGBE_82598_RAR_ENTRIES   16
45dc0cb1cdSDale Ghent #define IXGBE_82598_MC_TBL_SIZE  128
46dc0cb1cdSDale Ghent #define IXGBE_82598_VFT_TBL_SIZE 128
47dc0cb1cdSDale Ghent #define IXGBE_82598_RX_PB_SIZE   512
48dc0cb1cdSDale Ghent 
4913740cb2SPaul Guo static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
5069b5a878SDan McDonald 					     ixgbe_link_speed *speed,
5169b5a878SDan McDonald 					     bool *autoneg);
5213740cb2SPaul Guo static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw);
533cfa0eb9Schenlu chen - Sun Microsystems - Beijing China static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
5469b5a878SDan McDonald 				      bool autoneg_wait_to_complete);
5513740cb2SPaul Guo static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
5669b5a878SDan McDonald 				      ixgbe_link_speed *speed, bool *link_up,
5769b5a878SDan McDonald 				      bool link_up_wait_to_complete);
583cfa0eb9Schenlu chen - Sun Microsystems - Beijing China static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
5969b5a878SDan McDonald 				      ixgbe_link_speed speed,
6069b5a878SDan McDonald 				      bool autoneg_wait_to_complete);
613cfa0eb9Schenlu chen - Sun Microsystems - Beijing China static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
6269b5a878SDan McDonald 					 ixgbe_link_speed speed,
6369b5a878SDan McDonald 					 bool autoneg_wait_to_complete);
6413740cb2SPaul Guo static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
6513740cb2SPaul Guo static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
6613740cb2SPaul Guo static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw);
6769b5a878SDan McDonald static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
6869b5a878SDan McDonald 				  u32 headroom, int strategy);
69dc0cb1cdSDale Ghent static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
70dc0cb1cdSDale Ghent 					u8 *sff8472_data);
7163b3bba8SJerry Jelinek /**
7263b3bba8SJerry Jelinek  *  ixgbe_set_pcie_completion_timeout - set pci-e completion timeout
7363b3bba8SJerry Jelinek  *  @hw: pointer to the HW structure
743cfa0eb9Schenlu chen - Sun Microsystems - Beijing China  *
7563b3bba8SJerry Jelinek  *  The defaults for 82598 should be in the range of 50us to 50ms,
7663b3bba8SJerry Jelinek  *  however the hardware default for these parts is 500us to 1ms which is less
7763b3bba8SJerry Jelinek  *  than the 10ms recommended by the pci-e spec.  To address this we need to
7863b3bba8SJerry Jelinek  *  increase the value to either 10ms to 250ms for capability version 1 config,
7963b3bba8SJerry Jelinek  *  or 16ms to 55ms for version 2.
8063b3bba8SJerry Jelinek  **/
ixgbe_set_pcie_completion_timeout(struct ixgbe_hw * hw)8163b3bba8SJerry Jelinek void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
823cfa0eb9Schenlu chen - Sun Microsystems - Beijing China {
833cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR);
843cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	u16 pcie_devctl2;
853cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
863cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	/* only take action if timeout value is defaulted to 0 */
873cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK)
883cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		goto out;
893cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
903cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	/*
913cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 * if capababilities version is type 1 we can write the
923cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 * timeout of 10ms to 250ms through the GCR register
933cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 */
943cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	if (!(gcr & IXGBE_GCR_CAP_VER2)) {
953cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		gcr |= IXGBE_GCR_CMPL_TMOUT_10ms;
963cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		goto out;
973cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	}
983cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
993cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	/*
1003cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 * for version 2 capabilities we need to write the config space
1013cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 * directly in order to set the completion timeout value for
1023cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 * 16ms to 55ms
1033cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	 */
1043cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	pcie_devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2);
1053cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms;
1063cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	IXGBE_WRITE_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2);
1073cfa0eb9Schenlu chen - Sun Microsystems - Beijing China out:
1083cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	/* disable completion timeout resend */
1093cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	gcr &= ~IXGBE_GCR_CMPL_TMOUT_RESEND;
1103cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	IXGBE_WRITE_REG(hw, IXGBE_GCR, gcr);
1113cfa0eb9Schenlu chen - Sun Microsystems - Beijing China }
11273cd555cSBin Tu - Sun Microsystems - Beijing China 
11363b3bba8SJerry Jelinek /**
11463b3bba8SJerry Jelinek  *  ixgbe_init_ops_82598 - Inits func ptrs and MAC type
11563b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
1169da57d7bSbt  *
11763b3bba8SJerry Jelinek  *  Initialize the function pointers and assign the MAC type for 82598.
11863b3bba8SJerry Jelinek  *  Does not touch the hardware.
11963b3bba8SJerry Jelinek  **/
ixgbe_init_ops_82598(struct ixgbe_hw * hw)12063b3bba8SJerry Jelinek s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw)
1219da57d7bSbt {
1229da57d7bSbt 	struct ixgbe_mac_info *mac = &hw->mac;
12313740cb2SPaul Guo 	struct ixgbe_phy_info *phy = &hw->phy;
12473cd555cSBin Tu - Sun Microsystems - Beijing China 	s32 ret_val;
1259da57d7bSbt 
1263cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_init_ops_82598");
1273cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
12873cd555cSBin Tu - Sun Microsystems - Beijing China 	ret_val = ixgbe_init_phy_ops_generic(hw);
12973cd555cSBin Tu - Sun Microsystems - Beijing China 	ret_val = ixgbe_init_ops_generic(hw);
13073cd555cSBin Tu - Sun Microsystems - Beijing China 
13173cd555cSBin Tu - Sun Microsystems - Beijing China 	/* PHY */
132dc0cb1cdSDale Ghent 	phy->ops.init = ixgbe_init_phy_ops_82598;
1339da57d7bSbt 
1349da57d7bSbt 	/* MAC */
135dc0cb1cdSDale Ghent 	mac->ops.start_hw = ixgbe_start_hw_82598;
136dc0cb1cdSDale Ghent 	mac->ops.enable_relaxed_ordering = ixgbe_enable_relaxed_ordering_82598;
137dc0cb1cdSDale Ghent 	mac->ops.reset_hw = ixgbe_reset_hw_82598;
138dc0cb1cdSDale Ghent 	mac->ops.get_media_type = ixgbe_get_media_type_82598;
13913740cb2SPaul Guo 	mac->ops.get_supported_physical_layer =
140dc0cb1cdSDale Ghent 				ixgbe_get_supported_physical_layer_82598;
141dc0cb1cdSDale Ghent 	mac->ops.read_analog_reg8 = ixgbe_read_analog_reg8_82598;
142dc0cb1cdSDale Ghent 	mac->ops.write_analog_reg8 = ixgbe_write_analog_reg8_82598;
143dc0cb1cdSDale Ghent 	mac->ops.set_lan_id = ixgbe_set_lan_id_multi_port_pcie_82598;
144dc0cb1cdSDale Ghent 	mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_82598;
1459da57d7bSbt 
1469da57d7bSbt 	/* RAR, Multicast, VLAN */
147dc0cb1cdSDale Ghent 	mac->ops.set_vmdq = ixgbe_set_vmdq_82598;
148dc0cb1cdSDale Ghent 	mac->ops.clear_vmdq = ixgbe_clear_vmdq_82598;
149dc0cb1cdSDale Ghent 	mac->ops.set_vfta = ixgbe_set_vfta_82598;
15069b5a878SDan McDonald 	mac->ops.set_vlvf = NULL;
151dc0cb1cdSDale Ghent 	mac->ops.clear_vfta = ixgbe_clear_vfta_82598;
1529da57d7bSbt 
1539da57d7bSbt 	/* Flow Control */
154dc0cb1cdSDale Ghent 	mac->ops.fc_enable = ixgbe_fc_enable_82598;
155dc0cb1cdSDale Ghent 
156dc0cb1cdSDale Ghent 	mac->mcft_size		= IXGBE_82598_MC_TBL_SIZE;
157dc0cb1cdSDale Ghent 	mac->vft_size		= IXGBE_82598_VFT_TBL_SIZE;
158dc0cb1cdSDale Ghent 	mac->num_rar_entries	= IXGBE_82598_RAR_ENTRIES;
159dc0cb1cdSDale Ghent 	mac->rx_pb_size		= IXGBE_82598_RX_PB_SIZE;
160dc0cb1cdSDale Ghent 	mac->max_rx_queues	= IXGBE_82598_MAX_RX_QUEUES;
161dc0cb1cdSDale Ghent 	mac->max_tx_queues	= IXGBE_82598_MAX_TX_QUEUES;
16269b5a878SDan McDonald 	mac->max_msix_vectors	= ixgbe_get_pcie_msix_count_generic(hw);
1639da57d7bSbt 
16413740cb2SPaul Guo 	/* SFP+ Module */
165dc0cb1cdSDale Ghent 	phy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_82598;
166dc0cb1cdSDale Ghent 	phy->ops.read_i2c_sff8472 = ixgbe_read_i2c_sff8472_82598;
16713740cb2SPaul Guo 
16873cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Link */
169dc0cb1cdSDale Ghent 	mac->ops.check_link = ixgbe_check_mac_link_82598;
170dc0cb1cdSDale Ghent 	mac->ops.setup_link = ixgbe_setup_mac_link_82598;
1715b6dd21fSchenlu chen - Sun Microsystems - Beijing China 	mac->ops.flap_tx_laser = NULL;
172dc0cb1cdSDale Ghent 	mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_82598;
173dc0cb1cdSDale Ghent 	mac->ops.setup_rxpba = ixgbe_set_rxpba_82598;
17469b5a878SDan McDonald 
17569b5a878SDan McDonald 	/* Manageability interface */
17669b5a878SDan McDonald 	mac->ops.set_fw_drv_ver = NULL;
17773cd555cSBin Tu - Sun Microsystems - Beijing China 
178dc0cb1cdSDale Ghent 	mac->ops.get_rtrup2tc = NULL;
179dc0cb1cdSDale Ghent 
18063b3bba8SJerry Jelinek 	return ret_val;
18173cd555cSBin Tu - Sun Microsystems - Beijing China }
18273cd555cSBin Tu - Sun Microsystems - Beijing China 
18363b3bba8SJerry Jelinek /**
18463b3bba8SJerry Jelinek  *  ixgbe_init_phy_ops_82598 - PHY/SFP specific init
18563b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
18673cd555cSBin Tu - Sun Microsystems - Beijing China  *
18763b3bba8SJerry Jelinek  *  Initialize any function pointers that were not able to be
18863b3bba8SJerry Jelinek  *  set during init_shared_code because the PHY/SFP type was
18963b3bba8SJerry Jelinek  *  not known.  Perform the SFP init if necessary.
19073cd555cSBin Tu - Sun Microsystems - Beijing China  *
19163b3bba8SJerry Jelinek  **/
ixgbe_init_phy_ops_82598(struct ixgbe_hw * hw)19263b3bba8SJerry Jelinek s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
19373cd555cSBin Tu - Sun Microsystems - Beijing China {
19473cd555cSBin Tu - Sun Microsystems - Beijing China 	struct ixgbe_mac_info *mac = &hw->mac;
19573cd555cSBin Tu - Sun Microsystems - Beijing China 	struct ixgbe_phy_info *phy = &hw->phy;
19673cd555cSBin Tu - Sun Microsystems - Beijing China 	s32 ret_val = IXGBE_SUCCESS;
19773cd555cSBin Tu - Sun Microsystems - Beijing China 	u16 list_offset, data_offset;
19873cd555cSBin Tu - Sun Microsystems - Beijing China 
1993cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_init_phy_ops_82598");
2003cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
20173cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Identify the PHY */
20273cd555cSBin Tu - Sun Microsystems - Beijing China 	phy->ops.identify(hw);
20373cd555cSBin Tu - Sun Microsystems - Beijing China 
20473cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Overwrite the link function pointers if copper PHY */
20573cd555cSBin Tu - Sun Microsystems - Beijing China 	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
206dc0cb1cdSDale Ghent 		mac->ops.setup_link = ixgbe_setup_copper_link_82598;
20773cd555cSBin Tu - Sun Microsystems - Beijing China 		mac->ops.get_link_capabilities =
208dc0cb1cdSDale Ghent 				ixgbe_get_copper_link_capabilities_generic;
20973cd555cSBin Tu - Sun Microsystems - Beijing China 	}
21073cd555cSBin Tu - Sun Microsystems - Beijing China 
21113740cb2SPaul Guo 	switch (hw->phy.type) {
21213740cb2SPaul Guo 	case ixgbe_phy_tn:
213dc0cb1cdSDale Ghent 		phy->ops.setup_link = ixgbe_setup_phy_link_tnx;
214dc0cb1cdSDale Ghent 		phy->ops.check_link = ixgbe_check_phy_link_tnx;
21513740cb2SPaul Guo 		phy->ops.get_firmware_version =
216dc0cb1cdSDale Ghent 					ixgbe_get_phy_firmware_version_tnx;
217185c5677SPaul Guo 		break;
21813740cb2SPaul Guo 	case ixgbe_phy_nl:
219dc0cb1cdSDale Ghent 		phy->ops.reset = ixgbe_reset_phy_nl;
22013740cb2SPaul Guo 
22113740cb2SPaul Guo 		/* Call SFP+ identify routine to get the SFP+ module type */
22213740cb2SPaul Guo 		ret_val = phy->ops.identify_sfp(hw);
22313740cb2SPaul Guo 		if (ret_val != IXGBE_SUCCESS)
22413740cb2SPaul Guo 			goto out;
22513740cb2SPaul Guo 		else if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) {
22613740cb2SPaul Guo 			ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
22713740cb2SPaul Guo 			goto out;
22813740cb2SPaul Guo 		}
22913740cb2SPaul Guo 
23013740cb2SPaul Guo 		/* Check to see if SFP+ module is supported */
23113740cb2SPaul Guo 		ret_val = ixgbe_get_sfp_init_sequence_offsets(hw,
23269b5a878SDan McDonald 							      &list_offset,
23369b5a878SDan McDonald 							      &data_offset);
23413740cb2SPaul Guo 		if (ret_val != IXGBE_SUCCESS) {
23513740cb2SPaul Guo 			ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
23613740cb2SPaul Guo 			goto out;
23713740cb2SPaul Guo 		}
23813740cb2SPaul Guo 		break;
23913740cb2SPaul Guo 	default:
24013740cb2SPaul Guo 		break;
24113740cb2SPaul Guo 	}
24263b3bba8SJerry Jelinek 
24313740cb2SPaul Guo out:
24463b3bba8SJerry Jelinek 	return ret_val;
2459da57d7bSbt }
2469da57d7bSbt 
24763b3bba8SJerry Jelinek /**
24863b3bba8SJerry Jelinek  *  ixgbe_start_hw_82598 - Prepare hardware for Tx/Rx
24963b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
25063b3bba8SJerry Jelinek  *
25163b3bba8SJerry Jelinek  *  Starts the hardware using the generic start_hw function.
25263b3bba8SJerry Jelinek  *  Disables relaxed ordering Then set pcie completion timeout
2533cfa0eb9Schenlu chen - Sun Microsystems - Beijing China  *
25463b3bba8SJerry Jelinek  **/
ixgbe_start_hw_82598(struct ixgbe_hw * hw)25563b3bba8SJerry Jelinek s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
2563cfa0eb9Schenlu chen - Sun Microsystems - Beijing China {
25719843f01SPaul Guo 	u32 regval;
25819843f01SPaul Guo 	u32 i;
2593cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	s32 ret_val = IXGBE_SUCCESS;
2603cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
2613cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_start_hw_82598");
2623cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
2633cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	ret_val = ixgbe_start_hw_generic(hw);
264dc0cb1cdSDale Ghent 	if (ret_val)
265dc0cb1cdSDale Ghent 		return ret_val;
2663cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
26763b3bba8SJerry Jelinek 	/* Disable relaxed ordering */
26819843f01SPaul Guo 	for (i = 0; ((i < hw->mac.max_tx_queues) &&
26963b3bba8SJerry Jelinek 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
27019843f01SPaul Guo 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
27169b5a878SDan McDonald 		regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
27219843f01SPaul Guo 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
27319843f01SPaul Guo 	}
27419843f01SPaul Guo 
27519843f01SPaul Guo 	for (i = 0; ((i < hw->mac.max_rx_queues) &&
27663b3bba8SJerry Jelinek 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
27719843f01SPaul Guo 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
27869b5a878SDan McDonald 		regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
27969b5a878SDan McDonald 			    IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
28019843f01SPaul Guo 		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
28119843f01SPaul Guo 	}
28219843f01SPaul Guo 
2833cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	/* set the completion timeout for interface */
284dc0cb1cdSDale Ghent 	ixgbe_set_pcie_completion_timeout(hw);
2853cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
28663b3bba8SJerry Jelinek 	return ret_val;
2873cfa0eb9Schenlu chen - Sun Microsystems - Beijing China }
2883cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
28963b3bba8SJerry Jelinek /**
29063b3bba8SJerry Jelinek  *  ixgbe_get_link_capabilities_82598 - Determines link capabilities
29163b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
29263b3bba8SJerry Jelinek  *  @speed: pointer to link speed
29363b3bba8SJerry Jelinek  *  @autoneg: boolean auto-negotiation value
2949da57d7bSbt  *
29563b3bba8SJerry Jelinek  *  Determines the link capabilities by reading the AUTOC register.
29663b3bba8SJerry Jelinek  **/
ixgbe_get_link_capabilities_82598(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * autoneg)29763b3bba8SJerry Jelinek static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
29869b5a878SDan McDonald 					     ixgbe_link_speed *speed,
29969b5a878SDan McDonald 					     bool *autoneg)
3009da57d7bSbt {
3019da57d7bSbt 	s32 status = IXGBE_SUCCESS;
30273cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 autoc = 0;
3039da57d7bSbt 
3043cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_get_link_capabilities_82598");
3053cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
30673cd555cSBin Tu - Sun Microsystems - Beijing China 	/*
30773cd555cSBin Tu - Sun Microsystems - Beijing China 	 * Determine link capabilities based on the stored value of AUTOC,
30873cd555cSBin Tu - Sun Microsystems - Beijing China 	 * which represents EEPROM defaults.  If AUTOC value has not been
30973cd555cSBin Tu - Sun Microsystems - Beijing China 	 * stored, use the current register value.
31073cd555cSBin Tu - Sun Microsystems - Beijing China 	 */
31173cd555cSBin Tu - Sun Microsystems - Beijing China 	if (hw->mac.orig_link_settings_stored)
31273cd555cSBin Tu - Sun Microsystems - Beijing China 		autoc = hw->mac.orig_autoc;
31373cd555cSBin Tu - Sun Microsystems - Beijing China 	else
31473cd555cSBin Tu - Sun Microsystems - Beijing China 		autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
3159da57d7bSbt 
31673cd555cSBin Tu - Sun Microsystems - Beijing China 	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
3179da57d7bSbt 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
3189da57d7bSbt 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
31963b3bba8SJerry Jelinek 		*autoneg = FALSE;
3209da57d7bSbt 		break;
3219da57d7bSbt 
3229da57d7bSbt 	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
3239da57d7bSbt 		*speed = IXGBE_LINK_SPEED_10GB_FULL;
32463b3bba8SJerry Jelinek 		*autoneg = FALSE;
3259da57d7bSbt 		break;
3269da57d7bSbt 
3279da57d7bSbt 	case IXGBE_AUTOC_LMS_1G_AN:
3289da57d7bSbt 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
32963b3bba8SJerry Jelinek 		*autoneg = TRUE;
3309da57d7bSbt 		break;
3319da57d7bSbt 
3329da57d7bSbt 	case IXGBE_AUTOC_LMS_KX4_AN:
3339da57d7bSbt 	case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
3349da57d7bSbt 		*speed = IXGBE_LINK_SPEED_UNKNOWN;
33573cd555cSBin Tu - Sun Microsystems - Beijing China 		if (autoc & IXGBE_AUTOC_KX4_SUPP)
3369da57d7bSbt 			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
33773cd555cSBin Tu - Sun Microsystems - Beijing China 		if (autoc & IXGBE_AUTOC_KX_SUPP)
3389da57d7bSbt 			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
33963b3bba8SJerry Jelinek 		*autoneg = TRUE;
3409da57d7bSbt 		break;
3419da57d7bSbt 
3429da57d7bSbt 	default:
3439da57d7bSbt 		status = IXGBE_ERR_LINK_SETUP;
3449da57d7bSbt 		break;
3459da57d7bSbt 	}
3469da57d7bSbt 
34763b3bba8SJerry Jelinek 	return status;
3489da57d7bSbt }
3499da57d7bSbt 
35063b3bba8SJerry Jelinek /**
35163b3bba8SJerry Jelinek  *  ixgbe_get_media_type_82598 - Determines media type
35263b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
3539da57d7bSbt  *
35463b3bba8SJerry Jelinek  *  Returns the media type (fiber, copper, backplane)
35563b3bba8SJerry Jelinek  **/
ixgbe_get_media_type_82598(struct ixgbe_hw * hw)35663b3bba8SJerry Jelinek static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
3579da57d7bSbt {
3589da57d7bSbt 	enum ixgbe_media_type media_type;
3599da57d7bSbt 
3603cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_get_media_type_82598");
3613cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
36273cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Detect if there is a copper PHY attached. */
36363b3bba8SJerry Jelinek 	switch (hw->phy.type) {
36463b3bba8SJerry Jelinek 	case ixgbe_phy_cu_unknown:
36563b3bba8SJerry Jelinek 	case ixgbe_phy_tn:
36673cd555cSBin Tu - Sun Microsystems - Beijing China 		media_type = ixgbe_media_type_copper;
36773cd555cSBin Tu - Sun Microsystems - Beijing China 		goto out;
36863b3bba8SJerry Jelinek 	default:
36963b3bba8SJerry Jelinek 		break;
37073cd555cSBin Tu - Sun Microsystems - Beijing China 	}
37173cd555cSBin Tu - Sun Microsystems - Beijing China 
3729da57d7bSbt 	/* Media type for I82598 is based on device ID */
3739da57d7bSbt 	switch (hw->device_id) {
37473cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598:
37573cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598_BX:
37673cd555cSBin Tu - Sun Microsystems - Beijing China 		/* Default device ID is mezzanine card KX/KX4 */
37773cd555cSBin Tu - Sun Microsystems - Beijing China 		media_type = ixgbe_media_type_backplane;
37873cd555cSBin Tu - Sun Microsystems - Beijing China 		break;
3799da57d7bSbt 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
3809da57d7bSbt 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
38113740cb2SPaul Guo 	case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
38213740cb2SPaul Guo 	case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
3839da57d7bSbt 	case IXGBE_DEV_ID_82598EB_XF_LR:
38413740cb2SPaul Guo 	case IXGBE_DEV_ID_82598EB_SFP_LOM:
3859da57d7bSbt 		media_type = ixgbe_media_type_fiber;
3869da57d7bSbt 		break;
3873cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598EB_CX4:
3883cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
3893cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		media_type = ixgbe_media_type_cx4;
3903cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		break;
39113740cb2SPaul Guo 	case IXGBE_DEV_ID_82598AT:
3923cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598AT2:
39313740cb2SPaul Guo 		media_type = ixgbe_media_type_copper;
39413740cb2SPaul Guo 		break;
3959da57d7bSbt 	default:
3969da57d7bSbt 		media_type = ixgbe_media_type_unknown;
3979da57d7bSbt 		break;
3989da57d7bSbt 	}
39973cd555cSBin Tu - Sun Microsystems - Beijing China out:
40063b3bba8SJerry Jelinek 	return media_type;
4019da57d7bSbt }
4029da57d7bSbt 
40363b3bba8SJerry Jelinek /**
40463b3bba8SJerry Jelinek  *  ixgbe_fc_enable_82598 - Enable flow control
40563b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
4069da57d7bSbt  *
40763b3bba8SJerry Jelinek  *  Enable flow control according to the current settings.
40863b3bba8SJerry Jelinek  **/
ixgbe_fc_enable_82598(struct ixgbe_hw * hw)40969b5a878SDan McDonald s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
4109da57d7bSbt {
41173cd555cSBin Tu - Sun Microsystems - Beijing China 	s32 ret_val = IXGBE_SUCCESS;
41273cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 fctrl_reg;
4139da57d7bSbt 	u32 rmcs_reg;
41473cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 reg;
41569b5a878SDan McDonald 	u32 fcrtl, fcrth;
41619843f01SPaul Guo 	u32 link_speed = 0;
41769b5a878SDan McDonald 	int i;
41819843f01SPaul Guo 	bool link_up;
4199da57d7bSbt 
42073cd555cSBin Tu - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_fc_enable_82598");
42173cd555cSBin Tu - Sun Microsystems - Beijing China 
42269b5a878SDan McDonald 	/* Validate the water mark configuration */
42369b5a878SDan McDonald 	if (!hw->fc.pause_time) {
42469b5a878SDan McDonald 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
42569b5a878SDan McDonald 		goto out;
42669b5a878SDan McDonald 	}
42769b5a878SDan McDonald 
42869b5a878SDan McDonald 	/* Low water mark of zero causes XOFF floods */
42969b5a878SDan McDonald 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
43069b5a878SDan McDonald 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
43169b5a878SDan McDonald 		    hw->fc.high_water[i]) {
43269b5a878SDan McDonald 			if (!hw->fc.low_water[i] ||
43369b5a878SDan McDonald 			    hw->fc.low_water[i] >= hw->fc.high_water[i]) {
43469b5a878SDan McDonald 				DEBUGOUT("Invalid water mark configuration\n");
43569b5a878SDan McDonald 				ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
43669b5a878SDan McDonald 				goto out;
43769b5a878SDan McDonald 			}
43869b5a878SDan McDonald 		}
43969b5a878SDan McDonald 	}
44069b5a878SDan McDonald 
44119843f01SPaul Guo 	/*
4425b6dd21fSchenlu chen - Sun Microsystems - Beijing China 	 * On 82598 having Rx FC on causes resets while doing 1G
4435b6dd21fSchenlu chen - Sun Microsystems - Beijing China 	 * so if it's on turn it off once we know link_speed. For
4445b6dd21fSchenlu chen - Sun Microsystems - Beijing China 	 * more details see 82598 Specification update.
44519843f01SPaul Guo 	 */
44663b3bba8SJerry Jelinek 	hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
4475b6dd21fSchenlu chen - Sun Microsystems - Beijing China 	if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) {
4485b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		switch (hw->fc.requested_mode) {
4495b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		case ixgbe_fc_full:
4505b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			hw->fc.requested_mode = ixgbe_fc_tx_pause;
4515b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			break;
4525b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		case ixgbe_fc_rx_pause:
4535b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			hw->fc.requested_mode = ixgbe_fc_none;
4545b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			break;
4555b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		default:
4565b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			/* no change */
4575b6dd21fSchenlu chen - Sun Microsystems - Beijing China 			break;
4585b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		}
45919843f01SPaul Guo 	}
46019843f01SPaul Guo 
46173cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Negotiate the fc mode to use */
46269b5a878SDan McDonald 	ixgbe_fc_autoneg(hw);
4639da57d7bSbt 
46473cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Disable any previous flow control settings */
46573cd555cSBin Tu - Sun Microsystems - Beijing China 	fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
46673cd555cSBin Tu - Sun Microsystems - Beijing China 	fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
4679da57d7bSbt 
4689da57d7bSbt 	rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
4699da57d7bSbt 	rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
4709da57d7bSbt 
4719da57d7bSbt 	/*
47273cd555cSBin Tu - Sun Microsystems - Beijing China 	 * The possible values of fc.current_mode are:
4739da57d7bSbt 	 * 0: Flow control is completely disabled
47473cd555cSBin Tu - Sun Microsystems - Beijing China 	 * 1: Rx flow control is enabled (we can receive pause frames,
47573cd555cSBin Tu - Sun Microsystems - Beijing China 	 *    but not send pause frames).
47673cd555cSBin Tu - Sun Microsystems - Beijing China 	 * 2: Tx flow control is enabled (we can send pause frames but
47763b3bba8SJerry Jelinek 	 *     we do not support receiving pause frames).
4789da57d7bSbt 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
4799da57d7bSbt 	 * other: Invalid.
4809da57d7bSbt 	 */
48173cd555cSBin Tu - Sun Microsystems - Beijing China 	switch (hw->fc.current_mode) {
4829da57d7bSbt 	case ixgbe_fc_none:
48373cd555cSBin Tu - Sun Microsystems - Beijing China 		/*
48473cd555cSBin Tu - Sun Microsystems - Beijing China 		 * Flow control is disabled by software override or autoneg.
48573cd555cSBin Tu - Sun Microsystems - Beijing China 		 * The code below will actually disable it in the HW.
48673cd555cSBin Tu - Sun Microsystems - Beijing China 		 */
4879da57d7bSbt 		break;
4889da57d7bSbt 	case ixgbe_fc_rx_pause:
4899da57d7bSbt 		/*
49073cd555cSBin Tu - Sun Microsystems - Beijing China 		 * Rx Flow control is enabled and Tx Flow control is
49173cd555cSBin Tu - Sun Microsystems - Beijing China 		 * disabled by software override. Since there really
49273cd555cSBin Tu - Sun Microsystems - Beijing China 		 * isn't a way to advertise that we are capable of RX
49373cd555cSBin Tu - Sun Microsystems - Beijing China 		 * Pause ONLY, we will advertise that we support both
49473cd555cSBin Tu - Sun Microsystems - Beijing China 		 * symmetric and asymmetric Rx PAUSE.  Later, we will
49573cd555cSBin Tu - Sun Microsystems - Beijing China 		 * disable the adapter's ability to send PAUSE frames.
4969da57d7bSbt 		 */
49773cd555cSBin Tu - Sun Microsystems - Beijing China 		fctrl_reg |= IXGBE_FCTRL_RFCE;
4989da57d7bSbt 		break;
4999da57d7bSbt 	case ixgbe_fc_tx_pause:
5009da57d7bSbt 		/*
50173cd555cSBin Tu - Sun Microsystems - Beijing China 		 * Tx Flow control is enabled, and Rx Flow control is
50273cd555cSBin Tu - Sun Microsystems - Beijing China 		 * disabled by software override.
5039da57d7bSbt 		 */
5049da57d7bSbt 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
5059da57d7bSbt 		break;
5069da57d7bSbt 	case ixgbe_fc_full:
50773cd555cSBin Tu - Sun Microsystems - Beijing China 		/* Flow control (both Rx and Tx) is enabled by SW override. */
50873cd555cSBin Tu - Sun Microsystems - Beijing China 		fctrl_reg |= IXGBE_FCTRL_RFCE;
5099da57d7bSbt 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
5109da57d7bSbt 		break;
5119da57d7bSbt 	default:
5129da57d7bSbt 		DEBUGOUT("Flow control param set incorrectly\n");
5133cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		ret_val = IXGBE_ERR_CONFIG;
51473cd555cSBin Tu - Sun Microsystems - Beijing China 		goto out;
515dc0cb1cdSDale Ghent 		break;
5169da57d7bSbt 	}
5179da57d7bSbt 
51873cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Set 802.3x based flow control settings. */
51973cd555cSBin Tu - Sun Microsystems - Beijing China 	fctrl_reg |= IXGBE_FCTRL_DPF;
52073cd555cSBin Tu - Sun Microsystems - Beijing China 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
5219da57d7bSbt 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
5229da57d7bSbt 
52373cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
52469b5a878SDan McDonald 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
52569b5a878SDan McDonald 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
52669b5a878SDan McDonald 		    hw->fc.high_water[i]) {
52769b5a878SDan McDonald 			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
52869b5a878SDan McDonald 			fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
52969b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
53069b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth);
53169b5a878SDan McDonald 		} else {
53269b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
53369b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
53469b5a878SDan McDonald 		}
53563b3bba8SJerry Jelinek 
5369da57d7bSbt 	}
5379da57d7bSbt 
53873cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Configure pause time (2 TCs per register) */
53969b5a878SDan McDonald 	reg = hw->fc.pause_time * 0x00010001;
54069b5a878SDan McDonald 	for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
54169b5a878SDan McDonald 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
54273cd555cSBin Tu - Sun Microsystems - Beijing China 
54369b5a878SDan McDonald 	/* Configure flow control refresh threshold value */
54469b5a878SDan McDonald 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
5459da57d7bSbt 
54673cd555cSBin Tu - Sun Microsystems - Beijing China out:
54763b3bba8SJerry Jelinek 	return ret_val;
5489da57d7bSbt }
5499da57d7bSbt 
55063b3bba8SJerry Jelinek /**
55163b3bba8SJerry Jelinek  *  ixgbe_start_mac_link_82598 - Configures MAC link settings
55263b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
55348ed61a7SRobert Mustacchi  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
5549da57d7bSbt  *
55563b3bba8SJerry Jelinek  *  Configures link settings based on values in the ixgbe_hw struct.
55663b3bba8SJerry Jelinek  *  Restarts the link.  Performs autonegotiation if needed.
55763b3bba8SJerry Jelinek  **/
ixgbe_start_mac_link_82598(struct ixgbe_hw * hw,bool autoneg_wait_to_complete)55863b3bba8SJerry Jelinek static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
55969b5a878SDan McDonald 				      bool autoneg_wait_to_complete)
5609da57d7bSbt {
5619da57d7bSbt 	u32 autoc_reg;
5629da57d7bSbt 	u32 links_reg;
5639da57d7bSbt 	u32 i;
5649da57d7bSbt 	s32 status = IXGBE_SUCCESS;
5659da57d7bSbt 
5663cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_start_mac_link_82598");
5673cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
5689da57d7bSbt 	/* Restart link */
56973cd555cSBin Tu - Sun Microsystems - Beijing China 	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
5709da57d7bSbt 	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
5719da57d7bSbt 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
5729da57d7bSbt 
5739da57d7bSbt 	/* Only poll for autoneg to complete if specified to do so */
5743cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	if (autoneg_wait_to_complete) {
57573cd555cSBin Tu - Sun Microsystems - Beijing China 		if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
57663b3bba8SJerry Jelinek 		     IXGBE_AUTOC_LMS_KX4_AN ||
57773cd555cSBin Tu - Sun Microsystems - Beijing China 		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
57863b3bba8SJerry Jelinek 		     IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
5799da57d7bSbt 			links_reg = 0; /* Just in case Autoneg time = 0 */
5809da57d7bSbt 			for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
5819da57d7bSbt 				links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
5829da57d7bSbt 				if (links_reg & IXGBE_LINKS_KX_AN_COMP)
5839da57d7bSbt 					break;
5849da57d7bSbt 				msec_delay(100);
5859da57d7bSbt 			}
5869da57d7bSbt 			if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
5879da57d7bSbt 				status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
5889da57d7bSbt 				DEBUGOUT("Autonegotiation did not complete.\n");
5899da57d7bSbt 			}
5909da57d7bSbt 		}
5919da57d7bSbt 	}
5929da57d7bSbt 
5939da57d7bSbt 	/* Add delay to filter out noises during initial link setup */
5949da57d7bSbt 	msec_delay(50);
5959da57d7bSbt 
59663b3bba8SJerry Jelinek 	return status;
5979da57d7bSbt }
5989da57d7bSbt 
59963b3bba8SJerry Jelinek /**
60063b3bba8SJerry Jelinek  *  ixgbe_validate_link_ready - Function looks for phy link
60163b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
6029da57d7bSbt  *
60363b3bba8SJerry Jelinek  *  Function indicates success when phy link is available. If phy is not ready
60463b3bba8SJerry Jelinek  *  within 5 seconds of MAC indicating link, the function returns error.
60563b3bba8SJerry Jelinek  **/
ixgbe_validate_link_ready(struct ixgbe_hw * hw)60663b3bba8SJerry Jelinek static s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw)
60763b3bba8SJerry Jelinek {
60863b3bba8SJerry Jelinek 	u32 timeout;
60963b3bba8SJerry Jelinek 	u16 an_reg;
61063b3bba8SJerry Jelinek 
61163b3bba8SJerry Jelinek 	if (hw->device_id != IXGBE_DEV_ID_82598AT2)
61263b3bba8SJerry Jelinek 		return IXGBE_SUCCESS;
61363b3bba8SJerry Jelinek 
61463b3bba8SJerry Jelinek 	for (timeout = 0;
61563b3bba8SJerry Jelinek 	     timeout < IXGBE_VALIDATE_LINK_READY_TIMEOUT; timeout++) {
61663b3bba8SJerry Jelinek 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
61769b5a878SDan McDonald 				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &an_reg);
61863b3bba8SJerry Jelinek 
61963b3bba8SJerry Jelinek 		if ((an_reg & IXGBE_MII_AUTONEG_COMPLETE) &&
62063b3bba8SJerry Jelinek 		    (an_reg & IXGBE_MII_AUTONEG_LINK_UP))
62163b3bba8SJerry Jelinek 			break;
62263b3bba8SJerry Jelinek 
62363b3bba8SJerry Jelinek 		msec_delay(100);
62463b3bba8SJerry Jelinek 	}
62563b3bba8SJerry Jelinek 
62663b3bba8SJerry Jelinek 	if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) {
62763b3bba8SJerry Jelinek 		DEBUGOUT("Link was indicated but link is down\n");
62863b3bba8SJerry Jelinek 		return IXGBE_ERR_LINK_SETUP;
62963b3bba8SJerry Jelinek 	}
63063b3bba8SJerry Jelinek 
63163b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
63263b3bba8SJerry Jelinek }
63363b3bba8SJerry Jelinek 
63463b3bba8SJerry Jelinek /**
63563b3bba8SJerry Jelinek  *  ixgbe_check_mac_link_82598 - Get link/speed status
63663b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
63763b3bba8SJerry Jelinek  *  @speed: pointer to link speed
63863b3bba8SJerry Jelinek  *  @link_up: TRUE is link is up, FALSE otherwise
63963b3bba8SJerry Jelinek  *  @link_up_wait_to_complete: bool used to wait for link up or not
64063b3bba8SJerry Jelinek  *
64163b3bba8SJerry Jelinek  *  Reads the links register to determine if link is up and the current speed
64263b3bba8SJerry Jelinek  **/
ixgbe_check_mac_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * link_up,bool link_up_wait_to_complete)64363b3bba8SJerry Jelinek static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
64469b5a878SDan McDonald 				      ixgbe_link_speed *speed, bool *link_up,
64569b5a878SDan McDonald 				      bool link_up_wait_to_complete)
6469da57d7bSbt {
6479da57d7bSbt 	u32 links_reg;
64813740cb2SPaul Guo 	u32 i;
64913740cb2SPaul Guo 	u16 link_reg, adapt_comp_reg;
6509da57d7bSbt 
6513cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_check_mac_link_82598");
6523cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
65313740cb2SPaul Guo 	/*
65413740cb2SPaul Guo 	 * SERDES PHY requires us to read link status from undocumented
65513740cb2SPaul Guo 	 * register 0xC79F.  Bit 0 set indicates link is up/ready; clear
65613740cb2SPaul Guo 	 * indicates link down.  OxC00C is read to check that the XAUI lanes
65713740cb2SPaul Guo 	 * are active.  Bit 0 clear indicates active; set indicates inactive.
65813740cb2SPaul Guo 	 */
65913740cb2SPaul Guo 	if (hw->phy.type == ixgbe_phy_nl) {
66013740cb2SPaul Guo 		hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
66113740cb2SPaul Guo 		hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
66213740cb2SPaul Guo 		hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV,
66369b5a878SDan McDonald 				     &adapt_comp_reg);
66413740cb2SPaul Guo 		if (link_up_wait_to_complete) {
665dc0cb1cdSDale Ghent 			for (i = 0; i < hw->mac.max_link_up_time; i++) {
66613740cb2SPaul Guo 				if ((link_reg & 1) &&
66713740cb2SPaul Guo 				    ((adapt_comp_reg & 1) == 0)) {
66863b3bba8SJerry Jelinek 					*link_up = TRUE;
66913740cb2SPaul Guo 					break;
67013740cb2SPaul Guo 				} else {
67163b3bba8SJerry Jelinek 					*link_up = FALSE;
67213740cb2SPaul Guo 				}
67313740cb2SPaul Guo 				msec_delay(100);
67413740cb2SPaul Guo 				hw->phy.ops.read_reg(hw, 0xC79F,
67569b5a878SDan McDonald 						     IXGBE_TWINAX_DEV,
67669b5a878SDan McDonald 						     &link_reg);
67713740cb2SPaul Guo 				hw->phy.ops.read_reg(hw, 0xC00C,
67869b5a878SDan McDonald 						     IXGBE_TWINAX_DEV,
67969b5a878SDan McDonald 						     &adapt_comp_reg);
68013740cb2SPaul Guo 			}
68113740cb2SPaul Guo 		} else {
68263b3bba8SJerry Jelinek 			if ((link_reg & 1) && ((adapt_comp_reg & 1) == 0))
68363b3bba8SJerry Jelinek 				*link_up = TRUE;
68413740cb2SPaul Guo 			else
68563b3bba8SJerry Jelinek 				*link_up = FALSE;
68613740cb2SPaul Guo 		}
6879da57d7bSbt 
68863b3bba8SJerry Jelinek 		if (*link_up == FALSE)
68913740cb2SPaul Guo 			goto out;
69013740cb2SPaul Guo 	}
69113740cb2SPaul Guo 
69213740cb2SPaul Guo 	links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
69313740cb2SPaul Guo 	if (link_up_wait_to_complete) {
694dc0cb1cdSDale Ghent 		for (i = 0; i < hw->mac.max_link_up_time; i++) {
69513740cb2SPaul Guo 			if (links_reg & IXGBE_LINKS_UP) {
69663b3bba8SJerry Jelinek 				*link_up = TRUE;
69713740cb2SPaul Guo 				break;
69813740cb2SPaul Guo 			} else {
69963b3bba8SJerry Jelinek 				*link_up = FALSE;
70013740cb2SPaul Guo 			}
70113740cb2SPaul Guo 			msec_delay(100);
70213740cb2SPaul Guo 			links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
70313740cb2SPaul Guo 		}
70413740cb2SPaul Guo 	} else {
70513740cb2SPaul Guo 		if (links_reg & IXGBE_LINKS_UP)
70663b3bba8SJerry Jelinek 			*link_up = TRUE;
70713740cb2SPaul Guo 		else
70863b3bba8SJerry Jelinek 			*link_up = FALSE;
70913740cb2SPaul Guo 	}
7109da57d7bSbt 
7119da57d7bSbt 	if (links_reg & IXGBE_LINKS_SPEED)
7129da57d7bSbt 		*speed = IXGBE_LINK_SPEED_10GB_FULL;
7139da57d7bSbt 	else
7149da57d7bSbt 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
7159da57d7bSbt 
71663b3bba8SJerry Jelinek 	if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && (*link_up == TRUE) &&
71719843f01SPaul Guo 	    (ixgbe_validate_link_ready(hw) != IXGBE_SUCCESS))
71863b3bba8SJerry Jelinek 		*link_up = FALSE;
71919843f01SPaul Guo 
72013740cb2SPaul Guo out:
72163b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
7229da57d7bSbt }
7239da57d7bSbt 
72463b3bba8SJerry Jelinek /**
72563b3bba8SJerry Jelinek  *  ixgbe_setup_mac_link_82598 - Set MAC link speed
72663b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
72763b3bba8SJerry Jelinek  *  @speed: new link speed
72863b3bba8SJerry Jelinek  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
7299da57d7bSbt  *
73063b3bba8SJerry Jelinek  *  Set the link speed in the AUTOC register and restarts link.
73163b3bba8SJerry Jelinek  **/
ixgbe_setup_mac_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)73263b3bba8SJerry Jelinek static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
733dc0cb1cdSDale Ghent 				      ixgbe_link_speed speed,
73469b5a878SDan McDonald 				      bool autoneg_wait_to_complete)
7359da57d7bSbt {
736dc0cb1cdSDale Ghent 	bool autoneg = FALSE;
737dc0cb1cdSDale Ghent 	s32 status = IXGBE_SUCCESS;
73873cd555cSBin Tu - Sun Microsystems - Beijing China 	ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
73969b5a878SDan McDonald 	u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
74069b5a878SDan McDonald 	u32 autoc = curr_autoc;
74169b5a878SDan McDonald 	u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
7429da57d7bSbt 
7433cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_setup_mac_link_82598");
7443cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
74573cd555cSBin Tu - Sun Microsystems - Beijing China 	/* Check to see if speed passed in is supported. */
746dc0cb1cdSDale Ghent 	ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
74773cd555cSBin Tu - Sun Microsystems - Beijing China 	speed &= link_capabilities;
74873cd555cSBin Tu - Sun Microsystems - Beijing China 
74963b3bba8SJerry Jelinek 	if (speed == IXGBE_LINK_SPEED_UNKNOWN)
7509da57d7bSbt 		status = IXGBE_ERR_LINK_SETUP;
75163b3bba8SJerry Jelinek 
75263b3bba8SJerry Jelinek 	/* Set KX4/KX support according to speed requested */
75363b3bba8SJerry Jelinek 	else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
75469b5a878SDan McDonald 		 link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
75573cd555cSBin Tu - Sun Microsystems - Beijing China 		autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK;
75673cd555cSBin Tu - Sun Microsystems - Beijing China 		if (speed & IXGBE_LINK_SPEED_10GB_FULL)
75773cd555cSBin Tu - Sun Microsystems - Beijing China 			autoc |= IXGBE_AUTOC_KX4_SUPP;
75873cd555cSBin Tu - Sun Microsystems - Beijing China 		if (speed & IXGBE_LINK_SPEED_1GB_FULL)
75973cd555cSBin Tu - Sun Microsystems - Beijing China 			autoc |= IXGBE_AUTOC_KX_SUPP;
76073cd555cSBin Tu - Sun Microsystems - Beijing China 		if (autoc != curr_autoc)
76173cd555cSBin Tu - Sun Microsystems - Beijing China 			IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
7629da57d7bSbt 	}
7639da57d7bSbt 
7649da57d7bSbt 	if (status == IXGBE_SUCCESS) {
7659da57d7bSbt 		/*
7669da57d7bSbt 		 * Setup and restart the link based on the new values in
7679da57d7bSbt 		 * ixgbe_hw This will write the AUTOC register based on the new
7689da57d7bSbt 		 * stored values
7699da57d7bSbt 		 */
7703cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 		status = ixgbe_start_mac_link_82598(hw,
77169b5a878SDan McDonald 						    autoneg_wait_to_complete);
7729da57d7bSbt 	}
7739da57d7bSbt 
77463b3bba8SJerry Jelinek 	return status;
7759da57d7bSbt }
7769da57d7bSbt 
77763b3bba8SJerry Jelinek 
77863b3bba8SJerry Jelinek /**
77963b3bba8SJerry Jelinek  *  ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field
78063b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
78163b3bba8SJerry Jelinek  *  @speed: new link speed
78263b3bba8SJerry Jelinek  *  @autoneg_wait_to_complete: TRUE if waiting is needed to complete
7839da57d7bSbt  *
78463b3bba8SJerry Jelinek  *  Sets the link speed in the AUTOC register in the MAC and restarts link.
78563b3bba8SJerry Jelinek  **/
ixgbe_setup_copper_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)78663b3bba8SJerry Jelinek static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
78769b5a878SDan McDonald 					 ixgbe_link_speed speed,
78869b5a878SDan McDonald 					 bool autoneg_wait_to_complete)
7899da57d7bSbt {
7909da57d7bSbt 	s32 status;
7919da57d7bSbt 
7923cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_setup_copper_link_82598");
7933cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
7949da57d7bSbt 	/* Setup the PHY according to input speed */
795dc0cb1cdSDale Ghent 	status = hw->phy.ops.setup_link_speed(hw, speed,
79669b5a878SDan McDonald 					      autoneg_wait_to_complete);
797dc0cb1cdSDale Ghent 	/* Set up MAC */
798dc0cb1cdSDale Ghent 	ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
7999da57d7bSbt 
80063b3bba8SJerry Jelinek 	return status;
8019da57d7bSbt }
8029da57d7bSbt 
80363b3bba8SJerry Jelinek /**
80463b3bba8SJerry Jelinek  *  ixgbe_reset_hw_82598 - Performs hardware reset
80563b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
8069da57d7bSbt  *
80763b3bba8SJerry Jelinek  *  Resets the hardware by resetting the transmit and receive units, masks and
80863b3bba8SJerry Jelinek  *  clears all interrupts, performing a PHY reset, and performing a link (MAC)
80963b3bba8SJerry Jelinek  *  reset.
81063b3bba8SJerry Jelinek  **/
ixgbe_reset_hw_82598(struct ixgbe_hw * hw)81163b3bba8SJerry Jelinek static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
8129da57d7bSbt {
8139da57d7bSbt 	s32 status = IXGBE_SUCCESS;
814185c5677SPaul Guo 	s32 phy_status = IXGBE_SUCCESS;
8159da57d7bSbt 	u32 ctrl;
8169da57d7bSbt 	u32 gheccr;
8179da57d7bSbt 	u32 i;
8189da57d7bSbt 	u32 autoc;
8199da57d7bSbt 	u8  analog_val;
8209da57d7bSbt 
8213cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_reset_hw_82598");
8223cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
8239da57d7bSbt 	/* Call adapter stop to disable tx/rx and clear interrupts */
82469b5a878SDan McDonald 	status = hw->mac.ops.stop_adapter(hw);
82569b5a878SDan McDonald 	if (status != IXGBE_SUCCESS)
82669b5a878SDan McDonald 		goto reset_hw_out;
8279da57d7bSbt 
8289da57d7bSbt 	/*
8299da57d7bSbt 	 * Power up the Atlas Tx lanes if they are currently powered down.
8309da57d7bSbt 	 * Atlas Tx lanes are powered down for MAC loopback tests, but
8319da57d7bSbt 	 * they are not automatically restored on reset.
8329da57d7bSbt 	 */
8339da57d7bSbt 	hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
8349da57d7bSbt 	if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) {
8359da57d7bSbt 		/* Enable Tx Atlas so packets can be transmitted again */
8369da57d7bSbt 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
83769b5a878SDan McDonald 					     &analog_val);
8389da57d7bSbt 		analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN;
8399da57d7bSbt 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
84069b5a878SDan McDonald 					      analog_val);
8419da57d7bSbt 
8429da57d7bSbt 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
84369b5a878SDan McDonald 					     &analog_val);
84413740cb2SPaul Guo 		analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
8459da57d7bSbt 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
84669b5a878SDan McDonald 					      analog_val);
8479da57d7bSbt 
8489da57d7bSbt 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
84969b5a878SDan McDonald 					     &analog_val);
8509da57d7bSbt 		analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
8519da57d7bSbt 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
85269b5a878SDan McDonald 					      analog_val);
8539da57d7bSbt 
8549da57d7bSbt 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
85569b5a878SDan McDonald 					     &analog_val);
8569da57d7bSbt 		analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
8579da57d7bSbt 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
85869b5a878SDan McDonald 					      analog_val);
8599da57d7bSbt 	}
8609da57d7bSbt 
8619da57d7bSbt 	/* Reset PHY */
86263b3bba8SJerry Jelinek 	if (hw->phy.reset_disable == FALSE) {
86373cd555cSBin Tu - Sun Microsystems - Beijing China 		/* PHY ops must be identified and initialized prior to reset */
86473cd555cSBin Tu - Sun Microsystems - Beijing China 
86573cd555cSBin Tu - Sun Microsystems - Beijing China 		/* Init PHY and function pointers, perform SFP setup */
866185c5677SPaul Guo 		phy_status = hw->phy.ops.init(hw);
867185c5677SPaul Guo 		if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
868185c5677SPaul Guo 			goto reset_hw_out;
86969b5a878SDan McDonald 		if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT)
87069b5a878SDan McDonald 			goto mac_reset_top;
87173cd555cSBin Tu - Sun Microsystems - Beijing China 
87213740cb2SPaul Guo 		hw->phy.ops.reset(hw);
87373cd555cSBin Tu - Sun Microsystems - Beijing China 	}
8749da57d7bSbt 
87519843f01SPaul Guo mac_reset_top:
8769da57d7bSbt 	/*
8779da57d7bSbt 	 * Issue global reset to the MAC.  This needs to be a SW reset.
8789da57d7bSbt 	 * If link reset is used, it might reset the MAC when mng is using it
8799da57d7bSbt 	 */
88069b5a878SDan McDonald 	ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL) | IXGBE_CTRL_RST;
88169b5a878SDan McDonald 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
8829da57d7bSbt 	IXGBE_WRITE_FLUSH(hw);
8839da57d7bSbt 
8849da57d7bSbt 	/* Poll for reset bit to self-clear indicating reset is complete */
8859da57d7bSbt 	for (i = 0; i < 10; i++) {
8869da57d7bSbt 		usec_delay(1);
8879da57d7bSbt 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
8889da57d7bSbt 		if (!(ctrl & IXGBE_CTRL_RST))
8899da57d7bSbt 			break;
8909da57d7bSbt 	}
8919da57d7bSbt 	if (ctrl & IXGBE_CTRL_RST) {
8929da57d7bSbt 		status = IXGBE_ERR_RESET_FAILED;
8939da57d7bSbt 		DEBUGOUT("Reset polling failed to complete.\n");
8949da57d7bSbt 	}
8959da57d7bSbt 
89669b5a878SDan McDonald 	msec_delay(50);
89769b5a878SDan McDonald 
89819843f01SPaul Guo 	/*
89919843f01SPaul Guo 	 * Double resets are required for recovery from certain error
90019843f01SPaul Guo 	 * conditions.  Between resets, it is necessary to stall to allow time
90169b5a878SDan McDonald 	 * for any pending HW events to complete.
90219843f01SPaul Guo 	 */
90319843f01SPaul Guo 	if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
90419843f01SPaul Guo 		hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
90519843f01SPaul Guo 		goto mac_reset_top;
90619843f01SPaul Guo 	}
90763b3bba8SJerry Jelinek 
9089da57d7bSbt 	gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR);
9099da57d7bSbt 	gheccr &= ~((1 << 21) | (1 << 18) | (1 << 9) | (1 << 6));
9109da57d7bSbt 	IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
9119da57d7bSbt 
9129da57d7bSbt 	/*
91373cd555cSBin Tu - Sun Microsystems - Beijing China 	 * Store the original AUTOC value if it has not been
91473cd555cSBin Tu - Sun Microsystems - Beijing China 	 * stored off yet.  Otherwise restore the stored original
915*9b622488SToomas Soome 	 * AUTOC value since the reset operation sets back to defaults.
9169da57d7bSbt 	 */
9179da57d7bSbt 	autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
91863b3bba8SJerry Jelinek 	if (hw->mac.orig_link_settings_stored == FALSE) {
91973cd555cSBin Tu - Sun Microsystems - Beijing China 		hw->mac.orig_autoc = autoc;
92063b3bba8SJerry Jelinek 		hw->mac.orig_link_settings_stored = TRUE;
92173cd555cSBin Tu - Sun Microsystems - Beijing China 	} else if (autoc != hw->mac.orig_autoc) {
92273cd555cSBin Tu - Sun Microsystems - Beijing China 		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
9239da57d7bSbt 	}
9249da57d7bSbt 
925185c5677SPaul Guo 	/* Store the permanent mac address */
926185c5677SPaul Guo 	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
927185c5677SPaul Guo 
92873cd555cSBin Tu - Sun Microsystems - Beijing China 	/*
92973cd555cSBin Tu - Sun Microsystems - Beijing China 	 * Store MAC address from RAR0, clear receive address registers, and
93073cd555cSBin Tu - Sun Microsystems - Beijing China 	 * clear the multicast table
93173cd555cSBin Tu - Sun Microsystems - Beijing China 	 */
93273cd555cSBin Tu - Sun Microsystems - Beijing China 	hw->mac.ops.init_rx_addrs(hw);
93373cd555cSBin Tu - Sun Microsystems - Beijing China 
934185c5677SPaul Guo reset_hw_out:
935185c5677SPaul Guo 	if (phy_status != IXGBE_SUCCESS)
936185c5677SPaul Guo 		status = phy_status;
9379da57d7bSbt 
93863b3bba8SJerry Jelinek 	return status;
9399da57d7bSbt }
9409da57d7bSbt 
94163b3bba8SJerry Jelinek /**
94263b3bba8SJerry Jelinek  *  ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address
94363b3bba8SJerry Jelinek  *  @hw: pointer to hardware struct
94463b3bba8SJerry Jelinek  *  @rar: receive address register index to associate with a VMDq index
94563b3bba8SJerry Jelinek  *  @vmdq: VMDq set index
94663b3bba8SJerry Jelinek  **/
ixgbe_set_vmdq_82598(struct ixgbe_hw * hw,u32 rar,u32 vmdq)94763b3bba8SJerry Jelinek s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
9489da57d7bSbt {
9499da57d7bSbt 	u32 rar_high;
95063b3bba8SJerry Jelinek 	u32 rar_entries = hw->mac.num_rar_entries;
9519da57d7bSbt 
9523cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_set_vmdq_82598");
9533cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
95463b3bba8SJerry Jelinek 	/* Make sure we are using a valid rar index range */
95563b3bba8SJerry Jelinek 	if (rar >= rar_entries) {
95663b3bba8SJerry Jelinek 		DEBUGOUT1("RAR index %d is out of range.\n", rar);
95763b3bba8SJerry Jelinek 		return IXGBE_ERR_INVALID_ARGUMENT;
95863b3bba8SJerry Jelinek 	}
95963b3bba8SJerry Jelinek 
9609da57d7bSbt 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
9619da57d7bSbt 	rar_high &= ~IXGBE_RAH_VIND_MASK;
9629da57d7bSbt 	rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK);
9639da57d7bSbt 	IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
96463b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
9659da57d7bSbt }
9669da57d7bSbt 
96763b3bba8SJerry Jelinek /**
96863b3bba8SJerry Jelinek  *  ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address
96963b3bba8SJerry Jelinek  *  @hw: pointer to hardware struct
97063b3bba8SJerry Jelinek  *  @rar: receive address register index to associate with a VMDq index
97163b3bba8SJerry Jelinek  *  @vmdq: VMDq clear index (not used in 82598, but elsewhere)
97263b3bba8SJerry Jelinek  **/
ixgbe_clear_vmdq_82598(struct ixgbe_hw * hw,u32 rar,u32 vmdq)97363b3bba8SJerry Jelinek static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
97413740cb2SPaul Guo {
97513740cb2SPaul Guo 	u32 rar_high;
97613740cb2SPaul Guo 	u32 rar_entries = hw->mac.num_rar_entries;
97713740cb2SPaul Guo 
97869b5a878SDan McDonald 	UNREFERENCED_1PARAMETER(vmdq);
97913740cb2SPaul Guo 
98063b3bba8SJerry Jelinek 	/* Make sure we are using a valid rar index range */
98163b3bba8SJerry Jelinek 	if (rar >= rar_entries) {
98213740cb2SPaul Guo 		DEBUGOUT1("RAR index %d is out of range.\n", rar);
98363b3bba8SJerry Jelinek 		return IXGBE_ERR_INVALID_ARGUMENT;
98463b3bba8SJerry Jelinek 	}
98563b3bba8SJerry Jelinek 
98663b3bba8SJerry Jelinek 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
98763b3bba8SJerry Jelinek 	if (rar_high & IXGBE_RAH_VIND_MASK) {
98863b3bba8SJerry Jelinek 		rar_high &= ~IXGBE_RAH_VIND_MASK;
98963b3bba8SJerry Jelinek 		IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
99013740cb2SPaul Guo 	}
99113740cb2SPaul Guo 
99263b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
99313740cb2SPaul Guo }
99413740cb2SPaul Guo 
99563b3bba8SJerry Jelinek /**
99663b3bba8SJerry Jelinek  *  ixgbe_set_vfta_82598 - Set VLAN filter table
99763b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
99863b3bba8SJerry Jelinek  *  @vlan: VLAN id to write to VLAN filter
99963b3bba8SJerry Jelinek  *  @vind: VMDq output index that maps queue to VLAN id in VFTA
100063b3bba8SJerry Jelinek  *  @vlan_on: boolean flag to turn on/off VLAN in VFTA
100148ed61a7SRobert Mustacchi  *  @vlvf_bypass: boolean flag - unused
100213740cb2SPaul Guo  *
100363b3bba8SJerry Jelinek  *  Turn on/off specified VLAN in the VLAN filter table.
100463b3bba8SJerry Jelinek  **/
ixgbe_set_vfta_82598(struct ixgbe_hw * hw,u32 vlan,u32 vind,bool vlan_on,bool vlvf_bypass)100563b3bba8SJerry Jelinek s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind,
100648ed61a7SRobert Mustacchi 			 bool vlan_on, bool vlvf_bypass)
100713740cb2SPaul Guo {
100813740cb2SPaul Guo 	u32 regindex;
100913740cb2SPaul Guo 	u32 bitindex;
101013740cb2SPaul Guo 	u32 bits;
101113740cb2SPaul Guo 	u32 vftabyte;
101213740cb2SPaul Guo 
101348ed61a7SRobert Mustacchi 	UNREFERENCED_1PARAMETER(vlvf_bypass);
101448ed61a7SRobert Mustacchi 
10153cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_set_vfta_82598");
10163cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
101713740cb2SPaul Guo 	if (vlan > 4095)
101863b3bba8SJerry Jelinek 		return IXGBE_ERR_PARAM;
101913740cb2SPaul Guo 
102013740cb2SPaul Guo 	/* Determine 32-bit word position in array */
102113740cb2SPaul Guo 	regindex = (vlan >> 5) & 0x7F;   /* upper seven bits */
102213740cb2SPaul Guo 
102313740cb2SPaul Guo 	/* Determine the location of the (VMD) queue index */
102413740cb2SPaul Guo 	vftabyte =  ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
102513740cb2SPaul Guo 	bitindex = (vlan & 0x7) << 2;    /* lower 3 bits indicate nibble */
102613740cb2SPaul Guo 
102713740cb2SPaul Guo 	/* Set the nibble for VMD queue index */
102813740cb2SPaul Guo 	bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex));
102913740cb2SPaul Guo 	bits &= (~(0x0F << bitindex));
103013740cb2SPaul Guo 	bits |= (vind << bitindex);
103113740cb2SPaul Guo 	IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits);
103213740cb2SPaul Guo 
103313740cb2SPaul Guo 	/* Determine the location of the bit for this VLAN id */
103413740cb2SPaul Guo 	bitindex = vlan & 0x1F;   /* lower five bits */
103513740cb2SPaul Guo 
103613740cb2SPaul Guo 	bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
103713740cb2SPaul Guo 	if (vlan_on)
103813740cb2SPaul Guo 		/* Turn on this VLAN id */
103913740cb2SPaul Guo 		bits |= (1 << bitindex);
104013740cb2SPaul Guo 	else
104113740cb2SPaul Guo 		/* Turn off this VLAN id */
104213740cb2SPaul Guo 		bits &= ~(1 << bitindex);
104313740cb2SPaul Guo 	IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
104413740cb2SPaul Guo 
104563b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
104613740cb2SPaul Guo }
104713740cb2SPaul Guo 
104863b3bba8SJerry Jelinek /**
104963b3bba8SJerry Jelinek  *  ixgbe_clear_vfta_82598 - Clear VLAN filter table
105063b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
105113740cb2SPaul Guo  *
105263b3bba8SJerry Jelinek  *  Clears the VLAN filer table, and the VMDq index associated with the filter
105363b3bba8SJerry Jelinek  **/
ixgbe_clear_vfta_82598(struct ixgbe_hw * hw)105463b3bba8SJerry Jelinek static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw)
105513740cb2SPaul Guo {
105613740cb2SPaul Guo 	u32 offset;
105713740cb2SPaul Guo 	u32 vlanbyte;
105813740cb2SPaul Guo 
10593cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_clear_vfta_82598");
10603cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
106113740cb2SPaul Guo 	for (offset = 0; offset < hw->mac.vft_size; offset++)
106213740cb2SPaul Guo 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
106313740cb2SPaul Guo 
106413740cb2SPaul Guo 	for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
106513740cb2SPaul Guo 		for (offset = 0; offset < hw->mac.vft_size; offset++)
106663b3bba8SJerry Jelinek 			IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
106769b5a878SDan McDonald 					0);
106813740cb2SPaul Guo 
106963b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
107013740cb2SPaul Guo }
107113740cb2SPaul Guo 
107263b3bba8SJerry Jelinek /**
107363b3bba8SJerry Jelinek  *  ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
107463b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
107563b3bba8SJerry Jelinek  *  @reg: analog register to read
107663b3bba8SJerry Jelinek  *  @val: read value
107713740cb2SPaul Guo  *
107863b3bba8SJerry Jelinek  *  Performs read operation to Atlas analog register specified.
107963b3bba8SJerry Jelinek  **/
ixgbe_read_analog_reg8_82598(struct ixgbe_hw * hw,u32 reg,u8 * val)108063b3bba8SJerry Jelinek s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val)
108113740cb2SPaul Guo {
108213740cb2SPaul Guo 	u32  atlas_ctl;
108313740cb2SPaul Guo 
10843cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_read_analog_reg8_82598");
10853cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
108613740cb2SPaul Guo 	IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
108769b5a878SDan McDonald 			IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
108813740cb2SPaul Guo 	IXGBE_WRITE_FLUSH(hw);
108913740cb2SPaul Guo 	usec_delay(10);
109013740cb2SPaul Guo 	atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
109113740cb2SPaul Guo 	*val = (u8)atlas_ctl;
109213740cb2SPaul Guo 
109363b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
109413740cb2SPaul Guo }
109513740cb2SPaul Guo 
109663b3bba8SJerry Jelinek /**
109763b3bba8SJerry Jelinek  *  ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register
109863b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
109963b3bba8SJerry Jelinek  *  @reg: atlas register to write
110063b3bba8SJerry Jelinek  *  @val: value to write
110113740cb2SPaul Guo  *
110263b3bba8SJerry Jelinek  *  Performs write operation to Atlas analog register specified.
110363b3bba8SJerry Jelinek  **/
ixgbe_write_analog_reg8_82598(struct ixgbe_hw * hw,u32 reg,u8 val)110463b3bba8SJerry Jelinek s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val)
110513740cb2SPaul Guo {
110613740cb2SPaul Guo 	u32  atlas_ctl;
110713740cb2SPaul Guo 
11083cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_write_analog_reg8_82598");
11093cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
111013740cb2SPaul Guo 	atlas_ctl = (reg << 8) | val;
111113740cb2SPaul Guo 	IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
111213740cb2SPaul Guo 	IXGBE_WRITE_FLUSH(hw);
111313740cb2SPaul Guo 	usec_delay(10);
111413740cb2SPaul Guo 
111563b3bba8SJerry Jelinek 	return IXGBE_SUCCESS;
111613740cb2SPaul Guo }
111713740cb2SPaul Guo 
111863b3bba8SJerry Jelinek /**
1119dc0cb1cdSDale Ghent  *  ixgbe_read_i2c_phy_82598 - Reads 8 bit word over I2C interface.
112063b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
1121dc0cb1cdSDale Ghent  *  @dev_addr: address to read from
1122dc0cb1cdSDale Ghent  *  @byte_offset: byte offset to read from dev_addr
112363b3bba8SJerry Jelinek  *  @eeprom_data: value read
112413740cb2SPaul Guo  *
112563b3bba8SJerry Jelinek  *  Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
112663b3bba8SJerry Jelinek  **/
ixgbe_read_i2c_phy_82598(struct ixgbe_hw * hw,u8 dev_addr,u8 byte_offset,u8 * eeprom_data)1127dc0cb1cdSDale Ghent static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr,
1128dc0cb1cdSDale Ghent 				    u8 byte_offset, u8 *eeprom_data)
112913740cb2SPaul Guo {
113013740cb2SPaul Guo 	s32 status = IXGBE_SUCCESS;
113113740cb2SPaul Guo 	u16 sfp_addr = 0;
113213740cb2SPaul Guo 	u16 sfp_data = 0;
113313740cb2SPaul Guo 	u16 sfp_stat = 0;
1134dc0cb1cdSDale Ghent 	u16 gssr;
113513740cb2SPaul Guo 	u32 i;
113613740cb2SPaul Guo 
1137dc0cb1cdSDale Ghent 	DEBUGFUNC("ixgbe_read_i2c_phy_82598");
1138dc0cb1cdSDale Ghent 
1139dc0cb1cdSDale Ghent 	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
1140dc0cb1cdSDale Ghent 		gssr = IXGBE_GSSR_PHY1_SM;
1141dc0cb1cdSDale Ghent 	else
1142dc0cb1cdSDale Ghent 		gssr = IXGBE_GSSR_PHY0_SM;
1143dc0cb1cdSDale Ghent 
1144dc0cb1cdSDale Ghent 	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != IXGBE_SUCCESS)
1145dc0cb1cdSDale Ghent 		return IXGBE_ERR_SWFW_SYNC;
11463cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
114713740cb2SPaul Guo 	if (hw->phy.type == ixgbe_phy_nl) {
114813740cb2SPaul Guo 		/*
114913740cb2SPaul Guo 		 * NetLogic phy SDA/SCL registers are at addresses 0xC30A to
115013740cb2SPaul Guo 		 * 0xC30D. These registers are used to talk to the SFP+
115113740cb2SPaul Guo 		 * module's EEPROM through the SDA/SCL (I2C) interface.
115213740cb2SPaul Guo 		 */
1153dc0cb1cdSDale Ghent 		sfp_addr = (dev_addr << 8) + byte_offset;
115413740cb2SPaul Guo 		sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
1155dc0cb1cdSDale Ghent 		hw->phy.ops.write_reg_mdi(hw,
1156dc0cb1cdSDale Ghent 					  IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
1157dc0cb1cdSDale Ghent 					  IXGBE_MDIO_PMA_PMD_DEV_TYPE,
1158dc0cb1cdSDale Ghent 					  sfp_addr);
115913740cb2SPaul Guo 
116013740cb2SPaul Guo 		/* Poll status */
116113740cb2SPaul Guo 		for (i = 0; i < 100; i++) {
1162dc0cb1cdSDale Ghent 			hw->phy.ops.read_reg_mdi(hw,
1163dc0cb1cdSDale Ghent 						IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
1164dc0cb1cdSDale Ghent 						IXGBE_MDIO_PMA_PMD_DEV_TYPE,
1165dc0cb1cdSDale Ghent 						&sfp_stat);
116613740cb2SPaul Guo 			sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
116713740cb2SPaul Guo 			if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
116813740cb2SPaul Guo 				break;
116913740cb2SPaul Guo 			msec_delay(10);
117013740cb2SPaul Guo 		}
117113740cb2SPaul Guo 
117213740cb2SPaul Guo 		if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) {
117313740cb2SPaul Guo 			DEBUGOUT("EEPROM read did not pass.\n");
117413740cb2SPaul Guo 			status = IXGBE_ERR_SFP_NOT_PRESENT;
117513740cb2SPaul Guo 			goto out;
117613740cb2SPaul Guo 		}
117713740cb2SPaul Guo 
117813740cb2SPaul Guo 		/* Read data */
1179dc0cb1cdSDale Ghent 		hw->phy.ops.read_reg_mdi(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
1180dc0cb1cdSDale Ghent 					IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
118113740cb2SPaul Guo 
118213740cb2SPaul Guo 		*eeprom_data = (u8)(sfp_data >> 8);
118313740cb2SPaul Guo 	} else {
118413740cb2SPaul Guo 		status = IXGBE_ERR_PHY;
118513740cb2SPaul Guo 	}
118613740cb2SPaul Guo 
118713740cb2SPaul Guo out:
1188dc0cb1cdSDale Ghent 	hw->mac.ops.release_swfw_sync(hw, gssr);
118963b3bba8SJerry Jelinek 	return status;
119013740cb2SPaul Guo }
119113740cb2SPaul Guo 
1192dc0cb1cdSDale Ghent /**
1193dc0cb1cdSDale Ghent  *  ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
1194dc0cb1cdSDale Ghent  *  @hw: pointer to hardware structure
1195dc0cb1cdSDale Ghent  *  @byte_offset: EEPROM byte offset to read
1196dc0cb1cdSDale Ghent  *  @eeprom_data: value read
1197dc0cb1cdSDale Ghent  *
1198dc0cb1cdSDale Ghent  *  Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
1199dc0cb1cdSDale Ghent  **/
ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw * hw,u8 byte_offset,u8 * eeprom_data)1200dc0cb1cdSDale Ghent s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
1201dc0cb1cdSDale Ghent 				u8 *eeprom_data)
1202dc0cb1cdSDale Ghent {
1203dc0cb1cdSDale Ghent 	return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR,
1204dc0cb1cdSDale Ghent 					byte_offset, eeprom_data);
1205dc0cb1cdSDale Ghent }
1206dc0cb1cdSDale Ghent 
1207dc0cb1cdSDale Ghent /**
1208dc0cb1cdSDale Ghent  *  ixgbe_read_i2c_sff8472_82598 - Reads 8 bit word over I2C interface.
1209dc0cb1cdSDale Ghent  *  @hw: pointer to hardware structure
1210dc0cb1cdSDale Ghent  *  @byte_offset: byte offset at address 0xA2
121148ed61a7SRobert Mustacchi  *  @sff8472_data: value read
1212dc0cb1cdSDale Ghent  *
1213dc0cb1cdSDale Ghent  *  Performs 8 byte read operation to SFP module's SFF-8472 data over I2C
1214dc0cb1cdSDale Ghent  **/
ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw * hw,u8 byte_offset,u8 * sff8472_data)1215dc0cb1cdSDale Ghent static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
1216dc0cb1cdSDale Ghent 					u8 *sff8472_data)
1217dc0cb1cdSDale Ghent {
1218dc0cb1cdSDale Ghent 	return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR2,
1219dc0cb1cdSDale Ghent 					byte_offset, sff8472_data);
1220dc0cb1cdSDale Ghent }
1221dc0cb1cdSDale Ghent 
122263b3bba8SJerry Jelinek /**
122363b3bba8SJerry Jelinek  *  ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
122463b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
122513740cb2SPaul Guo  *
122663b3bba8SJerry Jelinek  *  Determines physical layer capabilities of the current configuration.
122763b3bba8SJerry Jelinek  **/
ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw * hw)122848ed61a7SRobert Mustacchi u64 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
122913740cb2SPaul Guo {
123048ed61a7SRobert Mustacchi 	u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
123173cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
123273cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
123373cd555cSBin Tu - Sun Microsystems - Beijing China 	u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
123473cd555cSBin Tu - Sun Microsystems - Beijing China 	u16 ext_ability = 0;
123513740cb2SPaul Guo 
12363cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_get_supported_physical_layer_82598");
12373cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
123873cd555cSBin Tu - Sun Microsystems - Beijing China 	hw->phy.ops.identify(hw);
123973cd555cSBin Tu - Sun Microsystems - Beijing China 
124063b3bba8SJerry Jelinek 	/* Copper PHY must be checked before AUTOC LMS to determine correct
124163b3bba8SJerry Jelinek 	 * physical layer because 10GBase-T PHYs use LMS = KX4/KX */
124263b3bba8SJerry Jelinek 	switch (hw->phy.type) {
124363b3bba8SJerry Jelinek 	case ixgbe_phy_tn:
124463b3bba8SJerry Jelinek 	case ixgbe_phy_cu_unknown:
124573cd555cSBin Tu - Sun Microsystems - Beijing China 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
124663b3bba8SJerry Jelinek 		IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
124773cd555cSBin Tu - Sun Microsystems - Beijing China 		if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
124873cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
124973cd555cSBin Tu - Sun Microsystems - Beijing China 		if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
125073cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
125173cd555cSBin Tu - Sun Microsystems - Beijing China 		if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
125273cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
125373cd555cSBin Tu - Sun Microsystems - Beijing China 		goto out;
125463b3bba8SJerry Jelinek 	default:
125563b3bba8SJerry Jelinek 		break;
125673cd555cSBin Tu - Sun Microsystems - Beijing China 	}
125773cd555cSBin Tu - Sun Microsystems - Beijing China 
125873cd555cSBin Tu - Sun Microsystems - Beijing China 	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
125973cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_AUTOC_LMS_1G_AN:
126073cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
126173cd555cSBin Tu - Sun Microsystems - Beijing China 		if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
126273cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
126373cd555cSBin Tu - Sun Microsystems - Beijing China 		else
126473cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
126513740cb2SPaul Guo 		break;
126673cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
126773cd555cSBin Tu - Sun Microsystems - Beijing China 		if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
126873cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
126973cd555cSBin Tu - Sun Microsystems - Beijing China 		else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
127073cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
127173cd555cSBin Tu - Sun Microsystems - Beijing China 		else /* XAUI */
127273cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
127313740cb2SPaul Guo 		break;
127473cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_AUTOC_LMS_KX4_AN:
127573cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
127673cd555cSBin Tu - Sun Microsystems - Beijing China 		if (autoc & IXGBE_AUTOC_KX_SUPP)
127773cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
127873cd555cSBin Tu - Sun Microsystems - Beijing China 		if (autoc & IXGBE_AUTOC_KX4_SUPP)
127973cd555cSBin Tu - Sun Microsystems - Beijing China 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
128013740cb2SPaul Guo 		break;
128173cd555cSBin Tu - Sun Microsystems - Beijing China 	default:
128213740cb2SPaul Guo 		break;
128373cd555cSBin Tu - Sun Microsystems - Beijing China 	}
128473cd555cSBin Tu - Sun Microsystems - Beijing China 
128573cd555cSBin Tu - Sun Microsystems - Beijing China 	if (hw->phy.type == ixgbe_phy_nl) {
128613740cb2SPaul Guo 		hw->phy.ops.identify_sfp(hw);
128713740cb2SPaul Guo 
128813740cb2SPaul Guo 		switch (hw->phy.sfp_type) {
128913740cb2SPaul Guo 		case ixgbe_sfp_type_da_cu:
129013740cb2SPaul Guo 			physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
129113740cb2SPaul Guo 			break;
129213740cb2SPaul Guo 		case ixgbe_sfp_type_sr:
129313740cb2SPaul Guo 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
129413740cb2SPaul Guo 			break;
129513740cb2SPaul Guo 		case ixgbe_sfp_type_lr:
129613740cb2SPaul Guo 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
129713740cb2SPaul Guo 			break;
129813740cb2SPaul Guo 		default:
129913740cb2SPaul Guo 			physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
130013740cb2SPaul Guo 			break;
130113740cb2SPaul Guo 		}
130273cd555cSBin Tu - Sun Microsystems - Beijing China 	}
130313740cb2SPaul Guo 
130473cd555cSBin Tu - Sun Microsystems - Beijing China 	switch (hw->device_id) {
130573cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
130673cd555cSBin Tu - Sun Microsystems - Beijing China 		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
130773cd555cSBin Tu - Sun Microsystems - Beijing China 		break;
130873cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
130973cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
131073cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
131173cd555cSBin Tu - Sun Microsystems - Beijing China 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
131273cd555cSBin Tu - Sun Microsystems - Beijing China 		break;
131373cd555cSBin Tu - Sun Microsystems - Beijing China 	case IXGBE_DEV_ID_82598EB_XF_LR:
131473cd555cSBin Tu - Sun Microsystems - Beijing China 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
131573cd555cSBin Tu - Sun Microsystems - Beijing China 		break;
131613740cb2SPaul Guo 	default:
131713740cb2SPaul Guo 		break;
131813740cb2SPaul Guo 	}
131913740cb2SPaul Guo 
132073cd555cSBin Tu - Sun Microsystems - Beijing China out:
132163b3bba8SJerry Jelinek 	return physical_layer;
132213740cb2SPaul Guo }
1323185c5677SPaul Guo 
132463b3bba8SJerry Jelinek /**
132563b3bba8SJerry Jelinek  *  ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple
132663b3bba8SJerry Jelinek  *  port devices.
132763b3bba8SJerry Jelinek  *  @hw: pointer to the HW structure
1328185c5677SPaul Guo  *
132963b3bba8SJerry Jelinek  *  Calls common function and corrects issue with some single port devices
133063b3bba8SJerry Jelinek  *  that enable LAN1 but not LAN0.
133163b3bba8SJerry Jelinek  **/
ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw * hw)133263b3bba8SJerry Jelinek void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw)
1333185c5677SPaul Guo {
1334185c5677SPaul Guo 	struct ixgbe_bus_info *bus = &hw->bus;
133563b3bba8SJerry Jelinek 	u16 pci_gen = 0;
133663b3bba8SJerry Jelinek 	u16 pci_ctrl2 = 0;
1337185c5677SPaul Guo 
13383cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 	DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie_82598");
13393cfa0eb9Schenlu chen - Sun Microsystems - Beijing China 
1340185c5677SPaul Guo 	ixgbe_set_lan_id_multi_port_pcie(hw);
1341185c5677SPaul Guo 
1342185c5677SPaul Guo 	/* check if LAN0 is disabled */
1343185c5677SPaul Guo 	hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen);
1344185c5677SPaul Guo 	if ((pci_gen != 0) && (pci_gen != 0xFFFF)) {
134563b3bba8SJerry Jelinek 
1346185c5677SPaul Guo 		hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2);
1347185c5677SPaul Guo 
1348185c5677SPaul Guo 		/* if LAN0 is completely disabled force function to 0 */
1349185c5677SPaul Guo 		if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) &&
1350185c5677SPaul Guo 		    !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) &&
1351185c5677SPaul Guo 		    !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) {
135263b3bba8SJerry Jelinek 
1353185c5677SPaul Guo 			bus->func = 0;
1354185c5677SPaul Guo 		}
1355185c5677SPaul Guo 	}
1356185c5677SPaul Guo }
135719843f01SPaul Guo 
135863b3bba8SJerry Jelinek /**
135963b3bba8SJerry Jelinek  *  ixgbe_enable_relaxed_ordering_82598 - enable relaxed ordering
136063b3bba8SJerry Jelinek  *  @hw: pointer to hardware structure
136119843f01SPaul Guo  *
136263b3bba8SJerry Jelinek  **/
ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw * hw)136363b3bba8SJerry Jelinek void ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw *hw)
136419843f01SPaul Guo {
136519843f01SPaul Guo 	u32 regval;
136619843f01SPaul Guo 	u32 i;
136719843f01SPaul Guo 
136819843f01SPaul Guo 	DEBUGFUNC("ixgbe_enable_relaxed_ordering_82598");
136919843f01SPaul Guo 
137019843f01SPaul Guo 	/* Enable relaxed ordering */
137119843f01SPaul Guo 	for (i = 0; ((i < hw->mac.max_tx_queues) &&
137263b3bba8SJerry Jelinek 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
137319843f01SPaul Guo 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
137469b5a878SDan McDonald 		regval |= IXGBE_DCA_TXCTRL_DESC_WRO_EN;
137519843f01SPaul Guo 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
137619843f01SPaul Guo 	}
137719843f01SPaul Guo 
137819843f01SPaul Guo 	for (i = 0; ((i < hw->mac.max_rx_queues) &&
137963b3bba8SJerry Jelinek 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
138019843f01SPaul Guo 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
138169b5a878SDan McDonald 		regval |= IXGBE_DCA_RXCTRL_DATA_WRO_EN |
138269b5a878SDan McDonald 			  IXGBE_DCA_RXCTRL_HEAD_WRO_EN;
138319843f01SPaul Guo 		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
138419843f01SPaul Guo 	}
138563b3bba8SJerry Jelinek 
138619843f01SPaul Guo }
138769b5a878SDan McDonald 
138869b5a878SDan McDonald /**
138969b5a878SDan McDonald  * ixgbe_set_rxpba_82598 - Initialize RX packet buffer
139069b5a878SDan McDonald  * @hw: pointer to hardware structure
139169b5a878SDan McDonald  * @num_pb: number of packet buffers to allocate
139269b5a878SDan McDonald  * @headroom: reserve n KB of headroom
139369b5a878SDan McDonald  * @strategy: packet buffer allocation strategy
139469b5a878SDan McDonald  **/
ixgbe_set_rxpba_82598(struct ixgbe_hw * hw,int num_pb,u32 headroom,int strategy)139569b5a878SDan McDonald static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
139669b5a878SDan McDonald 				  u32 headroom, int strategy)
139769b5a878SDan McDonald {
139869b5a878SDan McDonald 	u32 rxpktsize = IXGBE_RXPBSIZE_64KB;
139969b5a878SDan McDonald 	u8 i = 0;
140069b5a878SDan McDonald 	UNREFERENCED_1PARAMETER(headroom);
140169b5a878SDan McDonald 
140269b5a878SDan McDonald 	if (!num_pb)
140369b5a878SDan McDonald 		return;
140469b5a878SDan McDonald 
140569b5a878SDan McDonald 	/* Setup Rx packet buffer sizes */
140669b5a878SDan McDonald 	switch (strategy) {
140769b5a878SDan McDonald 	case PBA_STRATEGY_WEIGHTED:
140869b5a878SDan McDonald 		/* Setup the first four at 80KB */
140969b5a878SDan McDonald 		rxpktsize = IXGBE_RXPBSIZE_80KB;
141069b5a878SDan McDonald 		for (; i < 4; i++)
141169b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
141269b5a878SDan McDonald 		/* Setup the last four at 48KB...don't re-init i */
141369b5a878SDan McDonald 		rxpktsize = IXGBE_RXPBSIZE_48KB;
141469b5a878SDan McDonald 		/* Fall Through */
141569b5a878SDan McDonald 	case PBA_STRATEGY_EQUAL:
141669b5a878SDan McDonald 	default:
141769b5a878SDan McDonald 		/* Divide the remaining Rx packet buffer evenly among the TCs */
141869b5a878SDan McDonald 		for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
141969b5a878SDan McDonald 			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
142069b5a878SDan McDonald 		break;
142169b5a878SDan McDonald 	}
142269b5a878SDan McDonald 
142369b5a878SDan McDonald 	/* Setup Tx packet buffer sizes */
142469b5a878SDan McDonald 	for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++)
142569b5a878SDan McDonald 		IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), IXGBE_TXPBSIZE_40KB);
142669b5a878SDan McDonald }
1427dc0cb1cdSDale Ghent 
1428dc0cb1cdSDale Ghent /**
1429dc0cb1cdSDale Ghent  *  ixgbe_enable_rx_dma_82598 - Enable the Rx DMA unit
1430dc0cb1cdSDale Ghent  *  @hw: pointer to hardware structure
1431dc0cb1cdSDale Ghent  *  @regval: register value to write to RXCTRL
1432dc0cb1cdSDale Ghent  *
1433dc0cb1cdSDale Ghent  *  Enables the Rx DMA unit
1434dc0cb1cdSDale Ghent  **/
ixgbe_enable_rx_dma_82598(struct ixgbe_hw * hw,u32 regval)1435dc0cb1cdSDale Ghent s32 ixgbe_enable_rx_dma_82598(struct ixgbe_hw *hw, u32 regval)
1436dc0cb1cdSDale Ghent {
1437dc0cb1cdSDale Ghent 	DEBUGFUNC("ixgbe_enable_rx_dma_82598");
1438dc0cb1cdSDale Ghent 
1439dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
1440dc0cb1cdSDale Ghent 
1441dc0cb1cdSDale Ghent 	return IXGBE_SUCCESS;
1442dc0cb1cdSDale Ghent }
1443