xref: /dflybsd-src/sys/dev/netif/ix/ixgbe_82599.c (revision dd5ce676d9b4496101d795200cb99fd0ddf5b254)
179251f5eSSepherosa Ziehau /******************************************************************************
279251f5eSSepherosa Ziehau 
36150453fSSepherosa Ziehau   Copyright (c) 2001-2017, Intel Corporation
479251f5eSSepherosa Ziehau   All rights reserved.
579251f5eSSepherosa Ziehau 
679251f5eSSepherosa Ziehau   Redistribution and use in source and binary forms, with or without
779251f5eSSepherosa Ziehau   modification, are permitted provided that the following conditions are met:
879251f5eSSepherosa Ziehau 
979251f5eSSepherosa Ziehau    1. Redistributions of source code must retain the above copyright notice,
1079251f5eSSepherosa Ziehau       this list of conditions and the following disclaimer.
1179251f5eSSepherosa Ziehau 
1279251f5eSSepherosa Ziehau    2. Redistributions in binary form must reproduce the above copyright
1379251f5eSSepherosa Ziehau       notice, this list of conditions and the following disclaimer in the
1479251f5eSSepherosa Ziehau       documentation and/or other materials provided with the distribution.
1579251f5eSSepherosa Ziehau 
1679251f5eSSepherosa Ziehau    3. Neither the name of the Intel Corporation nor the names of its
1779251f5eSSepherosa Ziehau       contributors may be used to endorse or promote products derived from
1879251f5eSSepherosa Ziehau       this software without specific prior written permission.
1979251f5eSSepherosa Ziehau 
2079251f5eSSepherosa Ziehau   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2179251f5eSSepherosa Ziehau   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2279251f5eSSepherosa Ziehau   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2379251f5eSSepherosa Ziehau   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2479251f5eSSepherosa Ziehau   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2579251f5eSSepherosa Ziehau   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2679251f5eSSepherosa Ziehau   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2779251f5eSSepherosa Ziehau   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2879251f5eSSepherosa Ziehau   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2979251f5eSSepherosa Ziehau   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3079251f5eSSepherosa Ziehau   POSSIBILITY OF SUCH DAMAGE.
3179251f5eSSepherosa Ziehau 
3279251f5eSSepherosa Ziehau ******************************************************************************/
3379251f5eSSepherosa Ziehau /*$FreeBSD$*/
3479251f5eSSepherosa Ziehau 
3579251f5eSSepherosa Ziehau #include "ixgbe_type.h"
3679251f5eSSepherosa Ziehau #include "ixgbe_82599.h"
3779251f5eSSepherosa Ziehau #include "ixgbe_api.h"
3879251f5eSSepherosa Ziehau #include "ixgbe_common.h"
3979251f5eSSepherosa Ziehau #include "ixgbe_phy.h"
4079251f5eSSepherosa Ziehau 
4163d483cdSSepherosa Ziehau #define IXGBE_82599_MAX_TX_QUEUES 128
4263d483cdSSepherosa Ziehau #define IXGBE_82599_MAX_RX_QUEUES 128
4363d483cdSSepherosa Ziehau #define IXGBE_82599_RAR_ENTRIES   128
4463d483cdSSepherosa Ziehau #define IXGBE_82599_MC_TBL_SIZE   128
4563d483cdSSepherosa Ziehau #define IXGBE_82599_VFT_TBL_SIZE  128
4663d483cdSSepherosa Ziehau #define IXGBE_82599_RX_PB_SIZE	  512
4763d483cdSSepherosa Ziehau 
4879251f5eSSepherosa Ziehau static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
4979251f5eSSepherosa Ziehau 					 ixgbe_link_speed speed,
5079251f5eSSepherosa Ziehau 					 bool autoneg_wait_to_complete);
5179251f5eSSepherosa Ziehau static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
5279251f5eSSepherosa Ziehau static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
5379251f5eSSepherosa Ziehau 				   u16 offset, u16 *data);
5479251f5eSSepherosa Ziehau static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
5579251f5eSSepherosa Ziehau 					  u16 words, u16 *data);
5663d483cdSSepherosa Ziehau static s32 ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
5763d483cdSSepherosa Ziehau 					u8 dev_addr, u8 *data);
5863d483cdSSepherosa Ziehau static s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
5963d483cdSSepherosa Ziehau 					u8 dev_addr, u8 data);
6079251f5eSSepherosa Ziehau 
ixgbe_init_mac_link_ops_82599(struct ixgbe_hw * hw)6179251f5eSSepherosa Ziehau void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
6279251f5eSSepherosa Ziehau {
6379251f5eSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
6479251f5eSSepherosa Ziehau 
6579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_mac_link_ops_82599");
6679251f5eSSepherosa Ziehau 
6779251f5eSSepherosa Ziehau 	/*
6879251f5eSSepherosa Ziehau 	 * enable the laser control functions for SFP+ fiber
6979251f5eSSepherosa Ziehau 	 * and MNG not enabled
7079251f5eSSepherosa Ziehau 	 */
7179251f5eSSepherosa Ziehau 	if ((mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
7263d483cdSSepherosa Ziehau 	    !ixgbe_mng_enabled(hw)) {
7379251f5eSSepherosa Ziehau 		mac->ops.disable_tx_laser =
7463d483cdSSepherosa Ziehau 				       ixgbe_disable_tx_laser_multispeed_fiber;
7579251f5eSSepherosa Ziehau 		mac->ops.enable_tx_laser =
7663d483cdSSepherosa Ziehau 					ixgbe_enable_tx_laser_multispeed_fiber;
7763d483cdSSepherosa Ziehau 		mac->ops.flap_tx_laser = ixgbe_flap_tx_laser_multispeed_fiber;
7879251f5eSSepherosa Ziehau 
7979251f5eSSepherosa Ziehau 	} else {
8079251f5eSSepherosa Ziehau 		mac->ops.disable_tx_laser = NULL;
8179251f5eSSepherosa Ziehau 		mac->ops.enable_tx_laser = NULL;
8279251f5eSSepherosa Ziehau 		mac->ops.flap_tx_laser = NULL;
8379251f5eSSepherosa Ziehau 	}
8479251f5eSSepherosa Ziehau 
8579251f5eSSepherosa Ziehau 	if (hw->phy.multispeed_fiber) {
8679251f5eSSepherosa Ziehau 		/* Set up dual speed SFP+ support */
8763d483cdSSepherosa Ziehau 		mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
8863d483cdSSepherosa Ziehau 		mac->ops.setup_mac_link = ixgbe_setup_mac_link_82599;
8963d483cdSSepherosa Ziehau 		mac->ops.set_rate_select_speed =
9063d483cdSSepherosa Ziehau 					       ixgbe_set_hard_rate_select_speed;
9163d483cdSSepherosa Ziehau 		if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber_fixed)
9263d483cdSSepherosa Ziehau 			mac->ops.set_rate_select_speed =
9363d483cdSSepherosa Ziehau 					       ixgbe_set_soft_rate_select_speed;
9479251f5eSSepherosa Ziehau 	} else {
9579251f5eSSepherosa Ziehau 		if ((ixgbe_get_media_type(hw) == ixgbe_media_type_backplane) &&
9679251f5eSSepherosa Ziehau 		     (hw->phy.smart_speed == ixgbe_smart_speed_auto ||
9779251f5eSSepherosa Ziehau 		      hw->phy.smart_speed == ixgbe_smart_speed_on) &&
9879251f5eSSepherosa Ziehau 		      !ixgbe_verify_lesm_fw_enabled_82599(hw)) {
9963d483cdSSepherosa Ziehau 			mac->ops.setup_link = ixgbe_setup_mac_link_smartspeed;
10079251f5eSSepherosa Ziehau 		} else {
10163d483cdSSepherosa Ziehau 			mac->ops.setup_link = ixgbe_setup_mac_link_82599;
10279251f5eSSepherosa Ziehau 		}
10379251f5eSSepherosa Ziehau 	}
10479251f5eSSepherosa Ziehau }
10579251f5eSSepherosa Ziehau 
10679251f5eSSepherosa Ziehau /**
10779251f5eSSepherosa Ziehau  *  ixgbe_init_phy_ops_82599 - PHY/SFP specific init
10879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
10979251f5eSSepherosa Ziehau  *
11079251f5eSSepherosa Ziehau  *  Initialize any function pointers that were not able to be
11179251f5eSSepherosa Ziehau  *  set during init_shared_code because the PHY/SFP type was
11279251f5eSSepherosa Ziehau  *  not known.  Perform the SFP init if necessary.
11379251f5eSSepherosa Ziehau  *
11479251f5eSSepherosa Ziehau  **/
ixgbe_init_phy_ops_82599(struct ixgbe_hw * hw)11579251f5eSSepherosa Ziehau s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
11679251f5eSSepherosa Ziehau {
11779251f5eSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
11879251f5eSSepherosa Ziehau 	struct ixgbe_phy_info *phy = &hw->phy;
11979251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
12063d483cdSSepherosa Ziehau 	u32 esdp;
12179251f5eSSepherosa Ziehau 
12279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_phy_ops_82599");
12379251f5eSSepherosa Ziehau 
12463d483cdSSepherosa Ziehau 	if (hw->device_id == IXGBE_DEV_ID_82599_QSFP_SF_QP) {
12563d483cdSSepherosa Ziehau 		/* Store flag indicating I2C bus access control unit. */
12663d483cdSSepherosa Ziehau 		hw->phy.qsfp_shared_i2c_bus = TRUE;
12763d483cdSSepherosa Ziehau 
12863d483cdSSepherosa Ziehau 		/* Initialize access to QSFP+ I2C bus */
12963d483cdSSepherosa Ziehau 		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
13063d483cdSSepherosa Ziehau 		esdp |= IXGBE_ESDP_SDP0_DIR;
13163d483cdSSepherosa Ziehau 		esdp &= ~IXGBE_ESDP_SDP1_DIR;
13263d483cdSSepherosa Ziehau 		esdp &= ~IXGBE_ESDP_SDP0;
13363d483cdSSepherosa Ziehau 		esdp &= ~IXGBE_ESDP_SDP0_NATIVE;
13463d483cdSSepherosa Ziehau 		esdp &= ~IXGBE_ESDP_SDP1_NATIVE;
13563d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
13663d483cdSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
13763d483cdSSepherosa Ziehau 
13863d483cdSSepherosa Ziehau 		phy->ops.read_i2c_byte = ixgbe_read_i2c_byte_82599;
13963d483cdSSepherosa Ziehau 		phy->ops.write_i2c_byte = ixgbe_write_i2c_byte_82599;
14063d483cdSSepherosa Ziehau 	}
14179251f5eSSepherosa Ziehau 	/* Identify the PHY or SFP module */
14279251f5eSSepherosa Ziehau 	ret_val = phy->ops.identify(hw);
14379251f5eSSepherosa Ziehau 	if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
14479251f5eSSepherosa Ziehau 		goto init_phy_ops_out;
14579251f5eSSepherosa Ziehau 
14679251f5eSSepherosa Ziehau 	/* Setup function pointers based on detected SFP module and speeds */
14779251f5eSSepherosa Ziehau 	ixgbe_init_mac_link_ops_82599(hw);
14879251f5eSSepherosa Ziehau 	if (hw->phy.sfp_type != ixgbe_sfp_type_unknown)
14979251f5eSSepherosa Ziehau 		hw->phy.ops.reset = NULL;
15079251f5eSSepherosa Ziehau 
15179251f5eSSepherosa Ziehau 	/* If copper media, overwrite with copper function pointers */
15279251f5eSSepherosa Ziehau 	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
15363d483cdSSepherosa Ziehau 		mac->ops.setup_link = ixgbe_setup_copper_link_82599;
15479251f5eSSepherosa Ziehau 		mac->ops.get_link_capabilities =
15563d483cdSSepherosa Ziehau 				  ixgbe_get_copper_link_capabilities_generic;
15679251f5eSSepherosa Ziehau 	}
15779251f5eSSepherosa Ziehau 
15863d483cdSSepherosa Ziehau 	/* Set necessary function pointers based on PHY type */
15979251f5eSSepherosa Ziehau 	switch (hw->phy.type) {
16079251f5eSSepherosa Ziehau 	case ixgbe_phy_tn:
16163d483cdSSepherosa Ziehau 		phy->ops.setup_link = ixgbe_setup_phy_link_tnx;
16263d483cdSSepherosa Ziehau 		phy->ops.check_link = ixgbe_check_phy_link_tnx;
16379251f5eSSepherosa Ziehau 		phy->ops.get_firmware_version =
16463d483cdSSepherosa Ziehau 			     ixgbe_get_phy_firmware_version_tnx;
16579251f5eSSepherosa Ziehau 		break;
16679251f5eSSepherosa Ziehau 	default:
16779251f5eSSepherosa Ziehau 		break;
16879251f5eSSepherosa Ziehau 	}
16979251f5eSSepherosa Ziehau init_phy_ops_out:
17079251f5eSSepherosa Ziehau 	return ret_val;
17179251f5eSSepherosa Ziehau }
17279251f5eSSepherosa Ziehau 
ixgbe_setup_sfp_modules_82599(struct ixgbe_hw * hw)17379251f5eSSepherosa Ziehau s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
17479251f5eSSepherosa Ziehau {
17579251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
17679251f5eSSepherosa Ziehau 	u16 list_offset, data_offset, data_value;
17779251f5eSSepherosa Ziehau 
17879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_sfp_modules_82599");
17979251f5eSSepherosa Ziehau 
18079251f5eSSepherosa Ziehau 	if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
18179251f5eSSepherosa Ziehau 		ixgbe_init_mac_link_ops_82599(hw);
18279251f5eSSepherosa Ziehau 
18379251f5eSSepherosa Ziehau 		hw->phy.ops.reset = NULL;
18479251f5eSSepherosa Ziehau 
18579251f5eSSepherosa Ziehau 		ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
18679251f5eSSepherosa Ziehau 							      &data_offset);
18779251f5eSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
18879251f5eSSepherosa Ziehau 			goto setup_sfp_out;
18979251f5eSSepherosa Ziehau 
19079251f5eSSepherosa Ziehau 		/* PHY config will finish before releasing the semaphore */
19179251f5eSSepherosa Ziehau 		ret_val = hw->mac.ops.acquire_swfw_sync(hw,
19279251f5eSSepherosa Ziehau 							IXGBE_GSSR_MAC_CSR_SM);
19379251f5eSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS) {
19479251f5eSSepherosa Ziehau 			ret_val = IXGBE_ERR_SWFW_SYNC;
19579251f5eSSepherosa Ziehau 			goto setup_sfp_out;
19679251f5eSSepherosa Ziehau 		}
19779251f5eSSepherosa Ziehau 
19879251f5eSSepherosa Ziehau 		if (hw->eeprom.ops.read(hw, ++data_offset, &data_value))
19979251f5eSSepherosa Ziehau 			goto setup_sfp_err;
20079251f5eSSepherosa Ziehau 		while (data_value != 0xffff) {
20179251f5eSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value);
20279251f5eSSepherosa Ziehau 			IXGBE_WRITE_FLUSH(hw);
20379251f5eSSepherosa Ziehau 			if (hw->eeprom.ops.read(hw, ++data_offset, &data_value))
20479251f5eSSepherosa Ziehau 				goto setup_sfp_err;
20579251f5eSSepherosa Ziehau 		}
20679251f5eSSepherosa Ziehau 
20779251f5eSSepherosa Ziehau 		/* Release the semaphore */
20879251f5eSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
20963d483cdSSepherosa Ziehau 		/* Delay obtaining semaphore again to allow FW access
21063d483cdSSepherosa Ziehau 		 * prot_autoc_write uses the semaphore too.
21163d483cdSSepherosa Ziehau 		 */
21279251f5eSSepherosa Ziehau 		msec_delay(hw->eeprom.semaphore_delay);
21379251f5eSSepherosa Ziehau 
21479251f5eSSepherosa Ziehau 		/* Restart DSP and set SFI mode */
21563d483cdSSepherosa Ziehau 		ret_val = hw->mac.ops.prot_autoc_write(hw,
21663d483cdSSepherosa Ziehau 			hw->mac.orig_autoc | IXGBE_AUTOC_LMS_10G_SERIAL,
21763d483cdSSepherosa Ziehau 			FALSE);
21879251f5eSSepherosa Ziehau 
21979251f5eSSepherosa Ziehau 		if (ret_val) {
22079251f5eSSepherosa Ziehau 			DEBUGOUT("sfp module setup not complete\n");
22179251f5eSSepherosa Ziehau 			ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
22279251f5eSSepherosa Ziehau 			goto setup_sfp_out;
22379251f5eSSepherosa Ziehau 		}
22479251f5eSSepherosa Ziehau 
22579251f5eSSepherosa Ziehau 	}
22679251f5eSSepherosa Ziehau 
22779251f5eSSepherosa Ziehau setup_sfp_out:
22879251f5eSSepherosa Ziehau 	return ret_val;
22979251f5eSSepherosa Ziehau 
23079251f5eSSepherosa Ziehau setup_sfp_err:
23179251f5eSSepherosa Ziehau 	/* Release the semaphore */
23279251f5eSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
23379251f5eSSepherosa Ziehau 	/* Delay obtaining semaphore again to allow FW access */
23479251f5eSSepherosa Ziehau 	msec_delay(hw->eeprom.semaphore_delay);
23579251f5eSSepherosa Ziehau 	ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
23679251f5eSSepherosa Ziehau 		      "eeprom read at offset %d failed", data_offset);
23779251f5eSSepherosa Ziehau 	return IXGBE_ERR_PHY;
23879251f5eSSepherosa Ziehau }
23979251f5eSSepherosa Ziehau 
24079251f5eSSepherosa Ziehau /**
24163d483cdSSepherosa Ziehau  *  prot_autoc_read_82599 - Hides MAC differences needed for AUTOC read
24263d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
24363d483cdSSepherosa Ziehau  *  @locked: Return the if we locked for this read.
24463d483cdSSepherosa Ziehau  *  @reg_val: Value we read from AUTOC
24563d483cdSSepherosa Ziehau  *
24663d483cdSSepherosa Ziehau  *  For this part (82599) we need to wrap read-modify-writes with a possible
24763d483cdSSepherosa Ziehau  *  FW/SW lock.  It is assumed this lock will be freed with the next
24863d483cdSSepherosa Ziehau  *  prot_autoc_write_82599().
24963d483cdSSepherosa Ziehau  */
prot_autoc_read_82599(struct ixgbe_hw * hw,bool * locked,u32 * reg_val)25063d483cdSSepherosa Ziehau s32 prot_autoc_read_82599(struct ixgbe_hw *hw, bool *locked, u32 *reg_val)
25163d483cdSSepherosa Ziehau {
25263d483cdSSepherosa Ziehau 	s32 ret_val;
25363d483cdSSepherosa Ziehau 
25463d483cdSSepherosa Ziehau 	*locked = FALSE;
25563d483cdSSepherosa Ziehau 	 /* If LESM is on then we need to hold the SW/FW semaphore. */
25663d483cdSSepherosa Ziehau 	if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
25763d483cdSSepherosa Ziehau 		ret_val = hw->mac.ops.acquire_swfw_sync(hw,
25863d483cdSSepherosa Ziehau 					IXGBE_GSSR_MAC_CSR_SM);
25963d483cdSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
26063d483cdSSepherosa Ziehau 			return IXGBE_ERR_SWFW_SYNC;
26163d483cdSSepherosa Ziehau 
26263d483cdSSepherosa Ziehau 		*locked = TRUE;
26363d483cdSSepherosa Ziehau 	}
26463d483cdSSepherosa Ziehau 
26563d483cdSSepherosa Ziehau 	*reg_val = IXGBE_READ_REG(hw, IXGBE_AUTOC);
26663d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
26763d483cdSSepherosa Ziehau }
26863d483cdSSepherosa Ziehau 
26963d483cdSSepherosa Ziehau /**
27063d483cdSSepherosa Ziehau  * prot_autoc_write_82599 - Hides MAC differences needed for AUTOC write
27163d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
272*dd5ce676SSepherosa Ziehau  * @autoc: value to write to AUTOC
27363d483cdSSepherosa Ziehau  * @locked: bool to indicate whether the SW/FW lock was already taken by
27463d483cdSSepherosa Ziehau  *           previous proc_autoc_read_82599.
27563d483cdSSepherosa Ziehau  *
27663d483cdSSepherosa Ziehau  * This part (82599) may need to hold the SW/FW lock around all writes to
27763d483cdSSepherosa Ziehau  * AUTOC. Likewise after a write we need to do a pipeline reset.
27863d483cdSSepherosa Ziehau  */
prot_autoc_write_82599(struct ixgbe_hw * hw,u32 autoc,bool locked)27963d483cdSSepherosa Ziehau s32 prot_autoc_write_82599(struct ixgbe_hw *hw, u32 autoc, bool locked)
28063d483cdSSepherosa Ziehau {
28163d483cdSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
28263d483cdSSepherosa Ziehau 
28363d483cdSSepherosa Ziehau 	/* Blocked by MNG FW so bail */
28463d483cdSSepherosa Ziehau 	if (ixgbe_check_reset_blocked(hw))
28563d483cdSSepherosa Ziehau 		goto out;
28663d483cdSSepherosa Ziehau 
28763d483cdSSepherosa Ziehau 	/* We only need to get the lock if:
28863d483cdSSepherosa Ziehau 	 *  - We didn't do it already (in the read part of a read-modify-write)
28963d483cdSSepherosa Ziehau 	 *  - LESM is enabled.
29063d483cdSSepherosa Ziehau 	 */
29163d483cdSSepherosa Ziehau 	if (!locked && ixgbe_verify_lesm_fw_enabled_82599(hw)) {
29263d483cdSSepherosa Ziehau 		ret_val = hw->mac.ops.acquire_swfw_sync(hw,
29363d483cdSSepherosa Ziehau 					IXGBE_GSSR_MAC_CSR_SM);
29463d483cdSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
29563d483cdSSepherosa Ziehau 			return IXGBE_ERR_SWFW_SYNC;
29663d483cdSSepherosa Ziehau 
29763d483cdSSepherosa Ziehau 		locked = TRUE;
29863d483cdSSepherosa Ziehau 	}
29963d483cdSSepherosa Ziehau 
30063d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
30163d483cdSSepherosa Ziehau 	ret_val = ixgbe_reset_pipeline_82599(hw);
30263d483cdSSepherosa Ziehau 
30363d483cdSSepherosa Ziehau out:
30463d483cdSSepherosa Ziehau 	/* Free the SW/FW semaphore as we either grabbed it here or
30563d483cdSSepherosa Ziehau 	 * already had it when this function was called.
30663d483cdSSepherosa Ziehau 	 */
30763d483cdSSepherosa Ziehau 	if (locked)
30863d483cdSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
30963d483cdSSepherosa Ziehau 
31063d483cdSSepherosa Ziehau 	return ret_val;
31163d483cdSSepherosa Ziehau }
31263d483cdSSepherosa Ziehau 
31363d483cdSSepherosa Ziehau /**
31479251f5eSSepherosa Ziehau  *  ixgbe_init_ops_82599 - Inits func ptrs and MAC type
31579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
31679251f5eSSepherosa Ziehau  *
31779251f5eSSepherosa Ziehau  *  Initialize the function pointers and assign the MAC type for 82599.
31879251f5eSSepherosa Ziehau  *  Does not touch the hardware.
31979251f5eSSepherosa Ziehau  **/
32079251f5eSSepherosa Ziehau 
ixgbe_init_ops_82599(struct ixgbe_hw * hw)32179251f5eSSepherosa Ziehau s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
32279251f5eSSepherosa Ziehau {
32379251f5eSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
32479251f5eSSepherosa Ziehau 	struct ixgbe_phy_info *phy = &hw->phy;
32579251f5eSSepherosa Ziehau 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
32679251f5eSSepherosa Ziehau 	s32 ret_val;
32779251f5eSSepherosa Ziehau 
32879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_ops_82599");
32979251f5eSSepherosa Ziehau 
33079251f5eSSepherosa Ziehau 	ixgbe_init_phy_ops_generic(hw);
33179251f5eSSepherosa Ziehau 	ret_val = ixgbe_init_ops_generic(hw);
33279251f5eSSepherosa Ziehau 
33379251f5eSSepherosa Ziehau 	/* PHY */
33463d483cdSSepherosa Ziehau 	phy->ops.identify = ixgbe_identify_phy_82599;
33563d483cdSSepherosa Ziehau 	phy->ops.init = ixgbe_init_phy_ops_82599;
33679251f5eSSepherosa Ziehau 
33779251f5eSSepherosa Ziehau 	/* MAC */
33863d483cdSSepherosa Ziehau 	mac->ops.reset_hw = ixgbe_reset_hw_82599;
33963d483cdSSepherosa Ziehau 	mac->ops.enable_relaxed_ordering = ixgbe_enable_relaxed_ordering_gen2;
34063d483cdSSepherosa Ziehau 	mac->ops.get_media_type = ixgbe_get_media_type_82599;
34179251f5eSSepherosa Ziehau 	mac->ops.get_supported_physical_layer =
34263d483cdSSepherosa Ziehau 				    ixgbe_get_supported_physical_layer_82599;
34363d483cdSSepherosa Ziehau 	mac->ops.disable_sec_rx_path = ixgbe_disable_sec_rx_path_generic;
34463d483cdSSepherosa Ziehau 	mac->ops.enable_sec_rx_path = ixgbe_enable_sec_rx_path_generic;
34563d483cdSSepherosa Ziehau 	mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_82599;
34663d483cdSSepherosa Ziehau 	mac->ops.read_analog_reg8 = ixgbe_read_analog_reg8_82599;
34763d483cdSSepherosa Ziehau 	mac->ops.write_analog_reg8 = ixgbe_write_analog_reg8_82599;
34863d483cdSSepherosa Ziehau 	mac->ops.start_hw = ixgbe_start_hw_82599;
34963d483cdSSepherosa Ziehau 	mac->ops.get_san_mac_addr = ixgbe_get_san_mac_addr_generic;
35063d483cdSSepherosa Ziehau 	mac->ops.set_san_mac_addr = ixgbe_set_san_mac_addr_generic;
35163d483cdSSepherosa Ziehau 	mac->ops.get_device_caps = ixgbe_get_device_caps_generic;
35263d483cdSSepherosa Ziehau 	mac->ops.get_wwn_prefix = ixgbe_get_wwn_prefix_generic;
35363d483cdSSepherosa Ziehau 	mac->ops.get_fcoe_boot_status = ixgbe_get_fcoe_boot_status_generic;
35463d483cdSSepherosa Ziehau 	mac->ops.prot_autoc_read = prot_autoc_read_82599;
35563d483cdSSepherosa Ziehau 	mac->ops.prot_autoc_write = prot_autoc_write_82599;
35679251f5eSSepherosa Ziehau 
35779251f5eSSepherosa Ziehau 	/* RAR, Multicast, VLAN */
35863d483cdSSepherosa Ziehau 	mac->ops.set_vmdq = ixgbe_set_vmdq_generic;
35963d483cdSSepherosa Ziehau 	mac->ops.set_vmdq_san_mac = ixgbe_set_vmdq_san_mac_generic;
36063d483cdSSepherosa Ziehau 	mac->ops.clear_vmdq = ixgbe_clear_vmdq_generic;
36163d483cdSSepherosa Ziehau 	mac->ops.insert_mac_addr = ixgbe_insert_mac_addr_generic;
36279251f5eSSepherosa Ziehau 	mac->rar_highwater = 1;
36363d483cdSSepherosa Ziehau 	mac->ops.set_vfta = ixgbe_set_vfta_generic;
36463d483cdSSepherosa Ziehau 	mac->ops.set_vlvf = ixgbe_set_vlvf_generic;
36563d483cdSSepherosa Ziehau 	mac->ops.clear_vfta = ixgbe_clear_vfta_generic;
36663d483cdSSepherosa Ziehau 	mac->ops.init_uta_tables = ixgbe_init_uta_tables_generic;
36763d483cdSSepherosa Ziehau 	mac->ops.setup_sfp = ixgbe_setup_sfp_modules_82599;
36863d483cdSSepherosa Ziehau 	mac->ops.set_mac_anti_spoofing = ixgbe_set_mac_anti_spoofing;
36963d483cdSSepherosa Ziehau 	mac->ops.set_vlan_anti_spoofing = ixgbe_set_vlan_anti_spoofing;
37079251f5eSSepherosa Ziehau 
37179251f5eSSepherosa Ziehau 	/* Link */
37263d483cdSSepherosa Ziehau 	mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_82599;
37363d483cdSSepherosa Ziehau 	mac->ops.check_link = ixgbe_check_mac_link_generic;
37463d483cdSSepherosa Ziehau 	mac->ops.setup_rxpba = ixgbe_set_rxpba_generic;
37579251f5eSSepherosa Ziehau 	ixgbe_init_mac_link_ops_82599(hw);
37679251f5eSSepherosa Ziehau 
37763d483cdSSepherosa Ziehau 	mac->mcft_size		= IXGBE_82599_MC_TBL_SIZE;
37863d483cdSSepherosa Ziehau 	mac->vft_size		= IXGBE_82599_VFT_TBL_SIZE;
37963d483cdSSepherosa Ziehau 	mac->num_rar_entries	= IXGBE_82599_RAR_ENTRIES;
38063d483cdSSepherosa Ziehau 	mac->rx_pb_size		= IXGBE_82599_RX_PB_SIZE;
38163d483cdSSepherosa Ziehau 	mac->max_rx_queues	= IXGBE_82599_MAX_RX_QUEUES;
38263d483cdSSepherosa Ziehau 	mac->max_tx_queues	= IXGBE_82599_MAX_TX_QUEUES;
38379251f5eSSepherosa Ziehau 	mac->max_msix_vectors	= ixgbe_get_pcie_msix_count_generic(hw);
38479251f5eSSepherosa Ziehau 
3856150453fSSepherosa Ziehau 	mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw))
3866150453fSSepherosa Ziehau 				      & IXGBE_FWSM_MODE_MASK);
38779251f5eSSepherosa Ziehau 
38879251f5eSSepherosa Ziehau 	hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;
38979251f5eSSepherosa Ziehau 
39079251f5eSSepherosa Ziehau 	/* EEPROM */
39163d483cdSSepherosa Ziehau 	eeprom->ops.read = ixgbe_read_eeprom_82599;
39263d483cdSSepherosa Ziehau 	eeprom->ops.read_buffer = ixgbe_read_eeprom_buffer_82599;
39379251f5eSSepherosa Ziehau 
39479251f5eSSepherosa Ziehau 	/* Manageability interface */
39563d483cdSSepherosa Ziehau 	mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_generic;
39679251f5eSSepherosa Ziehau 
3976150453fSSepherosa Ziehau 	mac->ops.bypass_rw = ixgbe_bypass_rw_generic;
3986150453fSSepherosa Ziehau 	mac->ops.bypass_valid_rd = ixgbe_bypass_valid_rd_generic;
3996150453fSSepherosa Ziehau 	mac->ops.bypass_set = ixgbe_bypass_set_generic;
4006150453fSSepherosa Ziehau 	mac->ops.bypass_rd_eep = ixgbe_bypass_rd_eep_generic;
40179251f5eSSepherosa Ziehau 
40263d483cdSSepherosa Ziehau 	mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic;
40379251f5eSSepherosa Ziehau 
40479251f5eSSepherosa Ziehau 	return ret_val;
40579251f5eSSepherosa Ziehau }
40679251f5eSSepherosa Ziehau 
40779251f5eSSepherosa Ziehau /**
40879251f5eSSepherosa Ziehau  *  ixgbe_get_link_capabilities_82599 - Determines link capabilities
40979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
41079251f5eSSepherosa Ziehau  *  @speed: pointer to link speed
41179251f5eSSepherosa Ziehau  *  @autoneg: TRUE when autoneg or autotry is enabled
41279251f5eSSepherosa Ziehau  *
41379251f5eSSepherosa Ziehau  *  Determines the link capabilities by reading the AUTOC register.
41479251f5eSSepherosa Ziehau  **/
ixgbe_get_link_capabilities_82599(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * autoneg)41579251f5eSSepherosa Ziehau s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
41679251f5eSSepherosa Ziehau 				      ixgbe_link_speed *speed,
41779251f5eSSepherosa Ziehau 				      bool *autoneg)
41879251f5eSSepherosa Ziehau {
41979251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
42079251f5eSSepherosa Ziehau 	u32 autoc = 0;
42179251f5eSSepherosa Ziehau 
42279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_link_capabilities_82599");
42379251f5eSSepherosa Ziehau 
42479251f5eSSepherosa Ziehau 
42579251f5eSSepherosa Ziehau 	/* Check if 1G SFP module. */
42679251f5eSSepherosa Ziehau 	if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
42779251f5eSSepherosa Ziehau 	    hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
42863d483cdSSepherosa Ziehau 	    hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
42963d483cdSSepherosa Ziehau 	    hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
43079251f5eSSepherosa Ziehau 	    hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
43179251f5eSSepherosa Ziehau 	    hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
43279251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
43379251f5eSSepherosa Ziehau 		*autoneg = TRUE;
43479251f5eSSepherosa Ziehau 		goto out;
43579251f5eSSepherosa Ziehau 	}
43679251f5eSSepherosa Ziehau 
43779251f5eSSepherosa Ziehau 	/*
43879251f5eSSepherosa Ziehau 	 * Determine link capabilities based on the stored value of AUTOC,
43979251f5eSSepherosa Ziehau 	 * which represents EEPROM defaults.  If AUTOC value has not
44079251f5eSSepherosa Ziehau 	 * been stored, use the current register values.
44179251f5eSSepherosa Ziehau 	 */
44279251f5eSSepherosa Ziehau 	if (hw->mac.orig_link_settings_stored)
44379251f5eSSepherosa Ziehau 		autoc = hw->mac.orig_autoc;
44479251f5eSSepherosa Ziehau 	else
44579251f5eSSepherosa Ziehau 		autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
44679251f5eSSepherosa Ziehau 
44779251f5eSSepherosa Ziehau 	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
44879251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
44979251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
45079251f5eSSepherosa Ziehau 		*autoneg = FALSE;
45179251f5eSSepherosa Ziehau 		break;
45279251f5eSSepherosa Ziehau 
45379251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
45479251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_10GB_FULL;
45579251f5eSSepherosa Ziehau 		*autoneg = FALSE;
45679251f5eSSepherosa Ziehau 		break;
45779251f5eSSepherosa Ziehau 
45879251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_1G_AN:
45979251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
46079251f5eSSepherosa Ziehau 		*autoneg = TRUE;
46179251f5eSSepherosa Ziehau 		break;
46279251f5eSSepherosa Ziehau 
46379251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_10G_SERIAL:
46479251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_10GB_FULL;
46579251f5eSSepherosa Ziehau 		*autoneg = FALSE;
46679251f5eSSepherosa Ziehau 		break;
46779251f5eSSepherosa Ziehau 
46879251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_KX4_KX_KR:
46979251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
47079251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_UNKNOWN;
47179251f5eSSepherosa Ziehau 		if (autoc & IXGBE_AUTOC_KR_SUPP)
47279251f5eSSepherosa Ziehau 			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
47379251f5eSSepherosa Ziehau 		if (autoc & IXGBE_AUTOC_KX4_SUPP)
47479251f5eSSepherosa Ziehau 			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
47579251f5eSSepherosa Ziehau 		if (autoc & IXGBE_AUTOC_KX_SUPP)
47679251f5eSSepherosa Ziehau 			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
47779251f5eSSepherosa Ziehau 		*autoneg = TRUE;
47879251f5eSSepherosa Ziehau 		break;
47979251f5eSSepherosa Ziehau 
48079251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
48179251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_100_FULL;
48279251f5eSSepherosa Ziehau 		if (autoc & IXGBE_AUTOC_KR_SUPP)
48379251f5eSSepherosa Ziehau 			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
48479251f5eSSepherosa Ziehau 		if (autoc & IXGBE_AUTOC_KX4_SUPP)
48579251f5eSSepherosa Ziehau 			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
48679251f5eSSepherosa Ziehau 		if (autoc & IXGBE_AUTOC_KX_SUPP)
48779251f5eSSepherosa Ziehau 			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
48879251f5eSSepherosa Ziehau 		*autoneg = TRUE;
48979251f5eSSepherosa Ziehau 		break;
49079251f5eSSepherosa Ziehau 
49179251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_SGMII_1G_100M:
49279251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL;
49379251f5eSSepherosa Ziehau 		*autoneg = FALSE;
49479251f5eSSepherosa Ziehau 		break;
49579251f5eSSepherosa Ziehau 
49679251f5eSSepherosa Ziehau 	default:
49779251f5eSSepherosa Ziehau 		status = IXGBE_ERR_LINK_SETUP;
49879251f5eSSepherosa Ziehau 		goto out;
49979251f5eSSepherosa Ziehau 		break;
50079251f5eSSepherosa Ziehau 	}
50179251f5eSSepherosa Ziehau 
50279251f5eSSepherosa Ziehau 	if (hw->phy.multispeed_fiber) {
50379251f5eSSepherosa Ziehau 		*speed |= IXGBE_LINK_SPEED_10GB_FULL |
50479251f5eSSepherosa Ziehau 			  IXGBE_LINK_SPEED_1GB_FULL;
50563d483cdSSepherosa Ziehau 
50663d483cdSSepherosa Ziehau 		/* QSFP must not enable full auto-negotiation
50763d483cdSSepherosa Ziehau 		 * Limited autoneg is enabled at 1G
50863d483cdSSepherosa Ziehau 		 */
50963d483cdSSepherosa Ziehau 		if (hw->phy.media_type == ixgbe_media_type_fiber_qsfp)
51063d483cdSSepherosa Ziehau 			*autoneg = FALSE;
51163d483cdSSepherosa Ziehau 		else
51279251f5eSSepherosa Ziehau 			*autoneg = TRUE;
51379251f5eSSepherosa Ziehau 	}
51479251f5eSSepherosa Ziehau 
51579251f5eSSepherosa Ziehau out:
51679251f5eSSepherosa Ziehau 	return status;
51779251f5eSSepherosa Ziehau }
51879251f5eSSepherosa Ziehau 
51979251f5eSSepherosa Ziehau /**
52079251f5eSSepherosa Ziehau  *  ixgbe_get_media_type_82599 - Get media type
52179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
52279251f5eSSepherosa Ziehau  *
52379251f5eSSepherosa Ziehau  *  Returns the media type (fiber, copper, backplane)
52479251f5eSSepherosa Ziehau  **/
ixgbe_get_media_type_82599(struct ixgbe_hw * hw)52579251f5eSSepherosa Ziehau enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
52679251f5eSSepherosa Ziehau {
52779251f5eSSepherosa Ziehau 	enum ixgbe_media_type media_type;
52879251f5eSSepherosa Ziehau 
52979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_media_type_82599");
53079251f5eSSepherosa Ziehau 
53179251f5eSSepherosa Ziehau 	/* Detect if there is a copper PHY attached. */
53279251f5eSSepherosa Ziehau 	switch (hw->phy.type) {
53379251f5eSSepherosa Ziehau 	case ixgbe_phy_cu_unknown:
53479251f5eSSepherosa Ziehau 	case ixgbe_phy_tn:
53579251f5eSSepherosa Ziehau 		media_type = ixgbe_media_type_copper;
53679251f5eSSepherosa Ziehau 		goto out;
53779251f5eSSepherosa Ziehau 	default:
53879251f5eSSepherosa Ziehau 		break;
53979251f5eSSepherosa Ziehau 	}
54079251f5eSSepherosa Ziehau 
54179251f5eSSepherosa Ziehau 	switch (hw->device_id) {
54279251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_KX4:
54379251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_KX4_MEZZ:
54479251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
54579251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_KR:
54679251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_BACKPLANE_FCOE:
54779251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_XAUI_LOM:
54879251f5eSSepherosa Ziehau 		/* Default device ID is mezzanine card KX/KX4 */
54979251f5eSSepherosa Ziehau 		media_type = ixgbe_media_type_backplane;
55079251f5eSSepherosa Ziehau 		break;
55179251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_SFP:
55279251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_SFP_FCOE:
55379251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_SFP_EM:
55479251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_SFP_SF2:
55579251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_SFP_SF_QP:
55679251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599EN_SFP:
55779251f5eSSepherosa Ziehau 		media_type = ixgbe_media_type_fiber;
55879251f5eSSepherosa Ziehau 		break;
55979251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_CX4:
56079251f5eSSepherosa Ziehau 		media_type = ixgbe_media_type_cx4;
56179251f5eSSepherosa Ziehau 		break;
56279251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_T3_LOM:
56379251f5eSSepherosa Ziehau 		media_type = ixgbe_media_type_copper;
56479251f5eSSepherosa Ziehau 		break;
56563d483cdSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_QSFP_SF_QP:
56663d483cdSSepherosa Ziehau 		media_type = ixgbe_media_type_fiber_qsfp;
56763d483cdSSepherosa Ziehau 		break;
56879251f5eSSepherosa Ziehau 	case IXGBE_DEV_ID_82599_BYPASS:
56979251f5eSSepherosa Ziehau 		media_type = ixgbe_media_type_fiber_fixed;
57079251f5eSSepherosa Ziehau 		hw->phy.multispeed_fiber = TRUE;
57179251f5eSSepherosa Ziehau 		break;
57279251f5eSSepherosa Ziehau 	default:
57379251f5eSSepherosa Ziehau 		media_type = ixgbe_media_type_unknown;
57479251f5eSSepherosa Ziehau 		break;
57579251f5eSSepherosa Ziehau 	}
57679251f5eSSepherosa Ziehau out:
57779251f5eSSepherosa Ziehau 	return media_type;
57879251f5eSSepherosa Ziehau }
57979251f5eSSepherosa Ziehau 
58079251f5eSSepherosa Ziehau /**
58179251f5eSSepherosa Ziehau  *  ixgbe_stop_mac_link_on_d3_82599 - Disables link on D3
58279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
58379251f5eSSepherosa Ziehau  *
58479251f5eSSepherosa Ziehau  *  Disables link during D3 power down sequence.
58579251f5eSSepherosa Ziehau  *
58679251f5eSSepherosa Ziehau  **/
ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw * hw)58779251f5eSSepherosa Ziehau void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw)
58879251f5eSSepherosa Ziehau {
58979251f5eSSepherosa Ziehau 	u32 autoc2_reg;
59079251f5eSSepherosa Ziehau 	u16 ee_ctrl_2 = 0;
59179251f5eSSepherosa Ziehau 
59279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_stop_mac_link_on_d3_82599");
59379251f5eSSepherosa Ziehau 	ixgbe_read_eeprom(hw, IXGBE_EEPROM_CTRL_2, &ee_ctrl_2);
59479251f5eSSepherosa Ziehau 
59563d483cdSSepherosa Ziehau 	if (!ixgbe_mng_present(hw) && !hw->wol_enabled &&
59679251f5eSSepherosa Ziehau 	    ee_ctrl_2 & IXGBE_EEPROM_CCD_BIT) {
59779251f5eSSepherosa Ziehau 		autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
59879251f5eSSepherosa Ziehau 		autoc2_reg |= IXGBE_AUTOC2_LINK_DISABLE_ON_D3_MASK;
59979251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2_reg);
60079251f5eSSepherosa Ziehau 	}
60179251f5eSSepherosa Ziehau }
60279251f5eSSepherosa Ziehau 
60379251f5eSSepherosa Ziehau /**
60479251f5eSSepherosa Ziehau  *  ixgbe_start_mac_link_82599 - Setup MAC link settings
60579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
60679251f5eSSepherosa Ziehau  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
60779251f5eSSepherosa Ziehau  *
60879251f5eSSepherosa Ziehau  *  Configures link settings based on values in the ixgbe_hw struct.
60979251f5eSSepherosa Ziehau  *  Restarts the link.  Performs autonegotiation if needed.
61079251f5eSSepherosa Ziehau  **/
ixgbe_start_mac_link_82599(struct ixgbe_hw * hw,bool autoneg_wait_to_complete)61179251f5eSSepherosa Ziehau s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
61279251f5eSSepherosa Ziehau 			       bool autoneg_wait_to_complete)
61379251f5eSSepherosa Ziehau {
61479251f5eSSepherosa Ziehau 	u32 autoc_reg;
61579251f5eSSepherosa Ziehau 	u32 links_reg;
61679251f5eSSepherosa Ziehau 	u32 i;
61779251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
61879251f5eSSepherosa Ziehau 	bool got_lock = FALSE;
61979251f5eSSepherosa Ziehau 
62079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_start_mac_link_82599");
62179251f5eSSepherosa Ziehau 
62279251f5eSSepherosa Ziehau 
62379251f5eSSepherosa Ziehau 	/*  reset_pipeline requires us to hold this lock as it writes to
62479251f5eSSepherosa Ziehau 	 *  AUTOC.
62579251f5eSSepherosa Ziehau 	 */
62679251f5eSSepherosa Ziehau 	if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
62779251f5eSSepherosa Ziehau 		status = hw->mac.ops.acquire_swfw_sync(hw,
62879251f5eSSepherosa Ziehau 						       IXGBE_GSSR_MAC_CSR_SM);
62979251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
63079251f5eSSepherosa Ziehau 			goto out;
63179251f5eSSepherosa Ziehau 
63279251f5eSSepherosa Ziehau 		got_lock = TRUE;
63379251f5eSSepherosa Ziehau 	}
63479251f5eSSepherosa Ziehau 
63579251f5eSSepherosa Ziehau 	/* Restart link */
63679251f5eSSepherosa Ziehau 	ixgbe_reset_pipeline_82599(hw);
63779251f5eSSepherosa Ziehau 
63879251f5eSSepherosa Ziehau 	if (got_lock)
63979251f5eSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
64079251f5eSSepherosa Ziehau 
64179251f5eSSepherosa Ziehau 	/* Only poll for autoneg to complete if specified to do so */
64279251f5eSSepherosa Ziehau 	if (autoneg_wait_to_complete) {
64379251f5eSSepherosa Ziehau 		autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
64479251f5eSSepherosa Ziehau 		if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
64579251f5eSSepherosa Ziehau 		     IXGBE_AUTOC_LMS_KX4_KX_KR ||
64679251f5eSSepherosa Ziehau 		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
64779251f5eSSepherosa Ziehau 		     IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
64879251f5eSSepherosa Ziehau 		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
64979251f5eSSepherosa Ziehau 		     IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
65079251f5eSSepherosa Ziehau 			links_reg = 0; /* Just in case Autoneg time = 0 */
65179251f5eSSepherosa Ziehau 			for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
65279251f5eSSepherosa Ziehau 				links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
65379251f5eSSepherosa Ziehau 				if (links_reg & IXGBE_LINKS_KX_AN_COMP)
65479251f5eSSepherosa Ziehau 					break;
65579251f5eSSepherosa Ziehau 				msec_delay(100);
65679251f5eSSepherosa Ziehau 			}
65779251f5eSSepherosa Ziehau 			if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
65879251f5eSSepherosa Ziehau 				status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
65979251f5eSSepherosa Ziehau 				DEBUGOUT("Autoneg did not complete.\n");
66079251f5eSSepherosa Ziehau 			}
66179251f5eSSepherosa Ziehau 		}
66279251f5eSSepherosa Ziehau 	}
66379251f5eSSepherosa Ziehau 
66479251f5eSSepherosa Ziehau 	/* Add delay to filter out noises during initial link setup */
66579251f5eSSepherosa Ziehau 	msec_delay(50);
66679251f5eSSepherosa Ziehau 
66779251f5eSSepherosa Ziehau out:
66879251f5eSSepherosa Ziehau 	return status;
66979251f5eSSepherosa Ziehau }
67079251f5eSSepherosa Ziehau 
67179251f5eSSepherosa Ziehau /**
67279251f5eSSepherosa Ziehau  *  ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser
67379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
67479251f5eSSepherosa Ziehau  *
67579251f5eSSepherosa Ziehau  *  The base drivers may require better control over SFP+ module
67679251f5eSSepherosa Ziehau  *  PHY states.  This includes selectively shutting down the Tx
67779251f5eSSepherosa Ziehau  *  laser on the PHY, effectively halting physical link.
67879251f5eSSepherosa Ziehau  **/
ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw * hw)67979251f5eSSepherosa Ziehau void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
68079251f5eSSepherosa Ziehau {
68179251f5eSSepherosa Ziehau 	u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
68279251f5eSSepherosa Ziehau 
68363d483cdSSepherosa Ziehau 	/* Blocked by MNG FW so bail */
68463d483cdSSepherosa Ziehau 	if (ixgbe_check_reset_blocked(hw))
68563d483cdSSepherosa Ziehau 		return;
68663d483cdSSepherosa Ziehau 
68763d483cdSSepherosa Ziehau 	/* Disable Tx laser; allow 100us to go dark per spec */
68879251f5eSSepherosa Ziehau 	esdp_reg |= IXGBE_ESDP_SDP3;
68979251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
69079251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
69179251f5eSSepherosa Ziehau 	usec_delay(100);
69279251f5eSSepherosa Ziehau }
69379251f5eSSepherosa Ziehau 
69479251f5eSSepherosa Ziehau /**
69579251f5eSSepherosa Ziehau  *  ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser
69679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
69779251f5eSSepherosa Ziehau  *
69879251f5eSSepherosa Ziehau  *  The base drivers may require better control over SFP+ module
69979251f5eSSepherosa Ziehau  *  PHY states.  This includes selectively turning on the Tx
70079251f5eSSepherosa Ziehau  *  laser on the PHY, effectively starting physical link.
70179251f5eSSepherosa Ziehau  **/
ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw * hw)70279251f5eSSepherosa Ziehau void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
70379251f5eSSepherosa Ziehau {
70479251f5eSSepherosa Ziehau 	u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
70579251f5eSSepherosa Ziehau 
70663d483cdSSepherosa Ziehau 	/* Enable Tx laser; allow 100ms to light up */
70779251f5eSSepherosa Ziehau 	esdp_reg &= ~IXGBE_ESDP_SDP3;
70879251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
70979251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
71079251f5eSSepherosa Ziehau 	msec_delay(100);
71179251f5eSSepherosa Ziehau }
71279251f5eSSepherosa Ziehau 
71379251f5eSSepherosa Ziehau /**
71479251f5eSSepherosa Ziehau  *  ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser
71579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
71679251f5eSSepherosa Ziehau  *
71779251f5eSSepherosa Ziehau  *  When the driver changes the link speeds that it can support,
71879251f5eSSepherosa Ziehau  *  it sets autotry_restart to TRUE to indicate that we need to
71979251f5eSSepherosa Ziehau  *  initiate a new autotry session with the link partner.  To do
72063d483cdSSepherosa Ziehau  *  so, we set the speed then disable and re-enable the Tx laser, to
72179251f5eSSepherosa Ziehau  *  alert the link partner that it also needs to restart autotry on its
72279251f5eSSepherosa Ziehau  *  end.  This is consistent with TRUE clause 37 autoneg, which also
72379251f5eSSepherosa Ziehau  *  involves a loss of signal.
72479251f5eSSepherosa Ziehau  **/
ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw * hw)72579251f5eSSepherosa Ziehau void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
72679251f5eSSepherosa Ziehau {
72779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_flap_tx_laser_multispeed_fiber");
72879251f5eSSepherosa Ziehau 
72963d483cdSSepherosa Ziehau 	/* Blocked by MNG FW so bail */
73063d483cdSSepherosa Ziehau 	if (ixgbe_check_reset_blocked(hw))
73163d483cdSSepherosa Ziehau 		return;
73263d483cdSSepherosa Ziehau 
73379251f5eSSepherosa Ziehau 	if (hw->mac.autotry_restart) {
73479251f5eSSepherosa Ziehau 		ixgbe_disable_tx_laser_multispeed_fiber(hw);
73579251f5eSSepherosa Ziehau 		ixgbe_enable_tx_laser_multispeed_fiber(hw);
73679251f5eSSepherosa Ziehau 		hw->mac.autotry_restart = FALSE;
73779251f5eSSepherosa Ziehau 	}
73879251f5eSSepherosa Ziehau }
73979251f5eSSepherosa Ziehau 
74079251f5eSSepherosa Ziehau /**
74163d483cdSSepherosa Ziehau  *  ixgbe_set_hard_rate_select_speed - Set module link speed
74279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
74379251f5eSSepherosa Ziehau  *  @speed: link speed to set
74479251f5eSSepherosa Ziehau  *
74563d483cdSSepherosa Ziehau  *  Set module link speed via RS0/RS1 rate select pins.
74679251f5eSSepherosa Ziehau  */
ixgbe_set_hard_rate_select_speed(struct ixgbe_hw * hw,ixgbe_link_speed speed)74763d483cdSSepherosa Ziehau void ixgbe_set_hard_rate_select_speed(struct ixgbe_hw *hw,
74879251f5eSSepherosa Ziehau 					ixgbe_link_speed speed)
74979251f5eSSepherosa Ziehau {
75063d483cdSSepherosa Ziehau 	u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
75179251f5eSSepherosa Ziehau 
75279251f5eSSepherosa Ziehau 	switch (speed) {
75379251f5eSSepherosa Ziehau 	case IXGBE_LINK_SPEED_10GB_FULL:
75463d483cdSSepherosa Ziehau 		esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
75579251f5eSSepherosa Ziehau 		break;
75679251f5eSSepherosa Ziehau 	case IXGBE_LINK_SPEED_1GB_FULL:
75763d483cdSSepherosa Ziehau 		esdp_reg &= ~IXGBE_ESDP_SDP5;
75863d483cdSSepherosa Ziehau 		esdp_reg |= IXGBE_ESDP_SDP5_DIR;
75979251f5eSSepherosa Ziehau 		break;
76079251f5eSSepherosa Ziehau 	default:
76179251f5eSSepherosa Ziehau 		DEBUGOUT("Invalid fixed module speed\n");
76279251f5eSSepherosa Ziehau 		return;
76379251f5eSSepherosa Ziehau 	}
76479251f5eSSepherosa Ziehau 
76579251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
76679251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
76779251f5eSSepherosa Ziehau }
76879251f5eSSepherosa Ziehau 
76979251f5eSSepherosa Ziehau /**
77079251f5eSSepherosa Ziehau  *  ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed
77179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
77279251f5eSSepherosa Ziehau  *  @speed: new link speed
77379251f5eSSepherosa Ziehau  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
77479251f5eSSepherosa Ziehau  *
77579251f5eSSepherosa Ziehau  *  Implements the Intel SmartSpeed algorithm.
77679251f5eSSepherosa Ziehau  **/
ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)77779251f5eSSepherosa Ziehau s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
77879251f5eSSepherosa Ziehau 				    ixgbe_link_speed speed,
77979251f5eSSepherosa Ziehau 				    bool autoneg_wait_to_complete)
78079251f5eSSepherosa Ziehau {
78179251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
78279251f5eSSepherosa Ziehau 	ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
78379251f5eSSepherosa Ziehau 	s32 i, j;
78479251f5eSSepherosa Ziehau 	bool link_up = FALSE;
78579251f5eSSepherosa Ziehau 	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
78679251f5eSSepherosa Ziehau 
78779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_mac_link_smartspeed");
78879251f5eSSepherosa Ziehau 
78979251f5eSSepherosa Ziehau 	 /* Set autoneg_advertised value based on input link speed */
79079251f5eSSepherosa Ziehau 	hw->phy.autoneg_advertised = 0;
79179251f5eSSepherosa Ziehau 
79279251f5eSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
79379251f5eSSepherosa Ziehau 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
79479251f5eSSepherosa Ziehau 
79579251f5eSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
79679251f5eSSepherosa Ziehau 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
79779251f5eSSepherosa Ziehau 
79879251f5eSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_100_FULL)
79979251f5eSSepherosa Ziehau 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
80079251f5eSSepherosa Ziehau 
80179251f5eSSepherosa Ziehau 	/*
80279251f5eSSepherosa Ziehau 	 * Implement Intel SmartSpeed algorithm.  SmartSpeed will reduce the
80379251f5eSSepherosa Ziehau 	 * autoneg advertisement if link is unable to be established at the
80479251f5eSSepherosa Ziehau 	 * highest negotiated rate.  This can sometimes happen due to integrity
80579251f5eSSepherosa Ziehau 	 * issues with the physical media connection.
80679251f5eSSepherosa Ziehau 	 */
80779251f5eSSepherosa Ziehau 
80879251f5eSSepherosa Ziehau 	/* First, try to get link with full advertisement */
80979251f5eSSepherosa Ziehau 	hw->phy.smart_speed_active = FALSE;
81079251f5eSSepherosa Ziehau 	for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) {
81179251f5eSSepherosa Ziehau 		status = ixgbe_setup_mac_link_82599(hw, speed,
81279251f5eSSepherosa Ziehau 						    autoneg_wait_to_complete);
81379251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
81479251f5eSSepherosa Ziehau 			goto out;
81579251f5eSSepherosa Ziehau 
81679251f5eSSepherosa Ziehau 		/*
81779251f5eSSepherosa Ziehau 		 * Wait for the controller to acquire link.  Per IEEE 802.3ap,
81879251f5eSSepherosa Ziehau 		 * Section 73.10.2, we may have to wait up to 500ms if KR is
81979251f5eSSepherosa Ziehau 		 * attempted, or 200ms if KX/KX4/BX/BX4 is attempted, per
82079251f5eSSepherosa Ziehau 		 * Table 9 in the AN MAS.
82179251f5eSSepherosa Ziehau 		 */
82279251f5eSSepherosa Ziehau 		for (i = 0; i < 5; i++) {
82379251f5eSSepherosa Ziehau 			msec_delay(100);
82479251f5eSSepherosa Ziehau 
82579251f5eSSepherosa Ziehau 			/* If we have link, just jump out */
82679251f5eSSepherosa Ziehau 			status = ixgbe_check_link(hw, &link_speed, &link_up,
82779251f5eSSepherosa Ziehau 						  FALSE);
82879251f5eSSepherosa Ziehau 			if (status != IXGBE_SUCCESS)
82979251f5eSSepherosa Ziehau 				goto out;
83079251f5eSSepherosa Ziehau 
83179251f5eSSepherosa Ziehau 			if (link_up)
83279251f5eSSepherosa Ziehau 				goto out;
83379251f5eSSepherosa Ziehau 		}
83479251f5eSSepherosa Ziehau 	}
83579251f5eSSepherosa Ziehau 
83679251f5eSSepherosa Ziehau 	/*
83779251f5eSSepherosa Ziehau 	 * We didn't get link.  If we advertised KR plus one of KX4/KX
83879251f5eSSepherosa Ziehau 	 * (or BX4/BX), then disable KR and try again.
83979251f5eSSepherosa Ziehau 	 */
84079251f5eSSepherosa Ziehau 	if (((autoc_reg & IXGBE_AUTOC_KR_SUPP) == 0) ||
84179251f5eSSepherosa Ziehau 	    ((autoc_reg & IXGBE_AUTOC_KX4_KX_SUPP_MASK) == 0))
84279251f5eSSepherosa Ziehau 		goto out;
84379251f5eSSepherosa Ziehau 
84479251f5eSSepherosa Ziehau 	/* Turn SmartSpeed on to disable KR support */
84579251f5eSSepherosa Ziehau 	hw->phy.smart_speed_active = TRUE;
84679251f5eSSepherosa Ziehau 	status = ixgbe_setup_mac_link_82599(hw, speed,
84779251f5eSSepherosa Ziehau 					    autoneg_wait_to_complete);
84879251f5eSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
84979251f5eSSepherosa Ziehau 		goto out;
85079251f5eSSepherosa Ziehau 
85179251f5eSSepherosa Ziehau 	/*
85279251f5eSSepherosa Ziehau 	 * Wait for the controller to acquire link.  600ms will allow for
85379251f5eSSepherosa Ziehau 	 * the AN link_fail_inhibit_timer as well for multiple cycles of
85479251f5eSSepherosa Ziehau 	 * parallel detect, both 10g and 1g. This allows for the maximum
85579251f5eSSepherosa Ziehau 	 * connect attempts as defined in the AN MAS table 73-7.
85679251f5eSSepherosa Ziehau 	 */
85779251f5eSSepherosa Ziehau 	for (i = 0; i < 6; i++) {
85879251f5eSSepherosa Ziehau 		msec_delay(100);
85979251f5eSSepherosa Ziehau 
86079251f5eSSepherosa Ziehau 		/* If we have link, just jump out */
86179251f5eSSepherosa Ziehau 		status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE);
86279251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
86379251f5eSSepherosa Ziehau 			goto out;
86479251f5eSSepherosa Ziehau 
86579251f5eSSepherosa Ziehau 		if (link_up)
86679251f5eSSepherosa Ziehau 			goto out;
86779251f5eSSepherosa Ziehau 	}
86879251f5eSSepherosa Ziehau 
86979251f5eSSepherosa Ziehau 	/* We didn't get link.  Turn SmartSpeed back off. */
87079251f5eSSepherosa Ziehau 	hw->phy.smart_speed_active = FALSE;
87179251f5eSSepherosa Ziehau 	status = ixgbe_setup_mac_link_82599(hw, speed,
87279251f5eSSepherosa Ziehau 					    autoneg_wait_to_complete);
87379251f5eSSepherosa Ziehau 
87479251f5eSSepherosa Ziehau out:
87579251f5eSSepherosa Ziehau 	if (link_up && (link_speed == IXGBE_LINK_SPEED_1GB_FULL))
87679251f5eSSepherosa Ziehau 		DEBUGOUT("Smartspeed has downgraded the link speed "
87779251f5eSSepherosa Ziehau 		"from the maximum advertised\n");
87879251f5eSSepherosa Ziehau 	return status;
87979251f5eSSepherosa Ziehau }
88079251f5eSSepherosa Ziehau 
88179251f5eSSepherosa Ziehau /**
88279251f5eSSepherosa Ziehau  *  ixgbe_setup_mac_link_82599 - Set MAC link speed
88379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
88479251f5eSSepherosa Ziehau  *  @speed: new link speed
88579251f5eSSepherosa Ziehau  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
88679251f5eSSepherosa Ziehau  *
88779251f5eSSepherosa Ziehau  *  Set the link speed in the AUTOC register and restarts link.
88879251f5eSSepherosa Ziehau  **/
ixgbe_setup_mac_link_82599(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)88979251f5eSSepherosa Ziehau s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
89079251f5eSSepherosa Ziehau 			       ixgbe_link_speed speed,
89179251f5eSSepherosa Ziehau 			       bool autoneg_wait_to_complete)
89279251f5eSSepherosa Ziehau {
89379251f5eSSepherosa Ziehau 	bool autoneg = FALSE;
89479251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
89563d483cdSSepherosa Ziehau 	u32 pma_pmd_1g, link_mode;
89663d483cdSSepherosa Ziehau 	u32 current_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); /* holds the value of AUTOC register at this current point in time */
89763d483cdSSepherosa Ziehau 	u32 orig_autoc = 0; /* holds the cached value of AUTOC register */
89863d483cdSSepherosa Ziehau 	u32 autoc = current_autoc; /* Temporary variable used for comparison purposes */
89979251f5eSSepherosa Ziehau 	u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
90079251f5eSSepherosa Ziehau 	u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
90179251f5eSSepherosa Ziehau 	u32 links_reg;
90279251f5eSSepherosa Ziehau 	u32 i;
90379251f5eSSepherosa Ziehau 	ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
90479251f5eSSepherosa Ziehau 
90579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_mac_link_82599");
90679251f5eSSepherosa Ziehau 
90779251f5eSSepherosa Ziehau 	/* Check to see if speed passed in is supported. */
90879251f5eSSepherosa Ziehau 	status = ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
90979251f5eSSepherosa Ziehau 	if (status)
91079251f5eSSepherosa Ziehau 		goto out;
91179251f5eSSepherosa Ziehau 
91279251f5eSSepherosa Ziehau 	speed &= link_capabilities;
91379251f5eSSepherosa Ziehau 
91479251f5eSSepherosa Ziehau 	if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
91579251f5eSSepherosa Ziehau 		status = IXGBE_ERR_LINK_SETUP;
91679251f5eSSepherosa Ziehau 		goto out;
91779251f5eSSepherosa Ziehau 	}
91879251f5eSSepherosa Ziehau 
91979251f5eSSepherosa Ziehau 	/* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
92079251f5eSSepherosa Ziehau 	if (hw->mac.orig_link_settings_stored)
92163d483cdSSepherosa Ziehau 		orig_autoc = hw->mac.orig_autoc;
92279251f5eSSepherosa Ziehau 	else
92379251f5eSSepherosa Ziehau 		orig_autoc = autoc;
92463d483cdSSepherosa Ziehau 
92579251f5eSSepherosa Ziehau 	link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
92679251f5eSSepherosa Ziehau 	pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
92779251f5eSSepherosa Ziehau 
92879251f5eSSepherosa Ziehau 	if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
92979251f5eSSepherosa Ziehau 	    link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
93079251f5eSSepherosa Ziehau 	    link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
93179251f5eSSepherosa Ziehau 		/* Set KX4/KX/KR support according to speed requested */
93279251f5eSSepherosa Ziehau 		autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
93379251f5eSSepherosa Ziehau 		if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
93479251f5eSSepherosa Ziehau 			if (orig_autoc & IXGBE_AUTOC_KX4_SUPP)
93579251f5eSSepherosa Ziehau 				autoc |= IXGBE_AUTOC_KX4_SUPP;
93679251f5eSSepherosa Ziehau 			if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) &&
93779251f5eSSepherosa Ziehau 			    (hw->phy.smart_speed_active == FALSE))
93879251f5eSSepherosa Ziehau 				autoc |= IXGBE_AUTOC_KR_SUPP;
93979251f5eSSepherosa Ziehau 		}
94079251f5eSSepherosa Ziehau 		if (speed & IXGBE_LINK_SPEED_1GB_FULL)
94179251f5eSSepherosa Ziehau 			autoc |= IXGBE_AUTOC_KX_SUPP;
94279251f5eSSepherosa Ziehau 	} else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) &&
94379251f5eSSepherosa Ziehau 		   (link_mode == IXGBE_AUTOC_LMS_1G_LINK_NO_AN ||
94479251f5eSSepherosa Ziehau 		    link_mode == IXGBE_AUTOC_LMS_1G_AN)) {
94579251f5eSSepherosa Ziehau 		/* Switch from 1G SFI to 10G SFI if requested */
94679251f5eSSepherosa Ziehau 		if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
94779251f5eSSepherosa Ziehau 		    (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)) {
94879251f5eSSepherosa Ziehau 			autoc &= ~IXGBE_AUTOC_LMS_MASK;
94979251f5eSSepherosa Ziehau 			autoc |= IXGBE_AUTOC_LMS_10G_SERIAL;
95079251f5eSSepherosa Ziehau 		}
95179251f5eSSepherosa Ziehau 	} else if ((pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI) &&
95279251f5eSSepherosa Ziehau 		   (link_mode == IXGBE_AUTOC_LMS_10G_SERIAL)) {
95379251f5eSSepherosa Ziehau 		/* Switch from 10G SFI to 1G SFI if requested */
95479251f5eSSepherosa Ziehau 		if ((speed == IXGBE_LINK_SPEED_1GB_FULL) &&
95579251f5eSSepherosa Ziehau 		    (pma_pmd_1g == IXGBE_AUTOC_1G_SFI)) {
95679251f5eSSepherosa Ziehau 			autoc &= ~IXGBE_AUTOC_LMS_MASK;
95763d483cdSSepherosa Ziehau 			if (autoneg || hw->phy.type == ixgbe_phy_qsfp_intel)
95879251f5eSSepherosa Ziehau 				autoc |= IXGBE_AUTOC_LMS_1G_AN;
95979251f5eSSepherosa Ziehau 			else
96079251f5eSSepherosa Ziehau 				autoc |= IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
96179251f5eSSepherosa Ziehau 		}
96279251f5eSSepherosa Ziehau 	}
96379251f5eSSepherosa Ziehau 
96463d483cdSSepherosa Ziehau 	if (autoc != current_autoc) {
96579251f5eSSepherosa Ziehau 		/* Restart link */
96663d483cdSSepherosa Ziehau 		status = hw->mac.ops.prot_autoc_write(hw, autoc, FALSE);
96763d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
96863d483cdSSepherosa Ziehau 			goto out;
96979251f5eSSepherosa Ziehau 
97079251f5eSSepherosa Ziehau 		/* Only poll for autoneg to complete if specified to do so */
97179251f5eSSepherosa Ziehau 		if (autoneg_wait_to_complete) {
97279251f5eSSepherosa Ziehau 			if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
97379251f5eSSepherosa Ziehau 			    link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
97479251f5eSSepherosa Ziehau 			    link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
97579251f5eSSepherosa Ziehau 				links_reg = 0; /*Just in case Autoneg time=0*/
97679251f5eSSepherosa Ziehau 				for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
97779251f5eSSepherosa Ziehau 					links_reg =
97879251f5eSSepherosa Ziehau 					       IXGBE_READ_REG(hw, IXGBE_LINKS);
97979251f5eSSepherosa Ziehau 					if (links_reg & IXGBE_LINKS_KX_AN_COMP)
98079251f5eSSepherosa Ziehau 						break;
98179251f5eSSepherosa Ziehau 					msec_delay(100);
98279251f5eSSepherosa Ziehau 				}
98379251f5eSSepherosa Ziehau 				if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
98479251f5eSSepherosa Ziehau 					status =
98579251f5eSSepherosa Ziehau 						IXGBE_ERR_AUTONEG_NOT_COMPLETE;
98679251f5eSSepherosa Ziehau 					DEBUGOUT("Autoneg did not complete.\n");
98779251f5eSSepherosa Ziehau 				}
98879251f5eSSepherosa Ziehau 			}
98979251f5eSSepherosa Ziehau 		}
99079251f5eSSepherosa Ziehau 
99179251f5eSSepherosa Ziehau 		/* Add delay to filter out noises during initial link setup */
99279251f5eSSepherosa Ziehau 		msec_delay(50);
99379251f5eSSepherosa Ziehau 	}
99479251f5eSSepherosa Ziehau 
99579251f5eSSepherosa Ziehau out:
99679251f5eSSepherosa Ziehau 	return status;
99779251f5eSSepherosa Ziehau }
99879251f5eSSepherosa Ziehau 
99979251f5eSSepherosa Ziehau /**
100079251f5eSSepherosa Ziehau  *  ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field
100179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
100279251f5eSSepherosa Ziehau  *  @speed: new link speed
100379251f5eSSepherosa Ziehau  *  @autoneg_wait_to_complete: TRUE if waiting is needed to complete
100479251f5eSSepherosa Ziehau  *
100579251f5eSSepherosa Ziehau  *  Restarts link on PHY and MAC based on settings passed in.
100679251f5eSSepherosa Ziehau  **/
ixgbe_setup_copper_link_82599(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)100779251f5eSSepherosa Ziehau static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
100879251f5eSSepherosa Ziehau 					 ixgbe_link_speed speed,
100979251f5eSSepherosa Ziehau 					 bool autoneg_wait_to_complete)
101079251f5eSSepherosa Ziehau {
101179251f5eSSepherosa Ziehau 	s32 status;
101279251f5eSSepherosa Ziehau 
101379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_copper_link_82599");
101479251f5eSSepherosa Ziehau 
101579251f5eSSepherosa Ziehau 	/* Setup the PHY according to input speed */
101679251f5eSSepherosa Ziehau 	status = hw->phy.ops.setup_link_speed(hw, speed,
101779251f5eSSepherosa Ziehau 					      autoneg_wait_to_complete);
101879251f5eSSepherosa Ziehau 	/* Set up MAC */
101979251f5eSSepherosa Ziehau 	ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete);
102079251f5eSSepherosa Ziehau 
102179251f5eSSepherosa Ziehau 	return status;
102279251f5eSSepherosa Ziehau }
102379251f5eSSepherosa Ziehau 
102479251f5eSSepherosa Ziehau /**
102579251f5eSSepherosa Ziehau  *  ixgbe_reset_hw_82599 - Perform hardware reset
102679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
102779251f5eSSepherosa Ziehau  *
102879251f5eSSepherosa Ziehau  *  Resets the hardware by resetting the transmit and receive units, masks
102979251f5eSSepherosa Ziehau  *  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
103079251f5eSSepherosa Ziehau  *  reset.
103179251f5eSSepherosa Ziehau  **/
ixgbe_reset_hw_82599(struct ixgbe_hw * hw)103279251f5eSSepherosa Ziehau s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
103379251f5eSSepherosa Ziehau {
103479251f5eSSepherosa Ziehau 	ixgbe_link_speed link_speed;
103579251f5eSSepherosa Ziehau 	s32 status;
103663d483cdSSepherosa Ziehau 	u32 ctrl = 0;
103763d483cdSSepherosa Ziehau 	u32 i, autoc, autoc2;
103879251f5eSSepherosa Ziehau 	u32 curr_lms;
103979251f5eSSepherosa Ziehau 	bool link_up = FALSE;
104079251f5eSSepherosa Ziehau 
104179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_reset_hw_82599");
104279251f5eSSepherosa Ziehau 
104379251f5eSSepherosa Ziehau 	/* Call adapter stop to disable tx/rx and clear interrupts */
104479251f5eSSepherosa Ziehau 	status = hw->mac.ops.stop_adapter(hw);
104579251f5eSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
104679251f5eSSepherosa Ziehau 		goto reset_hw_out;
104779251f5eSSepherosa Ziehau 
104879251f5eSSepherosa Ziehau 	/* flush pending Tx transactions */
104979251f5eSSepherosa Ziehau 	ixgbe_clear_tx_pending(hw);
105079251f5eSSepherosa Ziehau 
105179251f5eSSepherosa Ziehau 	/* PHY ops must be identified and initialized prior to reset */
105279251f5eSSepherosa Ziehau 
105379251f5eSSepherosa Ziehau 	/* Identify PHY and related function pointers */
105479251f5eSSepherosa Ziehau 	status = hw->phy.ops.init(hw);
105579251f5eSSepherosa Ziehau 
105679251f5eSSepherosa Ziehau 	if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
105779251f5eSSepherosa Ziehau 		goto reset_hw_out;
105879251f5eSSepherosa Ziehau 
105979251f5eSSepherosa Ziehau 	/* Setup SFP module if there is one present. */
106079251f5eSSepherosa Ziehau 	if (hw->phy.sfp_setup_needed) {
106179251f5eSSepherosa Ziehau 		status = hw->mac.ops.setup_sfp(hw);
106279251f5eSSepherosa Ziehau 		hw->phy.sfp_setup_needed = FALSE;
106379251f5eSSepherosa Ziehau 	}
106479251f5eSSepherosa Ziehau 
106579251f5eSSepherosa Ziehau 	if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
106679251f5eSSepherosa Ziehau 		goto reset_hw_out;
106779251f5eSSepherosa Ziehau 
106879251f5eSSepherosa Ziehau 	/* Reset PHY */
106979251f5eSSepherosa Ziehau 	if (hw->phy.reset_disable == FALSE && hw->phy.ops.reset != NULL)
107079251f5eSSepherosa Ziehau 		hw->phy.ops.reset(hw);
107179251f5eSSepherosa Ziehau 
107279251f5eSSepherosa Ziehau 	/* remember AUTOC from before we reset */
107363d483cdSSepherosa Ziehau 	curr_lms = IXGBE_READ_REG(hw, IXGBE_AUTOC) & IXGBE_AUTOC_LMS_MASK;
107479251f5eSSepherosa Ziehau 
107579251f5eSSepherosa Ziehau mac_reset_top:
107679251f5eSSepherosa Ziehau 	/*
107779251f5eSSepherosa Ziehau 	 * Issue global reset to the MAC.  Needs to be SW reset if link is up.
107879251f5eSSepherosa Ziehau 	 * If link reset is used when link is up, it might reset the PHY when
107979251f5eSSepherosa Ziehau 	 * mng is using it.  If link is down or the flag to force full link
108079251f5eSSepherosa Ziehau 	 * reset is set, then perform link reset.
108179251f5eSSepherosa Ziehau 	 */
108279251f5eSSepherosa Ziehau 	ctrl = IXGBE_CTRL_LNK_RST;
108379251f5eSSepherosa Ziehau 	if (!hw->force_full_reset) {
108479251f5eSSepherosa Ziehau 		hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
108579251f5eSSepherosa Ziehau 		if (link_up)
108679251f5eSSepherosa Ziehau 			ctrl = IXGBE_CTRL_RST;
108779251f5eSSepherosa Ziehau 	}
108879251f5eSSepherosa Ziehau 
108979251f5eSSepherosa Ziehau 	ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
109079251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
109179251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
109279251f5eSSepherosa Ziehau 
109363d483cdSSepherosa Ziehau 	/* Poll for reset bit to self-clear meaning reset is complete */
109479251f5eSSepherosa Ziehau 	for (i = 0; i < 10; i++) {
109579251f5eSSepherosa Ziehau 		usec_delay(1);
109679251f5eSSepherosa Ziehau 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
109779251f5eSSepherosa Ziehau 		if (!(ctrl & IXGBE_CTRL_RST_MASK))
109879251f5eSSepherosa Ziehau 			break;
109979251f5eSSepherosa Ziehau 	}
110079251f5eSSepherosa Ziehau 
110179251f5eSSepherosa Ziehau 	if (ctrl & IXGBE_CTRL_RST_MASK) {
110279251f5eSSepherosa Ziehau 		status = IXGBE_ERR_RESET_FAILED;
110379251f5eSSepherosa Ziehau 		DEBUGOUT("Reset polling failed to complete.\n");
110479251f5eSSepherosa Ziehau 	}
110579251f5eSSepherosa Ziehau 
110679251f5eSSepherosa Ziehau 	msec_delay(50);
110779251f5eSSepherosa Ziehau 
110879251f5eSSepherosa Ziehau 	/*
110979251f5eSSepherosa Ziehau 	 * Double resets are required for recovery from certain error
111063d483cdSSepherosa Ziehau 	 * conditions.  Between resets, it is necessary to stall to
111163d483cdSSepherosa Ziehau 	 * allow time for any pending HW events to complete.
111279251f5eSSepherosa Ziehau 	 */
111379251f5eSSepherosa Ziehau 	if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
111479251f5eSSepherosa Ziehau 		hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
111579251f5eSSepherosa Ziehau 		goto mac_reset_top;
111679251f5eSSepherosa Ziehau 	}
111779251f5eSSepherosa Ziehau 
111879251f5eSSepherosa Ziehau 	/*
111979251f5eSSepherosa Ziehau 	 * Store the original AUTOC/AUTOC2 values if they have not been
112079251f5eSSepherosa Ziehau 	 * stored off yet.  Otherwise restore the stored original
112179251f5eSSepherosa Ziehau 	 * values since the reset operation sets back to defaults.
112279251f5eSSepherosa Ziehau 	 */
112363d483cdSSepherosa Ziehau 	autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
112479251f5eSSepherosa Ziehau 	autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
112579251f5eSSepherosa Ziehau 
112679251f5eSSepherosa Ziehau 	/* Enable link if disabled in NVM */
112779251f5eSSepherosa Ziehau 	if (autoc2 & IXGBE_AUTOC2_LINK_DISABLE_MASK) {
112879251f5eSSepherosa Ziehau 		autoc2 &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK;
112979251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2);
113079251f5eSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
113179251f5eSSepherosa Ziehau 	}
113279251f5eSSepherosa Ziehau 
113379251f5eSSepherosa Ziehau 	if (hw->mac.orig_link_settings_stored == FALSE) {
113463d483cdSSepherosa Ziehau 		hw->mac.orig_autoc = autoc;
113579251f5eSSepherosa Ziehau 		hw->mac.orig_autoc2 = autoc2;
113679251f5eSSepherosa Ziehau 		hw->mac.orig_link_settings_stored = TRUE;
113779251f5eSSepherosa Ziehau 	} else {
113879251f5eSSepherosa Ziehau 
113979251f5eSSepherosa Ziehau 		/* If MNG FW is running on a multi-speed device that
114079251f5eSSepherosa Ziehau 		 * doesn't autoneg with out driver support we need to
114179251f5eSSepherosa Ziehau 		 * leave LMS in the state it was before we MAC reset.
114279251f5eSSepherosa Ziehau 		 * Likewise if we support WoL we don't want change the
114379251f5eSSepherosa Ziehau 		 * LMS state.
114479251f5eSSepherosa Ziehau 		 */
114563d483cdSSepherosa Ziehau 		if ((hw->phy.multispeed_fiber && ixgbe_mng_enabled(hw)) ||
114679251f5eSSepherosa Ziehau 		    hw->wol_enabled)
114779251f5eSSepherosa Ziehau 			hw->mac.orig_autoc =
114879251f5eSSepherosa Ziehau 				(hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) |
114979251f5eSSepherosa Ziehau 				curr_lms;
115079251f5eSSepherosa Ziehau 
115163d483cdSSepherosa Ziehau 		if (autoc != hw->mac.orig_autoc) {
115263d483cdSSepherosa Ziehau 			status = hw->mac.ops.prot_autoc_write(hw,
115363d483cdSSepherosa Ziehau 							hw->mac.orig_autoc,
115463d483cdSSepherosa Ziehau 							FALSE);
115563d483cdSSepherosa Ziehau 			if (status != IXGBE_SUCCESS)
115679251f5eSSepherosa Ziehau 				goto reset_hw_out;
115779251f5eSSepherosa Ziehau 		}
115879251f5eSSepherosa Ziehau 
115979251f5eSSepherosa Ziehau 		if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
116079251f5eSSepherosa Ziehau 		    (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
116179251f5eSSepherosa Ziehau 			autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK;
116279251f5eSSepherosa Ziehau 			autoc2 |= (hw->mac.orig_autoc2 &
116379251f5eSSepherosa Ziehau 				   IXGBE_AUTOC2_UPPER_MASK);
116479251f5eSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2);
116579251f5eSSepherosa Ziehau 		}
116679251f5eSSepherosa Ziehau 	}
116779251f5eSSepherosa Ziehau 
116879251f5eSSepherosa Ziehau 	/* Store the permanent mac address */
116979251f5eSSepherosa Ziehau 	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
117079251f5eSSepherosa Ziehau 
117179251f5eSSepherosa Ziehau 	/*
117279251f5eSSepherosa Ziehau 	 * Store MAC address from RAR0, clear receive address registers, and
117379251f5eSSepherosa Ziehau 	 * clear the multicast table.  Also reset num_rar_entries to 128,
117479251f5eSSepherosa Ziehau 	 * since we modify this value when programming the SAN MAC address.
117579251f5eSSepherosa Ziehau 	 */
117679251f5eSSepherosa Ziehau 	hw->mac.num_rar_entries = 128;
117779251f5eSSepherosa Ziehau 	hw->mac.ops.init_rx_addrs(hw);
117879251f5eSSepherosa Ziehau 
117979251f5eSSepherosa Ziehau 	/* Store the permanent SAN mac address */
118079251f5eSSepherosa Ziehau 	hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr);
118179251f5eSSepherosa Ziehau 
118279251f5eSSepherosa Ziehau 	/* Add the SAN MAC address to the RAR only if it's a valid address */
118379251f5eSSepherosa Ziehau 	if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
118479251f5eSSepherosa Ziehau 		/* Save the SAN MAC RAR index */
118579251f5eSSepherosa Ziehau 		hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
118679251f5eSSepherosa Ziehau 
11876150453fSSepherosa Ziehau 		hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
11886150453fSSepherosa Ziehau 				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
11896150453fSSepherosa Ziehau 
11906150453fSSepherosa Ziehau 		/* clear VMDq pool/queue selection for this RAR */
11916150453fSSepherosa Ziehau 		hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
11926150453fSSepherosa Ziehau 				       IXGBE_CLEAR_VMDQ_ALL);
11936150453fSSepherosa Ziehau 
119479251f5eSSepherosa Ziehau 		/* Reserve the last RAR for the SAN MAC address */
119579251f5eSSepherosa Ziehau 		hw->mac.num_rar_entries--;
119679251f5eSSepherosa Ziehau 	}
119779251f5eSSepherosa Ziehau 
119879251f5eSSepherosa Ziehau 	/* Store the alternative WWNN/WWPN prefix */
119979251f5eSSepherosa Ziehau 	hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
120079251f5eSSepherosa Ziehau 				   &hw->mac.wwpn_prefix);
120179251f5eSSepherosa Ziehau 
120279251f5eSSepherosa Ziehau reset_hw_out:
120379251f5eSSepherosa Ziehau 	return status;
120479251f5eSSepherosa Ziehau }
120579251f5eSSepherosa Ziehau 
120679251f5eSSepherosa Ziehau /**
120763d483cdSSepherosa Ziehau  * ixgbe_fdir_check_cmd_complete - poll to check whether FDIRCMD is complete
120863d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
120963d483cdSSepherosa Ziehau  * @fdircmd: current value of FDIRCMD register
121063d483cdSSepherosa Ziehau  */
ixgbe_fdir_check_cmd_complete(struct ixgbe_hw * hw,u32 * fdircmd)121163d483cdSSepherosa Ziehau static s32 ixgbe_fdir_check_cmd_complete(struct ixgbe_hw *hw, u32 *fdircmd)
121263d483cdSSepherosa Ziehau {
121363d483cdSSepherosa Ziehau 	int i;
121463d483cdSSepherosa Ziehau 
121563d483cdSSepherosa Ziehau 	for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) {
121663d483cdSSepherosa Ziehau 		*fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD);
121763d483cdSSepherosa Ziehau 		if (!(*fdircmd & IXGBE_FDIRCMD_CMD_MASK))
121863d483cdSSepherosa Ziehau 			return IXGBE_SUCCESS;
121963d483cdSSepherosa Ziehau 		usec_delay(10);
122063d483cdSSepherosa Ziehau 	}
122163d483cdSSepherosa Ziehau 
122263d483cdSSepherosa Ziehau 	return IXGBE_ERR_FDIR_CMD_INCOMPLETE;
122363d483cdSSepherosa Ziehau }
122463d483cdSSepherosa Ziehau 
122563d483cdSSepherosa Ziehau /**
122679251f5eSSepherosa Ziehau  *  ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables.
122779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
122879251f5eSSepherosa Ziehau  **/
ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw * hw)122979251f5eSSepherosa Ziehau s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
123079251f5eSSepherosa Ziehau {
123163d483cdSSepherosa Ziehau 	s32 err;
123279251f5eSSepherosa Ziehau 	int i;
123379251f5eSSepherosa Ziehau 	u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
123463d483cdSSepherosa Ziehau 	u32 fdircmd;
123579251f5eSSepherosa Ziehau 	fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE;
123679251f5eSSepherosa Ziehau 
123779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_reinit_fdir_tables_82599");
123879251f5eSSepherosa Ziehau 
123979251f5eSSepherosa Ziehau 	/*
124079251f5eSSepherosa Ziehau 	 * Before starting reinitialization process,
124179251f5eSSepherosa Ziehau 	 * FDIRCMD.CMD must be zero.
124279251f5eSSepherosa Ziehau 	 */
124363d483cdSSepherosa Ziehau 	err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd);
124463d483cdSSepherosa Ziehau 	if (err) {
124563d483cdSSepherosa Ziehau 		DEBUGOUT("Flow Director previous command did not complete, aborting table re-initialization.\n");
124663d483cdSSepherosa Ziehau 		return err;
124779251f5eSSepherosa Ziehau 	}
124879251f5eSSepherosa Ziehau 
124979251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0);
125079251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
125179251f5eSSepherosa Ziehau 	/*
125279251f5eSSepherosa Ziehau 	 * 82599 adapters flow director init flow cannot be restarted,
125379251f5eSSepherosa Ziehau 	 * Workaround 82599 silicon errata by performing the following steps
125479251f5eSSepherosa Ziehau 	 * before re-writing the FDIRCTRL control register with the same value.
125579251f5eSSepherosa Ziehau 	 * - write 1 to bit 8 of FDIRCMD register &
125679251f5eSSepherosa Ziehau 	 * - write 0 to bit 8 of FDIRCMD register
125779251f5eSSepherosa Ziehau 	 */
125879251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
125979251f5eSSepherosa Ziehau 			(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) |
126079251f5eSSepherosa Ziehau 			 IXGBE_FDIRCMD_CLEARHT));
126179251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
126279251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
126379251f5eSSepherosa Ziehau 			(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
126479251f5eSSepherosa Ziehau 			 ~IXGBE_FDIRCMD_CLEARHT));
126579251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
126679251f5eSSepherosa Ziehau 	/*
126779251f5eSSepherosa Ziehau 	 * Clear FDIR Hash register to clear any leftover hashes
126879251f5eSSepherosa Ziehau 	 * waiting to be programmed.
126979251f5eSSepherosa Ziehau 	 */
127079251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, 0x00);
127179251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
127279251f5eSSepherosa Ziehau 
127379251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
127479251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
127579251f5eSSepherosa Ziehau 
127679251f5eSSepherosa Ziehau 	/* Poll init-done after we write FDIRCTRL register */
127779251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
127879251f5eSSepherosa Ziehau 		if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
127979251f5eSSepherosa Ziehau 				   IXGBE_FDIRCTRL_INIT_DONE)
128079251f5eSSepherosa Ziehau 			break;
128179251f5eSSepherosa Ziehau 		msec_delay(1);
128279251f5eSSepherosa Ziehau 	}
128379251f5eSSepherosa Ziehau 	if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
128479251f5eSSepherosa Ziehau 		DEBUGOUT("Flow Director Signature poll time exceeded!\n");
128579251f5eSSepherosa Ziehau 		return IXGBE_ERR_FDIR_REINIT_FAILED;
128679251f5eSSepherosa Ziehau 	}
128779251f5eSSepherosa Ziehau 
128879251f5eSSepherosa Ziehau 	/* Clear FDIR statistics registers (read to clear) */
128979251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT);
129079251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT);
129179251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
129279251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
129379251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_FDIRLEN);
129479251f5eSSepherosa Ziehau 
129579251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
129679251f5eSSepherosa Ziehau }
129779251f5eSSepherosa Ziehau 
129879251f5eSSepherosa Ziehau /**
129979251f5eSSepherosa Ziehau  *  ixgbe_fdir_enable_82599 - Initialize Flow Director control registers
130079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
130179251f5eSSepherosa Ziehau  *  @fdirctrl: value to write to flow director control register
130279251f5eSSepherosa Ziehau  **/
ixgbe_fdir_enable_82599(struct ixgbe_hw * hw,u32 fdirctrl)130379251f5eSSepherosa Ziehau static void ixgbe_fdir_enable_82599(struct ixgbe_hw *hw, u32 fdirctrl)
130479251f5eSSepherosa Ziehau {
130579251f5eSSepherosa Ziehau 	int i;
130679251f5eSSepherosa Ziehau 
130779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_fdir_enable_82599");
130879251f5eSSepherosa Ziehau 
130979251f5eSSepherosa Ziehau 	/* Prime the keys for hashing */
131079251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, IXGBE_ATR_BUCKET_HASH_KEY);
131179251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, IXGBE_ATR_SIGNATURE_HASH_KEY);
131279251f5eSSepherosa Ziehau 
131379251f5eSSepherosa Ziehau 	/*
131479251f5eSSepherosa Ziehau 	 * Poll init-done after we write the register.  Estimated times:
131579251f5eSSepherosa Ziehau 	 *      10G: PBALLOC = 11b, timing is 60us
131679251f5eSSepherosa Ziehau 	 *       1G: PBALLOC = 11b, timing is 600us
131779251f5eSSepherosa Ziehau 	 *     100M: PBALLOC = 11b, timing is 6ms
131879251f5eSSepherosa Ziehau 	 *
131979251f5eSSepherosa Ziehau 	 *     Multiple these timings by 4 if under full Rx load
132079251f5eSSepherosa Ziehau 	 *
132179251f5eSSepherosa Ziehau 	 * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for
132279251f5eSSepherosa Ziehau 	 * 1 msec per poll time.  If we're at line rate and drop to 100M, then
132379251f5eSSepherosa Ziehau 	 * this might not finish in our poll time, but we can live with that
132479251f5eSSepherosa Ziehau 	 * for now.
132579251f5eSSepherosa Ziehau 	 */
132679251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
132779251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
132879251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
132979251f5eSSepherosa Ziehau 		if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
133079251f5eSSepherosa Ziehau 				   IXGBE_FDIRCTRL_INIT_DONE)
133179251f5eSSepherosa Ziehau 			break;
133279251f5eSSepherosa Ziehau 		msec_delay(1);
133379251f5eSSepherosa Ziehau 	}
133479251f5eSSepherosa Ziehau 
133579251f5eSSepherosa Ziehau 	if (i >= IXGBE_FDIR_INIT_DONE_POLL)
133679251f5eSSepherosa Ziehau 		DEBUGOUT("Flow Director poll time exceeded!\n");
133779251f5eSSepherosa Ziehau }
133879251f5eSSepherosa Ziehau 
133979251f5eSSepherosa Ziehau /**
134079251f5eSSepherosa Ziehau  *  ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters
134179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
134279251f5eSSepherosa Ziehau  *  @fdirctrl: value to write to flow director control register, initially
134379251f5eSSepherosa Ziehau  *	     contains just the value of the Rx packet buffer allocation
134479251f5eSSepherosa Ziehau  **/
ixgbe_init_fdir_signature_82599(struct ixgbe_hw * hw,u32 fdirctrl)134579251f5eSSepherosa Ziehau s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl)
134679251f5eSSepherosa Ziehau {
134779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_fdir_signature_82599");
134879251f5eSSepherosa Ziehau 
134979251f5eSSepherosa Ziehau 	/*
135079251f5eSSepherosa Ziehau 	 * Continue setup of fdirctrl register bits:
135179251f5eSSepherosa Ziehau 	 *  Move the flexible bytes to use the ethertype - shift 6 words
135279251f5eSSepherosa Ziehau 	 *  Set the maximum length per hash bucket to 0xA filters
135379251f5eSSepherosa Ziehau 	 *  Send interrupt when 64 filters are left
135479251f5eSSepherosa Ziehau 	 */
135579251f5eSSepherosa Ziehau 	fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) |
135679251f5eSSepherosa Ziehau 		    (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) |
135779251f5eSSepherosa Ziehau 		    (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT);
135879251f5eSSepherosa Ziehau 
135979251f5eSSepherosa Ziehau 	/* write hashes and fdirctrl register, poll for completion */
136079251f5eSSepherosa Ziehau 	ixgbe_fdir_enable_82599(hw, fdirctrl);
136179251f5eSSepherosa Ziehau 
136279251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
136379251f5eSSepherosa Ziehau }
136479251f5eSSepherosa Ziehau 
136579251f5eSSepherosa Ziehau /**
136679251f5eSSepherosa Ziehau  *  ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters
136779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
136879251f5eSSepherosa Ziehau  *  @fdirctrl: value to write to flow director control register, initially
136979251f5eSSepherosa Ziehau  *	     contains just the value of the Rx packet buffer allocation
137063d483cdSSepherosa Ziehau  *  @cloud_mode: TRUE - cloud mode, FALSE - other mode
137179251f5eSSepherosa Ziehau  **/
ixgbe_init_fdir_perfect_82599(struct ixgbe_hw * hw,u32 fdirctrl,bool cloud_mode)137263d483cdSSepherosa Ziehau s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl,
137363d483cdSSepherosa Ziehau 			bool cloud_mode)
137479251f5eSSepherosa Ziehau {
1375*dd5ce676SSepherosa Ziehau 	UNREFERENCED_1PARAMETER(cloud_mode);
137679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_fdir_perfect_82599");
137779251f5eSSepherosa Ziehau 
137879251f5eSSepherosa Ziehau 	/*
137979251f5eSSepherosa Ziehau 	 * Continue setup of fdirctrl register bits:
138079251f5eSSepherosa Ziehau 	 *  Turn perfect match filtering on
138179251f5eSSepherosa Ziehau 	 *  Report hash in RSS field of Rx wb descriptor
13826150453fSSepherosa Ziehau 	 *  Initialize the drop queue to queue 127
138379251f5eSSepherosa Ziehau 	 *  Move the flexible bytes to use the ethertype - shift 6 words
138479251f5eSSepherosa Ziehau 	 *  Set the maximum length per hash bucket to 0xA filters
138579251f5eSSepherosa Ziehau 	 *  Send interrupt when 64 (0x4 * 16) filters are left
138679251f5eSSepherosa Ziehau 	 */
138779251f5eSSepherosa Ziehau 	fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH |
138879251f5eSSepherosa Ziehau 		    IXGBE_FDIRCTRL_REPORT_STATUS |
138979251f5eSSepherosa Ziehau 		    (IXGBE_FDIR_DROP_QUEUE << IXGBE_FDIRCTRL_DROP_Q_SHIFT) |
139079251f5eSSepherosa Ziehau 		    (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) |
139179251f5eSSepherosa Ziehau 		    (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) |
139279251f5eSSepherosa Ziehau 		    (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT);
139379251f5eSSepherosa Ziehau 
139463d483cdSSepherosa Ziehau 	if (cloud_mode)
139563d483cdSSepherosa Ziehau 		fdirctrl |=(IXGBE_FDIRCTRL_FILTERMODE_CLOUD <<
139663d483cdSSepherosa Ziehau 					IXGBE_FDIRCTRL_FILTERMODE_SHIFT);
139763d483cdSSepherosa Ziehau 
139879251f5eSSepherosa Ziehau 	/* write hashes and fdirctrl register, poll for completion */
139979251f5eSSepherosa Ziehau 	ixgbe_fdir_enable_82599(hw, fdirctrl);
140079251f5eSSepherosa Ziehau 
140179251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
140279251f5eSSepherosa Ziehau }
140379251f5eSSepherosa Ziehau 
14046150453fSSepherosa Ziehau /**
14056150453fSSepherosa Ziehau  *  ixgbe_set_fdir_drop_queue_82599 - Set Flow Director drop queue
14066150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
14076150453fSSepherosa Ziehau  *  @dropqueue: Rx queue index used for the dropped packets
14086150453fSSepherosa Ziehau  **/
ixgbe_set_fdir_drop_queue_82599(struct ixgbe_hw * hw,u8 dropqueue)14096150453fSSepherosa Ziehau void ixgbe_set_fdir_drop_queue_82599(struct ixgbe_hw *hw, u8 dropqueue)
14106150453fSSepherosa Ziehau {
14116150453fSSepherosa Ziehau 	u32 fdirctrl;
14126150453fSSepherosa Ziehau 
14136150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_fdir_drop_queue_82599");
14146150453fSSepherosa Ziehau 	/* Clear init done bit and drop queue field */
14156150453fSSepherosa Ziehau 	fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
14166150453fSSepherosa Ziehau 	fdirctrl &= ~(IXGBE_FDIRCTRL_DROP_Q_MASK | IXGBE_FDIRCTRL_INIT_DONE);
14176150453fSSepherosa Ziehau 
14186150453fSSepherosa Ziehau 	/* Set drop queue */
14196150453fSSepherosa Ziehau 	fdirctrl |= (dropqueue << IXGBE_FDIRCTRL_DROP_Q_SHIFT);
14206150453fSSepherosa Ziehau 	if ((hw->mac.type == ixgbe_mac_X550) ||
14216150453fSSepherosa Ziehau 	    (hw->mac.type == ixgbe_mac_X550EM_x) ||
14226150453fSSepherosa Ziehau 	    (hw->mac.type == ixgbe_mac_X550EM_a))
14236150453fSSepherosa Ziehau 		fdirctrl |= IXGBE_FDIRCTRL_DROP_NO_MATCH;
14246150453fSSepherosa Ziehau 
14256150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
14266150453fSSepherosa Ziehau 			(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) |
14276150453fSSepherosa Ziehau 			 IXGBE_FDIRCMD_CLEARHT));
14286150453fSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
14296150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
14306150453fSSepherosa Ziehau 			(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
14316150453fSSepherosa Ziehau 			 ~IXGBE_FDIRCMD_CLEARHT));
14326150453fSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
14336150453fSSepherosa Ziehau 
14346150453fSSepherosa Ziehau 	/* write hashes and fdirctrl register, poll for completion */
14356150453fSSepherosa Ziehau 	ixgbe_fdir_enable_82599(hw, fdirctrl);
14366150453fSSepherosa Ziehau }
14376150453fSSepherosa Ziehau 
143879251f5eSSepherosa Ziehau /*
143979251f5eSSepherosa Ziehau  * These defines allow us to quickly generate all of the necessary instructions
144079251f5eSSepherosa Ziehau  * in the function below by simply calling out IXGBE_COMPUTE_SIG_HASH_ITERATION
144179251f5eSSepherosa Ziehau  * for values 0 through 15
144279251f5eSSepherosa Ziehau  */
144379251f5eSSepherosa Ziehau #define IXGBE_ATR_COMMON_HASH_KEY \
144479251f5eSSepherosa Ziehau 		(IXGBE_ATR_BUCKET_HASH_KEY & IXGBE_ATR_SIGNATURE_HASH_KEY)
144579251f5eSSepherosa Ziehau #define IXGBE_COMPUTE_SIG_HASH_ITERATION(_n) \
144679251f5eSSepherosa Ziehau do { \
144779251f5eSSepherosa Ziehau 	u32 n = (_n); \
144879251f5eSSepherosa Ziehau 	if (IXGBE_ATR_COMMON_HASH_KEY & (0x01 << n)) \
144979251f5eSSepherosa Ziehau 		common_hash ^= lo_hash_dword >> n; \
145079251f5eSSepherosa Ziehau 	else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) \
145179251f5eSSepherosa Ziehau 		bucket_hash ^= lo_hash_dword >> n; \
145279251f5eSSepherosa Ziehau 	else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << n)) \
145379251f5eSSepherosa Ziehau 		sig_hash ^= lo_hash_dword << (16 - n); \
145479251f5eSSepherosa Ziehau 	if (IXGBE_ATR_COMMON_HASH_KEY & (0x01 << (n + 16))) \
145579251f5eSSepherosa Ziehau 		common_hash ^= hi_hash_dword >> n; \
145679251f5eSSepherosa Ziehau 	else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \
145779251f5eSSepherosa Ziehau 		bucket_hash ^= hi_hash_dword >> n; \
145879251f5eSSepherosa Ziehau 	else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << (n + 16))) \
145979251f5eSSepherosa Ziehau 		sig_hash ^= hi_hash_dword << (16 - n); \
146063d483cdSSepherosa Ziehau } while (0)
146179251f5eSSepherosa Ziehau 
146279251f5eSSepherosa Ziehau /**
146379251f5eSSepherosa Ziehau  *  ixgbe_atr_compute_sig_hash_82599 - Compute the signature hash
1464*dd5ce676SSepherosa Ziehau  *  @input: input bitstream to compute the hash on
1465*dd5ce676SSepherosa Ziehau  *  @common: compressed common input dword
146679251f5eSSepherosa Ziehau  *
146779251f5eSSepherosa Ziehau  *  This function is almost identical to the function above but contains
146863d483cdSSepherosa Ziehau  *  several optimizations such as unwinding all of the loops, letting the
146979251f5eSSepherosa Ziehau  *  compiler work out all of the conditional ifs since the keys are static
147079251f5eSSepherosa Ziehau  *  defines, and computing two keys at once since the hashed dword stream
147179251f5eSSepherosa Ziehau  *  will be the same for both keys.
147279251f5eSSepherosa Ziehau  **/
ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,union ixgbe_atr_hash_dword common)147379251f5eSSepherosa Ziehau u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,
147479251f5eSSepherosa Ziehau 				     union ixgbe_atr_hash_dword common)
147579251f5eSSepherosa Ziehau {
147679251f5eSSepherosa Ziehau 	u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan;
147779251f5eSSepherosa Ziehau 	u32 sig_hash = 0, bucket_hash = 0, common_hash = 0;
147879251f5eSSepherosa Ziehau 
147979251f5eSSepherosa Ziehau 	/* record the flow_vm_vlan bits as they are a key part to the hash */
148079251f5eSSepherosa Ziehau 	flow_vm_vlan = IXGBE_NTOHL(input.dword);
148179251f5eSSepherosa Ziehau 
148279251f5eSSepherosa Ziehau 	/* generate common hash dword */
148379251f5eSSepherosa Ziehau 	hi_hash_dword = IXGBE_NTOHL(common.dword);
148479251f5eSSepherosa Ziehau 
148579251f5eSSepherosa Ziehau 	/* low dword is word swapped version of common */
148679251f5eSSepherosa Ziehau 	lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16);
148779251f5eSSepherosa Ziehau 
148879251f5eSSepherosa Ziehau 	/* apply flow ID/VM pool/VLAN ID bits to hash words */
148979251f5eSSepherosa Ziehau 	hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16);
149079251f5eSSepherosa Ziehau 
149179251f5eSSepherosa Ziehau 	/* Process bits 0 and 16 */
149279251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(0);
149379251f5eSSepherosa Ziehau 
149479251f5eSSepherosa Ziehau 	/*
149579251f5eSSepherosa Ziehau 	 * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to
149679251f5eSSepherosa Ziehau 	 * delay this because bit 0 of the stream should not be processed
149763d483cdSSepherosa Ziehau 	 * so we do not add the VLAN until after bit 0 was processed
149879251f5eSSepherosa Ziehau 	 */
149979251f5eSSepherosa Ziehau 	lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16);
150079251f5eSSepherosa Ziehau 
150179251f5eSSepherosa Ziehau 	/* Process remaining 30 bit of the key */
150279251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(1);
150379251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(2);
150479251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(3);
150579251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(4);
150679251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(5);
150779251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(6);
150879251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(7);
150979251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(8);
151079251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(9);
151179251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(10);
151279251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(11);
151379251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(12);
151479251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(13);
151579251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(14);
151679251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_SIG_HASH_ITERATION(15);
151779251f5eSSepherosa Ziehau 
151879251f5eSSepherosa Ziehau 	/* combine common_hash result with signature and bucket hashes */
151979251f5eSSepherosa Ziehau 	bucket_hash ^= common_hash;
152079251f5eSSepherosa Ziehau 	bucket_hash &= IXGBE_ATR_HASH_MASK;
152179251f5eSSepherosa Ziehau 
152279251f5eSSepherosa Ziehau 	sig_hash ^= common_hash << 16;
152379251f5eSSepherosa Ziehau 	sig_hash &= IXGBE_ATR_HASH_MASK << 16;
152479251f5eSSepherosa Ziehau 
152579251f5eSSepherosa Ziehau 	/* return completed signature hash */
152679251f5eSSepherosa Ziehau 	return sig_hash ^ bucket_hash;
152779251f5eSSepherosa Ziehau }
152879251f5eSSepherosa Ziehau 
152979251f5eSSepherosa Ziehau /**
153079251f5eSSepherosa Ziehau  *  ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter
153179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
153279251f5eSSepherosa Ziehau  *  @input: unique input dword
153379251f5eSSepherosa Ziehau  *  @common: compressed common input dword
153479251f5eSSepherosa Ziehau  *  @queue: queue index to direct traffic to
153563d483cdSSepherosa Ziehau  *
153663d483cdSSepherosa Ziehau  * Note that the tunnel bit in input must not be set when the hardware
153763d483cdSSepherosa Ziehau  * tunneling support does not exist.
153879251f5eSSepherosa Ziehau  **/
ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw * hw,union ixgbe_atr_hash_dword input,union ixgbe_atr_hash_dword common,u8 queue)15396150453fSSepherosa Ziehau void ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
154079251f5eSSepherosa Ziehau 					   union ixgbe_atr_hash_dword input,
154179251f5eSSepherosa Ziehau 					   union ixgbe_atr_hash_dword common,
154279251f5eSSepherosa Ziehau 					   u8 queue)
154379251f5eSSepherosa Ziehau {
154479251f5eSSepherosa Ziehau 	u64 fdirhashcmd;
154563d483cdSSepherosa Ziehau 	u8 flow_type;
154663d483cdSSepherosa Ziehau 	bool tunnel;
154779251f5eSSepherosa Ziehau 	u32 fdircmd;
154879251f5eSSepherosa Ziehau 
154979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_fdir_add_signature_filter_82599");
155079251f5eSSepherosa Ziehau 
155179251f5eSSepherosa Ziehau 	/*
155279251f5eSSepherosa Ziehau 	 * Get the flow_type in order to program FDIRCMD properly
155379251f5eSSepherosa Ziehau 	 * lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6
155463d483cdSSepherosa Ziehau 	 * fifth is FDIRCMD.TUNNEL_FILTER
155579251f5eSSepherosa Ziehau 	 */
155663d483cdSSepherosa Ziehau 	tunnel = !!(input.formatted.flow_type & IXGBE_ATR_L4TYPE_TUNNEL_MASK);
155763d483cdSSepherosa Ziehau 	flow_type = input.formatted.flow_type &
155863d483cdSSepherosa Ziehau 		    (IXGBE_ATR_L4TYPE_TUNNEL_MASK - 1);
155963d483cdSSepherosa Ziehau 	switch (flow_type) {
156079251f5eSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_TCPV4:
156179251f5eSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_UDPV4:
156279251f5eSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_SCTPV4:
156379251f5eSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_TCPV6:
156479251f5eSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_UDPV6:
156579251f5eSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_SCTPV6:
156679251f5eSSepherosa Ziehau 		break;
156779251f5eSSepherosa Ziehau 	default:
156879251f5eSSepherosa Ziehau 		DEBUGOUT(" Error on flow type input\n");
15696150453fSSepherosa Ziehau 		return;
157079251f5eSSepherosa Ziehau 	}
157179251f5eSSepherosa Ziehau 
157279251f5eSSepherosa Ziehau 	/* configure FDIRCMD register */
157379251f5eSSepherosa Ziehau 	fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
157479251f5eSSepherosa Ziehau 		  IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN;
157563d483cdSSepherosa Ziehau 	fdircmd |= (u32)flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
157679251f5eSSepherosa Ziehau 	fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
157763d483cdSSepherosa Ziehau 	if (tunnel)
157863d483cdSSepherosa Ziehau 		fdircmd |= IXGBE_FDIRCMD_TUNNEL_FILTER;
157979251f5eSSepherosa Ziehau 
158079251f5eSSepherosa Ziehau 	/*
158179251f5eSSepherosa Ziehau 	 * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits
158279251f5eSSepherosa Ziehau 	 * is for FDIRCMD.  Then do a 64-bit register write from FDIRHASH.
158379251f5eSSepherosa Ziehau 	 */
158479251f5eSSepherosa Ziehau 	fdirhashcmd = (u64)fdircmd << 32;
158579251f5eSSepherosa Ziehau 	fdirhashcmd |= ixgbe_atr_compute_sig_hash_82599(input, common);
158679251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd);
158779251f5eSSepherosa Ziehau 
158879251f5eSSepherosa Ziehau 	DEBUGOUT2("Tx Queue=%x hash=%x\n", queue, (u32)fdirhashcmd);
158979251f5eSSepherosa Ziehau 
15906150453fSSepherosa Ziehau 	return;
159179251f5eSSepherosa Ziehau }
159279251f5eSSepherosa Ziehau 
159379251f5eSSepherosa Ziehau #define IXGBE_COMPUTE_BKT_HASH_ITERATION(_n) \
159479251f5eSSepherosa Ziehau do { \
159579251f5eSSepherosa Ziehau 	u32 n = (_n); \
159679251f5eSSepherosa Ziehau 	if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) \
159779251f5eSSepherosa Ziehau 		bucket_hash ^= lo_hash_dword >> n; \
159879251f5eSSepherosa Ziehau 	if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \
159979251f5eSSepherosa Ziehau 		bucket_hash ^= hi_hash_dword >> n; \
160063d483cdSSepherosa Ziehau } while (0)
160179251f5eSSepherosa Ziehau 
160279251f5eSSepherosa Ziehau /**
160379251f5eSSepherosa Ziehau  *  ixgbe_atr_compute_perfect_hash_82599 - Compute the perfect filter hash
1604*dd5ce676SSepherosa Ziehau  *  @input: input bitstream to compute the hash on
160579251f5eSSepherosa Ziehau  *  @input_mask: mask for the input bitstream
160679251f5eSSepherosa Ziehau  *
160763d483cdSSepherosa Ziehau  *  This function serves two main purposes.  First it applies the input_mask
160879251f5eSSepherosa Ziehau  *  to the atr_input resulting in a cleaned up atr_input data stream.
160979251f5eSSepherosa Ziehau  *  Secondly it computes the hash and stores it in the bkt_hash field at
161079251f5eSSepherosa Ziehau  *  the end of the input byte stream.  This way it will be available for
161179251f5eSSepherosa Ziehau  *  future use without needing to recompute the hash.
161279251f5eSSepherosa Ziehau  **/
ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input * input,union ixgbe_atr_input * input_mask)161379251f5eSSepherosa Ziehau void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
161479251f5eSSepherosa Ziehau 					  union ixgbe_atr_input *input_mask)
161579251f5eSSepherosa Ziehau {
161679251f5eSSepherosa Ziehau 
161779251f5eSSepherosa Ziehau 	u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan;
161879251f5eSSepherosa Ziehau 	u32 bucket_hash = 0;
161963d483cdSSepherosa Ziehau 	u32 hi_dword = 0;
162063d483cdSSepherosa Ziehau 	u32 i = 0;
162179251f5eSSepherosa Ziehau 
162279251f5eSSepherosa Ziehau 	/* Apply masks to input data */
162363d483cdSSepherosa Ziehau 	for (i = 0; i < 14; i++)
162463d483cdSSepherosa Ziehau 		input->dword_stream[i]  &= input_mask->dword_stream[i];
162579251f5eSSepherosa Ziehau 
162679251f5eSSepherosa Ziehau 	/* record the flow_vm_vlan bits as they are a key part to the hash */
162779251f5eSSepherosa Ziehau 	flow_vm_vlan = IXGBE_NTOHL(input->dword_stream[0]);
162879251f5eSSepherosa Ziehau 
162979251f5eSSepherosa Ziehau 	/* generate common hash dword */
163063d483cdSSepherosa Ziehau 	for (i = 1; i <= 13; i++)
163163d483cdSSepherosa Ziehau 		hi_dword ^= input->dword_stream[i];
163263d483cdSSepherosa Ziehau 	hi_hash_dword = IXGBE_NTOHL(hi_dword);
163379251f5eSSepherosa Ziehau 
163479251f5eSSepherosa Ziehau 	/* low dword is word swapped version of common */
163579251f5eSSepherosa Ziehau 	lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16);
163679251f5eSSepherosa Ziehau 
163779251f5eSSepherosa Ziehau 	/* apply flow ID/VM pool/VLAN ID bits to hash words */
163879251f5eSSepherosa Ziehau 	hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16);
163979251f5eSSepherosa Ziehau 
164079251f5eSSepherosa Ziehau 	/* Process bits 0 and 16 */
164179251f5eSSepherosa Ziehau 	IXGBE_COMPUTE_BKT_HASH_ITERATION(0);
164279251f5eSSepherosa Ziehau 
164379251f5eSSepherosa Ziehau 	/*
164479251f5eSSepherosa Ziehau 	 * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to
164579251f5eSSepherosa Ziehau 	 * delay this because bit 0 of the stream should not be processed
164663d483cdSSepherosa Ziehau 	 * so we do not add the VLAN until after bit 0 was processed
164779251f5eSSepherosa Ziehau 	 */
164879251f5eSSepherosa Ziehau 	lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16);
164979251f5eSSepherosa Ziehau 
165079251f5eSSepherosa Ziehau 	/* Process remaining 30 bit of the key */
165163d483cdSSepherosa Ziehau 	for (i = 1; i <= 15; i++)
165263d483cdSSepherosa Ziehau 		IXGBE_COMPUTE_BKT_HASH_ITERATION(i);
165379251f5eSSepherosa Ziehau 
165479251f5eSSepherosa Ziehau 	/*
165579251f5eSSepherosa Ziehau 	 * Limit hash to 13 bits since max bucket count is 8K.
165679251f5eSSepherosa Ziehau 	 * Store result at the end of the input stream.
165779251f5eSSepherosa Ziehau 	 */
165879251f5eSSepherosa Ziehau 	input->formatted.bkt_hash = bucket_hash & 0x1FFF;
165979251f5eSSepherosa Ziehau }
166079251f5eSSepherosa Ziehau 
166179251f5eSSepherosa Ziehau /**
166263d483cdSSepherosa Ziehau  *  ixgbe_get_fdirtcpm_82599 - generate a TCP port from atr_input_masks
166379251f5eSSepherosa Ziehau  *  @input_mask: mask to be bit swapped
166479251f5eSSepherosa Ziehau  *
166579251f5eSSepherosa Ziehau  *  The source and destination port masks for flow director are bit swapped
166679251f5eSSepherosa Ziehau  *  in that bit 15 effects bit 0, 14 effects 1, 13, 2 etc.  In order to
166779251f5eSSepherosa Ziehau  *  generate a correctly swapped value we need to bit swap the mask and that
166879251f5eSSepherosa Ziehau  *  is what is accomplished by this function.
166979251f5eSSepherosa Ziehau  **/
ixgbe_get_fdirtcpm_82599(union ixgbe_atr_input * input_mask)167079251f5eSSepherosa Ziehau static u32 ixgbe_get_fdirtcpm_82599(union ixgbe_atr_input *input_mask)
167179251f5eSSepherosa Ziehau {
167279251f5eSSepherosa Ziehau 	u32 mask = IXGBE_NTOHS(input_mask->formatted.dst_port);
167379251f5eSSepherosa Ziehau 	mask <<= IXGBE_FDIRTCPM_DPORTM_SHIFT;
167479251f5eSSepherosa Ziehau 	mask |= IXGBE_NTOHS(input_mask->formatted.src_port);
167579251f5eSSepherosa Ziehau 	mask = ((mask & 0x55555555) << 1) | ((mask & 0xAAAAAAAA) >> 1);
167679251f5eSSepherosa Ziehau 	mask = ((mask & 0x33333333) << 2) | ((mask & 0xCCCCCCCC) >> 2);
167779251f5eSSepherosa Ziehau 	mask = ((mask & 0x0F0F0F0F) << 4) | ((mask & 0xF0F0F0F0) >> 4);
167879251f5eSSepherosa Ziehau 	return ((mask & 0x00FF00FF) << 8) | ((mask & 0xFF00FF00) >> 8);
167979251f5eSSepherosa Ziehau }
168079251f5eSSepherosa Ziehau 
168179251f5eSSepherosa Ziehau /*
168279251f5eSSepherosa Ziehau  * These two macros are meant to address the fact that we have registers
168379251f5eSSepherosa Ziehau  * that are either all or in part big-endian.  As a result on big-endian
168479251f5eSSepherosa Ziehau  * systems we will end up byte swapping the value to little-endian before
168579251f5eSSepherosa Ziehau  * it is byte swapped again and written to the hardware in the original
168679251f5eSSepherosa Ziehau  * big-endian format.
168779251f5eSSepherosa Ziehau  */
168879251f5eSSepherosa Ziehau #define IXGBE_STORE_AS_BE32(_value) \
168979251f5eSSepherosa Ziehau 	(((u32)(_value) >> 24) | (((u32)(_value) & 0x00FF0000) >> 8) | \
169079251f5eSSepherosa Ziehau 	 (((u32)(_value) & 0x0000FF00) << 8) | ((u32)(_value) << 24))
169179251f5eSSepherosa Ziehau 
169279251f5eSSepherosa Ziehau #define IXGBE_WRITE_REG_BE32(a, reg, value) \
169379251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG((a), (reg), IXGBE_STORE_AS_BE32(IXGBE_NTOHL(value)))
169479251f5eSSepherosa Ziehau 
169579251f5eSSepherosa Ziehau #define IXGBE_STORE_AS_BE16(_value) \
169679251f5eSSepherosa Ziehau 	IXGBE_NTOHS(((u16)(_value) >> 8) | ((u16)(_value) << 8))
169779251f5eSSepherosa Ziehau 
ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw * hw,union ixgbe_atr_input * input_mask,bool cloud_mode)169879251f5eSSepherosa Ziehau s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
169963d483cdSSepherosa Ziehau 				    union ixgbe_atr_input *input_mask, bool cloud_mode)
170079251f5eSSepherosa Ziehau {
170179251f5eSSepherosa Ziehau 	/* mask IPv6 since it is currently not supported */
170279251f5eSSepherosa Ziehau 	u32 fdirm = IXGBE_FDIRM_DIPv6;
170379251f5eSSepherosa Ziehau 	u32 fdirtcpm;
170463d483cdSSepherosa Ziehau 	u32 fdirip6m;
1705*dd5ce676SSepherosa Ziehau 	UNREFERENCED_1PARAMETER(cloud_mode);
170679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_fdir_set_atr_input_mask_82599");
170779251f5eSSepherosa Ziehau 
170879251f5eSSepherosa Ziehau 	/*
170979251f5eSSepherosa Ziehau 	 * Program the relevant mask registers.  If src/dst_port or src/dst_addr
171079251f5eSSepherosa Ziehau 	 * are zero, then assume a full mask for that field.  Also assume that
171179251f5eSSepherosa Ziehau 	 * a VLAN of 0 is unspecified, so mask that out as well.  L4type
171279251f5eSSepherosa Ziehau 	 * cannot be masked out in this implementation.
171379251f5eSSepherosa Ziehau 	 *
171479251f5eSSepherosa Ziehau 	 * This also assumes IPv4 only.  IPv6 masking isn't supported at this
171579251f5eSSepherosa Ziehau 	 * point in time.
171679251f5eSSepherosa Ziehau 	 */
171779251f5eSSepherosa Ziehau 
171879251f5eSSepherosa Ziehau 	/* verify bucket hash is cleared on hash generation */
171979251f5eSSepherosa Ziehau 	if (input_mask->formatted.bkt_hash)
172079251f5eSSepherosa Ziehau 		DEBUGOUT(" bucket hash should always be 0 in mask\n");
172179251f5eSSepherosa Ziehau 
172279251f5eSSepherosa Ziehau 	/* Program FDIRM and verify partial masks */
172379251f5eSSepherosa Ziehau 	switch (input_mask->formatted.vm_pool & 0x7F) {
172479251f5eSSepherosa Ziehau 	case 0x0:
172579251f5eSSepherosa Ziehau 		fdirm |= IXGBE_FDIRM_POOL;
172679251f5eSSepherosa Ziehau 	case 0x7F:
172779251f5eSSepherosa Ziehau 		break;
172879251f5eSSepherosa Ziehau 	default:
172979251f5eSSepherosa Ziehau 		DEBUGOUT(" Error on vm pool mask\n");
173079251f5eSSepherosa Ziehau 		return IXGBE_ERR_CONFIG;
173179251f5eSSepherosa Ziehau 	}
173279251f5eSSepherosa Ziehau 
173379251f5eSSepherosa Ziehau 	switch (input_mask->formatted.flow_type & IXGBE_ATR_L4TYPE_MASK) {
173479251f5eSSepherosa Ziehau 	case 0x0:
173579251f5eSSepherosa Ziehau 		fdirm |= IXGBE_FDIRM_L4P;
173679251f5eSSepherosa Ziehau 		if (input_mask->formatted.dst_port ||
173779251f5eSSepherosa Ziehau 		    input_mask->formatted.src_port) {
173879251f5eSSepherosa Ziehau 			DEBUGOUT(" Error on src/dst port mask\n");
173979251f5eSSepherosa Ziehau 			return IXGBE_ERR_CONFIG;
174079251f5eSSepherosa Ziehau 		}
174179251f5eSSepherosa Ziehau 	case IXGBE_ATR_L4TYPE_MASK:
174279251f5eSSepherosa Ziehau 		break;
174379251f5eSSepherosa Ziehau 	default:
174479251f5eSSepherosa Ziehau 		DEBUGOUT(" Error on flow type mask\n");
174579251f5eSSepherosa Ziehau 		return IXGBE_ERR_CONFIG;
174679251f5eSSepherosa Ziehau 	}
174779251f5eSSepherosa Ziehau 
174879251f5eSSepherosa Ziehau 	switch (IXGBE_NTOHS(input_mask->formatted.vlan_id) & 0xEFFF) {
174979251f5eSSepherosa Ziehau 	case 0x0000:
17506150453fSSepherosa Ziehau 		/* mask VLAN ID */
175179251f5eSSepherosa Ziehau 		fdirm |= IXGBE_FDIRM_VLANID;
17526150453fSSepherosa Ziehau 		/* fall through */
175379251f5eSSepherosa Ziehau 	case 0x0FFF:
175479251f5eSSepherosa Ziehau 		/* mask VLAN priority */
175579251f5eSSepherosa Ziehau 		fdirm |= IXGBE_FDIRM_VLANP;
175679251f5eSSepherosa Ziehau 		break;
175779251f5eSSepherosa Ziehau 	case 0xE000:
17586150453fSSepherosa Ziehau 		/* mask VLAN ID only */
175979251f5eSSepherosa Ziehau 		fdirm |= IXGBE_FDIRM_VLANID;
17606150453fSSepherosa Ziehau 		/* fall through */
176179251f5eSSepherosa Ziehau 	case 0xEFFF:
176279251f5eSSepherosa Ziehau 		/* no VLAN fields masked */
176379251f5eSSepherosa Ziehau 		break;
176479251f5eSSepherosa Ziehau 	default:
176579251f5eSSepherosa Ziehau 		DEBUGOUT(" Error on VLAN mask\n");
176679251f5eSSepherosa Ziehau 		return IXGBE_ERR_CONFIG;
176779251f5eSSepherosa Ziehau 	}
176879251f5eSSepherosa Ziehau 
176979251f5eSSepherosa Ziehau 	switch (input_mask->formatted.flex_bytes & 0xFFFF) {
177079251f5eSSepherosa Ziehau 	case 0x0000:
17716150453fSSepherosa Ziehau 		/* Mask Flex Bytes */
177279251f5eSSepherosa Ziehau 		fdirm |= IXGBE_FDIRM_FLEX;
17736150453fSSepherosa Ziehau 		/* fall through */
177479251f5eSSepherosa Ziehau 	case 0xFFFF:
177579251f5eSSepherosa Ziehau 		break;
177679251f5eSSepherosa Ziehau 	default:
177779251f5eSSepherosa Ziehau 		DEBUGOUT(" Error on flexible byte mask\n");
177879251f5eSSepherosa Ziehau 		return IXGBE_ERR_CONFIG;
177979251f5eSSepherosa Ziehau 	}
178079251f5eSSepherosa Ziehau 
178163d483cdSSepherosa Ziehau 	if (cloud_mode) {
178263d483cdSSepherosa Ziehau 		fdirm |= IXGBE_FDIRM_L3P;
178363d483cdSSepherosa Ziehau 		fdirip6m = ((u32) 0xFFFFU << IXGBE_FDIRIP6M_DIPM_SHIFT);
178463d483cdSSepherosa Ziehau 		fdirip6m |= IXGBE_FDIRIP6M_ALWAYS_MASK;
178563d483cdSSepherosa Ziehau 
178663d483cdSSepherosa Ziehau 		switch (input_mask->formatted.inner_mac[0] & 0xFF) {
178763d483cdSSepherosa Ziehau 		case 0x00:
178863d483cdSSepherosa Ziehau 			/* Mask inner MAC, fall through */
178963d483cdSSepherosa Ziehau 			fdirip6m |= IXGBE_FDIRIP6M_INNER_MAC;
179063d483cdSSepherosa Ziehau 		case 0xFF:
179163d483cdSSepherosa Ziehau 			break;
179263d483cdSSepherosa Ziehau 		default:
179363d483cdSSepherosa Ziehau 			DEBUGOUT(" Error on inner_mac byte mask\n");
179463d483cdSSepherosa Ziehau 			return IXGBE_ERR_CONFIG;
179563d483cdSSepherosa Ziehau 		}
179663d483cdSSepherosa Ziehau 
179763d483cdSSepherosa Ziehau 		switch (input_mask->formatted.tni_vni & 0xFFFFFFFF) {
179863d483cdSSepherosa Ziehau 		case 0x0:
179963d483cdSSepherosa Ziehau 			/* Mask vxlan id */
180063d483cdSSepherosa Ziehau 			fdirip6m |= IXGBE_FDIRIP6M_TNI_VNI;
180163d483cdSSepherosa Ziehau 			break;
180263d483cdSSepherosa Ziehau 		case 0x00FFFFFF:
180363d483cdSSepherosa Ziehau 			fdirip6m |= IXGBE_FDIRIP6M_TNI_VNI_24;
180463d483cdSSepherosa Ziehau 			break;
180563d483cdSSepherosa Ziehau 		case 0xFFFFFFFF:
180663d483cdSSepherosa Ziehau 			break;
180763d483cdSSepherosa Ziehau 		default:
180863d483cdSSepherosa Ziehau 			DEBUGOUT(" Error on TNI/VNI byte mask\n");
180963d483cdSSepherosa Ziehau 			return IXGBE_ERR_CONFIG;
181063d483cdSSepherosa Ziehau 		}
181163d483cdSSepherosa Ziehau 
181263d483cdSSepherosa Ziehau 		switch (input_mask->formatted.tunnel_type & 0xFFFF) {
181363d483cdSSepherosa Ziehau 		case 0x0:
181463d483cdSSepherosa Ziehau 			/* Mask turnnel type, fall through */
181563d483cdSSepherosa Ziehau 			fdirip6m |= IXGBE_FDIRIP6M_TUNNEL_TYPE;
181663d483cdSSepherosa Ziehau 		case 0xFFFF:
181763d483cdSSepherosa Ziehau 			break;
181863d483cdSSepherosa Ziehau 		default:
181963d483cdSSepherosa Ziehau 			DEBUGOUT(" Error on tunnel type byte mask\n");
182063d483cdSSepherosa Ziehau 			return IXGBE_ERR_CONFIG;
182163d483cdSSepherosa Ziehau 		}
182263d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIP6M, fdirip6m);
182363d483cdSSepherosa Ziehau 
18246150453fSSepherosa Ziehau 		/* Set all bits in FDIRTCPM, FDIRUDPM, FDIRSCTPM,
18256150453fSSepherosa Ziehau 		 * FDIRSIP4M and FDIRDIP4M in cloud mode to allow
18266150453fSSepherosa Ziehau 		 * L3/L3 packets to tunnel.
182763d483cdSSepherosa Ziehau 		 */
182863d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xFFFFFFFF);
182963d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xFFFFFFFF);
183063d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M, 0xFFFFFFFF);
183163d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M, 0xFFFFFFFF);
18326150453fSSepherosa Ziehau 		switch (hw->mac.type) {
18336150453fSSepherosa Ziehau 		case ixgbe_mac_X550:
18346150453fSSepherosa Ziehau 		case ixgbe_mac_X550EM_x:
18356150453fSSepherosa Ziehau 		case ixgbe_mac_X550EM_a:
18366150453fSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, 0xFFFFFFFF);
18376150453fSSepherosa Ziehau 			break;
18386150453fSSepherosa Ziehau 		default:
18396150453fSSepherosa Ziehau 			break;
18406150453fSSepherosa Ziehau 		}
184163d483cdSSepherosa Ziehau 	}
184263d483cdSSepherosa Ziehau 
184379251f5eSSepherosa Ziehau 	/* Now mask VM pool and destination IPv6 - bits 5 and 2 */
184479251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm);
184579251f5eSSepherosa Ziehau 
184663d483cdSSepherosa Ziehau 	if (!cloud_mode) {
184763d483cdSSepherosa Ziehau 		/* store the TCP/UDP port masks, bit reversed from port
184863d483cdSSepherosa Ziehau 		 * layout */
184979251f5eSSepherosa Ziehau 		fdirtcpm = ixgbe_get_fdirtcpm_82599(input_mask);
185079251f5eSSepherosa Ziehau 
185179251f5eSSepherosa Ziehau 		/* write both the same so that UDP and TCP use the same mask */
185279251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm);
185379251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, ~fdirtcpm);
185463d483cdSSepherosa Ziehau 		/* also use it for SCTP */
185563d483cdSSepherosa Ziehau 		switch (hw->mac.type) {
185663d483cdSSepherosa Ziehau 		case ixgbe_mac_X550:
185763d483cdSSepherosa Ziehau 		case ixgbe_mac_X550EM_x:
185863d483cdSSepherosa Ziehau 		case ixgbe_mac_X550EM_a:
185963d483cdSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, ~fdirtcpm);
186063d483cdSSepherosa Ziehau 			break;
186163d483cdSSepherosa Ziehau 		default:
186263d483cdSSepherosa Ziehau 			break;
186363d483cdSSepherosa Ziehau 		}
186479251f5eSSepherosa Ziehau 
186579251f5eSSepherosa Ziehau 		/* store source and destination IP masks (big-enian) */
186679251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M,
186779251f5eSSepherosa Ziehau 				     ~input_mask->formatted.src_ip[0]);
186879251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M,
186979251f5eSSepherosa Ziehau 				     ~input_mask->formatted.dst_ip[0]);
187063d483cdSSepherosa Ziehau 	}
187179251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
187279251f5eSSepherosa Ziehau }
187379251f5eSSepherosa Ziehau 
ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw * hw,union ixgbe_atr_input * input,u16 soft_id,u8 queue,bool cloud_mode)187479251f5eSSepherosa Ziehau s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
187579251f5eSSepherosa Ziehau 					  union ixgbe_atr_input *input,
187663d483cdSSepherosa Ziehau 					  u16 soft_id, u8 queue, bool cloud_mode)
187779251f5eSSepherosa Ziehau {
187879251f5eSSepherosa Ziehau 	u32 fdirport, fdirvlan, fdirhash, fdircmd;
187963d483cdSSepherosa Ziehau 	u32 addr_low, addr_high;
188063d483cdSSepherosa Ziehau 	u32 cloud_type = 0;
188163d483cdSSepherosa Ziehau 	s32 err;
1882*dd5ce676SSepherosa Ziehau 	UNREFERENCED_1PARAMETER(cloud_mode);
188379251f5eSSepherosa Ziehau 
188479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_fdir_write_perfect_filter_82599");
188563d483cdSSepherosa Ziehau 	if (!cloud_mode) {
188679251f5eSSepherosa Ziehau 		/* currently IPv6 is not supported, must be programmed with 0 */
188779251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(0),
188879251f5eSSepherosa Ziehau 				     input->formatted.src_ip[0]);
188979251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(1),
189079251f5eSSepherosa Ziehau 				     input->formatted.src_ip[1]);
189179251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(2),
189279251f5eSSepherosa Ziehau 				     input->formatted.src_ip[2]);
189379251f5eSSepherosa Ziehau 
189479251f5eSSepherosa Ziehau 		/* record the source address (big-endian) */
189563d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPSA,
189663d483cdSSepherosa Ziehau 			input->formatted.src_ip[0]);
189779251f5eSSepherosa Ziehau 
189863d483cdSSepherosa Ziehau 		/* record the first 32 bits of the destination address
189963d483cdSSepherosa Ziehau 		 * (big-endian) */
190063d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPDA,
190163d483cdSSepherosa Ziehau 			input->formatted.dst_ip[0]);
190279251f5eSSepherosa Ziehau 
190379251f5eSSepherosa Ziehau 		/* record source and destination port (little-endian)*/
190479251f5eSSepherosa Ziehau 		fdirport = IXGBE_NTOHS(input->formatted.dst_port);
190579251f5eSSepherosa Ziehau 		fdirport <<= IXGBE_FDIRPORT_DESTINATION_SHIFT;
190679251f5eSSepherosa Ziehau 		fdirport |= IXGBE_NTOHS(input->formatted.src_port);
190779251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, fdirport);
190863d483cdSSepherosa Ziehau 	}
190979251f5eSSepherosa Ziehau 
191063d483cdSSepherosa Ziehau 	/* record VLAN (little-endian) and flex_bytes(big-endian) */
191179251f5eSSepherosa Ziehau 	fdirvlan = IXGBE_STORE_AS_BE16(input->formatted.flex_bytes);
191279251f5eSSepherosa Ziehau 	fdirvlan <<= IXGBE_FDIRVLAN_FLEX_SHIFT;
191379251f5eSSepherosa Ziehau 	fdirvlan |= IXGBE_NTOHS(input->formatted.vlan_id);
191479251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, fdirvlan);
191579251f5eSSepherosa Ziehau 
191663d483cdSSepherosa Ziehau 	if (cloud_mode) {
191763d483cdSSepherosa Ziehau 		if (input->formatted.tunnel_type != 0)
191863d483cdSSepherosa Ziehau 			cloud_type = 0x80000000;
191963d483cdSSepherosa Ziehau 
192063d483cdSSepherosa Ziehau 		addr_low = ((u32)input->formatted.inner_mac[0] |
192163d483cdSSepherosa Ziehau 				((u32)input->formatted.inner_mac[1] << 8) |
192263d483cdSSepherosa Ziehau 				((u32)input->formatted.inner_mac[2] << 16) |
192363d483cdSSepherosa Ziehau 				((u32)input->formatted.inner_mac[3] << 24));
192463d483cdSSepherosa Ziehau 		addr_high = ((u32)input->formatted.inner_mac[4] |
192563d483cdSSepherosa Ziehau 				((u32)input->formatted.inner_mac[5] << 8));
192663d483cdSSepherosa Ziehau 		cloud_type |= addr_high;
192763d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(0), addr_low);
192863d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(1), cloud_type);
192963d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(2), input->formatted.tni_vni);
193063d483cdSSepherosa Ziehau 	}
193163d483cdSSepherosa Ziehau 
193279251f5eSSepherosa Ziehau 	/* configure FDIRHASH register */
193379251f5eSSepherosa Ziehau 	fdirhash = input->formatted.bkt_hash;
193479251f5eSSepherosa Ziehau 	fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT;
193579251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
193679251f5eSSepherosa Ziehau 
193779251f5eSSepherosa Ziehau 	/*
193879251f5eSSepherosa Ziehau 	 * flush all previous writes to make certain registers are
193979251f5eSSepherosa Ziehau 	 * programmed prior to issuing the command
194079251f5eSSepherosa Ziehau 	 */
194179251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
194279251f5eSSepherosa Ziehau 
194379251f5eSSepherosa Ziehau 	/* configure FDIRCMD register */
194479251f5eSSepherosa Ziehau 	fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
194579251f5eSSepherosa Ziehau 		  IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN;
194679251f5eSSepherosa Ziehau 	if (queue == IXGBE_FDIR_DROP_QUEUE)
194779251f5eSSepherosa Ziehau 		fdircmd |= IXGBE_FDIRCMD_DROP;
194863d483cdSSepherosa Ziehau 	if (input->formatted.flow_type & IXGBE_ATR_L4TYPE_TUNNEL_MASK)
194963d483cdSSepherosa Ziehau 		fdircmd |= IXGBE_FDIRCMD_TUNNEL_FILTER;
195079251f5eSSepherosa Ziehau 	fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
195179251f5eSSepherosa Ziehau 	fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
195279251f5eSSepherosa Ziehau 	fdircmd |= (u32)input->formatted.vm_pool << IXGBE_FDIRCMD_VT_POOL_SHIFT;
195379251f5eSSepherosa Ziehau 
195479251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd);
195563d483cdSSepherosa Ziehau 	err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd);
195663d483cdSSepherosa Ziehau 	if (err) {
195763d483cdSSepherosa Ziehau 		DEBUGOUT("Flow Director command did not complete!\n");
195863d483cdSSepherosa Ziehau 		return err;
195963d483cdSSepherosa Ziehau 	}
196079251f5eSSepherosa Ziehau 
196179251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
196279251f5eSSepherosa Ziehau }
196379251f5eSSepherosa Ziehau 
ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw * hw,union ixgbe_atr_input * input,u16 soft_id)196479251f5eSSepherosa Ziehau s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
196579251f5eSSepherosa Ziehau 					  union ixgbe_atr_input *input,
196679251f5eSSepherosa Ziehau 					  u16 soft_id)
196779251f5eSSepherosa Ziehau {
196879251f5eSSepherosa Ziehau 	u32 fdirhash;
196963d483cdSSepherosa Ziehau 	u32 fdircmd;
197063d483cdSSepherosa Ziehau 	s32 err;
197179251f5eSSepherosa Ziehau 
197279251f5eSSepherosa Ziehau 	/* configure FDIRHASH register */
197379251f5eSSepherosa Ziehau 	fdirhash = input->formatted.bkt_hash;
197479251f5eSSepherosa Ziehau 	fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT;
197579251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
197679251f5eSSepherosa Ziehau 
197779251f5eSSepherosa Ziehau 	/* flush hash to HW */
197879251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
197979251f5eSSepherosa Ziehau 
198079251f5eSSepherosa Ziehau 	/* Query if filter is present */
198179251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, IXGBE_FDIRCMD_CMD_QUERY_REM_FILT);
198279251f5eSSepherosa Ziehau 
198363d483cdSSepherosa Ziehau 	err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd);
198463d483cdSSepherosa Ziehau 	if (err) {
198563d483cdSSepherosa Ziehau 		DEBUGOUT("Flow Director command did not complete!\n");
198663d483cdSSepherosa Ziehau 		return err;
198779251f5eSSepherosa Ziehau 	}
198879251f5eSSepherosa Ziehau 
198979251f5eSSepherosa Ziehau 	/* if filter exists in hardware then remove it */
199079251f5eSSepherosa Ziehau 	if (fdircmd & IXGBE_FDIRCMD_FILTER_VALID) {
199179251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
199279251f5eSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
199379251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
199479251f5eSSepherosa Ziehau 				IXGBE_FDIRCMD_CMD_REMOVE_FLOW);
199579251f5eSSepherosa Ziehau 	}
199679251f5eSSepherosa Ziehau 
199763d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
199879251f5eSSepherosa Ziehau }
199979251f5eSSepherosa Ziehau 
200079251f5eSSepherosa Ziehau /**
200179251f5eSSepherosa Ziehau  *  ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter
200279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
200379251f5eSSepherosa Ziehau  *  @input: input bitstream
200479251f5eSSepherosa Ziehau  *  @input_mask: mask for the input bitstream
200579251f5eSSepherosa Ziehau  *  @soft_id: software index for the filters
200679251f5eSSepherosa Ziehau  *  @queue: queue index to direct traffic to
2007*dd5ce676SSepherosa Ziehau  *  @cloud_mode: unused
200879251f5eSSepherosa Ziehau  *
200979251f5eSSepherosa Ziehau  *  Note that the caller to this function must lock before calling, since the
201079251f5eSSepherosa Ziehau  *  hardware writes must be protected from one another.
201179251f5eSSepherosa Ziehau  **/
ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw * hw,union ixgbe_atr_input * input,union ixgbe_atr_input * input_mask,u16 soft_id,u8 queue,bool cloud_mode)201279251f5eSSepherosa Ziehau s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
201379251f5eSSepherosa Ziehau 					union ixgbe_atr_input *input,
201479251f5eSSepherosa Ziehau 					union ixgbe_atr_input *input_mask,
201563d483cdSSepherosa Ziehau 					u16 soft_id, u8 queue, bool cloud_mode)
201679251f5eSSepherosa Ziehau {
201779251f5eSSepherosa Ziehau 	s32 err = IXGBE_ERR_CONFIG;
2018*dd5ce676SSepherosa Ziehau 	UNREFERENCED_1PARAMETER(cloud_mode);
201979251f5eSSepherosa Ziehau 
202079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_fdir_add_perfect_filter_82599");
202179251f5eSSepherosa Ziehau 
202279251f5eSSepherosa Ziehau 	/*
202379251f5eSSepherosa Ziehau 	 * Check flow_type formatting, and bail out before we touch the hardware
202479251f5eSSepherosa Ziehau 	 * if there's a configuration issue
202579251f5eSSepherosa Ziehau 	 */
202679251f5eSSepherosa Ziehau 	switch (input->formatted.flow_type) {
202779251f5eSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_IPV4:
202863d483cdSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_TUNNELED_IPV4:
202979251f5eSSepherosa Ziehau 		input_mask->formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK;
203079251f5eSSepherosa Ziehau 		if (input->formatted.dst_port || input->formatted.src_port) {
203179251f5eSSepherosa Ziehau 			DEBUGOUT(" Error on src/dst port\n");
203279251f5eSSepherosa Ziehau 			return IXGBE_ERR_CONFIG;
203379251f5eSSepherosa Ziehau 		}
203479251f5eSSepherosa Ziehau 		break;
203579251f5eSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_SCTPV4:
203663d483cdSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_TUNNELED_SCTPV4:
203779251f5eSSepherosa Ziehau 		if (input->formatted.dst_port || input->formatted.src_port) {
203879251f5eSSepherosa Ziehau 			DEBUGOUT(" Error on src/dst port\n");
203979251f5eSSepherosa Ziehau 			return IXGBE_ERR_CONFIG;
204079251f5eSSepherosa Ziehau 		}
20416150453fSSepherosa Ziehau 		/* fall through */
204279251f5eSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_TCPV4:
204363d483cdSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_TUNNELED_TCPV4:
204479251f5eSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_UDPV4:
204563d483cdSSepherosa Ziehau 	case IXGBE_ATR_FLOW_TYPE_TUNNELED_UDPV4:
204679251f5eSSepherosa Ziehau 		input_mask->formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK |
204779251f5eSSepherosa Ziehau 						  IXGBE_ATR_L4TYPE_MASK;
204879251f5eSSepherosa Ziehau 		break;
204979251f5eSSepherosa Ziehau 	default:
205079251f5eSSepherosa Ziehau 		DEBUGOUT(" Error on flow type input\n");
205179251f5eSSepherosa Ziehau 		return err;
205279251f5eSSepherosa Ziehau 	}
205379251f5eSSepherosa Ziehau 
205479251f5eSSepherosa Ziehau 	/* program input mask into the HW */
205563d483cdSSepherosa Ziehau 	err = ixgbe_fdir_set_input_mask_82599(hw, input_mask, cloud_mode);
205679251f5eSSepherosa Ziehau 	if (err)
205779251f5eSSepherosa Ziehau 		return err;
205879251f5eSSepherosa Ziehau 
205979251f5eSSepherosa Ziehau 	/* apply mask and compute/store hash */
206079251f5eSSepherosa Ziehau 	ixgbe_atr_compute_perfect_hash_82599(input, input_mask);
206179251f5eSSepherosa Ziehau 
206279251f5eSSepherosa Ziehau 	/* program filters to filter memory */
206379251f5eSSepherosa Ziehau 	return ixgbe_fdir_write_perfect_filter_82599(hw, input,
206463d483cdSSepherosa Ziehau 						     soft_id, queue, cloud_mode);
206579251f5eSSepherosa Ziehau }
206679251f5eSSepherosa Ziehau 
206779251f5eSSepherosa Ziehau /**
206879251f5eSSepherosa Ziehau  *  ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
206979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
207079251f5eSSepherosa Ziehau  *  @reg: analog register to read
207179251f5eSSepherosa Ziehau  *  @val: read value
207279251f5eSSepherosa Ziehau  *
207379251f5eSSepherosa Ziehau  *  Performs read operation to Omer analog register specified.
207479251f5eSSepherosa Ziehau  **/
ixgbe_read_analog_reg8_82599(struct ixgbe_hw * hw,u32 reg,u8 * val)207579251f5eSSepherosa Ziehau s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val)
207679251f5eSSepherosa Ziehau {
207779251f5eSSepherosa Ziehau 	u32  core_ctl;
207879251f5eSSepherosa Ziehau 
207979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_analog_reg8_82599");
208079251f5eSSepherosa Ziehau 
208179251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_CORECTL, IXGBE_CORECTL_WRITE_CMD |
208279251f5eSSepherosa Ziehau 			(reg << 8));
208379251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
208479251f5eSSepherosa Ziehau 	usec_delay(10);
208579251f5eSSepherosa Ziehau 	core_ctl = IXGBE_READ_REG(hw, IXGBE_CORECTL);
208679251f5eSSepherosa Ziehau 	*val = (u8)core_ctl;
208779251f5eSSepherosa Ziehau 
208879251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
208979251f5eSSepherosa Ziehau }
209079251f5eSSepherosa Ziehau 
209179251f5eSSepherosa Ziehau /**
209279251f5eSSepherosa Ziehau  *  ixgbe_write_analog_reg8_82599 - Writes 8 bit Omer analog register
209379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
209479251f5eSSepherosa Ziehau  *  @reg: atlas register to write
209579251f5eSSepherosa Ziehau  *  @val: value to write
209679251f5eSSepherosa Ziehau  *
209779251f5eSSepherosa Ziehau  *  Performs write operation to Omer analog register specified.
209879251f5eSSepherosa Ziehau  **/
ixgbe_write_analog_reg8_82599(struct ixgbe_hw * hw,u32 reg,u8 val)209979251f5eSSepherosa Ziehau s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
210079251f5eSSepherosa Ziehau {
210179251f5eSSepherosa Ziehau 	u32  core_ctl;
210279251f5eSSepherosa Ziehau 
210379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_analog_reg8_82599");
210479251f5eSSepherosa Ziehau 
210579251f5eSSepherosa Ziehau 	core_ctl = (reg << 8) | val;
210679251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_CORECTL, core_ctl);
210779251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
210879251f5eSSepherosa Ziehau 	usec_delay(10);
210979251f5eSSepherosa Ziehau 
211079251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
211179251f5eSSepherosa Ziehau }
211279251f5eSSepherosa Ziehau 
211379251f5eSSepherosa Ziehau /**
211479251f5eSSepherosa Ziehau  *  ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx
211579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
211679251f5eSSepherosa Ziehau  *
211779251f5eSSepherosa Ziehau  *  Starts the hardware using the generic start_hw function
211879251f5eSSepherosa Ziehau  *  and the generation start_hw function.
211979251f5eSSepherosa Ziehau  *  Then performs revision-specific operations, if any.
212079251f5eSSepherosa Ziehau  **/
ixgbe_start_hw_82599(struct ixgbe_hw * hw)212179251f5eSSepherosa Ziehau s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
212279251f5eSSepherosa Ziehau {
212379251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
212479251f5eSSepherosa Ziehau 
212579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_start_hw_82599");
212679251f5eSSepherosa Ziehau 
212779251f5eSSepherosa Ziehau 	ret_val = ixgbe_start_hw_generic(hw);
212879251f5eSSepherosa Ziehau 	if (ret_val != IXGBE_SUCCESS)
212979251f5eSSepherosa Ziehau 		goto out;
213079251f5eSSepherosa Ziehau 
213179251f5eSSepherosa Ziehau 	ret_val = ixgbe_start_hw_gen2(hw);
213279251f5eSSepherosa Ziehau 	if (ret_val != IXGBE_SUCCESS)
213379251f5eSSepherosa Ziehau 		goto out;
213479251f5eSSepherosa Ziehau 
213579251f5eSSepherosa Ziehau 	/* We need to run link autotry after the driver loads */
213679251f5eSSepherosa Ziehau 	hw->mac.autotry_restart = TRUE;
213779251f5eSSepherosa Ziehau 
213879251f5eSSepherosa Ziehau 	if (ret_val == IXGBE_SUCCESS)
213979251f5eSSepherosa Ziehau 		ret_val = ixgbe_verify_fw_version_82599(hw);
214079251f5eSSepherosa Ziehau out:
214179251f5eSSepherosa Ziehau 	return ret_val;
214279251f5eSSepherosa Ziehau }
214379251f5eSSepherosa Ziehau 
214479251f5eSSepherosa Ziehau /**
214579251f5eSSepherosa Ziehau  *  ixgbe_identify_phy_82599 - Get physical layer module
214679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
214779251f5eSSepherosa Ziehau  *
214879251f5eSSepherosa Ziehau  *  Determines the physical layer module found on the current adapter.
214979251f5eSSepherosa Ziehau  *  If PHY already detected, maintains current PHY type in hw struct,
215079251f5eSSepherosa Ziehau  *  otherwise executes the PHY detection routine.
215179251f5eSSepherosa Ziehau  **/
ixgbe_identify_phy_82599(struct ixgbe_hw * hw)215279251f5eSSepherosa Ziehau s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
215379251f5eSSepherosa Ziehau {
215463d483cdSSepherosa Ziehau 	s32 status;
215579251f5eSSepherosa Ziehau 
215679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_identify_phy_82599");
215779251f5eSSepherosa Ziehau 
215879251f5eSSepherosa Ziehau 	/* Detect PHY if not unknown - returns success if already detected. */
215979251f5eSSepherosa Ziehau 	status = ixgbe_identify_phy_generic(hw);
216079251f5eSSepherosa Ziehau 	if (status != IXGBE_SUCCESS) {
216179251f5eSSepherosa Ziehau 		/* 82599 10GBASE-T requires an external PHY */
216279251f5eSSepherosa Ziehau 		if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper)
216363d483cdSSepherosa Ziehau 			return status;
216479251f5eSSepherosa Ziehau 		else
216579251f5eSSepherosa Ziehau 			status = ixgbe_identify_module_generic(hw);
216679251f5eSSepherosa Ziehau 	}
216779251f5eSSepherosa Ziehau 
216879251f5eSSepherosa Ziehau 	/* Set PHY type none if no PHY detected */
216979251f5eSSepherosa Ziehau 	if (hw->phy.type == ixgbe_phy_unknown) {
217079251f5eSSepherosa Ziehau 		hw->phy.type = ixgbe_phy_none;
217163d483cdSSepherosa Ziehau 		return IXGBE_SUCCESS;
217279251f5eSSepherosa Ziehau 	}
217379251f5eSSepherosa Ziehau 
217479251f5eSSepherosa Ziehau 	/* Return error if SFP module has been detected but is not supported */
217579251f5eSSepherosa Ziehau 	if (hw->phy.type == ixgbe_phy_sfp_unsupported)
217663d483cdSSepherosa Ziehau 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
217779251f5eSSepherosa Ziehau 
217879251f5eSSepherosa Ziehau 	return status;
217979251f5eSSepherosa Ziehau }
218079251f5eSSepherosa Ziehau 
218179251f5eSSepherosa Ziehau /**
218279251f5eSSepherosa Ziehau  *  ixgbe_get_supported_physical_layer_82599 - Returns physical layer type
218379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
218479251f5eSSepherosa Ziehau  *
218579251f5eSSepherosa Ziehau  *  Determines physical layer capabilities of the current configuration.
218679251f5eSSepherosa Ziehau  **/
ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw * hw)21876150453fSSepherosa Ziehau u64 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
218879251f5eSSepherosa Ziehau {
21896150453fSSepherosa Ziehau 	u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
219079251f5eSSepherosa Ziehau 	u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
219179251f5eSSepherosa Ziehau 	u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
219279251f5eSSepherosa Ziehau 	u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
219379251f5eSSepherosa Ziehau 	u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
219479251f5eSSepherosa Ziehau 	u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
219579251f5eSSepherosa Ziehau 	u16 ext_ability = 0;
219679251f5eSSepherosa Ziehau 
219779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_support_physical_layer_82599");
219879251f5eSSepherosa Ziehau 
219979251f5eSSepherosa Ziehau 	hw->phy.ops.identify(hw);
220079251f5eSSepherosa Ziehau 
220179251f5eSSepherosa Ziehau 	switch (hw->phy.type) {
220279251f5eSSepherosa Ziehau 	case ixgbe_phy_tn:
220379251f5eSSepherosa Ziehau 	case ixgbe_phy_cu_unknown:
220479251f5eSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
220579251f5eSSepherosa Ziehau 		IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
220679251f5eSSepherosa Ziehau 		if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
220779251f5eSSepherosa Ziehau 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
220879251f5eSSepherosa Ziehau 		if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
220979251f5eSSepherosa Ziehau 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
221079251f5eSSepherosa Ziehau 		if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
221179251f5eSSepherosa Ziehau 			physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
221279251f5eSSepherosa Ziehau 		goto out;
221379251f5eSSepherosa Ziehau 	default:
221479251f5eSSepherosa Ziehau 		break;
221579251f5eSSepherosa Ziehau 	}
221679251f5eSSepherosa Ziehau 
221779251f5eSSepherosa Ziehau 	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
221879251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_1G_AN:
221979251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
222079251f5eSSepherosa Ziehau 		if (pma_pmd_1g == IXGBE_AUTOC_1G_KX_BX) {
222179251f5eSSepherosa Ziehau 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX |
222279251f5eSSepherosa Ziehau 			    IXGBE_PHYSICAL_LAYER_1000BASE_BX;
222379251f5eSSepherosa Ziehau 			goto out;
222479251f5eSSepherosa Ziehau 		} else
222579251f5eSSepherosa Ziehau 			/* SFI mode so read SFP module */
222679251f5eSSepherosa Ziehau 			goto sfp_check;
222779251f5eSSepherosa Ziehau 		break;
222879251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
222979251f5eSSepherosa Ziehau 		if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_CX4)
223079251f5eSSepherosa Ziehau 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
223179251f5eSSepherosa Ziehau 		else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_KX4)
223279251f5eSSepherosa Ziehau 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
223379251f5eSSepherosa Ziehau 		else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_XAUI)
223479251f5eSSepherosa Ziehau 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_XAUI;
223579251f5eSSepherosa Ziehau 		goto out;
223679251f5eSSepherosa Ziehau 		break;
223779251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_10G_SERIAL:
223879251f5eSSepherosa Ziehau 		if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_KR) {
223979251f5eSSepherosa Ziehau 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR;
224079251f5eSSepherosa Ziehau 			goto out;
224179251f5eSSepherosa Ziehau 		} else if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)
224279251f5eSSepherosa Ziehau 			goto sfp_check;
224379251f5eSSepherosa Ziehau 		break;
224479251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_KX4_KX_KR:
224579251f5eSSepherosa Ziehau 	case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
224679251f5eSSepherosa Ziehau 		if (autoc & IXGBE_AUTOC_KX_SUPP)
224779251f5eSSepherosa Ziehau 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
224879251f5eSSepherosa Ziehau 		if (autoc & IXGBE_AUTOC_KX4_SUPP)
224979251f5eSSepherosa Ziehau 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
225079251f5eSSepherosa Ziehau 		if (autoc & IXGBE_AUTOC_KR_SUPP)
225179251f5eSSepherosa Ziehau 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR;
225279251f5eSSepherosa Ziehau 		goto out;
225379251f5eSSepherosa Ziehau 		break;
225479251f5eSSepherosa Ziehau 	default:
225579251f5eSSepherosa Ziehau 		goto out;
225679251f5eSSepherosa Ziehau 		break;
225779251f5eSSepherosa Ziehau 	}
225879251f5eSSepherosa Ziehau 
225979251f5eSSepherosa Ziehau sfp_check:
226079251f5eSSepherosa Ziehau 	/* SFP check must be done last since DA modules are sometimes used to
226179251f5eSSepherosa Ziehau 	 * test KR mode -  we need to id KR mode correctly before SFP module.
226279251f5eSSepherosa Ziehau 	 * Call identify_sfp because the pluggable module may have changed */
226363d483cdSSepherosa Ziehau 	physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw);
226479251f5eSSepherosa Ziehau out:
226579251f5eSSepherosa Ziehau 	return physical_layer;
226679251f5eSSepherosa Ziehau }
226779251f5eSSepherosa Ziehau 
226879251f5eSSepherosa Ziehau /**
226979251f5eSSepherosa Ziehau  *  ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599
227079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
227179251f5eSSepherosa Ziehau  *  @regval: register value to write to RXCTRL
227279251f5eSSepherosa Ziehau  *
227379251f5eSSepherosa Ziehau  *  Enables the Rx DMA unit for 82599
227479251f5eSSepherosa Ziehau  **/
ixgbe_enable_rx_dma_82599(struct ixgbe_hw * hw,u32 regval)227579251f5eSSepherosa Ziehau s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
227679251f5eSSepherosa Ziehau {
227779251f5eSSepherosa Ziehau 
227879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_enable_rx_dma_82599");
227979251f5eSSepherosa Ziehau 
228079251f5eSSepherosa Ziehau 	/*
228179251f5eSSepherosa Ziehau 	 * Workaround for 82599 silicon errata when enabling the Rx datapath.
228279251f5eSSepherosa Ziehau 	 * If traffic is incoming before we enable the Rx unit, it could hang
228379251f5eSSepherosa Ziehau 	 * the Rx DMA unit.  Therefore, make sure the security engine is
228479251f5eSSepherosa Ziehau 	 * completely disabled prior to enabling the Rx unit.
228579251f5eSSepherosa Ziehau 	 */
228679251f5eSSepherosa Ziehau 
228779251f5eSSepherosa Ziehau 	hw->mac.ops.disable_sec_rx_path(hw);
228879251f5eSSepherosa Ziehau 
228963d483cdSSepherosa Ziehau 	if (regval & IXGBE_RXCTRL_RXEN)
229063d483cdSSepherosa Ziehau 		ixgbe_enable_rx(hw);
229163d483cdSSepherosa Ziehau 	else
229263d483cdSSepherosa Ziehau 		ixgbe_disable_rx(hw);
229379251f5eSSepherosa Ziehau 
229479251f5eSSepherosa Ziehau 	hw->mac.ops.enable_sec_rx_path(hw);
229579251f5eSSepherosa Ziehau 
229679251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
229779251f5eSSepherosa Ziehau }
229879251f5eSSepherosa Ziehau 
229979251f5eSSepherosa Ziehau /**
230063d483cdSSepherosa Ziehau  *  ixgbe_verify_fw_version_82599 - verify FW version for 82599
230179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
230279251f5eSSepherosa Ziehau  *
230379251f5eSSepherosa Ziehau  *  Verifies that installed the firmware version is 0.6 or higher
230479251f5eSSepherosa Ziehau  *  for SFI devices. All 82599 SFI devices should have version 0.6 or higher.
230579251f5eSSepherosa Ziehau  *
230679251f5eSSepherosa Ziehau  *  Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or
230779251f5eSSepherosa Ziehau  *  if the FW version is not supported.
230879251f5eSSepherosa Ziehau  **/
ixgbe_verify_fw_version_82599(struct ixgbe_hw * hw)230979251f5eSSepherosa Ziehau static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
231079251f5eSSepherosa Ziehau {
231179251f5eSSepherosa Ziehau 	s32 status = IXGBE_ERR_EEPROM_VERSION;
231279251f5eSSepherosa Ziehau 	u16 fw_offset, fw_ptp_cfg_offset;
231379251f5eSSepherosa Ziehau 	u16 fw_version;
231479251f5eSSepherosa Ziehau 
231579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_verify_fw_version_82599");
231679251f5eSSepherosa Ziehau 
231779251f5eSSepherosa Ziehau 	/* firmware check is only necessary for SFI devices */
231879251f5eSSepherosa Ziehau 	if (hw->phy.media_type != ixgbe_media_type_fiber) {
231979251f5eSSepherosa Ziehau 		status = IXGBE_SUCCESS;
232079251f5eSSepherosa Ziehau 		goto fw_version_out;
232179251f5eSSepherosa Ziehau 	}
232279251f5eSSepherosa Ziehau 
232379251f5eSSepherosa Ziehau 	/* get the offset to the Firmware Module block */
232479251f5eSSepherosa Ziehau 	if (hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset)) {
232579251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
232679251f5eSSepherosa Ziehau 			      "eeprom read at offset %d failed", IXGBE_FW_PTR);
232779251f5eSSepherosa Ziehau 		return IXGBE_ERR_EEPROM_VERSION;
232879251f5eSSepherosa Ziehau 	}
232979251f5eSSepherosa Ziehau 
233079251f5eSSepherosa Ziehau 	if ((fw_offset == 0) || (fw_offset == 0xFFFF))
233179251f5eSSepherosa Ziehau 		goto fw_version_out;
233279251f5eSSepherosa Ziehau 
233379251f5eSSepherosa Ziehau 	/* get the offset to the Pass Through Patch Configuration block */
233479251f5eSSepherosa Ziehau 	if (hw->eeprom.ops.read(hw, (fw_offset +
233579251f5eSSepherosa Ziehau 				 IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR),
233679251f5eSSepherosa Ziehau 				 &fw_ptp_cfg_offset)) {
233779251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
233879251f5eSSepherosa Ziehau 			      "eeprom read at offset %d failed",
233979251f5eSSepherosa Ziehau 			      fw_offset +
234079251f5eSSepherosa Ziehau 			      IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR);
234179251f5eSSepherosa Ziehau 		return IXGBE_ERR_EEPROM_VERSION;
234279251f5eSSepherosa Ziehau 	}
234379251f5eSSepherosa Ziehau 
234479251f5eSSepherosa Ziehau 	if ((fw_ptp_cfg_offset == 0) || (fw_ptp_cfg_offset == 0xFFFF))
234579251f5eSSepherosa Ziehau 		goto fw_version_out;
234679251f5eSSepherosa Ziehau 
234779251f5eSSepherosa Ziehau 	/* get the firmware version */
234879251f5eSSepherosa Ziehau 	if (hw->eeprom.ops.read(hw, (fw_ptp_cfg_offset +
234979251f5eSSepherosa Ziehau 			    IXGBE_FW_PATCH_VERSION_4), &fw_version)) {
235079251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
235179251f5eSSepherosa Ziehau 			      "eeprom read at offset %d failed",
235279251f5eSSepherosa Ziehau 			      fw_ptp_cfg_offset + IXGBE_FW_PATCH_VERSION_4);
235379251f5eSSepherosa Ziehau 		return IXGBE_ERR_EEPROM_VERSION;
235479251f5eSSepherosa Ziehau 	}
235579251f5eSSepherosa Ziehau 
235679251f5eSSepherosa Ziehau 	if (fw_version > 0x5)
235779251f5eSSepherosa Ziehau 		status = IXGBE_SUCCESS;
235879251f5eSSepherosa Ziehau 
235979251f5eSSepherosa Ziehau fw_version_out:
236079251f5eSSepherosa Ziehau 	return status;
236179251f5eSSepherosa Ziehau }
236279251f5eSSepherosa Ziehau 
236379251f5eSSepherosa Ziehau /**
236479251f5eSSepherosa Ziehau  *  ixgbe_verify_lesm_fw_enabled_82599 - Checks LESM FW module state.
236579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
236679251f5eSSepherosa Ziehau  *
236779251f5eSSepherosa Ziehau  *  Returns TRUE if the LESM FW module is present and enabled. Otherwise
236879251f5eSSepherosa Ziehau  *  returns FALSE. Smart Speed must be disabled if LESM FW module is enabled.
236979251f5eSSepherosa Ziehau  **/
ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw * hw)237079251f5eSSepherosa Ziehau bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw)
237179251f5eSSepherosa Ziehau {
237279251f5eSSepherosa Ziehau 	bool lesm_enabled = FALSE;
237379251f5eSSepherosa Ziehau 	u16 fw_offset, fw_lesm_param_offset, fw_lesm_state;
237479251f5eSSepherosa Ziehau 	s32 status;
237579251f5eSSepherosa Ziehau 
237679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_verify_lesm_fw_enabled_82599");
237779251f5eSSepherosa Ziehau 
237879251f5eSSepherosa Ziehau 	/* get the offset to the Firmware Module block */
237979251f5eSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset);
238079251f5eSSepherosa Ziehau 
238179251f5eSSepherosa Ziehau 	if ((status != IXGBE_SUCCESS) ||
238279251f5eSSepherosa Ziehau 	    (fw_offset == 0) || (fw_offset == 0xFFFF))
238379251f5eSSepherosa Ziehau 		goto out;
238479251f5eSSepherosa Ziehau 
238579251f5eSSepherosa Ziehau 	/* get the offset to the LESM Parameters block */
238679251f5eSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, (fw_offset +
238779251f5eSSepherosa Ziehau 				     IXGBE_FW_LESM_PARAMETERS_PTR),
238879251f5eSSepherosa Ziehau 				     &fw_lesm_param_offset);
238979251f5eSSepherosa Ziehau 
239079251f5eSSepherosa Ziehau 	if ((status != IXGBE_SUCCESS) ||
239179251f5eSSepherosa Ziehau 	    (fw_lesm_param_offset == 0) || (fw_lesm_param_offset == 0xFFFF))
239279251f5eSSepherosa Ziehau 		goto out;
239379251f5eSSepherosa Ziehau 
239463d483cdSSepherosa Ziehau 	/* get the LESM state word */
239579251f5eSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, (fw_lesm_param_offset +
239679251f5eSSepherosa Ziehau 				     IXGBE_FW_LESM_STATE_1),
239779251f5eSSepherosa Ziehau 				     &fw_lesm_state);
239879251f5eSSepherosa Ziehau 
239979251f5eSSepherosa Ziehau 	if ((status == IXGBE_SUCCESS) &&
240079251f5eSSepherosa Ziehau 	    (fw_lesm_state & IXGBE_FW_LESM_STATE_ENABLED))
240179251f5eSSepherosa Ziehau 		lesm_enabled = TRUE;
240279251f5eSSepherosa Ziehau 
240379251f5eSSepherosa Ziehau out:
240479251f5eSSepherosa Ziehau 	return lesm_enabled;
240579251f5eSSepherosa Ziehau }
240679251f5eSSepherosa Ziehau 
240779251f5eSSepherosa Ziehau /**
240879251f5eSSepherosa Ziehau  *  ixgbe_read_eeprom_buffer_82599 - Read EEPROM word(s) using
240979251f5eSSepherosa Ziehau  *  fastest available method
241079251f5eSSepherosa Ziehau  *
241179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
241279251f5eSSepherosa Ziehau  *  @offset: offset of  word in EEPROM to read
241379251f5eSSepherosa Ziehau  *  @words: number of words
241479251f5eSSepherosa Ziehau  *  @data: word(s) read from the EEPROM
241579251f5eSSepherosa Ziehau  *
241679251f5eSSepherosa Ziehau  *  Retrieves 16 bit word(s) read from EEPROM
241779251f5eSSepherosa Ziehau  **/
ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)241879251f5eSSepherosa Ziehau static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
241979251f5eSSepherosa Ziehau 					  u16 words, u16 *data)
242079251f5eSSepherosa Ziehau {
242179251f5eSSepherosa Ziehau 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
242279251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_CONFIG;
242379251f5eSSepherosa Ziehau 
242479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_eeprom_buffer_82599");
242579251f5eSSepherosa Ziehau 
242679251f5eSSepherosa Ziehau 	/*
242779251f5eSSepherosa Ziehau 	 * If EEPROM is detected and can be addressed using 14 bits,
242879251f5eSSepherosa Ziehau 	 * use EERD otherwise use bit bang
242979251f5eSSepherosa Ziehau 	 */
243079251f5eSSepherosa Ziehau 	if ((eeprom->type == ixgbe_eeprom_spi) &&
243179251f5eSSepherosa Ziehau 	    (offset + (words - 1) <= IXGBE_EERD_MAX_ADDR))
243279251f5eSSepherosa Ziehau 		ret_val = ixgbe_read_eerd_buffer_generic(hw, offset, words,
243379251f5eSSepherosa Ziehau 							 data);
243479251f5eSSepherosa Ziehau 	else
243579251f5eSSepherosa Ziehau 		ret_val = ixgbe_read_eeprom_buffer_bit_bang_generic(hw, offset,
243679251f5eSSepherosa Ziehau 								    words,
243779251f5eSSepherosa Ziehau 								    data);
243879251f5eSSepherosa Ziehau 
243979251f5eSSepherosa Ziehau 	return ret_val;
244079251f5eSSepherosa Ziehau }
244179251f5eSSepherosa Ziehau 
244279251f5eSSepherosa Ziehau /**
244379251f5eSSepherosa Ziehau  *  ixgbe_read_eeprom_82599 - Read EEPROM word using
244479251f5eSSepherosa Ziehau  *  fastest available method
244579251f5eSSepherosa Ziehau  *
244679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
244779251f5eSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to read
244879251f5eSSepherosa Ziehau  *  @data: word read from the EEPROM
244979251f5eSSepherosa Ziehau  *
245079251f5eSSepherosa Ziehau  *  Reads a 16 bit word from the EEPROM
245179251f5eSSepherosa Ziehau  **/
ixgbe_read_eeprom_82599(struct ixgbe_hw * hw,u16 offset,u16 * data)245279251f5eSSepherosa Ziehau static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
245379251f5eSSepherosa Ziehau 				   u16 offset, u16 *data)
245479251f5eSSepherosa Ziehau {
245579251f5eSSepherosa Ziehau 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
245679251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_CONFIG;
245779251f5eSSepherosa Ziehau 
245879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_eeprom_82599");
245979251f5eSSepherosa Ziehau 
246079251f5eSSepherosa Ziehau 	/*
246179251f5eSSepherosa Ziehau 	 * If EEPROM is detected and can be addressed using 14 bits,
246279251f5eSSepherosa Ziehau 	 * use EERD otherwise use bit bang
246379251f5eSSepherosa Ziehau 	 */
246479251f5eSSepherosa Ziehau 	if ((eeprom->type == ixgbe_eeprom_spi) &&
246579251f5eSSepherosa Ziehau 	    (offset <= IXGBE_EERD_MAX_ADDR))
246679251f5eSSepherosa Ziehau 		ret_val = ixgbe_read_eerd_generic(hw, offset, data);
246779251f5eSSepherosa Ziehau 	else
246879251f5eSSepherosa Ziehau 		ret_val = ixgbe_read_eeprom_bit_bang_generic(hw, offset, data);
246979251f5eSSepherosa Ziehau 
247079251f5eSSepherosa Ziehau 	return ret_val;
247179251f5eSSepherosa Ziehau }
247279251f5eSSepherosa Ziehau 
247379251f5eSSepherosa Ziehau /**
247479251f5eSSepherosa Ziehau  * ixgbe_reset_pipeline_82599 - perform pipeline reset
247579251f5eSSepherosa Ziehau  *
247679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
247779251f5eSSepherosa Ziehau  *
247879251f5eSSepherosa Ziehau  * Reset pipeline by asserting Restart_AN together with LMS change to ensure
247963d483cdSSepherosa Ziehau  * full pipeline reset.  This function assumes the SW/FW lock is held.
248079251f5eSSepherosa Ziehau  **/
ixgbe_reset_pipeline_82599(struct ixgbe_hw * hw)248179251f5eSSepherosa Ziehau s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
248279251f5eSSepherosa Ziehau {
248379251f5eSSepherosa Ziehau 	s32 ret_val;
248479251f5eSSepherosa Ziehau 	u32 anlp1_reg = 0;
248579251f5eSSepherosa Ziehau 	u32 i, autoc_reg, autoc2_reg;
248679251f5eSSepherosa Ziehau 
248779251f5eSSepherosa Ziehau 	/* Enable link if disabled in NVM */
248879251f5eSSepherosa Ziehau 	autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
248979251f5eSSepherosa Ziehau 	if (autoc2_reg & IXGBE_AUTOC2_LINK_DISABLE_MASK) {
249079251f5eSSepherosa Ziehau 		autoc2_reg &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK;
249179251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2_reg);
249279251f5eSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
249379251f5eSSepherosa Ziehau 	}
249479251f5eSSepherosa Ziehau 
249563d483cdSSepherosa Ziehau 	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
249679251f5eSSepherosa Ziehau 	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
249779251f5eSSepherosa Ziehau 	/* Write AUTOC register with toggled LMS[2] bit and Restart_AN */
249863d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC,
249963d483cdSSepherosa Ziehau 			autoc_reg ^ (0x4 << IXGBE_AUTOC_LMS_SHIFT));
250079251f5eSSepherosa Ziehau 	/* Wait for AN to leave state 0 */
250179251f5eSSepherosa Ziehau 	for (i = 0; i < 10; i++) {
250279251f5eSSepherosa Ziehau 		msec_delay(4);
250379251f5eSSepherosa Ziehau 		anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
250479251f5eSSepherosa Ziehau 		if (anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)
250579251f5eSSepherosa Ziehau 			break;
250679251f5eSSepherosa Ziehau 	}
250779251f5eSSepherosa Ziehau 
250879251f5eSSepherosa Ziehau 	if (!(anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)) {
250979251f5eSSepherosa Ziehau 		DEBUGOUT("auto negotiation not completed\n");
251079251f5eSSepherosa Ziehau 		ret_val = IXGBE_ERR_RESET_FAILED;
251179251f5eSSepherosa Ziehau 		goto reset_pipeline_out;
251279251f5eSSepherosa Ziehau 	}
251379251f5eSSepherosa Ziehau 
251479251f5eSSepherosa Ziehau 	ret_val = IXGBE_SUCCESS;
251579251f5eSSepherosa Ziehau 
251679251f5eSSepherosa Ziehau reset_pipeline_out:
251779251f5eSSepherosa Ziehau 	/* Write AUTOC register with original LMS field and Restart_AN */
251879251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
251979251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
252079251f5eSSepherosa Ziehau 
252179251f5eSSepherosa Ziehau 	return ret_val;
252279251f5eSSepherosa Ziehau }
252379251f5eSSepherosa Ziehau 
252463d483cdSSepherosa Ziehau /**
252563d483cdSSepherosa Ziehau  *  ixgbe_read_i2c_byte_82599 - Reads 8 bit word over I2C
252663d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
252763d483cdSSepherosa Ziehau  *  @byte_offset: byte offset to read
2528*dd5ce676SSepherosa Ziehau  *  @dev_addr: address to read from
252963d483cdSSepherosa Ziehau  *  @data: value read
253063d483cdSSepherosa Ziehau  *
253163d483cdSSepherosa Ziehau  *  Performs byte read operation to SFP module's EEPROM over I2C interface at
253263d483cdSSepherosa Ziehau  *  a specified device address.
253363d483cdSSepherosa Ziehau  **/
ixgbe_read_i2c_byte_82599(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 * data)253463d483cdSSepherosa Ziehau static s32 ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
253563d483cdSSepherosa Ziehau 				u8 dev_addr, u8 *data)
253663d483cdSSepherosa Ziehau {
253763d483cdSSepherosa Ziehau 	u32 esdp;
253863d483cdSSepherosa Ziehau 	s32 status;
253963d483cdSSepherosa Ziehau 	s32 timeout = 200;
254079251f5eSSepherosa Ziehau 
254163d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_i2c_byte_82599");
254279251f5eSSepherosa Ziehau 
254363d483cdSSepherosa Ziehau 	if (hw->phy.qsfp_shared_i2c_bus == TRUE) {
254463d483cdSSepherosa Ziehau 		/* Acquire I2C bus ownership. */
254563d483cdSSepherosa Ziehau 		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
254663d483cdSSepherosa Ziehau 		esdp |= IXGBE_ESDP_SDP0;
254763d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
254863d483cdSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
254963d483cdSSepherosa Ziehau 
255063d483cdSSepherosa Ziehau 		while (timeout) {
255163d483cdSSepherosa Ziehau 			esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
255263d483cdSSepherosa Ziehau 			if (esdp & IXGBE_ESDP_SDP1)
255363d483cdSSepherosa Ziehau 				break;
255463d483cdSSepherosa Ziehau 
255563d483cdSSepherosa Ziehau 			msec_delay(5);
255663d483cdSSepherosa Ziehau 			timeout--;
255763d483cdSSepherosa Ziehau 		}
255863d483cdSSepherosa Ziehau 
255963d483cdSSepherosa Ziehau 		if (!timeout) {
256063d483cdSSepherosa Ziehau 			DEBUGOUT("Driver can't access resource,"
256163d483cdSSepherosa Ziehau 				 " acquiring I2C bus timeout.\n");
256263d483cdSSepherosa Ziehau 			status = IXGBE_ERR_I2C;
256363d483cdSSepherosa Ziehau 			goto release_i2c_access;
256463d483cdSSepherosa Ziehau 		}
256563d483cdSSepherosa Ziehau 	}
256663d483cdSSepherosa Ziehau 
256763d483cdSSepherosa Ziehau 	status = ixgbe_read_i2c_byte_generic(hw, byte_offset, dev_addr, data);
256863d483cdSSepherosa Ziehau 
256963d483cdSSepherosa Ziehau release_i2c_access:
257063d483cdSSepherosa Ziehau 
257163d483cdSSepherosa Ziehau 	if (hw->phy.qsfp_shared_i2c_bus == TRUE) {
257263d483cdSSepherosa Ziehau 		/* Release I2C bus ownership. */
257363d483cdSSepherosa Ziehau 		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
257463d483cdSSepherosa Ziehau 		esdp &= ~IXGBE_ESDP_SDP0;
257563d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
257663d483cdSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
257763d483cdSSepherosa Ziehau 	}
257863d483cdSSepherosa Ziehau 
257963d483cdSSepherosa Ziehau 	return status;
258063d483cdSSepherosa Ziehau }
258163d483cdSSepherosa Ziehau 
258263d483cdSSepherosa Ziehau /**
258363d483cdSSepherosa Ziehau  *  ixgbe_write_i2c_byte_82599 - Writes 8 bit word over I2C
258463d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
258563d483cdSSepherosa Ziehau  *  @byte_offset: byte offset to write
2586*dd5ce676SSepherosa Ziehau  *  @dev_addr: address to read from
258763d483cdSSepherosa Ziehau  *  @data: value to write
258863d483cdSSepherosa Ziehau  *
258963d483cdSSepherosa Ziehau  *  Performs byte write operation to SFP module's EEPROM over I2C interface at
259063d483cdSSepherosa Ziehau  *  a specified device address.
259163d483cdSSepherosa Ziehau  **/
ixgbe_write_i2c_byte_82599(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 data)259263d483cdSSepherosa Ziehau static s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
259363d483cdSSepherosa Ziehau 				 u8 dev_addr, u8 data)
259463d483cdSSepherosa Ziehau {
259563d483cdSSepherosa Ziehau 	u32 esdp;
259663d483cdSSepherosa Ziehau 	s32 status;
259763d483cdSSepherosa Ziehau 	s32 timeout = 200;
259863d483cdSSepherosa Ziehau 
259963d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_i2c_byte_82599");
260063d483cdSSepherosa Ziehau 
260163d483cdSSepherosa Ziehau 	if (hw->phy.qsfp_shared_i2c_bus == TRUE) {
260263d483cdSSepherosa Ziehau 		/* Acquire I2C bus ownership. */
260363d483cdSSepherosa Ziehau 		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
260463d483cdSSepherosa Ziehau 		esdp |= IXGBE_ESDP_SDP0;
260563d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
260663d483cdSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
260763d483cdSSepherosa Ziehau 
260863d483cdSSepherosa Ziehau 		while (timeout) {
260963d483cdSSepherosa Ziehau 			esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
261063d483cdSSepherosa Ziehau 			if (esdp & IXGBE_ESDP_SDP1)
261163d483cdSSepherosa Ziehau 				break;
261263d483cdSSepherosa Ziehau 
261363d483cdSSepherosa Ziehau 			msec_delay(5);
261463d483cdSSepherosa Ziehau 			timeout--;
261563d483cdSSepherosa Ziehau 		}
261663d483cdSSepherosa Ziehau 
261763d483cdSSepherosa Ziehau 		if (!timeout) {
261863d483cdSSepherosa Ziehau 			DEBUGOUT("Driver can't access resource,"
261963d483cdSSepherosa Ziehau 				 " acquiring I2C bus timeout.\n");
262063d483cdSSepherosa Ziehau 			status = IXGBE_ERR_I2C;
262163d483cdSSepherosa Ziehau 			goto release_i2c_access;
262263d483cdSSepherosa Ziehau 		}
262363d483cdSSepherosa Ziehau 	}
262463d483cdSSepherosa Ziehau 
262563d483cdSSepherosa Ziehau 	status = ixgbe_write_i2c_byte_generic(hw, byte_offset, dev_addr, data);
262663d483cdSSepherosa Ziehau 
262763d483cdSSepherosa Ziehau release_i2c_access:
262863d483cdSSepherosa Ziehau 
262963d483cdSSepherosa Ziehau 	if (hw->phy.qsfp_shared_i2c_bus == TRUE) {
263063d483cdSSepherosa Ziehau 		/* Release I2C bus ownership. */
263163d483cdSSepherosa Ziehau 		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
263263d483cdSSepherosa Ziehau 		esdp &= ~IXGBE_ESDP_SDP0;
263363d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
263463d483cdSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
263563d483cdSSepherosa Ziehau 	}
263663d483cdSSepherosa Ziehau 
263763d483cdSSepherosa Ziehau 	return status;
263863d483cdSSepherosa Ziehau }
2639