xref: /openbsd/sys/dev/pci/ixgbe_82598.c (revision 0f9e9ec2)
1*0f9e9ec2Sjsg /*	$OpenBSD: ixgbe_82598.c,v 1.21 2024/05/13 01:15:51 jsg Exp $	*/
2ad013249Sreyk 
3ad013249Sreyk /******************************************************************************
4d7a8f955Sjmatthew   SPDX-License-Identifier: BSD-3-Clause
5ad013249Sreyk 
6d7a8f955Sjmatthew   Copyright (c) 2001-2017, Intel Corporation
7ad013249Sreyk   All rights reserved.
8ad013249Sreyk 
9ad013249Sreyk   Redistribution and use in source and binary forms, with or without
10ad013249Sreyk   modification, are permitted provided that the following conditions are met:
11ad013249Sreyk 
12ad013249Sreyk    1. Redistributions of source code must retain the above copyright notice,
13ad013249Sreyk       this list of conditions and the following disclaimer.
14ad013249Sreyk 
15ad013249Sreyk    2. Redistributions in binary form must reproduce the above copyright
16ad013249Sreyk       notice, this list of conditions and the following disclaimer in the
17ad013249Sreyk       documentation and/or other materials provided with the distribution.
18ad013249Sreyk 
19ad013249Sreyk    3. Neither the name of the Intel Corporation nor the names of its
20ad013249Sreyk       contributors may be used to endorse or promote products derived from
21ad013249Sreyk       this software without specific prior written permission.
22ad013249Sreyk 
23ad013249Sreyk   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24ad013249Sreyk   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ad013249Sreyk   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ad013249Sreyk   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27ad013249Sreyk   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28ad013249Sreyk   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29ad013249Sreyk   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30ad013249Sreyk   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31ad013249Sreyk   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32ad013249Sreyk   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33ad013249Sreyk   POSSIBILITY OF SUCH DAMAGE.
34ad013249Sreyk 
35ad013249Sreyk ******************************************************************************/
36d7a8f955Sjmatthew /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_82598.c 331224 2018-03-19 20:55:05Z erj $*/
37d7a8f955Sjmatthew 
38ad013249Sreyk 
39ad013249Sreyk #include <dev/pci/ixgbe.h>
40ad013249Sreyk #include <dev/pci/ixgbe_type.h>
41ad013249Sreyk 
429e435848Smikeb #define IXGBE_82598_MAX_TX_QUEUES 32
439e435848Smikeb #define IXGBE_82598_MAX_RX_QUEUES 64
449e435848Smikeb #define IXGBE_82598_RAR_ENTRIES   16
459e435848Smikeb #define IXGBE_82598_MC_TBL_SIZE  128
469e435848Smikeb #define IXGBE_82598_VFT_TBL_SIZE 128
479e435848Smikeb #define IXGBE_82598_RX_PB_SIZE   512
489e435848Smikeb 
4935befa56Sreyk int32_t ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
50ad013249Sreyk 					  ixgbe_link_speed *speed,
5111efaf7fSmikeb 					  bool *autoneg);
52ad013249Sreyk enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw);
5311efaf7fSmikeb int32_t ixgbe_fc_enable_82598(struct ixgbe_hw *hw);
543201f924Sjsg int32_t ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
5511efaf7fSmikeb 				   bool autoneg_wait_to_complete);
569feba5bbSclaudio int32_t ixgbe_validate_link_ready(struct ixgbe_hw *hw);
5735befa56Sreyk int32_t ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
5811efaf7fSmikeb 				   ixgbe_link_speed *speed, bool *link_up,
5911efaf7fSmikeb 				   bool link_up_wait_to_complete);
603201f924Sjsg int32_t ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
61ad013249Sreyk 				   ixgbe_link_speed speed,
6211efaf7fSmikeb 				   bool autoneg_wait_to_complete);
633201f924Sjsg int32_t ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
64ad013249Sreyk 				      ixgbe_link_speed speed,
6511efaf7fSmikeb 				      bool autoneg_wait_to_complete);
6635befa56Sreyk int32_t ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
67d7a8f955Sjmatthew 
683201f924Sjsg int32_t ixgbe_start_hw_82598(struct ixgbe_hw *hw);
6935befa56Sreyk int32_t ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, uint32_t rar, uint32_t vmdq);
703201f924Sjsg int32_t ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, uint32_t rar, uint32_t vmdq);
713201f924Sjsg int32_t ixgbe_set_vfta_82598(struct ixgbe_hw *hw, uint32_t vlan,
72d7a8f955Sjmatthew 			     uint32_t vind, bool vlan_on, bool vlvf_bypass);
733201f924Sjsg int32_t ixgbe_clear_vfta_82598(struct ixgbe_hw *hw);
743201f924Sjsg int32_t ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, uint32_t reg, uint8_t *val);
753201f924Sjsg int32_t ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, uint32_t reg, uint8_t val);
7611efaf7fSmikeb int32_t ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, uint8_t dev_addr,
7711efaf7fSmikeb 				 uint8_t byte_offset, uint8_t *eeprom_data);
783201f924Sjsg int32_t ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, uint8_t byte_offset,
793201f924Sjsg 				uint8_t *eeprom_data);
80d7a8f955Sjmatthew uint64_t ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw);
813201f924Sjsg int32_t ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw);
823201f924Sjsg void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw);
833201f924Sjsg void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw);
8435e02db6Smikeb int32_t ixgbe_enable_rx_dma_82598(struct ixgbe_hw *hw, uint32_t regval);
853201f924Sjsg 
863201f924Sjsg /**
873201f924Sjsg  *  ixgbe_set_pcie_completion_timeout - set pci-e completion timeout
883201f924Sjsg  *  @hw: pointer to the HW structure
893201f924Sjsg  *
903201f924Sjsg  *  The defaults for 82598 should be in the range of 50us to 50ms,
913201f924Sjsg  *  however the hardware default for these parts is 500us to 1ms which is less
923201f924Sjsg  *  than the 10ms recommended by the pci-e spec.  To address this we need to
933201f924Sjsg  *  increase the value to either 10ms to 250ms for capability version 1 config,
943201f924Sjsg  *  or 16ms to 55ms for version 2.
953201f924Sjsg  **/
ixgbe_set_pcie_completion_timeout(struct ixgbe_hw * hw)963201f924Sjsg void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
973201f924Sjsg {
983201f924Sjsg 	uint32_t gcr = IXGBE_READ_REG(hw, IXGBE_GCR);
993201f924Sjsg 	uint16_t pcie_devctl2;
1003201f924Sjsg 
1013201f924Sjsg 	/* only take action if timeout value is defaulted to 0 */
1023201f924Sjsg 	if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK)
1033201f924Sjsg 		goto out;
1043201f924Sjsg 
1053201f924Sjsg 	/*
1064b1a56afSjsg 	 * if capabilities version is type 1 we can write the
1073201f924Sjsg 	 * timeout of 10ms to 250ms through the GCR register
1083201f924Sjsg 	 */
1093201f924Sjsg 	if (!(gcr & IXGBE_GCR_CAP_VER2)) {
1103201f924Sjsg 		gcr |= IXGBE_GCR_CMPL_TMOUT_10ms;
1113201f924Sjsg 		goto out;
1123201f924Sjsg 	}
1133201f924Sjsg 
1143201f924Sjsg 	/*
1153201f924Sjsg 	 * for version 2 capabilities we need to write the config space
1163201f924Sjsg 	 * directly in order to set the completion timeout value for
1173201f924Sjsg 	 * 16ms to 55ms
1183201f924Sjsg 	 */
1193201f924Sjsg 	pcie_devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2);
1203201f924Sjsg 	pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms;
1213201f924Sjsg 	IXGBE_WRITE_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2);
1223201f924Sjsg out:
1233201f924Sjsg 	/* disable completion timeout resend */
1243201f924Sjsg 	gcr &= ~IXGBE_GCR_CMPL_TMOUT_RESEND;
1253201f924Sjsg 	IXGBE_WRITE_REG(hw, IXGBE_GCR, gcr);
1263201f924Sjsg }
1273201f924Sjsg 
1283201f924Sjsg /**
129ad013249Sreyk  *  ixgbe_init_ops_82598 - Inits func ptrs and MAC type
130ad013249Sreyk  *  @hw: pointer to hardware structure
131ad013249Sreyk  *
132ad013249Sreyk  *  Initialize the function pointers and assign the MAC type for 82598.
133ad013249Sreyk  *  Does not touch the hardware.
134ad013249Sreyk  **/
ixgbe_init_ops_82598(struct ixgbe_hw * hw)13535befa56Sreyk int32_t ixgbe_init_ops_82598(struct ixgbe_hw *hw)
136ad013249Sreyk {
137ad013249Sreyk 	struct ixgbe_mac_info *mac = &hw->mac;
138ad013249Sreyk 	struct ixgbe_phy_info *phy = &hw->phy;
13935befa56Sreyk 	int32_t ret_val;
140ad013249Sreyk 
14111efaf7fSmikeb 	DEBUGFUNC("ixgbe_init_ops_82598");
14211efaf7fSmikeb 
143ad013249Sreyk 	ret_val = ixgbe_init_phy_ops_generic(hw);
144ad013249Sreyk 	ret_val = ixgbe_init_ops_generic(hw);
145ad013249Sreyk 
1463201f924Sjsg 	/* PHY */
1479e435848Smikeb 	phy->ops.init = ixgbe_init_phy_ops_82598;
148ad013249Sreyk 
1493201f924Sjsg 	/* MAC */
1509e435848Smikeb 	mac->ops.start_hw = ixgbe_start_hw_82598;
1519e435848Smikeb 	mac->ops.reset_hw = ixgbe_reset_hw_82598;
1529e435848Smikeb 	mac->ops.get_media_type = ixgbe_get_media_type_82598;
1533201f924Sjsg 	mac->ops.get_supported_physical_layer =
1549e435848Smikeb 				ixgbe_get_supported_physical_layer_82598;
1559e435848Smikeb 	mac->ops.read_analog_reg8 = ixgbe_read_analog_reg8_82598;
1569e435848Smikeb 	mac->ops.write_analog_reg8 = ixgbe_write_analog_reg8_82598;
1579e435848Smikeb 	mac->ops.set_lan_id = ixgbe_set_lan_id_multi_port_pcie_82598;
15835e02db6Smikeb 	mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_82598;
159ad013249Sreyk 
160ad013249Sreyk 	/* RAR, Multicast, VLAN */
1619e435848Smikeb 	mac->ops.set_vmdq = ixgbe_set_vmdq_82598;
1629e435848Smikeb 	mac->ops.clear_vmdq = ixgbe_clear_vmdq_82598;
1639e435848Smikeb 	mac->ops.set_vfta = ixgbe_set_vfta_82598;
164d7a8f955Sjmatthew 	mac->ops.set_vlvf = NULL;
1659e435848Smikeb 	mac->ops.clear_vfta = ixgbe_clear_vfta_82598;
166ad013249Sreyk 
167ad013249Sreyk 	/* Flow Control */
1689e435848Smikeb 	mac->ops.fc_enable = ixgbe_fc_enable_82598;
169ad013249Sreyk 
1709e435848Smikeb 	mac->mcft_size		= IXGBE_82598_MC_TBL_SIZE;
1719e435848Smikeb 	mac->vft_size		= IXGBE_82598_VFT_TBL_SIZE;
1729e435848Smikeb 	mac->num_rar_entries	= IXGBE_82598_RAR_ENTRIES;
1739e435848Smikeb 	mac->rx_pb_size		= IXGBE_82598_RX_PB_SIZE;
1749e435848Smikeb 	mac->max_rx_queues	= IXGBE_82598_MAX_RX_QUEUES;
17535e02db6Smikeb 	mac->max_tx_queues	= IXGBE_82598_MAX_TX_QUEUES;
176d7a8f955Sjmatthew 	mac->max_msix_vectors	= 0 /*ixgbe_get_pcie_msix_count_generic(hw)*/;
177ad013249Sreyk 
1783201f924Sjsg 	/* SFP+ Module */
1799e435848Smikeb 	phy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_82598;
1803201f924Sjsg 
1813201f924Sjsg 	/* Link */
1829e435848Smikeb 	mac->ops.check_link = ixgbe_check_mac_link_82598;
1839e435848Smikeb 	mac->ops.setup_link = ixgbe_setup_mac_link_82598;
1849feba5bbSclaudio 	mac->ops.flap_tx_laser = NULL;
1859e435848Smikeb 	mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_82598;
1863201f924Sjsg 
1873201f924Sjsg 	return ret_val;
1883201f924Sjsg }
1893201f924Sjsg 
1903201f924Sjsg /**
1913201f924Sjsg  *  ixgbe_init_phy_ops_82598 - PHY/SFP specific init
1923201f924Sjsg  *  @hw: pointer to hardware structure
1933201f924Sjsg  *
1943201f924Sjsg  *  Initialize any function pointers that were not able to be
1953201f924Sjsg  *  set during init_shared_code because the PHY/SFP type was
1963201f924Sjsg  *  not known.  Perform the SFP init if necessary.
1973201f924Sjsg  *
1983201f924Sjsg  **/
ixgbe_init_phy_ops_82598(struct ixgbe_hw * hw)1993201f924Sjsg int32_t ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
2003201f924Sjsg {
2013201f924Sjsg 	struct ixgbe_mac_info *mac = &hw->mac;
2023201f924Sjsg 	struct ixgbe_phy_info *phy = &hw->phy;
2033201f924Sjsg 	int32_t ret_val = IXGBE_SUCCESS;
2043201f924Sjsg 	uint16_t list_offset, data_offset;
2053201f924Sjsg 
20611efaf7fSmikeb 	DEBUGFUNC("ixgbe_init_phy_ops_82598");
20711efaf7fSmikeb 
2083201f924Sjsg 	/* Identify the PHY */
2093201f924Sjsg 	phy->ops.identify(hw);
2103201f924Sjsg 
2113201f924Sjsg 	/* Overwrite the link function pointers if copper PHY */
2123201f924Sjsg 	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
2139e435848Smikeb 		mac->ops.setup_link = ixgbe_setup_copper_link_82598;
2143201f924Sjsg 		mac->ops.get_link_capabilities =
2159e435848Smikeb 				ixgbe_get_copper_link_capabilities_generic;
2163201f924Sjsg 	}
2173201f924Sjsg 
2183201f924Sjsg 	switch (hw->phy.type) {
2193201f924Sjsg 	case ixgbe_phy_tn:
2209e435848Smikeb 		phy->ops.setup_link = ixgbe_setup_phy_link_tnx;
2219e435848Smikeb 		phy->ops.check_link = ixgbe_check_phy_link_tnx;
2223201f924Sjsg 		phy->ops.get_firmware_version =
2239e435848Smikeb 					ixgbe_get_phy_firmware_version_tnx;
2243201f924Sjsg 		break;
2253201f924Sjsg 	case ixgbe_phy_nl:
2269e435848Smikeb 		phy->ops.reset = ixgbe_reset_phy_nl;
2273201f924Sjsg 
2283201f924Sjsg 		/* Call SFP+ identify routine to get the SFP+ module type */
2293201f924Sjsg 		ret_val = phy->ops.identify_sfp(hw);
2303201f924Sjsg 		if (ret_val != IXGBE_SUCCESS)
2313201f924Sjsg 			goto out;
2323201f924Sjsg 		else if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) {
2333201f924Sjsg 			ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
2343201f924Sjsg 			goto out;
2353201f924Sjsg 		}
2363201f924Sjsg 
2373201f924Sjsg 		/* Check to see if SFP+ module is supported */
2383201f924Sjsg 		ret_val = ixgbe_get_sfp_init_sequence_offsets(hw,
2393201f924Sjsg 							      &list_offset,
2403201f924Sjsg 							      &data_offset);
2413201f924Sjsg 		if (ret_val != IXGBE_SUCCESS) {
2423201f924Sjsg 			ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
2433201f924Sjsg 			goto out;
2443201f924Sjsg 		}
2453201f924Sjsg 		break;
2463201f924Sjsg 	default:
2473201f924Sjsg 		break;
2483201f924Sjsg 	}
2493201f924Sjsg 
2503201f924Sjsg out:
2513201f924Sjsg 	return ret_val;
2523201f924Sjsg }
2533201f924Sjsg 
2543201f924Sjsg /**
2553201f924Sjsg  *  ixgbe_start_hw_82598 - Prepare hardware for Tx/Rx
2563201f924Sjsg  *  @hw: pointer to hardware structure
2573201f924Sjsg  *
2583201f924Sjsg  *  Starts the hardware using the generic start_hw function.
259d7a8f955Sjmatthew  *  Disables relaxed ordering Then set pcie completion timeout
26011efaf7fSmikeb  *
2613201f924Sjsg  **/
ixgbe_start_hw_82598(struct ixgbe_hw * hw)2623201f924Sjsg int32_t ixgbe_start_hw_82598(struct ixgbe_hw *hw)
2633201f924Sjsg {
2643201f924Sjsg 	uint32_t regval;
2653201f924Sjsg 	uint32_t i;
2663201f924Sjsg 	int32_t ret_val = IXGBE_SUCCESS;
2673201f924Sjsg 
26811efaf7fSmikeb 	DEBUGFUNC("ixgbe_start_hw_82598");
26911efaf7fSmikeb 
2703201f924Sjsg 	ret_val = ixgbe_start_hw_generic(hw);
27135e02db6Smikeb 	if (ret_val)
27235e02db6Smikeb 		return ret_val;
2733201f924Sjsg 
2743201f924Sjsg 	/* Disable relaxed ordering */
2753201f924Sjsg 	for (i = 0; ((i < hw->mac.max_tx_queues) &&
2763201f924Sjsg 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
2773201f924Sjsg 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
27811efaf7fSmikeb 		regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
2793201f924Sjsg 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
2803201f924Sjsg 	}
2813201f924Sjsg 
2823201f924Sjsg 	for (i = 0; ((i < hw->mac.max_rx_queues) &&
2833201f924Sjsg 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
2843201f924Sjsg 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
28511efaf7fSmikeb 		regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
28611efaf7fSmikeb 			    IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
2873201f924Sjsg 		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
2883201f924Sjsg 	}
2893201f924Sjsg 
2903201f924Sjsg 	/* set the completion timeout for interface */
2913201f924Sjsg 	ixgbe_set_pcie_completion_timeout(hw);
2923201f924Sjsg 
2933201f924Sjsg 	return ret_val;
294ad013249Sreyk }
295ad013249Sreyk 
296ad013249Sreyk /**
297ad013249Sreyk  *  ixgbe_get_link_capabilities_82598 - Determines link capabilities
298ad013249Sreyk  *  @hw: pointer to hardware structure
299ad013249Sreyk  *  @speed: pointer to link speed
3003201f924Sjsg  *  @autoneg: boolean auto-negotiation value
301ad013249Sreyk  *
302ad013249Sreyk  *  Determines the link capabilities by reading the AUTOC register.
303ad013249Sreyk  **/
ixgbe_get_link_capabilities_82598(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * autoneg)30435befa56Sreyk int32_t ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
305ad013249Sreyk 					  ixgbe_link_speed *speed,
30611efaf7fSmikeb 					  bool *autoneg)
307ad013249Sreyk {
30835befa56Sreyk 	int32_t status = IXGBE_SUCCESS;
3093201f924Sjsg 	uint32_t autoc = 0;
310ad013249Sreyk 
31111efaf7fSmikeb 	DEBUGFUNC("ixgbe_get_link_capabilities_82598");
31211efaf7fSmikeb 
3133201f924Sjsg 	/*
3143201f924Sjsg 	 * Determine link capabilities based on the stored value of AUTOC,
3153201f924Sjsg 	 * which represents EEPROM defaults.  If AUTOC value has not been
3163201f924Sjsg 	 * stored, use the current register value.
3173201f924Sjsg 	 */
3183201f924Sjsg 	if (hw->mac.orig_link_settings_stored)
3193201f924Sjsg 		autoc = hw->mac.orig_autoc;
3203201f924Sjsg 	else
3213201f924Sjsg 		autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
322ad013249Sreyk 
3233201f924Sjsg 	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
324ad013249Sreyk 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
325ad013249Sreyk 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
326ad013249Sreyk 		*autoneg = FALSE;
327ad013249Sreyk 		break;
328ad013249Sreyk 
329ad013249Sreyk 	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
330ad013249Sreyk 		*speed = IXGBE_LINK_SPEED_10GB_FULL;
331ad013249Sreyk 		*autoneg = FALSE;
332ad013249Sreyk 		break;
333ad013249Sreyk 
334ad013249Sreyk 	case IXGBE_AUTOC_LMS_1G_AN:
335ad013249Sreyk 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
336ad013249Sreyk 		*autoneg = TRUE;
337ad013249Sreyk 		break;
338ad013249Sreyk 
339ad013249Sreyk 	case IXGBE_AUTOC_LMS_KX4_AN:
340ad013249Sreyk 	case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
341ad013249Sreyk 		*speed = IXGBE_LINK_SPEED_UNKNOWN;
3423201f924Sjsg 		if (autoc & IXGBE_AUTOC_KX4_SUPP)
343ad013249Sreyk 			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
3443201f924Sjsg 		if (autoc & IXGBE_AUTOC_KX_SUPP)
345ad013249Sreyk 			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
346ad013249Sreyk 		*autoneg = TRUE;
347ad013249Sreyk 		break;
348ad013249Sreyk 
349ad013249Sreyk 	default:
350ad013249Sreyk 		status = IXGBE_ERR_LINK_SETUP;
351ad013249Sreyk 		break;
352ad013249Sreyk 	}
353ad013249Sreyk 
354ad013249Sreyk 	return status;
355ad013249Sreyk }
356ad013249Sreyk 
357ad013249Sreyk /**
358ad013249Sreyk  *  ixgbe_get_media_type_82598 - Determines media type
359ad013249Sreyk  *  @hw: pointer to hardware structure
360ad013249Sreyk  *
361ad013249Sreyk  *  Returns the media type (fiber, copper, backplane)
362ad013249Sreyk  **/
ixgbe_get_media_type_82598(struct ixgbe_hw * hw)363ad013249Sreyk enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
364ad013249Sreyk {
365ad013249Sreyk 	enum ixgbe_media_type media_type;
366ad013249Sreyk 
36711efaf7fSmikeb 	DEBUGFUNC("ixgbe_get_media_type_82598");
36811efaf7fSmikeb 
3693201f924Sjsg 	/* Detect if there is a copper PHY attached. */
3709feba5bbSclaudio 	switch (hw->phy.type) {
3719feba5bbSclaudio 	case ixgbe_phy_cu_unknown:
3729feba5bbSclaudio 	case ixgbe_phy_tn:
3733201f924Sjsg 		media_type = ixgbe_media_type_copper;
3743201f924Sjsg 		goto out;
3759feba5bbSclaudio 	default:
3769feba5bbSclaudio 		break;
3773201f924Sjsg 	}
3783201f924Sjsg 
379ad013249Sreyk 	/* Media type for I82598 is based on device ID */
380ad013249Sreyk 	switch (hw->device_id) {
3813201f924Sjsg 	case IXGBE_DEV_ID_82598:
3823201f924Sjsg 	case IXGBE_DEV_ID_82598_BX:
3833201f924Sjsg 		/* Default device ID is mezzanine card KX/KX4 */
3843201f924Sjsg 		media_type = ixgbe_media_type_backplane;
3853201f924Sjsg 		break;
386ad013249Sreyk 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
387ad013249Sreyk 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
388ad013249Sreyk 	case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
389ad013249Sreyk 	case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
390ad013249Sreyk 	case IXGBE_DEV_ID_82598EB_XF_LR:
3913201f924Sjsg 	case IXGBE_DEV_ID_82598EB_SFP_LOM:
392ad013249Sreyk 		media_type = ixgbe_media_type_fiber;
393ad013249Sreyk 		break;
3943201f924Sjsg 	case IXGBE_DEV_ID_82598EB_CX4:
3953201f924Sjsg 	case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
3963201f924Sjsg 		media_type = ixgbe_media_type_cx4;
397ad013249Sreyk 		break;
3983201f924Sjsg 	case IXGBE_DEV_ID_82598AT:
3993201f924Sjsg 	case IXGBE_DEV_ID_82598AT2:
400ad013249Sreyk 		media_type = ixgbe_media_type_copper;
401ad013249Sreyk 		break;
402ad013249Sreyk 	default:
403ad013249Sreyk 		media_type = ixgbe_media_type_unknown;
404ad013249Sreyk 		break;
405ad013249Sreyk 	}
4063201f924Sjsg out:
407ad013249Sreyk 	return media_type;
408ad013249Sreyk }
409ad013249Sreyk 
410ad013249Sreyk /**
4113201f924Sjsg  *  ixgbe_fc_enable_82598 - Enable flow control
412ad013249Sreyk  *  @hw: pointer to hardware structure
413ad013249Sreyk  *
4143201f924Sjsg  *  Enable flow control according to the current settings.
415ad013249Sreyk  **/
ixgbe_fc_enable_82598(struct ixgbe_hw * hw)41611efaf7fSmikeb int32_t ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
417ad013249Sreyk {
4183201f924Sjsg 	int32_t ret_val = IXGBE_SUCCESS;
4193201f924Sjsg 	uint32_t fctrl_reg;
42035befa56Sreyk 	uint32_t rmcs_reg;
4213201f924Sjsg 	uint32_t reg;
42211efaf7fSmikeb 	uint32_t fcrtl, fcrth;
4233201f924Sjsg 	uint32_t link_speed = 0;
42411efaf7fSmikeb 	int i;
42511efaf7fSmikeb 	bool link_up;
42611efaf7fSmikeb 
42711efaf7fSmikeb 	DEBUGFUNC("ixgbe_fc_enable_82598");
42811efaf7fSmikeb 
42911efaf7fSmikeb 	/* Validate the water mark configuration */
43011efaf7fSmikeb 	if (!hw->fc.pause_time) {
43111efaf7fSmikeb 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
43211efaf7fSmikeb 		goto out;
43311efaf7fSmikeb 	}
43411efaf7fSmikeb 
43511efaf7fSmikeb 	/* Low water mark of zero causes XOFF floods */
43611efaf7fSmikeb 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
43711efaf7fSmikeb 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
43811efaf7fSmikeb 		    hw->fc.high_water[i]) {
43911efaf7fSmikeb 			if (!hw->fc.low_water[i] ||
44011efaf7fSmikeb 			    hw->fc.low_water[i] >= hw->fc.high_water[i]) {
44111efaf7fSmikeb 				DEBUGOUT("Invalid water mark configuration\n");
44211efaf7fSmikeb 				ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
44311efaf7fSmikeb 				goto out;
44411efaf7fSmikeb 			}
44511efaf7fSmikeb 		}
44611efaf7fSmikeb 	}
447ad013249Sreyk 
4483201f924Sjsg 	/*
4499feba5bbSclaudio 	 * On 82598 having Rx FC on causes resets while doing 1G
4509feba5bbSclaudio 	 * so if it's on turn it off once we know link_speed. For
4519feba5bbSclaudio 	 * more details see 82598 Specification update.
4523201f924Sjsg 	 */
4533201f924Sjsg 	hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
4549feba5bbSclaudio 	if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) {
4559feba5bbSclaudio 		switch (hw->fc.requested_mode) {
4569feba5bbSclaudio 		case ixgbe_fc_full:
4579feba5bbSclaudio 			hw->fc.requested_mode = ixgbe_fc_tx_pause;
4589feba5bbSclaudio 			break;
4599feba5bbSclaudio 		case ixgbe_fc_rx_pause:
4603201f924Sjsg 			hw->fc.requested_mode = ixgbe_fc_none;
4619feba5bbSclaudio 			break;
4629feba5bbSclaudio 		default:
4639feba5bbSclaudio 			/* no change */
4649feba5bbSclaudio 			break;
4659feba5bbSclaudio 		}
466ad013249Sreyk 	}
467ad013249Sreyk 
4683201f924Sjsg 	/* Negotiate the fc mode to use */
46911efaf7fSmikeb 	ixgbe_fc_autoneg(hw);
4703201f924Sjsg 
4713201f924Sjsg 	/* Disable any previous flow control settings */
4723201f924Sjsg 	fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
4733201f924Sjsg 	fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
474ad013249Sreyk 
475ad013249Sreyk 	rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
476ad013249Sreyk 	rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
477ad013249Sreyk 
478ad013249Sreyk 	/*
4793201f924Sjsg 	 * The possible values of fc.current_mode are:
480ad013249Sreyk 	 * 0: Flow control is completely disabled
4813201f924Sjsg 	 * 1: Rx flow control is enabled (we can receive pause frames,
4823201f924Sjsg 	 *    but not send pause frames).
4833201f924Sjsg 	 * 2: Tx flow control is enabled (we can send pause frames but
4843201f924Sjsg 	 *     we do not support receiving pause frames).
485ad013249Sreyk 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
486ad013249Sreyk 	 * other: Invalid.
487ad013249Sreyk 	 */
4883201f924Sjsg 	switch (hw->fc.current_mode) {
489ad013249Sreyk 	case ixgbe_fc_none:
4909feba5bbSclaudio 		/*
4919feba5bbSclaudio 		 * Flow control is disabled by software override or autoneg.
4923201f924Sjsg 		 * The code below will actually disable it in the HW.
4933201f924Sjsg 		 */
494ad013249Sreyk 		break;
495ad013249Sreyk 	case ixgbe_fc_rx_pause:
496ad013249Sreyk 		/*
4973201f924Sjsg 		 * Rx Flow control is enabled and Tx Flow control is
4983201f924Sjsg 		 * disabled by software override. Since there really
4993201f924Sjsg 		 * isn't a way to advertise that we are capable of RX
5003201f924Sjsg 		 * Pause ONLY, we will advertise that we support both
5013201f924Sjsg 		 * symmetric and asymmetric Rx PAUSE.  Later, we will
5023201f924Sjsg 		 * disable the adapter's ability to send PAUSE frames.
503ad013249Sreyk 		 */
5043201f924Sjsg 		fctrl_reg |= IXGBE_FCTRL_RFCE;
505ad013249Sreyk 		break;
506ad013249Sreyk 	case ixgbe_fc_tx_pause:
507ad013249Sreyk 		/*
5083201f924Sjsg 		 * Tx Flow control is enabled, and Rx Flow control is
5093201f924Sjsg 		 * disabled by software override.
510ad013249Sreyk 		 */
511ad013249Sreyk 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
512ad013249Sreyk 		break;
513ad013249Sreyk 	case ixgbe_fc_full:
5143201f924Sjsg 		/* Flow control (both Rx and Tx) is enabled by SW override. */
5153201f924Sjsg 		fctrl_reg |= IXGBE_FCTRL_RFCE;
516ad013249Sreyk 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
517ad013249Sreyk 		break;
518ad013249Sreyk 	default:
519ad013249Sreyk 		DEBUGOUT("Flow control param set incorrectly\n");
5203201f924Sjsg 		ret_val = IXGBE_ERR_CONFIG;
5213201f924Sjsg 		goto out;
522ad013249Sreyk 		break;
523ad013249Sreyk 	}
524ad013249Sreyk 
5253201f924Sjsg 	/* Set 802.3x based flow control settings. */
5263201f924Sjsg 	fctrl_reg |= IXGBE_FCTRL_DPF;
5273201f924Sjsg 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
528ad013249Sreyk 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
529ad013249Sreyk 
5303201f924Sjsg 	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
53111efaf7fSmikeb 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
53211efaf7fSmikeb 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
53311efaf7fSmikeb 		    hw->fc.high_water[i]) {
53411efaf7fSmikeb 			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
53511efaf7fSmikeb 			fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
53611efaf7fSmikeb 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
53711efaf7fSmikeb 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth);
53811efaf7fSmikeb 		} else {
53911efaf7fSmikeb 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
54011efaf7fSmikeb 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
54111efaf7fSmikeb 		}
5423201f924Sjsg 
543ad013249Sreyk 	}
544ad013249Sreyk 
5453201f924Sjsg 	/* Configure pause time (2 TCs per register) */
546109b20f8Sbluhm 	reg = (uint32_t)hw->fc.pause_time * 0x00010001;
54711efaf7fSmikeb 	for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
54811efaf7fSmikeb 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
5493201f924Sjsg 
55011efaf7fSmikeb 	/* Configure flow control refresh threshold value */
55111efaf7fSmikeb 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
552ad013249Sreyk 
5533201f924Sjsg out:
5543201f924Sjsg 	return ret_val;
555ad013249Sreyk }
556ad013249Sreyk 
557ad013249Sreyk /**
5583201f924Sjsg  *  ixgbe_start_mac_link_82598 - Configures MAC link settings
559ad013249Sreyk  *  @hw: pointer to hardware structure
560d7a8f955Sjmatthew  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
561ad013249Sreyk  *
562ad013249Sreyk  *  Configures link settings based on values in the ixgbe_hw struct.
563ad013249Sreyk  *  Restarts the link.  Performs autonegotiation if needed.
564ad013249Sreyk  **/
ixgbe_start_mac_link_82598(struct ixgbe_hw * hw,bool autoneg_wait_to_complete)5653201f924Sjsg int32_t ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
56611efaf7fSmikeb 				   bool autoneg_wait_to_complete)
567ad013249Sreyk {
56835befa56Sreyk 	uint32_t autoc_reg;
56935befa56Sreyk 	uint32_t links_reg;
57035befa56Sreyk 	uint32_t i;
57135befa56Sreyk 	int32_t status = IXGBE_SUCCESS;
572ad013249Sreyk 
57311efaf7fSmikeb 	DEBUGFUNC("ixgbe_start_mac_link_82598");
57411efaf7fSmikeb 
575ad013249Sreyk 	/* Restart link */
5763201f924Sjsg 	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
577ad013249Sreyk 	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
578ad013249Sreyk 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
579ad013249Sreyk 
580ad013249Sreyk 	/* Only poll for autoneg to complete if specified to do so */
5813201f924Sjsg 	if (autoneg_wait_to_complete) {
5823201f924Sjsg 		if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
5833201f924Sjsg 		     IXGBE_AUTOC_LMS_KX4_AN ||
5843201f924Sjsg 		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
5853201f924Sjsg 		     IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
586ad013249Sreyk 			links_reg = 0; /* Just in case Autoneg time = 0 */
587ad013249Sreyk 			for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
588ad013249Sreyk 				links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
589ad013249Sreyk 				if (links_reg & IXGBE_LINKS_KX_AN_COMP)
590ad013249Sreyk 					break;
591ad013249Sreyk 				msec_delay(100);
592ad013249Sreyk 			}
593ad013249Sreyk 			if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
594ad013249Sreyk 				status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
595ad013249Sreyk 				DEBUGOUT("Autonegotiation did not complete.\n");
596ad013249Sreyk 			}
597ad013249Sreyk 		}
598ad013249Sreyk 	}
599ad013249Sreyk 
600ad013249Sreyk 	/* Add delay to filter out noises during initial link setup */
601ad013249Sreyk 	msec_delay(50);
602ad013249Sreyk 
603ad013249Sreyk 	return status;
604ad013249Sreyk }
605ad013249Sreyk 
606ad013249Sreyk /**
6079feba5bbSclaudio  *  ixgbe_validate_link_ready - Function looks for phy link
6089feba5bbSclaudio  *  @hw: pointer to hardware structure
6099feba5bbSclaudio  *
6109feba5bbSclaudio  *  Function indicates success when phy link is available. If phy is not ready
6119feba5bbSclaudio  *  within 5 seconds of MAC indicating link, the function returns error.
6129feba5bbSclaudio  **/
ixgbe_validate_link_ready(struct ixgbe_hw * hw)6139feba5bbSclaudio int32_t ixgbe_validate_link_ready(struct ixgbe_hw *hw)
6149feba5bbSclaudio {
6159feba5bbSclaudio 	uint32_t timeout;
6169feba5bbSclaudio 	uint16_t an_reg;
6179feba5bbSclaudio 
6189feba5bbSclaudio 	if (hw->device_id != IXGBE_DEV_ID_82598AT2)
6199feba5bbSclaudio 		return IXGBE_SUCCESS;
6209feba5bbSclaudio 
6219feba5bbSclaudio 	for (timeout = 0;
6229feba5bbSclaudio 	     timeout < IXGBE_VALIDATE_LINK_READY_TIMEOUT; timeout++) {
6239feba5bbSclaudio 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
6249feba5bbSclaudio 				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &an_reg);
6259feba5bbSclaudio 
6269feba5bbSclaudio 		if ((an_reg & IXGBE_MII_AUTONEG_COMPLETE) &&
6279feba5bbSclaudio 		    (an_reg & IXGBE_MII_AUTONEG_LINK_UP))
6289feba5bbSclaudio 			break;
6299feba5bbSclaudio 
6309feba5bbSclaudio 		msec_delay(100);
6319feba5bbSclaudio 	}
6329feba5bbSclaudio 
6339feba5bbSclaudio 	if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) {
6349feba5bbSclaudio 		DEBUGOUT("Link was indicated but link is down\n");
6359feba5bbSclaudio 		return IXGBE_ERR_LINK_SETUP;
6369feba5bbSclaudio 	}
6379feba5bbSclaudio 
6389feba5bbSclaudio 	return IXGBE_SUCCESS;
6399feba5bbSclaudio }
6409feba5bbSclaudio 
6419feba5bbSclaudio /**
642ad013249Sreyk  *  ixgbe_check_mac_link_82598 - Get link/speed status
643ad013249Sreyk  *  @hw: pointer to hardware structure
644ad013249Sreyk  *  @speed: pointer to link speed
645ad013249Sreyk  *  @link_up: TRUE is link is up, FALSE otherwise
6463201f924Sjsg  *  @link_up_wait_to_complete: bool used to wait for link up or not
647ad013249Sreyk  *
648ad013249Sreyk  *  Reads the links register to determine if link is up and the current speed
649ad013249Sreyk  **/
ixgbe_check_mac_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * link_up,bool link_up_wait_to_complete)65011efaf7fSmikeb int32_t ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
65111efaf7fSmikeb 				   ixgbe_link_speed *speed, bool *link_up,
65211efaf7fSmikeb 				   bool link_up_wait_to_complete)
653ad013249Sreyk {
65435befa56Sreyk 	uint32_t links_reg;
65535befa56Sreyk 	uint32_t i;
65635befa56Sreyk 	uint16_t link_reg, adapt_comp_reg;
657ad013249Sreyk 
65811efaf7fSmikeb 	DEBUGFUNC("ixgbe_check_mac_link_82598");
65911efaf7fSmikeb 
6603201f924Sjsg 	/*
6613201f924Sjsg 	 * SERDES PHY requires us to read link status from undocumented
6623201f924Sjsg 	 * register 0xC79F.  Bit 0 set indicates link is up/ready; clear
6633201f924Sjsg 	 * indicates link down.  OxC00C is read to check that the XAUI lanes
6643201f924Sjsg 	 * are active.  Bit 0 clear indicates active; set indicates inactive.
6653201f924Sjsg 	 */
666ad013249Sreyk 	if (hw->phy.type == ixgbe_phy_nl) {
6673201f924Sjsg 		hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
6683201f924Sjsg 		hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
669ad013249Sreyk 		hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV,
670ad013249Sreyk 				     &adapt_comp_reg);
671ad013249Sreyk 		if (link_up_wait_to_complete) {
6722f63561bSmikeb 			for (i = 0; i < hw->mac.max_link_up_time; i++) {
6733201f924Sjsg 				if ((link_reg & 1) &&
674ad013249Sreyk 				    ((adapt_comp_reg & 1) == 0)) {
675ad013249Sreyk 					*link_up = TRUE;
676ad013249Sreyk 					break;
677ad013249Sreyk 				} else {
678ad013249Sreyk 					*link_up = FALSE;
679ad013249Sreyk 				}
680ad013249Sreyk 				msec_delay(100);
6813201f924Sjsg 				hw->phy.ops.read_reg(hw, 0xC79F,
6823201f924Sjsg 						     IXGBE_TWINAX_DEV,
683ad013249Sreyk 						     &link_reg);
684ad013249Sreyk 				hw->phy.ops.read_reg(hw, 0xC00C,
685ad013249Sreyk 						     IXGBE_TWINAX_DEV,
686ad013249Sreyk 						     &adapt_comp_reg);
687ad013249Sreyk 			}
688ad013249Sreyk 		} else {
6899feba5bbSclaudio 			if ((link_reg & 1) && ((adapt_comp_reg & 1) == 0))
690ad013249Sreyk 				*link_up = TRUE;
691ad013249Sreyk 			else
692ad013249Sreyk 				*link_up = FALSE;
693ad013249Sreyk 		}
694ad013249Sreyk 
695ad013249Sreyk 		if (*link_up == FALSE)
696ad013249Sreyk 			goto out;
697ad013249Sreyk 	}
698ad013249Sreyk 
699ad013249Sreyk 	links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
700ad013249Sreyk 	if (link_up_wait_to_complete) {
7012f63561bSmikeb 		for (i = 0; i < hw->mac.max_link_up_time; i++) {
702ad013249Sreyk 			if (links_reg & IXGBE_LINKS_UP) {
703ad013249Sreyk 				*link_up = TRUE;
704ad013249Sreyk 				break;
705ad013249Sreyk 			} else {
706ad013249Sreyk 				*link_up = FALSE;
707ad013249Sreyk 			}
708ad013249Sreyk 			msec_delay(100);
709ad013249Sreyk 			links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
710ad013249Sreyk 		}
711ad013249Sreyk 	} else {
712ad013249Sreyk 		if (links_reg & IXGBE_LINKS_UP)
713ad013249Sreyk 			*link_up = TRUE;
714ad013249Sreyk 		else
715ad013249Sreyk 			*link_up = FALSE;
716ad013249Sreyk 	}
717ad013249Sreyk 
718ad013249Sreyk 	if (links_reg & IXGBE_LINKS_SPEED)
719ad013249Sreyk 		*speed = IXGBE_LINK_SPEED_10GB_FULL;
720ad013249Sreyk 	else
721ad013249Sreyk 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
722ad013249Sreyk 
7233201f924Sjsg 	if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && (*link_up == TRUE) &&
7243201f924Sjsg 	    (ixgbe_validate_link_ready(hw) != IXGBE_SUCCESS))
7253201f924Sjsg 		*link_up = FALSE;
7263201f924Sjsg 
727ad013249Sreyk out:
728ad013249Sreyk 	return IXGBE_SUCCESS;
729ad013249Sreyk }
730ad013249Sreyk 
731ad013249Sreyk /**
7323201f924Sjsg  *  ixgbe_setup_mac_link_82598 - Set MAC link speed
733ad013249Sreyk  *  @hw: pointer to hardware structure
734ad013249Sreyk  *  @speed: new link speed
7353201f924Sjsg  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
736ad013249Sreyk  *
737ad013249Sreyk  *  Set the link speed in the AUTOC register and restarts link.
738ad013249Sreyk  **/
ixgbe_setup_mac_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)7393201f924Sjsg int32_t ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
74011efaf7fSmikeb 				   ixgbe_link_speed speed,
74111efaf7fSmikeb 				   bool autoneg_wait_to_complete)
742ad013249Sreyk {
74311efaf7fSmikeb 	bool autoneg = FALSE;
74435befa56Sreyk 	int32_t status = IXGBE_SUCCESS;
7453201f924Sjsg 	ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
7463201f924Sjsg 	uint32_t curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
7473201f924Sjsg 	uint32_t autoc = curr_autoc;
7483201f924Sjsg 	uint32_t link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
749ad013249Sreyk 
75011efaf7fSmikeb 	DEBUGFUNC("ixgbe_setup_mac_link_82598");
75111efaf7fSmikeb 
7523201f924Sjsg 	/* Check to see if speed passed in is supported. */
753d7a8f955Sjmatthew 	hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg);
7543201f924Sjsg 	speed &= link_capabilities;
7553201f924Sjsg 
7563201f924Sjsg 	if (speed == IXGBE_LINK_SPEED_UNKNOWN)
757ad013249Sreyk 		status = IXGBE_ERR_LINK_SETUP;
7583201f924Sjsg 
7593201f924Sjsg 	/* Set KX4/KX support according to speed requested */
7603201f924Sjsg 	else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
7613201f924Sjsg 		 link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
7623201f924Sjsg 		autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK;
7633201f924Sjsg 		if (speed & IXGBE_LINK_SPEED_10GB_FULL)
7643201f924Sjsg 			autoc |= IXGBE_AUTOC_KX4_SUPP;
7653201f924Sjsg 		if (speed & IXGBE_LINK_SPEED_1GB_FULL)
7663201f924Sjsg 			autoc |= IXGBE_AUTOC_KX_SUPP;
7673201f924Sjsg 		if (autoc != curr_autoc)
7683201f924Sjsg 			IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
769ad013249Sreyk 	}
770ad013249Sreyk 
771ad013249Sreyk 	if (status == IXGBE_SUCCESS) {
772ad013249Sreyk 		/*
773ad013249Sreyk 		 * Setup and restart the link based on the new values in
774ad013249Sreyk 		 * ixgbe_hw This will write the AUTOC register based on the new
775ad013249Sreyk 		 * stored values
776ad013249Sreyk 		 */
7773201f924Sjsg 		status = ixgbe_start_mac_link_82598(hw,
7783201f924Sjsg 						    autoneg_wait_to_complete);
779ad013249Sreyk 	}
780ad013249Sreyk 
781ad013249Sreyk 	return status;
782ad013249Sreyk }
783ad013249Sreyk 
7849feba5bbSclaudio 
785ad013249Sreyk /**
7863201f924Sjsg  *  ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field
787ad013249Sreyk  *  @hw: pointer to hardware structure
788ad013249Sreyk  *  @speed: new link speed
789ad013249Sreyk  *  @autoneg_wait_to_complete: TRUE if waiting is needed to complete
790ad013249Sreyk  *
791ad013249Sreyk  *  Sets the link speed in the AUTOC register in the MAC and restarts link.
792ad013249Sreyk  **/
ixgbe_setup_copper_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)7933201f924Sjsg int32_t ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
794ad013249Sreyk 				      ixgbe_link_speed speed,
79511efaf7fSmikeb 				      bool autoneg_wait_to_complete)
796ad013249Sreyk {
79735befa56Sreyk 	int32_t status;
798ad013249Sreyk 
79911efaf7fSmikeb 	DEBUGFUNC("ixgbe_setup_copper_link_82598");
80011efaf7fSmikeb 
801ad013249Sreyk 	/* Setup the PHY according to input speed */
80211efaf7fSmikeb 	status = hw->phy.ops.setup_link_speed(hw, speed,
803ad013249Sreyk 					      autoneg_wait_to_complete);
804ad013249Sreyk 	/* Set up MAC */
8053201f924Sjsg 	ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
806ad013249Sreyk 
807ad013249Sreyk 	return status;
808ad013249Sreyk }
809ad013249Sreyk 
810ad013249Sreyk /**
811ad013249Sreyk  *  ixgbe_reset_hw_82598 - Performs hardware reset
812ad013249Sreyk  *  @hw: pointer to hardware structure
813ad013249Sreyk  *
814ad013249Sreyk  *  Resets the hardware by resetting the transmit and receive units, masks and
815ad013249Sreyk  *  clears all interrupts, performing a PHY reset, and performing a link (MAC)
816ad013249Sreyk  *  reset.
817ad013249Sreyk  **/
ixgbe_reset_hw_82598(struct ixgbe_hw * hw)81835befa56Sreyk int32_t ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
819ad013249Sreyk {
82035befa56Sreyk 	int32_t status = IXGBE_SUCCESS;
8213201f924Sjsg 	int32_t phy_status = IXGBE_SUCCESS;
82235befa56Sreyk 	uint32_t ctrl;
82335befa56Sreyk 	uint32_t gheccr;
82435befa56Sreyk 	uint32_t i;
82535befa56Sreyk 	uint32_t autoc;
82635befa56Sreyk 	uint8_t  analog_val;
827ad013249Sreyk 
82811efaf7fSmikeb 	DEBUGFUNC("ixgbe_reset_hw_82598");
82911efaf7fSmikeb 
830ad013249Sreyk 	/* Call adapter stop to disable tx/rx and clear interrupts */
83111efaf7fSmikeb 	status = hw->mac.ops.stop_adapter(hw);
83211efaf7fSmikeb 	if (status != IXGBE_SUCCESS)
83311efaf7fSmikeb 		goto reset_hw_out;
834ad013249Sreyk 
835ad013249Sreyk 	/*
836ad013249Sreyk 	 * Power up the Atlas Tx lanes if they are currently powered down.
837ad013249Sreyk 	 * Atlas Tx lanes are powered down for MAC loopback tests, but
838ad013249Sreyk 	 * they are not automatically restored on reset.
839ad013249Sreyk 	 */
840ad013249Sreyk 	hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
841ad013249Sreyk 	if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) {
842ad013249Sreyk 		/* Enable Tx Atlas so packets can be transmitted again */
843ad013249Sreyk 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
844ad013249Sreyk 					     &analog_val);
845ad013249Sreyk 		analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN;
846ad013249Sreyk 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
847ad013249Sreyk 					      analog_val);
848ad013249Sreyk 
849ad013249Sreyk 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
850ad013249Sreyk 					     &analog_val);
851ad013249Sreyk 		analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
852ad013249Sreyk 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
853ad013249Sreyk 					      analog_val);
854ad013249Sreyk 
855ad013249Sreyk 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
856ad013249Sreyk 					     &analog_val);
857ad013249Sreyk 		analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
858ad013249Sreyk 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
859ad013249Sreyk 					      analog_val);
860ad013249Sreyk 
861ad013249Sreyk 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
862ad013249Sreyk 					     &analog_val);
863ad013249Sreyk 		analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
864ad013249Sreyk 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
865ad013249Sreyk 					      analog_val);
866ad013249Sreyk 	}
867ad013249Sreyk 
868ad013249Sreyk 	/* Reset PHY */
8693201f924Sjsg 	if (hw->phy.reset_disable == FALSE) {
8703201f924Sjsg 		/* PHY ops must be identified and initialized prior to reset */
871ad013249Sreyk 
8723201f924Sjsg 		/* Init PHY and function pointers, perform SFP setup */
8733201f924Sjsg 		phy_status = hw->phy.ops.init(hw);
8743201f924Sjsg 		if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
8753201f924Sjsg 			goto reset_hw_out;
87611efaf7fSmikeb 		if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT)
87711efaf7fSmikeb 			goto mac_reset_top;
8783201f924Sjsg 
8793201f924Sjsg 		hw->phy.ops.reset(hw);
8803201f924Sjsg 	}
8813201f924Sjsg 
8829feba5bbSclaudio mac_reset_top:
883ad013249Sreyk 	/*
884ad013249Sreyk 	 * Issue global reset to the MAC.  This needs to be a SW reset.
885ad013249Sreyk 	 * If link reset is used, it might reset the MAC when mng is using it
886ad013249Sreyk 	 */
88711efaf7fSmikeb 	ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL) | IXGBE_CTRL_RST;
88811efaf7fSmikeb 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
889ad013249Sreyk 	IXGBE_WRITE_FLUSH(hw);
890ad013249Sreyk 
891ad013249Sreyk 	/* Poll for reset bit to self-clear indicating reset is complete */
892ad013249Sreyk 	for (i = 0; i < 10; i++) {
893ad013249Sreyk 		usec_delay(1);
894ad013249Sreyk 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
895ad013249Sreyk 		if (!(ctrl & IXGBE_CTRL_RST))
896ad013249Sreyk 			break;
897ad013249Sreyk 	}
898ad013249Sreyk 	if (ctrl & IXGBE_CTRL_RST) {
899ad013249Sreyk 		status = IXGBE_ERR_RESET_FAILED;
900ad013249Sreyk 		DEBUGOUT("Reset polling failed to complete.\n");
901ad013249Sreyk 	}
902ad013249Sreyk 
90354ed48bfSmikeb 	msec_delay(50);
90454ed48bfSmikeb 
9059feba5bbSclaudio 	/*
9069feba5bbSclaudio 	 * Double resets are required for recovery from certain error
9079feba5bbSclaudio 	 * conditions.  Between resets, it is necessary to stall to allow time
90854ed48bfSmikeb 	 * for any pending HW events to complete.
9099feba5bbSclaudio 	 */
9109feba5bbSclaudio 	if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
9119feba5bbSclaudio 		hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
9129feba5bbSclaudio 		goto mac_reset_top;
9139feba5bbSclaudio 	}
9149feba5bbSclaudio 
915ad013249Sreyk 	gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR);
916ad013249Sreyk 	gheccr &= ~((1 << 21) | (1 << 18) | (1 << 9) | (1 << 6));
917ad013249Sreyk 	IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
918ad013249Sreyk 
919ad013249Sreyk 	/*
9203201f924Sjsg 	 * Store the original AUTOC value if it has not been
9213201f924Sjsg 	 * stored off yet.  Otherwise restore the stored original
9224b1a56afSjsg 	 * AUTOC value since the reset operation sets back to defaults.
923ad013249Sreyk 	 */
924ad013249Sreyk 	autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
9253201f924Sjsg 	if (hw->mac.orig_link_settings_stored == FALSE) {
9263201f924Sjsg 		hw->mac.orig_autoc = autoc;
9273201f924Sjsg 		hw->mac.orig_link_settings_stored = TRUE;
9289feba5bbSclaudio 	} else if (autoc != hw->mac.orig_autoc) {
9293201f924Sjsg 		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
9309feba5bbSclaudio 	}
931ad013249Sreyk 
932ad013249Sreyk 	/* Store the permanent mac address */
933ad013249Sreyk 	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
934ad013249Sreyk 
9353201f924Sjsg 	/*
9363201f924Sjsg 	 * Store MAC address from RAR0, clear receive address registers, and
9373201f924Sjsg 	 * clear the multicast table
9383201f924Sjsg 	 */
9393201f924Sjsg 	hw->mac.ops.init_rx_addrs(hw);
9403201f924Sjsg 
9413201f924Sjsg reset_hw_out:
9423201f924Sjsg 	if (phy_status != IXGBE_SUCCESS)
9433201f924Sjsg 		status = phy_status;
9449feba5bbSclaudio 
945ad013249Sreyk 	return status;
946ad013249Sreyk }
947ad013249Sreyk 
948ad013249Sreyk /**
949ad013249Sreyk  *  ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address
950ad013249Sreyk  *  @hw: pointer to hardware struct
951ad013249Sreyk  *  @rar: receive address register index to associate with a VMDq index
952ad013249Sreyk  *  @vmdq: VMDq set index
953ad013249Sreyk  **/
ixgbe_set_vmdq_82598(struct ixgbe_hw * hw,uint32_t rar,uint32_t vmdq)95435befa56Sreyk int32_t ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, uint32_t rar, uint32_t vmdq)
955ad013249Sreyk {
95635befa56Sreyk 	uint32_t rar_high;
9579feba5bbSclaudio 	uint32_t rar_entries = hw->mac.num_rar_entries;
9589feba5bbSclaudio 
95911efaf7fSmikeb 	DEBUGFUNC("ixgbe_set_vmdq_82598");
96011efaf7fSmikeb 
9619feba5bbSclaudio 	/* Make sure we are using a valid rar index range */
9629feba5bbSclaudio 	if (rar >= rar_entries) {
9639feba5bbSclaudio 		DEBUGOUT1("RAR index %d is out of range.\n", rar);
9649feba5bbSclaudio 		return IXGBE_ERR_INVALID_ARGUMENT;
9659feba5bbSclaudio 	}
966ad013249Sreyk 
967ad013249Sreyk 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
968ad013249Sreyk 	rar_high &= ~IXGBE_RAH_VIND_MASK;
969ad013249Sreyk 	rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK);
970ad013249Sreyk 	IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
971ad013249Sreyk 	return IXGBE_SUCCESS;
972ad013249Sreyk }
973ad013249Sreyk 
974ad013249Sreyk /**
9753201f924Sjsg  *  ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address
9763201f924Sjsg  *  @hw: pointer to hardware struct
9773201f924Sjsg  *  @rar: receive address register index to associate with a VMDq index
9783201f924Sjsg  *  @vmdq: VMDq clear index (not used in 82598, but elsewhere)
979ad013249Sreyk  **/
ixgbe_clear_vmdq_82598(struct ixgbe_hw * hw,uint32_t rar,uint32_t vmdq)9803201f924Sjsg int32_t ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, uint32_t rar, uint32_t vmdq)
981ad013249Sreyk {
9823201f924Sjsg 	uint32_t rar_high;
9833201f924Sjsg 	uint32_t rar_entries = hw->mac.num_rar_entries;
984ad013249Sreyk 
9859feba5bbSclaudio 	/* Make sure we are using a valid rar index range */
9869feba5bbSclaudio 	if (rar >= rar_entries) {
9879feba5bbSclaudio 		DEBUGOUT1("RAR index %d is out of range.\n", rar);
9889feba5bbSclaudio 		return IXGBE_ERR_INVALID_ARGUMENT;
9899feba5bbSclaudio 	}
9909feba5bbSclaudio 
9913201f924Sjsg 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
9923201f924Sjsg 	if (rar_high & IXGBE_RAH_VIND_MASK) {
9933201f924Sjsg 		rar_high &= ~IXGBE_RAH_VIND_MASK;
9943201f924Sjsg 		IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
995ad013249Sreyk 	}
996ad013249Sreyk 
997ad013249Sreyk 	return IXGBE_SUCCESS;
998ad013249Sreyk }
999ad013249Sreyk 
1000ad013249Sreyk /**
10013201f924Sjsg  *  ixgbe_set_vfta_82598 - Set VLAN filter table
1002ad013249Sreyk  *  @hw: pointer to hardware structure
10033201f924Sjsg  *  @vlan: VLAN id to write to VLAN filter
10043201f924Sjsg  *  @vind: VMDq output index that maps queue to VLAN id in VFTA
10053201f924Sjsg  *  @vlan_on: boolean flag to turn on/off VLAN in VFTA
1006d7a8f955Sjmatthew  *  @vlvf_bypass: boolean flag - unused
10073201f924Sjsg  *
10083201f924Sjsg  *  Turn on/off specified VLAN in the VLAN filter table.
1009ad013249Sreyk  **/
ixgbe_set_vfta_82598(struct ixgbe_hw * hw,uint32_t vlan,uint32_t vind,bool vlan_on,bool vlvf_bypass)10103201f924Sjsg int32_t ixgbe_set_vfta_82598(struct ixgbe_hw *hw, uint32_t vlan, uint32_t vind,
1011d7a8f955Sjmatthew 			     bool vlan_on, bool vlvf_bypass)
1012ad013249Sreyk {
10133201f924Sjsg 	uint32_t regindex;
10143201f924Sjsg 	uint32_t bitindex;
10153201f924Sjsg 	uint32_t bits;
10163201f924Sjsg 	uint32_t vftabyte;
1017ad013249Sreyk 
101811efaf7fSmikeb 	DEBUGFUNC("ixgbe_set_vfta_82598");
101911efaf7fSmikeb 
10203201f924Sjsg 	if (vlan > 4095)
10213201f924Sjsg 		return IXGBE_ERR_PARAM;
1022ad013249Sreyk 
10233201f924Sjsg 	/* Determine 32-bit word position in array */
10243201f924Sjsg 	regindex = (vlan >> 5) & 0x7F;   /* upper seven bits */
10253201f924Sjsg 
10263201f924Sjsg 	/* Determine the location of the (VMD) queue index */
10273201f924Sjsg 	vftabyte =  ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
10283201f924Sjsg 	bitindex = (vlan & 0x7) << 2;    /* lower 3 bits indicate nibble */
10293201f924Sjsg 
10303201f924Sjsg 	/* Set the nibble for VMD queue index */
10313201f924Sjsg 	bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex));
10323201f924Sjsg 	bits &= (~(0x0F << bitindex));
10333201f924Sjsg 	bits |= (vind << bitindex);
10343201f924Sjsg 	IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits);
10353201f924Sjsg 
10363201f924Sjsg 	/* Determine the location of the bit for this VLAN id */
10373201f924Sjsg 	bitindex = vlan & 0x1F;   /* lower five bits */
10383201f924Sjsg 
10393201f924Sjsg 	bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
10403201f924Sjsg 	if (vlan_on)
10413201f924Sjsg 		/* Turn on this VLAN id */
10423201f924Sjsg 		bits |= (1 << bitindex);
10433201f924Sjsg 	else
10443201f924Sjsg 		/* Turn off this VLAN id */
10453201f924Sjsg 		bits &= ~(1 << bitindex);
10463201f924Sjsg 	IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
10473201f924Sjsg 
10483201f924Sjsg 	return IXGBE_SUCCESS;
10493201f924Sjsg }
10503201f924Sjsg 
10513201f924Sjsg /**
10523201f924Sjsg  *  ixgbe_clear_vfta_82598 - Clear VLAN filter table
10533201f924Sjsg  *  @hw: pointer to hardware structure
10543201f924Sjsg  *
10553201f924Sjsg  *  Clears the VLAN filer table, and the VMDq index associated with the filter
10563201f924Sjsg  **/
ixgbe_clear_vfta_82598(struct ixgbe_hw * hw)10573201f924Sjsg int32_t ixgbe_clear_vfta_82598(struct ixgbe_hw *hw)
10583201f924Sjsg {
10593201f924Sjsg 	uint32_t offset;
10603201f924Sjsg 	uint32_t vlanbyte;
10613201f924Sjsg 
106211efaf7fSmikeb 	DEBUGFUNC("ixgbe_clear_vfta_82598");
106311efaf7fSmikeb 
10643201f924Sjsg 	for (offset = 0; offset < hw->mac.vft_size; offset++)
10653201f924Sjsg 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
10663201f924Sjsg 
10673201f924Sjsg 	for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
10683201f924Sjsg 		for (offset = 0; offset < hw->mac.vft_size; offset++)
10693201f924Sjsg 			IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
10703201f924Sjsg 					0);
10713201f924Sjsg 
10723201f924Sjsg 	return IXGBE_SUCCESS;
10733201f924Sjsg }
10743201f924Sjsg 
10753201f924Sjsg /**
10763201f924Sjsg  *  ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
10773201f924Sjsg  *  @hw: pointer to hardware structure
10783201f924Sjsg  *  @reg: analog register to read
10793201f924Sjsg  *  @val: read value
10803201f924Sjsg  *
10813201f924Sjsg  *  Performs read operation to Atlas analog register specified.
10823201f924Sjsg  **/
ixgbe_read_analog_reg8_82598(struct ixgbe_hw * hw,uint32_t reg,uint8_t * val)10833201f924Sjsg int32_t ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, uint32_t reg, uint8_t *val)
10843201f924Sjsg {
10853201f924Sjsg 	uint32_t  atlas_ctl;
10863201f924Sjsg 
108711efaf7fSmikeb 	DEBUGFUNC("ixgbe_read_analog_reg8_82598");
108811efaf7fSmikeb 
10893201f924Sjsg 	IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
10903201f924Sjsg 			IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
1091ad013249Sreyk 	IXGBE_WRITE_FLUSH(hw);
10923201f924Sjsg 	usec_delay(10);
10933201f924Sjsg 	atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
10943201f924Sjsg 	*val = (uint8_t)atlas_ctl;
10953201f924Sjsg 
10963201f924Sjsg 	return IXGBE_SUCCESS;
10973201f924Sjsg }
10983201f924Sjsg 
10993201f924Sjsg /**
11003201f924Sjsg  *  ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register
11013201f924Sjsg  *  @hw: pointer to hardware structure
11023201f924Sjsg  *  @reg: atlas register to write
11033201f924Sjsg  *  @val: value to write
11043201f924Sjsg  *
11053201f924Sjsg  *  Performs write operation to Atlas analog register specified.
11063201f924Sjsg  **/
ixgbe_write_analog_reg8_82598(struct ixgbe_hw * hw,uint32_t reg,uint8_t val)11073201f924Sjsg int32_t ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, uint32_t reg, uint8_t val)
11083201f924Sjsg {
11093201f924Sjsg 	uint32_t  atlas_ctl;
11103201f924Sjsg 
111111efaf7fSmikeb 	DEBUGFUNC("ixgbe_write_analog_reg8_82598");
111211efaf7fSmikeb 
11133201f924Sjsg 	atlas_ctl = (reg << 8) | val;
11143201f924Sjsg 	IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
11153201f924Sjsg 	IXGBE_WRITE_FLUSH(hw);
11163201f924Sjsg 	usec_delay(10);
11173201f924Sjsg 
11183201f924Sjsg 	return IXGBE_SUCCESS;
11193201f924Sjsg }
11203201f924Sjsg 
11213201f924Sjsg /**
112211efaf7fSmikeb  *  ixgbe_read_i2c_phy_82598 - Reads 8 bit word over I2C interface.
11233201f924Sjsg  *  @hw: pointer to hardware structure
112411efaf7fSmikeb  *  @dev_addr: address to read from
112511efaf7fSmikeb  *  @byte_offset: byte offset to read from dev_addr
11263201f924Sjsg  *  @eeprom_data: value read
11273201f924Sjsg  *
11283201f924Sjsg  *  Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
11293201f924Sjsg  **/
ixgbe_read_i2c_phy_82598(struct ixgbe_hw * hw,uint8_t dev_addr,uint8_t byte_offset,uint8_t * eeprom_data)113011efaf7fSmikeb int32_t ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, uint8_t dev_addr,
113111efaf7fSmikeb 				 uint8_t byte_offset, uint8_t *eeprom_data)
11323201f924Sjsg {
11333201f924Sjsg 	int32_t status = IXGBE_SUCCESS;
11343201f924Sjsg 	uint16_t sfp_addr = 0;
11353201f924Sjsg 	uint16_t sfp_data = 0;
11363201f924Sjsg 	uint16_t sfp_stat = 0;
113711efaf7fSmikeb 	uint16_t gssr;
11383201f924Sjsg 	uint32_t i;
11393201f924Sjsg 
114011efaf7fSmikeb 	DEBUGFUNC("ixgbe_read_i2c_phy_82598");
114111efaf7fSmikeb 
114211efaf7fSmikeb 	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
114311efaf7fSmikeb 		gssr = IXGBE_GSSR_PHY1_SM;
114411efaf7fSmikeb 	else
114511efaf7fSmikeb 		gssr = IXGBE_GSSR_PHY0_SM;
114611efaf7fSmikeb 
114711efaf7fSmikeb 	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != IXGBE_SUCCESS)
114811efaf7fSmikeb 		return IXGBE_ERR_SWFW_SYNC;
114911efaf7fSmikeb 
11503201f924Sjsg 	if (hw->phy.type == ixgbe_phy_nl) {
11513201f924Sjsg 		/*
11523201f924Sjsg 		 * NetLogic phy SDA/SCL registers are at addresses 0xC30A to
11533201f924Sjsg 		 * 0xC30D. These registers are used to talk to the SFP+
11543201f924Sjsg 		 * module's EEPROM through the SDA/SCL (I2C) interface.
11553201f924Sjsg 		 */
115611efaf7fSmikeb 		sfp_addr = (dev_addr << 8) + byte_offset;
11573201f924Sjsg 		sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
115811efaf7fSmikeb 		hw->phy.ops.write_reg_mdi(hw,
11593201f924Sjsg 					  IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
11603201f924Sjsg 					  IXGBE_MDIO_PMA_PMD_DEV_TYPE,
11613201f924Sjsg 					  sfp_addr);
11623201f924Sjsg 
11633201f924Sjsg 		/* Poll status */
11643201f924Sjsg 		for (i = 0; i < 100; i++) {
116511efaf7fSmikeb 			hw->phy.ops.read_reg_mdi(hw,
11663201f924Sjsg 						IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
11673201f924Sjsg 						IXGBE_MDIO_PMA_PMD_DEV_TYPE,
11683201f924Sjsg 						&sfp_stat);
11693201f924Sjsg 			sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
11703201f924Sjsg 			if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
11713201f924Sjsg 				break;
11723201f924Sjsg 			msec_delay(10);
11733201f924Sjsg 		}
11743201f924Sjsg 
11753201f924Sjsg 		if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) {
11763201f924Sjsg 			DEBUGOUT("EEPROM read did not pass.\n");
11773201f924Sjsg 			status = IXGBE_ERR_SFP_NOT_PRESENT;
11783201f924Sjsg 			goto out;
11793201f924Sjsg 		}
11803201f924Sjsg 
11813201f924Sjsg 		/* Read data */
118211efaf7fSmikeb 		hw->phy.ops.read_reg_mdi(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
11833201f924Sjsg 					IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
11843201f924Sjsg 
11853201f924Sjsg 		*eeprom_data = (uint8_t)(sfp_data >> 8);
11863201f924Sjsg 	} else {
11873201f924Sjsg 		status = IXGBE_ERR_PHY;
11883201f924Sjsg 	}
11893201f924Sjsg 
11903201f924Sjsg out:
119111efaf7fSmikeb 	hw->mac.ops.release_swfw_sync(hw, gssr);
11923201f924Sjsg 	return status;
11933201f924Sjsg }
11943201f924Sjsg 
11953201f924Sjsg /**
119611efaf7fSmikeb  *  ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
119711efaf7fSmikeb  *  @hw: pointer to hardware structure
119811efaf7fSmikeb  *  @byte_offset: EEPROM byte offset to read
119911efaf7fSmikeb  *  @eeprom_data: value read
120011efaf7fSmikeb  *
120111efaf7fSmikeb  *  Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
120211efaf7fSmikeb  **/
ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw * hw,uint8_t byte_offset,uint8_t * eeprom_data)120311efaf7fSmikeb int32_t ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, uint8_t byte_offset,
120411efaf7fSmikeb 				    uint8_t *eeprom_data)
120511efaf7fSmikeb {
120611efaf7fSmikeb 	return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR,
120711efaf7fSmikeb 					byte_offset, eeprom_data);
120811efaf7fSmikeb }
120911efaf7fSmikeb 
121011efaf7fSmikeb /**
12113201f924Sjsg  *  ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
12123201f924Sjsg  *  @hw: pointer to hardware structure
12133201f924Sjsg  *
12143201f924Sjsg  *  Determines physical layer capabilities of the current configuration.
12153201f924Sjsg  **/
ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw * hw)1216d7a8f955Sjmatthew uint64_t ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
12173201f924Sjsg {
1218d7a8f955Sjmatthew 	uint64_t physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
12193201f924Sjsg 	uint32_t autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
12203201f924Sjsg 	uint32_t pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
12213201f924Sjsg 	uint32_t pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
12223201f924Sjsg 	uint16_t ext_ability = 0;
12233201f924Sjsg 
122411efaf7fSmikeb 	DEBUGFUNC("ixgbe_get_supported_physical_layer_82598");
122511efaf7fSmikeb 
12263201f924Sjsg 	hw->phy.ops.identify(hw);
12273201f924Sjsg 
12283201f924Sjsg 	/* Copper PHY must be checked before AUTOC LMS to determine correct
12293201f924Sjsg 	 * physical layer because 10GBase-T PHYs use LMS = KX4/KX */
12309feba5bbSclaudio 	switch (hw->phy.type) {
12319feba5bbSclaudio 	case ixgbe_phy_tn:
12329feba5bbSclaudio 	case ixgbe_phy_cu_unknown:
12333201f924Sjsg 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
12343201f924Sjsg 		IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
12353201f924Sjsg 		if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
12363201f924Sjsg 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
12373201f924Sjsg 		if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
12383201f924Sjsg 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
12393201f924Sjsg 		if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
12403201f924Sjsg 			physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
12413201f924Sjsg 		goto out;
12429feba5bbSclaudio 	default:
12439feba5bbSclaudio 		break;
12443201f924Sjsg 	}
12453201f924Sjsg 
12463201f924Sjsg 	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
12473201f924Sjsg 	case IXGBE_AUTOC_LMS_1G_AN:
12483201f924Sjsg 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
12493201f924Sjsg 		if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
12503201f924Sjsg 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
12513201f924Sjsg 		else
12523201f924Sjsg 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
12533201f924Sjsg 		break;
12543201f924Sjsg 	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
12553201f924Sjsg 		if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
12563201f924Sjsg 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
12573201f924Sjsg 		else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
12583201f924Sjsg 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
1259d7a8f955Sjmatthew 		else /* XAUI */
1260d7a8f955Sjmatthew 			physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
12613201f924Sjsg 		break;
12623201f924Sjsg 	case IXGBE_AUTOC_LMS_KX4_AN:
12633201f924Sjsg 	case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
12643201f924Sjsg 		if (autoc & IXGBE_AUTOC_KX_SUPP)
12653201f924Sjsg 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
12663201f924Sjsg 		if (autoc & IXGBE_AUTOC_KX4_SUPP)
12673201f924Sjsg 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
12683201f924Sjsg 		break;
12693201f924Sjsg 	default:
12703201f924Sjsg 		break;
12713201f924Sjsg 	}
12723201f924Sjsg 
12733201f924Sjsg 	if (hw->phy.type == ixgbe_phy_nl) {
12743201f924Sjsg 		hw->phy.ops.identify_sfp(hw);
12753201f924Sjsg 
12763201f924Sjsg 		switch (hw->phy.sfp_type) {
12773201f924Sjsg 		case ixgbe_sfp_type_da_cu:
12783201f924Sjsg 			physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
12793201f924Sjsg 			break;
12803201f924Sjsg 		case ixgbe_sfp_type_sr:
12813201f924Sjsg 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
12823201f924Sjsg 			break;
12833201f924Sjsg 		case ixgbe_sfp_type_lr:
12843201f924Sjsg 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
12853201f924Sjsg 			break;
12863201f924Sjsg 		default:
12873201f924Sjsg 			physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
12883201f924Sjsg 			break;
12893201f924Sjsg 		}
12903201f924Sjsg 	}
12913201f924Sjsg 
12923201f924Sjsg 	switch (hw->device_id) {
12933201f924Sjsg 	case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
12943201f924Sjsg 		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
12953201f924Sjsg 		break;
12963201f924Sjsg 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
12973201f924Sjsg 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
12983201f924Sjsg 	case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
12993201f924Sjsg 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
13003201f924Sjsg 		break;
13013201f924Sjsg 	case IXGBE_DEV_ID_82598EB_XF_LR:
13023201f924Sjsg 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
13033201f924Sjsg 		break;
13043201f924Sjsg 	default:
13053201f924Sjsg 		break;
13063201f924Sjsg 	}
13073201f924Sjsg 
13083201f924Sjsg out:
13093201f924Sjsg 	return physical_layer;
13103201f924Sjsg }
13113201f924Sjsg 
13123201f924Sjsg /**
13133201f924Sjsg  *  ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple
13143201f924Sjsg  *  port devices.
13153201f924Sjsg  *  @hw: pointer to the HW structure
13163201f924Sjsg  *
13173201f924Sjsg  *  Calls common function and corrects issue with some single port devices
13183201f924Sjsg  *  that enable LAN1 but not LAN0.
13193201f924Sjsg  **/
ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw * hw)13203201f924Sjsg void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw)
13213201f924Sjsg {
13223201f924Sjsg 	struct ixgbe_bus_info *bus = &hw->bus;
132311efaf7fSmikeb 	uint16_t pci_gen = 0;
132411efaf7fSmikeb 	uint16_t pci_ctrl2 = 0;
132511efaf7fSmikeb 
132611efaf7fSmikeb 	DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie_82598");
13273201f924Sjsg 
13283201f924Sjsg 	ixgbe_set_lan_id_multi_port_pcie(hw);
13293201f924Sjsg 
13303201f924Sjsg 	/* check if LAN0 is disabled */
13313201f924Sjsg 	hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen);
13323201f924Sjsg 	if ((pci_gen != 0) && (pci_gen != 0xFFFF)) {
13333201f924Sjsg 
13343201f924Sjsg 		hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2);
13353201f924Sjsg 
13363201f924Sjsg 		/* if LAN0 is completely disabled force function to 0 */
13373201f924Sjsg 		if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) &&
13383201f924Sjsg 		    !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) &&
13393201f924Sjsg 		    !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) {
13403201f924Sjsg 
13413201f924Sjsg 			bus->func = 0;
13423201f924Sjsg 		}
13433201f924Sjsg 	}
13443201f924Sjsg }
134535e02db6Smikeb 
134635e02db6Smikeb /**
134735e02db6Smikeb  *  ixgbe_enable_rx_dma_82598 - Enable the Rx DMA unit
134835e02db6Smikeb  *  @hw: pointer to hardware structure
134935e02db6Smikeb  *  @regval: register value to write to RXCTRL
135035e02db6Smikeb  *
135135e02db6Smikeb  *  Enables the Rx DMA unit
135235e02db6Smikeb  **/
ixgbe_enable_rx_dma_82598(struct ixgbe_hw * hw,uint32_t regval)135335e02db6Smikeb int32_t ixgbe_enable_rx_dma_82598(struct ixgbe_hw *hw, uint32_t regval)
135435e02db6Smikeb {
135535e02db6Smikeb 	DEBUGFUNC("ixgbe_enable_rx_dma_82598");
135635e02db6Smikeb 
135735e02db6Smikeb 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
135835e02db6Smikeb 
135935e02db6Smikeb 	return IXGBE_SUCCESS;
136035e02db6Smikeb }
1361