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 ®);
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