19a799d71034c4e2b168740c8a8530591011313d5Auke Kok/*******************************************************************************
29a799d71034c4e2b168740c8a8530591011313d5Auke Kok
39a799d71034c4e2b168740c8a8530591011313d5Auke Kok  Intel 10 Gigabit PCI Express Linux driver
49497182051f261fe688bb2d672fdbc07ab3d5348Don Skidmore  Copyright(c) 1999 - 2012 Intel Corporation.
59a799d71034c4e2b168740c8a8530591011313d5Auke Kok
69a799d71034c4e2b168740c8a8530591011313d5Auke Kok  This program is free software; you can redistribute it and/or modify it
79a799d71034c4e2b168740c8a8530591011313d5Auke Kok  under the terms and conditions of the GNU General Public License,
89a799d71034c4e2b168740c8a8530591011313d5Auke Kok  version 2, as published by the Free Software Foundation.
99a799d71034c4e2b168740c8a8530591011313d5Auke Kok
109a799d71034c4e2b168740c8a8530591011313d5Auke Kok  This program is distributed in the hope it will be useful, but WITHOUT
119a799d71034c4e2b168740c8a8530591011313d5Auke Kok  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
129a799d71034c4e2b168740c8a8530591011313d5Auke Kok  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
139a799d71034c4e2b168740c8a8530591011313d5Auke Kok  more details.
149a799d71034c4e2b168740c8a8530591011313d5Auke Kok
159a799d71034c4e2b168740c8a8530591011313d5Auke Kok  You should have received a copy of the GNU General Public License along with
169a799d71034c4e2b168740c8a8530591011313d5Auke Kok  this program; if not, write to the Free Software Foundation, Inc.,
179a799d71034c4e2b168740c8a8530591011313d5Auke Kok  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
189a799d71034c4e2b168740c8a8530591011313d5Auke Kok
199a799d71034c4e2b168740c8a8530591011313d5Auke Kok  The full GNU General Public License is included in this distribution in
209a799d71034c4e2b168740c8a8530591011313d5Auke Kok  the file called "COPYING".
219a799d71034c4e2b168740c8a8530591011313d5Auke Kok
229a799d71034c4e2b168740c8a8530591011313d5Auke Kok  Contact Information:
239a799d71034c4e2b168740c8a8530591011313d5Auke Kok  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
249a799d71034c4e2b168740c8a8530591011313d5Auke Kok  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
259a799d71034c4e2b168740c8a8530591011313d5Auke Kok
269a799d71034c4e2b168740c8a8530591011313d5Auke Kok*******************************************************************************/
279a799d71034c4e2b168740c8a8530591011313d5Auke Kok
289a799d71034c4e2b168740c8a8530591011313d5Auke Kok#include <linux/pci.h>
299a799d71034c4e2b168740c8a8530591011313d5Auke Kok#include <linux/delay.h>
309a799d71034c4e2b168740c8a8530591011313d5Auke Kok#include <linux/sched.h>
319a799d71034c4e2b168740c8a8530591011313d5Auke Kok
329a799d71034c4e2b168740c8a8530591011313d5Auke Kok#include "ixgbe_common.h"
339a799d71034c4e2b168740c8a8530591011313d5Auke Kok#include "ixgbe_phy.h"
349a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic void ixgbe_i2c_start(struct ixgbe_hw *hw);
3611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic void ixgbe_i2c_stop(struct ixgbe_hw *hw);
3711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data);
3811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data);
3911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw);
4011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data);
4111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data);
42e1befd774a049bdc85cf0ed5b307f913b33e1691Emil Tantilovstatic void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
4311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
4411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
4511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic bool ixgbe_get_i2c_data(u32 *i2cctl);
4611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
479a799d71034c4e2b168740c8a8530591011313d5Auke Kokstatic enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
489a799d71034c4e2b168740c8a8530591011313d5Auke Kokstatic s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
499a799d71034c4e2b168740c8a8530591011313d5Auke Kok
509a799d71034c4e2b168740c8a8530591011313d5Auke Kok/**
51c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg *  ixgbe_identify_phy_generic - Get physical layer module
529a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @hw: pointer to hardware structure
539a799d71034c4e2b168740c8a8530591011313d5Auke Kok *
549a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  Determines the physical layer module found on the current adapter.
559a799d71034c4e2b168740c8a8530591011313d5Auke Kok **/
56c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburgs32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
579a799d71034c4e2b168740c8a8530591011313d5Auke Kok{
589a799d71034c4e2b168740c8a8530591011313d5Auke Kok	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
599a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u32 phy_addr;
60037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov	u16 ext_ability = 0;
619a799d71034c4e2b168740c8a8530591011313d5Auke Kok
62c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg	if (hw->phy.type == ixgbe_phy_unknown) {
63c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg		for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
6463d6e1d80a8c3118be2ca0f1f21ba883f282060cDon Skidmore			hw->phy.mdio.prtad = phy_addr;
656b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings			if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) {
66c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg				ixgbe_get_phy_id(hw);
67c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg				hw->phy.type =
68c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg				        ixgbe_get_phy_type_from_id(hw->phy.id);
69037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov
70037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov				if (hw->phy.type == ixgbe_phy_unknown) {
71037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov					hw->phy.ops.read_reg(hw,
72037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov							     MDIO_PMA_EXTABLE,
73037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov							     MDIO_MMD_PMAPMD,
74037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov							     &ext_ability);
75037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov					if (ext_ability &
76037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov					    (MDIO_PMA_EXTABLE_10GBT |
77037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov					     MDIO_PMA_EXTABLE_1000BT))
78037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov						hw->phy.type =
79037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov							 ixgbe_phy_cu_unknown;
80037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov					else
81037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov						hw->phy.type =
82037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov							 ixgbe_phy_generic;
83037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov				}
84037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov
85c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg				status = 0;
86c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg				break;
87c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg			}
889a799d71034c4e2b168740c8a8530591011313d5Auke Kok		}
8963d6e1d80a8c3118be2ca0f1f21ba883f282060cDon Skidmore		/* clear value if nothing found */
90037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov		if (status != 0)
91037c6d0a33453bf025c6d6b21e5a0fabe117a797Emil Tantilov			hw->phy.mdio.prtad = 0;
92c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg	} else {
93c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg		status = 0;
949a799d71034c4e2b168740c8a8530591011313d5Auke Kok	}
95c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg
969a799d71034c4e2b168740c8a8530591011313d5Auke Kok	return status;
979a799d71034c4e2b168740c8a8530591011313d5Auke Kok}
989a799d71034c4e2b168740c8a8530591011313d5Auke Kok
999a799d71034c4e2b168740c8a8530591011313d5Auke Kok/**
1009a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  ixgbe_get_phy_id - Get the phy type
1019a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @hw: pointer to hardware structure
1029a799d71034c4e2b168740c8a8530591011313d5Auke Kok *
1039a799d71034c4e2b168740c8a8530591011313d5Auke Kok **/
1049a799d71034c4e2b168740c8a8530591011313d5Auke Kokstatic s32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
1059a799d71034c4e2b168740c8a8530591011313d5Auke Kok{
1069a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u32 status;
1079a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u16 phy_id_high = 0;
1089a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u16 phy_id_low = 0;
1099a799d71034c4e2b168740c8a8530591011313d5Auke Kok
1106b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings	status = hw->phy.ops.read_reg(hw, MDIO_DEVID1, MDIO_MMD_PMAPMD,
111c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg	                              &phy_id_high);
1129a799d71034c4e2b168740c8a8530591011313d5Auke Kok
1139a799d71034c4e2b168740c8a8530591011313d5Auke Kok	if (status == 0) {
1149a799d71034c4e2b168740c8a8530591011313d5Auke Kok		hw->phy.id = (u32)(phy_id_high << 16);
1156b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings		status = hw->phy.ops.read_reg(hw, MDIO_DEVID2, MDIO_MMD_PMAPMD,
116c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg		                              &phy_id_low);
1179a799d71034c4e2b168740c8a8530591011313d5Auke Kok		hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
1189a799d71034c4e2b168740c8a8530591011313d5Auke Kok		hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
1199a799d71034c4e2b168740c8a8530591011313d5Auke Kok	}
1209a799d71034c4e2b168740c8a8530591011313d5Auke Kok	return status;
1219a799d71034c4e2b168740c8a8530591011313d5Auke Kok}
1229a799d71034c4e2b168740c8a8530591011313d5Auke Kok
1239a799d71034c4e2b168740c8a8530591011313d5Auke Kok/**
1249a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  ixgbe_get_phy_type_from_id - Get the phy type
1259a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @hw: pointer to hardware structure
1269a799d71034c4e2b168740c8a8530591011313d5Auke Kok *
1279a799d71034c4e2b168740c8a8530591011313d5Auke Kok **/
1289a799d71034c4e2b168740c8a8530591011313d5Auke Kokstatic enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
1299a799d71034c4e2b168740c8a8530591011313d5Auke Kok{
1309a799d71034c4e2b168740c8a8530591011313d5Auke Kok	enum ixgbe_phy_type phy_type;
1319a799d71034c4e2b168740c8a8530591011313d5Auke Kok
1329a799d71034c4e2b168740c8a8530591011313d5Auke Kok	switch (phy_id) {
1330befdb3e0a26a8949063915274e1bec8873c526bJesse Brandeburg	case TN1010_PHY_ID:
1340befdb3e0a26a8949063915274e1bec8873c526bJesse Brandeburg		phy_type = ixgbe_phy_tn;
1350befdb3e0a26a8949063915274e1bec8873c526bJesse Brandeburg		break;
1362b264909c660717a67da997a181a4a4f551ef9b6Don Skidmore	case X540_PHY_ID:
137fe15e8e1c78521e0b4e375d6ed415b82265419c9Don Skidmore		phy_type = ixgbe_phy_aq;
138fe15e8e1c78521e0b4e375d6ed415b82265419c9Don Skidmore		break;
1399a799d71034c4e2b168740c8a8530591011313d5Auke Kok	case QT2022_PHY_ID:
1409a799d71034c4e2b168740c8a8530591011313d5Auke Kok		phy_type = ixgbe_phy_qt;
1419a799d71034c4e2b168740c8a8530591011313d5Auke Kok		break;
142c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	case ATH_PHY_ID:
143c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		phy_type = ixgbe_phy_nl;
144c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		break;
1459a799d71034c4e2b168740c8a8530591011313d5Auke Kok	default:
1469a799d71034c4e2b168740c8a8530591011313d5Auke Kok		phy_type = ixgbe_phy_unknown;
1479a799d71034c4e2b168740c8a8530591011313d5Auke Kok		break;
1489a799d71034c4e2b168740c8a8530591011313d5Auke Kok	}
1499a799d71034c4e2b168740c8a8530591011313d5Auke Kok
1509a799d71034c4e2b168740c8a8530591011313d5Auke Kok	return phy_type;
1519a799d71034c4e2b168740c8a8530591011313d5Auke Kok}
1529a799d71034c4e2b168740c8a8530591011313d5Auke Kok
1539a799d71034c4e2b168740c8a8530591011313d5Auke Kok/**
154c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg *  ixgbe_reset_phy_generic - Performs a PHY reset
1559a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @hw: pointer to hardware structure
1569a799d71034c4e2b168740c8a8530591011313d5Auke Kok **/
157c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburgs32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
1589a799d71034c4e2b168740c8a8530591011313d5Auke Kok{
1591783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	u32 i;
1601783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	u16 ctrl = 0;
1611783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	s32 status = 0;
1621783575c1a11f726130522b851737cddda4c14c0Emil Tantilov
1631783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	if (hw->phy.type == ixgbe_phy_unknown)
1641783575c1a11f726130522b851737cddda4c14c0Emil Tantilov		status = ixgbe_identify_phy_generic(hw);
1651783575c1a11f726130522b851737cddda4c14c0Emil Tantilov
1661783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	if (status != 0 || hw->phy.type == ixgbe_phy_none)
1671783575c1a11f726130522b851737cddda4c14c0Emil Tantilov		goto out;
1681783575c1a11f726130522b851737cddda4c14c0Emil Tantilov
169119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	/* Don't reset PHY if it's shut down due to overtemp. */
170119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	if (!hw->phy.reset_if_overtemp &&
171119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	    (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw)))
1721783575c1a11f726130522b851737cddda4c14c0Emil Tantilov		goto out;
173119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala
1749a799d71034c4e2b168740c8a8530591011313d5Auke Kok	/*
1759a799d71034c4e2b168740c8a8530591011313d5Auke Kok	 * Perform soft PHY reset to the PHY_XS.
1769a799d71034c4e2b168740c8a8530591011313d5Auke Kok	 * This will cause a soft reset to the PHY
1779a799d71034c4e2b168740c8a8530591011313d5Auke Kok	 */
1781783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	hw->phy.ops.write_reg(hw, MDIO_CTRL1,
1791783575c1a11f726130522b851737cddda4c14c0Emil Tantilov			      MDIO_MMD_PHYXS,
1801783575c1a11f726130522b851737cddda4c14c0Emil Tantilov			      MDIO_CTRL1_RESET);
1811783575c1a11f726130522b851737cddda4c14c0Emil Tantilov
1821783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	/*
1831783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	 * Poll for reset bit to self-clear indicating reset is complete.
1841783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	 * Some PHYs could take up to 3 seconds to complete and need about
1851783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	 * 1.7 usec delay after the reset is complete.
1861783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	 */
1871783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	for (i = 0; i < 30; i++) {
1881783575c1a11f726130522b851737cddda4c14c0Emil Tantilov		msleep(100);
1891783575c1a11f726130522b851737cddda4c14c0Emil Tantilov		hw->phy.ops.read_reg(hw, MDIO_CTRL1,
1901783575c1a11f726130522b851737cddda4c14c0Emil Tantilov				     MDIO_MMD_PHYXS, &ctrl);
1911783575c1a11f726130522b851737cddda4c14c0Emil Tantilov		if (!(ctrl & MDIO_CTRL1_RESET)) {
1921783575c1a11f726130522b851737cddda4c14c0Emil Tantilov			udelay(2);
1931783575c1a11f726130522b851737cddda4c14c0Emil Tantilov			break;
1941783575c1a11f726130522b851737cddda4c14c0Emil Tantilov		}
1951783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	}
1961783575c1a11f726130522b851737cddda4c14c0Emil Tantilov
1971783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	if (ctrl & MDIO_CTRL1_RESET) {
1981783575c1a11f726130522b851737cddda4c14c0Emil Tantilov		status = IXGBE_ERR_RESET_FAILED;
1991783575c1a11f726130522b851737cddda4c14c0Emil Tantilov		hw_dbg(hw, "PHY reset polling failed to complete.\n");
2001783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	}
2011783575c1a11f726130522b851737cddda4c14c0Emil Tantilov
2021783575c1a11f726130522b851737cddda4c14c0Emil Tantilovout:
2031783575c1a11f726130522b851737cddda4c14c0Emil Tantilov	return status;
2049a799d71034c4e2b168740c8a8530591011313d5Auke Kok}
2059a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2069a799d71034c4e2b168740c8a8530591011313d5Auke Kok/**
207c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg *  ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register
2089a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @hw: pointer to hardware structure
2099a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @reg_addr: 32 bit address of PHY register to read
2109a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @phy_data: Pointer to read data from PHY register
2119a799d71034c4e2b168740c8a8530591011313d5Auke Kok **/
212c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburgs32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
213c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg                               u32 device_type, u16 *phy_data)
2149a799d71034c4e2b168740c8a8530591011313d5Auke Kok{
2159a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u32 command;
2169a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u32 i;
2179a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u32 data;
2189a799d71034c4e2b168740c8a8530591011313d5Auke Kok	s32 status = 0;
2199a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u16 gssr;
2209a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2219a799d71034c4e2b168740c8a8530591011313d5Auke Kok	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
2229a799d71034c4e2b168740c8a8530591011313d5Auke Kok		gssr = IXGBE_GSSR_PHY1_SM;
2239a799d71034c4e2b168740c8a8530591011313d5Auke Kok	else
2249a799d71034c4e2b168740c8a8530591011313d5Auke Kok		gssr = IXGBE_GSSR_PHY0_SM;
2259a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2265e655105e3e19d746f9e95c514b014c11c3d1b6aDon Skidmore	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0)
2279a799d71034c4e2b168740c8a8530591011313d5Auke Kok		status = IXGBE_ERR_SWFW_SYNC;
2289a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2299a799d71034c4e2b168740c8a8530591011313d5Auke Kok	if (status == 0) {
2309a799d71034c4e2b168740c8a8530591011313d5Auke Kok		/* Setup and write the address cycle command */
2319a799d71034c4e2b168740c8a8530591011313d5Auke Kok		command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
232c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg		           (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
2336b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings		           (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
234c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg		           (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
2359a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2369a799d71034c4e2b168740c8a8530591011313d5Auke Kok		IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
2379a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2389a799d71034c4e2b168740c8a8530591011313d5Auke Kok		/*
2399a799d71034c4e2b168740c8a8530591011313d5Auke Kok		 * Check every 10 usec to see if the address cycle completed.
2409a799d71034c4e2b168740c8a8530591011313d5Auke Kok		 * The MDI Command bit will clear when the operation is
2419a799d71034c4e2b168740c8a8530591011313d5Auke Kok		 * complete
2429a799d71034c4e2b168740c8a8530591011313d5Auke Kok		 */
243c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg		for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
2449a799d71034c4e2b168740c8a8530591011313d5Auke Kok			udelay(10);
2459a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2469a799d71034c4e2b168740c8a8530591011313d5Auke Kok			command = IXGBE_READ_REG(hw, IXGBE_MSCA);
2479a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2489a799d71034c4e2b168740c8a8530591011313d5Auke Kok			if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
2499a799d71034c4e2b168740c8a8530591011313d5Auke Kok				break;
2509a799d71034c4e2b168740c8a8530591011313d5Auke Kok		}
2519a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2529a799d71034c4e2b168740c8a8530591011313d5Auke Kok		if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
2539a799d71034c4e2b168740c8a8530591011313d5Auke Kok			hw_dbg(hw, "PHY address command did not complete.\n");
2549a799d71034c4e2b168740c8a8530591011313d5Auke Kok			status = IXGBE_ERR_PHY;
2559a799d71034c4e2b168740c8a8530591011313d5Auke Kok		}
2569a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2579a799d71034c4e2b168740c8a8530591011313d5Auke Kok		if (status == 0) {
2589a799d71034c4e2b168740c8a8530591011313d5Auke Kok			/*
2599a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 * Address cycle complete, setup and write the read
2609a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 * command
2619a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 */
2629a799d71034c4e2b168740c8a8530591011313d5Auke Kok			command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
263c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg			           (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
2646b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings			           (hw->phy.mdio.prtad <<
2656b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings				    IXGBE_MSCA_PHY_ADDR_SHIFT) |
266c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg			           (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
2679a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2689a799d71034c4e2b168740c8a8530591011313d5Auke Kok			IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
2699a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2709a799d71034c4e2b168740c8a8530591011313d5Auke Kok			/*
2719a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 * Check every 10 usec to see if the address cycle
2729a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 * completed. The MDI Command bit will clear when the
2739a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 * operation is complete
2749a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 */
275c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg			for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
2769a799d71034c4e2b168740c8a8530591011313d5Auke Kok				udelay(10);
2779a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2789a799d71034c4e2b168740c8a8530591011313d5Auke Kok				command = IXGBE_READ_REG(hw, IXGBE_MSCA);
2799a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2809a799d71034c4e2b168740c8a8530591011313d5Auke Kok				if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
2819a799d71034c4e2b168740c8a8530591011313d5Auke Kok					break;
2829a799d71034c4e2b168740c8a8530591011313d5Auke Kok			}
2839a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2849a799d71034c4e2b168740c8a8530591011313d5Auke Kok			if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
285c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg				hw_dbg(hw, "PHY read command didn't complete\n");
2869a799d71034c4e2b168740c8a8530591011313d5Auke Kok				status = IXGBE_ERR_PHY;
2879a799d71034c4e2b168740c8a8530591011313d5Auke Kok			} else {
2889a799d71034c4e2b168740c8a8530591011313d5Auke Kok				/*
2899a799d71034c4e2b168740c8a8530591011313d5Auke Kok				 * Read operation is complete.  Get the data
2909a799d71034c4e2b168740c8a8530591011313d5Auke Kok				 * from MSRWD
2919a799d71034c4e2b168740c8a8530591011313d5Auke Kok				 */
2929a799d71034c4e2b168740c8a8530591011313d5Auke Kok				data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
2939a799d71034c4e2b168740c8a8530591011313d5Auke Kok				data >>= IXGBE_MSRWD_READ_DATA_SHIFT;
2949a799d71034c4e2b168740c8a8530591011313d5Auke Kok				*phy_data = (u16)(data);
2959a799d71034c4e2b168740c8a8530591011313d5Auke Kok			}
2969a799d71034c4e2b168740c8a8530591011313d5Auke Kok		}
2979a799d71034c4e2b168740c8a8530591011313d5Auke Kok
2985e655105e3e19d746f9e95c514b014c11c3d1b6aDon Skidmore		hw->mac.ops.release_swfw_sync(hw, gssr);
2999a799d71034c4e2b168740c8a8530591011313d5Auke Kok	}
300c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg
3019a799d71034c4e2b168740c8a8530591011313d5Auke Kok	return status;
3029a799d71034c4e2b168740c8a8530591011313d5Auke Kok}
3039a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3049a799d71034c4e2b168740c8a8530591011313d5Auke Kok/**
305c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg *  ixgbe_write_phy_reg_generic - Writes a value to specified PHY register
3069a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @hw: pointer to hardware structure
3079a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @reg_addr: 32 bit PHY register to write
3089a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @device_type: 5 bit device type
3099a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @phy_data: Data to write to the PHY register
3109a799d71034c4e2b168740c8a8530591011313d5Auke Kok **/
311c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburgs32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
312c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg                                u32 device_type, u16 phy_data)
3139a799d71034c4e2b168740c8a8530591011313d5Auke Kok{
3149a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u32 command;
3159a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u32 i;
3169a799d71034c4e2b168740c8a8530591011313d5Auke Kok	s32 status = 0;
3179a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u16 gssr;
3189a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3199a799d71034c4e2b168740c8a8530591011313d5Auke Kok	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
3209a799d71034c4e2b168740c8a8530591011313d5Auke Kok		gssr = IXGBE_GSSR_PHY1_SM;
3219a799d71034c4e2b168740c8a8530591011313d5Auke Kok	else
3229a799d71034c4e2b168740c8a8530591011313d5Auke Kok		gssr = IXGBE_GSSR_PHY0_SM;
3239a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3245e655105e3e19d746f9e95c514b014c11c3d1b6aDon Skidmore	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0)
3259a799d71034c4e2b168740c8a8530591011313d5Auke Kok		status = IXGBE_ERR_SWFW_SYNC;
3269a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3279a799d71034c4e2b168740c8a8530591011313d5Auke Kok	if (status == 0) {
3289a799d71034c4e2b168740c8a8530591011313d5Auke Kok		/* Put the data in the MDI single read and write data register*/
3299a799d71034c4e2b168740c8a8530591011313d5Auke Kok		IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data);
3309a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3319a799d71034c4e2b168740c8a8530591011313d5Auke Kok		/* Setup and write the address cycle command */
3329a799d71034c4e2b168740c8a8530591011313d5Auke Kok		command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
333c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg		           (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
3346b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings		           (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
335c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg		           (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
3369a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3379a799d71034c4e2b168740c8a8530591011313d5Auke Kok		IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
3389a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3399a799d71034c4e2b168740c8a8530591011313d5Auke Kok		/*
3409a799d71034c4e2b168740c8a8530591011313d5Auke Kok		 * Check every 10 usec to see if the address cycle completed.
3419a799d71034c4e2b168740c8a8530591011313d5Auke Kok		 * The MDI Command bit will clear when the operation is
3429a799d71034c4e2b168740c8a8530591011313d5Auke Kok		 * complete
3439a799d71034c4e2b168740c8a8530591011313d5Auke Kok		 */
344c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg		for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
3459a799d71034c4e2b168740c8a8530591011313d5Auke Kok			udelay(10);
3469a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3479a799d71034c4e2b168740c8a8530591011313d5Auke Kok			command = IXGBE_READ_REG(hw, IXGBE_MSCA);
3489a799d71034c4e2b168740c8a8530591011313d5Auke Kok
349c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg			if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
3509a799d71034c4e2b168740c8a8530591011313d5Auke Kok				break;
3519a799d71034c4e2b168740c8a8530591011313d5Auke Kok		}
3529a799d71034c4e2b168740c8a8530591011313d5Auke Kok
353c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg		if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
354c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg			hw_dbg(hw, "PHY address cmd didn't complete\n");
3559a799d71034c4e2b168740c8a8530591011313d5Auke Kok			status = IXGBE_ERR_PHY;
356c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg		}
3579a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3589a799d71034c4e2b168740c8a8530591011313d5Auke Kok		if (status == 0) {
3599a799d71034c4e2b168740c8a8530591011313d5Auke Kok			/*
3609a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 * Address cycle complete, setup and write the write
3619a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 * command
3629a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 */
3639a799d71034c4e2b168740c8a8530591011313d5Auke Kok			command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
364c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg			           (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
3656b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings			           (hw->phy.mdio.prtad <<
3666b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings				    IXGBE_MSCA_PHY_ADDR_SHIFT) |
367c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg			           (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
3689a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3699a799d71034c4e2b168740c8a8530591011313d5Auke Kok			IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
3709a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3719a799d71034c4e2b168740c8a8530591011313d5Auke Kok			/*
3729a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 * Check every 10 usec to see if the address cycle
3739a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 * completed. The MDI Command bit will clear when the
3749a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 * operation is complete
3759a799d71034c4e2b168740c8a8530591011313d5Auke Kok			 */
376c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg			for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
3779a799d71034c4e2b168740c8a8530591011313d5Auke Kok				udelay(10);
3789a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3799a799d71034c4e2b168740c8a8530591011313d5Auke Kok				command = IXGBE_READ_REG(hw, IXGBE_MSCA);
3809a799d71034c4e2b168740c8a8530591011313d5Auke Kok
381c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg				if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
3829a799d71034c4e2b168740c8a8530591011313d5Auke Kok					break;
3839a799d71034c4e2b168740c8a8530591011313d5Auke Kok			}
3849a799d71034c4e2b168740c8a8530591011313d5Auke Kok
385c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg			if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
386c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg				hw_dbg(hw, "PHY address cmd didn't complete\n");
3879a799d71034c4e2b168740c8a8530591011313d5Auke Kok				status = IXGBE_ERR_PHY;
388c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg			}
3899a799d71034c4e2b168740c8a8530591011313d5Auke Kok		}
3909a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3915e655105e3e19d746f9e95c514b014c11c3d1b6aDon Skidmore		hw->mac.ops.release_swfw_sync(hw, gssr);
3929a799d71034c4e2b168740c8a8530591011313d5Auke Kok	}
3939a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3949a799d71034c4e2b168740c8a8530591011313d5Auke Kok	return status;
3959a799d71034c4e2b168740c8a8530591011313d5Auke Kok}
3969a799d71034c4e2b168740c8a8530591011313d5Auke Kok
3979a799d71034c4e2b168740c8a8530591011313d5Auke Kok/**
398c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg *  ixgbe_setup_phy_link_generic - Set and restart autoneg
3999a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @hw: pointer to hardware structure
4009a799d71034c4e2b168740c8a8530591011313d5Auke Kok *
4019a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  Restart autonegotiation and PHY and waits for completion.
4029a799d71034c4e2b168740c8a8530591011313d5Auke Kok **/
403c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburgs32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
4049a799d71034c4e2b168740c8a8530591011313d5Auke Kok{
4059dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	s32 status = 0;
4069a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u32 time_out;
4079a799d71034c4e2b168740c8a8530591011313d5Auke Kok	u32 max_time_out = 10;
4089dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
4099dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	bool autoneg = false;
4109dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	ixgbe_link_speed speed;
4119a799d71034c4e2b168740c8a8530591011313d5Auke Kok
4129dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
4139dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
4149dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
4159dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		/* Set or unset auto-negotiation 10G advertisement */
4169dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL,
4179dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     MDIO_MMD_AN,
4189dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     &autoneg_reg);
4199a799d71034c4e2b168740c8a8530591011313d5Auke Kok
4206b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings		autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G;
4219dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
4229dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
4239a799d71034c4e2b168740c8a8530591011313d5Auke Kok
4249dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL,
4259dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      MDIO_MMD_AN,
4269dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      autoneg_reg);
4279dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	}
4289dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
4299dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
4309dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		/* Set or unset auto-negotiation 1G advertisement */
4319dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.read_reg(hw,
4329dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
4339dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     MDIO_MMD_AN,
4349dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     &autoneg_reg);
4359dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
4369dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE;
4379dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
4389dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE;
4399dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
4409dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.write_reg(hw,
4419dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
4429dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      MDIO_MMD_AN,
4439dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      autoneg_reg);
4449dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	}
4459dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
4469dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	if (speed & IXGBE_LINK_SPEED_100_FULL) {
4479dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		/* Set or unset auto-negotiation 100M advertisement */
4489dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE,
4499dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     MDIO_MMD_AN,
4509dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     &autoneg_reg);
4519dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
452a59e8a1a72806057084adc2d321fc2a7cbce9579Emil Tantilov		autoneg_reg &= ~(ADVERTISE_100FULL |
453a59e8a1a72806057084adc2d321fc2a7cbce9579Emil Tantilov				 ADVERTISE_100HALF);
4549dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
4559dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			autoneg_reg |= ADVERTISE_100FULL;
4569dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
4579dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
4589dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      MDIO_MMD_AN,
4599dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      autoneg_reg);
4609dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	}
4619a799d71034c4e2b168740c8a8530591011313d5Auke Kok
4629a799d71034c4e2b168740c8a8530591011313d5Auke Kok	/* Restart PHY autonegotiation and wait for completion */
4639dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	hw->phy.ops.read_reg(hw, MDIO_CTRL1,
4649dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			     MDIO_MMD_AN, &autoneg_reg);
4659a799d71034c4e2b168740c8a8530591011313d5Auke Kok
4666b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings	autoneg_reg |= MDIO_AN_CTRL1_RESTART;
4679a799d71034c4e2b168740c8a8530591011313d5Auke Kok
4689dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	hw->phy.ops.write_reg(hw, MDIO_CTRL1,
4699dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			      MDIO_MMD_AN, autoneg_reg);
4709a799d71034c4e2b168740c8a8530591011313d5Auke Kok
4719a799d71034c4e2b168740c8a8530591011313d5Auke Kok	/* Wait for autonegotiation to finish */
4729a799d71034c4e2b168740c8a8530591011313d5Auke Kok	for (time_out = 0; time_out < max_time_out; time_out++) {
4739a799d71034c4e2b168740c8a8530591011313d5Auke Kok		udelay(10);
4749a799d71034c4e2b168740c8a8530591011313d5Auke Kok		/* Restart PHY autonegotiation and wait for completion */
4759dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		status = hw->phy.ops.read_reg(hw, MDIO_STAT1,
4769dda173667207fe59d380e522d318c144dc032f7Emil Tantilov					      MDIO_MMD_AN,
4779dda173667207fe59d380e522d318c144dc032f7Emil Tantilov					      &autoneg_reg);
4789a799d71034c4e2b168740c8a8530591011313d5Auke Kok
4796b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings		autoneg_reg &= MDIO_AN_STAT1_COMPLETE;
4806b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings		if (autoneg_reg == MDIO_AN_STAT1_COMPLETE) {
4819a799d71034c4e2b168740c8a8530591011313d5Auke Kok			break;
4829a799d71034c4e2b168740c8a8530591011313d5Auke Kok		}
4839a799d71034c4e2b168740c8a8530591011313d5Auke Kok	}
4849a799d71034c4e2b168740c8a8530591011313d5Auke Kok
4859dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	if (time_out == max_time_out) {
4869a799d71034c4e2b168740c8a8530591011313d5Auke Kok		status = IXGBE_ERR_LINK_SETUP;
4879dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out");
4889dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	}
4899a799d71034c4e2b168740c8a8530591011313d5Auke Kok
4909a799d71034c4e2b168740c8a8530591011313d5Auke Kok	return status;
4919a799d71034c4e2b168740c8a8530591011313d5Auke Kok}
4929a799d71034c4e2b168740c8a8530591011313d5Auke Kok
4939a799d71034c4e2b168740c8a8530591011313d5Auke Kok/**
494c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg *  ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities
4959a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @hw: pointer to hardware structure
4969a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @speed: new link speed
4979a799d71034c4e2b168740c8a8530591011313d5Auke Kok *  @autoneg: true if autonegotiation enabled
4989a799d71034c4e2b168740c8a8530591011313d5Auke Kok **/
499c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburgs32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
500c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg                                       ixgbe_link_speed speed,
501c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg                                       bool autoneg,
502c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg                                       bool autoneg_wait_to_complete)
5039a799d71034c4e2b168740c8a8530591011313d5Auke Kok{
504c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg
5059a799d71034c4e2b168740c8a8530591011313d5Auke Kok	/*
5069a799d71034c4e2b168740c8a8530591011313d5Auke Kok	 * Clear autoneg_advertised and set new values based on input link
5079a799d71034c4e2b168740c8a8530591011313d5Auke Kok	 * speed.
5089a799d71034c4e2b168740c8a8530591011313d5Auke Kok	 */
5099a799d71034c4e2b168740c8a8530591011313d5Auke Kok	hw->phy.autoneg_advertised = 0;
5109a799d71034c4e2b168740c8a8530591011313d5Auke Kok
5119a799d71034c4e2b168740c8a8530591011313d5Auke Kok	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
5129a799d71034c4e2b168740c8a8530591011313d5Auke Kok		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
513c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg
5149a799d71034c4e2b168740c8a8530591011313d5Auke Kok	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
5159a799d71034c4e2b168740c8a8530591011313d5Auke Kok		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
5169a799d71034c4e2b168740c8a8530591011313d5Auke Kok
5179dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	if (speed & IXGBE_LINK_SPEED_100_FULL)
5189dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
5199dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
5209a799d71034c4e2b168740c8a8530591011313d5Auke Kok	/* Setup link based on the new speed settings */
521c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg	hw->phy.ops.setup_link(hw);
5229a799d71034c4e2b168740c8a8530591011313d5Auke Kok
5239a799d71034c4e2b168740c8a8530591011313d5Auke Kok	return 0;
5249a799d71034c4e2b168740c8a8530591011313d5Auke Kok}
525c44ade9ef8ffd73cb8b026065ade78bc0040f0b4Jesse Brandeburg
5260befdb3e0a26a8949063915274e1bec8873c526bJesse Brandeburg/**
527a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities
528a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore * @hw: pointer to hardware structure
529a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore * @speed: pointer to link speed
530a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore * @autoneg: boolean auto-negotiation value
531a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore *
532a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore * Determines the link capabilities by reading the AUTOC register.
533a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore */
534a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmores32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
535fe15e8e1c78521e0b4e375d6ed415b82265419c9Don Skidmore                                               ixgbe_link_speed *speed,
536fe15e8e1c78521e0b4e375d6ed415b82265419c9Don Skidmore                                               bool *autoneg)
537a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore{
538a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore	s32 status = IXGBE_ERR_LINK_SETUP;
539a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore	u16 speed_ability;
540a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore
541a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore	*speed = 0;
542a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore	*autoneg = true;
543a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore
544a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore	status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD,
545a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore	                              &speed_ability);
546a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore
547a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore	if (status == 0) {
548a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore		if (speed_ability & MDIO_SPEED_10G)
549a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
550a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore		if (speed_ability & MDIO_PMA_SPEED_1000)
551a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
552a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore		if (speed_ability & MDIO_PMA_SPEED_100)
553a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore			*speed |= IXGBE_LINK_SPEED_100_FULL;
554a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore	}
555a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore
556a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore	return status;
557a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore}
558a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore
559a391f1d51244b8274920a33c5d11aeebec3aa68fDon Skidmore/**
5609dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *  ixgbe_check_phy_link_tnx - Determine link and speed status
5619dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *  @hw: pointer to hardware structure
5629dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *
5639dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *  Reads the VS1 register to determine if link is up and the current speed for
5649dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *  the PHY.
5659dda173667207fe59d380e522d318c144dc032f7Emil Tantilov **/
5669dda173667207fe59d380e522d318c144dc032f7Emil Tantilovs32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
5679dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			     bool *link_up)
5689dda173667207fe59d380e522d318c144dc032f7Emil Tantilov{
5699dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	s32 status = 0;
5709dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	u32 time_out;
5719dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	u32 max_time_out = 10;
5729dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	u16 phy_link = 0;
5739dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	u16 phy_speed = 0;
5749dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	u16 phy_data = 0;
5759dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
5769dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	/* Initialize speed and link to default case */
5779dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	*link_up = false;
5789dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	*speed = IXGBE_LINK_SPEED_10GB_FULL;
5799dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
5809dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	/*
5819dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	 * Check current speed and link status of the PHY register.
5829dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	 * This is a vendor specific register and may have to
5839dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	 * be changed for other copper PHYs.
5849dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	 */
5859dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	for (time_out = 0; time_out < max_time_out; time_out++) {
5869dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		udelay(10);
5879dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		status = hw->phy.ops.read_reg(hw,
5889dda173667207fe59d380e522d318c144dc032f7Emil Tantilov					      MDIO_STAT1,
5899dda173667207fe59d380e522d318c144dc032f7Emil Tantilov					      MDIO_MMD_VEND1,
5909dda173667207fe59d380e522d318c144dc032f7Emil Tantilov					      &phy_data);
5919dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		phy_link = phy_data &
5929dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			    IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
5939dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		phy_speed = phy_data &
5949dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			    IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
5959dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
5969dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			*link_up = true;
5979dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			if (phy_speed ==
5989dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			    IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
5999dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				*speed = IXGBE_LINK_SPEED_1GB_FULL;
6009dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			break;
6019dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		}
6029dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	}
6039dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6049dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	return status;
6059dda173667207fe59d380e522d318c144dc032f7Emil Tantilov}
6069dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6079dda173667207fe59d380e522d318c144dc032f7Emil Tantilov/**
6089dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *	ixgbe_setup_phy_link_tnx - Set and restart autoneg
6099dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *	@hw: pointer to hardware structure
6109dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *
6119dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *	Restart autonegotiation and PHY and waits for completion.
6129dda173667207fe59d380e522d318c144dc032f7Emil Tantilov **/
6139dda173667207fe59d380e522d318c144dc032f7Emil Tantilovs32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
6149dda173667207fe59d380e522d318c144dc032f7Emil Tantilov{
6159dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	s32 status = 0;
6169dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	u32 time_out;
6179dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	u32 max_time_out = 10;
6189dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
6199dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	bool autoneg = false;
6209dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	ixgbe_link_speed speed;
6219dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6229dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
6239dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6249dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
6259dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		/* Set or unset auto-negotiation 10G advertisement */
6269dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL,
6279dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     MDIO_MMD_AN,
6289dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     &autoneg_reg);
6299dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6309dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G;
6319dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
6329dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
6339dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6349dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL,
6359dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      MDIO_MMD_AN,
6369dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      autoneg_reg);
6379dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	}
6389dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6399dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
6409dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		/* Set or unset auto-negotiation 1G advertisement */
6419dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
6429dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     MDIO_MMD_AN,
6439dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     &autoneg_reg);
6449dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6459dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
6469dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
6479dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
6489dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6499dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
6509dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      MDIO_MMD_AN,
6519dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      autoneg_reg);
6529dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	}
6539dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6549dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	if (speed & IXGBE_LINK_SPEED_100_FULL) {
6559dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		/* Set or unset auto-negotiation 100M advertisement */
6569dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE,
6579dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     MDIO_MMD_AN,
6589dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				     &autoneg_reg);
6599dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
66050c022e7936354d854091ebdc699872d3432e874Emil Tantilov		autoneg_reg &= ~(ADVERTISE_100FULL |
66150c022e7936354d854091ebdc699872d3432e874Emil Tantilov				 ADVERTISE_100HALF);
6629dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
6639dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			autoneg_reg |= ADVERTISE_100FULL;
6649dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6659dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
6669dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      MDIO_MMD_AN,
6679dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      autoneg_reg);
6689dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	}
6699dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6709dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	/* Restart PHY autonegotiation and wait for completion */
6719dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	hw->phy.ops.read_reg(hw, MDIO_CTRL1,
6729dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			     MDIO_MMD_AN, &autoneg_reg);
6739dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6749dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	autoneg_reg |= MDIO_AN_CTRL1_RESTART;
6759dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6769dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	hw->phy.ops.write_reg(hw, MDIO_CTRL1,
6779dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			      MDIO_MMD_AN, autoneg_reg);
6789dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6799dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	/* Wait for autonegotiation to finish */
6809dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	for (time_out = 0; time_out < max_time_out; time_out++) {
6819dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		udelay(10);
6829dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		/* Restart PHY autonegotiation and wait for completion */
6839dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		status = hw->phy.ops.read_reg(hw, MDIO_STAT1,
6849dda173667207fe59d380e522d318c144dc032f7Emil Tantilov					      MDIO_MMD_AN,
6859dda173667207fe59d380e522d318c144dc032f7Emil Tantilov					      &autoneg_reg);
6869dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6879dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		autoneg_reg &= MDIO_AN_STAT1_COMPLETE;
6889dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		if (autoneg_reg == MDIO_AN_STAT1_COMPLETE)
6899dda173667207fe59d380e522d318c144dc032f7Emil Tantilov			break;
6909dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	}
6919dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6929dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	if (time_out == max_time_out) {
6939dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		status = IXGBE_ERR_LINK_SETUP;
6949dda173667207fe59d380e522d318c144dc032f7Emil Tantilov		hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out");
6959dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	}
6969dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
6979dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	return status;
6989dda173667207fe59d380e522d318c144dc032f7Emil Tantilov}
6999dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
7009dda173667207fe59d380e522d318c144dc032f7Emil Tantilov/**
7019dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *  ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version
7029dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *  @hw: pointer to hardware structure
7039dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *  @firmware_version: pointer to the PHY Firmware Version
7049dda173667207fe59d380e522d318c144dc032f7Emil Tantilov **/
7059dda173667207fe59d380e522d318c144dc032f7Emil Tantilovs32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
7069dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				       u16 *firmware_version)
7079dda173667207fe59d380e522d318c144dc032f7Emil Tantilov{
7089dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	s32 status = 0;
7099dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
7109dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
7119dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      MDIO_MMD_VEND1,
7129dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      firmware_version);
7139dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
7149dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	return status;
7159dda173667207fe59d380e522d318c144dc032f7Emil Tantilov}
7169dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
7179dda173667207fe59d380e522d318c144dc032f7Emil Tantilov/**
7189dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *  ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version
7199dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *  @hw: pointer to hardware structure
7209dda173667207fe59d380e522d318c144dc032f7Emil Tantilov *  @firmware_version: pointer to the PHY Firmware Version
7219dda173667207fe59d380e522d318c144dc032f7Emil Tantilov **/
7229dda173667207fe59d380e522d318c144dc032f7Emil Tantilovs32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
7239dda173667207fe59d380e522d318c144dc032f7Emil Tantilov					   u16 *firmware_version)
7249dda173667207fe59d380e522d318c144dc032f7Emil Tantilov{
7259dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	s32 status = 0;
7269dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
7279dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	status = hw->phy.ops.read_reg(hw, AQ_FW_REV,
7289dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      MDIO_MMD_VEND1,
7299dda173667207fe59d380e522d318c144dc032f7Emil Tantilov				      firmware_version);
7309dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
7319dda173667207fe59d380e522d318c144dc032f7Emil Tantilov	return status;
7329dda173667207fe59d380e522d318c144dc032f7Emil Tantilov}
7339dda173667207fe59d380e522d318c144dc032f7Emil Tantilov
7349dda173667207fe59d380e522d318c144dc032f7Emil Tantilov/**
735c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore *  ixgbe_reset_phy_nl - Performs a PHY reset
736c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore *  @hw: pointer to hardware structure
737c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore **/
738c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmores32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
739c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore{
740c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	u16 phy_offset, control, eword, edata, block_crc;
741c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	bool end_data = false;
742c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	u16 list_offset, data_offset;
743c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	u16 phy_data = 0;
744c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	s32 ret_val = 0;
745c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	u32 i;
746c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
7476b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings	hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &phy_data);
748c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
749c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	/* reset the PHY and poll for completion */
7506b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings	hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
7516b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings	                      (phy_data | MDIO_CTRL1_RESET));
752c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
753c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	for (i = 0; i < 100; i++) {
7546b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings		hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
7556b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings		                     &phy_data);
7566b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings		if ((phy_data & MDIO_CTRL1_RESET) == 0)
757c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			break;
758032b4325b61b03f87f0346d0e92e39f785e24105Don Skidmore		usleep_range(10000, 20000);
759c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	}
760c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
7616b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings	if ((phy_data & MDIO_CTRL1_RESET) != 0) {
762c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		hw_dbg(hw, "PHY reset did not complete.\n");
763c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		ret_val = IXGBE_ERR_PHY;
764c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		goto out;
765c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	}
766c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
767c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	/* Get init offsets */
768c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
769c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	                                              &data_offset);
770c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	if (ret_val != 0)
771c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		goto out;
772c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
773c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	ret_val = hw->eeprom.ops.read(hw, data_offset, &block_crc);
774c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	data_offset++;
775c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	while (!end_data) {
776c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		/*
777c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		 * Read control word from PHY init contents offset
778c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		 */
779c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		ret_val = hw->eeprom.ops.read(hw, data_offset, &eword);
780c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		control = (eword & IXGBE_CONTROL_MASK_NL) >>
781c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		           IXGBE_CONTROL_SHIFT_NL;
782c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		edata = eword & IXGBE_DATA_MASK_NL;
783c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		switch (control) {
784c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		case IXGBE_DELAY_NL:
785c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			data_offset++;
786c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			hw_dbg(hw, "DELAY: %d MS\n", edata);
787032b4325b61b03f87f0346d0e92e39f785e24105Don Skidmore			usleep_range(edata * 1000, edata * 2000);
788c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			break;
789c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		case IXGBE_DATA_NL:
790d6dbee861386cd3f4cee62bcf28597e63e251e0cFrans Pop			hw_dbg(hw, "DATA:\n");
791c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			data_offset++;
792c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			hw->eeprom.ops.read(hw, data_offset++,
793c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			                    &phy_offset);
794c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			for (i = 0; i < edata; i++) {
795c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				hw->eeprom.ops.read(hw, data_offset, &eword);
796c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				hw->phy.ops.write_reg(hw, phy_offset,
7976b73e10d2d89f9ce773f9b47d61b195936d059baBen Hutchings				                      MDIO_MMD_PMAPMD, eword);
798c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				hw_dbg(hw, "Wrote %4.4x to %4.4x\n", eword,
799c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				       phy_offset);
800c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				data_offset++;
801c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				phy_offset++;
802c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			}
803c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			break;
804c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		case IXGBE_CONTROL_NL:
805c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			data_offset++;
806d6dbee861386cd3f4cee62bcf28597e63e251e0cFrans Pop			hw_dbg(hw, "CONTROL:\n");
807c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			if (edata == IXGBE_CONTROL_EOL_NL) {
808c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				hw_dbg(hw, "EOL\n");
809c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				end_data = true;
810c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			} else if (edata == IXGBE_CONTROL_SOL_NL) {
811c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				hw_dbg(hw, "SOL\n");
812c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			} else {
813c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				hw_dbg(hw, "Bad control value\n");
814c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				ret_val = IXGBE_ERR_PHY;
815c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				goto out;
816c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			}
817c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			break;
818c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		default:
819c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			hw_dbg(hw, "Bad control type\n");
820c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			ret_val = IXGBE_ERR_PHY;
821c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			goto out;
822c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		}
823c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	}
824c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
825c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmoreout:
826c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	return ret_val;
827c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore}
828c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
829c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore/**
83076d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov *  ixgbe_identify_sfp_module_generic - Identifies SFP modules
831c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore *  @hw: pointer to hardware structure
832c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore *
83376d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov *  Searches for and identifies the SFP module and assigns appropriate PHY type.
834c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore **/
835c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmores32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
836c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore{
8378ef78adcb03b1fcb53c3bd62df4e96c1d2706c58Peter P Waskiewicz Jr	struct ixgbe_adapter *adapter = hw->back;
838c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
839c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	u32 vendor_oui = 0;
840553b449784e27bb7244c41aa27397d29f213e5a3PJ Waskiewicz	enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
841c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	u8 identifier = 0;
842c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	u8 comp_codes_1g = 0;
843c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	u8 comp_codes_10g = 0;
84411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u8 oui_bytes[3] = {0, 0, 0};
845537d58a00a8756189b10ffc1309c0131d57b6320Peter P Waskiewicz Jr	u8 cable_tech = 0;
846ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore	u8 cable_spec = 0;
84711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u16 enforce_sfp = 0;
848c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
8498ca783ab78e3fa518885c4fef93d0972e450a4deDon Skidmore	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) {
8508ca783ab78e3fa518885c4fef93d0972e450a4deDon Skidmore		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
8518ca783ab78e3fa518885c4fef93d0972e450a4deDon Skidmore		status = IXGBE_ERR_SFP_NOT_PRESENT;
8528ca783ab78e3fa518885c4fef93d0972e450a4deDon Skidmore		goto out;
8538ca783ab78e3fa518885c4fef93d0972e450a4deDon Skidmore	}
8548ca783ab78e3fa518885c4fef93d0972e450a4deDon Skidmore
85576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	status = hw->phy.ops.read_i2c_eeprom(hw,
85676d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov					     IXGBE_SFF_IDENTIFIER,
857c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	                                     &identifier);
858c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
85976d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	if (status == IXGBE_ERR_SWFW_SYNC ||
86076d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	    status == IXGBE_ERR_I2C ||
86176d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	    status == IXGBE_ERR_SFP_NOT_PRESENT)
86276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		goto err_read_i2c_eeprom;
863c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
86476d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	/* LAN ID is needed for sfp_type determination */
86576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	hw->mac.ops.set_lan_id(hw);
86676d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
86776d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	if (identifier != IXGBE_SFF_IDENTIFIER_SFP) {
86876d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		hw->phy.type = ixgbe_phy_sfp_unsupported;
86976d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		status = IXGBE_ERR_SFP_NOT_SUPPORTED;
87076d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	} else {
87176d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		status = hw->phy.ops.read_i2c_eeprom(hw,
87276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov						     IXGBE_SFF_1GBE_COMP_CODES,
87376d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov						     &comp_codes_1g);
87476d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
87576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		if (status == IXGBE_ERR_SWFW_SYNC ||
87676d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		    status == IXGBE_ERR_I2C ||
87776d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		    status == IXGBE_ERR_SFP_NOT_PRESENT)
87876d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			goto err_read_i2c_eeprom;
87976d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
88076d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		status = hw->phy.ops.read_i2c_eeprom(hw,
88176d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov						     IXGBE_SFF_10GBE_COMP_CODES,
88276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov						     &comp_codes_10g);
88376d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
88476d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		if (status == IXGBE_ERR_SWFW_SYNC ||
88576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		    status == IXGBE_ERR_I2C ||
88676d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		    status == IXGBE_ERR_SFP_NOT_PRESENT)
88776d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			goto err_read_i2c_eeprom;
88876d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		status = hw->phy.ops.read_i2c_eeprom(hw,
88976d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov						     IXGBE_SFF_CABLE_TECHNOLOGY,
89076d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov						     &cable_tech);
89176d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
89276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		if (status == IXGBE_ERR_SWFW_SYNC ||
89376d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		    status == IXGBE_ERR_I2C ||
89476d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		    status == IXGBE_ERR_SFP_NOT_PRESENT)
89576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			goto err_read_i2c_eeprom;
89676d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
89776d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		 /* ID Module
89876d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * =========
89976d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * 0   SFP_DA_CU
90076d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * 1   SFP_SR
90176d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * 2   SFP_LR
90276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * 3   SFP_DA_CORE0 - 82599-specific
90376d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * 4   SFP_DA_CORE1 - 82599-specific
90476d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * 5   SFP_SR/LR_CORE0 - 82599-specific
90576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * 6   SFP_SR/LR_CORE1 - 82599-specific
90676d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * 7   SFP_act_lmt_DA_CORE0 - 82599-specific
90776d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * 8   SFP_act_lmt_DA_CORE1 - 82599-specific
90876d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * 9   SFP_1g_cu_CORE0 - 82599-specific
90976d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  * 10  SFP_1g_cu_CORE1 - 82599-specific
91076d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		  */
91111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (hw->mac.type == ixgbe_mac_82598EB) {
912537d58a00a8756189b10ffc1309c0131d57b6320Peter P Waskiewicz Jr			if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
91311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
91411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
91511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				hw->phy.sfp_type = ixgbe_sfp_type_sr;
91611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
91711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				hw->phy.sfp_type = ixgbe_sfp_type_lr;
91811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			else
91911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				hw->phy.sfp_type = ixgbe_sfp_type_unknown;
92011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		} else if (hw->mac.type == ixgbe_mac_82599EB) {
921ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore			if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
92211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				if (hw->bus.lan_id == 0)
92311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz					hw->phy.sfp_type =
92411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz					             ixgbe_sfp_type_da_cu_core0;
92511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				else
92611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz					hw->phy.sfp_type =
92711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz					             ixgbe_sfp_type_da_cu_core1;
928ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore			} else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) {
929ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore				hw->phy.ops.read_i2c_eeprom(
930ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore						hw, IXGBE_SFF_CABLE_SPEC_COMP,
931ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore						&cable_spec);
932ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore				if (cable_spec &
933ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore				    IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) {
934ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore					if (hw->bus.lan_id == 0)
935ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore						hw->phy.sfp_type =
936ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore						ixgbe_sfp_type_da_act_lmt_core0;
937ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore					else
938ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore						hw->phy.sfp_type =
939ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore						ixgbe_sfp_type_da_act_lmt_core1;
940ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore				} else {
941ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore					hw->phy.sfp_type =
94276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov							ixgbe_sfp_type_unknown;
943ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore				}
94476d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			} else if (comp_codes_10g &
94576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov				   (IXGBE_SFF_10GBASESR_CAPABLE |
94676d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov				    IXGBE_SFF_10GBASELR_CAPABLE)) {
94711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				if (hw->bus.lan_id == 0)
94811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz					hw->phy.sfp_type =
94911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz					              ixgbe_sfp_type_srlr_core0;
95011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				else
95111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz					hw->phy.sfp_type =
95211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz					              ixgbe_sfp_type_srlr_core1;
95376d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			} else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) {
954cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore				if (hw->bus.lan_id == 0)
955cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore					hw->phy.sfp_type =
956cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore						ixgbe_sfp_type_1g_cu_core0;
957cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore				else
958cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore					hw->phy.sfp_type =
959cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore						ixgbe_sfp_type_1g_cu_core1;
96076d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			} else {
96111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				hw->phy.sfp_type = ixgbe_sfp_type_unknown;
96276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			}
96311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		}
964c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
965553b449784e27bb7244c41aa27397d29f213e5a3PJ Waskiewicz		if (hw->phy.sfp_type != stored_sfp_type)
966553b449784e27bb7244c41aa27397d29f213e5a3PJ Waskiewicz			hw->phy.sfp_setup_needed = true;
967553b449784e27bb7244c41aa27397d29f213e5a3PJ Waskiewicz
968553b449784e27bb7244c41aa27397d29f213e5a3PJ Waskiewicz		/* Determine if the SFP+ PHY is dual speed or not. */
96950ac58ba1d707df33f0c398ae700214e49bf918fPeter P Waskiewicz Jr		hw->phy.multispeed_fiber = false;
970553b449784e27bb7244c41aa27397d29f213e5a3PJ Waskiewicz		if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
971553b449784e27bb7244c41aa27397d29f213e5a3PJ Waskiewicz		   (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
972553b449784e27bb7244c41aa27397d29f213e5a3PJ Waskiewicz		   ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
973553b449784e27bb7244c41aa27397d29f213e5a3PJ Waskiewicz		   (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
974553b449784e27bb7244c41aa27397d29f213e5a3PJ Waskiewicz			hw->phy.multispeed_fiber = true;
975553b449784e27bb7244c41aa27397d29f213e5a3PJ Waskiewicz
976c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		/* Determine PHY vendor */
97704193058c1005551af93f04a4b975fbd7f95cad5Peter P Waskiewicz Jr		if (hw->phy.type != ixgbe_phy_nl) {
978c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			hw->phy.id = identifier;
97976d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			status = hw->phy.ops.read_i2c_eeprom(hw,
980c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			                            IXGBE_SFF_VENDOR_OUI_BYTE0,
981c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			                            &oui_bytes[0]);
98276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
98376d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			if (status == IXGBE_ERR_SWFW_SYNC ||
98476d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			    status == IXGBE_ERR_I2C ||
98576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			    status == IXGBE_ERR_SFP_NOT_PRESENT)
98676d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov				goto err_read_i2c_eeprom;
98776d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
98876d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			status = hw->phy.ops.read_i2c_eeprom(hw,
989c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			                            IXGBE_SFF_VENDOR_OUI_BYTE1,
990c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			                            &oui_bytes[1]);
99176d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
99276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			if (status == IXGBE_ERR_SWFW_SYNC ||
99376d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			    status == IXGBE_ERR_I2C ||
99476d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			    status == IXGBE_ERR_SFP_NOT_PRESENT)
99576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov				goto err_read_i2c_eeprom;
99676d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
99776d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			status = hw->phy.ops.read_i2c_eeprom(hw,
998c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			                            IXGBE_SFF_VENDOR_OUI_BYTE2,
999c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			                            &oui_bytes[2]);
1000c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
100176d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			if (status == IXGBE_ERR_SWFW_SYNC ||
100276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			    status == IXGBE_ERR_I2C ||
100376d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov			    status == IXGBE_ERR_SFP_NOT_PRESENT)
100476d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov				goto err_read_i2c_eeprom;
100576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
1006c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			vendor_oui =
1007c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			  ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
1008c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			   (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
1009c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			   (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
1010c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1011c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			switch (vendor_oui) {
1012c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			case IXGBE_SFF_VENDOR_OUI_TYCO:
1013537d58a00a8756189b10ffc1309c0131d57b6320Peter P Waskiewicz Jr				if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
1014ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore					hw->phy.type =
101576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov						    ixgbe_phy_sfp_passive_tyco;
1016c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				break;
1017c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			case IXGBE_SFF_VENDOR_OUI_FTL:
1018ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore				if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
1019ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore					hw->phy.type = ixgbe_phy_sfp_ftl_active;
1020ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore				else
1021ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore					hw->phy.type = ixgbe_phy_sfp_ftl;
1022c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				break;
1023c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			case IXGBE_SFF_VENDOR_OUI_AVAGO:
1024c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				hw->phy.type = ixgbe_phy_sfp_avago;
1025c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				break;
102611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			case IXGBE_SFF_VENDOR_OUI_INTEL:
102711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				hw->phy.type = ixgbe_phy_sfp_intel;
102811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				break;
1029c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			default:
1030537d58a00a8756189b10ffc1309c0131d57b6320Peter P Waskiewicz Jr				if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
1031ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore					hw->phy.type =
103276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov						 ixgbe_phy_sfp_passive_unknown;
1033ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore				else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
1034ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore					hw->phy.type =
1035ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore						ixgbe_phy_sfp_active_unknown;
1036c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				else
1037c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore					hw->phy.type = ixgbe_phy_sfp_unknown;
1038c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				break;
1039c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			}
1040c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		}
1041fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P
104276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		/* Allow any DA cable vendor */
1043ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore		if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE |
1044ea0a04dfc1c6701489edabf47f608d8aa474cbabDon Skidmore		    IXGBE_SFF_DA_ACTIVE_CABLE)) {
1045fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P			status = 0;
1046fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P			goto out;
1047fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P		}
1048fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P
1049cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore		/* Verify supported 1G SFP modules */
1050cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore		if (comp_codes_10g == 0 &&
1051cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore		    !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
1052cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore		      hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0)) {
1053fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P			hw->phy.type = ixgbe_phy_sfp_unsupported;
1054fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P			status = IXGBE_ERR_SFP_NOT_SUPPORTED;
1055fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P			goto out;
1056fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P		}
1057fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P
1058fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P		/* Anything else 82598-based is supported */
1059fa466e91bdf214e6e136e9da9a46a52775a1e884Waskiewicz Jr, Peter P		if (hw->mac.type == ixgbe_mac_82598EB) {
106011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			status = 0;
106111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto out;
106211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		}
106311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
106404193058c1005551af93f04a4b975fbd7f95cad5Peter P Waskiewicz Jr		hw->mac.ops.get_device_caps(hw, &enforce_sfp);
1065cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore		if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
1066cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore		    !((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) ||
1067cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore		      (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1))) {
106811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			/* Make sure we're a supported PHY type */
106911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			if (hw->phy.type == ixgbe_phy_sfp_intel) {
107011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz				status = 0;
107111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			} else {
10728ef78adcb03b1fcb53c3bd62df4e96c1d2706c58Peter P Waskiewicz Jr				if (hw->allow_unsupported_sfp) {
10738ef78adcb03b1fcb53c3bd62df4e96c1d2706c58Peter P Waskiewicz Jr					e_warn(drv, "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.");
10748ef78adcb03b1fcb53c3bd62df4e96c1d2706c58Peter P Waskiewicz Jr					status = 0;
10758ef78adcb03b1fcb53c3bd62df4e96c1d2706c58Peter P Waskiewicz Jr				} else {
10768ef78adcb03b1fcb53c3bd62df4e96c1d2706c58Peter P Waskiewicz Jr					hw_dbg(hw,
10778ef78adcb03b1fcb53c3bd62df4e96c1d2706c58Peter P Waskiewicz Jr					       "SFP+ module not supported\n");
10788ef78adcb03b1fcb53c3bd62df4e96c1d2706c58Peter P Waskiewicz Jr					hw->phy.type =
10798ef78adcb03b1fcb53c3bd62df4e96c1d2706c58Peter P Waskiewicz Jr						ixgbe_phy_sfp_unsupported;
10808ef78adcb03b1fcb53c3bd62df4e96c1d2706c58Peter P Waskiewicz Jr					status = IXGBE_ERR_SFP_NOT_SUPPORTED;
10818ef78adcb03b1fcb53c3bd62df4e96c1d2706c58Peter P Waskiewicz Jr				}
108211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			}
108311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		} else {
108411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			status = 0;
108511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		}
1086c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	}
1087c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1088c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmoreout:
1089c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	return status;
109076d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov
109176d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantiloverr_read_i2c_eeprom:
109276d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	hw->phy.sfp_type = ixgbe_sfp_type_not_present;
109376d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	if (hw->phy.type != ixgbe_phy_nl) {
109476d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		hw->phy.id = 0;
109576d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov		hw->phy.type = ixgbe_phy_unknown;
109676d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	}
109776d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov	return IXGBE_ERR_SFP_NOT_PRESENT;
1098c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore}
1099c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1100c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore/**
110176d97dd4c44c6847029ae9021fe0d880cad90d33Emil Tantilov *  ixgbe_get_sfp_init_sequence_offsets - Provides offset of PHY init sequence
1102c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore *  @hw: pointer to hardware structure
1103c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore *  @list_offset: offset to the SFP ID list
1104c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore *  @data_offset: offset to the SFP data block
110575f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov *
110675f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov *  Checks the MAC's EEPROM to see if it supports a given SFP+ module type, if
110775f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov *  so it returns the offsets to the phy init sequence block.
1108c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore **/
1109c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmores32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
1110c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore                                        u16 *list_offset,
1111c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore                                        u16 *data_offset)
1112c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore{
1113c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	u16 sfp_id;
1114cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore	u16 sfp_type = hw->phy.sfp_type;
1115c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1116c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	if (hw->phy.sfp_type == ixgbe_sfp_type_unknown)
1117c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1118c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1119c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
1120c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		return IXGBE_ERR_SFP_NOT_PRESENT;
1121c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1122c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	if ((hw->device_id == IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM) &&
1123c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	    (hw->phy.sfp_type == ixgbe_sfp_type_da_cu))
1124c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1125c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1126cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore	/*
1127cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore	 * Limiting active cables and 1G Phys must be initialized as
1128cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore	 * SR modules
1129cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore	 */
1130cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore	if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 ||
1131cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore	    sfp_type == ixgbe_sfp_type_1g_cu_core0)
1132cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore		sfp_type = ixgbe_sfp_type_srlr_core0;
1133cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore	else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 ||
1134cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore	         sfp_type == ixgbe_sfp_type_1g_cu_core1)
1135cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore		sfp_type = ixgbe_sfp_type_srlr_core1;
1136cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore
1137c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	/* Read offset to PHY init contents */
1138c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset);
1139c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1140c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	if ((!*list_offset) || (*list_offset == 0xFFFF))
114111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
1142c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1143c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	/* Shift offset to first ID word */
1144c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	(*list_offset)++;
1145c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1146c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	/*
1147c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	 * Find the matching SFP ID in the EEPROM
1148c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	 * and program the init sequence
1149c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	 */
1150c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	hw->eeprom.ops.read(hw, *list_offset, &sfp_id);
1151c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1152c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	while (sfp_id != IXGBE_PHY_INIT_END_NL) {
1153cb836a977f71f76ccbb1ff35b9c113ace96377e9Don Skidmore		if (sfp_id == sfp_type) {
1154c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			(*list_offset)++;
1155c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			hw->eeprom.ops.read(hw, *list_offset, data_offset);
1156c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			if ((!*data_offset) || (*data_offset == 0xFFFF)) {
1157c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				hw_dbg(hw, "SFP+ module not supported\n");
1158c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				return IXGBE_ERR_SFP_NOT_SUPPORTED;
1159c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			} else {
1160c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				break;
1161c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			}
1162c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		} else {
1163c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			(*list_offset) += 2;
1164c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore			if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id))
1165c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore				return IXGBE_ERR_PHY;
1166c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		}
1167c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	}
1168c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1169c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	if (sfp_id == IXGBE_PHY_INIT_END_NL) {
1170c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		hw_dbg(hw, "No matching SFP+ module found\n");
1171c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1172c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	}
1173c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1174c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore	return 0;
1175c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore}
1176c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore
1177c4900be053d376dfe4f603d000aa5e4c60745decDonald Skidmore/**
117811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface
117911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
118011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @byte_offset: EEPROM byte offset to read
118111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @eeprom_data: value read
118211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
118311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Performs byte read operation to SFP module's EEPROM over I2C interface.
118411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
118511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczs32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
118611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz                                  u8 *eeprom_data)
118711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
118811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	return hw->phy.ops.read_i2c_byte(hw, byte_offset,
118911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	                                 IXGBE_I2C_EEPROM_DEV_ADDR,
119011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	                                 eeprom_data);
119111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
119211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
119311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
119411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
119511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
119611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @byte_offset: EEPROM byte offset to write
119711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @eeprom_data: value to write
119811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
119911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Performs byte write operation to SFP module's EEPROM over I2C interface.
120011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
120111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczs32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
120211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz                                   u8 eeprom_data)
120311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
120411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	return hw->phy.ops.write_i2c_byte(hw, byte_offset,
120511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	                                  IXGBE_I2C_EEPROM_DEV_ADDR,
120611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	                                  eeprom_data);
120711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
120811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
120911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
121011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
121111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
121211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @byte_offset: byte offset to read
121311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @data: value read
121411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
121511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Performs byte read operation to SFP module's EEPROM over I2C interface at
12163fbaa3ac0d47e0cbad9bb65f0b71a5ce3ef1b76cEmil Tantilov *  a specified device address.
121711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
121811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczs32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
121911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz                                u8 dev_addr, u8 *data)
122011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
122111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	s32 status = 0;
122275f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov	u32 max_retry = 10;
122311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 retry = 0;
122475f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov	u16 swfw_mask = 0;
12253db1cd5c05f35fb43eb134df6f321de4e63141f2Rusty Russell	bool nack = true;
12263fbaa3ac0d47e0cbad9bb65f0b71a5ce3ef1b76cEmil Tantilov	*data = 0;
122711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
122875f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
122975f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov		swfw_mask = IXGBE_GSSR_PHY1_SM;
123075f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov	else
123175f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov		swfw_mask = IXGBE_GSSR_PHY0_SM;
123275f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov
123311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	do {
12346d980c3e50189e5437fdb5ef2c6e6d3c282035dcEmil Tantilov		if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 0) {
123575f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov			status = IXGBE_ERR_SWFW_SYNC;
123675f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov			goto read_byte_out;
123775f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov		}
123875f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov
123911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		ixgbe_i2c_start(hw);
124011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
124111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		/* Device Address and write indication */
124211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
124311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
124411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
124511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
124611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_get_i2c_ack(hw);
124711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
124811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
124911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
125011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
125111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
125211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
125311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
125411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_get_i2c_ack(hw);
125511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
125611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
125711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
125811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		ixgbe_i2c_start(hw);
125911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
126011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		/* Device Address and read indication */
126111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1));
126211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
126311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
126411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
126511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_get_i2c_ack(hw);
126611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
126711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
126811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
126911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_clock_in_i2c_byte(hw, data);
127011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
127111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
127211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
127311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_clock_out_i2c_bit(hw, nack);
127411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
127511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
127611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
127711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		ixgbe_i2c_stop(hw);
127811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		break;
127911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
128011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczfail:
12816d980c3e50189e5437fdb5ef2c6e6d3c282035dcEmil Tantilov		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
128275f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov		msleep(100);
128311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		ixgbe_i2c_bus_clear(hw);
128411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		retry++;
128511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (retry < max_retry)
128611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			hw_dbg(hw, "I2C byte read error - Retrying.\n");
128711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		else
128811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			hw_dbg(hw, "I2C byte read error.\n");
128911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
129011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	} while (retry < max_retry);
129111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
12926d980c3e50189e5437fdb5ef2c6e6d3c282035dcEmil Tantilov	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
129375f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov
129475f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilovread_byte_out:
129511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	return status;
129611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
129711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
129811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
129911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
130011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
130111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @byte_offset: byte offset to write
130211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @data: value to write
130311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
130411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Performs byte write operation to SFP module's EEPROM over I2C interface at
130511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  a specified device address.
130611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
130711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczs32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
130811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz                                 u8 dev_addr, u8 data)
130911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
131011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	s32 status = 0;
131111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 max_retry = 1;
131211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 retry = 0;
131375f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov	u16 swfw_mask = 0;
131475f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov
131575f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
131675f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov		swfw_mask = IXGBE_GSSR_PHY1_SM;
131775f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov	else
131875f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov		swfw_mask = IXGBE_GSSR_PHY0_SM;
131975f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov
13206d980c3e50189e5437fdb5ef2c6e6d3c282035dcEmil Tantilov	if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 0) {
132175f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov		status = IXGBE_ERR_SWFW_SYNC;
132275f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov		goto write_byte_out;
132375f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov	}
132411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
132511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	do {
132611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		ixgbe_i2c_start(hw);
132711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
132811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
132911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
133011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
133111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
133211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_get_i2c_ack(hw);
133311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
133411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
133511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
133611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
133711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
133811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
133911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
134011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_get_i2c_ack(hw);
134111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
134211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
134311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
134411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_clock_out_i2c_byte(hw, data);
134511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
134611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
134711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
134811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_get_i2c_ack(hw);
134911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
135011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			goto fail;
135111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
135211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		ixgbe_i2c_stop(hw);
135311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		break;
135411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
135511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczfail:
135611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		ixgbe_i2c_bus_clear(hw);
135711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		retry++;
135811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (retry < max_retry)
135911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			hw_dbg(hw, "I2C byte write error - Retrying.\n");
136011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		else
136111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			hw_dbg(hw, "I2C byte write error.\n");
136211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	} while (retry < max_retry);
136311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
13646d980c3e50189e5437fdb5ef2c6e6d3c282035dcEmil Tantilov	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
136575f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov
136675f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilovwrite_byte_out:
136711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	return status;
136811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
136911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
137011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
137111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_i2c_start - Sets I2C start condition
137211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
137311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
137411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Sets I2C start condition (High -> Low on SDA while SCL is High)
137511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
137611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic void ixgbe_i2c_start(struct ixgbe_hw *hw)
137711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
137811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
137911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
138011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Start condition must begin with data and clock high */
138111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	ixgbe_set_i2c_data(hw, &i2cctl, 1);
138211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	ixgbe_raise_i2c_clk(hw, &i2cctl);
138311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
138411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Setup time for start condition (4.7us) */
138511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_SU_STA);
138611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
138711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	ixgbe_set_i2c_data(hw, &i2cctl, 0);
138811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
138911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Hold time for start condition (4us) */
139011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_HD_STA);
139111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
139211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	ixgbe_lower_i2c_clk(hw, &i2cctl);
139311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
139411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Minimum low period of clock is 4.7 us */
139511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_LOW);
139611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
139711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
139811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
139911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
140011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_i2c_stop - Sets I2C stop condition
140111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
140211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
140311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Sets I2C stop condition (Low -> High on SDA while SCL is High)
140411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
140511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic void ixgbe_i2c_stop(struct ixgbe_hw *hw)
140611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
140711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
140811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
140911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Stop condition must begin with data low and clock high */
141011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	ixgbe_set_i2c_data(hw, &i2cctl, 0);
141111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	ixgbe_raise_i2c_clk(hw, &i2cctl);
141211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
141311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Setup time for stop condition (4us) */
141411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_SU_STO);
141511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
141611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	ixgbe_set_i2c_data(hw, &i2cctl, 1);
141711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
141811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* bus free time between stop and start (4.7us)*/
141911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_BUF);
142011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
142111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
142211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
142311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C
142411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
142511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @data: data byte to clock in
142611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
142711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Clocks in one byte data via I2C data/clock
142811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
142911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
143011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
143111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	s32 i;
14323db1cd5c05f35fb43eb134df6f321de4e63141f2Rusty Russell	bool bit = false;
143311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
143411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	for (i = 7; i >= 0; i--) {
1435e1befd774a049bdc85cf0ed5b307f913b33e1691Emil Tantilov		ixgbe_clock_in_i2c_bit(hw, &bit);
143611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		*data |= bit << i;
143711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	}
143811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
1439e1befd774a049bdc85cf0ed5b307f913b33e1691Emil Tantilov	return 0;
144011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
144111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
144211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
144311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C
144411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
144511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @data: data byte clocked out
144611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
144711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Clocks out one byte data via I2C data/clock
144811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
144911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
145011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
145111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	s32 status = 0;
145211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	s32 i;
145311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 i2cctl;
14543db1cd5c05f35fb43eb134df6f321de4e63141f2Rusty Russell	bool bit = false;
145511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
145611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	for (i = 7; i >= 0; i--) {
145711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		bit = (data >> i) & 0x1;
145811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = ixgbe_clock_out_i2c_bit(hw, bit);
145911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
146011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (status != 0)
146111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			break;
146211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	}
146311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
146411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Release SDA line (set high) */
146511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
146611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	i2cctl |= IXGBE_I2C_DATA_OUT;
146711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, i2cctl);
1468176f950d310c81b7fafd96aabe53704f778ce269Emil Tantilov	IXGBE_WRITE_FLUSH(hw);
146911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
147011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	return status;
147111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
147211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
147311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
147411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_get_i2c_ack - Polls for I2C ACK
147511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
147611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
147711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Clocks in/out one bit via I2C data/clock
147811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
147911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
148011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
1481e1befd774a049bdc85cf0ed5b307f913b33e1691Emil Tantilov	s32 status = 0;
148211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 i = 0;
148311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
148411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 timeout = 10;
14853db1cd5c05f35fb43eb134df6f321de4e63141f2Rusty Russell	bool ack = true;
148611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
1487e1befd774a049bdc85cf0ed5b307f913b33e1691Emil Tantilov	ixgbe_raise_i2c_clk(hw, &i2cctl);
148811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
148911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
149011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Minimum high period of clock is 4us */
149111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_HIGH);
149211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
149311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Poll for ACK.  Note that ACK in I2C spec is
149411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	 * transition from 1 to 0 */
149511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	for (i = 0; i < timeout; i++) {
149611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
149711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		ack = ixgbe_get_i2c_data(&i2cctl);
149811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
149911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		udelay(1);
150011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		if (ack == 0)
150111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz			break;
150211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	}
150311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
150411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	if (ack == 1) {
150511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		hw_dbg(hw, "I2C ack was not received.\n");
150611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = IXGBE_ERR_I2C;
150711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	}
150811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
150911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	ixgbe_lower_i2c_clk(hw, &i2cctl);
151011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
151111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Minimum low period of clock is 4.7 us */
151211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_LOW);
151311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
151411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	return status;
151511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
151611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
151711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
151811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
151911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
152011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @data: read data value
152111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
152211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Clocks in one bit via I2C data/clock
152311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
152411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
152511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
152611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
152711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
1528e1befd774a049bdc85cf0ed5b307f913b33e1691Emil Tantilov	ixgbe_raise_i2c_clk(hw, &i2cctl);
152911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
153011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Minimum high period of clock is 4us */
153111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_HIGH);
153211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
153311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
153411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	*data = ixgbe_get_i2c_data(&i2cctl);
153511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
153611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	ixgbe_lower_i2c_clk(hw, &i2cctl);
153711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
153811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Minimum low period of clock is 4.7 us */
153911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_LOW);
154011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
1541e1befd774a049bdc85cf0ed5b307f913b33e1691Emil Tantilov	return 0;
154211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
154311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
154411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
154511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
154611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
154711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @data: data value to write
154811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
154911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Clocks out one bit via I2C data/clock
155011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
155111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
155211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
155311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	s32 status;
155411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
155511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
155611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	status = ixgbe_set_i2c_data(hw, &i2cctl, data);
155711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	if (status == 0) {
1558e1befd774a049bdc85cf0ed5b307f913b33e1691Emil Tantilov		ixgbe_raise_i2c_clk(hw, &i2cctl);
155911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
156011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		/* Minimum high period of clock is 4us */
156111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		udelay(IXGBE_I2C_T_HIGH);
156211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
156311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		ixgbe_lower_i2c_clk(hw, &i2cctl);
156411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
156511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		/* Minimum low period of clock is 4.7 us.
156611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		 * This also takes care of the data hold time.
156711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		 */
156811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		udelay(IXGBE_I2C_T_LOW);
156911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	} else {
157011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = IXGBE_ERR_I2C;
157111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		hw_dbg(hw, "I2C data was not set to %X\n", data);
157211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	}
157311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
157411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	return status;
157511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
157611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
157711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_raise_i2c_clk - Raises the I2C SCL clock
157811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
157911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @i2cctl: Current value of I2CCTL register
158011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
158111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Raises the I2C clock line '0'->'1'
158211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
1583e1befd774a049bdc85cf0ed5b307f913b33e1691Emil Tantilovstatic void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
158411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
158511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	*i2cctl |= IXGBE_I2C_CLK_OUT;
158611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
158711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
1588945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGBE_WRITE_FLUSH(hw);
158911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
159011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* SCL rise time (1000ns) */
159111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_RISE);
159211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
159311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
159411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
159511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_lower_i2c_clk - Lowers the I2C SCL clock
159611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
159711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @i2cctl: Current value of I2CCTL register
159811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
159911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Lowers the I2C clock line '1'->'0'
160011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
160111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
160211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
160311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
160411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	*i2cctl &= ~IXGBE_I2C_CLK_OUT;
160511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
160611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
1607945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGBE_WRITE_FLUSH(hw);
160811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
160911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* SCL fall time (300ns) */
161011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_FALL);
161111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
161211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
161311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
161411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_set_i2c_data - Sets the I2C data bit
161511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
161611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @i2cctl: Current value of I2CCTL register
161711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @data: I2C data value (0 or 1) to set
161811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
161911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Sets the I2C data bit
162011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
162111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
162211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
162311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	s32 status = 0;
162411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
162511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	if (data)
162611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		*i2cctl |= IXGBE_I2C_DATA_OUT;
162711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	else
162811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		*i2cctl &= ~IXGBE_I2C_DATA_OUT;
162911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
163011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
1631945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGBE_WRITE_FLUSH(hw);
163211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
163311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
163411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	udelay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
163511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
163611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Verify data was set correctly */
163711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	*i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
163811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	if (data != ixgbe_get_i2c_data(i2cctl)) {
163911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		status = IXGBE_ERR_I2C;
164011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		hw_dbg(hw, "Error - I2C data was not set to %X.\n", data);
164111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	}
164211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
164311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	return status;
164411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
164511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
164611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
164711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_get_i2c_data - Reads the I2C SDA data bit
164811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
164911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @i2cctl: Current value of I2CCTL register
165011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
165111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Returns the I2C data bit value
165211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
165311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic bool ixgbe_get_i2c_data(u32 *i2cctl)
165411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
165511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	bool data;
165611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
165711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	if (*i2cctl & IXGBE_I2C_DATA_IN)
16583db1cd5c05f35fb43eb134df6f321de4e63141f2Rusty Russell		data = true;
165911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	else
16603db1cd5c05f35fb43eb134df6f321de4e63141f2Rusty Russell		data = false;
166111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
166211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	return data;
166311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
166411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
166511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
166611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  ixgbe_i2c_bus_clear - Clears the I2C bus
166711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  @hw: pointer to hardware structure
166811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *
166911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Clears the I2C bus by sending nine clock pulses.
167011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz *  Used when data line is stuck low.
167111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz **/
167211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewiczstatic void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
167311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz{
167411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
167511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	u32 i;
167611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
167775f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov	ixgbe_i2c_start(hw);
167875f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov
167911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	ixgbe_set_i2c_data(hw, &i2cctl, 1);
168011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
168111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	for (i = 0; i < 9; i++) {
168211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		ixgbe_raise_i2c_clk(hw, &i2cctl);
168311afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
168411afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		/* Min high period of clock is 4us */
168511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		udelay(IXGBE_I2C_T_HIGH);
168611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
168711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		ixgbe_lower_i2c_clk(hw, &i2cctl);
168811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
168911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		/* Min low period of clock is 4.7us*/
169011afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz		udelay(IXGBE_I2C_T_LOW);
169111afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	}
169211afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
169375f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov	ixgbe_i2c_start(hw);
169475f19c3c5eeb67d37ce96e0ea78dc0beb485a723Emil Tantilov
169511afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	/* Put the i2c bus back to default state */
169611afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz	ixgbe_i2c_stop(hw);
169711afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz}
169811afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz
169911afc1b1fd802c11dc0fa986c210602c177f1e21PJ Waskiewicz/**
170025985edcedea6396277003854657b5f3cb31a628Lucas De Marchi *  ixgbe_tn_check_overtemp - Checks if an overtemp occurred.
1701119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala *  @hw: pointer to hardware structure
1702119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala *
1703119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala *  Checks if the LASI temp alarm status was triggered due to overtemp
1704119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala **/
1705119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakalas32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
1706119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala{
1707119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	s32 status = 0;
1708119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	u16 phy_data = 0;
1709119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala
1710119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM)
1711119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala		goto out;
1712119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala
1713119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	/* Check that the LASI temp alarm status was triggered */
1714119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
1715119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	                     MDIO_MMD_PMAPMD, &phy_data);
1716119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala
1717119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM))
1718119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala		goto out;
1719119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala
1720119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	status = IXGBE_ERR_OVERTEMP;
1721119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakalaout:
1722119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala	return status;
1723119fc60a2d20b63439fdae99f0c7022d3dd99defMallikarjuna R Chilakala}
1724