xref: /dflybsd-src/sys/dev/netif/ix/ixgbe_phy.c (revision dd5ce676d9b4496101d795200cb99fd0ddf5b254)
179251f5eSSepherosa Ziehau /******************************************************************************
279251f5eSSepherosa Ziehau 
36150453fSSepherosa Ziehau   Copyright (c) 2001-2017, Intel Corporation
479251f5eSSepherosa Ziehau   All rights reserved.
579251f5eSSepherosa Ziehau 
679251f5eSSepherosa Ziehau   Redistribution and use in source and binary forms, with or without
779251f5eSSepherosa Ziehau   modification, are permitted provided that the following conditions are met:
879251f5eSSepherosa Ziehau 
979251f5eSSepherosa Ziehau    1. Redistributions of source code must retain the above copyright notice,
1079251f5eSSepherosa Ziehau       this list of conditions and the following disclaimer.
1179251f5eSSepherosa Ziehau 
1279251f5eSSepherosa Ziehau    2. Redistributions in binary form must reproduce the above copyright
1379251f5eSSepherosa Ziehau       notice, this list of conditions and the following disclaimer in the
1479251f5eSSepherosa Ziehau       documentation and/or other materials provided with the distribution.
1579251f5eSSepherosa Ziehau 
1679251f5eSSepherosa Ziehau    3. Neither the name of the Intel Corporation nor the names of its
1779251f5eSSepherosa Ziehau       contributors may be used to endorse or promote products derived from
1879251f5eSSepherosa Ziehau       this software without specific prior written permission.
1979251f5eSSepherosa Ziehau 
2079251f5eSSepherosa Ziehau   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2179251f5eSSepherosa Ziehau   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2279251f5eSSepherosa Ziehau   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2379251f5eSSepherosa Ziehau   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2479251f5eSSepherosa Ziehau   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2579251f5eSSepherosa Ziehau   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2679251f5eSSepherosa Ziehau   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2779251f5eSSepherosa Ziehau   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2879251f5eSSepherosa Ziehau   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2979251f5eSSepherosa Ziehau   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3079251f5eSSepherosa Ziehau   POSSIBILITY OF SUCH DAMAGE.
3179251f5eSSepherosa Ziehau 
3279251f5eSSepherosa Ziehau ******************************************************************************/
3379251f5eSSepherosa Ziehau /*$FreeBSD$*/
3479251f5eSSepherosa Ziehau 
3579251f5eSSepherosa Ziehau #include "ixgbe_api.h"
3679251f5eSSepherosa Ziehau #include "ixgbe_common.h"
3779251f5eSSepherosa Ziehau #include "ixgbe_phy.h"
3879251f5eSSepherosa Ziehau 
3979251f5eSSepherosa Ziehau static void ixgbe_i2c_start(struct ixgbe_hw *hw);
4079251f5eSSepherosa Ziehau static void ixgbe_i2c_stop(struct ixgbe_hw *hw);
4179251f5eSSepherosa Ziehau static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data);
4279251f5eSSepherosa Ziehau static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data);
4379251f5eSSepherosa Ziehau static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw);
4479251f5eSSepherosa Ziehau static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data);
4579251f5eSSepherosa Ziehau static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data);
4679251f5eSSepherosa Ziehau static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
4779251f5eSSepherosa Ziehau static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
4879251f5eSSepherosa Ziehau static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
4963d483cdSSepherosa Ziehau static bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl);
5079251f5eSSepherosa Ziehau static s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
5179251f5eSSepherosa Ziehau 					  u8 *sff8472_data);
5279251f5eSSepherosa Ziehau 
5379251f5eSSepherosa Ziehau /**
5463d483cdSSepherosa Ziehau  * ixgbe_out_i2c_byte_ack - Send I2C byte with ack
5563d483cdSSepherosa Ziehau  * @hw: pointer to the hardware structure
5663d483cdSSepherosa Ziehau  * @byte: byte to send
5763d483cdSSepherosa Ziehau  *
5863d483cdSSepherosa Ziehau  * Returns an error code on error.
5963d483cdSSepherosa Ziehau  */
ixgbe_out_i2c_byte_ack(struct ixgbe_hw * hw,u8 byte)6063d483cdSSepherosa Ziehau static s32 ixgbe_out_i2c_byte_ack(struct ixgbe_hw *hw, u8 byte)
6163d483cdSSepherosa Ziehau {
6263d483cdSSepherosa Ziehau 	s32 status;
6363d483cdSSepherosa Ziehau 
6463d483cdSSepherosa Ziehau 	status = ixgbe_clock_out_i2c_byte(hw, byte);
6563d483cdSSepherosa Ziehau 	if (status)
6663d483cdSSepherosa Ziehau 		return status;
6763d483cdSSepherosa Ziehau 	return ixgbe_get_i2c_ack(hw);
6863d483cdSSepherosa Ziehau }
6963d483cdSSepherosa Ziehau 
7063d483cdSSepherosa Ziehau /**
7163d483cdSSepherosa Ziehau  * ixgbe_in_i2c_byte_ack - Receive an I2C byte and send ack
7263d483cdSSepherosa Ziehau  * @hw: pointer to the hardware structure
7363d483cdSSepherosa Ziehau  * @byte: pointer to a u8 to receive the byte
7463d483cdSSepherosa Ziehau  *
7563d483cdSSepherosa Ziehau  * Returns an error code on error.
7663d483cdSSepherosa Ziehau  */
ixgbe_in_i2c_byte_ack(struct ixgbe_hw * hw,u8 * byte)7763d483cdSSepherosa Ziehau static s32 ixgbe_in_i2c_byte_ack(struct ixgbe_hw *hw, u8 *byte)
7863d483cdSSepherosa Ziehau {
7963d483cdSSepherosa Ziehau 	s32 status;
8063d483cdSSepherosa Ziehau 
8163d483cdSSepherosa Ziehau 	status = ixgbe_clock_in_i2c_byte(hw, byte);
8263d483cdSSepherosa Ziehau 	if (status)
8363d483cdSSepherosa Ziehau 		return status;
8463d483cdSSepherosa Ziehau 	/* ACK */
8563d483cdSSepherosa Ziehau 	return ixgbe_clock_out_i2c_bit(hw, FALSE);
8663d483cdSSepherosa Ziehau }
8763d483cdSSepherosa Ziehau 
8863d483cdSSepherosa Ziehau /**
8963d483cdSSepherosa Ziehau  * ixgbe_ones_comp_byte_add - Perform one's complement addition
90*dd5ce676SSepherosa Ziehau  * @add1: addend 1
91*dd5ce676SSepherosa Ziehau  * @add2: addend 2
9263d483cdSSepherosa Ziehau  *
9363d483cdSSepherosa Ziehau  * Returns one's complement 8-bit sum.
9463d483cdSSepherosa Ziehau  */
ixgbe_ones_comp_byte_add(u8 add1,u8 add2)9563d483cdSSepherosa Ziehau static u8 ixgbe_ones_comp_byte_add(u8 add1, u8 add2)
9663d483cdSSepherosa Ziehau {
9763d483cdSSepherosa Ziehau 	u16 sum = add1 + add2;
9863d483cdSSepherosa Ziehau 
9963d483cdSSepherosa Ziehau 	sum = (sum & 0xFF) + (sum >> 8);
10063d483cdSSepherosa Ziehau 	return sum & 0xFF;
10163d483cdSSepherosa Ziehau }
10263d483cdSSepherosa Ziehau 
10363d483cdSSepherosa Ziehau /**
10463d483cdSSepherosa Ziehau  * ixgbe_read_i2c_combined_generic_int - Perform I2C read combined operation
10563d483cdSSepherosa Ziehau  * @hw: pointer to the hardware structure
10663d483cdSSepherosa Ziehau  * @addr: I2C bus address to read from
10763d483cdSSepherosa Ziehau  * @reg: I2C device register to read from
10863d483cdSSepherosa Ziehau  * @val: pointer to location to receive read value
10963d483cdSSepherosa Ziehau  * @lock: TRUE if to take and release semaphore
11063d483cdSSepherosa Ziehau  *
11163d483cdSSepherosa Ziehau  * Returns an error code on error.
11263d483cdSSepherosa Ziehau  */
ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 * val,bool lock)1136150453fSSepherosa Ziehau s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, u16 reg,
1146150453fSSepherosa Ziehau 					u16 *val, bool lock)
11563d483cdSSepherosa Ziehau {
11663d483cdSSepherosa Ziehau 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
1176150453fSSepherosa Ziehau 	int max_retry = 3;
11863d483cdSSepherosa Ziehau 	int retry = 0;
11963d483cdSSepherosa Ziehau 	u8 csum_byte;
12063d483cdSSepherosa Ziehau 	u8 high_bits;
12163d483cdSSepherosa Ziehau 	u8 low_bits;
12263d483cdSSepherosa Ziehau 	u8 reg_high;
12363d483cdSSepherosa Ziehau 	u8 csum;
12463d483cdSSepherosa Ziehau 
12563d483cdSSepherosa Ziehau 	reg_high = ((reg >> 7) & 0xFE) | 1;	/* Indicate read combined */
12663d483cdSSepherosa Ziehau 	csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF);
12763d483cdSSepherosa Ziehau 	csum = ~csum;
12863d483cdSSepherosa Ziehau 	do {
12963d483cdSSepherosa Ziehau 		if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
13063d483cdSSepherosa Ziehau 			return IXGBE_ERR_SWFW_SYNC;
13163d483cdSSepherosa Ziehau 		ixgbe_i2c_start(hw);
13263d483cdSSepherosa Ziehau 		/* Device Address and write indication */
13363d483cdSSepherosa Ziehau 		if (ixgbe_out_i2c_byte_ack(hw, addr))
13463d483cdSSepherosa Ziehau 			goto fail;
13563d483cdSSepherosa Ziehau 		/* Write bits 14:8 */
13663d483cdSSepherosa Ziehau 		if (ixgbe_out_i2c_byte_ack(hw, reg_high))
13763d483cdSSepherosa Ziehau 			goto fail;
13863d483cdSSepherosa Ziehau 		/* Write bits 7:0 */
13963d483cdSSepherosa Ziehau 		if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF))
14063d483cdSSepherosa Ziehau 			goto fail;
14163d483cdSSepherosa Ziehau 		/* Write csum */
14263d483cdSSepherosa Ziehau 		if (ixgbe_out_i2c_byte_ack(hw, csum))
14363d483cdSSepherosa Ziehau 			goto fail;
14463d483cdSSepherosa Ziehau 		/* Re-start condition */
14563d483cdSSepherosa Ziehau 		ixgbe_i2c_start(hw);
14663d483cdSSepherosa Ziehau 		/* Device Address and read indication */
14763d483cdSSepherosa Ziehau 		if (ixgbe_out_i2c_byte_ack(hw, addr | 1))
14863d483cdSSepherosa Ziehau 			goto fail;
14963d483cdSSepherosa Ziehau 		/* Get upper bits */
15063d483cdSSepherosa Ziehau 		if (ixgbe_in_i2c_byte_ack(hw, &high_bits))
15163d483cdSSepherosa Ziehau 			goto fail;
15263d483cdSSepherosa Ziehau 		/* Get low bits */
15363d483cdSSepherosa Ziehau 		if (ixgbe_in_i2c_byte_ack(hw, &low_bits))
15463d483cdSSepherosa Ziehau 			goto fail;
15563d483cdSSepherosa Ziehau 		/* Get csum */
15663d483cdSSepherosa Ziehau 		if (ixgbe_clock_in_i2c_byte(hw, &csum_byte))
15763d483cdSSepherosa Ziehau 			goto fail;
15863d483cdSSepherosa Ziehau 		/* NACK */
15963d483cdSSepherosa Ziehau 		if (ixgbe_clock_out_i2c_bit(hw, FALSE))
16063d483cdSSepherosa Ziehau 			goto fail;
16163d483cdSSepherosa Ziehau 		ixgbe_i2c_stop(hw);
16263d483cdSSepherosa Ziehau 		if (lock)
16363d483cdSSepherosa Ziehau 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
16463d483cdSSepherosa Ziehau 		*val = (high_bits << 8) | low_bits;
16563d483cdSSepherosa Ziehau 		return 0;
16663d483cdSSepherosa Ziehau 
16763d483cdSSepherosa Ziehau fail:
16863d483cdSSepherosa Ziehau 		ixgbe_i2c_bus_clear(hw);
16963d483cdSSepherosa Ziehau 		if (lock)
17063d483cdSSepherosa Ziehau 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
17163d483cdSSepherosa Ziehau 		retry++;
17263d483cdSSepherosa Ziehau 		if (retry < max_retry)
17363d483cdSSepherosa Ziehau 			DEBUGOUT("I2C byte read combined error - Retrying.\n");
17463d483cdSSepherosa Ziehau 		else
17563d483cdSSepherosa Ziehau 			DEBUGOUT("I2C byte read combined error.\n");
17663d483cdSSepherosa Ziehau 	} while (retry < max_retry);
17763d483cdSSepherosa Ziehau 
17863d483cdSSepherosa Ziehau 	return IXGBE_ERR_I2C;
17963d483cdSSepherosa Ziehau }
18063d483cdSSepherosa Ziehau 
18163d483cdSSepherosa Ziehau /**
18263d483cdSSepherosa Ziehau  * ixgbe_write_i2c_combined_generic_int - Perform I2C write combined operation
18363d483cdSSepherosa Ziehau  * @hw: pointer to the hardware structure
18463d483cdSSepherosa Ziehau  * @addr: I2C bus address to write to
18563d483cdSSepherosa Ziehau  * @reg: I2C device register to write to
18663d483cdSSepherosa Ziehau  * @val: value to write
18763d483cdSSepherosa Ziehau  * @lock: TRUE if to take and release semaphore
18863d483cdSSepherosa Ziehau  *
18963d483cdSSepherosa Ziehau  * Returns an error code on error.
19063d483cdSSepherosa Ziehau  */
ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 val,bool lock)1916150453fSSepherosa Ziehau s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, u16 reg,
1926150453fSSepherosa Ziehau 					 u16 val, bool lock)
19363d483cdSSepherosa Ziehau {
19463d483cdSSepherosa Ziehau 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
19563d483cdSSepherosa Ziehau 	int max_retry = 1;
19663d483cdSSepherosa Ziehau 	int retry = 0;
19763d483cdSSepherosa Ziehau 	u8 reg_high;
19863d483cdSSepherosa Ziehau 	u8 csum;
19963d483cdSSepherosa Ziehau 
20063d483cdSSepherosa Ziehau 	reg_high = (reg >> 7) & 0xFE;	/* Indicate write combined */
20163d483cdSSepherosa Ziehau 	csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF);
20263d483cdSSepherosa Ziehau 	csum = ixgbe_ones_comp_byte_add(csum, val >> 8);
20363d483cdSSepherosa Ziehau 	csum = ixgbe_ones_comp_byte_add(csum, val & 0xFF);
20463d483cdSSepherosa Ziehau 	csum = ~csum;
20563d483cdSSepherosa Ziehau 	do {
20663d483cdSSepherosa Ziehau 		if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
20763d483cdSSepherosa Ziehau 			return IXGBE_ERR_SWFW_SYNC;
20863d483cdSSepherosa Ziehau 		ixgbe_i2c_start(hw);
20963d483cdSSepherosa Ziehau 		/* Device Address and write indication */
21063d483cdSSepherosa Ziehau 		if (ixgbe_out_i2c_byte_ack(hw, addr))
21163d483cdSSepherosa Ziehau 			goto fail;
21263d483cdSSepherosa Ziehau 		/* Write bits 14:8 */
21363d483cdSSepherosa Ziehau 		if (ixgbe_out_i2c_byte_ack(hw, reg_high))
21463d483cdSSepherosa Ziehau 			goto fail;
21563d483cdSSepherosa Ziehau 		/* Write bits 7:0 */
21663d483cdSSepherosa Ziehau 		if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF))
21763d483cdSSepherosa Ziehau 			goto fail;
21863d483cdSSepherosa Ziehau 		/* Write data 15:8 */
21963d483cdSSepherosa Ziehau 		if (ixgbe_out_i2c_byte_ack(hw, val >> 8))
22063d483cdSSepherosa Ziehau 			goto fail;
22163d483cdSSepherosa Ziehau 		/* Write data 7:0 */
22263d483cdSSepherosa Ziehau 		if (ixgbe_out_i2c_byte_ack(hw, val & 0xFF))
22363d483cdSSepherosa Ziehau 			goto fail;
22463d483cdSSepherosa Ziehau 		/* Write csum */
22563d483cdSSepherosa Ziehau 		if (ixgbe_out_i2c_byte_ack(hw, csum))
22663d483cdSSepherosa Ziehau 			goto fail;
22763d483cdSSepherosa Ziehau 		ixgbe_i2c_stop(hw);
22863d483cdSSepherosa Ziehau 		if (lock)
22963d483cdSSepherosa Ziehau 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
23063d483cdSSepherosa Ziehau 		return 0;
23163d483cdSSepherosa Ziehau 
23263d483cdSSepherosa Ziehau fail:
23363d483cdSSepherosa Ziehau 		ixgbe_i2c_bus_clear(hw);
23463d483cdSSepherosa Ziehau 		if (lock)
23563d483cdSSepherosa Ziehau 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
23663d483cdSSepherosa Ziehau 		retry++;
23763d483cdSSepherosa Ziehau 		if (retry < max_retry)
23863d483cdSSepherosa Ziehau 			DEBUGOUT("I2C byte write combined error - Retrying.\n");
23963d483cdSSepherosa Ziehau 		else
24063d483cdSSepherosa Ziehau 			DEBUGOUT("I2C byte write combined error.\n");
24163d483cdSSepherosa Ziehau 	} while (retry < max_retry);
24263d483cdSSepherosa Ziehau 
24363d483cdSSepherosa Ziehau 	return IXGBE_ERR_I2C;
24463d483cdSSepherosa Ziehau }
24563d483cdSSepherosa Ziehau 
24663d483cdSSepherosa Ziehau /**
24779251f5eSSepherosa Ziehau  *  ixgbe_init_phy_ops_generic - Inits PHY function ptrs
24879251f5eSSepherosa Ziehau  *  @hw: pointer to the hardware structure
24979251f5eSSepherosa Ziehau  *
25079251f5eSSepherosa Ziehau  *  Initialize the function pointers.
25179251f5eSSepherosa Ziehau  **/
ixgbe_init_phy_ops_generic(struct ixgbe_hw * hw)25279251f5eSSepherosa Ziehau s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
25379251f5eSSepherosa Ziehau {
25479251f5eSSepherosa Ziehau 	struct ixgbe_phy_info *phy = &hw->phy;
25579251f5eSSepherosa Ziehau 
25679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_phy_ops_generic");
25779251f5eSSepherosa Ziehau 
25879251f5eSSepherosa Ziehau 	/* PHY */
25963d483cdSSepherosa Ziehau 	phy->ops.identify = ixgbe_identify_phy_generic;
26063d483cdSSepherosa Ziehau 	phy->ops.reset = ixgbe_reset_phy_generic;
26163d483cdSSepherosa Ziehau 	phy->ops.read_reg = ixgbe_read_phy_reg_generic;
26263d483cdSSepherosa Ziehau 	phy->ops.write_reg = ixgbe_write_phy_reg_generic;
26363d483cdSSepherosa Ziehau 	phy->ops.read_reg_mdi = ixgbe_read_phy_reg_mdi;
26463d483cdSSepherosa Ziehau 	phy->ops.write_reg_mdi = ixgbe_write_phy_reg_mdi;
26563d483cdSSepherosa Ziehau 	phy->ops.setup_link = ixgbe_setup_phy_link_generic;
26663d483cdSSepherosa Ziehau 	phy->ops.setup_link_speed = ixgbe_setup_phy_link_speed_generic;
26779251f5eSSepherosa Ziehau 	phy->ops.check_link = NULL;
26879251f5eSSepherosa Ziehau 	phy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_generic;
26963d483cdSSepherosa Ziehau 	phy->ops.read_i2c_byte = ixgbe_read_i2c_byte_generic;
27063d483cdSSepherosa Ziehau 	phy->ops.write_i2c_byte = ixgbe_write_i2c_byte_generic;
27163d483cdSSepherosa Ziehau 	phy->ops.read_i2c_sff8472 = ixgbe_read_i2c_sff8472_generic;
27263d483cdSSepherosa Ziehau 	phy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_generic;
27363d483cdSSepherosa Ziehau 	phy->ops.write_i2c_eeprom = ixgbe_write_i2c_eeprom_generic;
27463d483cdSSepherosa Ziehau 	phy->ops.i2c_bus_clear = ixgbe_i2c_bus_clear;
27563d483cdSSepherosa Ziehau 	phy->ops.identify_sfp = ixgbe_identify_module_generic;
27679251f5eSSepherosa Ziehau 	phy->sfp_type = ixgbe_sfp_type_unknown;
27763d483cdSSepherosa Ziehau 	phy->ops.read_i2c_byte_unlocked = ixgbe_read_i2c_byte_generic_unlocked;
27863d483cdSSepherosa Ziehau 	phy->ops.write_i2c_byte_unlocked =
27963d483cdSSepherosa Ziehau 				ixgbe_write_i2c_byte_generic_unlocked;
28063d483cdSSepherosa Ziehau 	phy->ops.check_overtemp = ixgbe_tn_check_overtemp;
28179251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
28279251f5eSSepherosa Ziehau }
28379251f5eSSepherosa Ziehau 
28479251f5eSSepherosa Ziehau /**
2856150453fSSepherosa Ziehau  * ixgbe_probe_phy - Probe a single address for a PHY
2866150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
2876150453fSSepherosa Ziehau  * @phy_addr: PHY address to probe
2886150453fSSepherosa Ziehau  *
2896150453fSSepherosa Ziehau  * Returns TRUE if PHY found
2906150453fSSepherosa Ziehau  */
ixgbe_probe_phy(struct ixgbe_hw * hw,u16 phy_addr)2916150453fSSepherosa Ziehau static bool ixgbe_probe_phy(struct ixgbe_hw *hw, u16 phy_addr)
2926150453fSSepherosa Ziehau {
2936150453fSSepherosa Ziehau 	u16 ext_ability = 0;
2946150453fSSepherosa Ziehau 
2956150453fSSepherosa Ziehau 	if (!ixgbe_validate_phy_addr(hw, phy_addr)) {
2966150453fSSepherosa Ziehau 		DEBUGOUT1("Unable to validate PHY address 0x%04X\n",
2976150453fSSepherosa Ziehau 			phy_addr);
2986150453fSSepherosa Ziehau 		return FALSE;
2996150453fSSepherosa Ziehau 	}
3006150453fSSepherosa Ziehau 
3016150453fSSepherosa Ziehau 	if (ixgbe_get_phy_id(hw))
3026150453fSSepherosa Ziehau 		return FALSE;
3036150453fSSepherosa Ziehau 
3046150453fSSepherosa Ziehau 	hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id);
3056150453fSSepherosa Ziehau 
3066150453fSSepherosa Ziehau 	if (hw->phy.type == ixgbe_phy_unknown) {
3076150453fSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
3086150453fSSepherosa Ziehau 				     IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
3096150453fSSepherosa Ziehau 		if (ext_ability &
3106150453fSSepherosa Ziehau 		    (IXGBE_MDIO_PHY_10GBASET_ABILITY |
3116150453fSSepherosa Ziehau 		     IXGBE_MDIO_PHY_1000BASET_ABILITY))
3126150453fSSepherosa Ziehau 			hw->phy.type = ixgbe_phy_cu_unknown;
3136150453fSSepherosa Ziehau 		else
3146150453fSSepherosa Ziehau 			hw->phy.type = ixgbe_phy_generic;
3156150453fSSepherosa Ziehau 	}
3166150453fSSepherosa Ziehau 
3176150453fSSepherosa Ziehau 	return TRUE;
3186150453fSSepherosa Ziehau }
3196150453fSSepherosa Ziehau 
3206150453fSSepherosa Ziehau /**
32179251f5eSSepherosa Ziehau  *  ixgbe_identify_phy_generic - Get physical layer module
32279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
32379251f5eSSepherosa Ziehau  *
32479251f5eSSepherosa Ziehau  *  Determines the physical layer module found on the current adapter.
32579251f5eSSepherosa Ziehau  **/
ixgbe_identify_phy_generic(struct ixgbe_hw * hw)32679251f5eSSepherosa Ziehau s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
32779251f5eSSepherosa Ziehau {
32879251f5eSSepherosa Ziehau 	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
3296150453fSSepherosa Ziehau 	u16 phy_addr;
33079251f5eSSepherosa Ziehau 
33179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_identify_phy_generic");
33279251f5eSSepherosa Ziehau 
33363d483cdSSepherosa Ziehau 	if (!hw->phy.phy_semaphore_mask) {
33463d483cdSSepherosa Ziehau 		if (hw->bus.lan_id)
33563d483cdSSepherosa Ziehau 			hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
33663d483cdSSepherosa Ziehau 		else
33763d483cdSSepherosa Ziehau 			hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
33863d483cdSSepherosa Ziehau 	}
33963d483cdSSepherosa Ziehau 
3406150453fSSepherosa Ziehau 	if (hw->phy.type != ixgbe_phy_unknown)
3416150453fSSepherosa Ziehau 		return IXGBE_SUCCESS;
34279251f5eSSepherosa Ziehau 
3436150453fSSepherosa Ziehau 	if (hw->phy.nw_mng_if_sel) {
3446150453fSSepherosa Ziehau 		phy_addr = (hw->phy.nw_mng_if_sel &
3456150453fSSepherosa Ziehau 			    IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >>
3466150453fSSepherosa Ziehau 			   IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT;
3476150453fSSepherosa Ziehau 		if (ixgbe_probe_phy(hw, phy_addr))
3486150453fSSepherosa Ziehau 			return IXGBE_SUCCESS;
34979251f5eSSepherosa Ziehau 		else
3506150453fSSepherosa Ziehau 			return IXGBE_ERR_PHY_ADDR_INVALID;
35179251f5eSSepherosa Ziehau 	}
35279251f5eSSepherosa Ziehau 
3536150453fSSepherosa Ziehau 	for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
3546150453fSSepherosa Ziehau 		if (ixgbe_probe_phy(hw, phy_addr)) {
35579251f5eSSepherosa Ziehau 			status = IXGBE_SUCCESS;
35679251f5eSSepherosa Ziehau 			break;
35779251f5eSSepherosa Ziehau 		}
35879251f5eSSepherosa Ziehau 	}
35963d483cdSSepherosa Ziehau 
36063d483cdSSepherosa Ziehau 	/* Certain media types do not have a phy so an address will not
36163d483cdSSepherosa Ziehau 	 * be found and the code will take this path.  Caller has to
36263d483cdSSepherosa Ziehau 	 * decide if it is an error or not.
36363d483cdSSepherosa Ziehau 	 */
3646150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
36579251f5eSSepherosa Ziehau 		hw->phy.addr = 0;
36679251f5eSSepherosa Ziehau 
36779251f5eSSepherosa Ziehau 	return status;
36879251f5eSSepherosa Ziehau }
36979251f5eSSepherosa Ziehau 
37079251f5eSSepherosa Ziehau /**
37163d483cdSSepherosa Ziehau  * ixgbe_check_reset_blocked - check status of MNG FW veto bit
37263d483cdSSepherosa Ziehau  * @hw: pointer to the hardware structure
37363d483cdSSepherosa Ziehau  *
37463d483cdSSepherosa Ziehau  * This function checks the MMNGC.MNG_VETO bit to see if there are
37563d483cdSSepherosa Ziehau  * any constraints on link from manageability.  For MAC's that don't
37663d483cdSSepherosa Ziehau  * have this bit just return faluse since the link can not be blocked
37763d483cdSSepherosa Ziehau  * via this method.
37863d483cdSSepherosa Ziehau  **/
ixgbe_check_reset_blocked(struct ixgbe_hw * hw)37963d483cdSSepherosa Ziehau s32 ixgbe_check_reset_blocked(struct ixgbe_hw *hw)
38063d483cdSSepherosa Ziehau {
38163d483cdSSepherosa Ziehau 	u32 mmngc;
38263d483cdSSepherosa Ziehau 
38363d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_reset_blocked");
38463d483cdSSepherosa Ziehau 
38563d483cdSSepherosa Ziehau 	/* If we don't have this bit, it can't be blocking */
38663d483cdSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_82598EB)
38763d483cdSSepherosa Ziehau 		return FALSE;
38863d483cdSSepherosa Ziehau 
38963d483cdSSepherosa Ziehau 	mmngc = IXGBE_READ_REG(hw, IXGBE_MMNGC);
39063d483cdSSepherosa Ziehau 	if (mmngc & IXGBE_MMNGC_MNG_VETO) {
39163d483cdSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_SOFTWARE,
39263d483cdSSepherosa Ziehau 			      "MNG_VETO bit detected.\n");
39363d483cdSSepherosa Ziehau 		return TRUE;
39463d483cdSSepherosa Ziehau 	}
39563d483cdSSepherosa Ziehau 
39663d483cdSSepherosa Ziehau 	return FALSE;
39763d483cdSSepherosa Ziehau }
39863d483cdSSepherosa Ziehau 
39963d483cdSSepherosa Ziehau /**
40079251f5eSSepherosa Ziehau  *  ixgbe_validate_phy_addr - Determines phy address is valid
40179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
402*dd5ce676SSepherosa Ziehau  *  @phy_addr: PHY address
40379251f5eSSepherosa Ziehau  *
40479251f5eSSepherosa Ziehau  **/
ixgbe_validate_phy_addr(struct ixgbe_hw * hw,u32 phy_addr)40579251f5eSSepherosa Ziehau bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr)
40679251f5eSSepherosa Ziehau {
40779251f5eSSepherosa Ziehau 	u16 phy_id = 0;
40879251f5eSSepherosa Ziehau 	bool valid = FALSE;
40979251f5eSSepherosa Ziehau 
41079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_validate_phy_addr");
41179251f5eSSepherosa Ziehau 
41279251f5eSSepherosa Ziehau 	hw->phy.addr = phy_addr;
41379251f5eSSepherosa Ziehau 	hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
41479251f5eSSepherosa Ziehau 			     IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id);
41579251f5eSSepherosa Ziehau 
41679251f5eSSepherosa Ziehau 	if (phy_id != 0xFFFF && phy_id != 0x0)
41779251f5eSSepherosa Ziehau 		valid = TRUE;
41879251f5eSSepherosa Ziehau 
4196150453fSSepherosa Ziehau 	DEBUGOUT1("PHY ID HIGH is 0x%04X\n", phy_id);
4206150453fSSepherosa Ziehau 
42179251f5eSSepherosa Ziehau 	return valid;
42279251f5eSSepherosa Ziehau }
42379251f5eSSepherosa Ziehau 
42479251f5eSSepherosa Ziehau /**
42579251f5eSSepherosa Ziehau  *  ixgbe_get_phy_id - Get the phy type
42679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
42779251f5eSSepherosa Ziehau  *
42879251f5eSSepherosa Ziehau  **/
ixgbe_get_phy_id(struct ixgbe_hw * hw)42979251f5eSSepherosa Ziehau s32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
43079251f5eSSepherosa Ziehau {
43179251f5eSSepherosa Ziehau 	u32 status;
43279251f5eSSepherosa Ziehau 	u16 phy_id_high = 0;
43379251f5eSSepherosa Ziehau 	u16 phy_id_low = 0;
43479251f5eSSepherosa Ziehau 
43579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_phy_id");
43679251f5eSSepherosa Ziehau 
43779251f5eSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
43879251f5eSSepherosa Ziehau 				      IXGBE_MDIO_PMA_PMD_DEV_TYPE,
43979251f5eSSepherosa Ziehau 				      &phy_id_high);
44079251f5eSSepherosa Ziehau 
44179251f5eSSepherosa Ziehau 	if (status == IXGBE_SUCCESS) {
44279251f5eSSepherosa Ziehau 		hw->phy.id = (u32)(phy_id_high << 16);
44379251f5eSSepherosa Ziehau 		status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW,
44479251f5eSSepherosa Ziehau 					      IXGBE_MDIO_PMA_PMD_DEV_TYPE,
44579251f5eSSepherosa Ziehau 					      &phy_id_low);
44679251f5eSSepherosa Ziehau 		hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
44779251f5eSSepherosa Ziehau 		hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
44879251f5eSSepherosa Ziehau 	}
4496150453fSSepherosa Ziehau 	DEBUGOUT2("PHY_ID_HIGH 0x%04X, PHY_ID_LOW 0x%04X\n",
4506150453fSSepherosa Ziehau 		  phy_id_high, phy_id_low);
4516150453fSSepherosa Ziehau 
45279251f5eSSepherosa Ziehau 	return status;
45379251f5eSSepherosa Ziehau }
45479251f5eSSepherosa Ziehau 
45579251f5eSSepherosa Ziehau /**
45679251f5eSSepherosa Ziehau  *  ixgbe_get_phy_type_from_id - Get the phy type
4576150453fSSepherosa Ziehau  *  @phy_id: PHY ID information
45879251f5eSSepherosa Ziehau  *
45979251f5eSSepherosa Ziehau  **/
ixgbe_get_phy_type_from_id(u32 phy_id)46079251f5eSSepherosa Ziehau enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
46179251f5eSSepherosa Ziehau {
46279251f5eSSepherosa Ziehau 	enum ixgbe_phy_type phy_type;
46379251f5eSSepherosa Ziehau 
46479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_phy_type_from_id");
46579251f5eSSepherosa Ziehau 
46679251f5eSSepherosa Ziehau 	switch (phy_id) {
46779251f5eSSepherosa Ziehau 	case TN1010_PHY_ID:
46879251f5eSSepherosa Ziehau 		phy_type = ixgbe_phy_tn;
46979251f5eSSepherosa Ziehau 		break;
4706150453fSSepherosa Ziehau 	case X550_PHY_ID2:
4716150453fSSepherosa Ziehau 	case X550_PHY_ID3:
47279251f5eSSepherosa Ziehau 	case X540_PHY_ID:
47379251f5eSSepherosa Ziehau 		phy_type = ixgbe_phy_aq;
47479251f5eSSepherosa Ziehau 		break;
47579251f5eSSepherosa Ziehau 	case QT2022_PHY_ID:
47679251f5eSSepherosa Ziehau 		phy_type = ixgbe_phy_qt;
47779251f5eSSepherosa Ziehau 		break;
47879251f5eSSepherosa Ziehau 	case ATH_PHY_ID:
47979251f5eSSepherosa Ziehau 		phy_type = ixgbe_phy_nl;
48079251f5eSSepherosa Ziehau 		break;
48163d483cdSSepherosa Ziehau 	case X557_PHY_ID:
4826150453fSSepherosa Ziehau 	case X557_PHY_ID2:
48363d483cdSSepherosa Ziehau 		phy_type = ixgbe_phy_x550em_ext_t;
48463d483cdSSepherosa Ziehau 		break;
4856150453fSSepherosa Ziehau 	case IXGBE_M88E1500_E_PHY_ID:
4866150453fSSepherosa Ziehau 	case IXGBE_M88E1543_E_PHY_ID:
4876150453fSSepherosa Ziehau 		phy_type = ixgbe_phy_ext_1g_t;
4886150453fSSepherosa Ziehau 		break;
48979251f5eSSepherosa Ziehau 	default:
49079251f5eSSepherosa Ziehau 		phy_type = ixgbe_phy_unknown;
49179251f5eSSepherosa Ziehau 		break;
49279251f5eSSepherosa Ziehau 	}
49379251f5eSSepherosa Ziehau 	return phy_type;
49479251f5eSSepherosa Ziehau }
49579251f5eSSepherosa Ziehau 
49679251f5eSSepherosa Ziehau /**
49779251f5eSSepherosa Ziehau  *  ixgbe_reset_phy_generic - Performs a PHY reset
49879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
49979251f5eSSepherosa Ziehau  **/
ixgbe_reset_phy_generic(struct ixgbe_hw * hw)50079251f5eSSepherosa Ziehau s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
50179251f5eSSepherosa Ziehau {
50279251f5eSSepherosa Ziehau 	u32 i;
50379251f5eSSepherosa Ziehau 	u16 ctrl = 0;
50479251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
50579251f5eSSepherosa Ziehau 
50679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_reset_phy_generic");
50779251f5eSSepherosa Ziehau 
50879251f5eSSepherosa Ziehau 	if (hw->phy.type == ixgbe_phy_unknown)
50979251f5eSSepherosa Ziehau 		status = ixgbe_identify_phy_generic(hw);
51079251f5eSSepherosa Ziehau 
51179251f5eSSepherosa Ziehau 	if (status != IXGBE_SUCCESS || hw->phy.type == ixgbe_phy_none)
51279251f5eSSepherosa Ziehau 		goto out;
51379251f5eSSepherosa Ziehau 
51479251f5eSSepherosa Ziehau 	/* Don't reset PHY if it's shut down due to overtemp. */
51579251f5eSSepherosa Ziehau 	if (!hw->phy.reset_if_overtemp &&
51679251f5eSSepherosa Ziehau 	    (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw)))
51779251f5eSSepherosa Ziehau 		goto out;
51879251f5eSSepherosa Ziehau 
51963d483cdSSepherosa Ziehau 	/* Blocked by MNG FW so bail */
52063d483cdSSepherosa Ziehau 	if (ixgbe_check_reset_blocked(hw))
52163d483cdSSepherosa Ziehau 		goto out;
52263d483cdSSepherosa Ziehau 
52379251f5eSSepherosa Ziehau 	/*
52479251f5eSSepherosa Ziehau 	 * Perform soft PHY reset to the PHY_XS.
52579251f5eSSepherosa Ziehau 	 * This will cause a soft reset to the PHY
52679251f5eSSepherosa Ziehau 	 */
52779251f5eSSepherosa Ziehau 	hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
52879251f5eSSepherosa Ziehau 			      IXGBE_MDIO_PHY_XS_DEV_TYPE,
52979251f5eSSepherosa Ziehau 			      IXGBE_MDIO_PHY_XS_RESET);
53079251f5eSSepherosa Ziehau 
53179251f5eSSepherosa Ziehau 	/*
53279251f5eSSepherosa Ziehau 	 * Poll for reset bit to self-clear indicating reset is complete.
53379251f5eSSepherosa Ziehau 	 * Some PHYs could take up to 3 seconds to complete and need about
53479251f5eSSepherosa Ziehau 	 * 1.7 usec delay after the reset is complete.
53579251f5eSSepherosa Ziehau 	 */
53679251f5eSSepherosa Ziehau 	for (i = 0; i < 30; i++) {
53779251f5eSSepherosa Ziehau 		msec_delay(100);
5386150453fSSepherosa Ziehau 		if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
5396150453fSSepherosa Ziehau 			status = hw->phy.ops.read_reg(hw,
5406150453fSSepherosa Ziehau 						  IXGBE_MDIO_TX_VENDOR_ALARMS_3,
5416150453fSSepherosa Ziehau 						  IXGBE_MDIO_PMA_PMD_DEV_TYPE,
5426150453fSSepherosa Ziehau 						  &ctrl);
5436150453fSSepherosa Ziehau 			if (status != IXGBE_SUCCESS)
5446150453fSSepherosa Ziehau 				return status;
5456150453fSSepherosa Ziehau 
5466150453fSSepherosa Ziehau 			if (ctrl & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
5476150453fSSepherosa Ziehau 				usec_delay(2);
5486150453fSSepherosa Ziehau 				break;
5496150453fSSepherosa Ziehau 			}
5506150453fSSepherosa Ziehau 		} else {
5516150453fSSepherosa Ziehau 			status = hw->phy.ops.read_reg(hw,
5526150453fSSepherosa Ziehau 						     IXGBE_MDIO_PHY_XS_CONTROL,
5536150453fSSepherosa Ziehau 						     IXGBE_MDIO_PHY_XS_DEV_TYPE,
5546150453fSSepherosa Ziehau 						     &ctrl);
5556150453fSSepherosa Ziehau 			if (status != IXGBE_SUCCESS)
5566150453fSSepherosa Ziehau 				return status;
5576150453fSSepherosa Ziehau 
55879251f5eSSepherosa Ziehau 			if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) {
55979251f5eSSepherosa Ziehau 				usec_delay(2);
56079251f5eSSepherosa Ziehau 				break;
56179251f5eSSepherosa Ziehau 			}
56279251f5eSSepherosa Ziehau 		}
5636150453fSSepherosa Ziehau 	}
56479251f5eSSepherosa Ziehau 
56579251f5eSSepherosa Ziehau 	if (ctrl & IXGBE_MDIO_PHY_XS_RESET) {
56679251f5eSSepherosa Ziehau 		status = IXGBE_ERR_RESET_FAILED;
56779251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_POLLING,
56879251f5eSSepherosa Ziehau 			     "PHY reset polling failed to complete.\n");
56979251f5eSSepherosa Ziehau 	}
57079251f5eSSepherosa Ziehau 
57179251f5eSSepherosa Ziehau out:
57279251f5eSSepherosa Ziehau 	return status;
57379251f5eSSepherosa Ziehau }
57479251f5eSSepherosa Ziehau 
57579251f5eSSepherosa Ziehau /**
57679251f5eSSepherosa Ziehau  *  ixgbe_read_phy_mdi - Reads a value from a specified PHY register without
57779251f5eSSepherosa Ziehau  *  the SWFW lock
57879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
57979251f5eSSepherosa Ziehau  *  @reg_addr: 32 bit address of PHY register to read
580*dd5ce676SSepherosa Ziehau  *  @device_type: 5 bit device type
58179251f5eSSepherosa Ziehau  *  @phy_data: Pointer to read data from PHY register
58279251f5eSSepherosa Ziehau  **/
ixgbe_read_phy_reg_mdi(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 * phy_data)58379251f5eSSepherosa Ziehau s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
58479251f5eSSepherosa Ziehau 			   u16 *phy_data)
58579251f5eSSepherosa Ziehau {
58679251f5eSSepherosa Ziehau 	u32 i, data, command;
58779251f5eSSepherosa Ziehau 
58879251f5eSSepherosa Ziehau 	/* Setup and write the address cycle command */
58979251f5eSSepherosa Ziehau 	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
59079251f5eSSepherosa Ziehau 		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
59179251f5eSSepherosa Ziehau 		   (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
59279251f5eSSepherosa Ziehau 		   (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
59379251f5eSSepherosa Ziehau 
59479251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
59579251f5eSSepherosa Ziehau 
59679251f5eSSepherosa Ziehau 	/*
59779251f5eSSepherosa Ziehau 	 * Check every 10 usec to see if the address cycle completed.
59879251f5eSSepherosa Ziehau 	 * The MDI Command bit will clear when the operation is
59979251f5eSSepherosa Ziehau 	 * complete
60079251f5eSSepherosa Ziehau 	 */
60179251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
60279251f5eSSepherosa Ziehau 		usec_delay(10);
60379251f5eSSepherosa Ziehau 
60479251f5eSSepherosa Ziehau 		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
60579251f5eSSepherosa Ziehau 		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
60679251f5eSSepherosa Ziehau 			break;
60779251f5eSSepherosa Ziehau 	}
60879251f5eSSepherosa Ziehau 
60979251f5eSSepherosa Ziehau 
61079251f5eSSepherosa Ziehau 	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
61179251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY address command did not complete.\n");
6126150453fSSepherosa Ziehau 		DEBUGOUT("PHY address command did not complete, returning IXGBE_ERR_PHY\n");
61379251f5eSSepherosa Ziehau 		return IXGBE_ERR_PHY;
61479251f5eSSepherosa Ziehau 	}
61579251f5eSSepherosa Ziehau 
61679251f5eSSepherosa Ziehau 	/*
61779251f5eSSepherosa Ziehau 	 * Address cycle complete, setup and write the read
61879251f5eSSepherosa Ziehau 	 * command
61979251f5eSSepherosa Ziehau 	 */
62079251f5eSSepherosa Ziehau 	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
62179251f5eSSepherosa Ziehau 		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
62279251f5eSSepherosa Ziehau 		   (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
62379251f5eSSepherosa Ziehau 		   (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
62479251f5eSSepherosa Ziehau 
62579251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
62679251f5eSSepherosa Ziehau 
62779251f5eSSepherosa Ziehau 	/*
62879251f5eSSepherosa Ziehau 	 * Check every 10 usec to see if the address cycle
62979251f5eSSepherosa Ziehau 	 * completed. The MDI Command bit will clear when the
63079251f5eSSepherosa Ziehau 	 * operation is complete
63179251f5eSSepherosa Ziehau 	 */
63279251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
63379251f5eSSepherosa Ziehau 		usec_delay(10);
63479251f5eSSepherosa Ziehau 
63579251f5eSSepherosa Ziehau 		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
63679251f5eSSepherosa Ziehau 		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
63779251f5eSSepherosa Ziehau 			break;
63879251f5eSSepherosa Ziehau 	}
63979251f5eSSepherosa Ziehau 
64079251f5eSSepherosa Ziehau 	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
64179251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY read command didn't complete\n");
6426150453fSSepherosa Ziehau 		DEBUGOUT("PHY read command didn't complete, returning IXGBE_ERR_PHY\n");
64379251f5eSSepherosa Ziehau 		return IXGBE_ERR_PHY;
64479251f5eSSepherosa Ziehau 	}
64579251f5eSSepherosa Ziehau 
64679251f5eSSepherosa Ziehau 	/*
64779251f5eSSepherosa Ziehau 	 * Read operation is complete.  Get the data
64879251f5eSSepherosa Ziehau 	 * from MSRWD
64979251f5eSSepherosa Ziehau 	 */
65079251f5eSSepherosa Ziehau 	data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
65179251f5eSSepherosa Ziehau 	data >>= IXGBE_MSRWD_READ_DATA_SHIFT;
65279251f5eSSepherosa Ziehau 	*phy_data = (u16)(data);
65379251f5eSSepherosa Ziehau 
65479251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
65579251f5eSSepherosa Ziehau }
65679251f5eSSepherosa Ziehau 
65779251f5eSSepherosa Ziehau /**
65879251f5eSSepherosa Ziehau  *  ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register
65979251f5eSSepherosa Ziehau  *  using the SWFW lock - this function is needed in most cases
66079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
66179251f5eSSepherosa Ziehau  *  @reg_addr: 32 bit address of PHY register to read
662*dd5ce676SSepherosa Ziehau  *  @device_type: 5 bit device type
66379251f5eSSepherosa Ziehau  *  @phy_data: Pointer to read data from PHY register
66479251f5eSSepherosa Ziehau  **/
ixgbe_read_phy_reg_generic(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 * phy_data)66579251f5eSSepherosa Ziehau s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
66679251f5eSSepherosa Ziehau 			       u32 device_type, u16 *phy_data)
66779251f5eSSepherosa Ziehau {
66879251f5eSSepherosa Ziehau 	s32 status;
66963d483cdSSepherosa Ziehau 	u32 gssr = hw->phy.phy_semaphore_mask;
67079251f5eSSepherosa Ziehau 
67179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_phy_reg_generic");
67279251f5eSSepherosa Ziehau 
6736150453fSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, gssr))
6746150453fSSepherosa Ziehau 		return IXGBE_ERR_SWFW_SYNC;
6756150453fSSepherosa Ziehau 
6766150453fSSepherosa Ziehau 	status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data);
6776150453fSSepherosa Ziehau 
67879251f5eSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, gssr);
67979251f5eSSepherosa Ziehau 
68079251f5eSSepherosa Ziehau 	return status;
68179251f5eSSepherosa Ziehau }
68279251f5eSSepherosa Ziehau 
68379251f5eSSepherosa Ziehau /**
68479251f5eSSepherosa Ziehau  *  ixgbe_write_phy_reg_mdi - Writes a value to specified PHY register
68579251f5eSSepherosa Ziehau  *  without SWFW lock
68679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
68779251f5eSSepherosa Ziehau  *  @reg_addr: 32 bit PHY register to write
68879251f5eSSepherosa Ziehau  *  @device_type: 5 bit device type
68979251f5eSSepherosa Ziehau  *  @phy_data: Data to write to the PHY register
69079251f5eSSepherosa Ziehau  **/
ixgbe_write_phy_reg_mdi(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 phy_data)69179251f5eSSepherosa Ziehau s32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr,
69279251f5eSSepherosa Ziehau 				u32 device_type, u16 phy_data)
69379251f5eSSepherosa Ziehau {
69479251f5eSSepherosa Ziehau 	u32 i, command;
69579251f5eSSepherosa Ziehau 
69679251f5eSSepherosa Ziehau 	/* Put the data in the MDI single read and write data register*/
69779251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data);
69879251f5eSSepherosa Ziehau 
69979251f5eSSepherosa Ziehau 	/* Setup and write the address cycle command */
70079251f5eSSepherosa Ziehau 	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
70179251f5eSSepherosa Ziehau 		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
70279251f5eSSepherosa Ziehau 		   (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
70379251f5eSSepherosa Ziehau 		   (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
70479251f5eSSepherosa Ziehau 
70579251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
70679251f5eSSepherosa Ziehau 
70779251f5eSSepherosa Ziehau 	/*
70879251f5eSSepherosa Ziehau 	 * Check every 10 usec to see if the address cycle completed.
70979251f5eSSepherosa Ziehau 	 * The MDI Command bit will clear when the operation is
71079251f5eSSepherosa Ziehau 	 * complete
71179251f5eSSepherosa Ziehau 	 */
71279251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
71379251f5eSSepherosa Ziehau 		usec_delay(10);
71479251f5eSSepherosa Ziehau 
71579251f5eSSepherosa Ziehau 		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
71679251f5eSSepherosa Ziehau 		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
71779251f5eSSepherosa Ziehau 			break;
71879251f5eSSepherosa Ziehau 	}
71979251f5eSSepherosa Ziehau 
72079251f5eSSepherosa Ziehau 	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
72179251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY address cmd didn't complete\n");
72279251f5eSSepherosa Ziehau 		return IXGBE_ERR_PHY;
72379251f5eSSepherosa Ziehau 	}
72479251f5eSSepherosa Ziehau 
72579251f5eSSepherosa Ziehau 	/*
72679251f5eSSepherosa Ziehau 	 * Address cycle complete, setup and write the write
72779251f5eSSepherosa Ziehau 	 * command
72879251f5eSSepherosa Ziehau 	 */
72979251f5eSSepherosa Ziehau 	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
73079251f5eSSepherosa Ziehau 		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
73179251f5eSSepherosa Ziehau 		   (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
73279251f5eSSepherosa Ziehau 		   (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
73379251f5eSSepherosa Ziehau 
73479251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
73579251f5eSSepherosa Ziehau 
73679251f5eSSepherosa Ziehau 	/*
73779251f5eSSepherosa Ziehau 	 * Check every 10 usec to see if the address cycle
73879251f5eSSepherosa Ziehau 	 * completed. The MDI Command bit will clear when the
73979251f5eSSepherosa Ziehau 	 * operation is complete
74079251f5eSSepherosa Ziehau 	 */
74179251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
74279251f5eSSepherosa Ziehau 		usec_delay(10);
74379251f5eSSepherosa Ziehau 
74479251f5eSSepherosa Ziehau 		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
74579251f5eSSepherosa Ziehau 		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
74679251f5eSSepherosa Ziehau 			break;
74779251f5eSSepherosa Ziehau 	}
74879251f5eSSepherosa Ziehau 
74979251f5eSSepherosa Ziehau 	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
75079251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY write cmd didn't complete\n");
75179251f5eSSepherosa Ziehau 		return IXGBE_ERR_PHY;
75279251f5eSSepherosa Ziehau 	}
75379251f5eSSepherosa Ziehau 
75479251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
75579251f5eSSepherosa Ziehau }
75679251f5eSSepherosa Ziehau 
75779251f5eSSepherosa Ziehau /**
75879251f5eSSepherosa Ziehau  *  ixgbe_write_phy_reg_generic - Writes a value to specified PHY register
75979251f5eSSepherosa Ziehau  *  using SWFW lock- this function is needed in most cases
76079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
76179251f5eSSepherosa Ziehau  *  @reg_addr: 32 bit PHY register to write
76279251f5eSSepherosa Ziehau  *  @device_type: 5 bit device type
76379251f5eSSepherosa Ziehau  *  @phy_data: Data to write to the PHY register
76479251f5eSSepherosa Ziehau  **/
ixgbe_write_phy_reg_generic(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 phy_data)76579251f5eSSepherosa Ziehau s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
76679251f5eSSepherosa Ziehau 				u32 device_type, u16 phy_data)
76779251f5eSSepherosa Ziehau {
76879251f5eSSepherosa Ziehau 	s32 status;
76963d483cdSSepherosa Ziehau 	u32 gssr = hw->phy.phy_semaphore_mask;
77079251f5eSSepherosa Ziehau 
77179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_phy_reg_generic");
77279251f5eSSepherosa Ziehau 
77379251f5eSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == IXGBE_SUCCESS) {
7746150453fSSepherosa Ziehau 		status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type,
77579251f5eSSepherosa Ziehau 						 phy_data);
77679251f5eSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, gssr);
77779251f5eSSepherosa Ziehau 	} else {
77879251f5eSSepherosa Ziehau 		status = IXGBE_ERR_SWFW_SYNC;
77979251f5eSSepherosa Ziehau 	}
78079251f5eSSepherosa Ziehau 
78179251f5eSSepherosa Ziehau 	return status;
78279251f5eSSepherosa Ziehau }
78379251f5eSSepherosa Ziehau 
78479251f5eSSepherosa Ziehau /**
78563d483cdSSepherosa Ziehau  *  ixgbe_setup_phy_link_generic - Set and restart auto-neg
78679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
78779251f5eSSepherosa Ziehau  *
78863d483cdSSepherosa Ziehau  *  Restart auto-negotiation and PHY and waits for completion.
78979251f5eSSepherosa Ziehau  **/
ixgbe_setup_phy_link_generic(struct ixgbe_hw * hw)79079251f5eSSepherosa Ziehau s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
79179251f5eSSepherosa Ziehau {
79279251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
79379251f5eSSepherosa Ziehau 	u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
79479251f5eSSepherosa Ziehau 	bool autoneg = FALSE;
79579251f5eSSepherosa Ziehau 	ixgbe_link_speed speed;
79679251f5eSSepherosa Ziehau 
79779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_phy_link_generic");
79879251f5eSSepherosa Ziehau 
79979251f5eSSepherosa Ziehau 	ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
80079251f5eSSepherosa Ziehau 
80179251f5eSSepherosa Ziehau 	/* Set or unset auto-negotiation 10G advertisement */
80279251f5eSSepherosa Ziehau 	hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
80379251f5eSSepherosa Ziehau 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
80479251f5eSSepherosa Ziehau 			     &autoneg_reg);
80579251f5eSSepherosa Ziehau 
80679251f5eSSepherosa Ziehau 	autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE;
8076150453fSSepherosa Ziehau 	if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) &&
8086150453fSSepherosa Ziehau 	    (speed & IXGBE_LINK_SPEED_10GB_FULL))
80979251f5eSSepherosa Ziehau 		autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE;
81079251f5eSSepherosa Ziehau 
81179251f5eSSepherosa Ziehau 	hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
81279251f5eSSepherosa Ziehau 			      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
81379251f5eSSepherosa Ziehau 			      autoneg_reg);
8146150453fSSepherosa Ziehau 
8156150453fSSepherosa Ziehau 	hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
8166150453fSSepherosa Ziehau 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
8176150453fSSepherosa Ziehau 			     &autoneg_reg);
81879251f5eSSepherosa Ziehau 
81963d483cdSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_X550) {
8206150453fSSepherosa Ziehau 		/* Set or unset auto-negotiation 5G advertisement */
82163d483cdSSepherosa Ziehau 		autoneg_reg &= ~IXGBE_MII_5GBASE_T_ADVERTISE;
8226150453fSSepherosa Ziehau 		if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL) &&
8236150453fSSepherosa Ziehau 		    (speed & IXGBE_LINK_SPEED_5GB_FULL))
82463d483cdSSepherosa Ziehau 			autoneg_reg |= IXGBE_MII_5GBASE_T_ADVERTISE;
82563d483cdSSepherosa Ziehau 
8266150453fSSepherosa Ziehau 		/* Set or unset auto-negotiation 2.5G advertisement */
82763d483cdSSepherosa Ziehau 		autoneg_reg &= ~IXGBE_MII_2_5GBASE_T_ADVERTISE;
8286150453fSSepherosa Ziehau 		if ((hw->phy.autoneg_advertised &
8296150453fSSepherosa Ziehau 		     IXGBE_LINK_SPEED_2_5GB_FULL) &&
8306150453fSSepherosa Ziehau 		    (speed & IXGBE_LINK_SPEED_2_5GB_FULL))
83163d483cdSSepherosa Ziehau 			autoneg_reg |= IXGBE_MII_2_5GBASE_T_ADVERTISE;
83263d483cdSSepherosa Ziehau 	}
83363d483cdSSepherosa Ziehau 
83479251f5eSSepherosa Ziehau 	/* Set or unset auto-negotiation 1G advertisement */
83579251f5eSSepherosa Ziehau 	autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE;
8366150453fSSepherosa Ziehau 	if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) &&
8376150453fSSepherosa Ziehau 	    (speed & IXGBE_LINK_SPEED_1GB_FULL))
83879251f5eSSepherosa Ziehau 		autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE;
83979251f5eSSepherosa Ziehau 
8406150453fSSepherosa Ziehau 	hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
84179251f5eSSepherosa Ziehau 			      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
84279251f5eSSepherosa Ziehau 			      autoneg_reg);
84379251f5eSSepherosa Ziehau 
84479251f5eSSepherosa Ziehau 	/* Set or unset auto-negotiation 100M advertisement */
84579251f5eSSepherosa Ziehau 	hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
84679251f5eSSepherosa Ziehau 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
84779251f5eSSepherosa Ziehau 			     &autoneg_reg);
84879251f5eSSepherosa Ziehau 
84979251f5eSSepherosa Ziehau 	autoneg_reg &= ~(IXGBE_MII_100BASE_T_ADVERTISE |
85079251f5eSSepherosa Ziehau 			 IXGBE_MII_100BASE_T_ADVERTISE_HALF);
8516150453fSSepherosa Ziehau 	if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) &&
8526150453fSSepherosa Ziehau 	    (speed & IXGBE_LINK_SPEED_100_FULL))
85379251f5eSSepherosa Ziehau 		autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE;
85479251f5eSSepherosa Ziehau 
85579251f5eSSepherosa Ziehau 	hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
85679251f5eSSepherosa Ziehau 			      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
85779251f5eSSepherosa Ziehau 			      autoneg_reg);
85879251f5eSSepherosa Ziehau 
85963d483cdSSepherosa Ziehau 	/* Blocked by MNG FW so don't reset PHY */
86063d483cdSSepherosa Ziehau 	if (ixgbe_check_reset_blocked(hw))
86163d483cdSSepherosa Ziehau 		return status;
86263d483cdSSepherosa Ziehau 
86363d483cdSSepherosa Ziehau 	/* Restart PHY auto-negotiation. */
86479251f5eSSepherosa Ziehau 	hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
86579251f5eSSepherosa Ziehau 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
86679251f5eSSepherosa Ziehau 
86779251f5eSSepherosa Ziehau 	autoneg_reg |= IXGBE_MII_RESTART;
86879251f5eSSepherosa Ziehau 
86979251f5eSSepherosa Ziehau 	hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
87079251f5eSSepherosa Ziehau 			      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
87179251f5eSSepherosa Ziehau 
87279251f5eSSepherosa Ziehau 	return status;
87379251f5eSSepherosa Ziehau }
87479251f5eSSepherosa Ziehau 
87579251f5eSSepherosa Ziehau /**
87679251f5eSSepherosa Ziehau  *  ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities
87779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
87879251f5eSSepherosa Ziehau  *  @speed: new link speed
879*dd5ce676SSepherosa Ziehau  *  @autoneg_wait_to_complete: unused
88079251f5eSSepherosa Ziehau  **/
ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)88179251f5eSSepherosa Ziehau s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
88279251f5eSSepherosa Ziehau 				       ixgbe_link_speed speed,
88379251f5eSSepherosa Ziehau 				       bool autoneg_wait_to_complete)
88479251f5eSSepherosa Ziehau {
88579251f5eSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
88679251f5eSSepherosa Ziehau 
88779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_phy_link_speed_generic");
88879251f5eSSepherosa Ziehau 
88979251f5eSSepherosa Ziehau 	/*
89079251f5eSSepherosa Ziehau 	 * Clear autoneg_advertised and set new values based on input link
89179251f5eSSepherosa Ziehau 	 * speed.
89279251f5eSSepherosa Ziehau 	 */
89379251f5eSSepherosa Ziehau 	hw->phy.autoneg_advertised = 0;
89479251f5eSSepherosa Ziehau 
89579251f5eSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
89679251f5eSSepherosa Ziehau 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
89779251f5eSSepherosa Ziehau 
89863d483cdSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_5GB_FULL)
89963d483cdSSepherosa Ziehau 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_5GB_FULL;
90063d483cdSSepherosa Ziehau 
90163d483cdSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_2_5GB_FULL)
90263d483cdSSepherosa Ziehau 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_2_5GB_FULL;
90363d483cdSSepherosa Ziehau 
90479251f5eSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
90579251f5eSSepherosa Ziehau 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
90679251f5eSSepherosa Ziehau 
90779251f5eSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_100_FULL)
90879251f5eSSepherosa Ziehau 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
90979251f5eSSepherosa Ziehau 
9106150453fSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_10_FULL)
9116150453fSSepherosa Ziehau 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10_FULL;
9126150453fSSepherosa Ziehau 
91379251f5eSSepherosa Ziehau 	/* Setup link based on the new speed settings */
9146150453fSSepherosa Ziehau 	ixgbe_setup_phy_link(hw);
91579251f5eSSepherosa Ziehau 
91679251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
91779251f5eSSepherosa Ziehau }
91879251f5eSSepherosa Ziehau 
91979251f5eSSepherosa Ziehau /**
9206150453fSSepherosa Ziehau  * ixgbe_get_copper_speeds_supported - Get copper link speeds from phy
9216150453fSSepherosa Ziehau  * @hw: pointer to hardware structure
9226150453fSSepherosa Ziehau  *
9236150453fSSepherosa Ziehau  * Determines the supported link capabilities by reading the PHY auto
9246150453fSSepherosa Ziehau  * negotiation register.
9256150453fSSepherosa Ziehau  **/
ixgbe_get_copper_speeds_supported(struct ixgbe_hw * hw)9266150453fSSepherosa Ziehau static s32 ixgbe_get_copper_speeds_supported(struct ixgbe_hw *hw)
9276150453fSSepherosa Ziehau {
9286150453fSSepherosa Ziehau 	s32 status;
9296150453fSSepherosa Ziehau 	u16 speed_ability;
9306150453fSSepherosa Ziehau 
9316150453fSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
9326150453fSSepherosa Ziehau 				      IXGBE_MDIO_PMA_PMD_DEV_TYPE,
9336150453fSSepherosa Ziehau 				      &speed_ability);
9346150453fSSepherosa Ziehau 	if (status)
9356150453fSSepherosa Ziehau 		return status;
9366150453fSSepherosa Ziehau 
9376150453fSSepherosa Ziehau 	if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
9386150453fSSepherosa Ziehau 		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10GB_FULL;
9396150453fSSepherosa Ziehau 	if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
9406150453fSSepherosa Ziehau 		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_1GB_FULL;
9416150453fSSepherosa Ziehau 	if (speed_ability & IXGBE_MDIO_PHY_SPEED_100M)
9426150453fSSepherosa Ziehau 		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_100_FULL;
9436150453fSSepherosa Ziehau 
9446150453fSSepherosa Ziehau 	switch (hw->mac.type) {
9456150453fSSepherosa Ziehau 	case ixgbe_mac_X550:
9466150453fSSepherosa Ziehau 		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL;
9476150453fSSepherosa Ziehau 		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL;
9486150453fSSepherosa Ziehau 		break;
9496150453fSSepherosa Ziehau 	case ixgbe_mac_X550EM_x:
9506150453fSSepherosa Ziehau 	case ixgbe_mac_X550EM_a:
9516150453fSSepherosa Ziehau 		hw->phy.speeds_supported &= ~IXGBE_LINK_SPEED_100_FULL;
9526150453fSSepherosa Ziehau 		break;
9536150453fSSepherosa Ziehau 	default:
9546150453fSSepherosa Ziehau 		break;
9556150453fSSepherosa Ziehau 	}
9566150453fSSepherosa Ziehau 
9576150453fSSepherosa Ziehau 	return status;
9586150453fSSepherosa Ziehau }
9596150453fSSepherosa Ziehau 
9606150453fSSepherosa Ziehau /**
96179251f5eSSepherosa Ziehau  *  ixgbe_get_copper_link_capabilities_generic - Determines link capabilities
96279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
96379251f5eSSepherosa Ziehau  *  @speed: pointer to link speed
96479251f5eSSepherosa Ziehau  *  @autoneg: boolean auto-negotiation value
96579251f5eSSepherosa Ziehau  **/
ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * autoneg)96679251f5eSSepherosa Ziehau s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
96779251f5eSSepherosa Ziehau 					       ixgbe_link_speed *speed,
96879251f5eSSepherosa Ziehau 					       bool *autoneg)
96979251f5eSSepherosa Ziehau {
9706150453fSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
97179251f5eSSepherosa Ziehau 
97279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_copper_link_capabilities_generic");
97379251f5eSSepherosa Ziehau 
97479251f5eSSepherosa Ziehau 	*autoneg = TRUE;
9756150453fSSepherosa Ziehau 	if (!hw->phy.speeds_supported)
9766150453fSSepherosa Ziehau 		status = ixgbe_get_copper_speeds_supported(hw);
97779251f5eSSepherosa Ziehau 
9786150453fSSepherosa Ziehau 	*speed = hw->phy.speeds_supported;
97979251f5eSSepherosa Ziehau 	return status;
98079251f5eSSepherosa Ziehau }
98179251f5eSSepherosa Ziehau 
98279251f5eSSepherosa Ziehau /**
98379251f5eSSepherosa Ziehau  *  ixgbe_check_phy_link_tnx - Determine link and speed status
98479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
985*dd5ce676SSepherosa Ziehau  *  @speed: current link speed
986*dd5ce676SSepherosa Ziehau  *  @link_up: TRUE is link is up, FALSE otherwise
98779251f5eSSepherosa Ziehau  *
98879251f5eSSepherosa Ziehau  *  Reads the VS1 register to determine if link is up and the current speed for
98979251f5eSSepherosa Ziehau  *  the PHY.
99079251f5eSSepherosa Ziehau  **/
ixgbe_check_phy_link_tnx(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * link_up)99179251f5eSSepherosa Ziehau s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
99279251f5eSSepherosa Ziehau 			     bool *link_up)
99379251f5eSSepherosa Ziehau {
99479251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
99579251f5eSSepherosa Ziehau 	u32 time_out;
99679251f5eSSepherosa Ziehau 	u32 max_time_out = 10;
99779251f5eSSepherosa Ziehau 	u16 phy_link = 0;
99879251f5eSSepherosa Ziehau 	u16 phy_speed = 0;
99979251f5eSSepherosa Ziehau 	u16 phy_data = 0;
100079251f5eSSepherosa Ziehau 
100179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_phy_link_tnx");
100279251f5eSSepherosa Ziehau 
100379251f5eSSepherosa Ziehau 	/* Initialize speed and link to default case */
100479251f5eSSepherosa Ziehau 	*link_up = FALSE;
100579251f5eSSepherosa Ziehau 	*speed = IXGBE_LINK_SPEED_10GB_FULL;
100679251f5eSSepherosa Ziehau 
100779251f5eSSepherosa Ziehau 	/*
100879251f5eSSepherosa Ziehau 	 * Check current speed and link status of the PHY register.
100979251f5eSSepherosa Ziehau 	 * This is a vendor specific register and may have to
101079251f5eSSepherosa Ziehau 	 * be changed for other copper PHYs.
101179251f5eSSepherosa Ziehau 	 */
101279251f5eSSepherosa Ziehau 	for (time_out = 0; time_out < max_time_out; time_out++) {
101379251f5eSSepherosa Ziehau 		usec_delay(10);
101479251f5eSSepherosa Ziehau 		status = hw->phy.ops.read_reg(hw,
101579251f5eSSepherosa Ziehau 					IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
101679251f5eSSepherosa Ziehau 					IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
101779251f5eSSepherosa Ziehau 					&phy_data);
101879251f5eSSepherosa Ziehau 		phy_link = phy_data & IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
101979251f5eSSepherosa Ziehau 		phy_speed = phy_data &
102079251f5eSSepherosa Ziehau 				 IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
102179251f5eSSepherosa Ziehau 		if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
102279251f5eSSepherosa Ziehau 			*link_up = TRUE;
102379251f5eSSepherosa Ziehau 			if (phy_speed ==
102479251f5eSSepherosa Ziehau 			    IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
102579251f5eSSepherosa Ziehau 				*speed = IXGBE_LINK_SPEED_1GB_FULL;
102679251f5eSSepherosa Ziehau 			break;
102779251f5eSSepherosa Ziehau 		}
102879251f5eSSepherosa Ziehau 	}
102979251f5eSSepherosa Ziehau 
103079251f5eSSepherosa Ziehau 	return status;
103179251f5eSSepherosa Ziehau }
103279251f5eSSepherosa Ziehau 
103379251f5eSSepherosa Ziehau /**
103463d483cdSSepherosa Ziehau  *	ixgbe_setup_phy_link_tnx - Set and restart auto-neg
103579251f5eSSepherosa Ziehau  *	@hw: pointer to hardware structure
103679251f5eSSepherosa Ziehau  *
103763d483cdSSepherosa Ziehau  *	Restart auto-negotiation and PHY and waits for completion.
103879251f5eSSepherosa Ziehau  **/
ixgbe_setup_phy_link_tnx(struct ixgbe_hw * hw)103979251f5eSSepherosa Ziehau s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
104079251f5eSSepherosa Ziehau {
104179251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
104279251f5eSSepherosa Ziehau 	u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
104379251f5eSSepherosa Ziehau 	bool autoneg = FALSE;
104479251f5eSSepherosa Ziehau 	ixgbe_link_speed speed;
104579251f5eSSepherosa Ziehau 
104679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_phy_link_tnx");
104779251f5eSSepherosa Ziehau 
104879251f5eSSepherosa Ziehau 	ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
104979251f5eSSepherosa Ziehau 
105079251f5eSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
105179251f5eSSepherosa Ziehau 		/* Set or unset auto-negotiation 10G advertisement */
105279251f5eSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
105379251f5eSSepherosa Ziehau 				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
105479251f5eSSepherosa Ziehau 				     &autoneg_reg);
105579251f5eSSepherosa Ziehau 
105679251f5eSSepherosa Ziehau 		autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE;
105779251f5eSSepherosa Ziehau 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
105879251f5eSSepherosa Ziehau 			autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE;
105979251f5eSSepherosa Ziehau 
106079251f5eSSepherosa Ziehau 		hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
106179251f5eSSepherosa Ziehau 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
106279251f5eSSepherosa Ziehau 				      autoneg_reg);
106379251f5eSSepherosa Ziehau 	}
106479251f5eSSepherosa Ziehau 
106579251f5eSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
106679251f5eSSepherosa Ziehau 		/* Set or unset auto-negotiation 1G advertisement */
106779251f5eSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
106879251f5eSSepherosa Ziehau 				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
106979251f5eSSepherosa Ziehau 				     &autoneg_reg);
107079251f5eSSepherosa Ziehau 
107179251f5eSSepherosa Ziehau 		autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
107279251f5eSSepherosa Ziehau 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
107379251f5eSSepherosa Ziehau 			autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
107479251f5eSSepherosa Ziehau 
107579251f5eSSepherosa Ziehau 		hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
107679251f5eSSepherosa Ziehau 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
107779251f5eSSepherosa Ziehau 				      autoneg_reg);
107879251f5eSSepherosa Ziehau 	}
107979251f5eSSepherosa Ziehau 
108079251f5eSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_100_FULL) {
108179251f5eSSepherosa Ziehau 		/* Set or unset auto-negotiation 100M advertisement */
108279251f5eSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
108379251f5eSSepherosa Ziehau 				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
108479251f5eSSepherosa Ziehau 				     &autoneg_reg);
108579251f5eSSepherosa Ziehau 
108679251f5eSSepherosa Ziehau 		autoneg_reg &= ~IXGBE_MII_100BASE_T_ADVERTISE;
108779251f5eSSepherosa Ziehau 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
108879251f5eSSepherosa Ziehau 			autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE;
108979251f5eSSepherosa Ziehau 
109079251f5eSSepherosa Ziehau 		hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
109179251f5eSSepherosa Ziehau 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
109279251f5eSSepherosa Ziehau 				      autoneg_reg);
109379251f5eSSepherosa Ziehau 	}
109479251f5eSSepherosa Ziehau 
109563d483cdSSepherosa Ziehau 	/* Blocked by MNG FW so don't reset PHY */
109663d483cdSSepherosa Ziehau 	if (ixgbe_check_reset_blocked(hw))
109763d483cdSSepherosa Ziehau 		return status;
109863d483cdSSepherosa Ziehau 
109963d483cdSSepherosa Ziehau 	/* Restart PHY auto-negotiation. */
110079251f5eSSepherosa Ziehau 	hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
110179251f5eSSepherosa Ziehau 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
110279251f5eSSepherosa Ziehau 
110379251f5eSSepherosa Ziehau 	autoneg_reg |= IXGBE_MII_RESTART;
110479251f5eSSepherosa Ziehau 
110579251f5eSSepherosa Ziehau 	hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
110679251f5eSSepherosa Ziehau 			      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
110779251f5eSSepherosa Ziehau 
110879251f5eSSepherosa Ziehau 	return status;
110979251f5eSSepherosa Ziehau }
111079251f5eSSepherosa Ziehau 
111179251f5eSSepherosa Ziehau /**
111279251f5eSSepherosa Ziehau  *  ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version
111379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
111479251f5eSSepherosa Ziehau  *  @firmware_version: pointer to the PHY Firmware Version
111579251f5eSSepherosa Ziehau  **/
ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw * hw,u16 * firmware_version)111679251f5eSSepherosa Ziehau s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
111779251f5eSSepherosa Ziehau 				       u16 *firmware_version)
111879251f5eSSepherosa Ziehau {
111963d483cdSSepherosa Ziehau 	s32 status;
112079251f5eSSepherosa Ziehau 
112179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_phy_firmware_version_tnx");
112279251f5eSSepherosa Ziehau 
112379251f5eSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
112479251f5eSSepherosa Ziehau 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
112579251f5eSSepherosa Ziehau 				      firmware_version);
112679251f5eSSepherosa Ziehau 
112779251f5eSSepherosa Ziehau 	return status;
112879251f5eSSepherosa Ziehau }
112979251f5eSSepherosa Ziehau 
113079251f5eSSepherosa Ziehau /**
113179251f5eSSepherosa Ziehau  *  ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version
113279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
113379251f5eSSepherosa Ziehau  *  @firmware_version: pointer to the PHY Firmware Version
113479251f5eSSepherosa Ziehau  **/
ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw * hw,u16 * firmware_version)113579251f5eSSepherosa Ziehau s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
113679251f5eSSepherosa Ziehau 					   u16 *firmware_version)
113779251f5eSSepherosa Ziehau {
113863d483cdSSepherosa Ziehau 	s32 status;
113979251f5eSSepherosa Ziehau 
114079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_phy_firmware_version_generic");
114179251f5eSSepherosa Ziehau 
114279251f5eSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, AQ_FW_REV,
114379251f5eSSepherosa Ziehau 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
114479251f5eSSepherosa Ziehau 				      firmware_version);
114579251f5eSSepherosa Ziehau 
114679251f5eSSepherosa Ziehau 	return status;
114779251f5eSSepherosa Ziehau }
114879251f5eSSepherosa Ziehau 
114979251f5eSSepherosa Ziehau /**
115079251f5eSSepherosa Ziehau  *  ixgbe_reset_phy_nl - Performs a PHY reset
115179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
115279251f5eSSepherosa Ziehau  **/
ixgbe_reset_phy_nl(struct ixgbe_hw * hw)115379251f5eSSepherosa Ziehau s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
115479251f5eSSepherosa Ziehau {
115579251f5eSSepherosa Ziehau 	u16 phy_offset, control, eword, edata, block_crc;
115679251f5eSSepherosa Ziehau 	bool end_data = FALSE;
115779251f5eSSepherosa Ziehau 	u16 list_offset, data_offset;
115879251f5eSSepherosa Ziehau 	u16 phy_data = 0;
115979251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
116079251f5eSSepherosa Ziehau 	u32 i;
116179251f5eSSepherosa Ziehau 
116279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_reset_phy_nl");
116379251f5eSSepherosa Ziehau 
116463d483cdSSepherosa Ziehau 	/* Blocked by MNG FW so bail */
116563d483cdSSepherosa Ziehau 	if (ixgbe_check_reset_blocked(hw))
116663d483cdSSepherosa Ziehau 		goto out;
116763d483cdSSepherosa Ziehau 
116879251f5eSSepherosa Ziehau 	hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
116979251f5eSSepherosa Ziehau 			     IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
117079251f5eSSepherosa Ziehau 
117179251f5eSSepherosa Ziehau 	/* reset the PHY and poll for completion */
117279251f5eSSepherosa Ziehau 	hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
117379251f5eSSepherosa Ziehau 			      IXGBE_MDIO_PHY_XS_DEV_TYPE,
117479251f5eSSepherosa Ziehau 			      (phy_data | IXGBE_MDIO_PHY_XS_RESET));
117579251f5eSSepherosa Ziehau 
117679251f5eSSepherosa Ziehau 	for (i = 0; i < 100; i++) {
117779251f5eSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
117879251f5eSSepherosa Ziehau 				     IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
117979251f5eSSepherosa Ziehau 		if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) == 0)
118079251f5eSSepherosa Ziehau 			break;
118179251f5eSSepherosa Ziehau 		msec_delay(10);
118279251f5eSSepherosa Ziehau 	}
118379251f5eSSepherosa Ziehau 
118479251f5eSSepherosa Ziehau 	if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) != 0) {
118579251f5eSSepherosa Ziehau 		DEBUGOUT("PHY reset did not complete.\n");
118679251f5eSSepherosa Ziehau 		ret_val = IXGBE_ERR_PHY;
118779251f5eSSepherosa Ziehau 		goto out;
118879251f5eSSepherosa Ziehau 	}
118979251f5eSSepherosa Ziehau 
119079251f5eSSepherosa Ziehau 	/* Get init offsets */
119179251f5eSSepherosa Ziehau 	ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
119279251f5eSSepherosa Ziehau 						      &data_offset);
119379251f5eSSepherosa Ziehau 	if (ret_val != IXGBE_SUCCESS)
119479251f5eSSepherosa Ziehau 		goto out;
119579251f5eSSepherosa Ziehau 
119679251f5eSSepherosa Ziehau 	ret_val = hw->eeprom.ops.read(hw, data_offset, &block_crc);
119779251f5eSSepherosa Ziehau 	data_offset++;
119879251f5eSSepherosa Ziehau 	while (!end_data) {
119979251f5eSSepherosa Ziehau 		/*
120079251f5eSSepherosa Ziehau 		 * Read control word from PHY init contents offset
120179251f5eSSepherosa Ziehau 		 */
120279251f5eSSepherosa Ziehau 		ret_val = hw->eeprom.ops.read(hw, data_offset, &eword);
120379251f5eSSepherosa Ziehau 		if (ret_val)
120479251f5eSSepherosa Ziehau 			goto err_eeprom;
120579251f5eSSepherosa Ziehau 		control = (eword & IXGBE_CONTROL_MASK_NL) >>
120679251f5eSSepherosa Ziehau 			   IXGBE_CONTROL_SHIFT_NL;
120779251f5eSSepherosa Ziehau 		edata = eword & IXGBE_DATA_MASK_NL;
120879251f5eSSepherosa Ziehau 		switch (control) {
120979251f5eSSepherosa Ziehau 		case IXGBE_DELAY_NL:
121079251f5eSSepherosa Ziehau 			data_offset++;
121179251f5eSSepherosa Ziehau 			DEBUGOUT1("DELAY: %d MS\n", edata);
121279251f5eSSepherosa Ziehau 			msec_delay(edata);
121379251f5eSSepherosa Ziehau 			break;
121479251f5eSSepherosa Ziehau 		case IXGBE_DATA_NL:
121579251f5eSSepherosa Ziehau 			DEBUGOUT("DATA:\n");
121679251f5eSSepherosa Ziehau 			data_offset++;
121779251f5eSSepherosa Ziehau 			ret_val = hw->eeprom.ops.read(hw, data_offset,
121879251f5eSSepherosa Ziehau 						      &phy_offset);
121979251f5eSSepherosa Ziehau 			if (ret_val)
122079251f5eSSepherosa Ziehau 				goto err_eeprom;
122179251f5eSSepherosa Ziehau 			data_offset++;
122279251f5eSSepherosa Ziehau 			for (i = 0; i < edata; i++) {
122379251f5eSSepherosa Ziehau 				ret_val = hw->eeprom.ops.read(hw, data_offset,
122479251f5eSSepherosa Ziehau 							      &eword);
122579251f5eSSepherosa Ziehau 				if (ret_val)
122679251f5eSSepherosa Ziehau 					goto err_eeprom;
122779251f5eSSepherosa Ziehau 				hw->phy.ops.write_reg(hw, phy_offset,
122879251f5eSSepherosa Ziehau 						      IXGBE_TWINAX_DEV, eword);
122979251f5eSSepherosa Ziehau 				DEBUGOUT2("Wrote %4.4x to %4.4x\n", eword,
123079251f5eSSepherosa Ziehau 					  phy_offset);
123179251f5eSSepherosa Ziehau 				data_offset++;
123279251f5eSSepherosa Ziehau 				phy_offset++;
123379251f5eSSepherosa Ziehau 			}
123479251f5eSSepherosa Ziehau 			break;
123579251f5eSSepherosa Ziehau 		case IXGBE_CONTROL_NL:
123679251f5eSSepherosa Ziehau 			data_offset++;
123779251f5eSSepherosa Ziehau 			DEBUGOUT("CONTROL:\n");
123879251f5eSSepherosa Ziehau 			if (edata == IXGBE_CONTROL_EOL_NL) {
123979251f5eSSepherosa Ziehau 				DEBUGOUT("EOL\n");
124079251f5eSSepherosa Ziehau 				end_data = TRUE;
124179251f5eSSepherosa Ziehau 			} else if (edata == IXGBE_CONTROL_SOL_NL) {
124279251f5eSSepherosa Ziehau 				DEBUGOUT("SOL\n");
124379251f5eSSepherosa Ziehau 			} else {
124479251f5eSSepherosa Ziehau 				DEBUGOUT("Bad control value\n");
124579251f5eSSepherosa Ziehau 				ret_val = IXGBE_ERR_PHY;
124679251f5eSSepherosa Ziehau 				goto out;
124779251f5eSSepherosa Ziehau 			}
124879251f5eSSepherosa Ziehau 			break;
124979251f5eSSepherosa Ziehau 		default:
125079251f5eSSepherosa Ziehau 			DEBUGOUT("Bad control type\n");
125179251f5eSSepherosa Ziehau 			ret_val = IXGBE_ERR_PHY;
125279251f5eSSepherosa Ziehau 			goto out;
125379251f5eSSepherosa Ziehau 		}
125479251f5eSSepherosa Ziehau 	}
125579251f5eSSepherosa Ziehau 
125679251f5eSSepherosa Ziehau out:
125779251f5eSSepherosa Ziehau 	return ret_val;
125879251f5eSSepherosa Ziehau 
125979251f5eSSepherosa Ziehau err_eeprom:
126079251f5eSSepherosa Ziehau 	ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
126179251f5eSSepherosa Ziehau 		      "eeprom read at offset %d failed", data_offset);
126279251f5eSSepherosa Ziehau 	return IXGBE_ERR_PHY;
126379251f5eSSepherosa Ziehau }
126479251f5eSSepherosa Ziehau 
126579251f5eSSepherosa Ziehau /**
126679251f5eSSepherosa Ziehau  *  ixgbe_identify_module_generic - Identifies module type
126779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
126879251f5eSSepherosa Ziehau  *
126979251f5eSSepherosa Ziehau  *  Determines HW type and calls appropriate function.
127079251f5eSSepherosa Ziehau  **/
ixgbe_identify_module_generic(struct ixgbe_hw * hw)127179251f5eSSepherosa Ziehau s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw)
127279251f5eSSepherosa Ziehau {
127379251f5eSSepherosa Ziehau 	s32 status = IXGBE_ERR_SFP_NOT_PRESENT;
127479251f5eSSepherosa Ziehau 
127579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_identify_module_generic");
127679251f5eSSepherosa Ziehau 
127779251f5eSSepherosa Ziehau 	switch (hw->mac.ops.get_media_type(hw)) {
127879251f5eSSepherosa Ziehau 	case ixgbe_media_type_fiber:
127979251f5eSSepherosa Ziehau 		status = ixgbe_identify_sfp_module_generic(hw);
128079251f5eSSepherosa Ziehau 		break;
128179251f5eSSepherosa Ziehau 
128263d483cdSSepherosa Ziehau 	case ixgbe_media_type_fiber_qsfp:
128363d483cdSSepherosa Ziehau 		status = ixgbe_identify_qsfp_module_generic(hw);
128463d483cdSSepherosa Ziehau 		break;
128579251f5eSSepherosa Ziehau 
128679251f5eSSepherosa Ziehau 	default:
128779251f5eSSepherosa Ziehau 		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
128879251f5eSSepherosa Ziehau 		status = IXGBE_ERR_SFP_NOT_PRESENT;
128979251f5eSSepherosa Ziehau 		break;
129079251f5eSSepherosa Ziehau 	}
129179251f5eSSepherosa Ziehau 
129279251f5eSSepherosa Ziehau 	return status;
129379251f5eSSepherosa Ziehau }
129479251f5eSSepherosa Ziehau 
129579251f5eSSepherosa Ziehau /**
129679251f5eSSepherosa Ziehau  *  ixgbe_identify_sfp_module_generic - Identifies SFP modules
129779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
129879251f5eSSepherosa Ziehau  *
129979251f5eSSepherosa Ziehau  *  Searches for and identifies the SFP module and assigns appropriate PHY type.
130079251f5eSSepherosa Ziehau  **/
ixgbe_identify_sfp_module_generic(struct ixgbe_hw * hw)130179251f5eSSepherosa Ziehau s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
130279251f5eSSepherosa Ziehau {
130379251f5eSSepherosa Ziehau 	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
130479251f5eSSepherosa Ziehau 	u32 vendor_oui = 0;
130579251f5eSSepherosa Ziehau 	enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
130679251f5eSSepherosa Ziehau 	u8 identifier = 0;
130779251f5eSSepherosa Ziehau 	u8 comp_codes_1g = 0;
130879251f5eSSepherosa Ziehau 	u8 comp_codes_10g = 0;
130979251f5eSSepherosa Ziehau 	u8 oui_bytes[3] = {0, 0, 0};
131079251f5eSSepherosa Ziehau 	u8 cable_tech = 0;
131179251f5eSSepherosa Ziehau 	u8 cable_spec = 0;
131279251f5eSSepherosa Ziehau 	u16 enforce_sfp = 0;
131379251f5eSSepherosa Ziehau 
131479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_identify_sfp_module_generic");
131579251f5eSSepherosa Ziehau 
131679251f5eSSepherosa Ziehau 	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) {
131779251f5eSSepherosa Ziehau 		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
131879251f5eSSepherosa Ziehau 		status = IXGBE_ERR_SFP_NOT_PRESENT;
131979251f5eSSepherosa Ziehau 		goto out;
132079251f5eSSepherosa Ziehau 	}
132179251f5eSSepherosa Ziehau 
132263d483cdSSepherosa Ziehau 	/* LAN ID is needed for I2C access */
132363d483cdSSepherosa Ziehau 	hw->mac.ops.set_lan_id(hw);
132463d483cdSSepherosa Ziehau 
132579251f5eSSepherosa Ziehau 	status = hw->phy.ops.read_i2c_eeprom(hw,
132679251f5eSSepherosa Ziehau 					     IXGBE_SFF_IDENTIFIER,
132779251f5eSSepherosa Ziehau 					     &identifier);
132879251f5eSSepherosa Ziehau 
132979251f5eSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
133079251f5eSSepherosa Ziehau 		goto err_read_i2c_eeprom;
133179251f5eSSepherosa Ziehau 
133279251f5eSSepherosa Ziehau 	if (identifier != IXGBE_SFF_IDENTIFIER_SFP) {
133379251f5eSSepherosa Ziehau 		hw->phy.type = ixgbe_phy_sfp_unsupported;
133479251f5eSSepherosa Ziehau 		status = IXGBE_ERR_SFP_NOT_SUPPORTED;
133579251f5eSSepherosa Ziehau 	} else {
133679251f5eSSepherosa Ziehau 		status = hw->phy.ops.read_i2c_eeprom(hw,
133779251f5eSSepherosa Ziehau 						     IXGBE_SFF_1GBE_COMP_CODES,
133879251f5eSSepherosa Ziehau 						     &comp_codes_1g);
133979251f5eSSepherosa Ziehau 
134079251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
134179251f5eSSepherosa Ziehau 			goto err_read_i2c_eeprom;
134279251f5eSSepherosa Ziehau 
134379251f5eSSepherosa Ziehau 		status = hw->phy.ops.read_i2c_eeprom(hw,
134479251f5eSSepherosa Ziehau 						     IXGBE_SFF_10GBE_COMP_CODES,
134579251f5eSSepherosa Ziehau 						     &comp_codes_10g);
134679251f5eSSepherosa Ziehau 
134779251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
134879251f5eSSepherosa Ziehau 			goto err_read_i2c_eeprom;
134979251f5eSSepherosa Ziehau 		status = hw->phy.ops.read_i2c_eeprom(hw,
135079251f5eSSepherosa Ziehau 						     IXGBE_SFF_CABLE_TECHNOLOGY,
135179251f5eSSepherosa Ziehau 						     &cable_tech);
135279251f5eSSepherosa Ziehau 
135379251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
135479251f5eSSepherosa Ziehau 			goto err_read_i2c_eeprom;
135579251f5eSSepherosa Ziehau 
135679251f5eSSepherosa Ziehau 		 /* ID Module
135779251f5eSSepherosa Ziehau 		  * =========
135879251f5eSSepherosa Ziehau 		  * 0   SFP_DA_CU
135979251f5eSSepherosa Ziehau 		  * 1   SFP_SR
136079251f5eSSepherosa Ziehau 		  * 2   SFP_LR
136179251f5eSSepherosa Ziehau 		  * 3   SFP_DA_CORE0 - 82599-specific
136279251f5eSSepherosa Ziehau 		  * 4   SFP_DA_CORE1 - 82599-specific
136379251f5eSSepherosa Ziehau 		  * 5   SFP_SR/LR_CORE0 - 82599-specific
136479251f5eSSepherosa Ziehau 		  * 6   SFP_SR/LR_CORE1 - 82599-specific
136579251f5eSSepherosa Ziehau 		  * 7   SFP_act_lmt_DA_CORE0 - 82599-specific
136679251f5eSSepherosa Ziehau 		  * 8   SFP_act_lmt_DA_CORE1 - 82599-specific
136779251f5eSSepherosa Ziehau 		  * 9   SFP_1g_cu_CORE0 - 82599-specific
136879251f5eSSepherosa Ziehau 		  * 10  SFP_1g_cu_CORE1 - 82599-specific
136979251f5eSSepherosa Ziehau 		  * 11  SFP_1g_sx_CORE0 - 82599-specific
137079251f5eSSepherosa Ziehau 		  * 12  SFP_1g_sx_CORE1 - 82599-specific
137179251f5eSSepherosa Ziehau 		  */
137279251f5eSSepherosa Ziehau 		if (hw->mac.type == ixgbe_mac_82598EB) {
137379251f5eSSepherosa Ziehau 			if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
137479251f5eSSepherosa Ziehau 				hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
137579251f5eSSepherosa Ziehau 			else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
137679251f5eSSepherosa Ziehau 				hw->phy.sfp_type = ixgbe_sfp_type_sr;
137779251f5eSSepherosa Ziehau 			else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
137879251f5eSSepherosa Ziehau 				hw->phy.sfp_type = ixgbe_sfp_type_lr;
137979251f5eSSepherosa Ziehau 			else
138079251f5eSSepherosa Ziehau 				hw->phy.sfp_type = ixgbe_sfp_type_unknown;
138163d483cdSSepherosa Ziehau 		} else {
138279251f5eSSepherosa Ziehau 			if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
138379251f5eSSepherosa Ziehau 				if (hw->bus.lan_id == 0)
138479251f5eSSepherosa Ziehau 					hw->phy.sfp_type =
138579251f5eSSepherosa Ziehau 						     ixgbe_sfp_type_da_cu_core0;
138679251f5eSSepherosa Ziehau 				else
138779251f5eSSepherosa Ziehau 					hw->phy.sfp_type =
138879251f5eSSepherosa Ziehau 						     ixgbe_sfp_type_da_cu_core1;
138979251f5eSSepherosa Ziehau 			} else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) {
139079251f5eSSepherosa Ziehau 				hw->phy.ops.read_i2c_eeprom(
139179251f5eSSepherosa Ziehau 						hw, IXGBE_SFF_CABLE_SPEC_COMP,
139279251f5eSSepherosa Ziehau 						&cable_spec);
139379251f5eSSepherosa Ziehau 				if (cable_spec &
139479251f5eSSepherosa Ziehau 				    IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) {
139579251f5eSSepherosa Ziehau 					if (hw->bus.lan_id == 0)
139679251f5eSSepherosa Ziehau 						hw->phy.sfp_type =
139779251f5eSSepherosa Ziehau 						ixgbe_sfp_type_da_act_lmt_core0;
139879251f5eSSepherosa Ziehau 					else
139979251f5eSSepherosa Ziehau 						hw->phy.sfp_type =
140079251f5eSSepherosa Ziehau 						ixgbe_sfp_type_da_act_lmt_core1;
140179251f5eSSepherosa Ziehau 				} else {
140279251f5eSSepherosa Ziehau 					hw->phy.sfp_type =
140379251f5eSSepherosa Ziehau 							ixgbe_sfp_type_unknown;
140479251f5eSSepherosa Ziehau 				}
140579251f5eSSepherosa Ziehau 			} else if (comp_codes_10g &
140679251f5eSSepherosa Ziehau 				   (IXGBE_SFF_10GBASESR_CAPABLE |
140779251f5eSSepherosa Ziehau 				    IXGBE_SFF_10GBASELR_CAPABLE)) {
140879251f5eSSepherosa Ziehau 				if (hw->bus.lan_id == 0)
140979251f5eSSepherosa Ziehau 					hw->phy.sfp_type =
141079251f5eSSepherosa Ziehau 						      ixgbe_sfp_type_srlr_core0;
141179251f5eSSepherosa Ziehau 				else
141279251f5eSSepherosa Ziehau 					hw->phy.sfp_type =
141379251f5eSSepherosa Ziehau 						      ixgbe_sfp_type_srlr_core1;
141479251f5eSSepherosa Ziehau 			} else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) {
141579251f5eSSepherosa Ziehau 				if (hw->bus.lan_id == 0)
141679251f5eSSepherosa Ziehau 					hw->phy.sfp_type =
141779251f5eSSepherosa Ziehau 						ixgbe_sfp_type_1g_cu_core0;
141879251f5eSSepherosa Ziehau 				else
141979251f5eSSepherosa Ziehau 					hw->phy.sfp_type =
142079251f5eSSepherosa Ziehau 						ixgbe_sfp_type_1g_cu_core1;
142179251f5eSSepherosa Ziehau 			} else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) {
142279251f5eSSepherosa Ziehau 				if (hw->bus.lan_id == 0)
142379251f5eSSepherosa Ziehau 					hw->phy.sfp_type =
142479251f5eSSepherosa Ziehau 						ixgbe_sfp_type_1g_sx_core0;
142579251f5eSSepherosa Ziehau 				else
142679251f5eSSepherosa Ziehau 					hw->phy.sfp_type =
142779251f5eSSepherosa Ziehau 						ixgbe_sfp_type_1g_sx_core1;
142863d483cdSSepherosa Ziehau 			} else if (comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) {
142963d483cdSSepherosa Ziehau 				if (hw->bus.lan_id == 0)
143063d483cdSSepherosa Ziehau 					hw->phy.sfp_type =
143163d483cdSSepherosa Ziehau 						ixgbe_sfp_type_1g_lx_core0;
143263d483cdSSepherosa Ziehau 				else
143363d483cdSSepherosa Ziehau 					hw->phy.sfp_type =
143463d483cdSSepherosa Ziehau 						ixgbe_sfp_type_1g_lx_core1;
143579251f5eSSepherosa Ziehau 			} else {
143679251f5eSSepherosa Ziehau 				hw->phy.sfp_type = ixgbe_sfp_type_unknown;
143779251f5eSSepherosa Ziehau 			}
143879251f5eSSepherosa Ziehau 		}
143979251f5eSSepherosa Ziehau 
144079251f5eSSepherosa Ziehau 		if (hw->phy.sfp_type != stored_sfp_type)
144179251f5eSSepherosa Ziehau 			hw->phy.sfp_setup_needed = TRUE;
144279251f5eSSepherosa Ziehau 
144379251f5eSSepherosa Ziehau 		/* Determine if the SFP+ PHY is dual speed or not. */
144479251f5eSSepherosa Ziehau 		hw->phy.multispeed_fiber = FALSE;
144579251f5eSSepherosa Ziehau 		if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
144679251f5eSSepherosa Ziehau 		   (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
144779251f5eSSepherosa Ziehau 		   ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
144879251f5eSSepherosa Ziehau 		   (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
144979251f5eSSepherosa Ziehau 			hw->phy.multispeed_fiber = TRUE;
145079251f5eSSepherosa Ziehau 
145179251f5eSSepherosa Ziehau 		/* Determine PHY vendor */
145279251f5eSSepherosa Ziehau 		if (hw->phy.type != ixgbe_phy_nl) {
145379251f5eSSepherosa Ziehau 			hw->phy.id = identifier;
145479251f5eSSepherosa Ziehau 			status = hw->phy.ops.read_i2c_eeprom(hw,
145579251f5eSSepherosa Ziehau 						    IXGBE_SFF_VENDOR_OUI_BYTE0,
145679251f5eSSepherosa Ziehau 						    &oui_bytes[0]);
145779251f5eSSepherosa Ziehau 
145879251f5eSSepherosa Ziehau 			if (status != IXGBE_SUCCESS)
145979251f5eSSepherosa Ziehau 				goto err_read_i2c_eeprom;
146079251f5eSSepherosa Ziehau 
146179251f5eSSepherosa Ziehau 			status = hw->phy.ops.read_i2c_eeprom(hw,
146279251f5eSSepherosa Ziehau 						    IXGBE_SFF_VENDOR_OUI_BYTE1,
146379251f5eSSepherosa Ziehau 						    &oui_bytes[1]);
146479251f5eSSepherosa Ziehau 
146579251f5eSSepherosa Ziehau 			if (status != IXGBE_SUCCESS)
146679251f5eSSepherosa Ziehau 				goto err_read_i2c_eeprom;
146779251f5eSSepherosa Ziehau 
146879251f5eSSepherosa Ziehau 			status = hw->phy.ops.read_i2c_eeprom(hw,
146979251f5eSSepherosa Ziehau 						    IXGBE_SFF_VENDOR_OUI_BYTE2,
147079251f5eSSepherosa Ziehau 						    &oui_bytes[2]);
147179251f5eSSepherosa Ziehau 
147279251f5eSSepherosa Ziehau 			if (status != IXGBE_SUCCESS)
147379251f5eSSepherosa Ziehau 				goto err_read_i2c_eeprom;
147479251f5eSSepherosa Ziehau 
147579251f5eSSepherosa Ziehau 			vendor_oui =
147679251f5eSSepherosa Ziehau 			  ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
147779251f5eSSepherosa Ziehau 			   (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
147879251f5eSSepherosa Ziehau 			   (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
147979251f5eSSepherosa Ziehau 
148079251f5eSSepherosa Ziehau 			switch (vendor_oui) {
148179251f5eSSepherosa Ziehau 			case IXGBE_SFF_VENDOR_OUI_TYCO:
148279251f5eSSepherosa Ziehau 				if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
148379251f5eSSepherosa Ziehau 					hw->phy.type =
148479251f5eSSepherosa Ziehau 						    ixgbe_phy_sfp_passive_tyco;
148579251f5eSSepherosa Ziehau 				break;
148679251f5eSSepherosa Ziehau 			case IXGBE_SFF_VENDOR_OUI_FTL:
148779251f5eSSepherosa Ziehau 				if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
148879251f5eSSepherosa Ziehau 					hw->phy.type = ixgbe_phy_sfp_ftl_active;
148979251f5eSSepherosa Ziehau 				else
149079251f5eSSepherosa Ziehau 					hw->phy.type = ixgbe_phy_sfp_ftl;
149179251f5eSSepherosa Ziehau 				break;
149279251f5eSSepherosa Ziehau 			case IXGBE_SFF_VENDOR_OUI_AVAGO:
149379251f5eSSepherosa Ziehau 				hw->phy.type = ixgbe_phy_sfp_avago;
149479251f5eSSepherosa Ziehau 				break;
149579251f5eSSepherosa Ziehau 			case IXGBE_SFF_VENDOR_OUI_INTEL:
149679251f5eSSepherosa Ziehau 				hw->phy.type = ixgbe_phy_sfp_intel;
149779251f5eSSepherosa Ziehau 				break;
149879251f5eSSepherosa Ziehau 			default:
149979251f5eSSepherosa Ziehau 				if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
150079251f5eSSepherosa Ziehau 					hw->phy.type =
150179251f5eSSepherosa Ziehau 						 ixgbe_phy_sfp_passive_unknown;
150279251f5eSSepherosa Ziehau 				else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
150379251f5eSSepherosa Ziehau 					hw->phy.type =
150479251f5eSSepherosa Ziehau 						ixgbe_phy_sfp_active_unknown;
150579251f5eSSepherosa Ziehau 				else
150679251f5eSSepherosa Ziehau 					hw->phy.type = ixgbe_phy_sfp_unknown;
150779251f5eSSepherosa Ziehau 				break;
150879251f5eSSepherosa Ziehau 			}
150979251f5eSSepherosa Ziehau 		}
151079251f5eSSepherosa Ziehau 
151179251f5eSSepherosa Ziehau 		/* Allow any DA cable vendor */
151279251f5eSSepherosa Ziehau 		if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE |
151379251f5eSSepherosa Ziehau 		    IXGBE_SFF_DA_ACTIVE_CABLE)) {
151479251f5eSSepherosa Ziehau 			status = IXGBE_SUCCESS;
151579251f5eSSepherosa Ziehau 			goto out;
151679251f5eSSepherosa Ziehau 		}
151779251f5eSSepherosa Ziehau 
151879251f5eSSepherosa Ziehau 		/* Verify supported 1G SFP modules */
151979251f5eSSepherosa Ziehau 		if (comp_codes_10g == 0 &&
152079251f5eSSepherosa Ziehau 		    !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
152179251f5eSSepherosa Ziehau 		      hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
152263d483cdSSepherosa Ziehau 		      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
152363d483cdSSepherosa Ziehau 		      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
152479251f5eSSepherosa Ziehau 		      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
152579251f5eSSepherosa Ziehau 		      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
152679251f5eSSepherosa Ziehau 			hw->phy.type = ixgbe_phy_sfp_unsupported;
152779251f5eSSepherosa Ziehau 			status = IXGBE_ERR_SFP_NOT_SUPPORTED;
152879251f5eSSepherosa Ziehau 			goto out;
152979251f5eSSepherosa Ziehau 		}
153079251f5eSSepherosa Ziehau 
153179251f5eSSepherosa Ziehau 		/* Anything else 82598-based is supported */
153279251f5eSSepherosa Ziehau 		if (hw->mac.type == ixgbe_mac_82598EB) {
153379251f5eSSepherosa Ziehau 			status = IXGBE_SUCCESS;
153479251f5eSSepherosa Ziehau 			goto out;
153579251f5eSSepherosa Ziehau 		}
153679251f5eSSepherosa Ziehau 
153779251f5eSSepherosa Ziehau 		ixgbe_get_device_caps(hw, &enforce_sfp);
153879251f5eSSepherosa Ziehau 		if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
153979251f5eSSepherosa Ziehau 		    !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
154079251f5eSSepherosa Ziehau 		      hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
154163d483cdSSepherosa Ziehau 		      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
154263d483cdSSepherosa Ziehau 		      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
154379251f5eSSepherosa Ziehau 		      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
154479251f5eSSepherosa Ziehau 		      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
154579251f5eSSepherosa Ziehau 			/* Make sure we're a supported PHY type */
154679251f5eSSepherosa Ziehau 			if (hw->phy.type == ixgbe_phy_sfp_intel) {
154779251f5eSSepherosa Ziehau 				status = IXGBE_SUCCESS;
154879251f5eSSepherosa Ziehau 			} else {
154979251f5eSSepherosa Ziehau 				if (hw->allow_unsupported_sfp == TRUE) {
15506150453fSSepherosa Ziehau 					EWARN(hw, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n");
155179251f5eSSepherosa Ziehau 					status = IXGBE_SUCCESS;
155279251f5eSSepherosa Ziehau 				} else {
155379251f5eSSepherosa Ziehau 					DEBUGOUT("SFP+ module not supported\n");
155479251f5eSSepherosa Ziehau 					hw->phy.type =
155579251f5eSSepherosa Ziehau 						ixgbe_phy_sfp_unsupported;
155679251f5eSSepherosa Ziehau 					status = IXGBE_ERR_SFP_NOT_SUPPORTED;
155779251f5eSSepherosa Ziehau 				}
155879251f5eSSepherosa Ziehau 			}
155979251f5eSSepherosa Ziehau 		} else {
156079251f5eSSepherosa Ziehau 			status = IXGBE_SUCCESS;
156179251f5eSSepherosa Ziehau 		}
156279251f5eSSepherosa Ziehau 	}
156379251f5eSSepherosa Ziehau 
156479251f5eSSepherosa Ziehau out:
156579251f5eSSepherosa Ziehau 	return status;
156679251f5eSSepherosa Ziehau 
156779251f5eSSepherosa Ziehau err_read_i2c_eeprom:
156879251f5eSSepherosa Ziehau 	hw->phy.sfp_type = ixgbe_sfp_type_not_present;
156979251f5eSSepherosa Ziehau 	if (hw->phy.type != ixgbe_phy_nl) {
157079251f5eSSepherosa Ziehau 		hw->phy.id = 0;
157179251f5eSSepherosa Ziehau 		hw->phy.type = ixgbe_phy_unknown;
157279251f5eSSepherosa Ziehau 	}
157379251f5eSSepherosa Ziehau 	return IXGBE_ERR_SFP_NOT_PRESENT;
157479251f5eSSepherosa Ziehau }
157579251f5eSSepherosa Ziehau 
157663d483cdSSepherosa Ziehau /**
157763d483cdSSepherosa Ziehau  *  ixgbe_get_supported_phy_sfp_layer_generic - Returns physical layer type
157863d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
157963d483cdSSepherosa Ziehau  *
158063d483cdSSepherosa Ziehau  *  Determines physical layer capabilities of the current SFP.
158163d483cdSSepherosa Ziehau  */
ixgbe_get_supported_phy_sfp_layer_generic(struct ixgbe_hw * hw)15826150453fSSepherosa Ziehau u64 ixgbe_get_supported_phy_sfp_layer_generic(struct ixgbe_hw *hw)
158363d483cdSSepherosa Ziehau {
15846150453fSSepherosa Ziehau 	u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
158563d483cdSSepherosa Ziehau 	u8 comp_codes_10g = 0;
158663d483cdSSepherosa Ziehau 	u8 comp_codes_1g = 0;
158763d483cdSSepherosa Ziehau 
158863d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_supported_phy_sfp_layer_generic");
158963d483cdSSepherosa Ziehau 
159063d483cdSSepherosa Ziehau 	hw->phy.ops.identify_sfp(hw);
159163d483cdSSepherosa Ziehau 	if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
159263d483cdSSepherosa Ziehau 		return physical_layer;
159363d483cdSSepherosa Ziehau 
159463d483cdSSepherosa Ziehau 	switch (hw->phy.type) {
159563d483cdSSepherosa Ziehau 	case ixgbe_phy_sfp_passive_tyco:
159663d483cdSSepherosa Ziehau 	case ixgbe_phy_sfp_passive_unknown:
159763d483cdSSepherosa Ziehau 	case ixgbe_phy_qsfp_passive_unknown:
159863d483cdSSepherosa Ziehau 		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
159963d483cdSSepherosa Ziehau 		break;
160063d483cdSSepherosa Ziehau 	case ixgbe_phy_sfp_ftl_active:
160163d483cdSSepherosa Ziehau 	case ixgbe_phy_sfp_active_unknown:
160263d483cdSSepherosa Ziehau 	case ixgbe_phy_qsfp_active_unknown:
160363d483cdSSepherosa Ziehau 		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA;
160463d483cdSSepherosa Ziehau 		break;
160563d483cdSSepherosa Ziehau 	case ixgbe_phy_sfp_avago:
160663d483cdSSepherosa Ziehau 	case ixgbe_phy_sfp_ftl:
160763d483cdSSepherosa Ziehau 	case ixgbe_phy_sfp_intel:
160863d483cdSSepherosa Ziehau 	case ixgbe_phy_sfp_unknown:
160963d483cdSSepherosa Ziehau 		hw->phy.ops.read_i2c_eeprom(hw,
161063d483cdSSepherosa Ziehau 		      IXGBE_SFF_1GBE_COMP_CODES, &comp_codes_1g);
161163d483cdSSepherosa Ziehau 		hw->phy.ops.read_i2c_eeprom(hw,
161263d483cdSSepherosa Ziehau 		      IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g);
161363d483cdSSepherosa Ziehau 		if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
161463d483cdSSepherosa Ziehau 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
161563d483cdSSepherosa Ziehau 		else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
161663d483cdSSepherosa Ziehau 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
161763d483cdSSepherosa Ziehau 		else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE)
161863d483cdSSepherosa Ziehau 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
161963d483cdSSepherosa Ziehau 		else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE)
162063d483cdSSepherosa Ziehau 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_SX;
162163d483cdSSepherosa Ziehau 		break;
162263d483cdSSepherosa Ziehau 	case ixgbe_phy_qsfp_intel:
162363d483cdSSepherosa Ziehau 	case ixgbe_phy_qsfp_unknown:
162463d483cdSSepherosa Ziehau 		hw->phy.ops.read_i2c_eeprom(hw,
162563d483cdSSepherosa Ziehau 		      IXGBE_SFF_QSFP_10GBE_COMP, &comp_codes_10g);
162663d483cdSSepherosa Ziehau 		if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
162763d483cdSSepherosa Ziehau 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
162863d483cdSSepherosa Ziehau 		else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
162963d483cdSSepherosa Ziehau 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
163063d483cdSSepherosa Ziehau 		break;
163163d483cdSSepherosa Ziehau 	default:
163263d483cdSSepherosa Ziehau 		break;
163363d483cdSSepherosa Ziehau 	}
163463d483cdSSepherosa Ziehau 
163563d483cdSSepherosa Ziehau 	return physical_layer;
163663d483cdSSepherosa Ziehau }
163763d483cdSSepherosa Ziehau 
163863d483cdSSepherosa Ziehau /**
163963d483cdSSepherosa Ziehau  *  ixgbe_identify_qsfp_module_generic - Identifies QSFP modules
164063d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
164163d483cdSSepherosa Ziehau  *
164263d483cdSSepherosa Ziehau  *  Searches for and identifies the QSFP module and assigns appropriate PHY type
164363d483cdSSepherosa Ziehau  **/
ixgbe_identify_qsfp_module_generic(struct ixgbe_hw * hw)164463d483cdSSepherosa Ziehau s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
164563d483cdSSepherosa Ziehau {
164663d483cdSSepherosa Ziehau 	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
164763d483cdSSepherosa Ziehau 	u32 vendor_oui = 0;
164863d483cdSSepherosa Ziehau 	enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
164963d483cdSSepherosa Ziehau 	u8 identifier = 0;
165063d483cdSSepherosa Ziehau 	u8 comp_codes_1g = 0;
165163d483cdSSepherosa Ziehau 	u8 comp_codes_10g = 0;
165263d483cdSSepherosa Ziehau 	u8 oui_bytes[3] = {0, 0, 0};
165363d483cdSSepherosa Ziehau 	u16 enforce_sfp = 0;
165463d483cdSSepherosa Ziehau 	u8 connector = 0;
165563d483cdSSepherosa Ziehau 	u8 cable_length = 0;
165663d483cdSSepherosa Ziehau 	u8 device_tech = 0;
165763d483cdSSepherosa Ziehau 	bool active_cable = FALSE;
165863d483cdSSepherosa Ziehau 
165963d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_identify_qsfp_module_generic");
166063d483cdSSepherosa Ziehau 
166163d483cdSSepherosa Ziehau 	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber_qsfp) {
166263d483cdSSepherosa Ziehau 		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
166363d483cdSSepherosa Ziehau 		status = IXGBE_ERR_SFP_NOT_PRESENT;
166463d483cdSSepherosa Ziehau 		goto out;
166563d483cdSSepherosa Ziehau 	}
166663d483cdSSepherosa Ziehau 
166763d483cdSSepherosa Ziehau 	/* LAN ID is needed for I2C access */
166863d483cdSSepherosa Ziehau 	hw->mac.ops.set_lan_id(hw);
166963d483cdSSepherosa Ziehau 
167063d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
167163d483cdSSepherosa Ziehau 					     &identifier);
167263d483cdSSepherosa Ziehau 
167363d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
167463d483cdSSepherosa Ziehau 		goto err_read_i2c_eeprom;
167563d483cdSSepherosa Ziehau 
167663d483cdSSepherosa Ziehau 	if (identifier != IXGBE_SFF_IDENTIFIER_QSFP_PLUS) {
167763d483cdSSepherosa Ziehau 		hw->phy.type = ixgbe_phy_sfp_unsupported;
167863d483cdSSepherosa Ziehau 		status = IXGBE_ERR_SFP_NOT_SUPPORTED;
167963d483cdSSepherosa Ziehau 		goto out;
168063d483cdSSepherosa Ziehau 	}
168163d483cdSSepherosa Ziehau 
168263d483cdSSepherosa Ziehau 	hw->phy.id = identifier;
168363d483cdSSepherosa Ziehau 
168463d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_10GBE_COMP,
168563d483cdSSepherosa Ziehau 					     &comp_codes_10g);
168663d483cdSSepherosa Ziehau 
168763d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
168863d483cdSSepherosa Ziehau 		goto err_read_i2c_eeprom;
168963d483cdSSepherosa Ziehau 
169063d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_1GBE_COMP,
169163d483cdSSepherosa Ziehau 					     &comp_codes_1g);
169263d483cdSSepherosa Ziehau 
169363d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
169463d483cdSSepherosa Ziehau 		goto err_read_i2c_eeprom;
169563d483cdSSepherosa Ziehau 
169663d483cdSSepherosa Ziehau 	if (comp_codes_10g & IXGBE_SFF_QSFP_DA_PASSIVE_CABLE) {
169763d483cdSSepherosa Ziehau 		hw->phy.type = ixgbe_phy_qsfp_passive_unknown;
169863d483cdSSepherosa Ziehau 		if (hw->bus.lan_id == 0)
169963d483cdSSepherosa Ziehau 			hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core0;
170063d483cdSSepherosa Ziehau 		else
170163d483cdSSepherosa Ziehau 			hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core1;
170263d483cdSSepherosa Ziehau 	} else if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE |
170363d483cdSSepherosa Ziehau 				     IXGBE_SFF_10GBASELR_CAPABLE)) {
170463d483cdSSepherosa Ziehau 		if (hw->bus.lan_id == 0)
170563d483cdSSepherosa Ziehau 			hw->phy.sfp_type = ixgbe_sfp_type_srlr_core0;
170663d483cdSSepherosa Ziehau 		else
170763d483cdSSepherosa Ziehau 			hw->phy.sfp_type = ixgbe_sfp_type_srlr_core1;
170863d483cdSSepherosa Ziehau 	} else {
170963d483cdSSepherosa Ziehau 		if (comp_codes_10g & IXGBE_SFF_QSFP_DA_ACTIVE_CABLE)
171063d483cdSSepherosa Ziehau 			active_cable = TRUE;
171163d483cdSSepherosa Ziehau 
171263d483cdSSepherosa Ziehau 		if (!active_cable) {
171363d483cdSSepherosa Ziehau 			/* check for active DA cables that pre-date
171463d483cdSSepherosa Ziehau 			 * SFF-8436 v3.6 */
171563d483cdSSepherosa Ziehau 			hw->phy.ops.read_i2c_eeprom(hw,
171663d483cdSSepherosa Ziehau 					IXGBE_SFF_QSFP_CONNECTOR,
171763d483cdSSepherosa Ziehau 					&connector);
171863d483cdSSepherosa Ziehau 
171963d483cdSSepherosa Ziehau 			hw->phy.ops.read_i2c_eeprom(hw,
172063d483cdSSepherosa Ziehau 					IXGBE_SFF_QSFP_CABLE_LENGTH,
172163d483cdSSepherosa Ziehau 					&cable_length);
172263d483cdSSepherosa Ziehau 
172363d483cdSSepherosa Ziehau 			hw->phy.ops.read_i2c_eeprom(hw,
172463d483cdSSepherosa Ziehau 					IXGBE_SFF_QSFP_DEVICE_TECH,
172563d483cdSSepherosa Ziehau 					&device_tech);
172663d483cdSSepherosa Ziehau 
172763d483cdSSepherosa Ziehau 			if ((connector ==
172863d483cdSSepherosa Ziehau 				     IXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE) &&
172963d483cdSSepherosa Ziehau 			    (cable_length > 0) &&
173063d483cdSSepherosa Ziehau 			    ((device_tech >> 4) ==
173163d483cdSSepherosa Ziehau 				     IXGBE_SFF_QSFP_TRANSMITER_850NM_VCSEL))
173263d483cdSSepherosa Ziehau 				active_cable = TRUE;
173363d483cdSSepherosa Ziehau 		}
173463d483cdSSepherosa Ziehau 
173563d483cdSSepherosa Ziehau 		if (active_cable) {
173663d483cdSSepherosa Ziehau 			hw->phy.type = ixgbe_phy_qsfp_active_unknown;
173763d483cdSSepherosa Ziehau 			if (hw->bus.lan_id == 0)
173863d483cdSSepherosa Ziehau 				hw->phy.sfp_type =
173963d483cdSSepherosa Ziehau 						ixgbe_sfp_type_da_act_lmt_core0;
174063d483cdSSepherosa Ziehau 			else
174163d483cdSSepherosa Ziehau 				hw->phy.sfp_type =
174263d483cdSSepherosa Ziehau 						ixgbe_sfp_type_da_act_lmt_core1;
174363d483cdSSepherosa Ziehau 		} else {
174463d483cdSSepherosa Ziehau 			/* unsupported module type */
174563d483cdSSepherosa Ziehau 			hw->phy.type = ixgbe_phy_sfp_unsupported;
174663d483cdSSepherosa Ziehau 			status = IXGBE_ERR_SFP_NOT_SUPPORTED;
174763d483cdSSepherosa Ziehau 			goto out;
174863d483cdSSepherosa Ziehau 		}
174963d483cdSSepherosa Ziehau 	}
175063d483cdSSepherosa Ziehau 
175163d483cdSSepherosa Ziehau 	if (hw->phy.sfp_type != stored_sfp_type)
175263d483cdSSepherosa Ziehau 		hw->phy.sfp_setup_needed = TRUE;
175363d483cdSSepherosa Ziehau 
175463d483cdSSepherosa Ziehau 	/* Determine if the QSFP+ PHY is dual speed or not. */
175563d483cdSSepherosa Ziehau 	hw->phy.multispeed_fiber = FALSE;
175663d483cdSSepherosa Ziehau 	if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
175763d483cdSSepherosa Ziehau 	   (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
175863d483cdSSepherosa Ziehau 	   ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
175963d483cdSSepherosa Ziehau 	   (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
176063d483cdSSepherosa Ziehau 		hw->phy.multispeed_fiber = TRUE;
176163d483cdSSepherosa Ziehau 
176263d483cdSSepherosa Ziehau 	/* Determine PHY vendor for optical modules */
176363d483cdSSepherosa Ziehau 	if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE |
176463d483cdSSepherosa Ziehau 			      IXGBE_SFF_10GBASELR_CAPABLE))  {
176563d483cdSSepherosa Ziehau 		status = hw->phy.ops.read_i2c_eeprom(hw,
176663d483cdSSepherosa Ziehau 					    IXGBE_SFF_QSFP_VENDOR_OUI_BYTE0,
176763d483cdSSepherosa Ziehau 					    &oui_bytes[0]);
176863d483cdSSepherosa Ziehau 
176963d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
177063d483cdSSepherosa Ziehau 			goto err_read_i2c_eeprom;
177163d483cdSSepherosa Ziehau 
177263d483cdSSepherosa Ziehau 		status = hw->phy.ops.read_i2c_eeprom(hw,
177363d483cdSSepherosa Ziehau 					    IXGBE_SFF_QSFP_VENDOR_OUI_BYTE1,
177463d483cdSSepherosa Ziehau 					    &oui_bytes[1]);
177563d483cdSSepherosa Ziehau 
177663d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
177763d483cdSSepherosa Ziehau 			goto err_read_i2c_eeprom;
177863d483cdSSepherosa Ziehau 
177963d483cdSSepherosa Ziehau 		status = hw->phy.ops.read_i2c_eeprom(hw,
178063d483cdSSepherosa Ziehau 					    IXGBE_SFF_QSFP_VENDOR_OUI_BYTE2,
178163d483cdSSepherosa Ziehau 					    &oui_bytes[2]);
178263d483cdSSepherosa Ziehau 
178363d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
178463d483cdSSepherosa Ziehau 			goto err_read_i2c_eeprom;
178563d483cdSSepherosa Ziehau 
178663d483cdSSepherosa Ziehau 		vendor_oui =
178763d483cdSSepherosa Ziehau 		  ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
178863d483cdSSepherosa Ziehau 		   (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
178963d483cdSSepherosa Ziehau 		   (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
179063d483cdSSepherosa Ziehau 
179163d483cdSSepherosa Ziehau 		if (vendor_oui == IXGBE_SFF_VENDOR_OUI_INTEL)
179263d483cdSSepherosa Ziehau 			hw->phy.type = ixgbe_phy_qsfp_intel;
179363d483cdSSepherosa Ziehau 		else
179463d483cdSSepherosa Ziehau 			hw->phy.type = ixgbe_phy_qsfp_unknown;
179563d483cdSSepherosa Ziehau 
179663d483cdSSepherosa Ziehau 		ixgbe_get_device_caps(hw, &enforce_sfp);
179763d483cdSSepherosa Ziehau 		if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
179863d483cdSSepherosa Ziehau 			/* Make sure we're a supported PHY type */
179963d483cdSSepherosa Ziehau 			if (hw->phy.type == ixgbe_phy_qsfp_intel) {
180063d483cdSSepherosa Ziehau 				status = IXGBE_SUCCESS;
180163d483cdSSepherosa Ziehau 			} else {
180263d483cdSSepherosa Ziehau 				if (hw->allow_unsupported_sfp == TRUE) {
18036150453fSSepherosa Ziehau 					EWARN(hw, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n");
180463d483cdSSepherosa Ziehau 					status = IXGBE_SUCCESS;
180563d483cdSSepherosa Ziehau 				} else {
180663d483cdSSepherosa Ziehau 					DEBUGOUT("QSFP module not supported\n");
180763d483cdSSepherosa Ziehau 					hw->phy.type =
180863d483cdSSepherosa Ziehau 						ixgbe_phy_sfp_unsupported;
180963d483cdSSepherosa Ziehau 					status = IXGBE_ERR_SFP_NOT_SUPPORTED;
181063d483cdSSepherosa Ziehau 				}
181163d483cdSSepherosa Ziehau 			}
181263d483cdSSepherosa Ziehau 		} else {
181363d483cdSSepherosa Ziehau 			status = IXGBE_SUCCESS;
181463d483cdSSepherosa Ziehau 		}
181563d483cdSSepherosa Ziehau 	}
181663d483cdSSepherosa Ziehau 
181763d483cdSSepherosa Ziehau out:
181863d483cdSSepherosa Ziehau 	return status;
181963d483cdSSepherosa Ziehau 
182063d483cdSSepherosa Ziehau err_read_i2c_eeprom:
182163d483cdSSepherosa Ziehau 	hw->phy.sfp_type = ixgbe_sfp_type_not_present;
182263d483cdSSepherosa Ziehau 	hw->phy.id = 0;
182363d483cdSSepherosa Ziehau 	hw->phy.type = ixgbe_phy_unknown;
182463d483cdSSepherosa Ziehau 
182563d483cdSSepherosa Ziehau 	return IXGBE_ERR_SFP_NOT_PRESENT;
182663d483cdSSepherosa Ziehau }
182779251f5eSSepherosa Ziehau 
182879251f5eSSepherosa Ziehau /**
182979251f5eSSepherosa Ziehau  *  ixgbe_get_sfp_init_sequence_offsets - Provides offset of PHY init sequence
183079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
183179251f5eSSepherosa Ziehau  *  @list_offset: offset to the SFP ID list
183279251f5eSSepherosa Ziehau  *  @data_offset: offset to the SFP data block
183379251f5eSSepherosa Ziehau  *
183479251f5eSSepherosa Ziehau  *  Checks the MAC's EEPROM to see if it supports a given SFP+ module type, if
183579251f5eSSepherosa Ziehau  *  so it returns the offsets to the phy init sequence block.
183679251f5eSSepherosa Ziehau  **/
ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw * hw,u16 * list_offset,u16 * data_offset)183779251f5eSSepherosa Ziehau s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
183879251f5eSSepherosa Ziehau 					u16 *list_offset,
183979251f5eSSepherosa Ziehau 					u16 *data_offset)
184079251f5eSSepherosa Ziehau {
184179251f5eSSepherosa Ziehau 	u16 sfp_id;
184279251f5eSSepherosa Ziehau 	u16 sfp_type = hw->phy.sfp_type;
184379251f5eSSepherosa Ziehau 
184479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_sfp_init_sequence_offsets");
184579251f5eSSepherosa Ziehau 
184679251f5eSSepherosa Ziehau 	if (hw->phy.sfp_type == ixgbe_sfp_type_unknown)
184779251f5eSSepherosa Ziehau 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
184879251f5eSSepherosa Ziehau 
184979251f5eSSepherosa Ziehau 	if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
185079251f5eSSepherosa Ziehau 		return IXGBE_ERR_SFP_NOT_PRESENT;
185179251f5eSSepherosa Ziehau 
185279251f5eSSepherosa Ziehau 	if ((hw->device_id == IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM) &&
185379251f5eSSepherosa Ziehau 	    (hw->phy.sfp_type == ixgbe_sfp_type_da_cu))
185479251f5eSSepherosa Ziehau 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
185579251f5eSSepherosa Ziehau 
185679251f5eSSepherosa Ziehau 	/*
185779251f5eSSepherosa Ziehau 	 * Limiting active cables and 1G Phys must be initialized as
185879251f5eSSepherosa Ziehau 	 * SR modules
185979251f5eSSepherosa Ziehau 	 */
186079251f5eSSepherosa Ziehau 	if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 ||
186163d483cdSSepherosa Ziehau 	    sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
186279251f5eSSepherosa Ziehau 	    sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
186379251f5eSSepherosa Ziehau 	    sfp_type == ixgbe_sfp_type_1g_sx_core0)
186479251f5eSSepherosa Ziehau 		sfp_type = ixgbe_sfp_type_srlr_core0;
186579251f5eSSepherosa Ziehau 	else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 ||
186663d483cdSSepherosa Ziehau 		 sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
186779251f5eSSepherosa Ziehau 		 sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
186879251f5eSSepherosa Ziehau 		 sfp_type == ixgbe_sfp_type_1g_sx_core1)
186979251f5eSSepherosa Ziehau 		sfp_type = ixgbe_sfp_type_srlr_core1;
187079251f5eSSepherosa Ziehau 
187179251f5eSSepherosa Ziehau 	/* Read offset to PHY init contents */
187279251f5eSSepherosa Ziehau 	if (hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset)) {
187379251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
187479251f5eSSepherosa Ziehau 			      "eeprom read at offset %d failed",
187579251f5eSSepherosa Ziehau 			      IXGBE_PHY_INIT_OFFSET_NL);
187679251f5eSSepherosa Ziehau 		return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
187779251f5eSSepherosa Ziehau 	}
187879251f5eSSepherosa Ziehau 
187979251f5eSSepherosa Ziehau 	if ((!*list_offset) || (*list_offset == 0xFFFF))
188079251f5eSSepherosa Ziehau 		return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
188179251f5eSSepherosa Ziehau 
188279251f5eSSepherosa Ziehau 	/* Shift offset to first ID word */
188379251f5eSSepherosa Ziehau 	(*list_offset)++;
188479251f5eSSepherosa Ziehau 
188579251f5eSSepherosa Ziehau 	/*
188679251f5eSSepherosa Ziehau 	 * Find the matching SFP ID in the EEPROM
188779251f5eSSepherosa Ziehau 	 * and program the init sequence
188879251f5eSSepherosa Ziehau 	 */
188979251f5eSSepherosa Ziehau 	if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id))
189079251f5eSSepherosa Ziehau 		goto err_phy;
189179251f5eSSepherosa Ziehau 
189279251f5eSSepherosa Ziehau 	while (sfp_id != IXGBE_PHY_INIT_END_NL) {
189379251f5eSSepherosa Ziehau 		if (sfp_id == sfp_type) {
189479251f5eSSepherosa Ziehau 			(*list_offset)++;
189579251f5eSSepherosa Ziehau 			if (hw->eeprom.ops.read(hw, *list_offset, data_offset))
189679251f5eSSepherosa Ziehau 				goto err_phy;
189779251f5eSSepherosa Ziehau 			if ((!*data_offset) || (*data_offset == 0xFFFF)) {
189879251f5eSSepherosa Ziehau 				DEBUGOUT("SFP+ module not supported\n");
189979251f5eSSepherosa Ziehau 				return IXGBE_ERR_SFP_NOT_SUPPORTED;
190079251f5eSSepherosa Ziehau 			} else {
190179251f5eSSepherosa Ziehau 				break;
190279251f5eSSepherosa Ziehau 			}
190379251f5eSSepherosa Ziehau 		} else {
190479251f5eSSepherosa Ziehau 			(*list_offset) += 2;
190579251f5eSSepherosa Ziehau 			if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id))
190679251f5eSSepherosa Ziehau 				goto err_phy;
190779251f5eSSepherosa Ziehau 		}
190879251f5eSSepherosa Ziehau 	}
190979251f5eSSepherosa Ziehau 
191079251f5eSSepherosa Ziehau 	if (sfp_id == IXGBE_PHY_INIT_END_NL) {
191179251f5eSSepherosa Ziehau 		DEBUGOUT("No matching SFP+ module found\n");
191279251f5eSSepherosa Ziehau 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
191379251f5eSSepherosa Ziehau 	}
191479251f5eSSepherosa Ziehau 
191579251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
191679251f5eSSepherosa Ziehau 
191779251f5eSSepherosa Ziehau err_phy:
191879251f5eSSepherosa Ziehau 	ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
191979251f5eSSepherosa Ziehau 		      "eeprom read at offset %d failed", *list_offset);
192079251f5eSSepherosa Ziehau 	return IXGBE_ERR_PHY;
192179251f5eSSepherosa Ziehau }
192279251f5eSSepherosa Ziehau 
192379251f5eSSepherosa Ziehau /**
192479251f5eSSepherosa Ziehau  *  ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface
192579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
192679251f5eSSepherosa Ziehau  *  @byte_offset: EEPROM byte offset to read
192779251f5eSSepherosa Ziehau  *  @eeprom_data: value read
192879251f5eSSepherosa Ziehau  *
192979251f5eSSepherosa Ziehau  *  Performs byte read operation to SFP module's EEPROM over I2C interface.
193079251f5eSSepherosa Ziehau  **/
ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw * hw,u8 byte_offset,u8 * eeprom_data)193179251f5eSSepherosa Ziehau s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
193279251f5eSSepherosa Ziehau 				  u8 *eeprom_data)
193379251f5eSSepherosa Ziehau {
193479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_i2c_eeprom_generic");
193579251f5eSSepherosa Ziehau 
193679251f5eSSepherosa Ziehau 	return hw->phy.ops.read_i2c_byte(hw, byte_offset,
193779251f5eSSepherosa Ziehau 					 IXGBE_I2C_EEPROM_DEV_ADDR,
193879251f5eSSepherosa Ziehau 					 eeprom_data);
193979251f5eSSepherosa Ziehau }
194079251f5eSSepherosa Ziehau 
194179251f5eSSepherosa Ziehau /**
194279251f5eSSepherosa Ziehau  *  ixgbe_read_i2c_sff8472_generic - Reads 8 bit word over I2C interface
194379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
194479251f5eSSepherosa Ziehau  *  @byte_offset: byte offset at address 0xA2
1945*dd5ce676SSepherosa Ziehau  *  @sff8472_data: value read
194679251f5eSSepherosa Ziehau  *
194779251f5eSSepherosa Ziehau  *  Performs byte read operation to SFP module's SFF-8472 data over I2C
194879251f5eSSepherosa Ziehau  **/
ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw * hw,u8 byte_offset,u8 * sff8472_data)194979251f5eSSepherosa Ziehau static s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
195079251f5eSSepherosa Ziehau 					  u8 *sff8472_data)
195179251f5eSSepherosa Ziehau {
195279251f5eSSepherosa Ziehau 	return hw->phy.ops.read_i2c_byte(hw, byte_offset,
195379251f5eSSepherosa Ziehau 					 IXGBE_I2C_EEPROM_DEV_ADDR2,
195479251f5eSSepherosa Ziehau 					 sff8472_data);
195579251f5eSSepherosa Ziehau }
195679251f5eSSepherosa Ziehau 
195779251f5eSSepherosa Ziehau /**
195879251f5eSSepherosa Ziehau  *  ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
195979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
196079251f5eSSepherosa Ziehau  *  @byte_offset: EEPROM byte offset to write
196179251f5eSSepherosa Ziehau  *  @eeprom_data: value to write
196279251f5eSSepherosa Ziehau  *
196379251f5eSSepherosa Ziehau  *  Performs byte write operation to SFP module's EEPROM over I2C interface.
196479251f5eSSepherosa Ziehau  **/
ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw * hw,u8 byte_offset,u8 eeprom_data)196579251f5eSSepherosa Ziehau s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
196679251f5eSSepherosa Ziehau 				   u8 eeprom_data)
196779251f5eSSepherosa Ziehau {
196879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_i2c_eeprom_generic");
196979251f5eSSepherosa Ziehau 
197079251f5eSSepherosa Ziehau 	return hw->phy.ops.write_i2c_byte(hw, byte_offset,
197179251f5eSSepherosa Ziehau 					  IXGBE_I2C_EEPROM_DEV_ADDR,
197279251f5eSSepherosa Ziehau 					  eeprom_data);
197379251f5eSSepherosa Ziehau }
197479251f5eSSepherosa Ziehau 
197579251f5eSSepherosa Ziehau /**
197663d483cdSSepherosa Ziehau  * ixgbe_is_sfp_probe - Returns TRUE if SFP is being detected
197763d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
197863d483cdSSepherosa Ziehau  * @offset: eeprom offset to be read
197963d483cdSSepherosa Ziehau  * @addr: I2C address to be read
198063d483cdSSepherosa Ziehau  */
ixgbe_is_sfp_probe(struct ixgbe_hw * hw,u8 offset,u8 addr)198163d483cdSSepherosa Ziehau static bool ixgbe_is_sfp_probe(struct ixgbe_hw *hw, u8 offset, u8 addr)
198263d483cdSSepherosa Ziehau {
198363d483cdSSepherosa Ziehau 	if (addr == IXGBE_I2C_EEPROM_DEV_ADDR &&
198463d483cdSSepherosa Ziehau 	    offset == IXGBE_SFF_IDENTIFIER &&
198563d483cdSSepherosa Ziehau 	    hw->phy.sfp_type == ixgbe_sfp_type_not_present)
198663d483cdSSepherosa Ziehau 		return TRUE;
198763d483cdSSepherosa Ziehau 	return FALSE;
198863d483cdSSepherosa Ziehau }
198963d483cdSSepherosa Ziehau 
199063d483cdSSepherosa Ziehau /**
199163d483cdSSepherosa Ziehau  *  ixgbe_read_i2c_byte_generic_int - Reads 8 bit word over I2C
199279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
199379251f5eSSepherosa Ziehau  *  @byte_offset: byte offset to read
1994*dd5ce676SSepherosa Ziehau  *  @dev_addr: address to read from
199579251f5eSSepherosa Ziehau  *  @data: value read
199663d483cdSSepherosa Ziehau  *  @lock: TRUE if to take and release semaphore
199779251f5eSSepherosa Ziehau  *
199879251f5eSSepherosa Ziehau  *  Performs byte read operation to SFP module's EEPROM over I2C interface at
199979251f5eSSepherosa Ziehau  *  a specified device address.
200079251f5eSSepherosa Ziehau  **/
ixgbe_read_i2c_byte_generic_int(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 * data,bool lock)200163d483cdSSepherosa Ziehau static s32 ixgbe_read_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset,
200263d483cdSSepherosa Ziehau 					   u8 dev_addr, u8 *data, bool lock)
200379251f5eSSepherosa Ziehau {
200463d483cdSSepherosa Ziehau 	s32 status;
200579251f5eSSepherosa Ziehau 	u32 max_retry = 10;
200679251f5eSSepherosa Ziehau 	u32 retry = 0;
200763d483cdSSepherosa Ziehau 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
200879251f5eSSepherosa Ziehau 	bool nack = 1;
200979251f5eSSepherosa Ziehau 	*data = 0;
201079251f5eSSepherosa Ziehau 
201179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_i2c_byte_generic");
201279251f5eSSepherosa Ziehau 
201363d483cdSSepherosa Ziehau 	if (hw->mac.type >= ixgbe_mac_X550)
201463d483cdSSepherosa Ziehau 		max_retry = 3;
201563d483cdSSepherosa Ziehau 	if (ixgbe_is_sfp_probe(hw, byte_offset, dev_addr))
201663d483cdSSepherosa Ziehau 		max_retry = IXGBE_SFP_DETECT_RETRIES;
201779251f5eSSepherosa Ziehau 
201879251f5eSSepherosa Ziehau 	do {
201963d483cdSSepherosa Ziehau 		if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
202063d483cdSSepherosa Ziehau 			return IXGBE_ERR_SWFW_SYNC;
202179251f5eSSepherosa Ziehau 
202279251f5eSSepherosa Ziehau 		ixgbe_i2c_start(hw);
202379251f5eSSepherosa Ziehau 
202479251f5eSSepherosa Ziehau 		/* Device Address and write indication */
202579251f5eSSepherosa Ziehau 		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
202679251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
202779251f5eSSepherosa Ziehau 			goto fail;
202879251f5eSSepherosa Ziehau 
202979251f5eSSepherosa Ziehau 		status = ixgbe_get_i2c_ack(hw);
203079251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
203179251f5eSSepherosa Ziehau 			goto fail;
203279251f5eSSepherosa Ziehau 
203379251f5eSSepherosa Ziehau 		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
203479251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
203579251f5eSSepherosa Ziehau 			goto fail;
203679251f5eSSepherosa Ziehau 
203779251f5eSSepherosa Ziehau 		status = ixgbe_get_i2c_ack(hw);
203879251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
203979251f5eSSepherosa Ziehau 			goto fail;
204079251f5eSSepherosa Ziehau 
204179251f5eSSepherosa Ziehau 		ixgbe_i2c_start(hw);
204279251f5eSSepherosa Ziehau 
204379251f5eSSepherosa Ziehau 		/* Device Address and read indication */
204479251f5eSSepherosa Ziehau 		status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1));
204579251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
204679251f5eSSepherosa Ziehau 			goto fail;
204779251f5eSSepherosa Ziehau 
204879251f5eSSepherosa Ziehau 		status = ixgbe_get_i2c_ack(hw);
204979251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
205079251f5eSSepherosa Ziehau 			goto fail;
205179251f5eSSepherosa Ziehau 
205279251f5eSSepherosa Ziehau 		status = ixgbe_clock_in_i2c_byte(hw, data);
205379251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
205479251f5eSSepherosa Ziehau 			goto fail;
205579251f5eSSepherosa Ziehau 
205679251f5eSSepherosa Ziehau 		status = ixgbe_clock_out_i2c_bit(hw, nack);
205779251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
205879251f5eSSepherosa Ziehau 			goto fail;
205979251f5eSSepherosa Ziehau 
206079251f5eSSepherosa Ziehau 		ixgbe_i2c_stop(hw);
206163d483cdSSepherosa Ziehau 		if (lock)
206263d483cdSSepherosa Ziehau 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
206363d483cdSSepherosa Ziehau 		return IXGBE_SUCCESS;
206479251f5eSSepherosa Ziehau 
206579251f5eSSepherosa Ziehau fail:
206679251f5eSSepherosa Ziehau 		ixgbe_i2c_bus_clear(hw);
206763d483cdSSepherosa Ziehau 		if (lock) {
206879251f5eSSepherosa Ziehau 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
206979251f5eSSepherosa Ziehau 			msec_delay(100);
207063d483cdSSepherosa Ziehau 		}
207179251f5eSSepherosa Ziehau 		retry++;
207279251f5eSSepherosa Ziehau 		if (retry < max_retry)
207379251f5eSSepherosa Ziehau 			DEBUGOUT("I2C byte read error - Retrying.\n");
207479251f5eSSepherosa Ziehau 		else
207579251f5eSSepherosa Ziehau 			DEBUGOUT("I2C byte read error.\n");
207679251f5eSSepherosa Ziehau 
207779251f5eSSepherosa Ziehau 	} while (retry < max_retry);
207879251f5eSSepherosa Ziehau 
207979251f5eSSepherosa Ziehau 	return status;
208079251f5eSSepherosa Ziehau }
208179251f5eSSepherosa Ziehau 
208279251f5eSSepherosa Ziehau /**
208363d483cdSSepherosa Ziehau  *  ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
208463d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
208563d483cdSSepherosa Ziehau  *  @byte_offset: byte offset to read
2086*dd5ce676SSepherosa Ziehau  *  @dev_addr: address to read from
208763d483cdSSepherosa Ziehau  *  @data: value read
208863d483cdSSepherosa Ziehau  *
208963d483cdSSepherosa Ziehau  *  Performs byte read operation to SFP module's EEPROM over I2C interface at
209063d483cdSSepherosa Ziehau  *  a specified device address.
209163d483cdSSepherosa Ziehau  **/
ixgbe_read_i2c_byte_generic(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 * data)209263d483cdSSepherosa Ziehau s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
209363d483cdSSepherosa Ziehau 				u8 dev_addr, u8 *data)
209463d483cdSSepherosa Ziehau {
209563d483cdSSepherosa Ziehau 	return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr,
209663d483cdSSepherosa Ziehau 					       data, TRUE);
209763d483cdSSepherosa Ziehau }
209863d483cdSSepherosa Ziehau 
209963d483cdSSepherosa Ziehau /**
210063d483cdSSepherosa Ziehau  *  ixgbe_read_i2c_byte_generic_unlocked - Reads 8 bit word over I2C
210163d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
210263d483cdSSepherosa Ziehau  *  @byte_offset: byte offset to read
2103*dd5ce676SSepherosa Ziehau  *  @dev_addr: address to read from
210463d483cdSSepherosa Ziehau  *  @data: value read
210563d483cdSSepherosa Ziehau  *
210663d483cdSSepherosa Ziehau  *  Performs byte read operation to SFP module's EEPROM over I2C interface at
210763d483cdSSepherosa Ziehau  *  a specified device address.
210863d483cdSSepherosa Ziehau  **/
ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 * data)210963d483cdSSepherosa Ziehau s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
211063d483cdSSepherosa Ziehau 					 u8 dev_addr, u8 *data)
211163d483cdSSepherosa Ziehau {
211263d483cdSSepherosa Ziehau 	return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr,
211363d483cdSSepherosa Ziehau 					       data, FALSE);
211463d483cdSSepherosa Ziehau }
211563d483cdSSepherosa Ziehau 
211663d483cdSSepherosa Ziehau /**
211763d483cdSSepherosa Ziehau  *  ixgbe_write_i2c_byte_generic_int - Writes 8 bit word over I2C
211879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
211979251f5eSSepherosa Ziehau  *  @byte_offset: byte offset to write
2120*dd5ce676SSepherosa Ziehau  *  @dev_addr: address to write to
212179251f5eSSepherosa Ziehau  *  @data: value to write
212263d483cdSSepherosa Ziehau  *  @lock: TRUE if to take and release semaphore
212379251f5eSSepherosa Ziehau  *
212479251f5eSSepherosa Ziehau  *  Performs byte write operation to SFP module's EEPROM over I2C interface at
212579251f5eSSepherosa Ziehau  *  a specified device address.
212679251f5eSSepherosa Ziehau  **/
ixgbe_write_i2c_byte_generic_int(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 data,bool lock)212763d483cdSSepherosa Ziehau static s32 ixgbe_write_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset,
212863d483cdSSepherosa Ziehau 					    u8 dev_addr, u8 data, bool lock)
212979251f5eSSepherosa Ziehau {
213063d483cdSSepherosa Ziehau 	s32 status;
213179251f5eSSepherosa Ziehau 	u32 max_retry = 1;
213279251f5eSSepherosa Ziehau 	u32 retry = 0;
213363d483cdSSepherosa Ziehau 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
213479251f5eSSepherosa Ziehau 
213579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_i2c_byte_generic");
213679251f5eSSepherosa Ziehau 
213763d483cdSSepherosa Ziehau 	if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) !=
213863d483cdSSepherosa Ziehau 	    IXGBE_SUCCESS)
213963d483cdSSepherosa Ziehau 		return IXGBE_ERR_SWFW_SYNC;
214079251f5eSSepherosa Ziehau 
214179251f5eSSepherosa Ziehau 	do {
214279251f5eSSepherosa Ziehau 		ixgbe_i2c_start(hw);
214379251f5eSSepherosa Ziehau 
214479251f5eSSepherosa Ziehau 		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
214579251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
214679251f5eSSepherosa Ziehau 			goto fail;
214779251f5eSSepherosa Ziehau 
214879251f5eSSepherosa Ziehau 		status = ixgbe_get_i2c_ack(hw);
214979251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
215079251f5eSSepherosa Ziehau 			goto fail;
215179251f5eSSepherosa Ziehau 
215279251f5eSSepherosa Ziehau 		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
215379251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
215479251f5eSSepherosa Ziehau 			goto fail;
215579251f5eSSepherosa Ziehau 
215679251f5eSSepherosa Ziehau 		status = ixgbe_get_i2c_ack(hw);
215779251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
215879251f5eSSepherosa Ziehau 			goto fail;
215979251f5eSSepherosa Ziehau 
216079251f5eSSepherosa Ziehau 		status = ixgbe_clock_out_i2c_byte(hw, data);
216179251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
216279251f5eSSepherosa Ziehau 			goto fail;
216379251f5eSSepherosa Ziehau 
216479251f5eSSepherosa Ziehau 		status = ixgbe_get_i2c_ack(hw);
216579251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
216679251f5eSSepherosa Ziehau 			goto fail;
216779251f5eSSepherosa Ziehau 
216879251f5eSSepherosa Ziehau 		ixgbe_i2c_stop(hw);
216963d483cdSSepherosa Ziehau 		if (lock)
217063d483cdSSepherosa Ziehau 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
217163d483cdSSepherosa Ziehau 		return IXGBE_SUCCESS;
217279251f5eSSepherosa Ziehau 
217379251f5eSSepherosa Ziehau fail:
217479251f5eSSepherosa Ziehau 		ixgbe_i2c_bus_clear(hw);
217579251f5eSSepherosa Ziehau 		retry++;
217679251f5eSSepherosa Ziehau 		if (retry < max_retry)
217779251f5eSSepherosa Ziehau 			DEBUGOUT("I2C byte write error - Retrying.\n");
217879251f5eSSepherosa Ziehau 		else
217979251f5eSSepherosa Ziehau 			DEBUGOUT("I2C byte write error.\n");
218079251f5eSSepherosa Ziehau 	} while (retry < max_retry);
218179251f5eSSepherosa Ziehau 
218263d483cdSSepherosa Ziehau 	if (lock)
218379251f5eSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
218479251f5eSSepherosa Ziehau 
218579251f5eSSepherosa Ziehau 	return status;
218679251f5eSSepherosa Ziehau }
218779251f5eSSepherosa Ziehau 
218879251f5eSSepherosa Ziehau /**
218963d483cdSSepherosa Ziehau  *  ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
219063d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
219163d483cdSSepherosa Ziehau  *  @byte_offset: byte offset to write
2192*dd5ce676SSepherosa Ziehau  *  @dev_addr: address to write to
219363d483cdSSepherosa Ziehau  *  @data: value to write
219463d483cdSSepherosa Ziehau  *
219563d483cdSSepherosa Ziehau  *  Performs byte write operation to SFP module's EEPROM over I2C interface at
219663d483cdSSepherosa Ziehau  *  a specified device address.
219763d483cdSSepherosa Ziehau  **/
ixgbe_write_i2c_byte_generic(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 data)219863d483cdSSepherosa Ziehau s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
219963d483cdSSepherosa Ziehau 				 u8 dev_addr, u8 data)
220063d483cdSSepherosa Ziehau {
220163d483cdSSepherosa Ziehau 	return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr,
220263d483cdSSepherosa Ziehau 						data, TRUE);
220363d483cdSSepherosa Ziehau }
220463d483cdSSepherosa Ziehau 
220563d483cdSSepherosa Ziehau /**
220663d483cdSSepherosa Ziehau  *  ixgbe_write_i2c_byte_generic_unlocked - Writes 8 bit word over I2C
220763d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
220863d483cdSSepherosa Ziehau  *  @byte_offset: byte offset to write
2209*dd5ce676SSepherosa Ziehau  *  @dev_addr: address to write to
221063d483cdSSepherosa Ziehau  *  @data: value to write
221163d483cdSSepherosa Ziehau  *
221263d483cdSSepherosa Ziehau  *  Performs byte write operation to SFP module's EEPROM over I2C interface at
221363d483cdSSepherosa Ziehau  *  a specified device address.
221463d483cdSSepherosa Ziehau  **/
ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 data)221563d483cdSSepherosa Ziehau s32 ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
221663d483cdSSepherosa Ziehau 					  u8 dev_addr, u8 data)
221763d483cdSSepherosa Ziehau {
221863d483cdSSepherosa Ziehau 	return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr,
221963d483cdSSepherosa Ziehau 						data, FALSE);
222063d483cdSSepherosa Ziehau }
222163d483cdSSepherosa Ziehau 
222263d483cdSSepherosa Ziehau /**
222379251f5eSSepherosa Ziehau  *  ixgbe_i2c_start - Sets I2C start condition
222479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
222579251f5eSSepherosa Ziehau  *
222679251f5eSSepherosa Ziehau  *  Sets I2C start condition (High -> Low on SDA while SCL is High)
222763d483cdSSepherosa Ziehau  *  Set bit-bang mode on X550 hardware.
222879251f5eSSepherosa Ziehau  **/
ixgbe_i2c_start(struct ixgbe_hw * hw)222979251f5eSSepherosa Ziehau static void ixgbe_i2c_start(struct ixgbe_hw *hw)
223079251f5eSSepherosa Ziehau {
223163d483cdSSepherosa Ziehau 	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
223279251f5eSSepherosa Ziehau 
223379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_i2c_start");
223479251f5eSSepherosa Ziehau 
223563d483cdSSepherosa Ziehau 	i2cctl |= IXGBE_I2C_BB_EN_BY_MAC(hw);
223663d483cdSSepherosa Ziehau 
223779251f5eSSepherosa Ziehau 	/* Start condition must begin with data and clock high */
223879251f5eSSepherosa Ziehau 	ixgbe_set_i2c_data(hw, &i2cctl, 1);
223979251f5eSSepherosa Ziehau 	ixgbe_raise_i2c_clk(hw, &i2cctl);
224079251f5eSSepherosa Ziehau 
224179251f5eSSepherosa Ziehau 	/* Setup time for start condition (4.7us) */
224279251f5eSSepherosa Ziehau 	usec_delay(IXGBE_I2C_T_SU_STA);
224379251f5eSSepherosa Ziehau 
224479251f5eSSepherosa Ziehau 	ixgbe_set_i2c_data(hw, &i2cctl, 0);
224579251f5eSSepherosa Ziehau 
224679251f5eSSepherosa Ziehau 	/* Hold time for start condition (4us) */
224779251f5eSSepherosa Ziehau 	usec_delay(IXGBE_I2C_T_HD_STA);
224879251f5eSSepherosa Ziehau 
224979251f5eSSepherosa Ziehau 	ixgbe_lower_i2c_clk(hw, &i2cctl);
225079251f5eSSepherosa Ziehau 
225179251f5eSSepherosa Ziehau 	/* Minimum low period of clock is 4.7 us */
225279251f5eSSepherosa Ziehau 	usec_delay(IXGBE_I2C_T_LOW);
225379251f5eSSepherosa Ziehau 
225479251f5eSSepherosa Ziehau }
225579251f5eSSepherosa Ziehau 
225679251f5eSSepherosa Ziehau /**
225779251f5eSSepherosa Ziehau  *  ixgbe_i2c_stop - Sets I2C stop condition
225879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
225979251f5eSSepherosa Ziehau  *
226079251f5eSSepherosa Ziehau  *  Sets I2C stop condition (Low -> High on SDA while SCL is High)
226163d483cdSSepherosa Ziehau  *  Disables bit-bang mode and negates data output enable on X550
226263d483cdSSepherosa Ziehau  *  hardware.
226379251f5eSSepherosa Ziehau  **/
ixgbe_i2c_stop(struct ixgbe_hw * hw)226479251f5eSSepherosa Ziehau static void ixgbe_i2c_stop(struct ixgbe_hw *hw)
226579251f5eSSepherosa Ziehau {
226663d483cdSSepherosa Ziehau 	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
226763d483cdSSepherosa Ziehau 	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
226863d483cdSSepherosa Ziehau 	u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw);
226963d483cdSSepherosa Ziehau 	u32 bb_en_bit = IXGBE_I2C_BB_EN_BY_MAC(hw);
227079251f5eSSepherosa Ziehau 
227179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_i2c_stop");
227279251f5eSSepherosa Ziehau 
227379251f5eSSepherosa Ziehau 	/* Stop condition must begin with data low and clock high */
227479251f5eSSepherosa Ziehau 	ixgbe_set_i2c_data(hw, &i2cctl, 0);
227579251f5eSSepherosa Ziehau 	ixgbe_raise_i2c_clk(hw, &i2cctl);
227679251f5eSSepherosa Ziehau 
227779251f5eSSepherosa Ziehau 	/* Setup time for stop condition (4us) */
227879251f5eSSepherosa Ziehau 	usec_delay(IXGBE_I2C_T_SU_STO);
227979251f5eSSepherosa Ziehau 
228079251f5eSSepherosa Ziehau 	ixgbe_set_i2c_data(hw, &i2cctl, 1);
228179251f5eSSepherosa Ziehau 
228279251f5eSSepherosa Ziehau 	/* bus free time between stop and start (4.7us)*/
228379251f5eSSepherosa Ziehau 	usec_delay(IXGBE_I2C_T_BUF);
228463d483cdSSepherosa Ziehau 
228563d483cdSSepherosa Ziehau 	if (bb_en_bit || data_oe_bit || clk_oe_bit) {
228663d483cdSSepherosa Ziehau 		i2cctl &= ~bb_en_bit;
228763d483cdSSepherosa Ziehau 		i2cctl |= data_oe_bit | clk_oe_bit;
228863d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl);
228963d483cdSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
229063d483cdSSepherosa Ziehau 	}
229179251f5eSSepherosa Ziehau }
229279251f5eSSepherosa Ziehau 
229379251f5eSSepherosa Ziehau /**
229479251f5eSSepherosa Ziehau  *  ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C
229579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
229679251f5eSSepherosa Ziehau  *  @data: data byte to clock in
229779251f5eSSepherosa Ziehau  *
229879251f5eSSepherosa Ziehau  *  Clocks in one byte data via I2C data/clock
229979251f5eSSepherosa Ziehau  **/
ixgbe_clock_in_i2c_byte(struct ixgbe_hw * hw,u8 * data)230079251f5eSSepherosa Ziehau static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
230179251f5eSSepherosa Ziehau {
230279251f5eSSepherosa Ziehau 	s32 i;
230379251f5eSSepherosa Ziehau 	bool bit = 0;
230479251f5eSSepherosa Ziehau 
230579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_clock_in_i2c_byte");
230679251f5eSSepherosa Ziehau 
230763d483cdSSepherosa Ziehau 	*data = 0;
230879251f5eSSepherosa Ziehau 	for (i = 7; i >= 0; i--) {
230979251f5eSSepherosa Ziehau 		ixgbe_clock_in_i2c_bit(hw, &bit);
231079251f5eSSepherosa Ziehau 		*data |= bit << i;
231179251f5eSSepherosa Ziehau 	}
231279251f5eSSepherosa Ziehau 
231379251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
231479251f5eSSepherosa Ziehau }
231579251f5eSSepherosa Ziehau 
231679251f5eSSepherosa Ziehau /**
231779251f5eSSepherosa Ziehau  *  ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C
231879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
231979251f5eSSepherosa Ziehau  *  @data: data byte clocked out
232079251f5eSSepherosa Ziehau  *
232179251f5eSSepherosa Ziehau  *  Clocks out one byte data via I2C data/clock
232279251f5eSSepherosa Ziehau  **/
ixgbe_clock_out_i2c_byte(struct ixgbe_hw * hw,u8 data)232379251f5eSSepherosa Ziehau static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
232479251f5eSSepherosa Ziehau {
232579251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
232679251f5eSSepherosa Ziehau 	s32 i;
232779251f5eSSepherosa Ziehau 	u32 i2cctl;
232863d483cdSSepherosa Ziehau 	bool bit;
232979251f5eSSepherosa Ziehau 
233079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_clock_out_i2c_byte");
233179251f5eSSepherosa Ziehau 
233279251f5eSSepherosa Ziehau 	for (i = 7; i >= 0; i--) {
233379251f5eSSepherosa Ziehau 		bit = (data >> i) & 0x1;
233479251f5eSSepherosa Ziehau 		status = ixgbe_clock_out_i2c_bit(hw, bit);
233579251f5eSSepherosa Ziehau 
233679251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
233779251f5eSSepherosa Ziehau 			break;
233879251f5eSSepherosa Ziehau 	}
233979251f5eSSepherosa Ziehau 
234079251f5eSSepherosa Ziehau 	/* Release SDA line (set high) */
234163d483cdSSepherosa Ziehau 	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
234263d483cdSSepherosa Ziehau 	i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw);
234363d483cdSSepherosa Ziehau 	i2cctl |= IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
234463d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl);
234579251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
234679251f5eSSepherosa Ziehau 
234779251f5eSSepherosa Ziehau 	return status;
234879251f5eSSepherosa Ziehau }
234979251f5eSSepherosa Ziehau 
235079251f5eSSepherosa Ziehau /**
235179251f5eSSepherosa Ziehau  *  ixgbe_get_i2c_ack - Polls for I2C ACK
235279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
235379251f5eSSepherosa Ziehau  *
235479251f5eSSepherosa Ziehau  *  Clocks in/out one bit via I2C data/clock
235579251f5eSSepherosa Ziehau  **/
ixgbe_get_i2c_ack(struct ixgbe_hw * hw)235679251f5eSSepherosa Ziehau static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
235779251f5eSSepherosa Ziehau {
235863d483cdSSepherosa Ziehau 	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
235979251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
236079251f5eSSepherosa Ziehau 	u32 i = 0;
236163d483cdSSepherosa Ziehau 	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
236279251f5eSSepherosa Ziehau 	u32 timeout = 10;
236379251f5eSSepherosa Ziehau 	bool ack = 1;
236479251f5eSSepherosa Ziehau 
236579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_i2c_ack");
236679251f5eSSepherosa Ziehau 
236763d483cdSSepherosa Ziehau 	if (data_oe_bit) {
236863d483cdSSepherosa Ziehau 		i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw);
236963d483cdSSepherosa Ziehau 		i2cctl |= data_oe_bit;
237063d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl);
237163d483cdSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
237263d483cdSSepherosa Ziehau 	}
237379251f5eSSepherosa Ziehau 	ixgbe_raise_i2c_clk(hw, &i2cctl);
237479251f5eSSepherosa Ziehau 
237579251f5eSSepherosa Ziehau 	/* Minimum high period of clock is 4us */
237679251f5eSSepherosa Ziehau 	usec_delay(IXGBE_I2C_T_HIGH);
237779251f5eSSepherosa Ziehau 
237879251f5eSSepherosa Ziehau 	/* Poll for ACK.  Note that ACK in I2C spec is
237979251f5eSSepherosa Ziehau 	 * transition from 1 to 0 */
238079251f5eSSepherosa Ziehau 	for (i = 0; i < timeout; i++) {
238163d483cdSSepherosa Ziehau 		i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
238263d483cdSSepherosa Ziehau 		ack = ixgbe_get_i2c_data(hw, &i2cctl);
238379251f5eSSepherosa Ziehau 
238479251f5eSSepherosa Ziehau 		usec_delay(1);
238563d483cdSSepherosa Ziehau 		if (!ack)
238679251f5eSSepherosa Ziehau 			break;
238779251f5eSSepherosa Ziehau 	}
238879251f5eSSepherosa Ziehau 
238963d483cdSSepherosa Ziehau 	if (ack) {
239063d483cdSSepherosa Ziehau 		DEBUGOUT("I2C ack was not received.\n");
239179251f5eSSepherosa Ziehau 		status = IXGBE_ERR_I2C;
239279251f5eSSepherosa Ziehau 	}
239379251f5eSSepherosa Ziehau 
239479251f5eSSepherosa Ziehau 	ixgbe_lower_i2c_clk(hw, &i2cctl);
239579251f5eSSepherosa Ziehau 
239679251f5eSSepherosa Ziehau 	/* Minimum low period of clock is 4.7 us */
239779251f5eSSepherosa Ziehau 	usec_delay(IXGBE_I2C_T_LOW);
239879251f5eSSepherosa Ziehau 
239979251f5eSSepherosa Ziehau 	return status;
240079251f5eSSepherosa Ziehau }
240179251f5eSSepherosa Ziehau 
240279251f5eSSepherosa Ziehau /**
240379251f5eSSepherosa Ziehau  *  ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
240479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
240579251f5eSSepherosa Ziehau  *  @data: read data value
240679251f5eSSepherosa Ziehau  *
240779251f5eSSepherosa Ziehau  *  Clocks in one bit via I2C data/clock
240879251f5eSSepherosa Ziehau  **/
ixgbe_clock_in_i2c_bit(struct ixgbe_hw * hw,bool * data)240979251f5eSSepherosa Ziehau static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
241079251f5eSSepherosa Ziehau {
241163d483cdSSepherosa Ziehau 	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
241263d483cdSSepherosa Ziehau 	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
241379251f5eSSepherosa Ziehau 
241479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_clock_in_i2c_bit");
241579251f5eSSepherosa Ziehau 
241663d483cdSSepherosa Ziehau 	if (data_oe_bit) {
241763d483cdSSepherosa Ziehau 		i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw);
241863d483cdSSepherosa Ziehau 		i2cctl |= data_oe_bit;
241963d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl);
242063d483cdSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
242163d483cdSSepherosa Ziehau 	}
242279251f5eSSepherosa Ziehau 	ixgbe_raise_i2c_clk(hw, &i2cctl);
242379251f5eSSepherosa Ziehau 
242479251f5eSSepherosa Ziehau 	/* Minimum high period of clock is 4us */
242579251f5eSSepherosa Ziehau 	usec_delay(IXGBE_I2C_T_HIGH);
242679251f5eSSepherosa Ziehau 
242763d483cdSSepherosa Ziehau 	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
242863d483cdSSepherosa Ziehau 	*data = ixgbe_get_i2c_data(hw, &i2cctl);
242979251f5eSSepherosa Ziehau 
243079251f5eSSepherosa Ziehau 	ixgbe_lower_i2c_clk(hw, &i2cctl);
243179251f5eSSepherosa Ziehau 
243279251f5eSSepherosa Ziehau 	/* Minimum low period of clock is 4.7 us */
243379251f5eSSepherosa Ziehau 	usec_delay(IXGBE_I2C_T_LOW);
243479251f5eSSepherosa Ziehau 
243579251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
243679251f5eSSepherosa Ziehau }
243779251f5eSSepherosa Ziehau 
243879251f5eSSepherosa Ziehau /**
243979251f5eSSepherosa Ziehau  *  ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
244079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
244179251f5eSSepherosa Ziehau  *  @data: data value to write
244279251f5eSSepherosa Ziehau  *
244379251f5eSSepherosa Ziehau  *  Clocks out one bit via I2C data/clock
244479251f5eSSepherosa Ziehau  **/
ixgbe_clock_out_i2c_bit(struct ixgbe_hw * hw,bool data)244579251f5eSSepherosa Ziehau static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
244679251f5eSSepherosa Ziehau {
244779251f5eSSepherosa Ziehau 	s32 status;
244863d483cdSSepherosa Ziehau 	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
244979251f5eSSepherosa Ziehau 
245079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_clock_out_i2c_bit");
245179251f5eSSepherosa Ziehau 
245279251f5eSSepherosa Ziehau 	status = ixgbe_set_i2c_data(hw, &i2cctl, data);
245379251f5eSSepherosa Ziehau 	if (status == IXGBE_SUCCESS) {
245479251f5eSSepherosa Ziehau 		ixgbe_raise_i2c_clk(hw, &i2cctl);
245579251f5eSSepherosa Ziehau 
245679251f5eSSepherosa Ziehau 		/* Minimum high period of clock is 4us */
245779251f5eSSepherosa Ziehau 		usec_delay(IXGBE_I2C_T_HIGH);
245879251f5eSSepherosa Ziehau 
245979251f5eSSepherosa Ziehau 		ixgbe_lower_i2c_clk(hw, &i2cctl);
246079251f5eSSepherosa Ziehau 
246179251f5eSSepherosa Ziehau 		/* Minimum low period of clock is 4.7 us.
246279251f5eSSepherosa Ziehau 		 * This also takes care of the data hold time.
246379251f5eSSepherosa Ziehau 		 */
246479251f5eSSepherosa Ziehau 		usec_delay(IXGBE_I2C_T_LOW);
246579251f5eSSepherosa Ziehau 	} else {
246679251f5eSSepherosa Ziehau 		status = IXGBE_ERR_I2C;
246779251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
246879251f5eSSepherosa Ziehau 			     "I2C data was not set to %X\n", data);
246979251f5eSSepherosa Ziehau 	}
247079251f5eSSepherosa Ziehau 
247179251f5eSSepherosa Ziehau 	return status;
247279251f5eSSepherosa Ziehau }
247363d483cdSSepherosa Ziehau 
247479251f5eSSepherosa Ziehau /**
247579251f5eSSepherosa Ziehau  *  ixgbe_raise_i2c_clk - Raises the I2C SCL clock
247679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
247779251f5eSSepherosa Ziehau  *  @i2cctl: Current value of I2CCTL register
247879251f5eSSepherosa Ziehau  *
247979251f5eSSepherosa Ziehau  *  Raises the I2C clock line '0'->'1'
248063d483cdSSepherosa Ziehau  *  Negates the I2C clock output enable on X550 hardware.
248179251f5eSSepherosa Ziehau  **/
ixgbe_raise_i2c_clk(struct ixgbe_hw * hw,u32 * i2cctl)248279251f5eSSepherosa Ziehau static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
248379251f5eSSepherosa Ziehau {
248463d483cdSSepherosa Ziehau 	u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw);
248579251f5eSSepherosa Ziehau 	u32 i = 0;
248679251f5eSSepherosa Ziehau 	u32 timeout = IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT;
248779251f5eSSepherosa Ziehau 	u32 i2cctl_r = 0;
248879251f5eSSepherosa Ziehau 
248979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_raise_i2c_clk");
249079251f5eSSepherosa Ziehau 
249163d483cdSSepherosa Ziehau 	if (clk_oe_bit) {
249263d483cdSSepherosa Ziehau 		*i2cctl |= clk_oe_bit;
249363d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
249463d483cdSSepherosa Ziehau 	}
249579251f5eSSepherosa Ziehau 
249663d483cdSSepherosa Ziehau 	for (i = 0; i < timeout; i++) {
249763d483cdSSepherosa Ziehau 		*i2cctl |= IXGBE_I2C_CLK_OUT_BY_MAC(hw);
249863d483cdSSepherosa Ziehau 
249963d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
250079251f5eSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
250179251f5eSSepherosa Ziehau 		/* SCL rise time (1000ns) */
250279251f5eSSepherosa Ziehau 		usec_delay(IXGBE_I2C_T_RISE);
250379251f5eSSepherosa Ziehau 
250463d483cdSSepherosa Ziehau 		i2cctl_r = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
250563d483cdSSepherosa Ziehau 		if (i2cctl_r & IXGBE_I2C_CLK_IN_BY_MAC(hw))
250679251f5eSSepherosa Ziehau 			break;
250779251f5eSSepherosa Ziehau 	}
250879251f5eSSepherosa Ziehau }
250979251f5eSSepherosa Ziehau 
251079251f5eSSepherosa Ziehau /**
251179251f5eSSepherosa Ziehau  *  ixgbe_lower_i2c_clk - Lowers the I2C SCL clock
251279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
251379251f5eSSepherosa Ziehau  *  @i2cctl: Current value of I2CCTL register
251479251f5eSSepherosa Ziehau  *
251579251f5eSSepherosa Ziehau  *  Lowers the I2C clock line '1'->'0'
251663d483cdSSepherosa Ziehau  *  Asserts the I2C clock output enable on X550 hardware.
251779251f5eSSepherosa Ziehau  **/
ixgbe_lower_i2c_clk(struct ixgbe_hw * hw,u32 * i2cctl)251879251f5eSSepherosa Ziehau static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
251979251f5eSSepherosa Ziehau {
252079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_lower_i2c_clk");
252179251f5eSSepherosa Ziehau 
252263d483cdSSepherosa Ziehau 	*i2cctl &= ~(IXGBE_I2C_CLK_OUT_BY_MAC(hw));
252363d483cdSSepherosa Ziehau 	*i2cctl &= ~IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw);
252479251f5eSSepherosa Ziehau 
252563d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
252679251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
252779251f5eSSepherosa Ziehau 
252879251f5eSSepherosa Ziehau 	/* SCL fall time (300ns) */
252979251f5eSSepherosa Ziehau 	usec_delay(IXGBE_I2C_T_FALL);
253079251f5eSSepherosa Ziehau }
253179251f5eSSepherosa Ziehau 
253279251f5eSSepherosa Ziehau /**
253379251f5eSSepherosa Ziehau  *  ixgbe_set_i2c_data - Sets the I2C data bit
253479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
253579251f5eSSepherosa Ziehau  *  @i2cctl: Current value of I2CCTL register
253679251f5eSSepherosa Ziehau  *  @data: I2C data value (0 or 1) to set
253779251f5eSSepherosa Ziehau  *
253879251f5eSSepherosa Ziehau  *  Sets the I2C data bit
253963d483cdSSepherosa Ziehau  *  Asserts the I2C data output enable on X550 hardware.
254079251f5eSSepherosa Ziehau  **/
ixgbe_set_i2c_data(struct ixgbe_hw * hw,u32 * i2cctl,bool data)254179251f5eSSepherosa Ziehau static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
254279251f5eSSepherosa Ziehau {
254363d483cdSSepherosa Ziehau 	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
254479251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
254579251f5eSSepherosa Ziehau 
254679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_i2c_data");
254779251f5eSSepherosa Ziehau 
254879251f5eSSepherosa Ziehau 	if (data)
254963d483cdSSepherosa Ziehau 		*i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw);
255079251f5eSSepherosa Ziehau 	else
255163d483cdSSepherosa Ziehau 		*i2cctl &= ~(IXGBE_I2C_DATA_OUT_BY_MAC(hw));
255263d483cdSSepherosa Ziehau 	*i2cctl &= ~data_oe_bit;
255379251f5eSSepherosa Ziehau 
255463d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
255579251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
255679251f5eSSepherosa Ziehau 
255779251f5eSSepherosa Ziehau 	/* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
255879251f5eSSepherosa Ziehau 	usec_delay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
255979251f5eSSepherosa Ziehau 
256063d483cdSSepherosa Ziehau 	if (!data)	/* Can't verify data in this case */
256163d483cdSSepherosa Ziehau 		return IXGBE_SUCCESS;
256263d483cdSSepherosa Ziehau 	if (data_oe_bit) {
256363d483cdSSepherosa Ziehau 		*i2cctl |= data_oe_bit;
256463d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
256563d483cdSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
256663d483cdSSepherosa Ziehau 	}
256763d483cdSSepherosa Ziehau 
256879251f5eSSepherosa Ziehau 	/* Verify data was set correctly */
256963d483cdSSepherosa Ziehau 	*i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
257063d483cdSSepherosa Ziehau 	if (data != ixgbe_get_i2c_data(hw, i2cctl)) {
257179251f5eSSepherosa Ziehau 		status = IXGBE_ERR_I2C;
257279251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
257379251f5eSSepherosa Ziehau 			     "Error - I2C data was not set to %X.\n",
257479251f5eSSepherosa Ziehau 			     data);
257579251f5eSSepherosa Ziehau 	}
257679251f5eSSepherosa Ziehau 
257779251f5eSSepherosa Ziehau 	return status;
257879251f5eSSepherosa Ziehau }
257979251f5eSSepherosa Ziehau 
258079251f5eSSepherosa Ziehau /**
258179251f5eSSepherosa Ziehau  *  ixgbe_get_i2c_data - Reads the I2C SDA data bit
258279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
258379251f5eSSepherosa Ziehau  *  @i2cctl: Current value of I2CCTL register
258479251f5eSSepherosa Ziehau  *
258579251f5eSSepherosa Ziehau  *  Returns the I2C data bit value
258663d483cdSSepherosa Ziehau  *  Negates the I2C data output enable on X550 hardware.
258779251f5eSSepherosa Ziehau  **/
ixgbe_get_i2c_data(struct ixgbe_hw * hw,u32 * i2cctl)258863d483cdSSepherosa Ziehau static bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl)
258979251f5eSSepherosa Ziehau {
259063d483cdSSepherosa Ziehau 	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
259179251f5eSSepherosa Ziehau 	bool data;
259279251f5eSSepherosa Ziehau 
259379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_i2c_data");
259479251f5eSSepherosa Ziehau 
259563d483cdSSepherosa Ziehau 	if (data_oe_bit) {
259663d483cdSSepherosa Ziehau 		*i2cctl |= data_oe_bit;
259763d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
259863d483cdSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
259963d483cdSSepherosa Ziehau 		usec_delay(IXGBE_I2C_T_FALL);
260063d483cdSSepherosa Ziehau 	}
260163d483cdSSepherosa Ziehau 
260263d483cdSSepherosa Ziehau 	if (*i2cctl & IXGBE_I2C_DATA_IN_BY_MAC(hw))
260379251f5eSSepherosa Ziehau 		data = 1;
260479251f5eSSepherosa Ziehau 	else
260579251f5eSSepherosa Ziehau 		data = 0;
260679251f5eSSepherosa Ziehau 
260779251f5eSSepherosa Ziehau 	return data;
260879251f5eSSepherosa Ziehau }
260979251f5eSSepherosa Ziehau 
261079251f5eSSepherosa Ziehau /**
261179251f5eSSepherosa Ziehau  *  ixgbe_i2c_bus_clear - Clears the I2C bus
261279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
261379251f5eSSepherosa Ziehau  *
261479251f5eSSepherosa Ziehau  *  Clears the I2C bus by sending nine clock pulses.
261579251f5eSSepherosa Ziehau  *  Used when data line is stuck low.
261679251f5eSSepherosa Ziehau  **/
ixgbe_i2c_bus_clear(struct ixgbe_hw * hw)261779251f5eSSepherosa Ziehau void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
261879251f5eSSepherosa Ziehau {
261963d483cdSSepherosa Ziehau 	u32 i2cctl;
262079251f5eSSepherosa Ziehau 	u32 i;
262179251f5eSSepherosa Ziehau 
262279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_i2c_bus_clear");
262379251f5eSSepherosa Ziehau 
262479251f5eSSepherosa Ziehau 	ixgbe_i2c_start(hw);
262563d483cdSSepherosa Ziehau 	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
262679251f5eSSepherosa Ziehau 
262779251f5eSSepherosa Ziehau 	ixgbe_set_i2c_data(hw, &i2cctl, 1);
262879251f5eSSepherosa Ziehau 
262979251f5eSSepherosa Ziehau 	for (i = 0; i < 9; i++) {
263079251f5eSSepherosa Ziehau 		ixgbe_raise_i2c_clk(hw, &i2cctl);
263179251f5eSSepherosa Ziehau 
263279251f5eSSepherosa Ziehau 		/* Min high period of clock is 4us */
263379251f5eSSepherosa Ziehau 		usec_delay(IXGBE_I2C_T_HIGH);
263479251f5eSSepherosa Ziehau 
263579251f5eSSepherosa Ziehau 		ixgbe_lower_i2c_clk(hw, &i2cctl);
263679251f5eSSepherosa Ziehau 
263779251f5eSSepherosa Ziehau 		/* Min low period of clock is 4.7us*/
263879251f5eSSepherosa Ziehau 		usec_delay(IXGBE_I2C_T_LOW);
263979251f5eSSepherosa Ziehau 	}
264079251f5eSSepherosa Ziehau 
264179251f5eSSepherosa Ziehau 	ixgbe_i2c_start(hw);
264279251f5eSSepherosa Ziehau 
264379251f5eSSepherosa Ziehau 	/* Put the i2c bus back to default state */
264479251f5eSSepherosa Ziehau 	ixgbe_i2c_stop(hw);
264579251f5eSSepherosa Ziehau }
264679251f5eSSepherosa Ziehau 
264779251f5eSSepherosa Ziehau /**
264879251f5eSSepherosa Ziehau  *  ixgbe_tn_check_overtemp - Checks if an overtemp occurred.
264979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
265079251f5eSSepherosa Ziehau  *
265179251f5eSSepherosa Ziehau  *  Checks if the LASI temp alarm status was triggered due to overtemp
265279251f5eSSepherosa Ziehau  **/
ixgbe_tn_check_overtemp(struct ixgbe_hw * hw)265379251f5eSSepherosa Ziehau s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
265479251f5eSSepherosa Ziehau {
265579251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
265679251f5eSSepherosa Ziehau 	u16 phy_data = 0;
265779251f5eSSepherosa Ziehau 
265879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_tn_check_overtemp");
265979251f5eSSepherosa Ziehau 
266079251f5eSSepherosa Ziehau 	if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM)
266179251f5eSSepherosa Ziehau 		goto out;
266279251f5eSSepherosa Ziehau 
266379251f5eSSepherosa Ziehau 	/* Check that the LASI temp alarm status was triggered */
266479251f5eSSepherosa Ziehau 	hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
266579251f5eSSepherosa Ziehau 			     IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_data);
266679251f5eSSepherosa Ziehau 
266779251f5eSSepherosa Ziehau 	if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM))
266879251f5eSSepherosa Ziehau 		goto out;
266979251f5eSSepherosa Ziehau 
267079251f5eSSepherosa Ziehau 	status = IXGBE_ERR_OVERTEMP;
267179251f5eSSepherosa Ziehau 	ERROR_REPORT1(IXGBE_ERROR_CAUTION, "Device over temperature");
267279251f5eSSepherosa Ziehau out:
267379251f5eSSepherosa Ziehau 	return status;
267479251f5eSSepherosa Ziehau }
267563d483cdSSepherosa Ziehau 
267663d483cdSSepherosa Ziehau /**
267763d483cdSSepherosa Ziehau  * ixgbe_set_copper_phy_power - Control power for copper phy
267863d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
267963d483cdSSepherosa Ziehau  * @on: TRUE for on, FALSE for off
268063d483cdSSepherosa Ziehau  */
ixgbe_set_copper_phy_power(struct ixgbe_hw * hw,bool on)268163d483cdSSepherosa Ziehau s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on)
268263d483cdSSepherosa Ziehau {
268363d483cdSSepherosa Ziehau 	u32 status;
268463d483cdSSepherosa Ziehau 	u16 reg;
268563d483cdSSepherosa Ziehau 
26866150453fSSepherosa Ziehau 	if (!on && ixgbe_mng_present(hw))
26876150453fSSepherosa Ziehau 		return 0;
26886150453fSSepherosa Ziehau 
268963d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
269063d483cdSSepherosa Ziehau 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
269163d483cdSSepherosa Ziehau 				      &reg);
269263d483cdSSepherosa Ziehau 	if (status)
269363d483cdSSepherosa Ziehau 		return status;
269463d483cdSSepherosa Ziehau 
269563d483cdSSepherosa Ziehau 	if (on) {
269663d483cdSSepherosa Ziehau 		reg &= ~IXGBE_MDIO_PHY_SET_LOW_POWER_MODE;
269763d483cdSSepherosa Ziehau 	} else {
269863d483cdSSepherosa Ziehau 		if (ixgbe_check_reset_blocked(hw))
269963d483cdSSepherosa Ziehau 			return 0;
270063d483cdSSepherosa Ziehau 		reg |= IXGBE_MDIO_PHY_SET_LOW_POWER_MODE;
270163d483cdSSepherosa Ziehau 	}
270263d483cdSSepherosa Ziehau 
270363d483cdSSepherosa Ziehau 	status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
270463d483cdSSepherosa Ziehau 				       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
270563d483cdSSepherosa Ziehau 				       reg);
270663d483cdSSepherosa Ziehau 	return status;
270763d483cdSSepherosa Ziehau }
2708