xref: /dragonfly/sys/dev/netif/ix/ixgbe_x550.c (revision dd5ce676)
163d483cdSSepherosa Ziehau /******************************************************************************
263d483cdSSepherosa Ziehau 
36150453fSSepherosa Ziehau   Copyright (c) 2001-2017, Intel Corporation
463d483cdSSepherosa Ziehau   All rights reserved.
563d483cdSSepherosa Ziehau 
663d483cdSSepherosa Ziehau   Redistribution and use in source and binary forms, with or without
763d483cdSSepherosa Ziehau   modification, are permitted provided that the following conditions are met:
863d483cdSSepherosa Ziehau 
963d483cdSSepherosa Ziehau    1. Redistributions of source code must retain the above copyright notice,
1063d483cdSSepherosa Ziehau       this list of conditions and the following disclaimer.
1163d483cdSSepherosa Ziehau 
1263d483cdSSepherosa Ziehau    2. Redistributions in binary form must reproduce the above copyright
1363d483cdSSepherosa Ziehau       notice, this list of conditions and the following disclaimer in the
1463d483cdSSepherosa Ziehau       documentation and/or other materials provided with the distribution.
1563d483cdSSepherosa Ziehau 
1663d483cdSSepherosa Ziehau    3. Neither the name of the Intel Corporation nor the names of its
1763d483cdSSepherosa Ziehau       contributors may be used to endorse or promote products derived from
1863d483cdSSepherosa Ziehau       this software without specific prior written permission.
1963d483cdSSepherosa Ziehau 
2063d483cdSSepherosa Ziehau   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2163d483cdSSepherosa Ziehau   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2263d483cdSSepherosa Ziehau   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2363d483cdSSepherosa Ziehau   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2463d483cdSSepherosa Ziehau   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2563d483cdSSepherosa Ziehau   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2663d483cdSSepherosa Ziehau   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2763d483cdSSepherosa Ziehau   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2863d483cdSSepherosa Ziehau   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2963d483cdSSepherosa Ziehau   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3063d483cdSSepherosa Ziehau   POSSIBILITY OF SUCH DAMAGE.
3163d483cdSSepherosa Ziehau 
3263d483cdSSepherosa Ziehau ******************************************************************************/
3363d483cdSSepherosa Ziehau /*$FreeBSD$*/
3463d483cdSSepherosa Ziehau 
3563d483cdSSepherosa Ziehau #include "ixgbe_x550.h"
3663d483cdSSepherosa Ziehau #include "ixgbe_x540.h"
3763d483cdSSepherosa Ziehau #include "ixgbe_type.h"
3863d483cdSSepherosa Ziehau #include "ixgbe_api.h"
3963d483cdSSepherosa Ziehau #include "ixgbe_common.h"
4063d483cdSSepherosa Ziehau #include "ixgbe_phy.h"
4163d483cdSSepherosa Ziehau 
4263d483cdSSepherosa Ziehau static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed);
436150453fSSepherosa Ziehau static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
446150453fSSepherosa Ziehau static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
456150453fSSepherosa Ziehau static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw);
4663d483cdSSepherosa Ziehau 
4763d483cdSSepherosa Ziehau /**
4863d483cdSSepherosa Ziehau  *  ixgbe_init_ops_X550 - Inits func ptrs and MAC type
4963d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
5063d483cdSSepherosa Ziehau  *
5163d483cdSSepherosa Ziehau  *  Initialize the function pointers and assign the MAC type for X550.
5263d483cdSSepherosa Ziehau  *  Does not touch the hardware.
5363d483cdSSepherosa Ziehau  **/
ixgbe_init_ops_X550(struct ixgbe_hw * hw)5463d483cdSSepherosa Ziehau s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw)
5563d483cdSSepherosa Ziehau {
5663d483cdSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
5763d483cdSSepherosa Ziehau 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
5863d483cdSSepherosa Ziehau 	s32 ret_val;
5963d483cdSSepherosa Ziehau 
6063d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_ops_X550");
6163d483cdSSepherosa Ziehau 
6263d483cdSSepherosa Ziehau 	ret_val = ixgbe_init_ops_X540(hw);
6363d483cdSSepherosa Ziehau 	mac->ops.dmac_config = ixgbe_dmac_config_X550;
6463d483cdSSepherosa Ziehau 	mac->ops.dmac_config_tcs = ixgbe_dmac_config_tcs_X550;
6563d483cdSSepherosa Ziehau 	mac->ops.dmac_update_tcs = ixgbe_dmac_update_tcs_X550;
666150453fSSepherosa Ziehau 	mac->ops.setup_eee = NULL;
6763d483cdSSepherosa Ziehau 	mac->ops.set_source_address_pruning =
6863d483cdSSepherosa Ziehau 			ixgbe_set_source_address_pruning_X550;
6963d483cdSSepherosa Ziehau 	mac->ops.set_ethertype_anti_spoofing =
7063d483cdSSepherosa Ziehau 			ixgbe_set_ethertype_anti_spoofing_X550;
7163d483cdSSepherosa Ziehau 
7263d483cdSSepherosa Ziehau 	mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic;
7363d483cdSSepherosa Ziehau 	eeprom->ops.init_params = ixgbe_init_eeprom_params_X550;
7463d483cdSSepherosa Ziehau 	eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
7563d483cdSSepherosa Ziehau 	eeprom->ops.read = ixgbe_read_ee_hostif_X550;
7663d483cdSSepherosa Ziehau 	eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
7763d483cdSSepherosa Ziehau 	eeprom->ops.write = ixgbe_write_ee_hostif_X550;
7863d483cdSSepherosa Ziehau 	eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
7963d483cdSSepherosa Ziehau 	eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
8063d483cdSSepherosa Ziehau 	eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
8163d483cdSSepherosa Ziehau 
8263d483cdSSepherosa Ziehau 	mac->ops.disable_mdd = ixgbe_disable_mdd_X550;
8363d483cdSSepherosa Ziehau 	mac->ops.enable_mdd = ixgbe_enable_mdd_X550;
8463d483cdSSepherosa Ziehau 	mac->ops.mdd_event = ixgbe_mdd_event_X550;
8563d483cdSSepherosa Ziehau 	mac->ops.restore_mdd_vf = ixgbe_restore_mdd_vf_X550;
86*dd5ce676SSepherosa Ziehau 	mac->ops.fw_recovery_mode = ixgbe_fw_recovery_mode_X550;
8763d483cdSSepherosa Ziehau 	mac->ops.disable_rx = ixgbe_disable_rx_x550;
886150453fSSepherosa Ziehau 	/* Manageability interface */
896150453fSSepherosa Ziehau 	mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_x550;
906150453fSSepherosa Ziehau 	switch (hw->device_id) {
916150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_1G_T:
926150453fSSepherosa Ziehau 		hw->mac.ops.led_on = NULL;
936150453fSSepherosa Ziehau 		hw->mac.ops.led_off = NULL;
946150453fSSepherosa Ziehau 		break;
956150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_10G_T:
966150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_10G_T:
976150453fSSepherosa Ziehau 		hw->mac.ops.led_on = ixgbe_led_on_t_X550em;
986150453fSSepherosa Ziehau 		hw->mac.ops.led_off = ixgbe_led_off_t_X550em;
996150453fSSepherosa Ziehau 		break;
1006150453fSSepherosa Ziehau 	default:
1016150453fSSepherosa Ziehau 		break;
1026150453fSSepherosa Ziehau 	}
10363d483cdSSepherosa Ziehau 	return ret_val;
10463d483cdSSepherosa Ziehau }
10563d483cdSSepherosa Ziehau 
10663d483cdSSepherosa Ziehau /**
10763d483cdSSepherosa Ziehau  * ixgbe_read_cs4227 - Read CS4227 register
10863d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
10963d483cdSSepherosa Ziehau  * @reg: register number to write
11063d483cdSSepherosa Ziehau  * @value: pointer to receive value read
11163d483cdSSepherosa Ziehau  *
11263d483cdSSepherosa Ziehau  * Returns status code
11363d483cdSSepherosa Ziehau  **/
ixgbe_read_cs4227(struct ixgbe_hw * hw,u16 reg,u16 * value)11463d483cdSSepherosa Ziehau static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
11563d483cdSSepherosa Ziehau {
1166150453fSSepherosa Ziehau 	return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value);
11763d483cdSSepherosa Ziehau }
11863d483cdSSepherosa Ziehau 
11963d483cdSSepherosa Ziehau /**
12063d483cdSSepherosa Ziehau  * ixgbe_write_cs4227 - Write CS4227 register
12163d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
12263d483cdSSepherosa Ziehau  * @reg: register number to write
12363d483cdSSepherosa Ziehau  * @value: value to write to register
12463d483cdSSepherosa Ziehau  *
12563d483cdSSepherosa Ziehau  * Returns status code
12663d483cdSSepherosa Ziehau  **/
ixgbe_write_cs4227(struct ixgbe_hw * hw,u16 reg,u16 value)12763d483cdSSepherosa Ziehau static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
12863d483cdSSepherosa Ziehau {
1296150453fSSepherosa Ziehau 	return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value);
13063d483cdSSepherosa Ziehau }
13163d483cdSSepherosa Ziehau 
13263d483cdSSepherosa Ziehau /**
13363d483cdSSepherosa Ziehau  * ixgbe_read_pe - Read register from port expander
13463d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
13563d483cdSSepherosa Ziehau  * @reg: register number to read
13663d483cdSSepherosa Ziehau  * @value: pointer to receive read value
13763d483cdSSepherosa Ziehau  *
13863d483cdSSepherosa Ziehau  * Returns status code
13963d483cdSSepherosa Ziehau  **/
ixgbe_read_pe(struct ixgbe_hw * hw,u8 reg,u8 * value)14063d483cdSSepherosa Ziehau static s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
14163d483cdSSepherosa Ziehau {
14263d483cdSSepherosa Ziehau 	s32 status;
14363d483cdSSepherosa Ziehau 
14463d483cdSSepherosa Ziehau 	status = ixgbe_read_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
14563d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
14663d483cdSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_CAUTION,
14763d483cdSSepherosa Ziehau 			      "port expander access failed with %d\n", status);
14863d483cdSSepherosa Ziehau 	return status;
14963d483cdSSepherosa Ziehau }
15063d483cdSSepherosa Ziehau 
15163d483cdSSepherosa Ziehau /**
15263d483cdSSepherosa Ziehau  * ixgbe_write_pe - Write register to port expander
15363d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
15463d483cdSSepherosa Ziehau  * @reg: register number to write
15563d483cdSSepherosa Ziehau  * @value: value to write
15663d483cdSSepherosa Ziehau  *
15763d483cdSSepherosa Ziehau  * Returns status code
15863d483cdSSepherosa Ziehau  **/
ixgbe_write_pe(struct ixgbe_hw * hw,u8 reg,u8 value)15963d483cdSSepherosa Ziehau static s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
16063d483cdSSepherosa Ziehau {
16163d483cdSSepherosa Ziehau 	s32 status;
16263d483cdSSepherosa Ziehau 
16363d483cdSSepherosa Ziehau 	status = ixgbe_write_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
16463d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
16563d483cdSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_CAUTION,
16663d483cdSSepherosa Ziehau 			      "port expander access failed with %d\n", status);
16763d483cdSSepherosa Ziehau 	return status;
16863d483cdSSepherosa Ziehau }
16963d483cdSSepherosa Ziehau 
17063d483cdSSepherosa Ziehau /**
17163d483cdSSepherosa Ziehau  * ixgbe_reset_cs4227 - Reset CS4227 using port expander
17263d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
17363d483cdSSepherosa Ziehau  *
1746150453fSSepherosa Ziehau  * This function assumes that the caller has acquired the proper semaphore.
17563d483cdSSepherosa Ziehau  * Returns error code
17663d483cdSSepherosa Ziehau  **/
ixgbe_reset_cs4227(struct ixgbe_hw * hw)17763d483cdSSepherosa Ziehau static s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
17863d483cdSSepherosa Ziehau {
17963d483cdSSepherosa Ziehau 	s32 status;
1806150453fSSepherosa Ziehau 	u32 retry;
1816150453fSSepherosa Ziehau 	u16 value;
18263d483cdSSepherosa Ziehau 	u8 reg;
18363d483cdSSepherosa Ziehau 
1846150453fSSepherosa Ziehau 	/* Trigger hard reset. */
18563d483cdSSepherosa Ziehau 	status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
18663d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
18763d483cdSSepherosa Ziehau 		return status;
18863d483cdSSepherosa Ziehau 	reg |= IXGBE_PE_BIT1;
18963d483cdSSepherosa Ziehau 	status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
19063d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
19163d483cdSSepherosa Ziehau 		return status;
19263d483cdSSepherosa Ziehau 
19363d483cdSSepherosa Ziehau 	status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, &reg);
19463d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
19563d483cdSSepherosa Ziehau 		return status;
19663d483cdSSepherosa Ziehau 	reg &= ~IXGBE_PE_BIT1;
19763d483cdSSepherosa Ziehau 	status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
19863d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
19963d483cdSSepherosa Ziehau 		return status;
20063d483cdSSepherosa Ziehau 
20163d483cdSSepherosa Ziehau 	status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
20263d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
20363d483cdSSepherosa Ziehau 		return status;
20463d483cdSSepherosa Ziehau 	reg &= ~IXGBE_PE_BIT1;
20563d483cdSSepherosa Ziehau 	status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
20663d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
20763d483cdSSepherosa Ziehau 		return status;
20863d483cdSSepherosa Ziehau 
20963d483cdSSepherosa Ziehau 	usec_delay(IXGBE_CS4227_RESET_HOLD);
21063d483cdSSepherosa Ziehau 
21163d483cdSSepherosa Ziehau 	status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
21263d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
21363d483cdSSepherosa Ziehau 		return status;
21463d483cdSSepherosa Ziehau 	reg |= IXGBE_PE_BIT1;
21563d483cdSSepherosa Ziehau 	status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
21663d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
21763d483cdSSepherosa Ziehau 		return status;
21863d483cdSSepherosa Ziehau 
2196150453fSSepherosa Ziehau 	/* Wait for the reset to complete. */
22063d483cdSSepherosa Ziehau 	msec_delay(IXGBE_CS4227_RESET_DELAY);
2216150453fSSepherosa Ziehau 	for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
2226150453fSSepherosa Ziehau 		status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
2236150453fSSepherosa Ziehau 					   &value);
2246150453fSSepherosa Ziehau 		if (status == IXGBE_SUCCESS &&
2256150453fSSepherosa Ziehau 		    value == IXGBE_CS4227_EEPROM_LOAD_OK)
2266150453fSSepherosa Ziehau 			break;
2276150453fSSepherosa Ziehau 		msec_delay(IXGBE_CS4227_CHECK_DELAY);
2286150453fSSepherosa Ziehau 	}
2296150453fSSepherosa Ziehau 	if (retry == IXGBE_CS4227_RETRIES) {
2306150453fSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
2316150453fSSepherosa Ziehau 			"CS4227 reset did not complete.");
2326150453fSSepherosa Ziehau 		return IXGBE_ERR_PHY;
2336150453fSSepherosa Ziehau 	}
2346150453fSSepherosa Ziehau 
2356150453fSSepherosa Ziehau 	status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
2366150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS ||
2376150453fSSepherosa Ziehau 	    !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
2386150453fSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
2396150453fSSepherosa Ziehau 			"CS4227 EEPROM did not load successfully.");
2406150453fSSepherosa Ziehau 		return IXGBE_ERR_PHY;
2416150453fSSepherosa Ziehau 	}
24263d483cdSSepherosa Ziehau 
24363d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
24463d483cdSSepherosa Ziehau }
24563d483cdSSepherosa Ziehau 
24663d483cdSSepherosa Ziehau /**
24763d483cdSSepherosa Ziehau  * ixgbe_check_cs4227 - Check CS4227 and reset as needed
24863d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
24963d483cdSSepherosa Ziehau  **/
ixgbe_check_cs4227(struct ixgbe_hw * hw)25063d483cdSSepherosa Ziehau static void ixgbe_check_cs4227(struct ixgbe_hw *hw)
25163d483cdSSepherosa Ziehau {
2526150453fSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
25363d483cdSSepherosa Ziehau 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
2546150453fSSepherosa Ziehau 	u16 value = 0;
25563d483cdSSepherosa Ziehau 	u8 retry;
25663d483cdSSepherosa Ziehau 
25763d483cdSSepherosa Ziehau 	for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
25863d483cdSSepherosa Ziehau 		status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
25963d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS) {
26063d483cdSSepherosa Ziehau 			ERROR_REPORT2(IXGBE_ERROR_CAUTION,
2616150453fSSepherosa Ziehau 				"semaphore failed with %d", status);
2626150453fSSepherosa Ziehau 			msec_delay(IXGBE_CS4227_CHECK_DELAY);
2636150453fSSepherosa Ziehau 			continue;
26463d483cdSSepherosa Ziehau 		}
2656150453fSSepherosa Ziehau 
2666150453fSSepherosa Ziehau 		/* Get status of reset flow. */
2676150453fSSepherosa Ziehau 		status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
2686150453fSSepherosa Ziehau 
2696150453fSSepherosa Ziehau 		if (status == IXGBE_SUCCESS &&
2706150453fSSepherosa Ziehau 		    value == IXGBE_CS4227_RESET_COMPLETE)
2716150453fSSepherosa Ziehau 			goto out;
2726150453fSSepherosa Ziehau 
2736150453fSSepherosa Ziehau 		if (status != IXGBE_SUCCESS ||
2746150453fSSepherosa Ziehau 		    value != IXGBE_CS4227_RESET_PENDING)
2756150453fSSepherosa Ziehau 			break;
2766150453fSSepherosa Ziehau 
2776150453fSSepherosa Ziehau 		/* Reset is pending. Wait and check again. */
27863d483cdSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2796150453fSSepherosa Ziehau 		msec_delay(IXGBE_CS4227_CHECK_DELAY);
28063d483cdSSepherosa Ziehau 	}
2816150453fSSepherosa Ziehau 
2826150453fSSepherosa Ziehau 	/* If still pending, assume other instance failed. */
2836150453fSSepherosa Ziehau 	if (retry == IXGBE_CS4227_RETRIES) {
2846150453fSSepherosa Ziehau 		status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
2856150453fSSepherosa Ziehau 		if (status != IXGBE_SUCCESS) {
28663d483cdSSepherosa Ziehau 			ERROR_REPORT2(IXGBE_ERROR_CAUTION,
2876150453fSSepherosa Ziehau 				      "semaphore failed with %d", status);
2886150453fSSepherosa Ziehau 			return;
2896150453fSSepherosa Ziehau 		}
2906150453fSSepherosa Ziehau 	}
2916150453fSSepherosa Ziehau 
2926150453fSSepherosa Ziehau 	/* Reset the CS4227. */
2936150453fSSepherosa Ziehau 	status = ixgbe_reset_cs4227(hw);
2946150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS) {
2956150453fSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
2966150453fSSepherosa Ziehau 			"CS4227 reset failed: %d", status);
2976150453fSSepherosa Ziehau 		goto out;
2986150453fSSepherosa Ziehau 	}
2996150453fSSepherosa Ziehau 
3006150453fSSepherosa Ziehau 	/* Reset takes so long, temporarily release semaphore in case the
3016150453fSSepherosa Ziehau 	 * other driver instance is waiting for the reset indication.
3026150453fSSepherosa Ziehau 	 */
3036150453fSSepherosa Ziehau 	ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
3046150453fSSepherosa Ziehau 			   IXGBE_CS4227_RESET_PENDING);
3056150453fSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
3066150453fSSepherosa Ziehau 	msec_delay(10);
3076150453fSSepherosa Ziehau 	status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
3086150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS) {
3096150453fSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_CAUTION,
3106150453fSSepherosa Ziehau 			"semaphore failed with %d", status);
3116150453fSSepherosa Ziehau 		return;
3126150453fSSepherosa Ziehau 	}
3136150453fSSepherosa Ziehau 
3146150453fSSepherosa Ziehau 	/* Record completion for next time. */
3156150453fSSepherosa Ziehau 	status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
3166150453fSSepherosa Ziehau 		IXGBE_CS4227_RESET_COMPLETE);
3176150453fSSepherosa Ziehau 
3186150453fSSepherosa Ziehau out:
3196150453fSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
3206150453fSSepherosa Ziehau 	msec_delay(hw->eeprom.semaphore_delay);
32163d483cdSSepherosa Ziehau }
32263d483cdSSepherosa Ziehau 
32363d483cdSSepherosa Ziehau /**
32463d483cdSSepherosa Ziehau  * ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
32563d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
32663d483cdSSepherosa Ziehau  **/
ixgbe_setup_mux_ctl(struct ixgbe_hw * hw)32763d483cdSSepherosa Ziehau static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
32863d483cdSSepherosa Ziehau {
32963d483cdSSepherosa Ziehau 	u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
33063d483cdSSepherosa Ziehau 
33163d483cdSSepherosa Ziehau 	if (hw->bus.lan_id) {
33263d483cdSSepherosa Ziehau 		esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
33363d483cdSSepherosa Ziehau 		esdp |= IXGBE_ESDP_SDP1_DIR;
33463d483cdSSepherosa Ziehau 	}
33563d483cdSSepherosa Ziehau 	esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
33663d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
33763d483cdSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
33863d483cdSSepherosa Ziehau }
33963d483cdSSepherosa Ziehau 
34063d483cdSSepherosa Ziehau /**
34163d483cdSSepherosa Ziehau  * ixgbe_identify_phy_x550em - Get PHY type based on device id
34263d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
34363d483cdSSepherosa Ziehau  *
34463d483cdSSepherosa Ziehau  * Returns error code
34563d483cdSSepherosa Ziehau  */
ixgbe_identify_phy_x550em(struct ixgbe_hw * hw)34663d483cdSSepherosa Ziehau static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
34763d483cdSSepherosa Ziehau {
3486150453fSSepherosa Ziehau 	hw->mac.ops.set_lan_id(hw);
3496150453fSSepherosa Ziehau 
3506150453fSSepherosa Ziehau 	ixgbe_read_mng_if_sel_x550em(hw);
3516150453fSSepherosa Ziehau 
35263d483cdSSepherosa Ziehau 	switch (hw->device_id) {
3536150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_SFP:
354*dd5ce676SSepherosa Ziehau 		return ixgbe_identify_sfp_module_X550em(hw);
35563d483cdSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_SFP:
35663d483cdSSepherosa Ziehau 		/* set up for CS4227 usage */
35763d483cdSSepherosa Ziehau 		ixgbe_setup_mux_ctl(hw);
35863d483cdSSepherosa Ziehau 		ixgbe_check_cs4227(hw);
3596150453fSSepherosa Ziehau 		/* Fallthrough */
36063d483cdSSepherosa Ziehau 
3616150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_SFP_N:
362*dd5ce676SSepherosa Ziehau 		return ixgbe_identify_sfp_module_X550em(hw);
36363d483cdSSepherosa Ziehau 		break;
36463d483cdSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_KX4:
36563d483cdSSepherosa Ziehau 		hw->phy.type = ixgbe_phy_x550em_kx4;
36663d483cdSSepherosa Ziehau 		break;
3676150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_XFI:
3686150453fSSepherosa Ziehau 		hw->phy.type = ixgbe_phy_x550em_xfi;
3696150453fSSepherosa Ziehau 		break;
37063d483cdSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_KR:
3716150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_KR:
3726150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_KR_L:
37363d483cdSSepherosa Ziehau 		hw->phy.type = ixgbe_phy_x550em_kr;
37463d483cdSSepherosa Ziehau 		break;
3756150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_10G_T:
37663d483cdSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_10G_T:
37763d483cdSSepherosa Ziehau 		return ixgbe_identify_phy_generic(hw);
3786150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_1G_T:
3796150453fSSepherosa Ziehau 		hw->phy.type = ixgbe_phy_ext_1g_t;
3806150453fSSepherosa Ziehau 		break;
3816150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T:
3826150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
3836150453fSSepherosa Ziehau 		hw->phy.type = ixgbe_phy_fw;
3846150453fSSepherosa Ziehau 		if (hw->bus.lan_id)
3856150453fSSepherosa Ziehau 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
3866150453fSSepherosa Ziehau 		else
3876150453fSSepherosa Ziehau 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
3886150453fSSepherosa Ziehau 		break;
38963d483cdSSepherosa Ziehau 	default:
39063d483cdSSepherosa Ziehau 		break;
39163d483cdSSepherosa Ziehau 	}
39263d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
39363d483cdSSepherosa Ziehau }
39463d483cdSSepherosa Ziehau 
3956150453fSSepherosa Ziehau /**
3966150453fSSepherosa Ziehau  * ixgbe_fw_phy_activity - Perform an activity on a PHY
3976150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
3986150453fSSepherosa Ziehau  * @activity: activity to perform
3996150453fSSepherosa Ziehau  * @data: Pointer to 4 32-bit words of data
4006150453fSSepherosa Ziehau  */
ixgbe_fw_phy_activity(struct ixgbe_hw * hw,u16 activity,u32 (* data)[FW_PHY_ACT_DATA_COUNT])4016150453fSSepherosa Ziehau s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity,
4026150453fSSepherosa Ziehau 			  u32 (*data)[FW_PHY_ACT_DATA_COUNT])
4036150453fSSepherosa Ziehau {
4046150453fSSepherosa Ziehau 	union {
4056150453fSSepherosa Ziehau 		struct ixgbe_hic_phy_activity_req cmd;
4066150453fSSepherosa Ziehau 		struct ixgbe_hic_phy_activity_resp rsp;
4076150453fSSepherosa Ziehau 	} hic;
4086150453fSSepherosa Ziehau 	u16 retries = FW_PHY_ACT_RETRIES;
4096150453fSSepherosa Ziehau 	s32 rc;
4106150453fSSepherosa Ziehau 	u16 i;
4116150453fSSepherosa Ziehau 
4126150453fSSepherosa Ziehau 	do {
4136150453fSSepherosa Ziehau 		memset(&hic, 0, sizeof(hic));
4146150453fSSepherosa Ziehau 		hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD;
4156150453fSSepherosa Ziehau 		hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN;
4166150453fSSepherosa Ziehau 		hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
4176150453fSSepherosa Ziehau 		hic.cmd.port_number = hw->bus.lan_id;
4186150453fSSepherosa Ziehau 		hic.cmd.activity_id = IXGBE_CPU_TO_LE16(activity);
4196150453fSSepherosa Ziehau 		for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
4206150453fSSepherosa Ziehau 			hic.cmd.data[i] = IXGBE_CPU_TO_BE32((*data)[i]);
4216150453fSSepherosa Ziehau 
4226150453fSSepherosa Ziehau 		rc = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd,
4236150453fSSepherosa Ziehau 						  sizeof(hic.cmd),
4246150453fSSepherosa Ziehau 						  IXGBE_HI_COMMAND_TIMEOUT,
4256150453fSSepherosa Ziehau 						  TRUE);
4266150453fSSepherosa Ziehau 		if (rc != IXGBE_SUCCESS)
4276150453fSSepherosa Ziehau 			return rc;
4286150453fSSepherosa Ziehau 		if (hic.rsp.hdr.cmd_or_resp.ret_status ==
4296150453fSSepherosa Ziehau 		    FW_CEM_RESP_STATUS_SUCCESS) {
4306150453fSSepherosa Ziehau 			for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
4316150453fSSepherosa Ziehau 				(*data)[i] = IXGBE_BE32_TO_CPU(hic.rsp.data[i]);
4326150453fSSepherosa Ziehau 			return IXGBE_SUCCESS;
4336150453fSSepherosa Ziehau 		}
4346150453fSSepherosa Ziehau 		usec_delay(20);
4356150453fSSepherosa Ziehau 		--retries;
4366150453fSSepherosa Ziehau 	} while (retries > 0);
4376150453fSSepherosa Ziehau 
4386150453fSSepherosa Ziehau 	return IXGBE_ERR_HOST_INTERFACE_COMMAND;
4396150453fSSepherosa Ziehau }
4406150453fSSepherosa Ziehau 
4416150453fSSepherosa Ziehau static const struct {
4426150453fSSepherosa Ziehau 	u16 fw_speed;
4436150453fSSepherosa Ziehau 	ixgbe_link_speed phy_speed;
4446150453fSSepherosa Ziehau } ixgbe_fw_map[] = {
4456150453fSSepherosa Ziehau 	{ FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL },
4466150453fSSepherosa Ziehau 	{ FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL },
4476150453fSSepherosa Ziehau 	{ FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL },
4486150453fSSepherosa Ziehau 	{ FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL },
4496150453fSSepherosa Ziehau 	{ FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL },
4506150453fSSepherosa Ziehau 	{ FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL },
4516150453fSSepherosa Ziehau };
4526150453fSSepherosa Ziehau 
4536150453fSSepherosa Ziehau /**
4546150453fSSepherosa Ziehau  * ixgbe_get_phy_id_fw - Get the phy ID via firmware command
4556150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
4566150453fSSepherosa Ziehau  *
4576150453fSSepherosa Ziehau  * Returns error code
4586150453fSSepherosa Ziehau  */
ixgbe_get_phy_id_fw(struct ixgbe_hw * hw)4596150453fSSepherosa Ziehau static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw)
4606150453fSSepherosa Ziehau {
4616150453fSSepherosa Ziehau 	u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
4626150453fSSepherosa Ziehau 	u16 phy_speeds;
4636150453fSSepherosa Ziehau 	u16 phy_id_lo;
4646150453fSSepherosa Ziehau 	s32 rc;
4656150453fSSepherosa Ziehau 	u16 i;
4666150453fSSepherosa Ziehau 
4676150453fSSepherosa Ziehau 	rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info);
4686150453fSSepherosa Ziehau 	if (rc)
4696150453fSSepherosa Ziehau 		return rc;
4706150453fSSepherosa Ziehau 
4716150453fSSepherosa Ziehau 	hw->phy.speeds_supported = 0;
4726150453fSSepherosa Ziehau 	phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK;
4736150453fSSepherosa Ziehau 	for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
4746150453fSSepherosa Ziehau 		if (phy_speeds & ixgbe_fw_map[i].fw_speed)
4756150453fSSepherosa Ziehau 			hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed;
4766150453fSSepherosa Ziehau 	}
4776150453fSSepherosa Ziehau 	if (!hw->phy.autoneg_advertised)
4786150453fSSepherosa Ziehau 		hw->phy.autoneg_advertised = hw->phy.speeds_supported;
4796150453fSSepherosa Ziehau 
4806150453fSSepherosa Ziehau 	hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK;
4816150453fSSepherosa Ziehau 	phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK;
4826150453fSSepherosa Ziehau 	hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK;
4836150453fSSepherosa Ziehau 	hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK;
4846150453fSSepherosa Ziehau 	if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK)
4856150453fSSepherosa Ziehau 		return IXGBE_ERR_PHY_ADDR_INVALID;
4866150453fSSepherosa Ziehau 	return IXGBE_SUCCESS;
4876150453fSSepherosa Ziehau }
4886150453fSSepherosa Ziehau 
4896150453fSSepherosa Ziehau /**
4906150453fSSepherosa Ziehau  * ixgbe_identify_phy_fw - Get PHY type based on firmware command
4916150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
4926150453fSSepherosa Ziehau  *
4936150453fSSepherosa Ziehau  * Returns error code
4946150453fSSepherosa Ziehau  */
ixgbe_identify_phy_fw(struct ixgbe_hw * hw)4956150453fSSepherosa Ziehau static s32 ixgbe_identify_phy_fw(struct ixgbe_hw *hw)
4966150453fSSepherosa Ziehau {
4976150453fSSepherosa Ziehau 	if (hw->bus.lan_id)
4986150453fSSepherosa Ziehau 		hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
4996150453fSSepherosa Ziehau 	else
5006150453fSSepherosa Ziehau 		hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
5016150453fSSepherosa Ziehau 
5026150453fSSepherosa Ziehau 	hw->phy.type = ixgbe_phy_fw;
5036150453fSSepherosa Ziehau 	hw->phy.ops.read_reg = NULL;
5046150453fSSepherosa Ziehau 	hw->phy.ops.write_reg = NULL;
5056150453fSSepherosa Ziehau 	return ixgbe_get_phy_id_fw(hw);
5066150453fSSepherosa Ziehau }
5076150453fSSepherosa Ziehau 
5086150453fSSepherosa Ziehau /**
5096150453fSSepherosa Ziehau  * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY
5106150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
5116150453fSSepherosa Ziehau  *
5126150453fSSepherosa Ziehau  * Returns error code
5136150453fSSepherosa Ziehau  */
ixgbe_shutdown_fw_phy(struct ixgbe_hw * hw)5146150453fSSepherosa Ziehau s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw)
5156150453fSSepherosa Ziehau {
5166150453fSSepherosa Ziehau 	u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
5176150453fSSepherosa Ziehau 
5186150453fSSepherosa Ziehau 	setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF;
5196150453fSSepherosa Ziehau 	return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup);
5206150453fSSepherosa Ziehau }
5216150453fSSepherosa Ziehau 
ixgbe_read_phy_reg_x550em(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 * phy_data)52263d483cdSSepherosa Ziehau static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
52363d483cdSSepherosa Ziehau 				     u32 device_type, u16 *phy_data)
52463d483cdSSepherosa Ziehau {
52563d483cdSSepherosa Ziehau 	UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, *phy_data);
52663d483cdSSepherosa Ziehau 	return IXGBE_NOT_IMPLEMENTED;
52763d483cdSSepherosa Ziehau }
52863d483cdSSepherosa Ziehau 
ixgbe_write_phy_reg_x550em(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 phy_data)52963d483cdSSepherosa Ziehau static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
53063d483cdSSepherosa Ziehau 				      u32 device_type, u16 phy_data)
53163d483cdSSepherosa Ziehau {
53263d483cdSSepherosa Ziehau 	UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, phy_data);
53363d483cdSSepherosa Ziehau 	return IXGBE_NOT_IMPLEMENTED;
53463d483cdSSepherosa Ziehau }
53563d483cdSSepherosa Ziehau 
53663d483cdSSepherosa Ziehau /**
5376150453fSSepherosa Ziehau  * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
5386150453fSSepherosa Ziehau  * @hw: pointer to the hardware structure
5396150453fSSepherosa Ziehau  * @addr: I2C bus address to read from
5406150453fSSepherosa Ziehau  * @reg: I2C device register to read from
5416150453fSSepherosa Ziehau  * @val: pointer to location to receive read value
5426150453fSSepherosa Ziehau  *
5436150453fSSepherosa Ziehau  * Returns an error code on error.
5446150453fSSepherosa Ziehau  **/
ixgbe_read_i2c_combined_generic(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 * val)5456150453fSSepherosa Ziehau static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
5466150453fSSepherosa Ziehau 					   u16 reg, u16 *val)
5476150453fSSepherosa Ziehau {
5486150453fSSepherosa Ziehau 	return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
5496150453fSSepherosa Ziehau }
5506150453fSSepherosa Ziehau 
5516150453fSSepherosa Ziehau /**
5526150453fSSepherosa Ziehau  * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation
5536150453fSSepherosa Ziehau  * @hw: pointer to the hardware structure
5546150453fSSepherosa Ziehau  * @addr: I2C bus address to read from
5556150453fSSepherosa Ziehau  * @reg: I2C device register to read from
5566150453fSSepherosa Ziehau  * @val: pointer to location to receive read value
5576150453fSSepherosa Ziehau  *
5586150453fSSepherosa Ziehau  * Returns an error code on error.
5596150453fSSepherosa Ziehau  **/
5606150453fSSepherosa Ziehau static s32
ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 * val)5616150453fSSepherosa Ziehau ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
5626150453fSSepherosa Ziehau 					 u16 reg, u16 *val)
5636150453fSSepherosa Ziehau {
5646150453fSSepherosa Ziehau 	return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
5656150453fSSepherosa Ziehau }
5666150453fSSepherosa Ziehau 
5676150453fSSepherosa Ziehau /**
5686150453fSSepherosa Ziehau  * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
5696150453fSSepherosa Ziehau  * @hw: pointer to the hardware structure
5706150453fSSepherosa Ziehau  * @addr: I2C bus address to write to
5716150453fSSepherosa Ziehau  * @reg: I2C device register to write to
5726150453fSSepherosa Ziehau  * @val: value to write
5736150453fSSepherosa Ziehau  *
5746150453fSSepherosa Ziehau  * Returns an error code on error.
5756150453fSSepherosa Ziehau  **/
ixgbe_write_i2c_combined_generic(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 val)5766150453fSSepherosa Ziehau static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
5776150453fSSepherosa Ziehau 					    u8 addr, u16 reg, u16 val)
5786150453fSSepherosa Ziehau {
5796150453fSSepherosa Ziehau 	return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
5806150453fSSepherosa Ziehau }
5816150453fSSepherosa Ziehau 
5826150453fSSepherosa Ziehau /**
5836150453fSSepherosa Ziehau  * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation
5846150453fSSepherosa Ziehau  * @hw: pointer to the hardware structure
5856150453fSSepherosa Ziehau  * @addr: I2C bus address to write to
5866150453fSSepherosa Ziehau  * @reg: I2C device register to write to
5876150453fSSepherosa Ziehau  * @val: value to write
5886150453fSSepherosa Ziehau  *
5896150453fSSepherosa Ziehau  * Returns an error code on error.
5906150453fSSepherosa Ziehau  **/
5916150453fSSepherosa Ziehau static s32
ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 val)5926150453fSSepherosa Ziehau ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw,
5936150453fSSepherosa Ziehau 					  u8 addr, u16 reg, u16 val)
5946150453fSSepherosa Ziehau {
5956150453fSSepherosa Ziehau 	return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
5966150453fSSepherosa Ziehau }
5976150453fSSepherosa Ziehau 
5986150453fSSepherosa Ziehau /**
59963d483cdSSepherosa Ziehau *  ixgbe_init_ops_X550EM - Inits func ptrs and MAC type
60063d483cdSSepherosa Ziehau *  @hw: pointer to hardware structure
60163d483cdSSepherosa Ziehau *
60263d483cdSSepherosa Ziehau *  Initialize the function pointers and for MAC type X550EM.
60363d483cdSSepherosa Ziehau *  Does not touch the hardware.
60463d483cdSSepherosa Ziehau **/
ixgbe_init_ops_X550EM(struct ixgbe_hw * hw)60563d483cdSSepherosa Ziehau s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
60663d483cdSSepherosa Ziehau {
60763d483cdSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
60863d483cdSSepherosa Ziehau 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
60963d483cdSSepherosa Ziehau 	struct ixgbe_phy_info *phy = &hw->phy;
61063d483cdSSepherosa Ziehau 	s32 ret_val;
61163d483cdSSepherosa Ziehau 
61263d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_ops_X550EM");
61363d483cdSSepherosa Ziehau 
61463d483cdSSepherosa Ziehau 	/* Similar to X550 so start there. */
61563d483cdSSepherosa Ziehau 	ret_val = ixgbe_init_ops_X550(hw);
61663d483cdSSepherosa Ziehau 
61763d483cdSSepherosa Ziehau 	/* Since this function eventually calls
61863d483cdSSepherosa Ziehau 	 * ixgbe_init_ops_540 by design, we are setting
61963d483cdSSepherosa Ziehau 	 * the pointers to NULL explicitly here to overwrite
62063d483cdSSepherosa Ziehau 	 * the values being set in the x540 function.
62163d483cdSSepherosa Ziehau 	 */
62263d483cdSSepherosa Ziehau 
6236150453fSSepherosa Ziehau 	/* Bypass not supported in x550EM */
6246150453fSSepherosa Ziehau 	mac->ops.bypass_rw = NULL;
6256150453fSSepherosa Ziehau 	mac->ops.bypass_valid_rd = NULL;
6266150453fSSepherosa Ziehau 	mac->ops.bypass_set = NULL;
6276150453fSSepherosa Ziehau 	mac->ops.bypass_rd_eep = NULL;
6286150453fSSepherosa Ziehau 
62963d483cdSSepherosa Ziehau 	/* FCOE not supported in x550EM */
63063d483cdSSepherosa Ziehau 	mac->ops.get_san_mac_addr = NULL;
63163d483cdSSepherosa Ziehau 	mac->ops.set_san_mac_addr = NULL;
63263d483cdSSepherosa Ziehau 	mac->ops.get_wwn_prefix = NULL;
63363d483cdSSepherosa Ziehau 	mac->ops.get_fcoe_boot_status = NULL;
63463d483cdSSepherosa Ziehau 
63563d483cdSSepherosa Ziehau 	/* IPsec not supported in x550EM */
63663d483cdSSepherosa Ziehau 	mac->ops.disable_sec_rx_path = NULL;
63763d483cdSSepherosa Ziehau 	mac->ops.enable_sec_rx_path = NULL;
63863d483cdSSepherosa Ziehau 
63963d483cdSSepherosa Ziehau 	/* AUTOC register is not present in x550EM. */
64063d483cdSSepherosa Ziehau 	mac->ops.prot_autoc_read = NULL;
64163d483cdSSepherosa Ziehau 	mac->ops.prot_autoc_write = NULL;
64263d483cdSSepherosa Ziehau 
64363d483cdSSepherosa Ziehau 	/* X550EM bus type is internal*/
64463d483cdSSepherosa Ziehau 	hw->bus.type = ixgbe_bus_type_internal;
64563d483cdSSepherosa Ziehau 	mac->ops.get_bus_info = ixgbe_get_bus_info_X550em;
64663d483cdSSepherosa Ziehau 
6476150453fSSepherosa Ziehau 
64863d483cdSSepherosa Ziehau 	mac->ops.get_media_type = ixgbe_get_media_type_X550em;
64963d483cdSSepherosa Ziehau 	mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em;
65063d483cdSSepherosa Ziehau 	mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_X550em;
65163d483cdSSepherosa Ziehau 	mac->ops.reset_hw = ixgbe_reset_hw_X550em;
65263d483cdSSepherosa Ziehau 	mac->ops.get_supported_physical_layer =
65363d483cdSSepherosa Ziehau 				    ixgbe_get_supported_physical_layer_X550em;
65463d483cdSSepherosa Ziehau 
65563d483cdSSepherosa Ziehau 	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper)
65663d483cdSSepherosa Ziehau 		mac->ops.setup_fc = ixgbe_setup_fc_generic;
65763d483cdSSepherosa Ziehau 	else
65863d483cdSSepherosa Ziehau 		mac->ops.setup_fc = ixgbe_setup_fc_X550em;
65963d483cdSSepherosa Ziehau 
66063d483cdSSepherosa Ziehau 	/* PHY */
66163d483cdSSepherosa Ziehau 	phy->ops.init = ixgbe_init_phy_ops_X550em;
6626150453fSSepherosa Ziehau 	switch (hw->device_id) {
6636150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T:
6646150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
6656150453fSSepherosa Ziehau 		mac->ops.setup_fc = NULL;
6666150453fSSepherosa Ziehau 		phy->ops.identify = ixgbe_identify_phy_fw;
6676150453fSSepherosa Ziehau 		phy->ops.set_phy_power = NULL;
6686150453fSSepherosa Ziehau 		phy->ops.get_firmware_version = NULL;
6696150453fSSepherosa Ziehau 		break;
6706150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_1G_T:
6716150453fSSepherosa Ziehau 		mac->ops.setup_fc = NULL;
67263d483cdSSepherosa Ziehau 		phy->ops.identify = ixgbe_identify_phy_x550em;
6736150453fSSepherosa Ziehau 		phy->ops.set_phy_power = NULL;
6746150453fSSepherosa Ziehau 		break;
6756150453fSSepherosa Ziehau 	default:
6766150453fSSepherosa Ziehau 		phy->ops.identify = ixgbe_identify_phy_x550em;
6776150453fSSepherosa Ziehau 	}
6786150453fSSepherosa Ziehau 
67963d483cdSSepherosa Ziehau 	if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
68063d483cdSSepherosa Ziehau 		phy->ops.set_phy_power = NULL;
68163d483cdSSepherosa Ziehau 
68263d483cdSSepherosa Ziehau 
68363d483cdSSepherosa Ziehau 	/* EEPROM */
68463d483cdSSepherosa Ziehau 	eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
68563d483cdSSepherosa Ziehau 	eeprom->ops.read = ixgbe_read_ee_hostif_X550;
68663d483cdSSepherosa Ziehau 	eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
68763d483cdSSepherosa Ziehau 	eeprom->ops.write = ixgbe_write_ee_hostif_X550;
68863d483cdSSepherosa Ziehau 	eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
68963d483cdSSepherosa Ziehau 	eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
69063d483cdSSepherosa Ziehau 	eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
69163d483cdSSepherosa Ziehau 	eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
69263d483cdSSepherosa Ziehau 
69363d483cdSSepherosa Ziehau 	return ret_val;
69463d483cdSSepherosa Ziehau }
69563d483cdSSepherosa Ziehau 
69663d483cdSSepherosa Ziehau /**
6976150453fSSepherosa Ziehau  * ixgbe_setup_fw_link - Setup firmware-controlled PHYs
6986150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
6996150453fSSepherosa Ziehau  */
ixgbe_setup_fw_link(struct ixgbe_hw * hw)7006150453fSSepherosa Ziehau static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw)
7016150453fSSepherosa Ziehau {
7026150453fSSepherosa Ziehau 	u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
7036150453fSSepherosa Ziehau 	s32 rc;
7046150453fSSepherosa Ziehau 	u16 i;
7056150453fSSepherosa Ziehau 
7066150453fSSepherosa Ziehau 	if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
7076150453fSSepherosa Ziehau 		return 0;
7086150453fSSepherosa Ziehau 
7096150453fSSepherosa Ziehau 	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
7106150453fSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
7116150453fSSepherosa Ziehau 			      "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
7126150453fSSepherosa Ziehau 		return IXGBE_ERR_INVALID_LINK_SETTINGS;
7136150453fSSepherosa Ziehau 	}
7146150453fSSepherosa Ziehau 
7156150453fSSepherosa Ziehau 	switch (hw->fc.requested_mode) {
7166150453fSSepherosa Ziehau 	case ixgbe_fc_full:
7176150453fSSepherosa Ziehau 		setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX <<
7186150453fSSepherosa Ziehau 			    FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
7196150453fSSepherosa Ziehau 		break;
7206150453fSSepherosa Ziehau 	case ixgbe_fc_rx_pause:
7216150453fSSepherosa Ziehau 		setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX <<
7226150453fSSepherosa Ziehau 			    FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
7236150453fSSepherosa Ziehau 		break;
7246150453fSSepherosa Ziehau 	case ixgbe_fc_tx_pause:
7256150453fSSepherosa Ziehau 		setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX <<
7266150453fSSepherosa Ziehau 			    FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
7276150453fSSepherosa Ziehau 		break;
7286150453fSSepherosa Ziehau 	default:
7296150453fSSepherosa Ziehau 		break;
7306150453fSSepherosa Ziehau 	}
7316150453fSSepherosa Ziehau 
7326150453fSSepherosa Ziehau 	for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
7336150453fSSepherosa Ziehau 		if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed)
7346150453fSSepherosa Ziehau 			setup[0] |= ixgbe_fw_map[i].fw_speed;
7356150453fSSepherosa Ziehau 	}
7366150453fSSepherosa Ziehau 	setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN;
7376150453fSSepherosa Ziehau 
7386150453fSSepherosa Ziehau 	if (hw->phy.eee_speeds_advertised)
7396150453fSSepherosa Ziehau 		setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE;
7406150453fSSepherosa Ziehau 
7416150453fSSepherosa Ziehau 	rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup);
7426150453fSSepherosa Ziehau 	if (rc)
7436150453fSSepherosa Ziehau 		return rc;
7446150453fSSepherosa Ziehau 	if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)
7456150453fSSepherosa Ziehau 		return IXGBE_ERR_OVERTEMP;
7466150453fSSepherosa Ziehau 	return IXGBE_SUCCESS;
7476150453fSSepherosa Ziehau }
7486150453fSSepherosa Ziehau 
7496150453fSSepherosa Ziehau /**
7506150453fSSepherosa Ziehau  * ixgbe_fc_autoneg_fw _ Set up flow control for FW-controlled PHYs
7516150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
7526150453fSSepherosa Ziehau  *
7536150453fSSepherosa Ziehau  *  Called at init time to set up flow control.
7546150453fSSepherosa Ziehau  */
ixgbe_fc_autoneg_fw(struct ixgbe_hw * hw)7556150453fSSepherosa Ziehau static s32 ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw)
7566150453fSSepherosa Ziehau {
7576150453fSSepherosa Ziehau 	if (hw->fc.requested_mode == ixgbe_fc_default)
7586150453fSSepherosa Ziehau 		hw->fc.requested_mode = ixgbe_fc_full;
7596150453fSSepherosa Ziehau 
7606150453fSSepherosa Ziehau 	return ixgbe_setup_fw_link(hw);
7616150453fSSepherosa Ziehau }
7626150453fSSepherosa Ziehau 
7636150453fSSepherosa Ziehau /**
7646150453fSSepherosa Ziehau  * ixgbe_setup_eee_fw - Enable/disable EEE support
7656150453fSSepherosa Ziehau  * @hw: pointer to the HW structure
7666150453fSSepherosa Ziehau  * @enable_eee: boolean flag to enable EEE
7676150453fSSepherosa Ziehau  *
7686150453fSSepherosa Ziehau  * Enable/disable EEE based on enable_eee flag.
7696150453fSSepherosa Ziehau  * This function controls EEE for firmware-based PHY implementations.
7706150453fSSepherosa Ziehau  */
ixgbe_setup_eee_fw(struct ixgbe_hw * hw,bool enable_eee)7716150453fSSepherosa Ziehau static s32 ixgbe_setup_eee_fw(struct ixgbe_hw *hw, bool enable_eee)
7726150453fSSepherosa Ziehau {
7736150453fSSepherosa Ziehau 	if (!!hw->phy.eee_speeds_advertised == enable_eee)
7746150453fSSepherosa Ziehau 		return IXGBE_SUCCESS;
7756150453fSSepherosa Ziehau 	if (enable_eee)
7766150453fSSepherosa Ziehau 		hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
7776150453fSSepherosa Ziehau 	else
7786150453fSSepherosa Ziehau 		hw->phy.eee_speeds_advertised = 0;
7796150453fSSepherosa Ziehau 	return hw->phy.ops.setup_link(hw);
7806150453fSSepherosa Ziehau }
7816150453fSSepherosa Ziehau 
7826150453fSSepherosa Ziehau /**
7836150453fSSepherosa Ziehau *  ixgbe_init_ops_X550EM_a - Inits func ptrs and MAC type
7846150453fSSepherosa Ziehau *  @hw: pointer to hardware structure
7856150453fSSepherosa Ziehau *
7866150453fSSepherosa Ziehau *  Initialize the function pointers and for MAC type X550EM_a.
7876150453fSSepherosa Ziehau *  Does not touch the hardware.
7886150453fSSepherosa Ziehau **/
ixgbe_init_ops_X550EM_a(struct ixgbe_hw * hw)7896150453fSSepherosa Ziehau s32 ixgbe_init_ops_X550EM_a(struct ixgbe_hw *hw)
7906150453fSSepherosa Ziehau {
7916150453fSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
7926150453fSSepherosa Ziehau 	s32 ret_val;
7936150453fSSepherosa Ziehau 
7946150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_ops_X550EM_a");
7956150453fSSepherosa Ziehau 
7966150453fSSepherosa Ziehau 	/* Start with generic X550EM init */
7976150453fSSepherosa Ziehau 	ret_val = ixgbe_init_ops_X550EM(hw);
7986150453fSSepherosa Ziehau 
7996150453fSSepherosa Ziehau 	if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
8006150453fSSepherosa Ziehau 	    hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) {
8016150453fSSepherosa Ziehau 		mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
8026150453fSSepherosa Ziehau 		mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
8036150453fSSepherosa Ziehau 	} else {
8046150453fSSepherosa Ziehau 		mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a;
8056150453fSSepherosa Ziehau 		mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a;
8066150453fSSepherosa Ziehau 	}
8076150453fSSepherosa Ziehau 	mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550a;
8086150453fSSepherosa Ziehau 	mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550a;
8096150453fSSepherosa Ziehau 
8106150453fSSepherosa Ziehau 	switch (mac->ops.get_media_type(hw)) {
8116150453fSSepherosa Ziehau 	case ixgbe_media_type_fiber:
8126150453fSSepherosa Ziehau 		mac->ops.setup_fc = NULL;
8136150453fSSepherosa Ziehau 		mac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a;
8146150453fSSepherosa Ziehau 		break;
8156150453fSSepherosa Ziehau 	case ixgbe_media_type_backplane:
8166150453fSSepherosa Ziehau 		mac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a;
8176150453fSSepherosa Ziehau 		mac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a;
8186150453fSSepherosa Ziehau 		break;
8196150453fSSepherosa Ziehau 	default:
8206150453fSSepherosa Ziehau 		break;
8216150453fSSepherosa Ziehau 	}
8226150453fSSepherosa Ziehau 
8236150453fSSepherosa Ziehau 	switch (hw->device_id) {
8246150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T:
8256150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
8266150453fSSepherosa Ziehau 		mac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a;
8276150453fSSepherosa Ziehau 		mac->ops.setup_fc = ixgbe_fc_autoneg_fw;
8286150453fSSepherosa Ziehau 		mac->ops.setup_eee = ixgbe_setup_eee_fw;
8296150453fSSepherosa Ziehau 		hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL |
8306150453fSSepherosa Ziehau 					       IXGBE_LINK_SPEED_1GB_FULL;
8316150453fSSepherosa Ziehau 		hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
8326150453fSSepherosa Ziehau 		break;
8336150453fSSepherosa Ziehau 	default:
8346150453fSSepherosa Ziehau 		break;
8356150453fSSepherosa Ziehau 	}
8366150453fSSepherosa Ziehau 
8376150453fSSepherosa Ziehau 	return ret_val;
8386150453fSSepherosa Ziehau }
8396150453fSSepherosa Ziehau 
8406150453fSSepherosa Ziehau /**
8416150453fSSepherosa Ziehau *  ixgbe_init_ops_X550EM_x - Inits func ptrs and MAC type
8426150453fSSepherosa Ziehau *  @hw: pointer to hardware structure
8436150453fSSepherosa Ziehau *
8446150453fSSepherosa Ziehau *  Initialize the function pointers and for MAC type X550EM_x.
8456150453fSSepherosa Ziehau *  Does not touch the hardware.
8466150453fSSepherosa Ziehau **/
ixgbe_init_ops_X550EM_x(struct ixgbe_hw * hw)8476150453fSSepherosa Ziehau s32 ixgbe_init_ops_X550EM_x(struct ixgbe_hw *hw)
8486150453fSSepherosa Ziehau {
8496150453fSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
8506150453fSSepherosa Ziehau 	struct ixgbe_link_info *link = &hw->link;
8516150453fSSepherosa Ziehau 	s32 ret_val;
8526150453fSSepherosa Ziehau 
8536150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_ops_X550EM_x");
8546150453fSSepherosa Ziehau 
8556150453fSSepherosa Ziehau 	/* Start with generic X550EM init */
8566150453fSSepherosa Ziehau 	ret_val = ixgbe_init_ops_X550EM(hw);
8576150453fSSepherosa Ziehau 
8586150453fSSepherosa Ziehau 	mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
8596150453fSSepherosa Ziehau 	mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
8606150453fSSepherosa Ziehau 	mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em;
8616150453fSSepherosa Ziehau 	mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em;
8626150453fSSepherosa Ziehau 	link->ops.read_link = ixgbe_read_i2c_combined_generic;
8636150453fSSepherosa Ziehau 	link->ops.read_link_unlocked = ixgbe_read_i2c_combined_generic_unlocked;
8646150453fSSepherosa Ziehau 	link->ops.write_link = ixgbe_write_i2c_combined_generic;
8656150453fSSepherosa Ziehau 	link->ops.write_link_unlocked =
8666150453fSSepherosa Ziehau 				      ixgbe_write_i2c_combined_generic_unlocked;
8676150453fSSepherosa Ziehau 	link->addr = IXGBE_CS4227;
8686150453fSSepherosa Ziehau 
8696150453fSSepherosa Ziehau 	if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) {
8706150453fSSepherosa Ziehau 		mac->ops.setup_fc = NULL;
8716150453fSSepherosa Ziehau 		mac->ops.setup_eee = NULL;
8726150453fSSepherosa Ziehau 		mac->ops.init_led_link_act = NULL;
8736150453fSSepherosa Ziehau 	}
8746150453fSSepherosa Ziehau 
8756150453fSSepherosa Ziehau 	return ret_val;
8766150453fSSepherosa Ziehau }
8776150453fSSepherosa Ziehau 
8786150453fSSepherosa Ziehau /**
87963d483cdSSepherosa Ziehau  *  ixgbe_dmac_config_X550
88063d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
88163d483cdSSepherosa Ziehau  *
88263d483cdSSepherosa Ziehau  *  Configure DMA coalescing. If enabling dmac, dmac is activated.
88363d483cdSSepherosa Ziehau  *  When disabling dmac, dmac enable dmac bit is cleared.
88463d483cdSSepherosa Ziehau  **/
ixgbe_dmac_config_X550(struct ixgbe_hw * hw)88563d483cdSSepherosa Ziehau s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw)
88663d483cdSSepherosa Ziehau {
88763d483cdSSepherosa Ziehau 	u32 reg, high_pri_tc;
88863d483cdSSepherosa Ziehau 
88963d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_dmac_config_X550");
89063d483cdSSepherosa Ziehau 
89163d483cdSSepherosa Ziehau 	/* Disable DMA coalescing before configuring */
89263d483cdSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
89363d483cdSSepherosa Ziehau 	reg &= ~IXGBE_DMACR_DMAC_EN;
89463d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
89563d483cdSSepherosa Ziehau 
89663d483cdSSepherosa Ziehau 	/* Disable DMA Coalescing if the watchdog timer is 0 */
89763d483cdSSepherosa Ziehau 	if (!hw->mac.dmac_config.watchdog_timer)
89863d483cdSSepherosa Ziehau 		goto out;
89963d483cdSSepherosa Ziehau 
90063d483cdSSepherosa Ziehau 	ixgbe_dmac_config_tcs_X550(hw);
90163d483cdSSepherosa Ziehau 
90263d483cdSSepherosa Ziehau 	/* Configure DMA Coalescing Control Register */
90363d483cdSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
90463d483cdSSepherosa Ziehau 
90563d483cdSSepherosa Ziehau 	/* Set the watchdog timer in units of 40.96 usec */
90663d483cdSSepherosa Ziehau 	reg &= ~IXGBE_DMACR_DMACWT_MASK;
90763d483cdSSepherosa Ziehau 	reg |= (hw->mac.dmac_config.watchdog_timer * 100) / 4096;
90863d483cdSSepherosa Ziehau 
90963d483cdSSepherosa Ziehau 	reg &= ~IXGBE_DMACR_HIGH_PRI_TC_MASK;
91063d483cdSSepherosa Ziehau 	/* If fcoe is enabled, set high priority traffic class */
91163d483cdSSepherosa Ziehau 	if (hw->mac.dmac_config.fcoe_en) {
91263d483cdSSepherosa Ziehau 		high_pri_tc = 1 << hw->mac.dmac_config.fcoe_tc;
91363d483cdSSepherosa Ziehau 		reg |= ((high_pri_tc << IXGBE_DMACR_HIGH_PRI_TC_SHIFT) &
91463d483cdSSepherosa Ziehau 			IXGBE_DMACR_HIGH_PRI_TC_MASK);
91563d483cdSSepherosa Ziehau 	}
91663d483cdSSepherosa Ziehau 	reg |= IXGBE_DMACR_EN_MNG_IND;
91763d483cdSSepherosa Ziehau 
91863d483cdSSepherosa Ziehau 	/* Enable DMA coalescing after configuration */
91963d483cdSSepherosa Ziehau 	reg |= IXGBE_DMACR_DMAC_EN;
92063d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
92163d483cdSSepherosa Ziehau 
92263d483cdSSepherosa Ziehau out:
92363d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
92463d483cdSSepherosa Ziehau }
92563d483cdSSepherosa Ziehau 
92663d483cdSSepherosa Ziehau /**
92763d483cdSSepherosa Ziehau  *  ixgbe_dmac_config_tcs_X550
92863d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
92963d483cdSSepherosa Ziehau  *
93063d483cdSSepherosa Ziehau  *  Configure DMA coalescing threshold per TC. The dmac enable bit must
93163d483cdSSepherosa Ziehau  *  be cleared before configuring.
93263d483cdSSepherosa Ziehau  **/
ixgbe_dmac_config_tcs_X550(struct ixgbe_hw * hw)93363d483cdSSepherosa Ziehau s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw)
93463d483cdSSepherosa Ziehau {
93563d483cdSSepherosa Ziehau 	u32 tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb;
93663d483cdSSepherosa Ziehau 
93763d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_dmac_config_tcs_X550");
93863d483cdSSepherosa Ziehau 
93963d483cdSSepherosa Ziehau 	/* Configure DMA coalescing enabled */
94063d483cdSSepherosa Ziehau 	switch (hw->mac.dmac_config.link_speed) {
9416150453fSSepherosa Ziehau 	case IXGBE_LINK_SPEED_10_FULL:
94263d483cdSSepherosa Ziehau 	case IXGBE_LINK_SPEED_100_FULL:
94363d483cdSSepherosa Ziehau 		pb_headroom = IXGBE_DMACRXT_100M;
94463d483cdSSepherosa Ziehau 		break;
94563d483cdSSepherosa Ziehau 	case IXGBE_LINK_SPEED_1GB_FULL:
94663d483cdSSepherosa Ziehau 		pb_headroom = IXGBE_DMACRXT_1G;
94763d483cdSSepherosa Ziehau 		break;
94863d483cdSSepherosa Ziehau 	default:
94963d483cdSSepherosa Ziehau 		pb_headroom = IXGBE_DMACRXT_10G;
95063d483cdSSepherosa Ziehau 		break;
95163d483cdSSepherosa Ziehau 	}
95263d483cdSSepherosa Ziehau 
95363d483cdSSepherosa Ziehau 	maxframe_size_kb = ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >>
95463d483cdSSepherosa Ziehau 			     IXGBE_MHADD_MFS_SHIFT) / 1024);
95563d483cdSSepherosa Ziehau 
95663d483cdSSepherosa Ziehau 	/* Set the per Rx packet buffer receive threshold */
95763d483cdSSepherosa Ziehau 	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) {
95863d483cdSSepherosa Ziehau 		reg = IXGBE_READ_REG(hw, IXGBE_DMCTH(tc));
95963d483cdSSepherosa Ziehau 		reg &= ~IXGBE_DMCTH_DMACRXT_MASK;
96063d483cdSSepherosa Ziehau 
96163d483cdSSepherosa Ziehau 		if (tc < hw->mac.dmac_config.num_tcs) {
96263d483cdSSepherosa Ziehau 			/* Get Rx PB size */
96363d483cdSSepherosa Ziehau 			rx_pb_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc));
96463d483cdSSepherosa Ziehau 			rx_pb_size = (rx_pb_size & IXGBE_RXPBSIZE_MASK) >>
96563d483cdSSepherosa Ziehau 				IXGBE_RXPBSIZE_SHIFT;
96663d483cdSSepherosa Ziehau 
96763d483cdSSepherosa Ziehau 			/* Calculate receive buffer threshold in kilobytes */
96863d483cdSSepherosa Ziehau 			if (rx_pb_size > pb_headroom)
96963d483cdSSepherosa Ziehau 				rx_pb_size = rx_pb_size - pb_headroom;
97063d483cdSSepherosa Ziehau 			else
97163d483cdSSepherosa Ziehau 				rx_pb_size = 0;
97263d483cdSSepherosa Ziehau 
97363d483cdSSepherosa Ziehau 			/* Minimum of MFS shall be set for DMCTH */
97463d483cdSSepherosa Ziehau 			reg |= (rx_pb_size > maxframe_size_kb) ?
97563d483cdSSepherosa Ziehau 				rx_pb_size : maxframe_size_kb;
97663d483cdSSepherosa Ziehau 		}
97763d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg);
97863d483cdSSepherosa Ziehau 	}
97963d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
98063d483cdSSepherosa Ziehau }
98163d483cdSSepherosa Ziehau 
98263d483cdSSepherosa Ziehau /**
98363d483cdSSepherosa Ziehau  *  ixgbe_dmac_update_tcs_X550
98463d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
98563d483cdSSepherosa Ziehau  *
98663d483cdSSepherosa Ziehau  *  Disables dmac, updates per TC settings, and then enables dmac.
98763d483cdSSepherosa Ziehau  **/
ixgbe_dmac_update_tcs_X550(struct ixgbe_hw * hw)98863d483cdSSepherosa Ziehau s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw)
98963d483cdSSepherosa Ziehau {
99063d483cdSSepherosa Ziehau 	u32 reg;
99163d483cdSSepherosa Ziehau 
99263d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_dmac_update_tcs_X550");
99363d483cdSSepherosa Ziehau 
99463d483cdSSepherosa Ziehau 	/* Disable DMA coalescing before configuring */
99563d483cdSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
99663d483cdSSepherosa Ziehau 	reg &= ~IXGBE_DMACR_DMAC_EN;
99763d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
99863d483cdSSepherosa Ziehau 
99963d483cdSSepherosa Ziehau 	ixgbe_dmac_config_tcs_X550(hw);
100063d483cdSSepherosa Ziehau 
100163d483cdSSepherosa Ziehau 	/* Enable DMA coalescing after configuration */
100263d483cdSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
100363d483cdSSepherosa Ziehau 	reg |= IXGBE_DMACR_DMAC_EN;
100463d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
100563d483cdSSepherosa Ziehau 
100663d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
100763d483cdSSepherosa Ziehau }
100863d483cdSSepherosa Ziehau 
100963d483cdSSepherosa Ziehau /**
101063d483cdSSepherosa Ziehau  *  ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
101163d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
101263d483cdSSepherosa Ziehau  *
101363d483cdSSepherosa Ziehau  *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
101463d483cdSSepherosa Ziehau  *  ixgbe_hw struct in order to set up EEPROM access.
101563d483cdSSepherosa Ziehau  **/
ixgbe_init_eeprom_params_X550(struct ixgbe_hw * hw)101663d483cdSSepherosa Ziehau s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
101763d483cdSSepherosa Ziehau {
101863d483cdSSepherosa Ziehau 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
101963d483cdSSepherosa Ziehau 	u32 eec;
102063d483cdSSepherosa Ziehau 	u16 eeprom_size;
102163d483cdSSepherosa Ziehau 
102263d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_eeprom_params_X550");
102363d483cdSSepherosa Ziehau 
102463d483cdSSepherosa Ziehau 	if (eeprom->type == ixgbe_eeprom_uninitialized) {
102563d483cdSSepherosa Ziehau 		eeprom->semaphore_delay = 10;
102663d483cdSSepherosa Ziehau 		eeprom->type = ixgbe_flash;
102763d483cdSSepherosa Ziehau 
102863d483cdSSepherosa Ziehau 		eec = IXGBE_READ_REG(hw, IXGBE_EEC);
102963d483cdSSepherosa Ziehau 		eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
103063d483cdSSepherosa Ziehau 				    IXGBE_EEC_SIZE_SHIFT);
103163d483cdSSepherosa Ziehau 		eeprom->word_size = 1 << (eeprom_size +
103263d483cdSSepherosa Ziehau 					  IXGBE_EEPROM_WORD_SIZE_SHIFT);
103363d483cdSSepherosa Ziehau 
103463d483cdSSepherosa Ziehau 		DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
103563d483cdSSepherosa Ziehau 			  eeprom->type, eeprom->word_size);
103663d483cdSSepherosa Ziehau 	}
103763d483cdSSepherosa Ziehau 
103863d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
103963d483cdSSepherosa Ziehau }
104063d483cdSSepherosa Ziehau 
104163d483cdSSepherosa Ziehau /**
104263d483cdSSepherosa Ziehau  * ixgbe_set_source_address_pruning_X550 - Enable/Disbale source address pruning
104363d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
104463d483cdSSepherosa Ziehau  * @enable: enable or disable source address pruning
104563d483cdSSepherosa Ziehau  * @pool: Rx pool to set source address pruning for
104663d483cdSSepherosa Ziehau  **/
ixgbe_set_source_address_pruning_X550(struct ixgbe_hw * hw,bool enable,unsigned int pool)104763d483cdSSepherosa Ziehau void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
104863d483cdSSepherosa Ziehau 					   unsigned int pool)
104963d483cdSSepherosa Ziehau {
105063d483cdSSepherosa Ziehau 	u64 pfflp;
105163d483cdSSepherosa Ziehau 
105263d483cdSSepherosa Ziehau 	/* max rx pool is 63 */
105363d483cdSSepherosa Ziehau 	if (pool > 63)
105463d483cdSSepherosa Ziehau 		return;
105563d483cdSSepherosa Ziehau 
105663d483cdSSepherosa Ziehau 	pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
105763d483cdSSepherosa Ziehau 	pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
105863d483cdSSepherosa Ziehau 
105963d483cdSSepherosa Ziehau 	if (enable)
106063d483cdSSepherosa Ziehau 		pfflp |= (1ULL << pool);
106163d483cdSSepherosa Ziehau 	else
106263d483cdSSepherosa Ziehau 		pfflp &= ~(1ULL << pool);
106363d483cdSSepherosa Ziehau 
106463d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp);
106563d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
106663d483cdSSepherosa Ziehau }
106763d483cdSSepherosa Ziehau 
106863d483cdSSepherosa Ziehau /**
106963d483cdSSepherosa Ziehau  *  ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype anti-spoofing
107063d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
107163d483cdSSepherosa Ziehau  *  @enable: enable or disable switch for Ethertype anti-spoofing
107263d483cdSSepherosa Ziehau  *  @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing
107363d483cdSSepherosa Ziehau  *
107463d483cdSSepherosa Ziehau  **/
ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw * hw,bool enable,int vf)107563d483cdSSepherosa Ziehau void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
107663d483cdSSepherosa Ziehau 		bool enable, int vf)
107763d483cdSSepherosa Ziehau {
107863d483cdSSepherosa Ziehau 	int vf_target_reg = vf >> 3;
107963d483cdSSepherosa Ziehau 	int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT;
108063d483cdSSepherosa Ziehau 	u32 pfvfspoof;
108163d483cdSSepherosa Ziehau 
108263d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_ethertype_anti_spoofing_X550");
108363d483cdSSepherosa Ziehau 
108463d483cdSSepherosa Ziehau 	pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
108563d483cdSSepherosa Ziehau 	if (enable)
108663d483cdSSepherosa Ziehau 		pfvfspoof |= (1 << vf_target_shift);
108763d483cdSSepherosa Ziehau 	else
108863d483cdSSepherosa Ziehau 		pfvfspoof &= ~(1 << vf_target_shift);
108963d483cdSSepherosa Ziehau 
109063d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
109163d483cdSSepherosa Ziehau }
109263d483cdSSepherosa Ziehau 
109363d483cdSSepherosa Ziehau /**
109463d483cdSSepherosa Ziehau  * ixgbe_iosf_wait - Wait for IOSF command completion
109563d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
109663d483cdSSepherosa Ziehau  * @ctrl: pointer to location to receive final IOSF control value
109763d483cdSSepherosa Ziehau  *
109863d483cdSSepherosa Ziehau  * Returns failing status on timeout
109963d483cdSSepherosa Ziehau  *
110063d483cdSSepherosa Ziehau  * Note: ctrl can be NULL if the IOSF control register value is not needed
110163d483cdSSepherosa Ziehau  **/
ixgbe_iosf_wait(struct ixgbe_hw * hw,u32 * ctrl)110263d483cdSSepherosa Ziehau static s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl)
110363d483cdSSepherosa Ziehau {
11046150453fSSepherosa Ziehau 	u32 i, command = 0;
110563d483cdSSepherosa Ziehau 
110663d483cdSSepherosa Ziehau 	/* Check every 10 usec to see if the address cycle completed.
110763d483cdSSepherosa Ziehau 	 * The SB IOSF BUSY bit will clear when the operation is
110863d483cdSSepherosa Ziehau 	 * complete
110963d483cdSSepherosa Ziehau 	 */
111063d483cdSSepherosa Ziehau 	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
111163d483cdSSepherosa Ziehau 		command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
111263d483cdSSepherosa Ziehau 		if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
111363d483cdSSepherosa Ziehau 			break;
111463d483cdSSepherosa Ziehau 		usec_delay(10);
111563d483cdSSepherosa Ziehau 	}
111663d483cdSSepherosa Ziehau 	if (ctrl)
111763d483cdSSepherosa Ziehau 		*ctrl = command;
111863d483cdSSepherosa Ziehau 	if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
111963d483cdSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_POLLING, "Wait timed out\n");
112063d483cdSSepherosa Ziehau 		return IXGBE_ERR_PHY;
112163d483cdSSepherosa Ziehau 	}
112263d483cdSSepherosa Ziehau 
112363d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
112463d483cdSSepherosa Ziehau }
112563d483cdSSepherosa Ziehau 
112663d483cdSSepherosa Ziehau /**
11276150453fSSepherosa Ziehau  *  ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register
11286150453fSSepherosa Ziehau  *  of the IOSF device
112963d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
113063d483cdSSepherosa Ziehau  *  @reg_addr: 32 bit PHY register to write
113163d483cdSSepherosa Ziehau  *  @device_type: 3 bit device type
113263d483cdSSepherosa Ziehau  *  @data: Data to write to the register
113363d483cdSSepherosa Ziehau  **/
ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u32 data)113463d483cdSSepherosa Ziehau s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
113563d483cdSSepherosa Ziehau 			    u32 device_type, u32 data)
113663d483cdSSepherosa Ziehau {
113763d483cdSSepherosa Ziehau 	u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
113863d483cdSSepherosa Ziehau 	u32 command, error;
113963d483cdSSepherosa Ziehau 	s32 ret;
114063d483cdSSepherosa Ziehau 
114163d483cdSSepherosa Ziehau 	ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
114263d483cdSSepherosa Ziehau 	if (ret != IXGBE_SUCCESS)
114363d483cdSSepherosa Ziehau 		return ret;
114463d483cdSSepherosa Ziehau 
114563d483cdSSepherosa Ziehau 	ret = ixgbe_iosf_wait(hw, NULL);
114663d483cdSSepherosa Ziehau 	if (ret != IXGBE_SUCCESS)
114763d483cdSSepherosa Ziehau 		goto out;
114863d483cdSSepherosa Ziehau 
114963d483cdSSepherosa Ziehau 	command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
115063d483cdSSepherosa Ziehau 		   (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
115163d483cdSSepherosa Ziehau 
115263d483cdSSepherosa Ziehau 	/* Write IOSF control register */
115363d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
115463d483cdSSepherosa Ziehau 
115563d483cdSSepherosa Ziehau 	/* Write IOSF data register */
115663d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
115763d483cdSSepherosa Ziehau 
115863d483cdSSepherosa Ziehau 	ret = ixgbe_iosf_wait(hw, &command);
115963d483cdSSepherosa Ziehau 
116063d483cdSSepherosa Ziehau 	if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
116163d483cdSSepherosa Ziehau 		error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
116263d483cdSSepherosa Ziehau 			 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
116363d483cdSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
116463d483cdSSepherosa Ziehau 			      "Failed to write, error %x\n", error);
116563d483cdSSepherosa Ziehau 		ret = IXGBE_ERR_PHY;
116663d483cdSSepherosa Ziehau 	}
116763d483cdSSepherosa Ziehau 
116863d483cdSSepherosa Ziehau out:
116963d483cdSSepherosa Ziehau 	ixgbe_release_swfw_semaphore(hw, gssr);
117063d483cdSSepherosa Ziehau 	return ret;
117163d483cdSSepherosa Ziehau }
117263d483cdSSepherosa Ziehau 
117363d483cdSSepherosa Ziehau /**
11746150453fSSepherosa Ziehau  *  ixgbe_read_iosf_sb_reg_x550 - Reads specified register of the IOSF device
117563d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
117663d483cdSSepherosa Ziehau  *  @reg_addr: 32 bit PHY register to write
117763d483cdSSepherosa Ziehau  *  @device_type: 3 bit device type
11786150453fSSepherosa Ziehau  *  @data: Pointer to read data from the register
117963d483cdSSepherosa Ziehau  **/
ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u32 * data)118063d483cdSSepherosa Ziehau s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
118163d483cdSSepherosa Ziehau 			   u32 device_type, u32 *data)
118263d483cdSSepherosa Ziehau {
118363d483cdSSepherosa Ziehau 	u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
118463d483cdSSepherosa Ziehau 	u32 command, error;
118563d483cdSSepherosa Ziehau 	s32 ret;
118663d483cdSSepherosa Ziehau 
118763d483cdSSepherosa Ziehau 	ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
118863d483cdSSepherosa Ziehau 	if (ret != IXGBE_SUCCESS)
118963d483cdSSepherosa Ziehau 		return ret;
119063d483cdSSepherosa Ziehau 
119163d483cdSSepherosa Ziehau 	ret = ixgbe_iosf_wait(hw, NULL);
119263d483cdSSepherosa Ziehau 	if (ret != IXGBE_SUCCESS)
119363d483cdSSepherosa Ziehau 		goto out;
119463d483cdSSepherosa Ziehau 
119563d483cdSSepherosa Ziehau 	command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
119663d483cdSSepherosa Ziehau 		   (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
119763d483cdSSepherosa Ziehau 
119863d483cdSSepherosa Ziehau 	/* Write IOSF control register */
119963d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
120063d483cdSSepherosa Ziehau 
120163d483cdSSepherosa Ziehau 	ret = ixgbe_iosf_wait(hw, &command);
120263d483cdSSepherosa Ziehau 
120363d483cdSSepherosa Ziehau 	if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
120463d483cdSSepherosa Ziehau 		error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
120563d483cdSSepherosa Ziehau 			 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
120663d483cdSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
120763d483cdSSepherosa Ziehau 				"Failed to read, error %x\n", error);
120863d483cdSSepherosa Ziehau 		ret = IXGBE_ERR_PHY;
120963d483cdSSepherosa Ziehau 	}
121063d483cdSSepherosa Ziehau 
121163d483cdSSepherosa Ziehau 	if (ret == IXGBE_SUCCESS)
121263d483cdSSepherosa Ziehau 		*data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
121363d483cdSSepherosa Ziehau 
121463d483cdSSepherosa Ziehau out:
121563d483cdSSepherosa Ziehau 	ixgbe_release_swfw_semaphore(hw, gssr);
121663d483cdSSepherosa Ziehau 	return ret;
121763d483cdSSepherosa Ziehau }
121863d483cdSSepherosa Ziehau 
121963d483cdSSepherosa Ziehau /**
12206150453fSSepherosa Ziehau  * ixgbe_get_phy_token - Get the token for shared phy access
12216150453fSSepherosa Ziehau  * @hw: Pointer to hardware structure
12226150453fSSepherosa Ziehau  */
12236150453fSSepherosa Ziehau 
ixgbe_get_phy_token(struct ixgbe_hw * hw)12246150453fSSepherosa Ziehau s32 ixgbe_get_phy_token(struct ixgbe_hw *hw)
12256150453fSSepherosa Ziehau {
12266150453fSSepherosa Ziehau 	struct ixgbe_hic_phy_token_req token_cmd;
12276150453fSSepherosa Ziehau 	s32 status;
12286150453fSSepherosa Ziehau 
12296150453fSSepherosa Ziehau 	token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
12306150453fSSepherosa Ziehau 	token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
12316150453fSSepherosa Ziehau 	token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
12326150453fSSepherosa Ziehau 	token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
12336150453fSSepherosa Ziehau 	token_cmd.port_number = hw->bus.lan_id;
12346150453fSSepherosa Ziehau 	token_cmd.command_type = FW_PHY_TOKEN_REQ;
12356150453fSSepherosa Ziehau 	token_cmd.pad = 0;
12366150453fSSepherosa Ziehau 	status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd,
12376150453fSSepherosa Ziehau 					      sizeof(token_cmd),
12386150453fSSepherosa Ziehau 					      IXGBE_HI_COMMAND_TIMEOUT,
12396150453fSSepherosa Ziehau 					      TRUE);
12406150453fSSepherosa Ziehau 	if (status) {
12416150453fSSepherosa Ziehau 		DEBUGOUT1("Issuing host interface command failed with Status = %d\n",
12426150453fSSepherosa Ziehau 			  status);
12436150453fSSepherosa Ziehau 		return status;
12446150453fSSepherosa Ziehau 	}
12456150453fSSepherosa Ziehau 	if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
12466150453fSSepherosa Ziehau 		return IXGBE_SUCCESS;
12476150453fSSepherosa Ziehau 	if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY) {
12486150453fSSepherosa Ziehau 		DEBUGOUT1("Host interface command returned 0x%08x , returning IXGBE_ERR_FW_RESP_INVALID\n",
12496150453fSSepherosa Ziehau 			  token_cmd.hdr.cmd_or_resp.ret_status);
12506150453fSSepherosa Ziehau 		return IXGBE_ERR_FW_RESP_INVALID;
12516150453fSSepherosa Ziehau 	}
12526150453fSSepherosa Ziehau 
12536150453fSSepherosa Ziehau 	DEBUGOUT("Returning  IXGBE_ERR_TOKEN_RETRY\n");
12546150453fSSepherosa Ziehau 	return IXGBE_ERR_TOKEN_RETRY;
12556150453fSSepherosa Ziehau }
12566150453fSSepherosa Ziehau 
12576150453fSSepherosa Ziehau /**
12586150453fSSepherosa Ziehau  * ixgbe_put_phy_token - Put the token for shared phy access
12596150453fSSepherosa Ziehau  * @hw: Pointer to hardware structure
12606150453fSSepherosa Ziehau  */
12616150453fSSepherosa Ziehau 
ixgbe_put_phy_token(struct ixgbe_hw * hw)12626150453fSSepherosa Ziehau s32 ixgbe_put_phy_token(struct ixgbe_hw *hw)
12636150453fSSepherosa Ziehau {
12646150453fSSepherosa Ziehau 	struct ixgbe_hic_phy_token_req token_cmd;
12656150453fSSepherosa Ziehau 	s32 status;
12666150453fSSepherosa Ziehau 
12676150453fSSepherosa Ziehau 	token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
12686150453fSSepherosa Ziehau 	token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
12696150453fSSepherosa Ziehau 	token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
12706150453fSSepherosa Ziehau 	token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
12716150453fSSepherosa Ziehau 	token_cmd.port_number = hw->bus.lan_id;
12726150453fSSepherosa Ziehau 	token_cmd.command_type = FW_PHY_TOKEN_REL;
12736150453fSSepherosa Ziehau 	token_cmd.pad = 0;
12746150453fSSepherosa Ziehau 	status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd,
12756150453fSSepherosa Ziehau 					      sizeof(token_cmd),
12766150453fSSepherosa Ziehau 					      IXGBE_HI_COMMAND_TIMEOUT,
12776150453fSSepherosa Ziehau 					      TRUE);
12786150453fSSepherosa Ziehau 	if (status)
12796150453fSSepherosa Ziehau 		return status;
12806150453fSSepherosa Ziehau 	if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
12816150453fSSepherosa Ziehau 		return IXGBE_SUCCESS;
12826150453fSSepherosa Ziehau 
12836150453fSSepherosa Ziehau 	DEBUGOUT("Put PHY Token host interface command failed");
12846150453fSSepherosa Ziehau 	return IXGBE_ERR_FW_RESP_INVALID;
12856150453fSSepherosa Ziehau }
12866150453fSSepherosa Ziehau 
12876150453fSSepherosa Ziehau /**
12886150453fSSepherosa Ziehau  *  ixgbe_write_iosf_sb_reg_x550a - Writes a value to specified register
12896150453fSSepherosa Ziehau  *  of the IOSF device
12906150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
12916150453fSSepherosa Ziehau  *  @reg_addr: 32 bit PHY register to write
12926150453fSSepherosa Ziehau  *  @device_type: 3 bit device type
12936150453fSSepherosa Ziehau  *  @data: Data to write to the register
12946150453fSSepherosa Ziehau  **/
ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u32 data)12956150453fSSepherosa Ziehau s32 ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
12966150453fSSepherosa Ziehau 				  u32 device_type, u32 data)
12976150453fSSepherosa Ziehau {
12986150453fSSepherosa Ziehau 	struct ixgbe_hic_internal_phy_req write_cmd;
12996150453fSSepherosa Ziehau 	s32 status;
13006150453fSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(device_type);
13016150453fSSepherosa Ziehau 
13026150453fSSepherosa Ziehau 	memset(&write_cmd, 0, sizeof(write_cmd));
13036150453fSSepherosa Ziehau 	write_cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
13046150453fSSepherosa Ziehau 	write_cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
13056150453fSSepherosa Ziehau 	write_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
13066150453fSSepherosa Ziehau 	write_cmd.port_number = hw->bus.lan_id;
13076150453fSSepherosa Ziehau 	write_cmd.command_type = FW_INT_PHY_REQ_WRITE;
13086150453fSSepherosa Ziehau 	write_cmd.address = IXGBE_CPU_TO_BE16(reg_addr);
13096150453fSSepherosa Ziehau 	write_cmd.write_data = IXGBE_CPU_TO_BE32(data);
13106150453fSSepherosa Ziehau 
13116150453fSSepherosa Ziehau 	status = ixgbe_host_interface_command(hw, (u32 *)&write_cmd,
13126150453fSSepherosa Ziehau 					      sizeof(write_cmd),
13136150453fSSepherosa Ziehau 					      IXGBE_HI_COMMAND_TIMEOUT, FALSE);
13146150453fSSepherosa Ziehau 
13156150453fSSepherosa Ziehau 	return status;
13166150453fSSepherosa Ziehau }
13176150453fSSepherosa Ziehau 
13186150453fSSepherosa Ziehau /**
13196150453fSSepherosa Ziehau  *  ixgbe_read_iosf_sb_reg_x550a - Reads specified register of the IOSF device
13206150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
13216150453fSSepherosa Ziehau  *  @reg_addr: 32 bit PHY register to write
13226150453fSSepherosa Ziehau  *  @device_type: 3 bit device type
13236150453fSSepherosa Ziehau  *  @data: Pointer to read data from the register
13246150453fSSepherosa Ziehau  **/
ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u32 * data)13256150453fSSepherosa Ziehau s32 ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
13266150453fSSepherosa Ziehau 				 u32 device_type, u32 *data)
13276150453fSSepherosa Ziehau {
13286150453fSSepherosa Ziehau 	union {
13296150453fSSepherosa Ziehau 		struct ixgbe_hic_internal_phy_req cmd;
13306150453fSSepherosa Ziehau 		struct ixgbe_hic_internal_phy_resp rsp;
13316150453fSSepherosa Ziehau 	} hic;
13326150453fSSepherosa Ziehau 	s32 status;
13336150453fSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(device_type);
13346150453fSSepherosa Ziehau 
13356150453fSSepherosa Ziehau 	memset(&hic, 0, sizeof(hic));
13366150453fSSepherosa Ziehau 	hic.cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
13376150453fSSepherosa Ziehau 	hic.cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
13386150453fSSepherosa Ziehau 	hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
13396150453fSSepherosa Ziehau 	hic.cmd.port_number = hw->bus.lan_id;
13406150453fSSepherosa Ziehau 	hic.cmd.command_type = FW_INT_PHY_REQ_READ;
13416150453fSSepherosa Ziehau 	hic.cmd.address = IXGBE_CPU_TO_BE16(reg_addr);
13426150453fSSepherosa Ziehau 
13436150453fSSepherosa Ziehau 	status = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd,
13446150453fSSepherosa Ziehau 					      sizeof(hic.cmd),
13456150453fSSepherosa Ziehau 					      IXGBE_HI_COMMAND_TIMEOUT, TRUE);
13466150453fSSepherosa Ziehau 
13476150453fSSepherosa Ziehau 	/* Extract the register value from the response. */
13486150453fSSepherosa Ziehau 	*data = IXGBE_BE32_TO_CPU(hic.rsp.read_data);
13496150453fSSepherosa Ziehau 
13506150453fSSepherosa Ziehau 	return status;
13516150453fSSepherosa Ziehau }
13526150453fSSepherosa Ziehau 
13536150453fSSepherosa Ziehau /**
135463d483cdSSepherosa Ziehau  *  ixgbe_disable_mdd_X550
135563d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
135663d483cdSSepherosa Ziehau  *
135763d483cdSSepherosa Ziehau  *  Disable malicious driver detection
135863d483cdSSepherosa Ziehau  **/
ixgbe_disable_mdd_X550(struct ixgbe_hw * hw)135963d483cdSSepherosa Ziehau void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw)
136063d483cdSSepherosa Ziehau {
136163d483cdSSepherosa Ziehau 	u32 reg;
136263d483cdSSepherosa Ziehau 
136363d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_disable_mdd_X550");
136463d483cdSSepherosa Ziehau 
136563d483cdSSepherosa Ziehau 	/* Disable MDD for TX DMA and interrupt */
136663d483cdSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
136763d483cdSSepherosa Ziehau 	reg &= ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
136863d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
136963d483cdSSepherosa Ziehau 
137063d483cdSSepherosa Ziehau 	/* Disable MDD for RX and interrupt */
137163d483cdSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
137263d483cdSSepherosa Ziehau 	reg &= ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
137363d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
137463d483cdSSepherosa Ziehau }
137563d483cdSSepherosa Ziehau 
137663d483cdSSepherosa Ziehau /**
137763d483cdSSepherosa Ziehau  *  ixgbe_enable_mdd_X550
137863d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
137963d483cdSSepherosa Ziehau  *
138063d483cdSSepherosa Ziehau  *  Enable malicious driver detection
138163d483cdSSepherosa Ziehau  **/
ixgbe_enable_mdd_X550(struct ixgbe_hw * hw)138263d483cdSSepherosa Ziehau void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw)
138363d483cdSSepherosa Ziehau {
138463d483cdSSepherosa Ziehau 	u32 reg;
138563d483cdSSepherosa Ziehau 
138663d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_enable_mdd_X550");
138763d483cdSSepherosa Ziehau 
138863d483cdSSepherosa Ziehau 	/* Enable MDD for TX DMA and interrupt */
138963d483cdSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
139063d483cdSSepherosa Ziehau 	reg |= (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
139163d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
139263d483cdSSepherosa Ziehau 
139363d483cdSSepherosa Ziehau 	/* Enable MDD for RX and interrupt */
139463d483cdSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
139563d483cdSSepherosa Ziehau 	reg |= (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
139663d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
139763d483cdSSepherosa Ziehau }
139863d483cdSSepherosa Ziehau 
139963d483cdSSepherosa Ziehau /**
140063d483cdSSepherosa Ziehau  *  ixgbe_restore_mdd_vf_X550
140163d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
140263d483cdSSepherosa Ziehau  *  @vf: vf index
140363d483cdSSepherosa Ziehau  *
140463d483cdSSepherosa Ziehau  *  Restore VF that was disabled during malicious driver detection event
140563d483cdSSepherosa Ziehau  **/
ixgbe_restore_mdd_vf_X550(struct ixgbe_hw * hw,u32 vf)140663d483cdSSepherosa Ziehau void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf)
140763d483cdSSepherosa Ziehau {
140863d483cdSSepherosa Ziehau 	u32 idx, reg, num_qs, start_q, bitmask;
140963d483cdSSepherosa Ziehau 
141063d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_restore_mdd_vf_X550");
141163d483cdSSepherosa Ziehau 
141263d483cdSSepherosa Ziehau 	/* Map VF to queues */
141363d483cdSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
141463d483cdSSepherosa Ziehau 	switch (reg & IXGBE_MRQC_MRQE_MASK) {
141563d483cdSSepherosa Ziehau 	case IXGBE_MRQC_VMDQRT8TCEN:
141663d483cdSSepherosa Ziehau 		num_qs = 8;  /* 16 VFs / pools */
141763d483cdSSepherosa Ziehau 		bitmask = 0x000000FF;
141863d483cdSSepherosa Ziehau 		break;
141963d483cdSSepherosa Ziehau 	case IXGBE_MRQC_VMDQRSS32EN:
142063d483cdSSepherosa Ziehau 	case IXGBE_MRQC_VMDQRT4TCEN:
142163d483cdSSepherosa Ziehau 		num_qs = 4;  /* 32 VFs / pools */
142263d483cdSSepherosa Ziehau 		bitmask = 0x0000000F;
142363d483cdSSepherosa Ziehau 		break;
142463d483cdSSepherosa Ziehau 	default:            /* 64 VFs / pools */
142563d483cdSSepherosa Ziehau 		num_qs = 2;
142663d483cdSSepherosa Ziehau 		bitmask = 0x00000003;
142763d483cdSSepherosa Ziehau 		break;
142863d483cdSSepherosa Ziehau 	}
142963d483cdSSepherosa Ziehau 	start_q = vf * num_qs;
143063d483cdSSepherosa Ziehau 
143163d483cdSSepherosa Ziehau 	/* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */
143263d483cdSSepherosa Ziehau 	idx = start_q / 32;
143363d483cdSSepherosa Ziehau 	reg = 0;
143463d483cdSSepherosa Ziehau 	reg |= (bitmask << (start_q % 32));
143563d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), reg);
143663d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), reg);
143763d483cdSSepherosa Ziehau }
143863d483cdSSepherosa Ziehau 
143963d483cdSSepherosa Ziehau /**
144063d483cdSSepherosa Ziehau  *  ixgbe_mdd_event_X550
144163d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
144263d483cdSSepherosa Ziehau  *  @vf_bitmap: vf bitmap of malicious vfs
144363d483cdSSepherosa Ziehau  *
144463d483cdSSepherosa Ziehau  *  Handle malicious driver detection event.
144563d483cdSSepherosa Ziehau  **/
ixgbe_mdd_event_X550(struct ixgbe_hw * hw,u32 * vf_bitmap)144663d483cdSSepherosa Ziehau void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap)
144763d483cdSSepherosa Ziehau {
144863d483cdSSepherosa Ziehau 	u32 wqbr;
144963d483cdSSepherosa Ziehau 	u32 i, j, reg, q, shift, vf, idx;
145063d483cdSSepherosa Ziehau 
145163d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_mdd_event_X550");
145263d483cdSSepherosa Ziehau 
145363d483cdSSepherosa Ziehau 	/* figure out pool size for mapping to vf's */
145463d483cdSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
145563d483cdSSepherosa Ziehau 	switch (reg & IXGBE_MRQC_MRQE_MASK) {
145663d483cdSSepherosa Ziehau 	case IXGBE_MRQC_VMDQRT8TCEN:
145763d483cdSSepherosa Ziehau 		shift = 3;  /* 16 VFs / pools */
145863d483cdSSepherosa Ziehau 		break;
145963d483cdSSepherosa Ziehau 	case IXGBE_MRQC_VMDQRSS32EN:
146063d483cdSSepherosa Ziehau 	case IXGBE_MRQC_VMDQRT4TCEN:
146163d483cdSSepherosa Ziehau 		shift = 2;  /* 32 VFs / pools */
146263d483cdSSepherosa Ziehau 		break;
146363d483cdSSepherosa Ziehau 	default:
146463d483cdSSepherosa Ziehau 		shift = 1;  /* 64 VFs / pools */
146563d483cdSSepherosa Ziehau 		break;
146663d483cdSSepherosa Ziehau 	}
146763d483cdSSepherosa Ziehau 
146863d483cdSSepherosa Ziehau 	/* Read WQBR_TX and WQBR_RX and check for malicious queues */
146963d483cdSSepherosa Ziehau 	for (i = 0; i < 4; i++) {
147063d483cdSSepherosa Ziehau 		wqbr = IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i));
147163d483cdSSepherosa Ziehau 		wqbr |= IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i));
147263d483cdSSepherosa Ziehau 
147363d483cdSSepherosa Ziehau 		if (!wqbr)
147463d483cdSSepherosa Ziehau 			continue;
147563d483cdSSepherosa Ziehau 
147663d483cdSSepherosa Ziehau 		/* Get malicious queue */
147763d483cdSSepherosa Ziehau 		for (j = 0; j < 32 && wqbr; j++) {
147863d483cdSSepherosa Ziehau 
147963d483cdSSepherosa Ziehau 			if (!(wqbr & (1 << j)))
148063d483cdSSepherosa Ziehau 				continue;
148163d483cdSSepherosa Ziehau 
148263d483cdSSepherosa Ziehau 			/* Get queue from bitmask */
148363d483cdSSepherosa Ziehau 			q = j + (i * 32);
148463d483cdSSepherosa Ziehau 
148563d483cdSSepherosa Ziehau 			/* Map queue to vf */
148663d483cdSSepherosa Ziehau 			vf = (q >> shift);
148763d483cdSSepherosa Ziehau 
148863d483cdSSepherosa Ziehau 			/* Set vf bit in vf_bitmap */
148963d483cdSSepherosa Ziehau 			idx = vf / 32;
149063d483cdSSepherosa Ziehau 			vf_bitmap[idx] |= (1 << (vf % 32));
149163d483cdSSepherosa Ziehau 			wqbr &= ~(1 << j);
149263d483cdSSepherosa Ziehau 		}
149363d483cdSSepherosa Ziehau 	}
149463d483cdSSepherosa Ziehau }
149563d483cdSSepherosa Ziehau 
149663d483cdSSepherosa Ziehau /**
149763d483cdSSepherosa Ziehau  *  ixgbe_get_media_type_X550em - Get media type
149863d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
149963d483cdSSepherosa Ziehau  *
150063d483cdSSepherosa Ziehau  *  Returns the media type (fiber, copper, backplane)
150163d483cdSSepherosa Ziehau  */
ixgbe_get_media_type_X550em(struct ixgbe_hw * hw)150263d483cdSSepherosa Ziehau enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
150363d483cdSSepherosa Ziehau {
150463d483cdSSepherosa Ziehau 	enum ixgbe_media_type media_type;
150563d483cdSSepherosa Ziehau 
150663d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_media_type_X550em");
150763d483cdSSepherosa Ziehau 
150863d483cdSSepherosa Ziehau 	/* Detect if there is a copper PHY attached. */
150963d483cdSSepherosa Ziehau 	switch (hw->device_id) {
151063d483cdSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_KR:
151163d483cdSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_KX4:
15126150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_XFI:
15136150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_KR:
15146150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_KR_L:
151563d483cdSSepherosa Ziehau 		media_type = ixgbe_media_type_backplane;
151663d483cdSSepherosa Ziehau 		break;
151763d483cdSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_SFP:
15186150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_SFP:
15196150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_SFP_N:
15206150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_QSFP:
15216150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_QSFP_N:
152263d483cdSSepherosa Ziehau 		media_type = ixgbe_media_type_fiber;
152363d483cdSSepherosa Ziehau 		break;
152463d483cdSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_1G_T:
152563d483cdSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_10G_T:
15266150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_10G_T:
15276150453fSSepherosa Ziehau 		media_type = ixgbe_media_type_copper;
15286150453fSSepherosa Ziehau 		break;
15296150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_SGMII:
15306150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_SGMII_L:
15316150453fSSepherosa Ziehau 		media_type = ixgbe_media_type_backplane;
15326150453fSSepherosa Ziehau 		hw->phy.type = ixgbe_phy_sgmii;
15336150453fSSepherosa Ziehau 		break;
15346150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T:
15356150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
153663d483cdSSepherosa Ziehau 		media_type = ixgbe_media_type_copper;
153763d483cdSSepherosa Ziehau 		break;
153863d483cdSSepherosa Ziehau 	default:
153963d483cdSSepherosa Ziehau 		media_type = ixgbe_media_type_unknown;
154063d483cdSSepherosa Ziehau 		break;
154163d483cdSSepherosa Ziehau 	}
154263d483cdSSepherosa Ziehau 	return media_type;
154363d483cdSSepherosa Ziehau }
154463d483cdSSepherosa Ziehau 
154563d483cdSSepherosa Ziehau /**
154663d483cdSSepherosa Ziehau  *  ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
154763d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
154863d483cdSSepherosa Ziehau  *  @linear: TRUE if SFP module is linear
154963d483cdSSepherosa Ziehau  */
ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw * hw,bool * linear)155063d483cdSSepherosa Ziehau static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
155163d483cdSSepherosa Ziehau {
155263d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_supported_sfp_modules_X550em");
155363d483cdSSepherosa Ziehau 
155463d483cdSSepherosa Ziehau 	switch (hw->phy.sfp_type) {
155563d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_not_present:
155663d483cdSSepherosa Ziehau 		return IXGBE_ERR_SFP_NOT_PRESENT;
155763d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_da_cu_core0:
155863d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_da_cu_core1:
155963d483cdSSepherosa Ziehau 		*linear = TRUE;
156063d483cdSSepherosa Ziehau 		break;
156163d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_srlr_core0:
156263d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_srlr_core1:
156363d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_da_act_lmt_core0:
156463d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_da_act_lmt_core1:
156563d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_1g_sx_core0:
156663d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_1g_sx_core1:
156763d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_1g_lx_core0:
156863d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_1g_lx_core1:
156963d483cdSSepherosa Ziehau 		*linear = FALSE;
157063d483cdSSepherosa Ziehau 		break;
157163d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_unknown:
157263d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_1g_cu_core0:
157363d483cdSSepherosa Ziehau 	case ixgbe_sfp_type_1g_cu_core1:
157463d483cdSSepherosa Ziehau 	default:
157563d483cdSSepherosa Ziehau 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
157663d483cdSSepherosa Ziehau 	}
157763d483cdSSepherosa Ziehau 
157863d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
157963d483cdSSepherosa Ziehau }
158063d483cdSSepherosa Ziehau 
158163d483cdSSepherosa Ziehau /**
158263d483cdSSepherosa Ziehau  *  ixgbe_identify_sfp_module_X550em - Identifies SFP modules
158363d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
158463d483cdSSepherosa Ziehau  *
158563d483cdSSepherosa Ziehau  *  Searches for and identifies the SFP module and assigns appropriate PHY type.
158663d483cdSSepherosa Ziehau  **/
ixgbe_identify_sfp_module_X550em(struct ixgbe_hw * hw)158763d483cdSSepherosa Ziehau s32 ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw)
158863d483cdSSepherosa Ziehau {
158963d483cdSSepherosa Ziehau 	s32 status;
159063d483cdSSepherosa Ziehau 	bool linear;
159163d483cdSSepherosa Ziehau 
159263d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_identify_sfp_module_X550em");
159363d483cdSSepherosa Ziehau 
159463d483cdSSepherosa Ziehau 	status = ixgbe_identify_module_generic(hw);
159563d483cdSSepherosa Ziehau 
159663d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
159763d483cdSSepherosa Ziehau 		return status;
159863d483cdSSepherosa Ziehau 
159963d483cdSSepherosa Ziehau 	/* Check if SFP module is supported */
160063d483cdSSepherosa Ziehau 	status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
160163d483cdSSepherosa Ziehau 
160263d483cdSSepherosa Ziehau 	return status;
160363d483cdSSepherosa Ziehau }
160463d483cdSSepherosa Ziehau 
160563d483cdSSepherosa Ziehau /**
160663d483cdSSepherosa Ziehau  *  ixgbe_setup_sfp_modules_X550em - Setup MAC link ops
160763d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
160863d483cdSSepherosa Ziehau  */
ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw * hw)160963d483cdSSepherosa Ziehau s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
161063d483cdSSepherosa Ziehau {
161163d483cdSSepherosa Ziehau 	s32 status;
161263d483cdSSepherosa Ziehau 	bool linear;
161363d483cdSSepherosa Ziehau 
161463d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_sfp_modules_X550em");
161563d483cdSSepherosa Ziehau 
161663d483cdSSepherosa Ziehau 	/* Check if SFP module is supported */
161763d483cdSSepherosa Ziehau 	status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
161863d483cdSSepherosa Ziehau 
161963d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
162063d483cdSSepherosa Ziehau 		return status;
162163d483cdSSepherosa Ziehau 
162263d483cdSSepherosa Ziehau 	ixgbe_init_mac_link_ops_X550em(hw);
162363d483cdSSepherosa Ziehau 	hw->phy.ops.reset = NULL;
162463d483cdSSepherosa Ziehau 
162563d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
162663d483cdSSepherosa Ziehau }
162763d483cdSSepherosa Ziehau 
162863d483cdSSepherosa Ziehau /**
16296150453fSSepherosa Ziehau *  ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the
16306150453fSSepherosa Ziehau *  internal PHY
16316150453fSSepherosa Ziehau *  @hw: pointer to hardware structure
16326150453fSSepherosa Ziehau **/
ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw * hw)16336150453fSSepherosa Ziehau static s32 ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw)
16346150453fSSepherosa Ziehau {
16356150453fSSepherosa Ziehau 	s32 status;
16366150453fSSepherosa Ziehau 	u32 link_ctrl;
16376150453fSSepherosa Ziehau 
16386150453fSSepherosa Ziehau 	/* Restart auto-negotiation. */
16396150453fSSepherosa Ziehau 	status = hw->mac.ops.read_iosf_sb_reg(hw,
16406150453fSSepherosa Ziehau 				       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
16416150453fSSepherosa Ziehau 				       IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl);
16426150453fSSepherosa Ziehau 
16436150453fSSepherosa Ziehau 	if (status) {
16446150453fSSepherosa Ziehau 		DEBUGOUT("Auto-negotiation did not complete\n");
16456150453fSSepherosa Ziehau 		return status;
16466150453fSSepherosa Ziehau 	}
16476150453fSSepherosa Ziehau 
16486150453fSSepherosa Ziehau 	link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
16496150453fSSepherosa Ziehau 	status = hw->mac.ops.write_iosf_sb_reg(hw,
16506150453fSSepherosa Ziehau 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
16516150453fSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl);
16526150453fSSepherosa Ziehau 
16536150453fSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_X550EM_a) {
16546150453fSSepherosa Ziehau 		u32 flx_mask_st20;
16556150453fSSepherosa Ziehau 
16566150453fSSepherosa Ziehau 		/* Indicate to FW that AN restart has been asserted */
16576150453fSSepherosa Ziehau 		status = hw->mac.ops.read_iosf_sb_reg(hw,
16586150453fSSepherosa Ziehau 				IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
16596150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20);
16606150453fSSepherosa Ziehau 
16616150453fSSepherosa Ziehau 		if (status) {
16626150453fSSepherosa Ziehau 			DEBUGOUT("Auto-negotiation did not complete\n");
16636150453fSSepherosa Ziehau 			return status;
16646150453fSSepherosa Ziehau 		}
16656150453fSSepherosa Ziehau 
16666150453fSSepherosa Ziehau 		flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART;
16676150453fSSepherosa Ziehau 		status = hw->mac.ops.write_iosf_sb_reg(hw,
16686150453fSSepherosa Ziehau 				IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
16696150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20);
16706150453fSSepherosa Ziehau 	}
16716150453fSSepherosa Ziehau 
16726150453fSSepherosa Ziehau 	return status;
16736150453fSSepherosa Ziehau }
16746150453fSSepherosa Ziehau 
16756150453fSSepherosa Ziehau /**
16766150453fSSepherosa Ziehau  * ixgbe_setup_sgmii - Set up link for sgmii
16776150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
1678*dd5ce676SSepherosa Ziehau  * @speed: new link speed
1679*dd5ce676SSepherosa Ziehau  * @autoneg_wait: TRUE when waiting for completion is needed
16806150453fSSepherosa Ziehau  */
ixgbe_setup_sgmii(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait)16816150453fSSepherosa Ziehau static s32 ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed,
16826150453fSSepherosa Ziehau 			     bool autoneg_wait)
16836150453fSSepherosa Ziehau {
16846150453fSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
16856150453fSSepherosa Ziehau 	u32 lval, sval, flx_val;
16866150453fSSepherosa Ziehau 	s32 rc;
16876150453fSSepherosa Ziehau 
16886150453fSSepherosa Ziehau 	rc = mac->ops.read_iosf_sb_reg(hw,
16896150453fSSepherosa Ziehau 				       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
16906150453fSSepherosa Ziehau 				       IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
16916150453fSSepherosa Ziehau 	if (rc)
16926150453fSSepherosa Ziehau 		return rc;
16936150453fSSepherosa Ziehau 
16946150453fSSepherosa Ziehau 	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
16956150453fSSepherosa Ziehau 	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
16966150453fSSepherosa Ziehau 	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
16976150453fSSepherosa Ziehau 	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
16986150453fSSepherosa Ziehau 	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
16996150453fSSepherosa Ziehau 	rc = mac->ops.write_iosf_sb_reg(hw,
17006150453fSSepherosa Ziehau 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
17016150453fSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
17026150453fSSepherosa Ziehau 	if (rc)
17036150453fSSepherosa Ziehau 		return rc;
17046150453fSSepherosa Ziehau 
17056150453fSSepherosa Ziehau 	rc = mac->ops.read_iosf_sb_reg(hw,
17066150453fSSepherosa Ziehau 				       IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
17076150453fSSepherosa Ziehau 				       IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
17086150453fSSepherosa Ziehau 	if (rc)
17096150453fSSepherosa Ziehau 		return rc;
17106150453fSSepherosa Ziehau 
17116150453fSSepherosa Ziehau 	sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
17126150453fSSepherosa Ziehau 	sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
17136150453fSSepherosa Ziehau 	rc = mac->ops.write_iosf_sb_reg(hw,
17146150453fSSepherosa Ziehau 					IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
17156150453fSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
17166150453fSSepherosa Ziehau 	if (rc)
17176150453fSSepherosa Ziehau 		return rc;
17186150453fSSepherosa Ziehau 
17196150453fSSepherosa Ziehau 	rc = mac->ops.read_iosf_sb_reg(hw,
17206150453fSSepherosa Ziehau 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
17216150453fSSepherosa Ziehau 				    IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
17226150453fSSepherosa Ziehau 	if (rc)
17236150453fSSepherosa Ziehau 		return rc;
17246150453fSSepherosa Ziehau 
17256150453fSSepherosa Ziehau 	flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
17266150453fSSepherosa Ziehau 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
17276150453fSSepherosa Ziehau 	flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
17286150453fSSepherosa Ziehau 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
17296150453fSSepherosa Ziehau 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
17306150453fSSepherosa Ziehau 
17316150453fSSepherosa Ziehau 	rc = mac->ops.write_iosf_sb_reg(hw,
17326150453fSSepherosa Ziehau 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
17336150453fSSepherosa Ziehau 				    IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
17346150453fSSepherosa Ziehau 	if (rc)
17356150453fSSepherosa Ziehau 		return rc;
17366150453fSSepherosa Ziehau 
17376150453fSSepherosa Ziehau 	rc = ixgbe_restart_an_internal_phy_x550em(hw);
17386150453fSSepherosa Ziehau 	if (rc)
17396150453fSSepherosa Ziehau 		return rc;
17406150453fSSepherosa Ziehau 
17416150453fSSepherosa Ziehau 	return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
17426150453fSSepherosa Ziehau }
17436150453fSSepherosa Ziehau 
17446150453fSSepherosa Ziehau /**
17456150453fSSepherosa Ziehau  * ixgbe_setup_sgmii_fw - Set up link for internal PHY SGMII auto-negotiation
17466150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
1747*dd5ce676SSepherosa Ziehau  * @speed: new link speed
1748*dd5ce676SSepherosa Ziehau  * @autoneg_wait: TRUE when waiting for completion is needed
17496150453fSSepherosa Ziehau  */
ixgbe_setup_sgmii_fw(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait)17506150453fSSepherosa Ziehau static s32 ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed,
17516150453fSSepherosa Ziehau 				bool autoneg_wait)
17526150453fSSepherosa Ziehau {
17536150453fSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
17546150453fSSepherosa Ziehau 	u32 lval, sval, flx_val;
17556150453fSSepherosa Ziehau 	s32 rc;
17566150453fSSepherosa Ziehau 
17576150453fSSepherosa Ziehau 	rc = mac->ops.read_iosf_sb_reg(hw,
17586150453fSSepherosa Ziehau 				       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
17596150453fSSepherosa Ziehau 				       IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
17606150453fSSepherosa Ziehau 	if (rc)
17616150453fSSepherosa Ziehau 		return rc;
17626150453fSSepherosa Ziehau 
17636150453fSSepherosa Ziehau 	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
17646150453fSSepherosa Ziehau 	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
17656150453fSSepherosa Ziehau 	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
17666150453fSSepherosa Ziehau 	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
17676150453fSSepherosa Ziehau 	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
17686150453fSSepherosa Ziehau 	rc = mac->ops.write_iosf_sb_reg(hw,
17696150453fSSepherosa Ziehau 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
17706150453fSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
17716150453fSSepherosa Ziehau 	if (rc)
17726150453fSSepherosa Ziehau 		return rc;
17736150453fSSepherosa Ziehau 
17746150453fSSepherosa Ziehau 	rc = mac->ops.read_iosf_sb_reg(hw,
17756150453fSSepherosa Ziehau 				       IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
17766150453fSSepherosa Ziehau 				       IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
17776150453fSSepherosa Ziehau 	if (rc)
17786150453fSSepherosa Ziehau 		return rc;
17796150453fSSepherosa Ziehau 
17806150453fSSepherosa Ziehau 	sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
17816150453fSSepherosa Ziehau 	sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
17826150453fSSepherosa Ziehau 	rc = mac->ops.write_iosf_sb_reg(hw,
17836150453fSSepherosa Ziehau 					IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
17846150453fSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
17856150453fSSepherosa Ziehau 	if (rc)
17866150453fSSepherosa Ziehau 		return rc;
17876150453fSSepherosa Ziehau 
17886150453fSSepherosa Ziehau 	rc = mac->ops.write_iosf_sb_reg(hw,
17896150453fSSepherosa Ziehau 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
17906150453fSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
17916150453fSSepherosa Ziehau 	if (rc)
17926150453fSSepherosa Ziehau 		return rc;
17936150453fSSepherosa Ziehau 
17946150453fSSepherosa Ziehau 	rc = mac->ops.read_iosf_sb_reg(hw,
17956150453fSSepherosa Ziehau 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
17966150453fSSepherosa Ziehau 				    IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
17976150453fSSepherosa Ziehau 	if (rc)
17986150453fSSepherosa Ziehau 		return rc;
17996150453fSSepherosa Ziehau 
18006150453fSSepherosa Ziehau 	flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
18016150453fSSepherosa Ziehau 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
18026150453fSSepherosa Ziehau 	flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
18036150453fSSepherosa Ziehau 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
18046150453fSSepherosa Ziehau 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
18056150453fSSepherosa Ziehau 
18066150453fSSepherosa Ziehau 	rc = mac->ops.write_iosf_sb_reg(hw,
18076150453fSSepherosa Ziehau 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
18086150453fSSepherosa Ziehau 				    IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
18096150453fSSepherosa Ziehau 	if (rc)
18106150453fSSepherosa Ziehau 		return rc;
18116150453fSSepherosa Ziehau 
18126150453fSSepherosa Ziehau 	rc = ixgbe_restart_an_internal_phy_x550em(hw);
18136150453fSSepherosa Ziehau 
18146150453fSSepherosa Ziehau 	return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
18156150453fSSepherosa Ziehau }
18166150453fSSepherosa Ziehau 
18176150453fSSepherosa Ziehau /**
181863d483cdSSepherosa Ziehau  *  ixgbe_init_mac_link_ops_X550em - init mac link function pointers
181963d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
182063d483cdSSepherosa Ziehau  */
ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw * hw)182163d483cdSSepherosa Ziehau void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
182263d483cdSSepherosa Ziehau {
182363d483cdSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
182463d483cdSSepherosa Ziehau 
182563d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_mac_link_ops_X550em");
182663d483cdSSepherosa Ziehau 
182763d483cdSSepherosa Ziehau 	switch (hw->mac.ops.get_media_type(hw)) {
182863d483cdSSepherosa Ziehau 	case ixgbe_media_type_fiber:
182963d483cdSSepherosa Ziehau 		/* CS4227 does not support autoneg, so disable the laser control
183063d483cdSSepherosa Ziehau 		 * functions for SFP+ fiber
183163d483cdSSepherosa Ziehau 		 */
183263d483cdSSepherosa Ziehau 		mac->ops.disable_tx_laser = NULL;
183363d483cdSSepherosa Ziehau 		mac->ops.enable_tx_laser = NULL;
183463d483cdSSepherosa Ziehau 		mac->ops.flap_tx_laser = NULL;
183563d483cdSSepherosa Ziehau 		mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
183663d483cdSSepherosa Ziehau 		mac->ops.set_rate_select_speed =
183763d483cdSSepherosa Ziehau 					ixgbe_set_soft_rate_select_speed;
18386150453fSSepherosa Ziehau 
18396150453fSSepherosa Ziehau 		if ((hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) ||
18406150453fSSepherosa Ziehau 		    (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP))
18416150453fSSepherosa Ziehau 			mac->ops.setup_mac_link =
18426150453fSSepherosa Ziehau 						ixgbe_setup_mac_link_sfp_x550a;
18436150453fSSepherosa Ziehau 		else
18446150453fSSepherosa Ziehau 			mac->ops.setup_mac_link =
18456150453fSSepherosa Ziehau 						ixgbe_setup_mac_link_sfp_x550em;
184663d483cdSSepherosa Ziehau 		break;
184763d483cdSSepherosa Ziehau 	case ixgbe_media_type_copper:
18486150453fSSepherosa Ziehau 		if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T)
18496150453fSSepherosa Ziehau 			break;
18506150453fSSepherosa Ziehau 		if (hw->mac.type == ixgbe_mac_X550EM_a) {
18516150453fSSepherosa Ziehau 			if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
18526150453fSSepherosa Ziehau 			    hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) {
18536150453fSSepherosa Ziehau 				mac->ops.setup_link = ixgbe_setup_sgmii_fw;
18546150453fSSepherosa Ziehau 				mac->ops.check_link =
18556150453fSSepherosa Ziehau 						   ixgbe_check_mac_link_generic;
18566150453fSSepherosa Ziehau 			} else {
18576150453fSSepherosa Ziehau 				mac->ops.setup_link =
18586150453fSSepherosa Ziehau 						  ixgbe_setup_mac_link_t_X550em;
18596150453fSSepherosa Ziehau 			}
18606150453fSSepherosa Ziehau 		} else {
186163d483cdSSepherosa Ziehau 			mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
186263d483cdSSepherosa Ziehau 			mac->ops.check_link = ixgbe_check_link_t_X550em;
18636150453fSSepherosa Ziehau 		}
18646150453fSSepherosa Ziehau 		break;
18656150453fSSepherosa Ziehau 	case ixgbe_media_type_backplane:
18666150453fSSepherosa Ziehau 		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
18676150453fSSepherosa Ziehau 		    hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L)
18686150453fSSepherosa Ziehau 			mac->ops.setup_link = ixgbe_setup_sgmii;
186963d483cdSSepherosa Ziehau 		break;
187063d483cdSSepherosa Ziehau 	default:
187163d483cdSSepherosa Ziehau 		break;
187263d483cdSSepherosa Ziehau 	}
187363d483cdSSepherosa Ziehau }
187463d483cdSSepherosa Ziehau 
187563d483cdSSepherosa Ziehau /**
187663d483cdSSepherosa Ziehau  *  ixgbe_get_link_capabilities_x550em - Determines link capabilities
187763d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
187863d483cdSSepherosa Ziehau  *  @speed: pointer to link speed
187963d483cdSSepherosa Ziehau  *  @autoneg: TRUE when autoneg or autotry is enabled
188063d483cdSSepherosa Ziehau  */
ixgbe_get_link_capabilities_X550em(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * autoneg)188163d483cdSSepherosa Ziehau s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
188263d483cdSSepherosa Ziehau 				       ixgbe_link_speed *speed,
188363d483cdSSepherosa Ziehau 				       bool *autoneg)
188463d483cdSSepherosa Ziehau {
188563d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_link_capabilities_X550em");
188663d483cdSSepherosa Ziehau 
18876150453fSSepherosa Ziehau 
18886150453fSSepherosa Ziehau 	if (hw->phy.type == ixgbe_phy_fw) {
18896150453fSSepherosa Ziehau 		*autoneg = TRUE;
18906150453fSSepherosa Ziehau 		*speed = hw->phy.speeds_supported;
18916150453fSSepherosa Ziehau 		return 0;
18926150453fSSepherosa Ziehau 	}
18936150453fSSepherosa Ziehau 
189463d483cdSSepherosa Ziehau 	/* SFP */
189563d483cdSSepherosa Ziehau 	if (hw->phy.media_type == ixgbe_media_type_fiber) {
189663d483cdSSepherosa Ziehau 
189763d483cdSSepherosa Ziehau 		/* CS4227 SFP must not enable auto-negotiation */
189863d483cdSSepherosa Ziehau 		*autoneg = FALSE;
189963d483cdSSepherosa Ziehau 
190063d483cdSSepherosa Ziehau 		/* Check if 1G SFP module. */
190163d483cdSSepherosa Ziehau 		if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
190263d483cdSSepherosa Ziehau 		    hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1
190363d483cdSSepherosa Ziehau 		    || hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
190463d483cdSSepherosa Ziehau 		    hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) {
190563d483cdSSepherosa Ziehau 			*speed = IXGBE_LINK_SPEED_1GB_FULL;
190663d483cdSSepherosa Ziehau 			return IXGBE_SUCCESS;
190763d483cdSSepherosa Ziehau 		}
190863d483cdSSepherosa Ziehau 
190963d483cdSSepherosa Ziehau 		/* Link capabilities are based on SFP */
191063d483cdSSepherosa Ziehau 		if (hw->phy.multispeed_fiber)
191163d483cdSSepherosa Ziehau 			*speed = IXGBE_LINK_SPEED_10GB_FULL |
191263d483cdSSepherosa Ziehau 				 IXGBE_LINK_SPEED_1GB_FULL;
191363d483cdSSepherosa Ziehau 		else
191463d483cdSSepherosa Ziehau 			*speed = IXGBE_LINK_SPEED_10GB_FULL;
191563d483cdSSepherosa Ziehau 	} else {
19166150453fSSepherosa Ziehau 		switch (hw->phy.type) {
19176150453fSSepherosa Ziehau 		case ixgbe_phy_ext_1g_t:
19186150453fSSepherosa Ziehau 		case ixgbe_phy_sgmii:
19196150453fSSepherosa Ziehau 			*speed = IXGBE_LINK_SPEED_1GB_FULL;
19206150453fSSepherosa Ziehau 			break;
19216150453fSSepherosa Ziehau 		case ixgbe_phy_x550em_kr:
19226150453fSSepherosa Ziehau 			if (hw->mac.type == ixgbe_mac_X550EM_a) {
19236150453fSSepherosa Ziehau 				/* check different backplane modes */
19246150453fSSepherosa Ziehau 				if (hw->phy.nw_mng_if_sel &
19256150453fSSepherosa Ziehau 					   IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) {
19266150453fSSepherosa Ziehau 					*speed = IXGBE_LINK_SPEED_2_5GB_FULL;
19276150453fSSepherosa Ziehau 					break;
19286150453fSSepherosa Ziehau 				} else if (hw->device_id ==
19296150453fSSepherosa Ziehau 						   IXGBE_DEV_ID_X550EM_A_KR_L) {
19306150453fSSepherosa Ziehau 					*speed = IXGBE_LINK_SPEED_1GB_FULL;
19316150453fSSepherosa Ziehau 					break;
19326150453fSSepherosa Ziehau 				}
19336150453fSSepherosa Ziehau 			}
19346150453fSSepherosa Ziehau 			/* fall through */
19356150453fSSepherosa Ziehau 		default:
193663d483cdSSepherosa Ziehau 			*speed = IXGBE_LINK_SPEED_10GB_FULL |
193763d483cdSSepherosa Ziehau 				 IXGBE_LINK_SPEED_1GB_FULL;
19386150453fSSepherosa Ziehau 			break;
19396150453fSSepherosa Ziehau 		}
194063d483cdSSepherosa Ziehau 		*autoneg = TRUE;
194163d483cdSSepherosa Ziehau 	}
194263d483cdSSepherosa Ziehau 
194363d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
194463d483cdSSepherosa Ziehau }
194563d483cdSSepherosa Ziehau 
194663d483cdSSepherosa Ziehau /**
194763d483cdSSepherosa Ziehau  * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause
194863d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
194963d483cdSSepherosa Ziehau  * @lsc: pointer to boolean flag which indicates whether external Base T
195063d483cdSSepherosa Ziehau  *       PHY interrupt is lsc
195163d483cdSSepherosa Ziehau  *
195263d483cdSSepherosa Ziehau  * Determime if external Base T PHY interrupt cause is high temperature
195363d483cdSSepherosa Ziehau  * failure alarm or link status change.
195463d483cdSSepherosa Ziehau  *
195563d483cdSSepherosa Ziehau  * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
195663d483cdSSepherosa Ziehau  * failure alarm, else return PHY access status.
195763d483cdSSepherosa Ziehau  */
ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw * hw,bool * lsc)195863d483cdSSepherosa Ziehau static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
195963d483cdSSepherosa Ziehau {
196063d483cdSSepherosa Ziehau 	u32 status;
196163d483cdSSepherosa Ziehau 	u16 reg;
196263d483cdSSepherosa Ziehau 
196363d483cdSSepherosa Ziehau 	*lsc = FALSE;
196463d483cdSSepherosa Ziehau 
196563d483cdSSepherosa Ziehau 	/* Vendor alarm triggered */
196663d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
196763d483cdSSepherosa Ziehau 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
196863d483cdSSepherosa Ziehau 				      &reg);
196963d483cdSSepherosa Ziehau 
197063d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS ||
197163d483cdSSepherosa Ziehau 	    !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN))
197263d483cdSSepherosa Ziehau 		return status;
197363d483cdSSepherosa Ziehau 
197463d483cdSSepherosa Ziehau 	/* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */
197563d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG,
197663d483cdSSepherosa Ziehau 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
197763d483cdSSepherosa Ziehau 				      &reg);
197863d483cdSSepherosa Ziehau 
197963d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS ||
198063d483cdSSepherosa Ziehau 	    !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
198163d483cdSSepherosa Ziehau 	    IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
198263d483cdSSepherosa Ziehau 		return status;
198363d483cdSSepherosa Ziehau 
19846150453fSSepherosa Ziehau 	/* Global alarm triggered */
198563d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
198663d483cdSSepherosa Ziehau 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
198763d483cdSSepherosa Ziehau 				      &reg);
198863d483cdSSepherosa Ziehau 
198963d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
199063d483cdSSepherosa Ziehau 		return status;
199163d483cdSSepherosa Ziehau 
199263d483cdSSepherosa Ziehau 	/* If high temperature failure, then return over temp error and exit */
199363d483cdSSepherosa Ziehau 	if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
199463d483cdSSepherosa Ziehau 		/* power down the PHY in case the PHY FW didn't already */
199563d483cdSSepherosa Ziehau 		ixgbe_set_copper_phy_power(hw, FALSE);
199663d483cdSSepherosa Ziehau 		return IXGBE_ERR_OVERTEMP;
19976150453fSSepherosa Ziehau 	} else if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
19986150453fSSepherosa Ziehau 		/*  device fault alarm triggered */
19996150453fSSepherosa Ziehau 		status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
20006150453fSSepherosa Ziehau 					  IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
20016150453fSSepherosa Ziehau 					  &reg);
20026150453fSSepherosa Ziehau 
20036150453fSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
20046150453fSSepherosa Ziehau 			return status;
20056150453fSSepherosa Ziehau 
20066150453fSSepherosa Ziehau 		/* if device fault was due to high temp alarm handle and exit */
20076150453fSSepherosa Ziehau 		if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
20086150453fSSepherosa Ziehau 			/* power down the PHY in case the PHY FW didn't */
20096150453fSSepherosa Ziehau 			ixgbe_set_copper_phy_power(hw, FALSE);
20106150453fSSepherosa Ziehau 			return IXGBE_ERR_OVERTEMP;
20116150453fSSepherosa Ziehau 		}
201263d483cdSSepherosa Ziehau 	}
201363d483cdSSepherosa Ziehau 
201463d483cdSSepherosa Ziehau 	/* Vendor alarm 2 triggered */
201563d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
201663d483cdSSepherosa Ziehau 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
201763d483cdSSepherosa Ziehau 
201863d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS ||
201963d483cdSSepherosa Ziehau 	    !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT))
202063d483cdSSepherosa Ziehau 		return status;
202163d483cdSSepherosa Ziehau 
202263d483cdSSepherosa Ziehau 	/* link connect/disconnect event occurred */
202363d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2,
202463d483cdSSepherosa Ziehau 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
202563d483cdSSepherosa Ziehau 
202663d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
202763d483cdSSepherosa Ziehau 		return status;
202863d483cdSSepherosa Ziehau 
202963d483cdSSepherosa Ziehau 	/* Indicate LSC */
203063d483cdSSepherosa Ziehau 	if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC)
203163d483cdSSepherosa Ziehau 		*lsc = TRUE;
203263d483cdSSepherosa Ziehau 
203363d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
203463d483cdSSepherosa Ziehau }
203563d483cdSSepherosa Ziehau 
203663d483cdSSepherosa Ziehau /**
203763d483cdSSepherosa Ziehau  * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts
203863d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
203963d483cdSSepherosa Ziehau  *
204063d483cdSSepherosa Ziehau  * Enable link status change and temperature failure alarm for the external
204163d483cdSSepherosa Ziehau  * Base T PHY
204263d483cdSSepherosa Ziehau  *
204363d483cdSSepherosa Ziehau  * Returns PHY access status
204463d483cdSSepherosa Ziehau  */
ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw * hw)204563d483cdSSepherosa Ziehau static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
204663d483cdSSepherosa Ziehau {
204763d483cdSSepherosa Ziehau 	u32 status;
204863d483cdSSepherosa Ziehau 	u16 reg;
204963d483cdSSepherosa Ziehau 	bool lsc;
205063d483cdSSepherosa Ziehau 
205163d483cdSSepherosa Ziehau 	/* Clear interrupt flags */
205263d483cdSSepherosa Ziehau 	status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
205363d483cdSSepherosa Ziehau 
205463d483cdSSepherosa Ziehau 	/* Enable link status change alarm */
20556150453fSSepherosa Ziehau 
20566150453fSSepherosa Ziehau 	/* Enable the LASI interrupts on X552 devices to receive notifications
20576150453fSSepherosa Ziehau 	 * of the link configurations of the external PHY and correspondingly
20586150453fSSepherosa Ziehau 	 * support the configuration of the internal iXFI link, since iXFI does
20596150453fSSepherosa Ziehau 	 * not support auto-negotiation. This is not required for X553 devices
20606150453fSSepherosa Ziehau 	 * having KR support, which performs auto-negotiations and which is used
20616150453fSSepherosa Ziehau 	 * as the internal link to the external PHY. Hence adding a check here
20626150453fSSepherosa Ziehau 	 * to avoid enabling LASI interrupts for X553 devices.
20636150453fSSepherosa Ziehau 	 */
20646150453fSSepherosa Ziehau 	if (hw->mac.type != ixgbe_mac_X550EM_a) {
20656150453fSSepherosa Ziehau 		status = hw->phy.ops.read_reg(hw,
20666150453fSSepherosa Ziehau 					IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
206763d483cdSSepherosa Ziehau 					IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
206863d483cdSSepherosa Ziehau 
206963d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
207063d483cdSSepherosa Ziehau 			return status;
207163d483cdSSepherosa Ziehau 
207263d483cdSSepherosa Ziehau 		reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN;
207363d483cdSSepherosa Ziehau 
20746150453fSSepherosa Ziehau 		status = hw->phy.ops.write_reg(hw,
20756150453fSSepherosa Ziehau 					IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
207663d483cdSSepherosa Ziehau 					IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg);
207763d483cdSSepherosa Ziehau 
207863d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
207963d483cdSSepherosa Ziehau 			return status;
20806150453fSSepherosa Ziehau 	}
208163d483cdSSepherosa Ziehau 
20826150453fSSepherosa Ziehau 	/* Enable high temperature failure and global fault alarms */
208363d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
208463d483cdSSepherosa Ziehau 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
208563d483cdSSepherosa Ziehau 				      &reg);
208663d483cdSSepherosa Ziehau 
208763d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
208863d483cdSSepherosa Ziehau 		return status;
208963d483cdSSepherosa Ziehau 
20906150453fSSepherosa Ziehau 	reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN |
20916150453fSSepherosa Ziehau 		IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN);
209263d483cdSSepherosa Ziehau 
209363d483cdSSepherosa Ziehau 	status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
209463d483cdSSepherosa Ziehau 				       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
209563d483cdSSepherosa Ziehau 				       reg);
209663d483cdSSepherosa Ziehau 
209763d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
209863d483cdSSepherosa Ziehau 		return status;
209963d483cdSSepherosa Ziehau 
210063d483cdSSepherosa Ziehau 	/* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */
210163d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
210263d483cdSSepherosa Ziehau 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
210363d483cdSSepherosa Ziehau 				      &reg);
210463d483cdSSepherosa Ziehau 
210563d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
210663d483cdSSepherosa Ziehau 		return status;
210763d483cdSSepherosa Ziehau 
210863d483cdSSepherosa Ziehau 	reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
210963d483cdSSepherosa Ziehau 		IXGBE_MDIO_GLOBAL_ALARM_1_INT);
211063d483cdSSepherosa Ziehau 
211163d483cdSSepherosa Ziehau 	status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
211263d483cdSSepherosa Ziehau 				       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
211363d483cdSSepherosa Ziehau 				       reg);
211463d483cdSSepherosa Ziehau 
211563d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
211663d483cdSSepherosa Ziehau 		return status;
211763d483cdSSepherosa Ziehau 
211863d483cdSSepherosa Ziehau 	/* Enable chip-wide vendor alarm */
211963d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
212063d483cdSSepherosa Ziehau 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
212163d483cdSSepherosa Ziehau 				      &reg);
212263d483cdSSepherosa Ziehau 
212363d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
212463d483cdSSepherosa Ziehau 		return status;
212563d483cdSSepherosa Ziehau 
212663d483cdSSepherosa Ziehau 	reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN;
212763d483cdSSepherosa Ziehau 
212863d483cdSSepherosa Ziehau 	status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
212963d483cdSSepherosa Ziehau 				       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
213063d483cdSSepherosa Ziehau 				       reg);
213163d483cdSSepherosa Ziehau 
213263d483cdSSepherosa Ziehau 	return status;
213363d483cdSSepherosa Ziehau }
213463d483cdSSepherosa Ziehau 
213563d483cdSSepherosa Ziehau /**
213663d483cdSSepherosa Ziehau  *  ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed.
213763d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
213863d483cdSSepherosa Ziehau  *  @speed: link speed
213963d483cdSSepherosa Ziehau  *
214063d483cdSSepherosa Ziehau  *  Configures the integrated KR PHY.
214163d483cdSSepherosa Ziehau  **/
ixgbe_setup_kr_speed_x550em(struct ixgbe_hw * hw,ixgbe_link_speed speed)214263d483cdSSepherosa Ziehau static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
214363d483cdSSepherosa Ziehau 				       ixgbe_link_speed speed)
214463d483cdSSepherosa Ziehau {
214563d483cdSSepherosa Ziehau 	s32 status;
214663d483cdSSepherosa Ziehau 	u32 reg_val;
214763d483cdSSepherosa Ziehau 
21486150453fSSepherosa Ziehau 	status = hw->mac.ops.read_iosf_sb_reg(hw,
214963d483cdSSepherosa Ziehau 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
215063d483cdSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
215163d483cdSSepherosa Ziehau 	if (status)
215263d483cdSSepherosa Ziehau 		return status;
215363d483cdSSepherosa Ziehau 
215463d483cdSSepherosa Ziehau 	reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
215563d483cdSSepherosa Ziehau 	reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
215663d483cdSSepherosa Ziehau 		     IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
215763d483cdSSepherosa Ziehau 
215863d483cdSSepherosa Ziehau 	/* Advertise 10G support. */
215963d483cdSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
216063d483cdSSepherosa Ziehau 		reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
216163d483cdSSepherosa Ziehau 
216263d483cdSSepherosa Ziehau 	/* Advertise 1G support. */
216363d483cdSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
216463d483cdSSepherosa Ziehau 		reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
216563d483cdSSepherosa Ziehau 
21666150453fSSepherosa Ziehau 	status = hw->mac.ops.write_iosf_sb_reg(hw,
216763d483cdSSepherosa Ziehau 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
216863d483cdSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
216963d483cdSSepherosa Ziehau 
21706150453fSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_X550EM_a) {
21716150453fSSepherosa Ziehau 		/* Set lane mode  to KR auto negotiation */
21726150453fSSepherosa Ziehau 		status = hw->mac.ops.read_iosf_sb_reg(hw,
21736150453fSSepherosa Ziehau 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
21746150453fSSepherosa Ziehau 				    IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
21756150453fSSepherosa Ziehau 
21766150453fSSepherosa Ziehau 		if (status)
217763d483cdSSepherosa Ziehau 			return status;
21786150453fSSepherosa Ziehau 
21796150453fSSepherosa Ziehau 		reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
21806150453fSSepherosa Ziehau 		reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
21816150453fSSepherosa Ziehau 		reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
21826150453fSSepherosa Ziehau 		reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
21836150453fSSepherosa Ziehau 		reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
21846150453fSSepherosa Ziehau 
21856150453fSSepherosa Ziehau 		status = hw->mac.ops.write_iosf_sb_reg(hw,
21866150453fSSepherosa Ziehau 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
21876150453fSSepherosa Ziehau 				    IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
21886150453fSSepherosa Ziehau 	}
21896150453fSSepherosa Ziehau 
21906150453fSSepherosa Ziehau 	return ixgbe_restart_an_internal_phy_x550em(hw);
21916150453fSSepherosa Ziehau }
21926150453fSSepherosa Ziehau 
21936150453fSSepherosa Ziehau /**
21946150453fSSepherosa Ziehau  * ixgbe_reset_phy_fw - Reset firmware-controlled PHYs
21956150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
21966150453fSSepherosa Ziehau  */
ixgbe_reset_phy_fw(struct ixgbe_hw * hw)21976150453fSSepherosa Ziehau static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw)
21986150453fSSepherosa Ziehau {
21996150453fSSepherosa Ziehau 	u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
22006150453fSSepherosa Ziehau 	s32 rc;
22016150453fSSepherosa Ziehau 
22026150453fSSepherosa Ziehau 	if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
22036150453fSSepherosa Ziehau 		return IXGBE_SUCCESS;
22046150453fSSepherosa Ziehau 
22056150453fSSepherosa Ziehau 	rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_PHY_SW_RESET, &store);
22066150453fSSepherosa Ziehau 	if (rc)
22076150453fSSepherosa Ziehau 		return rc;
22086150453fSSepherosa Ziehau 	memset(store, 0, sizeof(store));
22096150453fSSepherosa Ziehau 
22106150453fSSepherosa Ziehau 	rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_INIT_PHY, &store);
22116150453fSSepherosa Ziehau 	if (rc)
22126150453fSSepherosa Ziehau 		return rc;
22136150453fSSepherosa Ziehau 
22146150453fSSepherosa Ziehau 	return ixgbe_setup_fw_link(hw);
22156150453fSSepherosa Ziehau }
22166150453fSSepherosa Ziehau 
22176150453fSSepherosa Ziehau /**
22186150453fSSepherosa Ziehau  * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp
22196150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
22206150453fSSepherosa Ziehau  */
ixgbe_check_overtemp_fw(struct ixgbe_hw * hw)22216150453fSSepherosa Ziehau static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw)
22226150453fSSepherosa Ziehau {
22236150453fSSepherosa Ziehau 	u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
22246150453fSSepherosa Ziehau 	s32 rc;
22256150453fSSepherosa Ziehau 
22266150453fSSepherosa Ziehau 	rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store);
22276150453fSSepherosa Ziehau 	if (rc)
22286150453fSSepherosa Ziehau 		return rc;
22296150453fSSepherosa Ziehau 
22306150453fSSepherosa Ziehau 	if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) {
22316150453fSSepherosa Ziehau 		ixgbe_shutdown_fw_phy(hw);
22326150453fSSepherosa Ziehau 		return IXGBE_ERR_OVERTEMP;
22336150453fSSepherosa Ziehau 	}
22346150453fSSepherosa Ziehau 	return IXGBE_SUCCESS;
22356150453fSSepherosa Ziehau }
22366150453fSSepherosa Ziehau 
22376150453fSSepherosa Ziehau /**
22386150453fSSepherosa Ziehau  *  ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register
22396150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
22406150453fSSepherosa Ziehau  *
22416150453fSSepherosa Ziehau  *  Read NW_MNG_IF_SEL register and save field values, and check for valid field
22426150453fSSepherosa Ziehau  *  values.
22436150453fSSepherosa Ziehau  **/
ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw * hw)22446150453fSSepherosa Ziehau static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw)
22456150453fSSepherosa Ziehau {
22466150453fSSepherosa Ziehau 	/* Save NW management interface connected on board. This is used
22476150453fSSepherosa Ziehau 	 * to determine internal PHY mode.
22486150453fSSepherosa Ziehau 	 */
22496150453fSSepherosa Ziehau 	hw->phy.nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
22506150453fSSepherosa Ziehau 
22516150453fSSepherosa Ziehau 	/* If X552 (X550EM_a) and MDIO is connected to external PHY, then set
22526150453fSSepherosa Ziehau 	 * PHY address. This register field was has only been used for X552.
22536150453fSSepherosa Ziehau 	 */
22546150453fSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_X550EM_a &&
22556150453fSSepherosa Ziehau 	    hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_MDIO_ACT) {
22566150453fSSepherosa Ziehau 		hw->phy.addr = (hw->phy.nw_mng_if_sel &
22576150453fSSepherosa Ziehau 				IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >>
22586150453fSSepherosa Ziehau 			       IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT;
22596150453fSSepherosa Ziehau 	}
22606150453fSSepherosa Ziehau 
22616150453fSSepherosa Ziehau 	return IXGBE_SUCCESS;
226263d483cdSSepherosa Ziehau }
226363d483cdSSepherosa Ziehau 
226463d483cdSSepherosa Ziehau /**
226563d483cdSSepherosa Ziehau  *  ixgbe_init_phy_ops_X550em - PHY/SFP specific init
226663d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
226763d483cdSSepherosa Ziehau  *
226863d483cdSSepherosa Ziehau  *  Initialize any function pointers that were not able to be
226963d483cdSSepherosa Ziehau  *  set during init_shared_code because the PHY/SFP type was
227063d483cdSSepherosa Ziehau  *  not known.  Perform the SFP init if necessary.
227163d483cdSSepherosa Ziehau  */
ixgbe_init_phy_ops_X550em(struct ixgbe_hw * hw)227263d483cdSSepherosa Ziehau s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
227363d483cdSSepherosa Ziehau {
227463d483cdSSepherosa Ziehau 	struct ixgbe_phy_info *phy = &hw->phy;
227563d483cdSSepherosa Ziehau 	s32 ret_val;
227663d483cdSSepherosa Ziehau 
227763d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_phy_ops_X550em");
227863d483cdSSepherosa Ziehau 
227963d483cdSSepherosa Ziehau 	hw->mac.ops.set_lan_id(hw);
22806150453fSSepherosa Ziehau 	ixgbe_read_mng_if_sel_x550em(hw);
228163d483cdSSepherosa Ziehau 
228263d483cdSSepherosa Ziehau 	if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
228363d483cdSSepherosa Ziehau 		phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
228463d483cdSSepherosa Ziehau 		ixgbe_setup_mux_ctl(hw);
22856150453fSSepherosa Ziehau 		phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em;
228663d483cdSSepherosa Ziehau 	}
228763d483cdSSepherosa Ziehau 
22886150453fSSepherosa Ziehau 	switch (hw->device_id) {
22896150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T:
22906150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
22916150453fSSepherosa Ziehau 		phy->ops.read_reg_mdi = NULL;
22926150453fSSepherosa Ziehau 		phy->ops.write_reg_mdi = NULL;
22936150453fSSepherosa Ziehau 		hw->phy.ops.read_reg = NULL;
22946150453fSSepherosa Ziehau 		hw->phy.ops.write_reg = NULL;
22956150453fSSepherosa Ziehau 		phy->ops.check_overtemp = ixgbe_check_overtemp_fw;
22966150453fSSepherosa Ziehau 		if (hw->bus.lan_id)
22976150453fSSepherosa Ziehau 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
22986150453fSSepherosa Ziehau 		else
22996150453fSSepherosa Ziehau 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
23006150453fSSepherosa Ziehau 
23016150453fSSepherosa Ziehau 		break;
23026150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_10G_T:
23036150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_SFP:
23046150453fSSepherosa Ziehau 		hw->phy.ops.read_reg = ixgbe_read_phy_reg_x550a;
23056150453fSSepherosa Ziehau 		hw->phy.ops.write_reg = ixgbe_write_phy_reg_x550a;
23066150453fSSepherosa Ziehau 		if (hw->bus.lan_id)
23076150453fSSepherosa Ziehau 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
23086150453fSSepherosa Ziehau 		else
23096150453fSSepherosa Ziehau 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
23106150453fSSepherosa Ziehau 		break;
23116150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_SFP:
23126150453fSSepherosa Ziehau 		/* set up for CS4227 usage */
23136150453fSSepherosa Ziehau 		hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
23146150453fSSepherosa Ziehau 		break;
23156150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_1G_T:
23166150453fSSepherosa Ziehau 		phy->ops.read_reg_mdi = NULL;
23176150453fSSepherosa Ziehau 		phy->ops.write_reg_mdi = NULL;
23186150453fSSepherosa Ziehau 	default:
23196150453fSSepherosa Ziehau 		break;
232063d483cdSSepherosa Ziehau 	}
232163d483cdSSepherosa Ziehau 
232263d483cdSSepherosa Ziehau 	/* Identify the PHY or SFP module */
232363d483cdSSepherosa Ziehau 	ret_val = phy->ops.identify(hw);
23246150453fSSepherosa Ziehau 	if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED ||
23256150453fSSepherosa Ziehau 	    ret_val == IXGBE_ERR_PHY_ADDR_INVALID)
232663d483cdSSepherosa Ziehau 		return ret_val;
232763d483cdSSepherosa Ziehau 
232863d483cdSSepherosa Ziehau 	/* Setup function pointers based on detected hardware */
232963d483cdSSepherosa Ziehau 	ixgbe_init_mac_link_ops_X550em(hw);
233063d483cdSSepherosa Ziehau 	if (phy->sfp_type != ixgbe_sfp_type_unknown)
233163d483cdSSepherosa Ziehau 		phy->ops.reset = NULL;
233263d483cdSSepherosa Ziehau 
233363d483cdSSepherosa Ziehau 	/* Set functions pointers based on phy type */
233463d483cdSSepherosa Ziehau 	switch (hw->phy.type) {
233563d483cdSSepherosa Ziehau 	case ixgbe_phy_x550em_kx4:
23366150453fSSepherosa Ziehau 		phy->ops.setup_link = NULL;
233763d483cdSSepherosa Ziehau 		phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
233863d483cdSSepherosa Ziehau 		phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
233963d483cdSSepherosa Ziehau 		break;
234063d483cdSSepherosa Ziehau 	case ixgbe_phy_x550em_kr:
234163d483cdSSepherosa Ziehau 		phy->ops.setup_link = ixgbe_setup_kr_x550em;
234263d483cdSSepherosa Ziehau 		phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
234363d483cdSSepherosa Ziehau 		phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
234463d483cdSSepherosa Ziehau 		break;
23456150453fSSepherosa Ziehau 	case ixgbe_phy_ext_1g_t:
23466150453fSSepherosa Ziehau 		/* link is managed by FW */
23476150453fSSepherosa Ziehau 		phy->ops.setup_link = NULL;
23486150453fSSepherosa Ziehau 		phy->ops.reset = NULL;
23496150453fSSepherosa Ziehau 		break;
23506150453fSSepherosa Ziehau 	case ixgbe_phy_x550em_xfi:
23516150453fSSepherosa Ziehau 		/* link is managed by HW */
23526150453fSSepherosa Ziehau 		phy->ops.setup_link = NULL;
23536150453fSSepherosa Ziehau 		phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
23546150453fSSepherosa Ziehau 		phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
23556150453fSSepherosa Ziehau 		break;
235663d483cdSSepherosa Ziehau 	case ixgbe_phy_x550em_ext_t:
235763d483cdSSepherosa Ziehau 		/* If internal link mode is XFI, then setup iXFI internal link,
235863d483cdSSepherosa Ziehau 		 * else setup KR now.
235963d483cdSSepherosa Ziehau 		 */
236063d483cdSSepherosa Ziehau 		phy->ops.setup_internal_link =
236163d483cdSSepherosa Ziehau 					      ixgbe_setup_internal_phy_t_x550em;
236263d483cdSSepherosa Ziehau 
23636150453fSSepherosa Ziehau 		/* setup SW LPLU only for first revision of X550EM_x */
23646150453fSSepherosa Ziehau 		if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
23656150453fSSepherosa Ziehau 		    !(IXGBE_FUSES0_REV_MASK &
23666150453fSSepherosa Ziehau 		      IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
236763d483cdSSepherosa Ziehau 			phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
23686150453fSSepherosa Ziehau 
236963d483cdSSepherosa Ziehau 		phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
237063d483cdSSepherosa Ziehau 		phy->ops.reset = ixgbe_reset_phy_t_X550em;
237163d483cdSSepherosa Ziehau 		break;
23726150453fSSepherosa Ziehau 	case ixgbe_phy_sgmii:
23736150453fSSepherosa Ziehau 		phy->ops.setup_link = NULL;
23746150453fSSepherosa Ziehau 		break;
23756150453fSSepherosa Ziehau 	case ixgbe_phy_fw:
23766150453fSSepherosa Ziehau 		phy->ops.setup_link = ixgbe_setup_fw_link;
23776150453fSSepherosa Ziehau 		phy->ops.reset = ixgbe_reset_phy_fw;
23786150453fSSepherosa Ziehau 		break;
237963d483cdSSepherosa Ziehau 	default:
238063d483cdSSepherosa Ziehau 		break;
238163d483cdSSepherosa Ziehau 	}
238263d483cdSSepherosa Ziehau 	return ret_val;
238363d483cdSSepherosa Ziehau }
238463d483cdSSepherosa Ziehau 
238563d483cdSSepherosa Ziehau /**
23866150453fSSepherosa Ziehau  * ixgbe_set_mdio_speed - Set MDIO clock speed
23876150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
23886150453fSSepherosa Ziehau  */
ixgbe_set_mdio_speed(struct ixgbe_hw * hw)23896150453fSSepherosa Ziehau static void ixgbe_set_mdio_speed(struct ixgbe_hw *hw)
23906150453fSSepherosa Ziehau {
23916150453fSSepherosa Ziehau 	u32 hlreg0;
23926150453fSSepherosa Ziehau 
23936150453fSSepherosa Ziehau 	switch (hw->device_id) {
23946150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_10G_T:
23956150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_SGMII:
23966150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_SGMII_L:
23976150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_10G_T:
23986150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_SFP:
23996150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_QSFP:
24006150453fSSepherosa Ziehau 		/* Config MDIO clock speed before the first MDIO PHY access */
24016150453fSSepherosa Ziehau 		hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
24026150453fSSepherosa Ziehau 		hlreg0 &= ~IXGBE_HLREG0_MDCSPD;
24036150453fSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
24046150453fSSepherosa Ziehau 		break;
24056150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T:
24066150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
24076150453fSSepherosa Ziehau 		/* Select fast MDIO clock speed for these devices */
24086150453fSSepherosa Ziehau 		hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
24096150453fSSepherosa Ziehau 		hlreg0 |= IXGBE_HLREG0_MDCSPD;
24106150453fSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
24116150453fSSepherosa Ziehau 		break;
24126150453fSSepherosa Ziehau 	default:
24136150453fSSepherosa Ziehau 		break;
24146150453fSSepherosa Ziehau 	}
24156150453fSSepherosa Ziehau }
24166150453fSSepherosa Ziehau 
24176150453fSSepherosa Ziehau /**
241863d483cdSSepherosa Ziehau  *  ixgbe_reset_hw_X550em - Perform hardware reset
241963d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
242063d483cdSSepherosa Ziehau  *
242163d483cdSSepherosa Ziehau  *  Resets the hardware by resetting the transmit and receive units, masks
242263d483cdSSepherosa Ziehau  *  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
242363d483cdSSepherosa Ziehau  *  reset.
242463d483cdSSepherosa Ziehau  */
ixgbe_reset_hw_X550em(struct ixgbe_hw * hw)242563d483cdSSepherosa Ziehau s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
242663d483cdSSepherosa Ziehau {
242763d483cdSSepherosa Ziehau 	ixgbe_link_speed link_speed;
242863d483cdSSepherosa Ziehau 	s32 status;
242963d483cdSSepherosa Ziehau 	u32 ctrl = 0;
243063d483cdSSepherosa Ziehau 	u32 i;
243163d483cdSSepherosa Ziehau 	bool link_up = FALSE;
24326150453fSSepherosa Ziehau 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
243363d483cdSSepherosa Ziehau 
243463d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_reset_hw_X550em");
243563d483cdSSepherosa Ziehau 
243663d483cdSSepherosa Ziehau 	/* Call adapter stop to disable Tx/Rx and clear interrupts */
243763d483cdSSepherosa Ziehau 	status = hw->mac.ops.stop_adapter(hw);
24386150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS) {
24396150453fSSepherosa Ziehau 		DEBUGOUT1("Failed to stop adapter, STATUS = %d\n", status);
244063d483cdSSepherosa Ziehau 		return status;
24416150453fSSepherosa Ziehau 	}
244263d483cdSSepherosa Ziehau 	/* flush pending Tx transactions */
244363d483cdSSepherosa Ziehau 	ixgbe_clear_tx_pending(hw);
244463d483cdSSepherosa Ziehau 
24456150453fSSepherosa Ziehau 	ixgbe_set_mdio_speed(hw);
244663d483cdSSepherosa Ziehau 
24476150453fSSepherosa Ziehau 	/* PHY ops must be identified and initialized prior to reset */
244863d483cdSSepherosa Ziehau 	status = hw->phy.ops.init(hw);
244963d483cdSSepherosa Ziehau 
24506150453fSSepherosa Ziehau 	if (status)
24516150453fSSepherosa Ziehau 		DEBUGOUT1("Failed to initialize PHY ops, STATUS = %d\n",
24526150453fSSepherosa Ziehau 			  status);
24536150453fSSepherosa Ziehau 
24546150453fSSepherosa Ziehau 	if (status == IXGBE_ERR_SFP_NOT_SUPPORTED ||
24556150453fSSepherosa Ziehau 	    status == IXGBE_ERR_PHY_ADDR_INVALID) {
24566150453fSSepherosa Ziehau 		DEBUGOUT("Returning from reset HW due to PHY init failure\n");
245763d483cdSSepherosa Ziehau 		return status;
24586150453fSSepherosa Ziehau 	}
245963d483cdSSepherosa Ziehau 
246063d483cdSSepherosa Ziehau 	/* start the external PHY */
246163d483cdSSepherosa Ziehau 	if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
246263d483cdSSepherosa Ziehau 		status = ixgbe_init_ext_t_x550em(hw);
24636150453fSSepherosa Ziehau 		if (status) {
24646150453fSSepherosa Ziehau 			DEBUGOUT1("Failed to start the external PHY, STATUS = %d\n",
24656150453fSSepherosa Ziehau 				  status);
246663d483cdSSepherosa Ziehau 			return status;
246763d483cdSSepherosa Ziehau 		}
24686150453fSSepherosa Ziehau 	}
246963d483cdSSepherosa Ziehau 
247063d483cdSSepherosa Ziehau 	/* Setup SFP module if there is one present. */
247163d483cdSSepherosa Ziehau 	if (hw->phy.sfp_setup_needed) {
247263d483cdSSepherosa Ziehau 		status = hw->mac.ops.setup_sfp(hw);
247363d483cdSSepherosa Ziehau 		hw->phy.sfp_setup_needed = FALSE;
247463d483cdSSepherosa Ziehau 	}
247563d483cdSSepherosa Ziehau 
247663d483cdSSepherosa Ziehau 	if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
247763d483cdSSepherosa Ziehau 		return status;
247863d483cdSSepherosa Ziehau 
247963d483cdSSepherosa Ziehau 	/* Reset PHY */
24806150453fSSepherosa Ziehau 	if (!hw->phy.reset_disable && hw->phy.ops.reset) {
24816150453fSSepherosa Ziehau 		if (hw->phy.ops.reset(hw) == IXGBE_ERR_OVERTEMP)
24826150453fSSepherosa Ziehau 			return IXGBE_ERR_OVERTEMP;
24836150453fSSepherosa Ziehau 	}
248463d483cdSSepherosa Ziehau 
248563d483cdSSepherosa Ziehau mac_reset_top:
248663d483cdSSepherosa Ziehau 	/* Issue global reset to the MAC.  Needs to be SW reset if link is up.
248763d483cdSSepherosa Ziehau 	 * If link reset is used when link is up, it might reset the PHY when
248863d483cdSSepherosa Ziehau 	 * mng is using it.  If link is down or the flag to force full link
248963d483cdSSepherosa Ziehau 	 * reset is set, then perform link reset.
249063d483cdSSepherosa Ziehau 	 */
249163d483cdSSepherosa Ziehau 	ctrl = IXGBE_CTRL_LNK_RST;
249263d483cdSSepherosa Ziehau 	if (!hw->force_full_reset) {
249363d483cdSSepherosa Ziehau 		hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
249463d483cdSSepherosa Ziehau 		if (link_up)
249563d483cdSSepherosa Ziehau 			ctrl = IXGBE_CTRL_RST;
249663d483cdSSepherosa Ziehau 	}
249763d483cdSSepherosa Ziehau 
24986150453fSSepherosa Ziehau 	status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
24996150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS) {
25006150453fSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_CAUTION,
25016150453fSSepherosa Ziehau 			"semaphore failed with %d", status);
25026150453fSSepherosa Ziehau 		return IXGBE_ERR_SWFW_SYNC;
25036150453fSSepherosa Ziehau 	}
250463d483cdSSepherosa Ziehau 	ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
250563d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
250663d483cdSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
25076150453fSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
250863d483cdSSepherosa Ziehau 
250963d483cdSSepherosa Ziehau 	/* Poll for reset bit to self-clear meaning reset is complete */
251063d483cdSSepherosa Ziehau 	for (i = 0; i < 10; i++) {
251163d483cdSSepherosa Ziehau 		usec_delay(1);
251263d483cdSSepherosa Ziehau 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
251363d483cdSSepherosa Ziehau 		if (!(ctrl & IXGBE_CTRL_RST_MASK))
251463d483cdSSepherosa Ziehau 			break;
251563d483cdSSepherosa Ziehau 	}
251663d483cdSSepherosa Ziehau 
251763d483cdSSepherosa Ziehau 	if (ctrl & IXGBE_CTRL_RST_MASK) {
251863d483cdSSepherosa Ziehau 		status = IXGBE_ERR_RESET_FAILED;
251963d483cdSSepherosa Ziehau 		DEBUGOUT("Reset polling failed to complete.\n");
252063d483cdSSepherosa Ziehau 	}
252163d483cdSSepherosa Ziehau 
252263d483cdSSepherosa Ziehau 	msec_delay(50);
252363d483cdSSepherosa Ziehau 
252463d483cdSSepherosa Ziehau 	/* Double resets are required for recovery from certain error
252563d483cdSSepherosa Ziehau 	 * conditions.  Between resets, it is necessary to stall to
252663d483cdSSepherosa Ziehau 	 * allow time for any pending HW events to complete.
252763d483cdSSepherosa Ziehau 	 */
252863d483cdSSepherosa Ziehau 	if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
252963d483cdSSepherosa Ziehau 		hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
253063d483cdSSepherosa Ziehau 		goto mac_reset_top;
253163d483cdSSepherosa Ziehau 	}
253263d483cdSSepherosa Ziehau 
253363d483cdSSepherosa Ziehau 	/* Store the permanent mac address */
253463d483cdSSepherosa Ziehau 	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
253563d483cdSSepherosa Ziehau 
253663d483cdSSepherosa Ziehau 	/* Store MAC address from RAR0, clear receive address registers, and
253763d483cdSSepherosa Ziehau 	 * clear the multicast table.  Also reset num_rar_entries to 128,
253863d483cdSSepherosa Ziehau 	 * since we modify this value when programming the SAN MAC address.
253963d483cdSSepherosa Ziehau 	 */
254063d483cdSSepherosa Ziehau 	hw->mac.num_rar_entries = 128;
254163d483cdSSepherosa Ziehau 	hw->mac.ops.init_rx_addrs(hw);
254263d483cdSSepherosa Ziehau 
25436150453fSSepherosa Ziehau 	ixgbe_set_mdio_speed(hw);
254463d483cdSSepherosa Ziehau 
254563d483cdSSepherosa Ziehau 	if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
254663d483cdSSepherosa Ziehau 		ixgbe_setup_mux_ctl(hw);
254763d483cdSSepherosa Ziehau 
25486150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
25496150453fSSepherosa Ziehau 		DEBUGOUT1("Reset HW failed, STATUS = %d\n", status);
25506150453fSSepherosa Ziehau 
255163d483cdSSepherosa Ziehau 	return status;
255263d483cdSSepherosa Ziehau }
255363d483cdSSepherosa Ziehau 
255463d483cdSSepherosa Ziehau /**
255563d483cdSSepherosa Ziehau  * ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
255663d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
255763d483cdSSepherosa Ziehau  */
ixgbe_init_ext_t_x550em(struct ixgbe_hw * hw)255863d483cdSSepherosa Ziehau s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
255963d483cdSSepherosa Ziehau {
256063d483cdSSepherosa Ziehau 	u32 status;
256163d483cdSSepherosa Ziehau 	u16 reg;
256263d483cdSSepherosa Ziehau 
256363d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw,
256463d483cdSSepherosa Ziehau 				      IXGBE_MDIO_TX_VENDOR_ALARMS_3,
256563d483cdSSepherosa Ziehau 				      IXGBE_MDIO_PMA_PMD_DEV_TYPE,
256663d483cdSSepherosa Ziehau 				      &reg);
256763d483cdSSepherosa Ziehau 
256863d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
256963d483cdSSepherosa Ziehau 		return status;
257063d483cdSSepherosa Ziehau 
257163d483cdSSepherosa Ziehau 	/* If PHY FW reset completed bit is set then this is the first
257263d483cdSSepherosa Ziehau 	 * SW instance after a power on so the PHY FW must be un-stalled.
257363d483cdSSepherosa Ziehau 	 */
257463d483cdSSepherosa Ziehau 	if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
257563d483cdSSepherosa Ziehau 		status = hw->phy.ops.read_reg(hw,
257663d483cdSSepherosa Ziehau 					IXGBE_MDIO_GLOBAL_RES_PR_10,
257763d483cdSSepherosa Ziehau 					IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
257863d483cdSSepherosa Ziehau 					&reg);
257963d483cdSSepherosa Ziehau 
258063d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
258163d483cdSSepherosa Ziehau 			return status;
258263d483cdSSepherosa Ziehau 
258363d483cdSSepherosa Ziehau 		reg &= ~IXGBE_MDIO_POWER_UP_STALL;
258463d483cdSSepherosa Ziehau 
258563d483cdSSepherosa Ziehau 		status = hw->phy.ops.write_reg(hw,
258663d483cdSSepherosa Ziehau 					IXGBE_MDIO_GLOBAL_RES_PR_10,
258763d483cdSSepherosa Ziehau 					IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
258863d483cdSSepherosa Ziehau 					reg);
258963d483cdSSepherosa Ziehau 
259063d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
259163d483cdSSepherosa Ziehau 			return status;
259263d483cdSSepherosa Ziehau 	}
259363d483cdSSepherosa Ziehau 
259463d483cdSSepherosa Ziehau 	return status;
259563d483cdSSepherosa Ziehau }
259663d483cdSSepherosa Ziehau 
259763d483cdSSepherosa Ziehau /**
259863d483cdSSepherosa Ziehau  *  ixgbe_setup_kr_x550em - Configure the KR PHY.
259963d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
260063d483cdSSepherosa Ziehau  **/
ixgbe_setup_kr_x550em(struct ixgbe_hw * hw)260163d483cdSSepherosa Ziehau s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
260263d483cdSSepherosa Ziehau {
26036150453fSSepherosa Ziehau 	/* leave link alone for 2.5G */
26046150453fSSepherosa Ziehau 	if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL)
26056150453fSSepherosa Ziehau 		return IXGBE_SUCCESS;
26066150453fSSepherosa Ziehau 
26076150453fSSepherosa Ziehau 	if (ixgbe_check_reset_blocked(hw))
26086150453fSSepherosa Ziehau 		return 0;
26096150453fSSepherosa Ziehau 
261063d483cdSSepherosa Ziehau 	return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised);
261163d483cdSSepherosa Ziehau }
261263d483cdSSepherosa Ziehau 
261363d483cdSSepherosa Ziehau /**
261463d483cdSSepherosa Ziehau  *  ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP
261563d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
2616*dd5ce676SSepherosa Ziehau  *  @speed: new link speed
2617*dd5ce676SSepherosa Ziehau  *  @autoneg_wait_to_complete: unused
261863d483cdSSepherosa Ziehau  *
261963d483cdSSepherosa Ziehau  *  Configure the external PHY and the integrated KR PHY for SFP support.
262063d483cdSSepherosa Ziehau  **/
ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)262163d483cdSSepherosa Ziehau s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
262263d483cdSSepherosa Ziehau 				    ixgbe_link_speed speed,
262363d483cdSSepherosa Ziehau 				    bool autoneg_wait_to_complete)
262463d483cdSSepherosa Ziehau {
262563d483cdSSepherosa Ziehau 	s32 ret_val;
262663d483cdSSepherosa Ziehau 	u16 reg_slice, reg_val;
262763d483cdSSepherosa Ziehau 	bool setup_linear = FALSE;
262863d483cdSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
262963d483cdSSepherosa Ziehau 
263063d483cdSSepherosa Ziehau 	/* Check if SFP module is supported and linear */
263163d483cdSSepherosa Ziehau 	ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
263263d483cdSSepherosa Ziehau 
263363d483cdSSepherosa Ziehau 	/* If no SFP module present, then return success. Return success since
263463d483cdSSepherosa Ziehau 	 * there is no reason to configure CS4227 and SFP not present error is
263563d483cdSSepherosa Ziehau 	 * not excepted in the setup MAC link flow.
263663d483cdSSepherosa Ziehau 	 */
263763d483cdSSepherosa Ziehau 	if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
263863d483cdSSepherosa Ziehau 		return IXGBE_SUCCESS;
263963d483cdSSepherosa Ziehau 
264063d483cdSSepherosa Ziehau 	if (ret_val != IXGBE_SUCCESS)
264163d483cdSSepherosa Ziehau 		return ret_val;
264263d483cdSSepherosa Ziehau 
26436150453fSSepherosa Ziehau 	/* Configure internal PHY for KR/KX. */
26446150453fSSepherosa Ziehau 	ixgbe_setup_kr_speed_x550em(hw, speed);
264563d483cdSSepherosa Ziehau 
26466150453fSSepherosa Ziehau 	/* Configure CS4227 LINE side to proper mode. */
26476150453fSSepherosa Ziehau 	reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB +
26486150453fSSepherosa Ziehau 		    (hw->bus.lan_id << 12);
264963d483cdSSepherosa Ziehau 	if (setup_linear)
265063d483cdSSepherosa Ziehau 		reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
265163d483cdSSepherosa Ziehau 	else
265263d483cdSSepherosa Ziehau 		reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
26536150453fSSepherosa Ziehau 	ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice,
265463d483cdSSepherosa Ziehau 					  reg_val);
265563d483cdSSepherosa Ziehau 	return ret_val;
265663d483cdSSepherosa Ziehau }
265763d483cdSSepherosa Ziehau 
265863d483cdSSepherosa Ziehau /**
26596150453fSSepherosa Ziehau  *  ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode
26606150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
26616150453fSSepherosa Ziehau  *  @speed: the link speed to force
26626150453fSSepherosa Ziehau  *
26636150453fSSepherosa Ziehau  *  Configures the integrated PHY for native SFI mode. Used to connect the
26646150453fSSepherosa Ziehau  *  internal PHY directly to an SFP cage, without autonegotiation.
26656150453fSSepherosa Ziehau  **/
ixgbe_setup_sfi_x550a(struct ixgbe_hw * hw,ixgbe_link_speed * speed)26666150453fSSepherosa Ziehau static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
26676150453fSSepherosa Ziehau {
26686150453fSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
26696150453fSSepherosa Ziehau 	s32 status;
26706150453fSSepherosa Ziehau 	u32 reg_val;
26716150453fSSepherosa Ziehau 
26726150453fSSepherosa Ziehau 	/* Disable all AN and force speed to 10G Serial. */
26736150453fSSepherosa Ziehau 	status = mac->ops.read_iosf_sb_reg(hw,
26746150453fSSepherosa Ziehau 				IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
26756150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
26766150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
26776150453fSSepherosa Ziehau 		return status;
26786150453fSSepherosa Ziehau 
26796150453fSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
26806150453fSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
26816150453fSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
26826150453fSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
26836150453fSSepherosa Ziehau 
26846150453fSSepherosa Ziehau 	/* Select forced link speed for internal PHY. */
26856150453fSSepherosa Ziehau 	switch (*speed) {
26866150453fSSepherosa Ziehau 	case IXGBE_LINK_SPEED_10GB_FULL:
26876150453fSSepherosa Ziehau 		reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G;
26886150453fSSepherosa Ziehau 		break;
26896150453fSSepherosa Ziehau 	case IXGBE_LINK_SPEED_1GB_FULL:
26906150453fSSepherosa Ziehau 		reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
26916150453fSSepherosa Ziehau 		break;
26926150453fSSepherosa Ziehau 	default:
26936150453fSSepherosa Ziehau 		/* Other link speeds are not supported by internal PHY. */
26946150453fSSepherosa Ziehau 		return IXGBE_ERR_LINK_SETUP;
26956150453fSSepherosa Ziehau 	}
26966150453fSSepherosa Ziehau 
26976150453fSSepherosa Ziehau 	status = mac->ops.write_iosf_sb_reg(hw,
26986150453fSSepherosa Ziehau 				IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
26996150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
27006150453fSSepherosa Ziehau 
27016150453fSSepherosa Ziehau 	/* Toggle port SW reset by AN reset. */
27026150453fSSepherosa Ziehau 	status = ixgbe_restart_an_internal_phy_x550em(hw);
27036150453fSSepherosa Ziehau 
27046150453fSSepherosa Ziehau 	return status;
27056150453fSSepherosa Ziehau }
27066150453fSSepherosa Ziehau 
27076150453fSSepherosa Ziehau /**
27086150453fSSepherosa Ziehau  *  ixgbe_setup_mac_link_sfp_x550a - Setup internal PHY for SFP
27096150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
2710*dd5ce676SSepherosa Ziehau  *  @speed: new link speed
2711*dd5ce676SSepherosa Ziehau  *  @autoneg_wait_to_complete: unused
27126150453fSSepherosa Ziehau  *
27136150453fSSepherosa Ziehau  *  Configure the the integrated PHY for SFP support.
27146150453fSSepherosa Ziehau  **/
ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)27156150453fSSepherosa Ziehau s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
27166150453fSSepherosa Ziehau 				    ixgbe_link_speed speed,
27176150453fSSepherosa Ziehau 				    bool autoneg_wait_to_complete)
27186150453fSSepherosa Ziehau {
27196150453fSSepherosa Ziehau 	s32 ret_val;
27206150453fSSepherosa Ziehau 	u16 reg_phy_ext;
27216150453fSSepherosa Ziehau 	bool setup_linear = FALSE;
27226150453fSSepherosa Ziehau 	u32 reg_slice, reg_phy_int, slice_offset;
27236150453fSSepherosa Ziehau 
27246150453fSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
27256150453fSSepherosa Ziehau 
27266150453fSSepherosa Ziehau 	/* Check if SFP module is supported and linear */
27276150453fSSepherosa Ziehau 	ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
27286150453fSSepherosa Ziehau 
27296150453fSSepherosa Ziehau 	/* If no SFP module present, then return success. Return success since
27306150453fSSepherosa Ziehau 	 * SFP not present error is not excepted in the setup MAC link flow.
27316150453fSSepherosa Ziehau 	 */
27326150453fSSepherosa Ziehau 	if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
27336150453fSSepherosa Ziehau 		return IXGBE_SUCCESS;
27346150453fSSepherosa Ziehau 
27356150453fSSepherosa Ziehau 	if (ret_val != IXGBE_SUCCESS)
27366150453fSSepherosa Ziehau 		return ret_val;
27376150453fSSepherosa Ziehau 
27386150453fSSepherosa Ziehau 	if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) {
27396150453fSSepherosa Ziehau 		/* Configure internal PHY for native SFI based on module type */
27406150453fSSepherosa Ziehau 		ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
27416150453fSSepherosa Ziehau 				   IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
27426150453fSSepherosa Ziehau 				   IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_phy_int);
27436150453fSSepherosa Ziehau 
27446150453fSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
27456150453fSSepherosa Ziehau 			return ret_val;
27466150453fSSepherosa Ziehau 
27476150453fSSepherosa Ziehau 		reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA;
27486150453fSSepherosa Ziehau 		if (!setup_linear)
27496150453fSSepherosa Ziehau 			reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR;
27506150453fSSepherosa Ziehau 
27516150453fSSepherosa Ziehau 		ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
27526150453fSSepherosa Ziehau 				   IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
27536150453fSSepherosa Ziehau 				   IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
27546150453fSSepherosa Ziehau 
27556150453fSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
27566150453fSSepherosa Ziehau 			return ret_val;
27576150453fSSepherosa Ziehau 
27586150453fSSepherosa Ziehau 		/* Setup SFI internal link. */
27596150453fSSepherosa Ziehau 		ret_val = ixgbe_setup_sfi_x550a(hw, &speed);
27606150453fSSepherosa Ziehau 	} else {
27616150453fSSepherosa Ziehau 		/* Configure internal PHY for KR/KX. */
27626150453fSSepherosa Ziehau 		ixgbe_setup_kr_speed_x550em(hw, speed);
27636150453fSSepherosa Ziehau 
27646150453fSSepherosa Ziehau 		if (hw->phy.addr == 0x0 || hw->phy.addr == 0xFFFF) {
27656150453fSSepherosa Ziehau 			/* Find Address */
27666150453fSSepherosa Ziehau 			DEBUGOUT("Invalid NW_MNG_IF_SEL.MDIO_PHY_ADD value\n");
27676150453fSSepherosa Ziehau 			return IXGBE_ERR_PHY_ADDR_INVALID;
27686150453fSSepherosa Ziehau 		}
27696150453fSSepherosa Ziehau 
27706150453fSSepherosa Ziehau 		/* Get external PHY SKU id */
27716150453fSSepherosa Ziehau 		ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU,
27726150453fSSepherosa Ziehau 					IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
27736150453fSSepherosa Ziehau 
27746150453fSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
27756150453fSSepherosa Ziehau 			return ret_val;
27766150453fSSepherosa Ziehau 
27776150453fSSepherosa Ziehau 		/* When configuring quad port CS4223, the MAC instance is part
27786150453fSSepherosa Ziehau 		 * of the slice offset.
27796150453fSSepherosa Ziehau 		 */
27806150453fSSepherosa Ziehau 		if (reg_phy_ext == IXGBE_CS4223_SKU_ID)
27816150453fSSepherosa Ziehau 			slice_offset = (hw->bus.lan_id +
27826150453fSSepherosa Ziehau 					(hw->bus.instance_id << 1)) << 12;
27836150453fSSepherosa Ziehau 		else
27846150453fSSepherosa Ziehau 			slice_offset = hw->bus.lan_id << 12;
27856150453fSSepherosa Ziehau 
27866150453fSSepherosa Ziehau 		/* Configure CS4227/CS4223 LINE side to proper mode. */
27876150453fSSepherosa Ziehau 		reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset;
27886150453fSSepherosa Ziehau 
27896150453fSSepherosa Ziehau 		ret_val = hw->phy.ops.read_reg(hw, reg_slice,
27906150453fSSepherosa Ziehau 					IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
27916150453fSSepherosa Ziehau 
27926150453fSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
27936150453fSSepherosa Ziehau 			return ret_val;
27946150453fSSepherosa Ziehau 
27956150453fSSepherosa Ziehau 		reg_phy_ext &= ~((IXGBE_CS4227_EDC_MODE_CX1 << 1) |
27966150453fSSepherosa Ziehau 				 (IXGBE_CS4227_EDC_MODE_SR << 1));
27976150453fSSepherosa Ziehau 
27986150453fSSepherosa Ziehau 		if (setup_linear)
2799*dd5ce676SSepherosa Ziehau 			reg_phy_ext |= (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
28006150453fSSepherosa Ziehau 		else
2801*dd5ce676SSepherosa Ziehau 			reg_phy_ext |= (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
28026150453fSSepherosa Ziehau 		ret_val = hw->phy.ops.write_reg(hw, reg_slice,
28036150453fSSepherosa Ziehau 					 IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext);
28046150453fSSepherosa Ziehau 
28056150453fSSepherosa Ziehau 		/* Flush previous write with a read */
28066150453fSSepherosa Ziehau 		ret_val = hw->phy.ops.read_reg(hw, reg_slice,
28076150453fSSepherosa Ziehau 					IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
28086150453fSSepherosa Ziehau 	}
28096150453fSSepherosa Ziehau 	return ret_val;
28106150453fSSepherosa Ziehau }
28116150453fSSepherosa Ziehau 
28126150453fSSepherosa Ziehau /**
28136150453fSSepherosa Ziehau  *  ixgbe_setup_ixfi_x550em_x - MAC specific iXFI configuration
28146150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
28156150453fSSepherosa Ziehau  *
28166150453fSSepherosa Ziehau  *  iXfI configuration needed for ixgbe_mac_X550EM_x devices.
28176150453fSSepherosa Ziehau  **/
ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw * hw)28186150453fSSepherosa Ziehau static s32 ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw)
28196150453fSSepherosa Ziehau {
28206150453fSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
28216150453fSSepherosa Ziehau 	s32 status;
28226150453fSSepherosa Ziehau 	u32 reg_val;
28236150453fSSepherosa Ziehau 
28246150453fSSepherosa Ziehau 	/* Disable training protocol FSM. */
28256150453fSSepherosa Ziehau 	status = mac->ops.read_iosf_sb_reg(hw,
28266150453fSSepherosa Ziehau 				IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
28276150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
28286150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
28296150453fSSepherosa Ziehau 		return status;
28306150453fSSepherosa Ziehau 	reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
28316150453fSSepherosa Ziehau 	status = mac->ops.write_iosf_sb_reg(hw,
28326150453fSSepherosa Ziehau 				IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
28336150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
28346150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
28356150453fSSepherosa Ziehau 		return status;
28366150453fSSepherosa Ziehau 
28376150453fSSepherosa Ziehau 	/* Disable Flex from training TXFFE. */
28386150453fSSepherosa Ziehau 	status = mac->ops.read_iosf_sb_reg(hw,
28396150453fSSepherosa Ziehau 				IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
28406150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
28416150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
28426150453fSSepherosa Ziehau 		return status;
28436150453fSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
28446150453fSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
28456150453fSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
28466150453fSSepherosa Ziehau 	status = mac->ops.write_iosf_sb_reg(hw,
28476150453fSSepherosa Ziehau 				IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
28486150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
28496150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
28506150453fSSepherosa Ziehau 		return status;
28516150453fSSepherosa Ziehau 	status = mac->ops.read_iosf_sb_reg(hw,
28526150453fSSepherosa Ziehau 				IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
28536150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
28546150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
28556150453fSSepherosa Ziehau 		return status;
28566150453fSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
28576150453fSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
28586150453fSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
28596150453fSSepherosa Ziehau 	status = mac->ops.write_iosf_sb_reg(hw,
28606150453fSSepherosa Ziehau 				IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
28616150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
28626150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
28636150453fSSepherosa Ziehau 		return status;
28646150453fSSepherosa Ziehau 
28656150453fSSepherosa Ziehau 	/* Enable override for coefficients. */
28666150453fSSepherosa Ziehau 	status = mac->ops.read_iosf_sb_reg(hw,
28676150453fSSepherosa Ziehau 				IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
28686150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
28696150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
28706150453fSSepherosa Ziehau 		return status;
28716150453fSSepherosa Ziehau 	reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
28726150453fSSepherosa Ziehau 	reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
28736150453fSSepherosa Ziehau 	reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
28746150453fSSepherosa Ziehau 	reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
28756150453fSSepherosa Ziehau 	status = mac->ops.write_iosf_sb_reg(hw,
28766150453fSSepherosa Ziehau 				IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
28776150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
28786150453fSSepherosa Ziehau 	return status;
28796150453fSSepherosa Ziehau }
28806150453fSSepherosa Ziehau 
28816150453fSSepherosa Ziehau /**
288263d483cdSSepherosa Ziehau  *  ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
288363d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
288463d483cdSSepherosa Ziehau  *  @speed: the link speed to force
288563d483cdSSepherosa Ziehau  *
288663d483cdSSepherosa Ziehau  *  Configures the integrated KR PHY to use iXFI mode. Used to connect an
288763d483cdSSepherosa Ziehau  *  internal and external PHY at a specific speed, without autonegotiation.
288863d483cdSSepherosa Ziehau  **/
ixgbe_setup_ixfi_x550em(struct ixgbe_hw * hw,ixgbe_link_speed * speed)288963d483cdSSepherosa Ziehau static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
289063d483cdSSepherosa Ziehau {
28916150453fSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
289263d483cdSSepherosa Ziehau 	s32 status;
289363d483cdSSepherosa Ziehau 	u32 reg_val;
289463d483cdSSepherosa Ziehau 
28956150453fSSepherosa Ziehau 	/* iXFI is only supported with X552 */
28966150453fSSepherosa Ziehau 	if (mac->type != ixgbe_mac_X550EM_x)
28976150453fSSepherosa Ziehau 		return IXGBE_ERR_LINK_SETUP;
28986150453fSSepherosa Ziehau 
289963d483cdSSepherosa Ziehau 	/* Disable AN and force speed to 10G Serial. */
29006150453fSSepherosa Ziehau 	status = mac->ops.read_iosf_sb_reg(hw,
290163d483cdSSepherosa Ziehau 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
290263d483cdSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
290363d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
290463d483cdSSepherosa Ziehau 		return status;
290563d483cdSSepherosa Ziehau 
290663d483cdSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
290763d483cdSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
290863d483cdSSepherosa Ziehau 
290963d483cdSSepherosa Ziehau 	/* Select forced link speed for internal PHY. */
291063d483cdSSepherosa Ziehau 	switch (*speed) {
291163d483cdSSepherosa Ziehau 	case IXGBE_LINK_SPEED_10GB_FULL:
291263d483cdSSepherosa Ziehau 		reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
291363d483cdSSepherosa Ziehau 		break;
291463d483cdSSepherosa Ziehau 	case IXGBE_LINK_SPEED_1GB_FULL:
291563d483cdSSepherosa Ziehau 		reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
291663d483cdSSepherosa Ziehau 		break;
291763d483cdSSepherosa Ziehau 	default:
291863d483cdSSepherosa Ziehau 		/* Other link speeds are not supported by internal KR PHY. */
291963d483cdSSepherosa Ziehau 		return IXGBE_ERR_LINK_SETUP;
292063d483cdSSepherosa Ziehau 	}
292163d483cdSSepherosa Ziehau 
29226150453fSSepherosa Ziehau 	status = mac->ops.write_iosf_sb_reg(hw,
292363d483cdSSepherosa Ziehau 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
292463d483cdSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
292563d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
292663d483cdSSepherosa Ziehau 		return status;
292763d483cdSSepherosa Ziehau 
29286150453fSSepherosa Ziehau 	/* Additional configuration needed for x550em_x */
29296150453fSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_X550EM_x) {
29306150453fSSepherosa Ziehau 		status = ixgbe_setup_ixfi_x550em_x(hw);
293163d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
293263d483cdSSepherosa Ziehau 			return status;
29336150453fSSepherosa Ziehau 	}
293463d483cdSSepherosa Ziehau 
293563d483cdSSepherosa Ziehau 	/* Toggle port SW reset by AN reset. */
29366150453fSSepherosa Ziehau 	status = ixgbe_restart_an_internal_phy_x550em(hw);
293763d483cdSSepherosa Ziehau 
293863d483cdSSepherosa Ziehau 	return status;
293963d483cdSSepherosa Ziehau }
294063d483cdSSepherosa Ziehau 
294163d483cdSSepherosa Ziehau /**
29426150453fSSepherosa Ziehau  * ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status
29436150453fSSepherosa Ziehau  * @hw: address of hardware structure
29446150453fSSepherosa Ziehau  * @link_up: address of boolean to indicate link status
29456150453fSSepherosa Ziehau  *
29466150453fSSepherosa Ziehau  * Returns error code if unable to get link status.
29476150453fSSepherosa Ziehau  */
ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw * hw,bool * link_up)29486150453fSSepherosa Ziehau static s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up)
29496150453fSSepherosa Ziehau {
29506150453fSSepherosa Ziehau 	u32 ret;
29516150453fSSepherosa Ziehau 	u16 autoneg_status;
29526150453fSSepherosa Ziehau 
29536150453fSSepherosa Ziehau 	*link_up = FALSE;
29546150453fSSepherosa Ziehau 
29556150453fSSepherosa Ziehau 	/* read this twice back to back to indicate current status */
29566150453fSSepherosa Ziehau 	ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
29576150453fSSepherosa Ziehau 				   IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
29586150453fSSepherosa Ziehau 				   &autoneg_status);
29596150453fSSepherosa Ziehau 	if (ret != IXGBE_SUCCESS)
29606150453fSSepherosa Ziehau 		return ret;
29616150453fSSepherosa Ziehau 
29626150453fSSepherosa Ziehau 	ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
29636150453fSSepherosa Ziehau 				   IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
29646150453fSSepherosa Ziehau 				   &autoneg_status);
29656150453fSSepherosa Ziehau 	if (ret != IXGBE_SUCCESS)
29666150453fSSepherosa Ziehau 		return ret;
29676150453fSSepherosa Ziehau 
29686150453fSSepherosa Ziehau 	*link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS);
29696150453fSSepherosa Ziehau 
29706150453fSSepherosa Ziehau 	return IXGBE_SUCCESS;
29716150453fSSepherosa Ziehau }
29726150453fSSepherosa Ziehau 
29736150453fSSepherosa Ziehau /**
297463d483cdSSepherosa Ziehau  * ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link
297563d483cdSSepherosa Ziehau  * @hw: point to hardware structure
297663d483cdSSepherosa Ziehau  *
297763d483cdSSepherosa Ziehau  * Configures the link between the integrated KR PHY and the external X557 PHY
297863d483cdSSepherosa Ziehau  * The driver will call this function when it gets a link status change
297963d483cdSSepherosa Ziehau  * interrupt from the X557 PHY. This function configures the link speed
298063d483cdSSepherosa Ziehau  * between the PHYs to match the link speed of the BASE-T link.
298163d483cdSSepherosa Ziehau  *
298263d483cdSSepherosa Ziehau  * A return of a non-zero value indicates an error, and the base driver should
298363d483cdSSepherosa Ziehau  * not report link up.
298463d483cdSSepherosa Ziehau  */
ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw * hw)298563d483cdSSepherosa Ziehau s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
298663d483cdSSepherosa Ziehau {
298763d483cdSSepherosa Ziehau 	ixgbe_link_speed force_speed;
29886150453fSSepherosa Ziehau 	bool link_up;
29896150453fSSepherosa Ziehau 	u32 status;
29906150453fSSepherosa Ziehau 	u16 speed;
299163d483cdSSepherosa Ziehau 
299263d483cdSSepherosa Ziehau 	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
299363d483cdSSepherosa Ziehau 		return IXGBE_ERR_CONFIG;
299463d483cdSSepherosa Ziehau 
29956150453fSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_X550EM_x &&
29966150453fSSepherosa Ziehau 	    !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
29976150453fSSepherosa Ziehau 		/* If link is down, there is no setup necessary so return  */
29986150453fSSepherosa Ziehau 		status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
299963d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
300063d483cdSSepherosa Ziehau 			return status;
300163d483cdSSepherosa Ziehau 
30026150453fSSepherosa Ziehau 		if (!link_up)
300363d483cdSSepherosa Ziehau 			return IXGBE_SUCCESS;
300463d483cdSSepherosa Ziehau 
30056150453fSSepherosa Ziehau 		status = hw->phy.ops.read_reg(hw,
30066150453fSSepherosa Ziehau 					      IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
300763d483cdSSepherosa Ziehau 					      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
300863d483cdSSepherosa Ziehau 					      &speed);
30096150453fSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
30106150453fSSepherosa Ziehau 			return status;
30116150453fSSepherosa Ziehau 
30126150453fSSepherosa Ziehau 		/* If link is still down - no setup is required so return */
30136150453fSSepherosa Ziehau 		status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
30146150453fSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
30156150453fSSepherosa Ziehau 			return status;
30166150453fSSepherosa Ziehau 		if (!link_up)
30176150453fSSepherosa Ziehau 			return IXGBE_SUCCESS;
301863d483cdSSepherosa Ziehau 
301963d483cdSSepherosa Ziehau 		/* clear everything but the speed and duplex bits */
302063d483cdSSepherosa Ziehau 		speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
302163d483cdSSepherosa Ziehau 
302263d483cdSSepherosa Ziehau 		switch (speed) {
302363d483cdSSepherosa Ziehau 		case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
302463d483cdSSepherosa Ziehau 			force_speed = IXGBE_LINK_SPEED_10GB_FULL;
302563d483cdSSepherosa Ziehau 			break;
302663d483cdSSepherosa Ziehau 		case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
302763d483cdSSepherosa Ziehau 			force_speed = IXGBE_LINK_SPEED_1GB_FULL;
302863d483cdSSepherosa Ziehau 			break;
302963d483cdSSepherosa Ziehau 		default:
303063d483cdSSepherosa Ziehau 			/* Internal PHY does not support anything else */
303163d483cdSSepherosa Ziehau 			return IXGBE_ERR_INVALID_LINK_SETTINGS;
303263d483cdSSepherosa Ziehau 		}
303363d483cdSSepherosa Ziehau 
303463d483cdSSepherosa Ziehau 		return ixgbe_setup_ixfi_x550em(hw, &force_speed);
30356150453fSSepherosa Ziehau 	} else {
30366150453fSSepherosa Ziehau 		speed = IXGBE_LINK_SPEED_10GB_FULL |
30376150453fSSepherosa Ziehau 			IXGBE_LINK_SPEED_1GB_FULL;
30386150453fSSepherosa Ziehau 		return ixgbe_setup_kr_speed_x550em(hw, speed);
30396150453fSSepherosa Ziehau 	}
304063d483cdSSepherosa Ziehau }
304163d483cdSSepherosa Ziehau 
304263d483cdSSepherosa Ziehau /**
304363d483cdSSepherosa Ziehau  *  ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback.
304463d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
304563d483cdSSepherosa Ziehau  *
304663d483cdSSepherosa Ziehau  *  Configures the integrated KR PHY to use internal loopback mode.
304763d483cdSSepherosa Ziehau  **/
ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw * hw)304863d483cdSSepherosa Ziehau s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw)
304963d483cdSSepherosa Ziehau {
305063d483cdSSepherosa Ziehau 	s32 status;
305163d483cdSSepherosa Ziehau 	u32 reg_val;
305263d483cdSSepherosa Ziehau 
305363d483cdSSepherosa Ziehau 	/* Disable AN and force speed to 10G Serial. */
30546150453fSSepherosa Ziehau 	status = hw->mac.ops.read_iosf_sb_reg(hw,
305563d483cdSSepherosa Ziehau 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
305663d483cdSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
305763d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
305863d483cdSSepherosa Ziehau 		return status;
305963d483cdSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
306063d483cdSSepherosa Ziehau 	reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
306163d483cdSSepherosa Ziehau 	reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
30626150453fSSepherosa Ziehau 	status = hw->mac.ops.write_iosf_sb_reg(hw,
306363d483cdSSepherosa Ziehau 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
306463d483cdSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
306563d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
306663d483cdSSepherosa Ziehau 		return status;
306763d483cdSSepherosa Ziehau 
306863d483cdSSepherosa Ziehau 	/* Set near-end loopback clocks. */
30696150453fSSepherosa Ziehau 	status = hw->mac.ops.read_iosf_sb_reg(hw,
307063d483cdSSepherosa Ziehau 				IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
307163d483cdSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
307263d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
307363d483cdSSepherosa Ziehau 		return status;
307463d483cdSSepherosa Ziehau 	reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B;
307563d483cdSSepherosa Ziehau 	reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS;
30766150453fSSepherosa Ziehau 	status = hw->mac.ops.write_iosf_sb_reg(hw,
307763d483cdSSepherosa Ziehau 				IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
307863d483cdSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
307963d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
308063d483cdSSepherosa Ziehau 		return status;
308163d483cdSSepherosa Ziehau 
308263d483cdSSepherosa Ziehau 	/* Set loopback enable. */
30836150453fSSepherosa Ziehau 	status = hw->mac.ops.read_iosf_sb_reg(hw,
308463d483cdSSepherosa Ziehau 				IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
308563d483cdSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
308663d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
308763d483cdSSepherosa Ziehau 		return status;
308863d483cdSSepherosa Ziehau 	reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK;
30896150453fSSepherosa Ziehau 	status = hw->mac.ops.write_iosf_sb_reg(hw,
309063d483cdSSepherosa Ziehau 				IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
309163d483cdSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
309263d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
309363d483cdSSepherosa Ziehau 		return status;
309463d483cdSSepherosa Ziehau 
309563d483cdSSepherosa Ziehau 	/* Training bypass. */
30966150453fSSepherosa Ziehau 	status = hw->mac.ops.read_iosf_sb_reg(hw,
309763d483cdSSepherosa Ziehau 				IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
309863d483cdSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
309963d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
310063d483cdSSepherosa Ziehau 		return status;
310163d483cdSSepherosa Ziehau 	reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS;
31026150453fSSepherosa Ziehau 	status = hw->mac.ops.write_iosf_sb_reg(hw,
310363d483cdSSepherosa Ziehau 				IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
310463d483cdSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
310563d483cdSSepherosa Ziehau 
310663d483cdSSepherosa Ziehau 	return status;
310763d483cdSSepherosa Ziehau }
310863d483cdSSepherosa Ziehau 
310963d483cdSSepherosa Ziehau /**
311063d483cdSSepherosa Ziehau  *  ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
311163d483cdSSepherosa Ziehau  *  assuming that the semaphore is already obtained.
311263d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
311363d483cdSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to read
311463d483cdSSepherosa Ziehau  *  @data: word read from the EEPROM
311563d483cdSSepherosa Ziehau  *
311663d483cdSSepherosa Ziehau  *  Reads a 16 bit word from the EEPROM using the hostif.
311763d483cdSSepherosa Ziehau  **/
ixgbe_read_ee_hostif_X550(struct ixgbe_hw * hw,u16 offset,u16 * data)31186150453fSSepherosa Ziehau s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data)
311963d483cdSSepherosa Ziehau {
31206150453fSSepherosa Ziehau 	const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
312163d483cdSSepherosa Ziehau 	struct ixgbe_hic_read_shadow_ram buffer;
31226150453fSSepherosa Ziehau 	s32 status;
312363d483cdSSepherosa Ziehau 
31246150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_ee_hostif_X550");
312563d483cdSSepherosa Ziehau 	buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
312663d483cdSSepherosa Ziehau 	buffer.hdr.req.buf_lenh = 0;
312763d483cdSSepherosa Ziehau 	buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
312863d483cdSSepherosa Ziehau 	buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
312963d483cdSSepherosa Ziehau 
313063d483cdSSepherosa Ziehau 	/* convert offset from words to bytes */
313163d483cdSSepherosa Ziehau 	buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
313263d483cdSSepherosa Ziehau 	/* one word */
313363d483cdSSepherosa Ziehau 	buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
31346150453fSSepherosa Ziehau 	buffer.pad2 = 0;
31356150453fSSepherosa Ziehau 	buffer.pad3 = 0;
313663d483cdSSepherosa Ziehau 
31376150453fSSepherosa Ziehau 	status = hw->mac.ops.acquire_swfw_sync(hw, mask);
313863d483cdSSepherosa Ziehau 	if (status)
313963d483cdSSepherosa Ziehau 		return status;
314063d483cdSSepherosa Ziehau 
31416150453fSSepherosa Ziehau 	status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
31426150453fSSepherosa Ziehau 				    IXGBE_HI_COMMAND_TIMEOUT);
31436150453fSSepherosa Ziehau 	if (!status) {
314463d483cdSSepherosa Ziehau 		*data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
314563d483cdSSepherosa Ziehau 						  FW_NVM_DATA_OFFSET);
314663d483cdSSepherosa Ziehau 	}
314763d483cdSSepherosa Ziehau 
31486150453fSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, mask);
314963d483cdSSepherosa Ziehau 	return status;
315063d483cdSSepherosa Ziehau }
315163d483cdSSepherosa Ziehau 
315263d483cdSSepherosa Ziehau /**
315363d483cdSSepherosa Ziehau  *  ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
315463d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
315563d483cdSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to read
315663d483cdSSepherosa Ziehau  *  @words: number of words
315763d483cdSSepherosa Ziehau  *  @data: word(s) read from the EEPROM
315863d483cdSSepherosa Ziehau  *
315963d483cdSSepherosa Ziehau  *  Reads a 16 bit word(s) from the EEPROM using the hostif.
316063d483cdSSepherosa Ziehau  **/
ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)316163d483cdSSepherosa Ziehau s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
316263d483cdSSepherosa Ziehau 				     u16 offset, u16 words, u16 *data)
316363d483cdSSepherosa Ziehau {
31646150453fSSepherosa Ziehau 	const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
316563d483cdSSepherosa Ziehau 	struct ixgbe_hic_read_shadow_ram buffer;
316663d483cdSSepherosa Ziehau 	u32 current_word = 0;
316763d483cdSSepherosa Ziehau 	u16 words_to_read;
316863d483cdSSepherosa Ziehau 	s32 status;
316963d483cdSSepherosa Ziehau 	u32 i;
317063d483cdSSepherosa Ziehau 
317163d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550");
317263d483cdSSepherosa Ziehau 
317363d483cdSSepherosa Ziehau 	/* Take semaphore for the entire operation. */
31746150453fSSepherosa Ziehau 	status = hw->mac.ops.acquire_swfw_sync(hw, mask);
317563d483cdSSepherosa Ziehau 	if (status) {
317663d483cdSSepherosa Ziehau 		DEBUGOUT("EEPROM read buffer - semaphore failed\n");
317763d483cdSSepherosa Ziehau 		return status;
317863d483cdSSepherosa Ziehau 	}
31796150453fSSepherosa Ziehau 
318063d483cdSSepherosa Ziehau 	while (words) {
318163d483cdSSepherosa Ziehau 		if (words > FW_MAX_READ_BUFFER_SIZE / 2)
318263d483cdSSepherosa Ziehau 			words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
318363d483cdSSepherosa Ziehau 		else
318463d483cdSSepherosa Ziehau 			words_to_read = words;
318563d483cdSSepherosa Ziehau 
318663d483cdSSepherosa Ziehau 		buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
318763d483cdSSepherosa Ziehau 		buffer.hdr.req.buf_lenh = 0;
318863d483cdSSepherosa Ziehau 		buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
318963d483cdSSepherosa Ziehau 		buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
319063d483cdSSepherosa Ziehau 
319163d483cdSSepherosa Ziehau 		/* convert offset from words to bytes */
319263d483cdSSepherosa Ziehau 		buffer.address = IXGBE_CPU_TO_BE32((offset + current_word) * 2);
319363d483cdSSepherosa Ziehau 		buffer.length = IXGBE_CPU_TO_BE16(words_to_read * 2);
31946150453fSSepherosa Ziehau 		buffer.pad2 = 0;
31956150453fSSepherosa Ziehau 		buffer.pad3 = 0;
319663d483cdSSepherosa Ziehau 
31976150453fSSepherosa Ziehau 		status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
31986150453fSSepherosa Ziehau 					    IXGBE_HI_COMMAND_TIMEOUT);
319963d483cdSSepherosa Ziehau 
320063d483cdSSepherosa Ziehau 		if (status) {
320163d483cdSSepherosa Ziehau 			DEBUGOUT("Host interface command failed\n");
320263d483cdSSepherosa Ziehau 			goto out;
320363d483cdSSepherosa Ziehau 		}
320463d483cdSSepherosa Ziehau 
320563d483cdSSepherosa Ziehau 		for (i = 0; i < words_to_read; i++) {
320663d483cdSSepherosa Ziehau 			u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
320763d483cdSSepherosa Ziehau 				  2 * i;
320863d483cdSSepherosa Ziehau 			u32 value = IXGBE_READ_REG(hw, reg);
320963d483cdSSepherosa Ziehau 
321063d483cdSSepherosa Ziehau 			data[current_word] = (u16)(value & 0xffff);
321163d483cdSSepherosa Ziehau 			current_word++;
321263d483cdSSepherosa Ziehau 			i++;
321363d483cdSSepherosa Ziehau 			if (i < words_to_read) {
321463d483cdSSepherosa Ziehau 				value >>= 16;
321563d483cdSSepherosa Ziehau 				data[current_word] = (u16)(value & 0xffff);
321663d483cdSSepherosa Ziehau 				current_word++;
321763d483cdSSepherosa Ziehau 			}
321863d483cdSSepherosa Ziehau 		}
321963d483cdSSepherosa Ziehau 		words -= words_to_read;
322063d483cdSSepherosa Ziehau 	}
322163d483cdSSepherosa Ziehau 
322263d483cdSSepherosa Ziehau out:
32236150453fSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, mask);
322463d483cdSSepherosa Ziehau 	return status;
322563d483cdSSepherosa Ziehau }
322663d483cdSSepherosa Ziehau 
322763d483cdSSepherosa Ziehau /**
322863d483cdSSepherosa Ziehau  *  ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
322963d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
323063d483cdSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to write
323163d483cdSSepherosa Ziehau  *  @data: word write to the EEPROM
323263d483cdSSepherosa Ziehau  *
323363d483cdSSepherosa Ziehau  *  Write a 16 bit word to the EEPROM using the hostif.
323463d483cdSSepherosa Ziehau  **/
ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw * hw,u16 offset,u16 data)323563d483cdSSepherosa Ziehau s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
323663d483cdSSepherosa Ziehau 				    u16 data)
323763d483cdSSepherosa Ziehau {
323863d483cdSSepherosa Ziehau 	s32 status;
323963d483cdSSepherosa Ziehau 	struct ixgbe_hic_write_shadow_ram buffer;
324063d483cdSSepherosa Ziehau 
324163d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_ee_hostif_data_X550");
324263d483cdSSepherosa Ziehau 
324363d483cdSSepherosa Ziehau 	buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
324463d483cdSSepherosa Ziehau 	buffer.hdr.req.buf_lenh = 0;
324563d483cdSSepherosa Ziehau 	buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
324663d483cdSSepherosa Ziehau 	buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
324763d483cdSSepherosa Ziehau 
324863d483cdSSepherosa Ziehau 	 /* one word */
324963d483cdSSepherosa Ziehau 	buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
325063d483cdSSepherosa Ziehau 	buffer.data = data;
325163d483cdSSepherosa Ziehau 	buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
325263d483cdSSepherosa Ziehau 
325363d483cdSSepherosa Ziehau 	status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
325463d483cdSSepherosa Ziehau 					      sizeof(buffer),
325563d483cdSSepherosa Ziehau 					      IXGBE_HI_COMMAND_TIMEOUT, FALSE);
325663d483cdSSepherosa Ziehau 
325763d483cdSSepherosa Ziehau 	return status;
325863d483cdSSepherosa Ziehau }
325963d483cdSSepherosa Ziehau 
326063d483cdSSepherosa Ziehau /**
326163d483cdSSepherosa Ziehau  *  ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
326263d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
326363d483cdSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to write
326463d483cdSSepherosa Ziehau  *  @data: word write to the EEPROM
326563d483cdSSepherosa Ziehau  *
326663d483cdSSepherosa Ziehau  *  Write a 16 bit word to the EEPROM using the hostif.
326763d483cdSSepherosa Ziehau  **/
ixgbe_write_ee_hostif_X550(struct ixgbe_hw * hw,u16 offset,u16 data)326863d483cdSSepherosa Ziehau s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
326963d483cdSSepherosa Ziehau 			       u16 data)
327063d483cdSSepherosa Ziehau {
327163d483cdSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
327263d483cdSSepherosa Ziehau 
327363d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_ee_hostif_X550");
327463d483cdSSepherosa Ziehau 
327563d483cdSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
327663d483cdSSepherosa Ziehau 	    IXGBE_SUCCESS) {
327763d483cdSSepherosa Ziehau 		status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
327863d483cdSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
327963d483cdSSepherosa Ziehau 	} else {
328063d483cdSSepherosa Ziehau 		DEBUGOUT("write ee hostif failed to get semaphore");
328163d483cdSSepherosa Ziehau 		status = IXGBE_ERR_SWFW_SYNC;
328263d483cdSSepherosa Ziehau 	}
328363d483cdSSepherosa Ziehau 
328463d483cdSSepherosa Ziehau 	return status;
328563d483cdSSepherosa Ziehau }
328663d483cdSSepherosa Ziehau 
328763d483cdSSepherosa Ziehau /**
328863d483cdSSepherosa Ziehau  *  ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
328963d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
329063d483cdSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to write
329163d483cdSSepherosa Ziehau  *  @words: number of words
329263d483cdSSepherosa Ziehau  *  @data: word(s) write to the EEPROM
329363d483cdSSepherosa Ziehau  *
329463d483cdSSepherosa Ziehau  *  Write a 16 bit word(s) to the EEPROM using the hostif.
329563d483cdSSepherosa Ziehau  **/
ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)329663d483cdSSepherosa Ziehau s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
329763d483cdSSepherosa Ziehau 				      u16 offset, u16 words, u16 *data)
329863d483cdSSepherosa Ziehau {
329963d483cdSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
330063d483cdSSepherosa Ziehau 	u32 i = 0;
330163d483cdSSepherosa Ziehau 
330263d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_ee_hostif_buffer_X550");
330363d483cdSSepherosa Ziehau 
330463d483cdSSepherosa Ziehau 	/* Take semaphore for the entire operation. */
330563d483cdSSepherosa Ziehau 	status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
330663d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS) {
330763d483cdSSepherosa Ziehau 		DEBUGOUT("EEPROM write buffer - semaphore failed\n");
330863d483cdSSepherosa Ziehau 		goto out;
330963d483cdSSepherosa Ziehau 	}
331063d483cdSSepherosa Ziehau 
331163d483cdSSepherosa Ziehau 	for (i = 0; i < words; i++) {
331263d483cdSSepherosa Ziehau 		status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
331363d483cdSSepherosa Ziehau 							 data[i]);
331463d483cdSSepherosa Ziehau 
331563d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS) {
331663d483cdSSepherosa Ziehau 			DEBUGOUT("Eeprom buffered write failed\n");
331763d483cdSSepherosa Ziehau 			break;
331863d483cdSSepherosa Ziehau 		}
331963d483cdSSepherosa Ziehau 	}
332063d483cdSSepherosa Ziehau 
332163d483cdSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
332263d483cdSSepherosa Ziehau out:
332363d483cdSSepherosa Ziehau 
332463d483cdSSepherosa Ziehau 	return status;
332563d483cdSSepherosa Ziehau }
332663d483cdSSepherosa Ziehau 
332763d483cdSSepherosa Ziehau /**
332863d483cdSSepherosa Ziehau  * ixgbe_checksum_ptr_x550 - Checksum one pointer region
332963d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
333063d483cdSSepherosa Ziehau  * @ptr: pointer offset in eeprom
333163d483cdSSepherosa Ziehau  * @size: size of section pointed by ptr, if 0 first word will be used as size
333263d483cdSSepherosa Ziehau  * @csum: address of checksum to update
3333*dd5ce676SSepherosa Ziehau  * @buffer: pointer to buffer containing calculated checksum
3334*dd5ce676SSepherosa Ziehau  * @buffer_size: size of buffer
333563d483cdSSepherosa Ziehau  *
333663d483cdSSepherosa Ziehau  * Returns error status for any failure
333763d483cdSSepherosa Ziehau  */
ixgbe_checksum_ptr_x550(struct ixgbe_hw * hw,u16 ptr,u16 size,u16 * csum,u16 * buffer,u32 buffer_size)333863d483cdSSepherosa Ziehau static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
333963d483cdSSepherosa Ziehau 				   u16 size, u16 *csum, u16 *buffer,
334063d483cdSSepherosa Ziehau 				   u32 buffer_size)
334163d483cdSSepherosa Ziehau {
334263d483cdSSepherosa Ziehau 	u16 buf[256];
334363d483cdSSepherosa Ziehau 	s32 status;
334463d483cdSSepherosa Ziehau 	u16 length, bufsz, i, start;
334563d483cdSSepherosa Ziehau 	u16 *local_buffer;
334663d483cdSSepherosa Ziehau 
334763d483cdSSepherosa Ziehau 	bufsz = sizeof(buf) / sizeof(buf[0]);
334863d483cdSSepherosa Ziehau 
334963d483cdSSepherosa Ziehau 	/* Read a chunk at the pointer location */
335063d483cdSSepherosa Ziehau 	if (!buffer) {
335163d483cdSSepherosa Ziehau 		status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
335263d483cdSSepherosa Ziehau 		if (status) {
335363d483cdSSepherosa Ziehau 			DEBUGOUT("Failed to read EEPROM image\n");
335463d483cdSSepherosa Ziehau 			return status;
335563d483cdSSepherosa Ziehau 		}
335663d483cdSSepherosa Ziehau 		local_buffer = buf;
335763d483cdSSepherosa Ziehau 	} else {
335863d483cdSSepherosa Ziehau 		if (buffer_size < ptr)
335963d483cdSSepherosa Ziehau 			return  IXGBE_ERR_PARAM;
336063d483cdSSepherosa Ziehau 		local_buffer = &buffer[ptr];
336163d483cdSSepherosa Ziehau 	}
336263d483cdSSepherosa Ziehau 
336363d483cdSSepherosa Ziehau 	if (size) {
336463d483cdSSepherosa Ziehau 		start = 0;
336563d483cdSSepherosa Ziehau 		length = size;
336663d483cdSSepherosa Ziehau 	} else {
336763d483cdSSepherosa Ziehau 		start = 1;
336863d483cdSSepherosa Ziehau 		length = local_buffer[0];
336963d483cdSSepherosa Ziehau 
337063d483cdSSepherosa Ziehau 		/* Skip pointer section if length is invalid. */
337163d483cdSSepherosa Ziehau 		if (length == 0xFFFF || length == 0 ||
337263d483cdSSepherosa Ziehau 		    (ptr + length) >= hw->eeprom.word_size)
337363d483cdSSepherosa Ziehau 			return IXGBE_SUCCESS;
337463d483cdSSepherosa Ziehau 	}
337563d483cdSSepherosa Ziehau 
337663d483cdSSepherosa Ziehau 	if (buffer && ((u32)start + (u32)length > buffer_size))
337763d483cdSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
337863d483cdSSepherosa Ziehau 
337963d483cdSSepherosa Ziehau 	for (i = start; length; i++, length--) {
338063d483cdSSepherosa Ziehau 		if (i == bufsz && !buffer) {
338163d483cdSSepherosa Ziehau 			ptr += bufsz;
338263d483cdSSepherosa Ziehau 			i = 0;
338363d483cdSSepherosa Ziehau 			if (length < bufsz)
338463d483cdSSepherosa Ziehau 				bufsz = length;
338563d483cdSSepherosa Ziehau 
338663d483cdSSepherosa Ziehau 			/* Read a chunk at the pointer location */
338763d483cdSSepherosa Ziehau 			status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
338863d483cdSSepherosa Ziehau 								  bufsz, buf);
338963d483cdSSepherosa Ziehau 			if (status) {
339063d483cdSSepherosa Ziehau 				DEBUGOUT("Failed to read EEPROM image\n");
339163d483cdSSepherosa Ziehau 				return status;
339263d483cdSSepherosa Ziehau 			}
339363d483cdSSepherosa Ziehau 		}
339463d483cdSSepherosa Ziehau 		*csum += local_buffer[i];
339563d483cdSSepherosa Ziehau 	}
339663d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
339763d483cdSSepherosa Ziehau }
339863d483cdSSepherosa Ziehau 
339963d483cdSSepherosa Ziehau /**
340063d483cdSSepherosa Ziehau  *  ixgbe_calc_checksum_X550 - Calculates and returns the checksum
340163d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
340263d483cdSSepherosa Ziehau  *  @buffer: pointer to buffer containing calculated checksum
340363d483cdSSepherosa Ziehau  *  @buffer_size: size of buffer
340463d483cdSSepherosa Ziehau  *
340563d483cdSSepherosa Ziehau  *  Returns a negative error code on error, or the 16-bit checksum
340663d483cdSSepherosa Ziehau  **/
ixgbe_calc_checksum_X550(struct ixgbe_hw * hw,u16 * buffer,u32 buffer_size)340763d483cdSSepherosa Ziehau s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, u32 buffer_size)
340863d483cdSSepherosa Ziehau {
340963d483cdSSepherosa Ziehau 	u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
341063d483cdSSepherosa Ziehau 	u16 *local_buffer;
341163d483cdSSepherosa Ziehau 	s32 status;
341263d483cdSSepherosa Ziehau 	u16 checksum = 0;
341363d483cdSSepherosa Ziehau 	u16 pointer, i, size;
341463d483cdSSepherosa Ziehau 
341563d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550");
341663d483cdSSepherosa Ziehau 
341763d483cdSSepherosa Ziehau 	hw->eeprom.ops.init_params(hw);
341863d483cdSSepherosa Ziehau 
341963d483cdSSepherosa Ziehau 	if (!buffer) {
342063d483cdSSepherosa Ziehau 		/* Read pointer area */
342163d483cdSSepherosa Ziehau 		status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
342263d483cdSSepherosa Ziehau 						     IXGBE_EEPROM_LAST_WORD + 1,
342363d483cdSSepherosa Ziehau 						     eeprom_ptrs);
342463d483cdSSepherosa Ziehau 		if (status) {
342563d483cdSSepherosa Ziehau 			DEBUGOUT("Failed to read EEPROM image\n");
342663d483cdSSepherosa Ziehau 			return status;
342763d483cdSSepherosa Ziehau 		}
342863d483cdSSepherosa Ziehau 		local_buffer = eeprom_ptrs;
342963d483cdSSepherosa Ziehau 	} else {
343063d483cdSSepherosa Ziehau 		if (buffer_size < IXGBE_EEPROM_LAST_WORD)
343163d483cdSSepherosa Ziehau 			return IXGBE_ERR_PARAM;
343263d483cdSSepherosa Ziehau 		local_buffer = buffer;
343363d483cdSSepherosa Ziehau 	}
343463d483cdSSepherosa Ziehau 
343563d483cdSSepherosa Ziehau 	/*
343663d483cdSSepherosa Ziehau 	 * For X550 hardware include 0x0-0x41 in the checksum, skip the
343763d483cdSSepherosa Ziehau 	 * checksum word itself
343863d483cdSSepherosa Ziehau 	 */
343963d483cdSSepherosa Ziehau 	for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
344063d483cdSSepherosa Ziehau 		if (i != IXGBE_EEPROM_CHECKSUM)
344163d483cdSSepherosa Ziehau 			checksum += local_buffer[i];
344263d483cdSSepherosa Ziehau 
344363d483cdSSepherosa Ziehau 	/*
344463d483cdSSepherosa Ziehau 	 * Include all data from pointers 0x3, 0x6-0xE.  This excludes the
344563d483cdSSepherosa Ziehau 	 * FW, PHY module, and PCIe Expansion/Option ROM pointers.
344663d483cdSSepherosa Ziehau 	 */
344763d483cdSSepherosa Ziehau 	for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
344863d483cdSSepherosa Ziehau 		if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
344963d483cdSSepherosa Ziehau 			continue;
345063d483cdSSepherosa Ziehau 
345163d483cdSSepherosa Ziehau 		pointer = local_buffer[i];
345263d483cdSSepherosa Ziehau 
345363d483cdSSepherosa Ziehau 		/* Skip pointer section if the pointer is invalid. */
345463d483cdSSepherosa Ziehau 		if (pointer == 0xFFFF || pointer == 0 ||
345563d483cdSSepherosa Ziehau 		    pointer >= hw->eeprom.word_size)
345663d483cdSSepherosa Ziehau 			continue;
345763d483cdSSepherosa Ziehau 
345863d483cdSSepherosa Ziehau 		switch (i) {
345963d483cdSSepherosa Ziehau 		case IXGBE_PCIE_GENERAL_PTR:
346063d483cdSSepherosa Ziehau 			size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
346163d483cdSSepherosa Ziehau 			break;
346263d483cdSSepherosa Ziehau 		case IXGBE_PCIE_CONFIG0_PTR:
346363d483cdSSepherosa Ziehau 		case IXGBE_PCIE_CONFIG1_PTR:
346463d483cdSSepherosa Ziehau 			size = IXGBE_PCIE_CONFIG_SIZE;
346563d483cdSSepherosa Ziehau 			break;
346663d483cdSSepherosa Ziehau 		default:
346763d483cdSSepherosa Ziehau 			size = 0;
346863d483cdSSepherosa Ziehau 			break;
346963d483cdSSepherosa Ziehau 		}
347063d483cdSSepherosa Ziehau 
347163d483cdSSepherosa Ziehau 		status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
347263d483cdSSepherosa Ziehau 						buffer, buffer_size);
347363d483cdSSepherosa Ziehau 		if (status)
347463d483cdSSepherosa Ziehau 			return status;
347563d483cdSSepherosa Ziehau 	}
347663d483cdSSepherosa Ziehau 
347763d483cdSSepherosa Ziehau 	checksum = (u16)IXGBE_EEPROM_SUM - checksum;
347863d483cdSSepherosa Ziehau 
347963d483cdSSepherosa Ziehau 	return (s32)checksum;
348063d483cdSSepherosa Ziehau }
348163d483cdSSepherosa Ziehau 
348263d483cdSSepherosa Ziehau /**
348363d483cdSSepherosa Ziehau  *  ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
348463d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
348563d483cdSSepherosa Ziehau  *
348663d483cdSSepherosa Ziehau  *  Returns a negative error code on error, or the 16-bit checksum
348763d483cdSSepherosa Ziehau  **/
ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw * hw)348863d483cdSSepherosa Ziehau s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
348963d483cdSSepherosa Ziehau {
349063d483cdSSepherosa Ziehau 	return ixgbe_calc_checksum_X550(hw, NULL, 0);
349163d483cdSSepherosa Ziehau }
349263d483cdSSepherosa Ziehau 
349363d483cdSSepherosa Ziehau /**
349463d483cdSSepherosa Ziehau  *  ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
349563d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
349663d483cdSSepherosa Ziehau  *  @checksum_val: calculated checksum
349763d483cdSSepherosa Ziehau  *
349863d483cdSSepherosa Ziehau  *  Performs checksum calculation and validates the EEPROM checksum.  If the
349963d483cdSSepherosa Ziehau  *  caller does not need checksum_val, the value can be NULL.
350063d483cdSSepherosa Ziehau  **/
ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw * hw,u16 * checksum_val)350163d483cdSSepherosa Ziehau s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, u16 *checksum_val)
350263d483cdSSepherosa Ziehau {
350363d483cdSSepherosa Ziehau 	s32 status;
350463d483cdSSepherosa Ziehau 	u16 checksum;
350563d483cdSSepherosa Ziehau 	u16 read_checksum = 0;
350663d483cdSSepherosa Ziehau 
350763d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550");
350863d483cdSSepherosa Ziehau 
350963d483cdSSepherosa Ziehau 	/* Read the first word from the EEPROM. If this times out or fails, do
351063d483cdSSepherosa Ziehau 	 * not continue or we could be in for a very long wait while every
351163d483cdSSepherosa Ziehau 	 * EEPROM read fails
351263d483cdSSepherosa Ziehau 	 */
351363d483cdSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, 0, &checksum);
351463d483cdSSepherosa Ziehau 	if (status) {
351563d483cdSSepherosa Ziehau 		DEBUGOUT("EEPROM read failed\n");
351663d483cdSSepherosa Ziehau 		return status;
351763d483cdSSepherosa Ziehau 	}
351863d483cdSSepherosa Ziehau 
351963d483cdSSepherosa Ziehau 	status = hw->eeprom.ops.calc_checksum(hw);
352063d483cdSSepherosa Ziehau 	if (status < 0)
352163d483cdSSepherosa Ziehau 		return status;
352263d483cdSSepherosa Ziehau 
352363d483cdSSepherosa Ziehau 	checksum = (u16)(status & 0xffff);
352463d483cdSSepherosa Ziehau 
352563d483cdSSepherosa Ziehau 	status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
352663d483cdSSepherosa Ziehau 					   &read_checksum);
352763d483cdSSepherosa Ziehau 	if (status)
352863d483cdSSepherosa Ziehau 		return status;
352963d483cdSSepherosa Ziehau 
353063d483cdSSepherosa Ziehau 	/* Verify read checksum from EEPROM is the same as
353163d483cdSSepherosa Ziehau 	 * calculated checksum
353263d483cdSSepherosa Ziehau 	 */
353363d483cdSSepherosa Ziehau 	if (read_checksum != checksum) {
353463d483cdSSepherosa Ziehau 		status = IXGBE_ERR_EEPROM_CHECKSUM;
353563d483cdSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
353663d483cdSSepherosa Ziehau 			     "Invalid EEPROM checksum");
353763d483cdSSepherosa Ziehau 	}
353863d483cdSSepherosa Ziehau 
353963d483cdSSepherosa Ziehau 	/* If the user cares, return the calculated checksum */
354063d483cdSSepherosa Ziehau 	if (checksum_val)
354163d483cdSSepherosa Ziehau 		*checksum_val = checksum;
354263d483cdSSepherosa Ziehau 
354363d483cdSSepherosa Ziehau 	return status;
354463d483cdSSepherosa Ziehau }
354563d483cdSSepherosa Ziehau 
354663d483cdSSepherosa Ziehau /**
354763d483cdSSepherosa Ziehau  * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
354863d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
354963d483cdSSepherosa Ziehau  *
355063d483cdSSepherosa Ziehau  * After writing EEPROM to shadow RAM using EEWR register, software calculates
355163d483cdSSepherosa Ziehau  * checksum and updates the EEPROM and instructs the hardware to update
355263d483cdSSepherosa Ziehau  * the flash.
355363d483cdSSepherosa Ziehau  **/
ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw * hw)355463d483cdSSepherosa Ziehau s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
355563d483cdSSepherosa Ziehau {
355663d483cdSSepherosa Ziehau 	s32 status;
355763d483cdSSepherosa Ziehau 	u16 checksum = 0;
355863d483cdSSepherosa Ziehau 
355963d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_update_eeprom_checksum_X550");
356063d483cdSSepherosa Ziehau 
356163d483cdSSepherosa Ziehau 	/* Read the first word from the EEPROM. If this times out or fails, do
356263d483cdSSepherosa Ziehau 	 * not continue or we could be in for a very long wait while every
356363d483cdSSepherosa Ziehau 	 * EEPROM read fails
356463d483cdSSepherosa Ziehau 	 */
356563d483cdSSepherosa Ziehau 	status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
356663d483cdSSepherosa Ziehau 	if (status) {
356763d483cdSSepherosa Ziehau 		DEBUGOUT("EEPROM read failed\n");
356863d483cdSSepherosa Ziehau 		return status;
356963d483cdSSepherosa Ziehau 	}
357063d483cdSSepherosa Ziehau 
357163d483cdSSepherosa Ziehau 	status = ixgbe_calc_eeprom_checksum_X550(hw);
357263d483cdSSepherosa Ziehau 	if (status < 0)
357363d483cdSSepherosa Ziehau 		return status;
357463d483cdSSepherosa Ziehau 
357563d483cdSSepherosa Ziehau 	checksum = (u16)(status & 0xffff);
357663d483cdSSepherosa Ziehau 
357763d483cdSSepherosa Ziehau 	status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
357863d483cdSSepherosa Ziehau 					    checksum);
357963d483cdSSepherosa Ziehau 	if (status)
358063d483cdSSepherosa Ziehau 		return status;
358163d483cdSSepherosa Ziehau 
358263d483cdSSepherosa Ziehau 	status = ixgbe_update_flash_X550(hw);
358363d483cdSSepherosa Ziehau 
358463d483cdSSepherosa Ziehau 	return status;
358563d483cdSSepherosa Ziehau }
358663d483cdSSepherosa Ziehau 
358763d483cdSSepherosa Ziehau /**
358863d483cdSSepherosa Ziehau  *  ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
358963d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
359063d483cdSSepherosa Ziehau  *
359163d483cdSSepherosa Ziehau  *  Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
359263d483cdSSepherosa Ziehau  **/
ixgbe_update_flash_X550(struct ixgbe_hw * hw)359363d483cdSSepherosa Ziehau s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
359463d483cdSSepherosa Ziehau {
359563d483cdSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
359663d483cdSSepherosa Ziehau 	union ixgbe_hic_hdr2 buffer;
359763d483cdSSepherosa Ziehau 
359863d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_update_flash_X550");
359963d483cdSSepherosa Ziehau 
360063d483cdSSepherosa Ziehau 	buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
360163d483cdSSepherosa Ziehau 	buffer.req.buf_lenh = 0;
360263d483cdSSepherosa Ziehau 	buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
360363d483cdSSepherosa Ziehau 	buffer.req.checksum = FW_DEFAULT_CHECKSUM;
360463d483cdSSepherosa Ziehau 
360563d483cdSSepherosa Ziehau 	status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
360663d483cdSSepherosa Ziehau 					      sizeof(buffer),
360763d483cdSSepherosa Ziehau 					      IXGBE_HI_COMMAND_TIMEOUT, FALSE);
360863d483cdSSepherosa Ziehau 
360963d483cdSSepherosa Ziehau 	return status;
361063d483cdSSepherosa Ziehau }
361163d483cdSSepherosa Ziehau 
361263d483cdSSepherosa Ziehau /**
361363d483cdSSepherosa Ziehau  *  ixgbe_get_supported_physical_layer_X550em - Returns physical layer type
361463d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
361563d483cdSSepherosa Ziehau  *
361663d483cdSSepherosa Ziehau  *  Determines physical layer capabilities of the current configuration.
361763d483cdSSepherosa Ziehau  **/
ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw * hw)36186150453fSSepherosa Ziehau u64 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw)
361963d483cdSSepherosa Ziehau {
36206150453fSSepherosa Ziehau 	u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
362163d483cdSSepherosa Ziehau 	u16 ext_ability = 0;
362263d483cdSSepherosa Ziehau 
362363d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em");
362463d483cdSSepherosa Ziehau 
362563d483cdSSepherosa Ziehau 	hw->phy.ops.identify(hw);
362663d483cdSSepherosa Ziehau 
362763d483cdSSepherosa Ziehau 	switch (hw->phy.type) {
362863d483cdSSepherosa Ziehau 	case ixgbe_phy_x550em_kr:
36296150453fSSepherosa Ziehau 		if (hw->mac.type == ixgbe_mac_X550EM_a) {
36306150453fSSepherosa Ziehau 			if (hw->phy.nw_mng_if_sel &
36316150453fSSepherosa Ziehau 			    IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) {
36326150453fSSepherosa Ziehau 				physical_layer =
36336150453fSSepherosa Ziehau 					IXGBE_PHYSICAL_LAYER_2500BASE_KX;
36346150453fSSepherosa Ziehau 				break;
36356150453fSSepherosa Ziehau 			} else if (hw->device_id ==
36366150453fSSepherosa Ziehau 				   IXGBE_DEV_ID_X550EM_A_KR_L) {
36376150453fSSepherosa Ziehau 				physical_layer =
36386150453fSSepherosa Ziehau 					IXGBE_PHYSICAL_LAYER_1000BASE_KX;
36396150453fSSepherosa Ziehau 				break;
36406150453fSSepherosa Ziehau 			}
36416150453fSSepherosa Ziehau 		}
36426150453fSSepherosa Ziehau 		/* fall through */
36436150453fSSepherosa Ziehau 	case ixgbe_phy_x550em_xfi:
364463d483cdSSepherosa Ziehau 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR |
364563d483cdSSepherosa Ziehau 				 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
364663d483cdSSepherosa Ziehau 		break;
364763d483cdSSepherosa Ziehau 	case ixgbe_phy_x550em_kx4:
364863d483cdSSepherosa Ziehau 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
364963d483cdSSepherosa Ziehau 				 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
365063d483cdSSepherosa Ziehau 		break;
365163d483cdSSepherosa Ziehau 	case ixgbe_phy_x550em_ext_t:
365263d483cdSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
365363d483cdSSepherosa Ziehau 				     IXGBE_MDIO_PMA_PMD_DEV_TYPE,
365463d483cdSSepherosa Ziehau 				     &ext_ability);
365563d483cdSSepherosa Ziehau 		if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
365663d483cdSSepherosa Ziehau 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
365763d483cdSSepherosa Ziehau 		if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
365863d483cdSSepherosa Ziehau 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
365963d483cdSSepherosa Ziehau 		break;
36606150453fSSepherosa Ziehau 	case ixgbe_phy_fw:
36616150453fSSepherosa Ziehau 		if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_1GB_FULL)
36626150453fSSepherosa Ziehau 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
36636150453fSSepherosa Ziehau 		if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_100_FULL)
36646150453fSSepherosa Ziehau 			physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
36656150453fSSepherosa Ziehau 		if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_10_FULL)
36666150453fSSepherosa Ziehau 			physical_layer |= IXGBE_PHYSICAL_LAYER_10BASE_T;
36676150453fSSepherosa Ziehau 		break;
36686150453fSSepherosa Ziehau 	case ixgbe_phy_sgmii:
36696150453fSSepherosa Ziehau 		physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
36706150453fSSepherosa Ziehau 		break;
36716150453fSSepherosa Ziehau 	case ixgbe_phy_ext_1g_t:
36726150453fSSepherosa Ziehau 		physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
36736150453fSSepherosa Ziehau 		break;
367463d483cdSSepherosa Ziehau 	default:
367563d483cdSSepherosa Ziehau 		break;
367663d483cdSSepherosa Ziehau 	}
367763d483cdSSepherosa Ziehau 
367863d483cdSSepherosa Ziehau 	if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber)
367963d483cdSSepherosa Ziehau 		physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw);
368063d483cdSSepherosa Ziehau 
368163d483cdSSepherosa Ziehau 	return physical_layer;
368263d483cdSSepherosa Ziehau }
368363d483cdSSepherosa Ziehau 
368463d483cdSSepherosa Ziehau /**
368563d483cdSSepherosa Ziehau  * ixgbe_get_bus_info_x550em - Set PCI bus info
368663d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
368763d483cdSSepherosa Ziehau  *
368863d483cdSSepherosa Ziehau  * Sets bus link width and speed to unknown because X550em is
368963d483cdSSepherosa Ziehau  * not a PCI device.
369063d483cdSSepherosa Ziehau  **/
ixgbe_get_bus_info_X550em(struct ixgbe_hw * hw)369163d483cdSSepherosa Ziehau s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
369263d483cdSSepherosa Ziehau {
369363d483cdSSepherosa Ziehau 
369463d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_bus_info_x550em");
369563d483cdSSepherosa Ziehau 
369663d483cdSSepherosa Ziehau 	hw->bus.width = ixgbe_bus_width_unknown;
369763d483cdSSepherosa Ziehau 	hw->bus.speed = ixgbe_bus_speed_unknown;
369863d483cdSSepherosa Ziehau 
369963d483cdSSepherosa Ziehau 	hw->mac.ops.set_lan_id(hw);
370063d483cdSSepherosa Ziehau 
370163d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
370263d483cdSSepherosa Ziehau }
370363d483cdSSepherosa Ziehau 
370463d483cdSSepherosa Ziehau /**
370563d483cdSSepherosa Ziehau  * ixgbe_disable_rx_x550 - Disable RX unit
3706*dd5ce676SSepherosa Ziehau  * @hw: pointer to hardware structure
370763d483cdSSepherosa Ziehau  *
370863d483cdSSepherosa Ziehau  * Enables the Rx DMA unit for x550
370963d483cdSSepherosa Ziehau  **/
ixgbe_disable_rx_x550(struct ixgbe_hw * hw)371063d483cdSSepherosa Ziehau void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
371163d483cdSSepherosa Ziehau {
371263d483cdSSepherosa Ziehau 	u32 rxctrl, pfdtxgswc;
371363d483cdSSepherosa Ziehau 	s32 status;
371463d483cdSSepherosa Ziehau 	struct ixgbe_hic_disable_rxen fw_cmd;
371563d483cdSSepherosa Ziehau 
371663d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_enable_rx_dma_x550");
371763d483cdSSepherosa Ziehau 
371863d483cdSSepherosa Ziehau 	rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
371963d483cdSSepherosa Ziehau 	if (rxctrl & IXGBE_RXCTRL_RXEN) {
372063d483cdSSepherosa Ziehau 		pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
372163d483cdSSepherosa Ziehau 		if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
372263d483cdSSepherosa Ziehau 			pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
372363d483cdSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
372463d483cdSSepherosa Ziehau 			hw->mac.set_lben = TRUE;
372563d483cdSSepherosa Ziehau 		} else {
372663d483cdSSepherosa Ziehau 			hw->mac.set_lben = FALSE;
372763d483cdSSepherosa Ziehau 		}
372863d483cdSSepherosa Ziehau 
372963d483cdSSepherosa Ziehau 		fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
373063d483cdSSepherosa Ziehau 		fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
373163d483cdSSepherosa Ziehau 		fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
373263d483cdSSepherosa Ziehau 		fw_cmd.port_number = (u8)hw->bus.lan_id;
373363d483cdSSepherosa Ziehau 
373463d483cdSSepherosa Ziehau 		status = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
373563d483cdSSepherosa Ziehau 					sizeof(struct ixgbe_hic_disable_rxen),
373663d483cdSSepherosa Ziehau 					IXGBE_HI_COMMAND_TIMEOUT, TRUE);
373763d483cdSSepherosa Ziehau 
373863d483cdSSepherosa Ziehau 		/* If we fail - disable RX using register write */
373963d483cdSSepherosa Ziehau 		if (status) {
374063d483cdSSepherosa Ziehau 			rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
374163d483cdSSepherosa Ziehau 			if (rxctrl & IXGBE_RXCTRL_RXEN) {
374263d483cdSSepherosa Ziehau 				rxctrl &= ~IXGBE_RXCTRL_RXEN;
374363d483cdSSepherosa Ziehau 				IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
374463d483cdSSepherosa Ziehau 			}
374563d483cdSSepherosa Ziehau 		}
374663d483cdSSepherosa Ziehau 	}
374763d483cdSSepherosa Ziehau }
374863d483cdSSepherosa Ziehau 
374963d483cdSSepherosa Ziehau /**
375063d483cdSSepherosa Ziehau  * ixgbe_enter_lplu_x550em - Transition to low power states
375163d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
375263d483cdSSepherosa Ziehau  *
375363d483cdSSepherosa Ziehau  * Configures Low Power Link Up on transition to low power states
375463d483cdSSepherosa Ziehau  * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the
375563d483cdSSepherosa Ziehau  * X557 PHY immediately prior to entering LPLU.
375663d483cdSSepherosa Ziehau  **/
ixgbe_enter_lplu_t_x550em(struct ixgbe_hw * hw)375763d483cdSSepherosa Ziehau s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
375863d483cdSSepherosa Ziehau {
37596150453fSSepherosa Ziehau 	u16 an_10g_cntl_reg, autoneg_reg, speed;
376063d483cdSSepherosa Ziehau 	s32 status;
376163d483cdSSepherosa Ziehau 	ixgbe_link_speed lcd_speed;
376263d483cdSSepherosa Ziehau 	u32 save_autoneg;
37636150453fSSepherosa Ziehau 	bool link_up;
37646150453fSSepherosa Ziehau 
37656150453fSSepherosa Ziehau 	/* SW LPLU not required on later HW revisions. */
37666150453fSSepherosa Ziehau 	if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
37676150453fSSepherosa Ziehau 	    (IXGBE_FUSES0_REV_MASK &
37686150453fSSepherosa Ziehau 	     IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
37696150453fSSepherosa Ziehau 		return IXGBE_SUCCESS;
377063d483cdSSepherosa Ziehau 
377163d483cdSSepherosa Ziehau 	/* If blocked by MNG FW, then don't restart AN */
377263d483cdSSepherosa Ziehau 	if (ixgbe_check_reset_blocked(hw))
377363d483cdSSepherosa Ziehau 		return IXGBE_SUCCESS;
377463d483cdSSepherosa Ziehau 
37756150453fSSepherosa Ziehau 	status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
377663d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
377763d483cdSSepherosa Ziehau 		return status;
377863d483cdSSepherosa Ziehau 
377963d483cdSSepherosa Ziehau 	status = ixgbe_read_eeprom(hw, NVM_INIT_CTRL_3, &hw->eeprom.ctrl_word_3);
378063d483cdSSepherosa Ziehau 
378163d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
378263d483cdSSepherosa Ziehau 		return status;
378363d483cdSSepherosa Ziehau 
378463d483cdSSepherosa Ziehau 	/* If link is down, LPLU disabled in NVM, WoL disabled, or manageability
378563d483cdSSepherosa Ziehau 	 * disabled, then force link down by entering low power mode.
378663d483cdSSepherosa Ziehau 	 */
37876150453fSSepherosa Ziehau 	if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) ||
378863d483cdSSepherosa Ziehau 	    !(hw->wol_enabled || ixgbe_mng_present(hw)))
378963d483cdSSepherosa Ziehau 		return ixgbe_set_copper_phy_power(hw, FALSE);
379063d483cdSSepherosa Ziehau 
379163d483cdSSepherosa Ziehau 	/* Determine LCD */
379263d483cdSSepherosa Ziehau 	status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed);
379363d483cdSSepherosa Ziehau 
379463d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
379563d483cdSSepherosa Ziehau 		return status;
379663d483cdSSepherosa Ziehau 
379763d483cdSSepherosa Ziehau 	/* If no valid LCD link speed, then force link down and exit. */
379863d483cdSSepherosa Ziehau 	if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN)
379963d483cdSSepherosa Ziehau 		return ixgbe_set_copper_phy_power(hw, FALSE);
380063d483cdSSepherosa Ziehau 
380163d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
380263d483cdSSepherosa Ziehau 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
380363d483cdSSepherosa Ziehau 				      &speed);
380463d483cdSSepherosa Ziehau 
380563d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
380663d483cdSSepherosa Ziehau 		return status;
380763d483cdSSepherosa Ziehau 
38086150453fSSepherosa Ziehau 	/* If no link now, speed is invalid so take link down */
38096150453fSSepherosa Ziehau 	status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
38106150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
38116150453fSSepherosa Ziehau 		return ixgbe_set_copper_phy_power(hw, FALSE);
38126150453fSSepherosa Ziehau 
381363d483cdSSepherosa Ziehau 	/* clear everything but the speed bits */
381463d483cdSSepherosa Ziehau 	speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK;
381563d483cdSSepherosa Ziehau 
381663d483cdSSepherosa Ziehau 	/* If current speed is already LCD, then exit. */
381763d483cdSSepherosa Ziehau 	if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) &&
381863d483cdSSepherosa Ziehau 	     (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) ||
381963d483cdSSepherosa Ziehau 	    ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) &&
382063d483cdSSepherosa Ziehau 	     (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL)))
382163d483cdSSepherosa Ziehau 		return status;
382263d483cdSSepherosa Ziehau 
382363d483cdSSepherosa Ziehau 	/* Clear AN completed indication */
382463d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM,
382563d483cdSSepherosa Ziehau 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
38266150453fSSepherosa Ziehau 				      &autoneg_reg);
382763d483cdSSepherosa Ziehau 
382863d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
382963d483cdSSepherosa Ziehau 		return status;
383063d483cdSSepherosa Ziehau 
383163d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
383263d483cdSSepherosa Ziehau 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
383363d483cdSSepherosa Ziehau 			     &an_10g_cntl_reg);
383463d483cdSSepherosa Ziehau 
383563d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
383663d483cdSSepherosa Ziehau 		return status;
383763d483cdSSepherosa Ziehau 
383863d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw,
383963d483cdSSepherosa Ziehau 			     IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
384063d483cdSSepherosa Ziehau 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
384163d483cdSSepherosa Ziehau 			     &autoneg_reg);
384263d483cdSSepherosa Ziehau 
384363d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
384463d483cdSSepherosa Ziehau 		return status;
384563d483cdSSepherosa Ziehau 
384663d483cdSSepherosa Ziehau 	save_autoneg = hw->phy.autoneg_advertised;
384763d483cdSSepherosa Ziehau 
384863d483cdSSepherosa Ziehau 	/* Setup link at least common link speed */
384963d483cdSSepherosa Ziehau 	status = hw->mac.ops.setup_link(hw, lcd_speed, FALSE);
385063d483cdSSepherosa Ziehau 
385163d483cdSSepherosa Ziehau 	/* restore autoneg from before setting lplu speed */
385263d483cdSSepherosa Ziehau 	hw->phy.autoneg_advertised = save_autoneg;
385363d483cdSSepherosa Ziehau 
385463d483cdSSepherosa Ziehau 	return status;
385563d483cdSSepherosa Ziehau }
385663d483cdSSepherosa Ziehau 
385763d483cdSSepherosa Ziehau /**
385863d483cdSSepherosa Ziehau  * ixgbe_get_lcd_x550em - Determine lowest common denominator
385963d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
386063d483cdSSepherosa Ziehau  *  @lcd_speed: pointer to lowest common link speed
386163d483cdSSepherosa Ziehau  *
386263d483cdSSepherosa Ziehau  * Determine lowest common link speed with link partner.
386363d483cdSSepherosa Ziehau  **/
ixgbe_get_lcd_t_x550em(struct ixgbe_hw * hw,ixgbe_link_speed * lcd_speed)386463d483cdSSepherosa Ziehau s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed)
386563d483cdSSepherosa Ziehau {
386663d483cdSSepherosa Ziehau 	u16 an_lp_status;
386763d483cdSSepherosa Ziehau 	s32 status;
386863d483cdSSepherosa Ziehau 	u16 word = hw->eeprom.ctrl_word_3;
386963d483cdSSepherosa Ziehau 
387063d483cdSSepherosa Ziehau 	*lcd_speed = IXGBE_LINK_SPEED_UNKNOWN;
387163d483cdSSepherosa Ziehau 
387263d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS,
387363d483cdSSepherosa Ziehau 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
387463d483cdSSepherosa Ziehau 				      &an_lp_status);
387563d483cdSSepherosa Ziehau 
387663d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
387763d483cdSSepherosa Ziehau 		return status;
387863d483cdSSepherosa Ziehau 
387963d483cdSSepherosa Ziehau 	/* If link partner advertised 1G, return 1G */
388063d483cdSSepherosa Ziehau 	if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) {
388163d483cdSSepherosa Ziehau 		*lcd_speed = IXGBE_LINK_SPEED_1GB_FULL;
388263d483cdSSepherosa Ziehau 		return status;
388363d483cdSSepherosa Ziehau 	}
388463d483cdSSepherosa Ziehau 
388563d483cdSSepherosa Ziehau 	/* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */
388663d483cdSSepherosa Ziehau 	if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) ||
388763d483cdSSepherosa Ziehau 	    (word & NVM_INIT_CTRL_3_D10GMP_PORT0))
388863d483cdSSepherosa Ziehau 		return status;
388963d483cdSSepherosa Ziehau 
389063d483cdSSepherosa Ziehau 	/* Link partner not capable of lower speeds, return 10G */
389163d483cdSSepherosa Ziehau 	*lcd_speed = IXGBE_LINK_SPEED_10GB_FULL;
389263d483cdSSepherosa Ziehau 	return status;
389363d483cdSSepherosa Ziehau }
389463d483cdSSepherosa Ziehau 
389563d483cdSSepherosa Ziehau /**
389663d483cdSSepherosa Ziehau  *  ixgbe_setup_fc_X550em - Set up flow control
389763d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
389863d483cdSSepherosa Ziehau  *
389963d483cdSSepherosa Ziehau  *  Called at init time to set up flow control.
390063d483cdSSepherosa Ziehau  **/
ixgbe_setup_fc_X550em(struct ixgbe_hw * hw)390163d483cdSSepherosa Ziehau s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw)
390263d483cdSSepherosa Ziehau {
390363d483cdSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
390463d483cdSSepherosa Ziehau 	u32 pause, asm_dir, reg_val;
390563d483cdSSepherosa Ziehau 
390663d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_fc_X550em");
390763d483cdSSepherosa Ziehau 
390863d483cdSSepherosa Ziehau 	/* Validate the requested mode */
390963d483cdSSepherosa Ziehau 	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
391063d483cdSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
391163d483cdSSepherosa Ziehau 			"ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
391263d483cdSSepherosa Ziehau 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
391363d483cdSSepherosa Ziehau 		goto out;
391463d483cdSSepherosa Ziehau 	}
391563d483cdSSepherosa Ziehau 
391663d483cdSSepherosa Ziehau 	/* 10gig parts do not have a word in the EEPROM to determine the
391763d483cdSSepherosa Ziehau 	 * default flow control setting, so we explicitly set it to full.
391863d483cdSSepherosa Ziehau 	 */
391963d483cdSSepherosa Ziehau 	if (hw->fc.requested_mode == ixgbe_fc_default)
392063d483cdSSepherosa Ziehau 		hw->fc.requested_mode = ixgbe_fc_full;
392163d483cdSSepherosa Ziehau 
392263d483cdSSepherosa Ziehau 	/* Determine PAUSE and ASM_DIR bits. */
392363d483cdSSepherosa Ziehau 	switch (hw->fc.requested_mode) {
392463d483cdSSepherosa Ziehau 	case ixgbe_fc_none:
392563d483cdSSepherosa Ziehau 		pause = 0;
392663d483cdSSepherosa Ziehau 		asm_dir = 0;
392763d483cdSSepherosa Ziehau 		break;
392863d483cdSSepherosa Ziehau 	case ixgbe_fc_tx_pause:
392963d483cdSSepherosa Ziehau 		pause = 0;
393063d483cdSSepherosa Ziehau 		asm_dir = 1;
393163d483cdSSepherosa Ziehau 		break;
393263d483cdSSepherosa Ziehau 	case ixgbe_fc_rx_pause:
393363d483cdSSepherosa Ziehau 		/* Rx Flow control is enabled and Tx Flow control is
393463d483cdSSepherosa Ziehau 		 * disabled by software override. Since there really
393563d483cdSSepherosa Ziehau 		 * isn't a way to advertise that we are capable of RX
393663d483cdSSepherosa Ziehau 		 * Pause ONLY, we will advertise that we support both
393763d483cdSSepherosa Ziehau 		 * symmetric and asymmetric Rx PAUSE, as such we fall
393863d483cdSSepherosa Ziehau 		 * through to the fc_full statement.  Later, we will
393963d483cdSSepherosa Ziehau 		 * disable the adapter's ability to send PAUSE frames.
394063d483cdSSepherosa Ziehau 		 */
394163d483cdSSepherosa Ziehau 	case ixgbe_fc_full:
394263d483cdSSepherosa Ziehau 		pause = 1;
394363d483cdSSepherosa Ziehau 		asm_dir = 1;
394463d483cdSSepherosa Ziehau 		break;
394563d483cdSSepherosa Ziehau 	default:
394663d483cdSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
394763d483cdSSepherosa Ziehau 			"Flow control param set incorrectly\n");
394863d483cdSSepherosa Ziehau 		ret_val = IXGBE_ERR_CONFIG;
394963d483cdSSepherosa Ziehau 		goto out;
395063d483cdSSepherosa Ziehau 	}
395163d483cdSSepherosa Ziehau 
39526150453fSSepherosa Ziehau 	switch (hw->device_id) {
39536150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_KR:
39546150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_KR:
39556150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_A_KR_L:
39566150453fSSepherosa Ziehau 		ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
395763d483cdSSepherosa Ziehau 					IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
395863d483cdSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
395963d483cdSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
396063d483cdSSepherosa Ziehau 			goto out;
396163d483cdSSepherosa Ziehau 		reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
396263d483cdSSepherosa Ziehau 			IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
396363d483cdSSepherosa Ziehau 		if (pause)
396463d483cdSSepherosa Ziehau 			reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
396563d483cdSSepherosa Ziehau 		if (asm_dir)
396663d483cdSSepherosa Ziehau 			reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
39676150453fSSepherosa Ziehau 		ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
396863d483cdSSepherosa Ziehau 					IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
396963d483cdSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
397063d483cdSSepherosa Ziehau 
39716150453fSSepherosa Ziehau 		/* This device does not fully support AN. */
397263d483cdSSepherosa Ziehau 		hw->fc.disable_fc_autoneg = TRUE;
39736150453fSSepherosa Ziehau 		break;
39746150453fSSepherosa Ziehau 	case IXGBE_DEV_ID_X550EM_X_XFI:
39756150453fSSepherosa Ziehau 		hw->fc.disable_fc_autoneg = TRUE;
39766150453fSSepherosa Ziehau 		break;
39776150453fSSepherosa Ziehau 	default:
39786150453fSSepherosa Ziehau 		break;
397963d483cdSSepherosa Ziehau 	}
398063d483cdSSepherosa Ziehau 
398163d483cdSSepherosa Ziehau out:
398263d483cdSSepherosa Ziehau 	return ret_val;
398363d483cdSSepherosa Ziehau }
398463d483cdSSepherosa Ziehau 
398563d483cdSSepherosa Ziehau /**
39866150453fSSepherosa Ziehau  *  ixgbe_fc_autoneg_backplane_x550em_a - Enable flow control IEEE clause 37
39876150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
39886150453fSSepherosa Ziehau  *
39896150453fSSepherosa Ziehau  *  Enable flow control according to IEEE clause 37.
39906150453fSSepherosa Ziehau  **/
ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw * hw)39916150453fSSepherosa Ziehau void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw)
39926150453fSSepherosa Ziehau {
39936150453fSSepherosa Ziehau 	u32 link_s1, lp_an_page_low, an_cntl_1;
39946150453fSSepherosa Ziehau 	s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
39956150453fSSepherosa Ziehau 	ixgbe_link_speed speed;
39966150453fSSepherosa Ziehau 	bool link_up;
39976150453fSSepherosa Ziehau 
39986150453fSSepherosa Ziehau 	/* AN should have completed when the cable was plugged in.
39996150453fSSepherosa Ziehau 	 * Look for reasons to bail out.  Bail out if:
40006150453fSSepherosa Ziehau 	 * - FC autoneg is disabled, or if
40016150453fSSepherosa Ziehau 	 * - link is not up.
40026150453fSSepherosa Ziehau 	 */
40036150453fSSepherosa Ziehau 	if (hw->fc.disable_fc_autoneg) {
40046150453fSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
40056150453fSSepherosa Ziehau 			     "Flow control autoneg is disabled");
40066150453fSSepherosa Ziehau 		goto out;
40076150453fSSepherosa Ziehau 	}
40086150453fSSepherosa Ziehau 
40096150453fSSepherosa Ziehau 	hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
40106150453fSSepherosa Ziehau 	if (!link_up) {
40116150453fSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
40126150453fSSepherosa Ziehau 		goto out;
40136150453fSSepherosa Ziehau 	}
40146150453fSSepherosa Ziehau 
40156150453fSSepherosa Ziehau 	/* Check at auto-negotiation has completed */
40166150453fSSepherosa Ziehau 	status = hw->mac.ops.read_iosf_sb_reg(hw,
40176150453fSSepherosa Ziehau 					IXGBE_KRM_LINK_S1(hw->bus.lan_id),
40186150453fSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, &link_s1);
40196150453fSSepherosa Ziehau 
40206150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS ||
40216150453fSSepherosa Ziehau 	    (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) {
40226150453fSSepherosa Ziehau 		DEBUGOUT("Auto-Negotiation did not complete\n");
40236150453fSSepherosa Ziehau 		status = IXGBE_ERR_FC_NOT_NEGOTIATED;
40246150453fSSepherosa Ziehau 		goto out;
40256150453fSSepherosa Ziehau 	}
40266150453fSSepherosa Ziehau 
40276150453fSSepherosa Ziehau 	/* Read the 10g AN autoc and LP ability registers and resolve
40286150453fSSepherosa Ziehau 	 * local flow control settings accordingly
40296150453fSSepherosa Ziehau 	 */
40306150453fSSepherosa Ziehau 	status = hw->mac.ops.read_iosf_sb_reg(hw,
40316150453fSSepherosa Ziehau 				IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
40326150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl_1);
40336150453fSSepherosa Ziehau 
40346150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS) {
40356150453fSSepherosa Ziehau 		DEBUGOUT("Auto-Negotiation did not complete\n");
40366150453fSSepherosa Ziehau 		goto out;
40376150453fSSepherosa Ziehau 	}
40386150453fSSepherosa Ziehau 
40396150453fSSepherosa Ziehau 	status = hw->mac.ops.read_iosf_sb_reg(hw,
40406150453fSSepherosa Ziehau 				IXGBE_KRM_LP_BASE_PAGE_HIGH(hw->bus.lan_id),
40416150453fSSepherosa Ziehau 				IXGBE_SB_IOSF_TARGET_KR_PHY, &lp_an_page_low);
40426150453fSSepherosa Ziehau 
40436150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS) {
40446150453fSSepherosa Ziehau 		DEBUGOUT("Auto-Negotiation did not complete\n");
40456150453fSSepherosa Ziehau 		goto out;
40466150453fSSepherosa Ziehau 	}
40476150453fSSepherosa Ziehau 
40486150453fSSepherosa Ziehau 	status = ixgbe_negotiate_fc(hw, an_cntl_1, lp_an_page_low,
40496150453fSSepherosa Ziehau 				    IXGBE_KRM_AN_CNTL_1_SYM_PAUSE,
40506150453fSSepherosa Ziehau 				    IXGBE_KRM_AN_CNTL_1_ASM_PAUSE,
40516150453fSSepherosa Ziehau 				    IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE,
40526150453fSSepherosa Ziehau 				    IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE);
40536150453fSSepherosa Ziehau 
40546150453fSSepherosa Ziehau out:
40556150453fSSepherosa Ziehau 	if (status == IXGBE_SUCCESS) {
40566150453fSSepherosa Ziehau 		hw->fc.fc_was_autonegged = TRUE;
40576150453fSSepherosa Ziehau 	} else {
40586150453fSSepherosa Ziehau 		hw->fc.fc_was_autonegged = FALSE;
40596150453fSSepherosa Ziehau 		hw->fc.current_mode = hw->fc.requested_mode;
40606150453fSSepherosa Ziehau 	}
40616150453fSSepherosa Ziehau }
40626150453fSSepherosa Ziehau 
40636150453fSSepherosa Ziehau /**
40646150453fSSepherosa Ziehau  *  ixgbe_fc_autoneg_fiber_x550em_a - passthrough FC settings
40656150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
40666150453fSSepherosa Ziehau  *
40676150453fSSepherosa Ziehau  **/
ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw * hw)40686150453fSSepherosa Ziehau void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw)
40696150453fSSepherosa Ziehau {
40706150453fSSepherosa Ziehau 	hw->fc.fc_was_autonegged = FALSE;
40716150453fSSepherosa Ziehau 	hw->fc.current_mode = hw->fc.requested_mode;
40726150453fSSepherosa Ziehau }
40736150453fSSepherosa Ziehau 
40746150453fSSepherosa Ziehau /**
40756150453fSSepherosa Ziehau  *  ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37
40766150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
40776150453fSSepherosa Ziehau  *
40786150453fSSepherosa Ziehau  *  Enable flow control according to IEEE clause 37.
40796150453fSSepherosa Ziehau  **/
ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw * hw)40806150453fSSepherosa Ziehau void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw)
40816150453fSSepherosa Ziehau {
40826150453fSSepherosa Ziehau 	s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
40836150453fSSepherosa Ziehau 	u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
40846150453fSSepherosa Ziehau 	ixgbe_link_speed speed;
40856150453fSSepherosa Ziehau 	bool link_up;
40866150453fSSepherosa Ziehau 
40876150453fSSepherosa Ziehau 	/* AN should have completed when the cable was plugged in.
40886150453fSSepherosa Ziehau 	 * Look for reasons to bail out.  Bail out if:
40896150453fSSepherosa Ziehau 	 * - FC autoneg is disabled, or if
40906150453fSSepherosa Ziehau 	 * - link is not up.
40916150453fSSepherosa Ziehau 	 */
40926150453fSSepherosa Ziehau 	if (hw->fc.disable_fc_autoneg) {
40936150453fSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
40946150453fSSepherosa Ziehau 			     "Flow control autoneg is disabled");
40956150453fSSepherosa Ziehau 		goto out;
40966150453fSSepherosa Ziehau 	}
40976150453fSSepherosa Ziehau 
40986150453fSSepherosa Ziehau 	hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
40996150453fSSepherosa Ziehau 	if (!link_up) {
41006150453fSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
41016150453fSSepherosa Ziehau 		goto out;
41026150453fSSepherosa Ziehau 	}
41036150453fSSepherosa Ziehau 
41046150453fSSepherosa Ziehau 	/* Check if auto-negotiation has completed */
41056150453fSSepherosa Ziehau 	status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info);
41066150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS ||
41076150453fSSepherosa Ziehau 	    !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) {
41086150453fSSepherosa Ziehau 		DEBUGOUT("Auto-Negotiation did not complete\n");
41096150453fSSepherosa Ziehau 		status = IXGBE_ERR_FC_NOT_NEGOTIATED;
41106150453fSSepherosa Ziehau 		goto out;
41116150453fSSepherosa Ziehau 	}
41126150453fSSepherosa Ziehau 
41136150453fSSepherosa Ziehau 	/* Negotiate the flow control */
41146150453fSSepherosa Ziehau 	status = ixgbe_negotiate_fc(hw, info[0], info[0],
41156150453fSSepherosa Ziehau 				    FW_PHY_ACT_GET_LINK_INFO_FC_RX,
41166150453fSSepherosa Ziehau 				    FW_PHY_ACT_GET_LINK_INFO_FC_TX,
41176150453fSSepherosa Ziehau 				    FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX,
41186150453fSSepherosa Ziehau 				    FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX);
41196150453fSSepherosa Ziehau 
41206150453fSSepherosa Ziehau out:
41216150453fSSepherosa Ziehau 	if (status == IXGBE_SUCCESS) {
41226150453fSSepherosa Ziehau 		hw->fc.fc_was_autonegged = TRUE;
41236150453fSSepherosa Ziehau 	} else {
41246150453fSSepherosa Ziehau 		hw->fc.fc_was_autonegged = FALSE;
41256150453fSSepherosa Ziehau 		hw->fc.current_mode = hw->fc.requested_mode;
41266150453fSSepherosa Ziehau 	}
41276150453fSSepherosa Ziehau }
41286150453fSSepherosa Ziehau 
41296150453fSSepherosa Ziehau /**
41306150453fSSepherosa Ziehau  *  ixgbe_setup_fc_backplane_x550em_a - Set up flow control
41316150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
41326150453fSSepherosa Ziehau  *
41336150453fSSepherosa Ziehau  *  Called at init time to set up flow control.
41346150453fSSepherosa Ziehau  **/
ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw * hw)41356150453fSSepherosa Ziehau s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw)
41366150453fSSepherosa Ziehau {
41376150453fSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
41386150453fSSepherosa Ziehau 	u32 an_cntl = 0;
41396150453fSSepherosa Ziehau 
41406150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_fc_backplane_x550em_a");
41416150453fSSepherosa Ziehau 
41426150453fSSepherosa Ziehau 	/* Validate the requested mode */
41436150453fSSepherosa Ziehau 	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
41446150453fSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
41456150453fSSepherosa Ziehau 			      "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
41466150453fSSepherosa Ziehau 		return IXGBE_ERR_INVALID_LINK_SETTINGS;
41476150453fSSepherosa Ziehau 	}
41486150453fSSepherosa Ziehau 
41496150453fSSepherosa Ziehau 	if (hw->fc.requested_mode == ixgbe_fc_default)
41506150453fSSepherosa Ziehau 		hw->fc.requested_mode = ixgbe_fc_full;
41516150453fSSepherosa Ziehau 
41526150453fSSepherosa Ziehau 	/* Set up the 1G and 10G flow control advertisement registers so the
41536150453fSSepherosa Ziehau 	 * HW will be able to do FC autoneg once the cable is plugged in.  If
41546150453fSSepherosa Ziehau 	 * we link at 10G, the 1G advertisement is harmless and vice versa.
41556150453fSSepherosa Ziehau 	 */
41566150453fSSepherosa Ziehau 	status = hw->mac.ops.read_iosf_sb_reg(hw,
41576150453fSSepherosa Ziehau 					IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
41586150453fSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl);
41596150453fSSepherosa Ziehau 
41606150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS) {
41616150453fSSepherosa Ziehau 		DEBUGOUT("Auto-Negotiation did not complete\n");
41626150453fSSepherosa Ziehau 		return status;
41636150453fSSepherosa Ziehau 	}
41646150453fSSepherosa Ziehau 
41656150453fSSepherosa Ziehau 	/* The possible values of fc.requested_mode are:
41666150453fSSepherosa Ziehau 	 * 0: Flow control is completely disabled
41676150453fSSepherosa Ziehau 	 * 1: Rx flow control is enabled (we can receive pause frames,
41686150453fSSepherosa Ziehau 	 *    but not send pause frames).
41696150453fSSepherosa Ziehau 	 * 2: Tx flow control is enabled (we can send pause frames but
41706150453fSSepherosa Ziehau 	 *    we do not support receiving pause frames).
41716150453fSSepherosa Ziehau 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
41726150453fSSepherosa Ziehau 	 * other: Invalid.
41736150453fSSepherosa Ziehau 	 */
41746150453fSSepherosa Ziehau 	switch (hw->fc.requested_mode) {
41756150453fSSepherosa Ziehau 	case ixgbe_fc_none:
41766150453fSSepherosa Ziehau 		/* Flow control completely disabled by software override. */
41776150453fSSepherosa Ziehau 		an_cntl &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
41786150453fSSepherosa Ziehau 			     IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
41796150453fSSepherosa Ziehau 		break;
41806150453fSSepherosa Ziehau 	case ixgbe_fc_tx_pause:
41816150453fSSepherosa Ziehau 		/* Tx Flow control is enabled, and Rx Flow control is
41826150453fSSepherosa Ziehau 		 * disabled by software override.
41836150453fSSepherosa Ziehau 		 */
41846150453fSSepherosa Ziehau 		an_cntl |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
41856150453fSSepherosa Ziehau 		an_cntl &= ~IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
41866150453fSSepherosa Ziehau 		break;
41876150453fSSepherosa Ziehau 	case ixgbe_fc_rx_pause:
41886150453fSSepherosa Ziehau 		/* Rx Flow control is enabled and Tx Flow control is
41896150453fSSepherosa Ziehau 		 * disabled by software override. Since there really
41906150453fSSepherosa Ziehau 		 * isn't a way to advertise that we are capable of RX
41916150453fSSepherosa Ziehau 		 * Pause ONLY, we will advertise that we support both
41926150453fSSepherosa Ziehau 		 * symmetric and asymmetric Rx PAUSE, as such we fall
41936150453fSSepherosa Ziehau 		 * through to the fc_full statement.  Later, we will
41946150453fSSepherosa Ziehau 		 * disable the adapter's ability to send PAUSE frames.
41956150453fSSepherosa Ziehau 		 */
41966150453fSSepherosa Ziehau 	case ixgbe_fc_full:
41976150453fSSepherosa Ziehau 		/* Flow control (both Rx and Tx) is enabled by SW override. */
41986150453fSSepherosa Ziehau 		an_cntl |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
41996150453fSSepherosa Ziehau 			   IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
42006150453fSSepherosa Ziehau 		break;
42016150453fSSepherosa Ziehau 	default:
42026150453fSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
42036150453fSSepherosa Ziehau 			      "Flow control param set incorrectly\n");
42046150453fSSepherosa Ziehau 		return IXGBE_ERR_CONFIG;
42056150453fSSepherosa Ziehau 	}
42066150453fSSepherosa Ziehau 
42076150453fSSepherosa Ziehau 	status = hw->mac.ops.write_iosf_sb_reg(hw,
42086150453fSSepherosa Ziehau 					IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
42096150453fSSepherosa Ziehau 					IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl);
42106150453fSSepherosa Ziehau 
42116150453fSSepherosa Ziehau 	/* Restart auto-negotiation. */
42126150453fSSepherosa Ziehau 	status = ixgbe_restart_an_internal_phy_x550em(hw);
42136150453fSSepherosa Ziehau 
42146150453fSSepherosa Ziehau 	return status;
42156150453fSSepherosa Ziehau }
42166150453fSSepherosa Ziehau 
42176150453fSSepherosa Ziehau /**
421863d483cdSSepherosa Ziehau  * ixgbe_set_mux - Set mux for port 1 access with CS4227
421963d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
422063d483cdSSepherosa Ziehau  * @state: set mux if 1, clear if 0
422163d483cdSSepherosa Ziehau  */
ixgbe_set_mux(struct ixgbe_hw * hw,u8 state)422263d483cdSSepherosa Ziehau static void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state)
422363d483cdSSepherosa Ziehau {
422463d483cdSSepherosa Ziehau 	u32 esdp;
422563d483cdSSepherosa Ziehau 
422663d483cdSSepherosa Ziehau 	if (!hw->bus.lan_id)
422763d483cdSSepherosa Ziehau 		return;
422863d483cdSSepherosa Ziehau 	esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
422963d483cdSSepherosa Ziehau 	if (state)
423063d483cdSSepherosa Ziehau 		esdp |= IXGBE_ESDP_SDP1;
423163d483cdSSepherosa Ziehau 	else
423263d483cdSSepherosa Ziehau 		esdp &= ~IXGBE_ESDP_SDP1;
423363d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
423463d483cdSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
423563d483cdSSepherosa Ziehau }
423663d483cdSSepherosa Ziehau 
423763d483cdSSepherosa Ziehau /**
423863d483cdSSepherosa Ziehau  *  ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
423963d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
424063d483cdSSepherosa Ziehau  *  @mask: Mask to specify which semaphore to acquire
424163d483cdSSepherosa Ziehau  *
424263d483cdSSepherosa Ziehau  *  Acquires the SWFW semaphore and sets the I2C MUX
424363d483cdSSepherosa Ziehau  **/
ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw * hw,u32 mask)424463d483cdSSepherosa Ziehau s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
424563d483cdSSepherosa Ziehau {
424663d483cdSSepherosa Ziehau 	s32 status;
424763d483cdSSepherosa Ziehau 
424863d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_acquire_swfw_sync_X550em");
424963d483cdSSepherosa Ziehau 
425063d483cdSSepherosa Ziehau 	status = ixgbe_acquire_swfw_sync_X540(hw, mask);
425163d483cdSSepherosa Ziehau 	if (status)
425263d483cdSSepherosa Ziehau 		return status;
425363d483cdSSepherosa Ziehau 
425463d483cdSSepherosa Ziehau 	if (mask & IXGBE_GSSR_I2C_MASK)
425563d483cdSSepherosa Ziehau 		ixgbe_set_mux(hw, 1);
425663d483cdSSepherosa Ziehau 
425763d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
425863d483cdSSepherosa Ziehau }
425963d483cdSSepherosa Ziehau 
426063d483cdSSepherosa Ziehau /**
426163d483cdSSepherosa Ziehau  *  ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
426263d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
426363d483cdSSepherosa Ziehau  *  @mask: Mask to specify which semaphore to release
426463d483cdSSepherosa Ziehau  *
426563d483cdSSepherosa Ziehau  *  Releases the SWFW semaphore and sets the I2C MUX
426663d483cdSSepherosa Ziehau  **/
ixgbe_release_swfw_sync_X550em(struct ixgbe_hw * hw,u32 mask)426763d483cdSSepherosa Ziehau void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
426863d483cdSSepherosa Ziehau {
426963d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_release_swfw_sync_X550em");
427063d483cdSSepherosa Ziehau 
427163d483cdSSepherosa Ziehau 	if (mask & IXGBE_GSSR_I2C_MASK)
427263d483cdSSepherosa Ziehau 		ixgbe_set_mux(hw, 0);
427363d483cdSSepherosa Ziehau 
427463d483cdSSepherosa Ziehau 	ixgbe_release_swfw_sync_X540(hw, mask);
427563d483cdSSepherosa Ziehau }
427663d483cdSSepherosa Ziehau 
427763d483cdSSepherosa Ziehau /**
42786150453fSSepherosa Ziehau  *  ixgbe_acquire_swfw_sync_X550a - Acquire SWFW semaphore
42796150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
42806150453fSSepherosa Ziehau  *  @mask: Mask to specify which semaphore to acquire
42816150453fSSepherosa Ziehau  *
42826150453fSSepherosa Ziehau  *  Acquires the SWFW semaphore and get the shared phy token as needed
42836150453fSSepherosa Ziehau  */
ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw * hw,u32 mask)42846150453fSSepherosa Ziehau static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask)
42856150453fSSepherosa Ziehau {
42866150453fSSepherosa Ziehau 	u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
42876150453fSSepherosa Ziehau 	int retries = FW_PHY_TOKEN_RETRIES;
42886150453fSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
42896150453fSSepherosa Ziehau 
42906150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_acquire_swfw_sync_X550a");
42916150453fSSepherosa Ziehau 
42926150453fSSepherosa Ziehau 	while (--retries) {
42936150453fSSepherosa Ziehau 		status = IXGBE_SUCCESS;
42946150453fSSepherosa Ziehau 		if (hmask)
42956150453fSSepherosa Ziehau 			status = ixgbe_acquire_swfw_sync_X540(hw, hmask);
42966150453fSSepherosa Ziehau 		if (status) {
42976150453fSSepherosa Ziehau 			DEBUGOUT1("Could not acquire SWFW semaphore, Status = %d\n",
42986150453fSSepherosa Ziehau 				  status);
42996150453fSSepherosa Ziehau 			return status;
43006150453fSSepherosa Ziehau 		}
43016150453fSSepherosa Ziehau 		if (!(mask & IXGBE_GSSR_TOKEN_SM))
43026150453fSSepherosa Ziehau 			return IXGBE_SUCCESS;
43036150453fSSepherosa Ziehau 
43046150453fSSepherosa Ziehau 		status = ixgbe_get_phy_token(hw);
43056150453fSSepherosa Ziehau 		if (status == IXGBE_ERR_TOKEN_RETRY)
43066150453fSSepherosa Ziehau 			DEBUGOUT1("Could not acquire PHY token, Status = %d\n",
43076150453fSSepherosa Ziehau 				  status);
43086150453fSSepherosa Ziehau 
43096150453fSSepherosa Ziehau 		if (status == IXGBE_SUCCESS)
43106150453fSSepherosa Ziehau 			return IXGBE_SUCCESS;
43116150453fSSepherosa Ziehau 
43126150453fSSepherosa Ziehau 		if (hmask)
43136150453fSSepherosa Ziehau 			ixgbe_release_swfw_sync_X540(hw, hmask);
43146150453fSSepherosa Ziehau 
43156150453fSSepherosa Ziehau 		if (status != IXGBE_ERR_TOKEN_RETRY) {
43166150453fSSepherosa Ziehau 			DEBUGOUT1("Unable to retry acquiring the PHY token, Status = %d\n",
43176150453fSSepherosa Ziehau 				  status);
43186150453fSSepherosa Ziehau 			return status;
43196150453fSSepherosa Ziehau 		}
43206150453fSSepherosa Ziehau 	}
43216150453fSSepherosa Ziehau 
43226150453fSSepherosa Ziehau 	DEBUGOUT1("Semaphore acquisition retries failed!: PHY ID = 0x%08X\n",
43236150453fSSepherosa Ziehau 		  hw->phy.id);
43246150453fSSepherosa Ziehau 	return status;
43256150453fSSepherosa Ziehau }
43266150453fSSepherosa Ziehau 
43276150453fSSepherosa Ziehau /**
43286150453fSSepherosa Ziehau  *  ixgbe_release_swfw_sync_X550a - Release SWFW semaphore
43296150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
43306150453fSSepherosa Ziehau  *  @mask: Mask to specify which semaphore to release
43316150453fSSepherosa Ziehau  *
43326150453fSSepherosa Ziehau  *  Releases the SWFW semaphore and puts the shared phy token as needed
43336150453fSSepherosa Ziehau  */
ixgbe_release_swfw_sync_X550a(struct ixgbe_hw * hw,u32 mask)43346150453fSSepherosa Ziehau static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask)
43356150453fSSepherosa Ziehau {
43366150453fSSepherosa Ziehau 	u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
43376150453fSSepherosa Ziehau 
43386150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_release_swfw_sync_X550a");
43396150453fSSepherosa Ziehau 
43406150453fSSepherosa Ziehau 	if (mask & IXGBE_GSSR_TOKEN_SM)
43416150453fSSepherosa Ziehau 		ixgbe_put_phy_token(hw);
43426150453fSSepherosa Ziehau 
43436150453fSSepherosa Ziehau 	if (hmask)
43446150453fSSepherosa Ziehau 		ixgbe_release_swfw_sync_X540(hw, hmask);
43456150453fSSepherosa Ziehau }
43466150453fSSepherosa Ziehau 
43476150453fSSepherosa Ziehau /**
43486150453fSSepherosa Ziehau  *  ixgbe_read_phy_reg_x550a  - Reads specified PHY register
43496150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
43506150453fSSepherosa Ziehau  *  @reg_addr: 32 bit address of PHY register to read
4351*dd5ce676SSepherosa Ziehau  *  @device_type: 5 bit device type
43526150453fSSepherosa Ziehau  *  @phy_data: Pointer to read data from PHY register
43536150453fSSepherosa Ziehau  *
43546150453fSSepherosa Ziehau  *  Reads a value from a specified PHY register using the SWFW lock and PHY
43556150453fSSepherosa Ziehau  *  Token. The PHY Token is needed since the MDIO is shared between to MAC
43566150453fSSepherosa Ziehau  *  instances.
43576150453fSSepherosa Ziehau  **/
ixgbe_read_phy_reg_x550a(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 * phy_data)43586150453fSSepherosa Ziehau s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
43596150453fSSepherosa Ziehau 			       u32 device_type, u16 *phy_data)
43606150453fSSepherosa Ziehau {
43616150453fSSepherosa Ziehau 	s32 status;
43626150453fSSepherosa Ziehau 	u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
43636150453fSSepherosa Ziehau 
43646150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_phy_reg_x550a");
43656150453fSSepherosa Ziehau 
43666150453fSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, mask))
43676150453fSSepherosa Ziehau 		return IXGBE_ERR_SWFW_SYNC;
43686150453fSSepherosa Ziehau 
43696150453fSSepherosa Ziehau 	status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data);
43706150453fSSepherosa Ziehau 
43716150453fSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, mask);
43726150453fSSepherosa Ziehau 
43736150453fSSepherosa Ziehau 	return status;
43746150453fSSepherosa Ziehau }
43756150453fSSepherosa Ziehau 
43766150453fSSepherosa Ziehau /**
43776150453fSSepherosa Ziehau  *  ixgbe_write_phy_reg_x550a - Writes specified PHY register
43786150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
43796150453fSSepherosa Ziehau  *  @reg_addr: 32 bit PHY register to write
43806150453fSSepherosa Ziehau  *  @device_type: 5 bit device type
43816150453fSSepherosa Ziehau  *  @phy_data: Data to write to the PHY register
43826150453fSSepherosa Ziehau  *
43836150453fSSepherosa Ziehau  *  Writes a value to specified PHY register using the SWFW lock and PHY Token.
43846150453fSSepherosa Ziehau  *  The PHY Token is needed since the MDIO is shared between to MAC instances.
43856150453fSSepherosa Ziehau  **/
ixgbe_write_phy_reg_x550a(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 phy_data)43866150453fSSepherosa Ziehau s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
43876150453fSSepherosa Ziehau 				u32 device_type, u16 phy_data)
43886150453fSSepherosa Ziehau {
43896150453fSSepherosa Ziehau 	s32 status;
43906150453fSSepherosa Ziehau 	u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
43916150453fSSepherosa Ziehau 
43926150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_phy_reg_x550a");
43936150453fSSepherosa Ziehau 
43946150453fSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, mask) == IXGBE_SUCCESS) {
43956150453fSSepherosa Ziehau 		status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type,
43966150453fSSepherosa Ziehau 						 phy_data);
43976150453fSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, mask);
43986150453fSSepherosa Ziehau 	} else {
43996150453fSSepherosa Ziehau 		status = IXGBE_ERR_SWFW_SYNC;
44006150453fSSepherosa Ziehau 	}
44016150453fSSepherosa Ziehau 
44026150453fSSepherosa Ziehau 	return status;
44036150453fSSepherosa Ziehau }
44046150453fSSepherosa Ziehau 
44056150453fSSepherosa Ziehau /**
440663d483cdSSepherosa Ziehau  * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
440763d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
440863d483cdSSepherosa Ziehau  *
440963d483cdSSepherosa Ziehau  * Handle external Base T PHY interrupt. If high temperature
441063d483cdSSepherosa Ziehau  * failure alarm then return error, else if link status change
441163d483cdSSepherosa Ziehau  * then setup internal/external PHY link
441263d483cdSSepherosa Ziehau  *
441363d483cdSSepherosa Ziehau  * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
441463d483cdSSepherosa Ziehau  * failure alarm, else return PHY access status.
441563d483cdSSepherosa Ziehau  */
ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw * hw)441663d483cdSSepherosa Ziehau s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
441763d483cdSSepherosa Ziehau {
441863d483cdSSepherosa Ziehau 	bool lsc;
441963d483cdSSepherosa Ziehau 	u32 status;
442063d483cdSSepherosa Ziehau 
442163d483cdSSepherosa Ziehau 	status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
442263d483cdSSepherosa Ziehau 
442363d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
442463d483cdSSepherosa Ziehau 		return status;
442563d483cdSSepherosa Ziehau 
442663d483cdSSepherosa Ziehau 	if (lsc)
442763d483cdSSepherosa Ziehau 		return ixgbe_setup_internal_phy(hw);
442863d483cdSSepherosa Ziehau 
442963d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
443063d483cdSSepherosa Ziehau }
443163d483cdSSepherosa Ziehau 
443263d483cdSSepherosa Ziehau /**
443363d483cdSSepherosa Ziehau  * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed
443463d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
443563d483cdSSepherosa Ziehau  * @speed: new link speed
443663d483cdSSepherosa Ziehau  * @autoneg_wait_to_complete: TRUE when waiting for completion is needed
443763d483cdSSepherosa Ziehau  *
443863d483cdSSepherosa Ziehau  * Setup internal/external PHY link speed based on link speed, then set
443963d483cdSSepherosa Ziehau  * external PHY auto advertised link speed.
444063d483cdSSepherosa Ziehau  *
444163d483cdSSepherosa Ziehau  * Returns error status for any failure
444263d483cdSSepherosa Ziehau  **/
ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)444363d483cdSSepherosa Ziehau s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
444463d483cdSSepherosa Ziehau 				  ixgbe_link_speed speed,
444563d483cdSSepherosa Ziehau 				  bool autoneg_wait_to_complete)
444663d483cdSSepherosa Ziehau {
444763d483cdSSepherosa Ziehau 	s32 status;
444863d483cdSSepherosa Ziehau 	ixgbe_link_speed force_speed;
444963d483cdSSepherosa Ziehau 
445063d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_mac_link_t_X550em");
445163d483cdSSepherosa Ziehau 
445263d483cdSSepherosa Ziehau 	/* Setup internal/external PHY link speed to iXFI (10G), unless
445363d483cdSSepherosa Ziehau 	 * only 1G is auto advertised then setup KX link.
445463d483cdSSepherosa Ziehau 	 */
445563d483cdSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
445663d483cdSSepherosa Ziehau 		force_speed = IXGBE_LINK_SPEED_10GB_FULL;
445763d483cdSSepherosa Ziehau 	else
445863d483cdSSepherosa Ziehau 		force_speed = IXGBE_LINK_SPEED_1GB_FULL;
445963d483cdSSepherosa Ziehau 
44606150453fSSepherosa Ziehau 	/* If X552 and internal link mode is XFI, then setup XFI internal link.
44616150453fSSepherosa Ziehau 	 */
44626150453fSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_X550EM_x &&
44636150453fSSepherosa Ziehau 	    !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
446463d483cdSSepherosa Ziehau 		status = ixgbe_setup_ixfi_x550em(hw, &force_speed);
446563d483cdSSepherosa Ziehau 
446663d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
446763d483cdSSepherosa Ziehau 			return status;
446863d483cdSSepherosa Ziehau 	}
446963d483cdSSepherosa Ziehau 
447063d483cdSSepherosa Ziehau 	return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
447163d483cdSSepherosa Ziehau }
447263d483cdSSepherosa Ziehau 
447363d483cdSSepherosa Ziehau /**
447463d483cdSSepherosa Ziehau  * ixgbe_check_link_t_X550em - Determine link and speed status
447563d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
447663d483cdSSepherosa Ziehau  * @speed: pointer to link speed
447763d483cdSSepherosa Ziehau  * @link_up: TRUE when link is up
447863d483cdSSepherosa Ziehau  * @link_up_wait_to_complete: bool used to wait for link up or not
447963d483cdSSepherosa Ziehau  *
448063d483cdSSepherosa Ziehau  * Check that both the MAC and X557 external PHY have link.
448163d483cdSSepherosa Ziehau  **/
ixgbe_check_link_t_X550em(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * link_up,bool link_up_wait_to_complete)448263d483cdSSepherosa Ziehau s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
448363d483cdSSepherosa Ziehau 			      bool *link_up, bool link_up_wait_to_complete)
448463d483cdSSepherosa Ziehau {
448563d483cdSSepherosa Ziehau 	u32 status;
44866150453fSSepherosa Ziehau 	u16 i, autoneg_status = 0;
448763d483cdSSepherosa Ziehau 
448863d483cdSSepherosa Ziehau 	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
448963d483cdSSepherosa Ziehau 		return IXGBE_ERR_CONFIG;
449063d483cdSSepherosa Ziehau 
449163d483cdSSepherosa Ziehau 	status = ixgbe_check_mac_link_generic(hw, speed, link_up,
449263d483cdSSepherosa Ziehau 					      link_up_wait_to_complete);
449363d483cdSSepherosa Ziehau 
449463d483cdSSepherosa Ziehau 	/* If check link fails or MAC link is not up, then return */
449563d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS || !(*link_up))
449663d483cdSSepherosa Ziehau 		return status;
449763d483cdSSepherosa Ziehau 
449863d483cdSSepherosa Ziehau 	/* MAC link is up, so check external PHY link.
44996150453fSSepherosa Ziehau 	 * X557 PHY. Link status is latching low, and can only be used to detect
45006150453fSSepherosa Ziehau 	 * link drop, and not the current status of the link without performing
45016150453fSSepherosa Ziehau 	 * back-to-back reads.
450263d483cdSSepherosa Ziehau 	 */
45036150453fSSepherosa Ziehau 	for (i = 0; i < 2; i++) {
450463d483cdSSepherosa Ziehau 		status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
450563d483cdSSepherosa Ziehau 					      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
450663d483cdSSepherosa Ziehau 					      &autoneg_status);
450763d483cdSSepherosa Ziehau 
450863d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
450963d483cdSSepherosa Ziehau 			return status;
45106150453fSSepherosa Ziehau 	}
451163d483cdSSepherosa Ziehau 
451263d483cdSSepherosa Ziehau 	/* If external PHY link is not up, then indicate link not up */
451363d483cdSSepherosa Ziehau 	if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
451463d483cdSSepherosa Ziehau 		*link_up = FALSE;
451563d483cdSSepherosa Ziehau 
451663d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
451763d483cdSSepherosa Ziehau }
451863d483cdSSepherosa Ziehau 
451963d483cdSSepherosa Ziehau /**
452063d483cdSSepherosa Ziehau  *  ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI
452163d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
452263d483cdSSepherosa Ziehau  **/
ixgbe_reset_phy_t_X550em(struct ixgbe_hw * hw)452363d483cdSSepherosa Ziehau s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw)
452463d483cdSSepherosa Ziehau {
452563d483cdSSepherosa Ziehau 	s32 status;
452663d483cdSSepherosa Ziehau 
452763d483cdSSepherosa Ziehau 	status = ixgbe_reset_phy_generic(hw);
452863d483cdSSepherosa Ziehau 
452963d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
453063d483cdSSepherosa Ziehau 		return status;
453163d483cdSSepherosa Ziehau 
453263d483cdSSepherosa Ziehau 	/* Configure Link Status Alarm and Temperature Threshold interrupts */
453363d483cdSSepherosa Ziehau 	return ixgbe_enable_lasi_ext_t_x550em(hw);
453463d483cdSSepherosa Ziehau }
45356150453fSSepherosa Ziehau 
45366150453fSSepherosa Ziehau /**
45376150453fSSepherosa Ziehau  *  ixgbe_led_on_t_X550em - Turns on the software controllable LEDs.
45386150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
45396150453fSSepherosa Ziehau  *  @led_idx: led number to turn on
45406150453fSSepherosa Ziehau  **/
ixgbe_led_on_t_X550em(struct ixgbe_hw * hw,u32 led_idx)45416150453fSSepherosa Ziehau s32 ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
45426150453fSSepherosa Ziehau {
45436150453fSSepherosa Ziehau 	u16 phy_data;
45446150453fSSepherosa Ziehau 
45456150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_led_on_t_X550em");
45466150453fSSepherosa Ziehau 
45476150453fSSepherosa Ziehau 	if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
45486150453fSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
45496150453fSSepherosa Ziehau 
45506150453fSSepherosa Ziehau 	/* To turn on the LED, set mode to ON. */
45516150453fSSepherosa Ziehau 	ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
45526150453fSSepherosa Ziehau 			   IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
45536150453fSSepherosa Ziehau 	phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK;
45546150453fSSepherosa Ziehau 	ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
45556150453fSSepherosa Ziehau 			    IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
45566150453fSSepherosa Ziehau 
45576150453fSSepherosa Ziehau 	/* Some designs have the LEDs wired to the MAC */
45586150453fSSepherosa Ziehau 	return ixgbe_led_on_generic(hw, led_idx);
45596150453fSSepherosa Ziehau }
45606150453fSSepherosa Ziehau 
45616150453fSSepherosa Ziehau /**
45626150453fSSepherosa Ziehau  *  ixgbe_led_off_t_X550em - Turns off the software controllable LEDs.
45636150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
45646150453fSSepherosa Ziehau  *  @led_idx: led number to turn off
45656150453fSSepherosa Ziehau  **/
ixgbe_led_off_t_X550em(struct ixgbe_hw * hw,u32 led_idx)45666150453fSSepherosa Ziehau s32 ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
45676150453fSSepherosa Ziehau {
45686150453fSSepherosa Ziehau 	u16 phy_data;
45696150453fSSepherosa Ziehau 
45706150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_led_off_t_X550em");
45716150453fSSepherosa Ziehau 
45726150453fSSepherosa Ziehau 	if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
45736150453fSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
45746150453fSSepherosa Ziehau 
45756150453fSSepherosa Ziehau 	/* To turn on the LED, set mode to ON. */
45766150453fSSepherosa Ziehau 	ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
45776150453fSSepherosa Ziehau 			   IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
45786150453fSSepherosa Ziehau 	phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK;
45796150453fSSepherosa Ziehau 	ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
45806150453fSSepherosa Ziehau 			    IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
45816150453fSSepherosa Ziehau 
45826150453fSSepherosa Ziehau 	/* Some designs have the LEDs wired to the MAC */
45836150453fSSepherosa Ziehau 	return ixgbe_led_off_generic(hw, led_idx);
45846150453fSSepherosa Ziehau }
45856150453fSSepherosa Ziehau 
45866150453fSSepherosa Ziehau /**
45876150453fSSepherosa Ziehau  *  ixgbe_set_fw_drv_ver_x550 - Sends driver version to firmware
45886150453fSSepherosa Ziehau  *  @hw: pointer to the HW structure
45896150453fSSepherosa Ziehau  *  @maj: driver version major number
45906150453fSSepherosa Ziehau  *  @min: driver version minor number
45916150453fSSepherosa Ziehau  *  @build: driver version build number
45926150453fSSepherosa Ziehau  *  @sub: driver version sub build number
45936150453fSSepherosa Ziehau  *  @len: length of driver_ver string
45946150453fSSepherosa Ziehau  *  @driver_ver: driver string
45956150453fSSepherosa Ziehau  *
45966150453fSSepherosa Ziehau  *  Sends driver version number to firmware through the manageability
45976150453fSSepherosa Ziehau  *  block.  On success return IXGBE_SUCCESS
45986150453fSSepherosa Ziehau  *  else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
45996150453fSSepherosa Ziehau  *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
46006150453fSSepherosa Ziehau  **/
ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw * hw,u8 maj,u8 min,u8 build,u8 sub,u16 len,const char * driver_ver)46016150453fSSepherosa Ziehau s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min,
46026150453fSSepherosa Ziehau 			      u8 build, u8 sub, u16 len, const char *driver_ver)
46036150453fSSepherosa Ziehau {
46046150453fSSepherosa Ziehau 	struct ixgbe_hic_drv_info2 fw_cmd;
46056150453fSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
46066150453fSSepherosa Ziehau 	int i;
46076150453fSSepherosa Ziehau 
46086150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_fw_drv_ver_x550");
46096150453fSSepherosa Ziehau 
46106150453fSSepherosa Ziehau 	if ((len == 0) || (driver_ver == NULL) ||
46116150453fSSepherosa Ziehau 	   (len > sizeof(fw_cmd.driver_string)))
46126150453fSSepherosa Ziehau 		return IXGBE_ERR_INVALID_ARGUMENT;
46136150453fSSepherosa Ziehau 
46146150453fSSepherosa Ziehau 	fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
46156150453fSSepherosa Ziehau 	fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len;
46166150453fSSepherosa Ziehau 	fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
46176150453fSSepherosa Ziehau 	fw_cmd.port_num = (u8)hw->bus.func;
46186150453fSSepherosa Ziehau 	fw_cmd.ver_maj = maj;
46196150453fSSepherosa Ziehau 	fw_cmd.ver_min = min;
46206150453fSSepherosa Ziehau 	fw_cmd.ver_build = build;
46216150453fSSepherosa Ziehau 	fw_cmd.ver_sub = sub;
46226150453fSSepherosa Ziehau 	fw_cmd.hdr.checksum = 0;
46236150453fSSepherosa Ziehau 	memcpy(fw_cmd.driver_string, driver_ver, len);
46246150453fSSepherosa Ziehau 	fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
46256150453fSSepherosa Ziehau 				(FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
46266150453fSSepherosa Ziehau 
46276150453fSSepherosa Ziehau 	for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
46286150453fSSepherosa Ziehau 		ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
46296150453fSSepherosa Ziehau 						       sizeof(fw_cmd),
46306150453fSSepherosa Ziehau 						       IXGBE_HI_COMMAND_TIMEOUT,
46316150453fSSepherosa Ziehau 						       TRUE);
46326150453fSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
46336150453fSSepherosa Ziehau 			continue;
46346150453fSSepherosa Ziehau 
46356150453fSSepherosa Ziehau 		if (fw_cmd.hdr.cmd_or_resp.ret_status ==
46366150453fSSepherosa Ziehau 		    FW_CEM_RESP_STATUS_SUCCESS)
46376150453fSSepherosa Ziehau 			ret_val = IXGBE_SUCCESS;
46386150453fSSepherosa Ziehau 		else
46396150453fSSepherosa Ziehau 			ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
46406150453fSSepherosa Ziehau 
46416150453fSSepherosa Ziehau 		break;
46426150453fSSepherosa Ziehau 	}
46436150453fSSepherosa Ziehau 
46446150453fSSepherosa Ziehau 	return ret_val;
46456150453fSSepherosa Ziehau }
4646*dd5ce676SSepherosa Ziehau 
4647*dd5ce676SSepherosa Ziehau /**
4648*dd5ce676SSepherosa Ziehau  * ixgbe_fw_recovery_mode_X550 - Check FW NVM recovery mode
4649*dd5ce676SSepherosa Ziehau  * @hw: pointer t hardware structure
4650*dd5ce676SSepherosa Ziehau  *
4651*dd5ce676SSepherosa Ziehau  * Returns TRUE if in FW NVM recovery mode.
4652*dd5ce676SSepherosa Ziehau  **/
ixgbe_fw_recovery_mode_X550(struct ixgbe_hw * hw)4653*dd5ce676SSepherosa Ziehau bool ixgbe_fw_recovery_mode_X550(struct ixgbe_hw *hw)
4654*dd5ce676SSepherosa Ziehau {
4655*dd5ce676SSepherosa Ziehau 	u32 fwsm;
4656*dd5ce676SSepherosa Ziehau 
4657*dd5ce676SSepherosa Ziehau 	fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw));
4658*dd5ce676SSepherosa Ziehau 
4659*dd5ce676SSepherosa Ziehau 	return !!(fwsm & IXGBE_FWSM_FW_NVM_RECOVERY_MODE);
4660*dd5ce676SSepherosa Ziehau }
4661*dd5ce676SSepherosa Ziehau 
4662