1179055Sjfv/******************************************************************************
2171384Sjfv
3283620Serj  Copyright (c) 2001-2015, Intel Corporation
4171384Sjfv  All rights reserved.
5171384Sjfv
6171384Sjfv  Redistribution and use in source and binary forms, with or without
7171384Sjfv  modification, are permitted provided that the following conditions are met:
8171384Sjfv
9171384Sjfv   1. Redistributions of source code must retain the above copyright notice,
10171384Sjfv      this list of conditions and the following disclaimer.
11171384Sjfv
12171384Sjfv   2. Redistributions in binary form must reproduce the above copyright
13171384Sjfv      notice, this list of conditions and the following disclaimer in the
14171384Sjfv      documentation and/or other materials provided with the distribution.
15171384Sjfv
16171384Sjfv   3. Neither the name of the Intel Corporation nor the names of its
17171384Sjfv      contributors may be used to endorse or promote products derived from
18171384Sjfv      this software without specific prior written permission.
19171384Sjfv
20171384Sjfv  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21171384Sjfv  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22171384Sjfv  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23171384Sjfv  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24171384Sjfv  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25171384Sjfv  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26171384Sjfv  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27171384Sjfv  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28171384Sjfv  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29171384Sjfv  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30171384Sjfv  POSSIBILITY OF SUCH DAMAGE.
31171384Sjfv
32179055Sjfv******************************************************************************/
33179055Sjfv/*$FreeBSD: releng/10.3/sys/dev/ixgbe/ixgbe_phy.c 295528 2016-02-11 16:54:23Z smh $*/
34171384Sjfv
35171384Sjfv#include "ixgbe_api.h"
36171384Sjfv#include "ixgbe_common.h"
37171384Sjfv#include "ixgbe_phy.h"
38171384Sjfv
39190873Sjfvstatic void ixgbe_i2c_start(struct ixgbe_hw *hw);
40190873Sjfvstatic void ixgbe_i2c_stop(struct ixgbe_hw *hw);
41190873Sjfvstatic s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data);
42190873Sjfvstatic s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data);
43190873Sjfvstatic s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw);
44190873Sjfvstatic s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data);
45190873Sjfvstatic s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data);
46230775Sjfvstatic void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
47190873Sjfvstatic void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
48190873Sjfvstatic s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
49283620Serjstatic bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl);
50247822Sjfvstatic s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
51247822Sjfv					  u8 *sff8472_data);
52190873Sjfv
53171384Sjfv/**
54283620Serj * ixgbe_out_i2c_byte_ack - Send I2C byte with ack
55283620Serj * @hw: pointer to the hardware structure
56283620Serj * @byte: byte to send
57283620Serj *
58283620Serj * Returns an error code on error.
59283620Serj */
60283620Serjstatic s32 ixgbe_out_i2c_byte_ack(struct ixgbe_hw *hw, u8 byte)
61283620Serj{
62283620Serj	s32 status;
63283620Serj
64283620Serj	status = ixgbe_clock_out_i2c_byte(hw, byte);
65283620Serj	if (status)
66283620Serj		return status;
67283620Serj	return ixgbe_get_i2c_ack(hw);
68283620Serj}
69283620Serj
70283620Serj/**
71283620Serj * ixgbe_in_i2c_byte_ack - Receive an I2C byte and send ack
72283620Serj * @hw: pointer to the hardware structure
73283620Serj * @byte: pointer to a u8 to receive the byte
74283620Serj *
75283620Serj * Returns an error code on error.
76283620Serj */
77283620Serjstatic s32 ixgbe_in_i2c_byte_ack(struct ixgbe_hw *hw, u8 *byte)
78283620Serj{
79283620Serj	s32 status;
80283620Serj
81283620Serj	status = ixgbe_clock_in_i2c_byte(hw, byte);
82283620Serj	if (status)
83283620Serj		return status;
84283620Serj	/* ACK */
85283620Serj	return ixgbe_clock_out_i2c_bit(hw, FALSE);
86283620Serj}
87283620Serj
88283620Serj/**
89283620Serj * ixgbe_ones_comp_byte_add - Perform one's complement addition
90283620Serj * @add1 - addend 1
91283620Serj * @add2 - addend 2
92283620Serj *
93283620Serj * Returns one's complement 8-bit sum.
94283620Serj */
95283620Serjstatic u8 ixgbe_ones_comp_byte_add(u8 add1, u8 add2)
96283620Serj{
97283620Serj	u16 sum = add1 + add2;
98283620Serj
99283620Serj	sum = (sum & 0xFF) + (sum >> 8);
100283620Serj	return sum & 0xFF;
101283620Serj}
102283620Serj
103283620Serj/**
104283620Serj * ixgbe_read_i2c_combined_generic_int - Perform I2C read combined operation
105283620Serj * @hw: pointer to the hardware structure
106283620Serj * @addr: I2C bus address to read from
107283620Serj * @reg: I2C device register to read from
108283620Serj * @val: pointer to location to receive read value
109283620Serj * @lock: TRUE if to take and release semaphore
110283620Serj *
111283620Serj * Returns an error code on error.
112283620Serj */
113283620Serjstatic s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr,
114283620Serj					       u16 reg, u16 *val, bool lock)
115283620Serj{
116283620Serj	u32 swfw_mask = hw->phy.phy_semaphore_mask;
117283620Serj	int max_retry = 10;
118283620Serj	int retry = 0;
119283620Serj	u8 csum_byte;
120283620Serj	u8 high_bits;
121283620Serj	u8 low_bits;
122283620Serj	u8 reg_high;
123283620Serj	u8 csum;
124283620Serj
125283620Serj	if (hw->mac.type >= ixgbe_mac_X550)
126283620Serj		max_retry = 3;
127283620Serj	reg_high = ((reg >> 7) & 0xFE) | 1;	/* Indicate read combined */
128283620Serj	csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF);
129283620Serj	csum = ~csum;
130283620Serj	do {
131283620Serj		if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
132283620Serj			return IXGBE_ERR_SWFW_SYNC;
133283620Serj		ixgbe_i2c_start(hw);
134283620Serj		/* Device Address and write indication */
135283620Serj		if (ixgbe_out_i2c_byte_ack(hw, addr))
136283620Serj			goto fail;
137283620Serj		/* Write bits 14:8 */
138283620Serj		if (ixgbe_out_i2c_byte_ack(hw, reg_high))
139283620Serj			goto fail;
140283620Serj		/* Write bits 7:0 */
141283620Serj		if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF))
142283620Serj			goto fail;
143283620Serj		/* Write csum */
144283620Serj		if (ixgbe_out_i2c_byte_ack(hw, csum))
145283620Serj			goto fail;
146283620Serj		/* Re-start condition */
147283620Serj		ixgbe_i2c_start(hw);
148283620Serj		/* Device Address and read indication */
149283620Serj		if (ixgbe_out_i2c_byte_ack(hw, addr | 1))
150283620Serj			goto fail;
151283620Serj		/* Get upper bits */
152283620Serj		if (ixgbe_in_i2c_byte_ack(hw, &high_bits))
153283620Serj			goto fail;
154283620Serj		/* Get low bits */
155283620Serj		if (ixgbe_in_i2c_byte_ack(hw, &low_bits))
156283620Serj			goto fail;
157283620Serj		/* Get csum */
158283620Serj		if (ixgbe_clock_in_i2c_byte(hw, &csum_byte))
159283620Serj			goto fail;
160283620Serj		/* NACK */
161283620Serj		if (ixgbe_clock_out_i2c_bit(hw, FALSE))
162283620Serj			goto fail;
163283620Serj		ixgbe_i2c_stop(hw);
164283620Serj		if (lock)
165283620Serj			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
166283620Serj		*val = (high_bits << 8) | low_bits;
167283620Serj		return 0;
168283620Serj
169283620Serjfail:
170283620Serj		ixgbe_i2c_bus_clear(hw);
171283620Serj		if (lock)
172283620Serj			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
173283620Serj		retry++;
174283620Serj		if (retry < max_retry)
175283620Serj			DEBUGOUT("I2C byte read combined error - Retrying.\n");
176283620Serj		else
177283620Serj			DEBUGOUT("I2C byte read combined error.\n");
178283620Serj	} while (retry < max_retry);
179283620Serj
180283620Serj	return IXGBE_ERR_I2C;
181283620Serj}
182283620Serj
183283620Serj/**
184283620Serj * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
185283620Serj * @hw: pointer to the hardware structure
186283620Serj * @addr: I2C bus address to read from
187283620Serj * @reg: I2C device register to read from
188283620Serj * @val: pointer to location to receive read value
189283620Serj *
190283620Serj * Returns an error code on error.
191283620Serj **/
192283620Serjstatic s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
193283620Serj					   u16 reg, u16 *val)
194283620Serj{
195283620Serj	return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
196283620Serj}
197283620Serj
198283620Serj/**
199283620Serj * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation
200283620Serj * @hw: pointer to the hardware structure
201283620Serj * @addr: I2C bus address to read from
202283620Serj * @reg: I2C device register to read from
203283620Serj * @val: pointer to location to receive read value
204283620Serj *
205283620Serj * Returns an error code on error.
206283620Serj **/
207283620Serjstatic s32
208283620Serjixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
209283620Serj					 u16 reg, u16 *val)
210283620Serj{
211283620Serj	return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
212283620Serj}
213283620Serj
214283620Serj/**
215283620Serj * ixgbe_write_i2c_combined_generic_int - Perform I2C write combined operation
216283620Serj * @hw: pointer to the hardware structure
217283620Serj * @addr: I2C bus address to write to
218283620Serj * @reg: I2C device register to write to
219283620Serj * @val: value to write
220283620Serj * @lock: TRUE if to take and release semaphore
221283620Serj *
222283620Serj * Returns an error code on error.
223283620Serj */
224283620Serjstatic s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr,
225283620Serj						u16 reg, u16 val, bool lock)
226283620Serj{
227283620Serj	u32 swfw_mask = hw->phy.phy_semaphore_mask;
228283620Serj	int max_retry = 1;
229283620Serj	int retry = 0;
230283620Serj	u8 reg_high;
231283620Serj	u8 csum;
232283620Serj
233283620Serj	reg_high = (reg >> 7) & 0xFE;	/* Indicate write combined */
234283620Serj	csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF);
235283620Serj	csum = ixgbe_ones_comp_byte_add(csum, val >> 8);
236283620Serj	csum = ixgbe_ones_comp_byte_add(csum, val & 0xFF);
237283620Serj	csum = ~csum;
238283620Serj	do {
239283620Serj		if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
240283620Serj			return IXGBE_ERR_SWFW_SYNC;
241283620Serj		ixgbe_i2c_start(hw);
242283620Serj		/* Device Address and write indication */
243283620Serj		if (ixgbe_out_i2c_byte_ack(hw, addr))
244283620Serj			goto fail;
245283620Serj		/* Write bits 14:8 */
246283620Serj		if (ixgbe_out_i2c_byte_ack(hw, reg_high))
247283620Serj			goto fail;
248283620Serj		/* Write bits 7:0 */
249283620Serj		if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF))
250283620Serj			goto fail;
251283620Serj		/* Write data 15:8 */
252283620Serj		if (ixgbe_out_i2c_byte_ack(hw, val >> 8))
253283620Serj			goto fail;
254283620Serj		/* Write data 7:0 */
255283620Serj		if (ixgbe_out_i2c_byte_ack(hw, val & 0xFF))
256283620Serj			goto fail;
257283620Serj		/* Write csum */
258283620Serj		if (ixgbe_out_i2c_byte_ack(hw, csum))
259283620Serj			goto fail;
260283620Serj		ixgbe_i2c_stop(hw);
261283620Serj		if (lock)
262283620Serj			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
263283620Serj		return 0;
264283620Serj
265283620Serjfail:
266283620Serj		ixgbe_i2c_bus_clear(hw);
267283620Serj		if (lock)
268283620Serj			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
269283620Serj		retry++;
270283620Serj		if (retry < max_retry)
271283620Serj			DEBUGOUT("I2C byte write combined error - Retrying.\n");
272283620Serj		else
273283620Serj			DEBUGOUT("I2C byte write combined error.\n");
274283620Serj	} while (retry < max_retry);
275283620Serj
276283620Serj	return IXGBE_ERR_I2C;
277283620Serj}
278283620Serj
279283620Serj/**
280283620Serj * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
281283620Serj * @hw: pointer to the hardware structure
282283620Serj * @addr: I2C bus address to write to
283283620Serj * @reg: I2C device register to write to
284283620Serj * @val: value to write
285283620Serj *
286283620Serj * Returns an error code on error.
287283620Serj **/
288283620Serjstatic s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
289283620Serj					    u8 addr, u16 reg, u16 val)
290283620Serj{
291283620Serj	return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
292283620Serj}
293283620Serj
294283620Serj/**
295283620Serj * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation
296283620Serj * @hw: pointer to the hardware structure
297283620Serj * @addr: I2C bus address to write to
298283620Serj * @reg: I2C device register to write to
299283620Serj * @val: value to write
300283620Serj *
301283620Serj * Returns an error code on error.
302283620Serj **/
303283620Serjstatic s32
304283620Serjixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw,
305283620Serj					  u8 addr, u16 reg, u16 val)
306283620Serj{
307283620Serj	return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
308283620Serj}
309283620Serj
310283620Serj/**
311179055Sjfv *  ixgbe_init_phy_ops_generic - Inits PHY function ptrs
312179055Sjfv *  @hw: pointer to the hardware structure
313179055Sjfv *
314179055Sjfv *  Initialize the function pointers.
315171384Sjfv **/
316179055Sjfvs32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
317171384Sjfv{
318179055Sjfv	struct ixgbe_phy_info *phy = &hw->phy;
319171384Sjfv
320200239Sjfv	DEBUGFUNC("ixgbe_init_phy_ops_generic");
321200239Sjfv
322179055Sjfv	/* PHY */
323283620Serj	phy->ops.identify = ixgbe_identify_phy_generic;
324283620Serj	phy->ops.reset = ixgbe_reset_phy_generic;
325283620Serj	phy->ops.read_reg = ixgbe_read_phy_reg_generic;
326283620Serj	phy->ops.write_reg = ixgbe_write_phy_reg_generic;
327283620Serj	phy->ops.read_reg_mdi = ixgbe_read_phy_reg_mdi;
328283620Serj	phy->ops.write_reg_mdi = ixgbe_write_phy_reg_mdi;
329283620Serj	phy->ops.setup_link = ixgbe_setup_phy_link_generic;
330283620Serj	phy->ops.setup_link_speed = ixgbe_setup_phy_link_speed_generic;
331179055Sjfv	phy->ops.check_link = NULL;
332200239Sjfv	phy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_generic;
333283620Serj	phy->ops.read_i2c_byte = ixgbe_read_i2c_byte_generic;
334283620Serj	phy->ops.write_i2c_byte = ixgbe_write_i2c_byte_generic;
335283620Serj	phy->ops.read_i2c_sff8472 = ixgbe_read_i2c_sff8472_generic;
336283620Serj	phy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_generic;
337283620Serj	phy->ops.write_i2c_eeprom = ixgbe_write_i2c_eeprom_generic;
338283620Serj	phy->ops.i2c_bus_clear = ixgbe_i2c_bus_clear;
339283620Serj	phy->ops.identify_sfp = ixgbe_identify_module_generic;
340185352Sjfv	phy->sfp_type = ixgbe_sfp_type_unknown;
341283620Serj	phy->ops.read_i2c_combined = ixgbe_read_i2c_combined_generic;
342283620Serj	phy->ops.write_i2c_combined = ixgbe_write_i2c_combined_generic;
343283620Serj	phy->ops.read_i2c_combined_unlocked =
344283620Serj				ixgbe_read_i2c_combined_generic_unlocked;
345283620Serj	phy->ops.write_i2c_combined_unlocked =
346283620Serj				ixgbe_write_i2c_combined_generic_unlocked;
347283620Serj	phy->ops.read_i2c_byte_unlocked = ixgbe_read_i2c_byte_generic_unlocked;
348283620Serj	phy->ops.write_i2c_byte_unlocked =
349283620Serj				ixgbe_write_i2c_byte_generic_unlocked;
350283620Serj	phy->ops.check_overtemp = ixgbe_tn_check_overtemp;
351171384Sjfv	return IXGBE_SUCCESS;
352171384Sjfv}
353171384Sjfv
354171384Sjfv/**
355171384Sjfv *  ixgbe_identify_phy_generic - Get physical layer module
356171384Sjfv *  @hw: pointer to hardware structure
357171384Sjfv *
358171384Sjfv *  Determines the physical layer module found on the current adapter.
359171384Sjfv **/
360171384Sjfvs32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
361171384Sjfv{
362171384Sjfv	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
363171384Sjfv	u32 phy_addr;
364190873Sjfv	u16 ext_ability = 0;
365171384Sjfv
366200239Sjfv	DEBUGFUNC("ixgbe_identify_phy_generic");
367200239Sjfv
368283620Serj	if (!hw->phy.phy_semaphore_mask) {
369283620Serj		if (hw->bus.lan_id)
370283620Serj			hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
371283620Serj		else
372283620Serj			hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
373283620Serj	}
374283620Serj
375179055Sjfv	if (hw->phy.type == ixgbe_phy_unknown) {
376179055Sjfv		for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
377179055Sjfv			if (ixgbe_validate_phy_addr(hw, phy_addr)) {
378179055Sjfv				hw->phy.addr = phy_addr;
379179055Sjfv				ixgbe_get_phy_id(hw);
380179055Sjfv				hw->phy.type =
381230775Sjfv					ixgbe_get_phy_type_from_id(hw->phy.id);
382190873Sjfv
383190873Sjfv				if (hw->phy.type == ixgbe_phy_unknown) {
384190873Sjfv					hw->phy.ops.read_reg(hw,
385190873Sjfv						  IXGBE_MDIO_PHY_EXT_ABILITY,
386230775Sjfv						  IXGBE_MDIO_PMA_PMD_DEV_TYPE,
387230775Sjfv						  &ext_ability);
388190873Sjfv					if (ext_ability &
389215911Sjfv					    (IXGBE_MDIO_PHY_10GBASET_ABILITY |
390215911Sjfv					     IXGBE_MDIO_PHY_1000BASET_ABILITY))
391190873Sjfv						hw->phy.type =
392230775Sjfv							 ixgbe_phy_cu_unknown;
393190873Sjfv					else
394190873Sjfv						hw->phy.type =
395230775Sjfv							 ixgbe_phy_generic;
396190873Sjfv				}
397190873Sjfv
398179055Sjfv				status = IXGBE_SUCCESS;
399179055Sjfv				break;
400179055Sjfv			}
401171384Sjfv		}
402283620Serj
403283620Serj		/* Certain media types do not have a phy so an address will not
404283620Serj		 * be found and the code will take this path.  Caller has to
405283620Serj		 * decide if it is an error or not.
406283620Serj		 */
407251964Sjfv		if (status != IXGBE_SUCCESS) {
408190873Sjfv			hw->phy.addr = 0;
409251964Sjfv		}
410179055Sjfv	} else {
411179055Sjfv		status = IXGBE_SUCCESS;
412171384Sjfv	}
413179055Sjfv
414171384Sjfv	return status;
415171384Sjfv}
416171384Sjfv
417171384Sjfv/**
418283620Serj * ixgbe_check_reset_blocked - check status of MNG FW veto bit
419283620Serj * @hw: pointer to the hardware structure
420283620Serj *
421283620Serj * This function checks the MMNGC.MNG_VETO bit to see if there are
422283620Serj * any constraints on link from manageability.  For MAC's that don't
423283620Serj * have this bit just return faluse since the link can not be blocked
424283620Serj * via this method.
425283620Serj **/
426283620Serjs32 ixgbe_check_reset_blocked(struct ixgbe_hw *hw)
427283620Serj{
428283620Serj	u32 mmngc;
429283620Serj
430283620Serj	DEBUGFUNC("ixgbe_check_reset_blocked");
431283620Serj
432283620Serj	/* If we don't have this bit, it can't be blocking */
433283620Serj	if (hw->mac.type == ixgbe_mac_82598EB)
434283620Serj		return FALSE;
435283620Serj
436283620Serj	mmngc = IXGBE_READ_REG(hw, IXGBE_MMNGC);
437283620Serj	if (mmngc & IXGBE_MMNGC_MNG_VETO) {
438283620Serj		ERROR_REPORT1(IXGBE_ERROR_SOFTWARE,
439283620Serj			      "MNG_VETO bit detected.\n");
440283620Serj		return TRUE;
441283620Serj	}
442283620Serj
443283620Serj	return FALSE;
444283620Serj}
445283620Serj
446283620Serj/**
447171384Sjfv *  ixgbe_validate_phy_addr - Determines phy address is valid
448171384Sjfv *  @hw: pointer to hardware structure
449171384Sjfv *
450171384Sjfv **/
451171384Sjfvbool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr)
452171384Sjfv{
453171384Sjfv	u16 phy_id = 0;
454171384Sjfv	bool valid = FALSE;
455171384Sjfv
456200239Sjfv	DEBUGFUNC("ixgbe_validate_phy_addr");
457200239Sjfv
458171384Sjfv	hw->phy.addr = phy_addr;
459179055Sjfv	hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
460230775Sjfv			     IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id);
461171384Sjfv
462171384Sjfv	if (phy_id != 0xFFFF && phy_id != 0x0)
463171384Sjfv		valid = TRUE;
464171384Sjfv
465171384Sjfv	return valid;
466171384Sjfv}
467171384Sjfv
468171384Sjfv/**
469171384Sjfv *  ixgbe_get_phy_id - Get the phy type
470171384Sjfv *  @hw: pointer to hardware structure
471171384Sjfv *
472171384Sjfv **/
473171384Sjfvs32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
474171384Sjfv{
475171384Sjfv	u32 status;
476171384Sjfv	u16 phy_id_high = 0;
477171384Sjfv	u16 phy_id_low = 0;
478171384Sjfv
479200239Sjfv	DEBUGFUNC("ixgbe_get_phy_id");
480200239Sjfv
481179055Sjfv	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
482230775Sjfv				      IXGBE_MDIO_PMA_PMD_DEV_TYPE,
483230775Sjfv				      &phy_id_high);
484171384Sjfv
485171384Sjfv	if (status == IXGBE_SUCCESS) {
486171384Sjfv		hw->phy.id = (u32)(phy_id_high << 16);
487179055Sjfv		status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW,
488230775Sjfv					      IXGBE_MDIO_PMA_PMD_DEV_TYPE,
489230775Sjfv					      &phy_id_low);
490171384Sjfv		hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
491171384Sjfv		hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
492171384Sjfv	}
493171384Sjfv	return status;
494171384Sjfv}
495171384Sjfv
496171384Sjfv/**
497171384Sjfv *  ixgbe_get_phy_type_from_id - Get the phy type
498171384Sjfv *  @hw: pointer to hardware structure
499171384Sjfv *
500171384Sjfv **/
501171384Sjfvenum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
502171384Sjfv{
503171384Sjfv	enum ixgbe_phy_type phy_type;
504171384Sjfv
505200239Sjfv	DEBUGFUNC("ixgbe_get_phy_type_from_id");
506200239Sjfv
507171384Sjfv	switch (phy_id) {
508179055Sjfv	case TN1010_PHY_ID:
509179055Sjfv		phy_type = ixgbe_phy_tn;
510179055Sjfv		break;
511295524Ssbruno	case X550_PHY_ID1:
512295524Ssbruno	case X550_PHY_ID2:
513295524Ssbruno	case X550_PHY_ID3:
514230775Sjfv	case X540_PHY_ID:
515190873Sjfv		phy_type = ixgbe_phy_aq;
516190873Sjfv		break;
517171384Sjfv	case QT2022_PHY_ID:
518171384Sjfv		phy_type = ixgbe_phy_qt;
519171384Sjfv		break;
520185352Sjfv	case ATH_PHY_ID:
521185352Sjfv		phy_type = ixgbe_phy_nl;
522185352Sjfv		break;
523283620Serj	case X557_PHY_ID:
524283620Serj		phy_type = ixgbe_phy_x550em_ext_t;
525283620Serj		break;
526171384Sjfv	default:
527171384Sjfv		phy_type = ixgbe_phy_unknown;
528171384Sjfv		break;
529171384Sjfv	}
530171384Sjfv
531179055Sjfv	DEBUGOUT1("phy type found is %d\n", phy_type);
532171384Sjfv	return phy_type;
533171384Sjfv}
534171384Sjfv
535171384Sjfv/**
536171384Sjfv *  ixgbe_reset_phy_generic - Performs a PHY reset
537171384Sjfv *  @hw: pointer to hardware structure
538171384Sjfv **/
539171384Sjfvs32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
540171384Sjfv{
541190873Sjfv	u32 i;
542190873Sjfv	u16 ctrl = 0;
543190873Sjfv	s32 status = IXGBE_SUCCESS;
544190873Sjfv
545200239Sjfv	DEBUGFUNC("ixgbe_reset_phy_generic");
546200239Sjfv
547190873Sjfv	if (hw->phy.type == ixgbe_phy_unknown)
548190873Sjfv		status = ixgbe_identify_phy_generic(hw);
549190873Sjfv
550190873Sjfv	if (status != IXGBE_SUCCESS || hw->phy.type == ixgbe_phy_none)
551190873Sjfv		goto out;
552190873Sjfv
553215911Sjfv	/* Don't reset PHY if it's shut down due to overtemp. */
554215911Sjfv	if (!hw->phy.reset_if_overtemp &&
555215911Sjfv	    (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw)))
556215911Sjfv		goto out;
557215911Sjfv
558283620Serj	/* Blocked by MNG FW so bail */
559283620Serj	if (ixgbe_check_reset_blocked(hw))
560283620Serj		goto out;
561283620Serj
562171384Sjfv	/*
563171384Sjfv	 * Perform soft PHY reset to the PHY_XS.
564171384Sjfv	 * This will cause a soft reset to the PHY
565171384Sjfv	 */
566190873Sjfv	hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
567230775Sjfv			      IXGBE_MDIO_PHY_XS_DEV_TYPE,
568230775Sjfv			      IXGBE_MDIO_PHY_XS_RESET);
569190873Sjfv
570205720Sjfv	/*
571205720Sjfv	 * Poll for reset bit to self-clear indicating reset is complete.
572205720Sjfv	 * Some PHYs could take up to 3 seconds to complete and need about
573205720Sjfv	 * 1.7 usec delay after the reset is complete.
574205720Sjfv	 */
575205720Sjfv	for (i = 0; i < 30; i++) {
576205720Sjfv		msec_delay(100);
577190873Sjfv		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
578230775Sjfv				     IXGBE_MDIO_PHY_XS_DEV_TYPE, &ctrl);
579205720Sjfv		if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) {
580205720Sjfv			usec_delay(2);
581190873Sjfv			break;
582205720Sjfv		}
583190873Sjfv	}
584190873Sjfv
585190873Sjfv	if (ctrl & IXGBE_MDIO_PHY_XS_RESET) {
586190873Sjfv		status = IXGBE_ERR_RESET_FAILED;
587251964Sjfv		ERROR_REPORT1(IXGBE_ERROR_POLLING,
588251964Sjfv			     "PHY reset polling failed to complete.\n");
589190873Sjfv	}
590190873Sjfv
591190873Sjfvout:
592190873Sjfv	return status;
593171384Sjfv}
594171384Sjfv
595171384Sjfv/**
596251964Sjfv *  ixgbe_read_phy_mdi - Reads a value from a specified PHY register without
597251964Sjfv *  the SWFW lock
598251964Sjfv *  @hw: pointer to hardware structure
599251964Sjfv *  @reg_addr: 32 bit address of PHY register to read
600251964Sjfv *  @phy_data: Pointer to read data from PHY register
601251964Sjfv **/
602251964Sjfvs32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
603251964Sjfv		       u16 *phy_data)
604251964Sjfv{
605251964Sjfv	u32 i, data, command;
606251964Sjfv
607251964Sjfv	/* Setup and write the address cycle command */
608251964Sjfv	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
609251964Sjfv		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
610251964Sjfv		   (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
611251964Sjfv		   (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
612251964Sjfv
613251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
614251964Sjfv
615251964Sjfv	/*
616251964Sjfv	 * Check every 10 usec to see if the address cycle completed.
617251964Sjfv	 * The MDI Command bit will clear when the operation is
618251964Sjfv	 * complete
619251964Sjfv	 */
620251964Sjfv	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
621251964Sjfv		usec_delay(10);
622251964Sjfv
623251964Sjfv		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
624251964Sjfv		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
625251964Sjfv				break;
626251964Sjfv	}
627251964Sjfv
628251964Sjfv
629251964Sjfv	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
630251964Sjfv		ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY address command did not complete.\n");
631251964Sjfv		return IXGBE_ERR_PHY;
632251964Sjfv	}
633251964Sjfv
634251964Sjfv	/*
635251964Sjfv	 * Address cycle complete, setup and write the read
636251964Sjfv	 * command
637251964Sjfv	 */
638251964Sjfv	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
639251964Sjfv		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
640251964Sjfv		   (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
641251964Sjfv		   (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
642251964Sjfv
643251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
644251964Sjfv
645251964Sjfv	/*
646251964Sjfv	 * Check every 10 usec to see if the address cycle
647251964Sjfv	 * completed. The MDI Command bit will clear when the
648251964Sjfv	 * operation is complete
649251964Sjfv	 */
650251964Sjfv	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
651251964Sjfv		usec_delay(10);
652251964Sjfv
653251964Sjfv		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
654251964Sjfv		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
655251964Sjfv			break;
656251964Sjfv	}
657251964Sjfv
658251964Sjfv	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
659251964Sjfv		ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY read command didn't complete\n");
660251964Sjfv		return IXGBE_ERR_PHY;
661251964Sjfv	}
662251964Sjfv
663251964Sjfv	/*
664251964Sjfv	 * Read operation is complete.  Get the data
665251964Sjfv	 * from MSRWD
666251964Sjfv	 */
667251964Sjfv	data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
668251964Sjfv	data >>= IXGBE_MSRWD_READ_DATA_SHIFT;
669251964Sjfv	*phy_data = (u16)(data);
670251964Sjfv
671251964Sjfv	return IXGBE_SUCCESS;
672251964Sjfv}
673251964Sjfv
674251964Sjfv/**
675171384Sjfv *  ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register
676251964Sjfv *  using the SWFW lock - this function is needed in most cases
677171384Sjfv *  @hw: pointer to hardware structure
678171384Sjfv *  @reg_addr: 32 bit address of PHY register to read
679171384Sjfv *  @phy_data: Pointer to read data from PHY register
680171384Sjfv **/
681171384Sjfvs32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
682230775Sjfv			       u32 device_type, u16 *phy_data)
683171384Sjfv{
684251964Sjfv	s32 status;
685283620Serj	u32 gssr = hw->phy.phy_semaphore_mask;
686171384Sjfv
687200239Sjfv	DEBUGFUNC("ixgbe_read_phy_reg_generic");
688200239Sjfv
689251964Sjfv	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == IXGBE_SUCCESS) {
690251964Sjfv		status = ixgbe_read_phy_reg_mdi(hw, reg_addr, device_type,
691251964Sjfv						phy_data);
692251964Sjfv		hw->mac.ops.release_swfw_sync(hw, gssr);
693251964Sjfv	} else {
694171384Sjfv		status = IXGBE_ERR_SWFW_SYNC;
695251964Sjfv	}
696171384Sjfv
697251964Sjfv	return status;
698251964Sjfv}
699171384Sjfv
700251964Sjfv/**
701251964Sjfv *  ixgbe_write_phy_reg_mdi - Writes a value to specified PHY register
702251964Sjfv *  without SWFW lock
703251964Sjfv *  @hw: pointer to hardware structure
704251964Sjfv *  @reg_addr: 32 bit PHY register to write
705251964Sjfv *  @device_type: 5 bit device type
706251964Sjfv *  @phy_data: Data to write to the PHY register
707251964Sjfv **/
708251964Sjfvs32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr,
709251964Sjfv				u32 device_type, u16 phy_data)
710251964Sjfv{
711251964Sjfv	u32 i, command;
712171384Sjfv
713251964Sjfv	/* Put the data in the MDI single read and write data register*/
714251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data);
715171384Sjfv
716251964Sjfv	/* Setup and write the address cycle command */
717251964Sjfv	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
718251964Sjfv		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
719251964Sjfv		   (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
720251964Sjfv		   (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
721171384Sjfv
722251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
723171384Sjfv
724251964Sjfv	/*
725251964Sjfv	 * Check every 10 usec to see if the address cycle completed.
726251964Sjfv	 * The MDI Command bit will clear when the operation is
727251964Sjfv	 * complete
728251964Sjfv	 */
729251964Sjfv	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
730251964Sjfv		usec_delay(10);
731171384Sjfv
732251964Sjfv		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
733251964Sjfv		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
734251964Sjfv			break;
735251964Sjfv	}
736171384Sjfv
737251964Sjfv	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
738251964Sjfv		ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY address cmd didn't complete\n");
739251964Sjfv		return IXGBE_ERR_PHY;
740251964Sjfv	}
741171384Sjfv
742251964Sjfv	/*
743251964Sjfv	 * Address cycle complete, setup and write the write
744251964Sjfv	 * command
745251964Sjfv	 */
746251964Sjfv	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
747251964Sjfv		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
748251964Sjfv		   (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
749251964Sjfv		   (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
750171384Sjfv
751251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
752171384Sjfv
753251964Sjfv	/*
754251964Sjfv	 * Check every 10 usec to see if the address cycle
755251964Sjfv	 * completed. The MDI Command bit will clear when the
756251964Sjfv	 * operation is complete
757251964Sjfv	 */
758251964Sjfv	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
759251964Sjfv		usec_delay(10);
760171384Sjfv
761251964Sjfv		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
762251964Sjfv		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
763251964Sjfv			break;
764251964Sjfv	}
765171384Sjfv
766251964Sjfv	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
767251964Sjfv		ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY write cmd didn't complete\n");
768251964Sjfv		return IXGBE_ERR_PHY;
769171384Sjfv	}
770179055Sjfv
771251964Sjfv	return IXGBE_SUCCESS;
772171384Sjfv}
773171384Sjfv
774171384Sjfv/**
775171384Sjfv *  ixgbe_write_phy_reg_generic - Writes a value to specified PHY register
776251964Sjfv *  using SWFW lock- this function is needed in most cases
777171384Sjfv *  @hw: pointer to hardware structure
778171384Sjfv *  @reg_addr: 32 bit PHY register to write
779171384Sjfv *  @device_type: 5 bit device type
780171384Sjfv *  @phy_data: Data to write to the PHY register
781171384Sjfv **/
782171384Sjfvs32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
783230775Sjfv				u32 device_type, u16 phy_data)
784171384Sjfv{
785251964Sjfv	s32 status;
786283620Serj	u32 gssr = hw->phy.phy_semaphore_mask;
787171384Sjfv
788200239Sjfv	DEBUGFUNC("ixgbe_write_phy_reg_generic");
789200239Sjfv
790251964Sjfv	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == IXGBE_SUCCESS) {
791251964Sjfv		status = ixgbe_write_phy_reg_mdi(hw, reg_addr, device_type,
792251964Sjfv						 phy_data);
793251964Sjfv		hw->mac.ops.release_swfw_sync(hw, gssr);
794251964Sjfv	} else {
795171384Sjfv		status = IXGBE_ERR_SWFW_SYNC;
796171384Sjfv	}
797171384Sjfv
798171384Sjfv	return status;
799171384Sjfv}
800171384Sjfv
801171384Sjfv/**
802283620Serj *  ixgbe_setup_phy_link_generic - Set and restart auto-neg
803215911Sjfv *  @hw: pointer to hardware structure
804171384Sjfv *
805283620Serj *  Restart auto-negotiation and PHY and waits for completion.
806171384Sjfv **/
807179055Sjfvs32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
808171384Sjfv{
809194875Sjfv	s32 status = IXGBE_SUCCESS;
810179055Sjfv	u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
811200239Sjfv	bool autoneg = FALSE;
812200239Sjfv	ixgbe_link_speed speed;
813179055Sjfv
814200239Sjfv	DEBUGFUNC("ixgbe_setup_phy_link_generic");
815179055Sjfv
816200239Sjfv	ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
817179055Sjfv
818200239Sjfv	if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
819200239Sjfv		/* Set or unset auto-negotiation 10G advertisement */
820200239Sjfv		hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
821230775Sjfv				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
822230775Sjfv				     &autoneg_reg);
823179055Sjfv
824200239Sjfv		autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE;
825200239Sjfv		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
826200239Sjfv			autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE;
827200239Sjfv
828200239Sjfv		hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
829230775Sjfv				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
830230775Sjfv				      autoneg_reg);
831200239Sjfv	}
832200239Sjfv
833283620Serj	if (hw->mac.type == ixgbe_mac_X550) {
834283620Serj		if (speed & IXGBE_LINK_SPEED_5GB_FULL) {
835295524Ssbruno			/* Set or unset auto-negotiation 5G advertisement */
836283620Serj			hw->phy.ops.read_reg(hw,
837283620Serj				IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
838283620Serj				IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
839283620Serj				&autoneg_reg);
840283620Serj
841283620Serj			autoneg_reg &= ~IXGBE_MII_5GBASE_T_ADVERTISE;
842283620Serj			if (hw->phy.autoneg_advertised &
843283620Serj			     IXGBE_LINK_SPEED_5GB_FULL)
844283620Serj				autoneg_reg |= IXGBE_MII_5GBASE_T_ADVERTISE;
845283620Serj
846283620Serj			hw->phy.ops.write_reg(hw,
847283620Serj				IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
848283620Serj				IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
849283620Serj				autoneg_reg);
850283620Serj		}
851283620Serj
852283620Serj		if (speed & IXGBE_LINK_SPEED_2_5GB_FULL) {
853295524Ssbruno			/* Set or unset auto-negotiation 2.5G advertisement */
854283620Serj			hw->phy.ops.read_reg(hw,
855283620Serj				IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
856283620Serj				IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
857283620Serj				&autoneg_reg);
858283620Serj
859283620Serj			autoneg_reg &= ~IXGBE_MII_2_5GBASE_T_ADVERTISE;
860283620Serj			if (hw->phy.autoneg_advertised &
861283620Serj			    IXGBE_LINK_SPEED_2_5GB_FULL)
862283620Serj				autoneg_reg |= IXGBE_MII_2_5GBASE_T_ADVERTISE;
863283620Serj
864283620Serj			hw->phy.ops.write_reg(hw,
865283620Serj				IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
866283620Serj				IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
867283620Serj				autoneg_reg);
868283620Serj		}
869283620Serj	}
870283620Serj
871200239Sjfv	if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
872200239Sjfv		/* Set or unset auto-negotiation 1G advertisement */
873200239Sjfv		hw->phy.ops.read_reg(hw,
874230775Sjfv				     IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
875230775Sjfv				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
876230775Sjfv				     &autoneg_reg);
877200239Sjfv
878200239Sjfv		autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE;
879200239Sjfv		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
880200239Sjfv			autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE;
881200239Sjfv
882200239Sjfv		hw->phy.ops.write_reg(hw,
883230775Sjfv				      IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
884230775Sjfv				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
885230775Sjfv				      autoneg_reg);
886200239Sjfv	}
887200239Sjfv
888200239Sjfv	if (speed & IXGBE_LINK_SPEED_100_FULL) {
889200239Sjfv		/* Set or unset auto-negotiation 100M advertisement */
890200239Sjfv		hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
891230775Sjfv				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
892230775Sjfv				     &autoneg_reg);
893200239Sjfv
894230775Sjfv		autoneg_reg &= ~(IXGBE_MII_100BASE_T_ADVERTISE |
895230775Sjfv				 IXGBE_MII_100BASE_T_ADVERTISE_HALF);
896200239Sjfv		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
897200239Sjfv			autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE;
898200239Sjfv
899200239Sjfv		hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
900230775Sjfv				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
901230775Sjfv				      autoneg_reg);
902200239Sjfv	}
903200239Sjfv
904283620Serj	/* Blocked by MNG FW so don't reset PHY */
905283620Serj	if (ixgbe_check_reset_blocked(hw))
906283620Serj		return status;
907283620Serj
908283620Serj	/* Restart PHY auto-negotiation. */
909179055Sjfv	hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
910230775Sjfv			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
911179055Sjfv
912179055Sjfv	autoneg_reg |= IXGBE_MII_RESTART;
913179055Sjfv
914179055Sjfv	hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
915230775Sjfv			      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
916179055Sjfv
917179055Sjfv	return status;
918171384Sjfv}
919171384Sjfv
920171384Sjfv/**
921179055Sjfv *  ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities
922171384Sjfv *  @hw: pointer to hardware structure
923179055Sjfv *  @speed: new link speed
924179055Sjfv **/
925179055Sjfvs32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
926230775Sjfv				       ixgbe_link_speed speed,
927230775Sjfv				       bool autoneg_wait_to_complete)
928179055Sjfv{
929247822Sjfv	UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
930179055Sjfv
931200239Sjfv	DEBUGFUNC("ixgbe_setup_phy_link_speed_generic");
932200239Sjfv
933179055Sjfv	/*
934179055Sjfv	 * Clear autoneg_advertised and set new values based on input link
935179055Sjfv	 * speed.
936179055Sjfv	 */
937179055Sjfv	hw->phy.autoneg_advertised = 0;
938179055Sjfv
939185352Sjfv	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
940179055Sjfv		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
941185352Sjfv
942283620Serj	if (speed & IXGBE_LINK_SPEED_5GB_FULL)
943283620Serj		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_5GB_FULL;
944283620Serj
945283620Serj	if (speed & IXGBE_LINK_SPEED_2_5GB_FULL)
946283620Serj		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_2_5GB_FULL;
947283620Serj
948185352Sjfv	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
949179055Sjfv		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
950179055Sjfv
951190873Sjfv	if (speed & IXGBE_LINK_SPEED_100_FULL)
952190873Sjfv		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
953190873Sjfv
954179055Sjfv	/* Setup link based on the new speed settings */
955295524Ssbruno	ixgbe_setup_phy_link(hw);
956179055Sjfv
957179055Sjfv	return IXGBE_SUCCESS;
958179055Sjfv}
959179055Sjfv
960179055Sjfv/**
961295524Ssbruno * ixgbe_get_copper_speeds_supported - Get copper link speeds from phy
962295524Ssbruno * @hw: pointer to hardware structure
963295524Ssbruno *
964295524Ssbruno * Determines the supported link capabilities by reading the PHY auto
965295524Ssbruno * negotiation register.
966295524Ssbruno **/
967295524Ssbrunostatic s32 ixgbe_get_copper_speeds_supported(struct ixgbe_hw *hw)
968295524Ssbruno{
969295524Ssbruno	s32 status;
970295524Ssbruno	u16 speed_ability;
971295524Ssbruno
972295524Ssbruno	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
973295524Ssbruno				      IXGBE_MDIO_PMA_PMD_DEV_TYPE,
974295524Ssbruno				      &speed_ability);
975295524Ssbruno	if (status)
976295524Ssbruno		return status;
977295524Ssbruno
978295524Ssbruno	if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
979295524Ssbruno		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10GB_FULL;
980295524Ssbruno	if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
981295524Ssbruno		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_1GB_FULL;
982295524Ssbruno	if (speed_ability & IXGBE_MDIO_PHY_SPEED_100M)
983295524Ssbruno		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_100_FULL;
984295524Ssbruno
985295524Ssbruno	switch (hw->mac.type) {
986295524Ssbruno	case ixgbe_mac_X550:
987295524Ssbruno		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL;
988295524Ssbruno		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL;
989295524Ssbruno		break;
990295524Ssbruno	case ixgbe_mac_X550EM_x:
991295524Ssbruno		hw->phy.speeds_supported &= ~IXGBE_LINK_SPEED_100_FULL;
992295524Ssbruno		break;
993295524Ssbruno	default:
994295524Ssbruno		break;
995295524Ssbruno	}
996295524Ssbruno
997295524Ssbruno	return status;
998295524Ssbruno}
999295524Ssbruno
1000295524Ssbruno/**
1001190873Sjfv *  ixgbe_get_copper_link_capabilities_generic - Determines link capabilities
1002190873Sjfv *  @hw: pointer to hardware structure
1003190873Sjfv *  @speed: pointer to link speed
1004190873Sjfv *  @autoneg: boolean auto-negotiation value
1005190873Sjfv **/
1006190873Sjfvs32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
1007230775Sjfv					       ixgbe_link_speed *speed,
1008230775Sjfv					       bool *autoneg)
1009190873Sjfv{
1010295524Ssbruno	s32 status = IXGBE_SUCCESS;
1011190873Sjfv
1012200239Sjfv	DEBUGFUNC("ixgbe_get_copper_link_capabilities_generic");
1013200239Sjfv
1014190873Sjfv	*autoneg = TRUE;
1015295524Ssbruno	if (!hw->phy.speeds_supported)
1016295524Ssbruno		status = ixgbe_get_copper_speeds_supported(hw);
1017190873Sjfv
1018295524Ssbruno	*speed = hw->phy.speeds_supported;
1019190873Sjfv	return status;
1020190873Sjfv}
1021190873Sjfv
1022190873Sjfv/**
1023179055Sjfv *  ixgbe_check_phy_link_tnx - Determine link and speed status
1024179055Sjfv *  @hw: pointer to hardware structure
1025171384Sjfv *
1026179055Sjfv *  Reads the VS1 register to determine if link is up and the current speed for
1027171384Sjfv *  the PHY.
1028171384Sjfv **/
1029179055Sjfvs32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
1030230775Sjfv			     bool *link_up)
1031171384Sjfv{
1032179055Sjfv	s32 status = IXGBE_SUCCESS;
1033179055Sjfv	u32 time_out;
1034179055Sjfv	u32 max_time_out = 10;
1035179055Sjfv	u16 phy_link = 0;
1036179055Sjfv	u16 phy_speed = 0;
1037179055Sjfv	u16 phy_data = 0;
1038179055Sjfv
1039200239Sjfv	DEBUGFUNC("ixgbe_check_phy_link_tnx");
1040200239Sjfv
1041179055Sjfv	/* Initialize speed and link to default case */
1042179055Sjfv	*link_up = FALSE;
1043179055Sjfv	*speed = IXGBE_LINK_SPEED_10GB_FULL;
1044179055Sjfv
1045179055Sjfv	/*
1046179055Sjfv	 * Check current speed and link status of the PHY register.
1047179055Sjfv	 * This is a vendor specific register and may have to
1048179055Sjfv	 * be changed for other copper PHYs.
1049179055Sjfv	 */
1050179055Sjfv	for (time_out = 0; time_out < max_time_out; time_out++) {
1051179055Sjfv		usec_delay(10);
1052179055Sjfv		status = hw->phy.ops.read_reg(hw,
1053230775Sjfv					IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
1054230775Sjfv					IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1055230775Sjfv					&phy_data);
1056230775Sjfv		phy_link = phy_data & IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
1057179055Sjfv		phy_speed = phy_data &
1058230775Sjfv				 IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
1059179055Sjfv		if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
1060179055Sjfv			*link_up = TRUE;
1061179055Sjfv			if (phy_speed ==
1062179055Sjfv			    IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
1063179055Sjfv				*speed = IXGBE_LINK_SPEED_1GB_FULL;
1064179055Sjfv			break;
1065179055Sjfv		}
1066179055Sjfv	}
1067179055Sjfv
1068179055Sjfv	return status;
1069171384Sjfv}
1070171384Sjfv
1071171384Sjfv/**
1072283620Serj *	ixgbe_setup_phy_link_tnx - Set and restart auto-neg
1073200239Sjfv *	@hw: pointer to hardware structure
1074200239Sjfv *
1075283620Serj *	Restart auto-negotiation and PHY and waits for completion.
1076200239Sjfv **/
1077200239Sjfvs32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
1078200239Sjfv{
1079200239Sjfv	s32 status = IXGBE_SUCCESS;
1080200239Sjfv	u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
1081200239Sjfv	bool autoneg = FALSE;
1082200239Sjfv	ixgbe_link_speed speed;
1083200239Sjfv
1084200239Sjfv	DEBUGFUNC("ixgbe_setup_phy_link_tnx");
1085200239Sjfv
1086200239Sjfv	ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
1087200239Sjfv
1088200239Sjfv	if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
1089200239Sjfv		/* Set or unset auto-negotiation 10G advertisement */
1090200239Sjfv		hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
1091230775Sjfv				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1092230775Sjfv				     &autoneg_reg);
1093200239Sjfv
1094200239Sjfv		autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE;
1095200239Sjfv		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
1096200239Sjfv			autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE;
1097200239Sjfv
1098200239Sjfv		hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
1099230775Sjfv				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1100230775Sjfv				      autoneg_reg);
1101200239Sjfv	}
1102200239Sjfv
1103200239Sjfv	if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
1104200239Sjfv		/* Set or unset auto-negotiation 1G advertisement */
1105200239Sjfv		hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
1106230775Sjfv				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1107230775Sjfv				     &autoneg_reg);
1108200239Sjfv
1109200239Sjfv		autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
1110200239Sjfv		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
1111200239Sjfv			autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
1112200239Sjfv
1113200239Sjfv		hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
1114230775Sjfv				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1115230775Sjfv				      autoneg_reg);
1116200239Sjfv	}
1117200239Sjfv
1118200239Sjfv	if (speed & IXGBE_LINK_SPEED_100_FULL) {
1119200239Sjfv		/* Set or unset auto-negotiation 100M advertisement */
1120200239Sjfv		hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
1121230775Sjfv				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1122230775Sjfv				     &autoneg_reg);
1123200239Sjfv
1124200239Sjfv		autoneg_reg &= ~IXGBE_MII_100BASE_T_ADVERTISE;
1125200239Sjfv		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
1126200239Sjfv			autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE;
1127200239Sjfv
1128200239Sjfv		hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
1129230775Sjfv				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1130230775Sjfv				      autoneg_reg);
1131200239Sjfv	}
1132200239Sjfv
1133283620Serj	/* Blocked by MNG FW so don't reset PHY */
1134283620Serj	if (ixgbe_check_reset_blocked(hw))
1135283620Serj		return status;
1136283620Serj
1137283620Serj	/* Restart PHY auto-negotiation. */
1138200239Sjfv	hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
1139230775Sjfv			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
1140200239Sjfv
1141200239Sjfv	autoneg_reg |= IXGBE_MII_RESTART;
1142200239Sjfv
1143200239Sjfv	hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
1144230775Sjfv			      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
1145200239Sjfv
1146200239Sjfv	return status;
1147200239Sjfv}
1148200239Sjfv
1149200239Sjfv/**
1150179055Sjfv *  ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version
1151171384Sjfv *  @hw: pointer to hardware structure
1152179055Sjfv *  @firmware_version: pointer to the PHY Firmware Version
1153171384Sjfv **/
1154179055Sjfvs32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
1155230775Sjfv				       u16 *firmware_version)
1156171384Sjfv{
1157283620Serj	s32 status;
1158179055Sjfv
1159200239Sjfv	DEBUGFUNC("ixgbe_get_phy_firmware_version_tnx");
1160200239Sjfv
1161179055Sjfv	status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
1162230775Sjfv				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1163230775Sjfv				      firmware_version);
1164179055Sjfv
1165179055Sjfv	return status;
1166171384Sjfv}
1167171384Sjfv
1168185352Sjfv/**
1169200239Sjfv *  ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version
1170190873Sjfv *  @hw: pointer to hardware structure
1171190873Sjfv *  @firmware_version: pointer to the PHY Firmware Version
1172190873Sjfv **/
1173200239Sjfvs32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
1174230775Sjfv					   u16 *firmware_version)
1175190873Sjfv{
1176283620Serj	s32 status;
1177190873Sjfv
1178200239Sjfv	DEBUGFUNC("ixgbe_get_phy_firmware_version_generic");
1179200239Sjfv
1180190873Sjfv	status = hw->phy.ops.read_reg(hw, AQ_FW_REV,
1181230775Sjfv				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1182230775Sjfv				      firmware_version);
1183190873Sjfv
1184190873Sjfv	return status;
1185190873Sjfv}
1186190873Sjfv
1187190873Sjfv/**
1188185352Sjfv *  ixgbe_reset_phy_nl - Performs a PHY reset
1189185352Sjfv *  @hw: pointer to hardware structure
1190185352Sjfv **/
1191185352Sjfvs32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
1192185352Sjfv{
1193185352Sjfv	u16 phy_offset, control, eword, edata, block_crc;
1194185352Sjfv	bool end_data = FALSE;
1195185352Sjfv	u16 list_offset, data_offset;
1196185352Sjfv	u16 phy_data = 0;
1197185352Sjfv	s32 ret_val = IXGBE_SUCCESS;
1198185352Sjfv	u32 i;
1199185352Sjfv
1200200239Sjfv	DEBUGFUNC("ixgbe_reset_phy_nl");
1201200239Sjfv
1202283620Serj	/* Blocked by MNG FW so bail */
1203283620Serj	if (ixgbe_check_reset_blocked(hw))
1204283620Serj		goto out;
1205283620Serj
1206185352Sjfv	hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
1207230775Sjfv			     IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
1208185352Sjfv
1209185352Sjfv	/* reset the PHY and poll for completion */
1210185352Sjfv	hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
1211230775Sjfv			      IXGBE_MDIO_PHY_XS_DEV_TYPE,
1212230775Sjfv			      (phy_data | IXGBE_MDIO_PHY_XS_RESET));
1213185352Sjfv
1214185352Sjfv	for (i = 0; i < 100; i++) {
1215185352Sjfv		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
1216230775Sjfv				     IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
1217185352Sjfv		if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) == 0)
1218185352Sjfv			break;
1219185352Sjfv		msec_delay(10);
1220185352Sjfv	}
1221185352Sjfv
1222185352Sjfv	if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) != 0) {
1223185352Sjfv		DEBUGOUT("PHY reset did not complete.\n");
1224185352Sjfv		ret_val = IXGBE_ERR_PHY;
1225185352Sjfv		goto out;
1226185352Sjfv	}
1227185352Sjfv
1228185352Sjfv	/* Get init offsets */
1229185352Sjfv	ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
1230230775Sjfv						      &data_offset);
1231185352Sjfv	if (ret_val != IXGBE_SUCCESS)
1232185352Sjfv		goto out;
1233185352Sjfv
1234185352Sjfv	ret_val = hw->eeprom.ops.read(hw, data_offset, &block_crc);
1235185352Sjfv	data_offset++;
1236185352Sjfv	while (!end_data) {
1237185352Sjfv		/*
1238185352Sjfv		 * Read control word from PHY init contents offset
1239185352Sjfv		 */
1240185352Sjfv		ret_val = hw->eeprom.ops.read(hw, data_offset, &eword);
1241251964Sjfv		if (ret_val)
1242251964Sjfv			goto err_eeprom;
1243185352Sjfv		control = (eword & IXGBE_CONTROL_MASK_NL) >>
1244230775Sjfv			   IXGBE_CONTROL_SHIFT_NL;
1245185352Sjfv		edata = eword & IXGBE_DATA_MASK_NL;
1246185352Sjfv		switch (control) {
1247185352Sjfv		case IXGBE_DELAY_NL:
1248185352Sjfv			data_offset++;
1249185352Sjfv			DEBUGOUT1("DELAY: %d MS\n", edata);
1250185352Sjfv			msec_delay(edata);
1251185352Sjfv			break;
1252185352Sjfv		case IXGBE_DATA_NL:
1253230775Sjfv			DEBUGOUT("DATA:\n");
1254185352Sjfv			data_offset++;
1255251964Sjfv			ret_val = hw->eeprom.ops.read(hw, data_offset,
1256251964Sjfv						      &phy_offset);
1257251964Sjfv			if (ret_val)
1258251964Sjfv				goto err_eeprom;
1259251964Sjfv			data_offset++;
1260185352Sjfv			for (i = 0; i < edata; i++) {
1261251964Sjfv				ret_val = hw->eeprom.ops.read(hw, data_offset,
1262251964Sjfv							      &eword);
1263251964Sjfv				if (ret_val)
1264251964Sjfv					goto err_eeprom;
1265185352Sjfv				hw->phy.ops.write_reg(hw, phy_offset,
1266230775Sjfv						      IXGBE_TWINAX_DEV, eword);
1267185352Sjfv				DEBUGOUT2("Wrote %4.4x to %4.4x\n", eword,
1268230775Sjfv					  phy_offset);
1269185352Sjfv				data_offset++;
1270185352Sjfv				phy_offset++;
1271185352Sjfv			}
1272185352Sjfv			break;
1273185352Sjfv		case IXGBE_CONTROL_NL:
1274185352Sjfv			data_offset++;
1275230775Sjfv			DEBUGOUT("CONTROL:\n");
1276185352Sjfv			if (edata == IXGBE_CONTROL_EOL_NL) {
1277185352Sjfv				DEBUGOUT("EOL\n");
1278185352Sjfv				end_data = TRUE;
1279185352Sjfv			} else if (edata == IXGBE_CONTROL_SOL_NL) {
1280185352Sjfv				DEBUGOUT("SOL\n");
1281185352Sjfv			} else {
1282185352Sjfv				DEBUGOUT("Bad control value\n");
1283185352Sjfv				ret_val = IXGBE_ERR_PHY;
1284185352Sjfv				goto out;
1285185352Sjfv			}
1286185352Sjfv			break;
1287185352Sjfv		default:
1288185352Sjfv			DEBUGOUT("Bad control type\n");
1289185352Sjfv			ret_val = IXGBE_ERR_PHY;
1290185352Sjfv			goto out;
1291185352Sjfv		}
1292185352Sjfv	}
1293185352Sjfv
1294185352Sjfvout:
1295185352Sjfv	return ret_val;
1296251964Sjfv
1297251964Sjfverr_eeprom:
1298251964Sjfv	ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
1299251964Sjfv		      "eeprom read at offset %d failed", data_offset);
1300251964Sjfv	return IXGBE_ERR_PHY;
1301185352Sjfv}
1302185352Sjfv
1303185352Sjfv/**
1304230775Sjfv *  ixgbe_identify_module_generic - Identifies module type
1305230775Sjfv *  @hw: pointer to hardware structure
1306230775Sjfv *
1307230775Sjfv *  Determines HW type and calls appropriate function.
1308230775Sjfv **/
1309230775Sjfvs32 ixgbe_identify_module_generic(struct ixgbe_hw *hw)
1310230775Sjfv{
1311230775Sjfv	s32 status = IXGBE_ERR_SFP_NOT_PRESENT;
1312230775Sjfv
1313230775Sjfv	DEBUGFUNC("ixgbe_identify_module_generic");
1314230775Sjfv
1315230775Sjfv	switch (hw->mac.ops.get_media_type(hw)) {
1316230775Sjfv	case ixgbe_media_type_fiber:
1317230775Sjfv		status = ixgbe_identify_sfp_module_generic(hw);
1318230775Sjfv		break;
1319230775Sjfv
1320283620Serj	case ixgbe_media_type_fiber_qsfp:
1321283620Serj		status = ixgbe_identify_qsfp_module_generic(hw);
1322283620Serj		break;
1323230775Sjfv
1324230775Sjfv	default:
1325230775Sjfv		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
1326230775Sjfv		status = IXGBE_ERR_SFP_NOT_PRESENT;
1327230775Sjfv		break;
1328230775Sjfv	}
1329230775Sjfv
1330230775Sjfv	return status;
1331230775Sjfv}
1332230775Sjfv
1333230775Sjfv/**
1334185352Sjfv *  ixgbe_identify_sfp_module_generic - Identifies SFP modules
1335185352Sjfv *  @hw: pointer to hardware structure
1336185352Sjfv *
1337185352Sjfv *  Searches for and identifies the SFP module and assigns appropriate PHY type.
1338185352Sjfv **/
1339185352Sjfvs32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
1340185352Sjfv{
1341185352Sjfv	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
1342185352Sjfv	u32 vendor_oui = 0;
1343190873Sjfv	enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
1344185352Sjfv	u8 identifier = 0;
1345185352Sjfv	u8 comp_codes_1g = 0;
1346185352Sjfv	u8 comp_codes_10g = 0;
1347190873Sjfv	u8 oui_bytes[3] = {0, 0, 0};
1348194875Sjfv	u8 cable_tech = 0;
1349205720Sjfv	u8 cable_spec = 0;
1350190873Sjfv	u16 enforce_sfp = 0;
1351185352Sjfv
1352200239Sjfv	DEBUGFUNC("ixgbe_identify_sfp_module_generic");
1353200239Sjfv
1354194875Sjfv	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) {
1355194875Sjfv		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
1356194875Sjfv		status = IXGBE_ERR_SFP_NOT_PRESENT;
1357194875Sjfv		goto out;
1358215911Sjfv	}
1359194875Sjfv
1360283620Serj	/* LAN ID is needed for I2C access */
1361283620Serj	hw->mac.ops.set_lan_id(hw);
1362283620Serj
1363215911Sjfv	status = hw->phy.ops.read_i2c_eeprom(hw,
1364230775Sjfv					     IXGBE_SFF_IDENTIFIER,
1365230775Sjfv					     &identifier);
1366185352Sjfv
1367247822Sjfv	if (status != IXGBE_SUCCESS)
1368215911Sjfv		goto err_read_i2c_eeprom;
1369185352Sjfv
1370194875Sjfv	if (identifier != IXGBE_SFF_IDENTIFIER_SFP) {
1371194875Sjfv		hw->phy.type = ixgbe_phy_sfp_unsupported;
1372194875Sjfv		status = IXGBE_ERR_SFP_NOT_SUPPORTED;
1373194875Sjfv	} else {
1374215911Sjfv		status = hw->phy.ops.read_i2c_eeprom(hw,
1375230775Sjfv						     IXGBE_SFF_1GBE_COMP_CODES,
1376230775Sjfv						     &comp_codes_1g);
1377185352Sjfv
1378247822Sjfv		if (status != IXGBE_SUCCESS)
1379215911Sjfv			goto err_read_i2c_eeprom;
1380215911Sjfv
1381215911Sjfv		status = hw->phy.ops.read_i2c_eeprom(hw,
1382230775Sjfv						     IXGBE_SFF_10GBE_COMP_CODES,
1383230775Sjfv						     &comp_codes_10g);
1384215911Sjfv
1385247822Sjfv		if (status != IXGBE_SUCCESS)
1386215911Sjfv			goto err_read_i2c_eeprom;
1387215911Sjfv		status = hw->phy.ops.read_i2c_eeprom(hw,
1388230775Sjfv						     IXGBE_SFF_CABLE_TECHNOLOGY,
1389230775Sjfv						     &cable_tech);
1390215911Sjfv
1391247822Sjfv		if (status != IXGBE_SUCCESS)
1392215911Sjfv			goto err_read_i2c_eeprom;
1393215911Sjfv
1394185352Sjfv		 /* ID Module
1395185352Sjfv		  * =========
1396185352Sjfv		  * 0   SFP_DA_CU
1397185352Sjfv		  * 1   SFP_SR
1398185352Sjfv		  * 2   SFP_LR
1399190873Sjfv		  * 3   SFP_DA_CORE0 - 82599-specific
1400190873Sjfv		  * 4   SFP_DA_CORE1 - 82599-specific
1401190873Sjfv		  * 5   SFP_SR/LR_CORE0 - 82599-specific
1402190873Sjfv		  * 6   SFP_SR/LR_CORE1 - 82599-specific
1403205720Sjfv		  * 7   SFP_act_lmt_DA_CORE0 - 82599-specific
1404205720Sjfv		  * 8   SFP_act_lmt_DA_CORE1 - 82599-specific
1405215911Sjfv		  * 9   SFP_1g_cu_CORE0 - 82599-specific
1406215911Sjfv		  * 10  SFP_1g_cu_CORE1 - 82599-specific
1407238149Sjfv		  * 11  SFP_1g_sx_CORE0 - 82599-specific
1408238149Sjfv		  * 12  SFP_1g_sx_CORE1 - 82599-specific
1409185352Sjfv		  */
1410190873Sjfv		if (hw->mac.type == ixgbe_mac_82598EB) {
1411194875Sjfv			if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
1412190873Sjfv				hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
1413190873Sjfv			else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
1414190873Sjfv				hw->phy.sfp_type = ixgbe_sfp_type_sr;
1415190873Sjfv			else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
1416190873Sjfv				hw->phy.sfp_type = ixgbe_sfp_type_lr;
1417190873Sjfv			else
1418190873Sjfv				hw->phy.sfp_type = ixgbe_sfp_type_unknown;
1419283620Serj		} else {
1420205720Sjfv			if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
1421190873Sjfv				if (hw->bus.lan_id == 0)
1422190873Sjfv					hw->phy.sfp_type =
1423230775Sjfv						     ixgbe_sfp_type_da_cu_core0;
1424190873Sjfv				else
1425190873Sjfv					hw->phy.sfp_type =
1426230775Sjfv						     ixgbe_sfp_type_da_cu_core1;
1427205720Sjfv			} else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) {
1428205720Sjfv				hw->phy.ops.read_i2c_eeprom(
1429205720Sjfv						hw, IXGBE_SFF_CABLE_SPEC_COMP,
1430205720Sjfv						&cable_spec);
1431205720Sjfv				if (cable_spec &
1432215911Sjfv				    IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) {
1433205720Sjfv					if (hw->bus.lan_id == 0)
1434205720Sjfv						hw->phy.sfp_type =
1435205720Sjfv						ixgbe_sfp_type_da_act_lmt_core0;
1436205720Sjfv					else
1437205720Sjfv						hw->phy.sfp_type =
1438205720Sjfv						ixgbe_sfp_type_da_act_lmt_core1;
1439215911Sjfv				} else {
1440190873Sjfv					hw->phy.sfp_type =
1441230775Sjfv							ixgbe_sfp_type_unknown;
1442215911Sjfv				}
1443205720Sjfv			} else if (comp_codes_10g &
1444205720Sjfv				   (IXGBE_SFF_10GBASESR_CAPABLE |
1445215911Sjfv				    IXGBE_SFF_10GBASELR_CAPABLE)) {
1446190873Sjfv				if (hw->bus.lan_id == 0)
1447190873Sjfv					hw->phy.sfp_type =
1448230775Sjfv						      ixgbe_sfp_type_srlr_core0;
1449190873Sjfv				else
1450190873Sjfv					hw->phy.sfp_type =
1451230775Sjfv						      ixgbe_sfp_type_srlr_core1;
1452215911Sjfv			} else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) {
1453215911Sjfv				if (hw->bus.lan_id == 0)
1454215911Sjfv					hw->phy.sfp_type =
1455215911Sjfv						ixgbe_sfp_type_1g_cu_core0;
1456215911Sjfv				else
1457215911Sjfv					hw->phy.sfp_type =
1458215911Sjfv						ixgbe_sfp_type_1g_cu_core1;
1459238149Sjfv			} else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) {
1460238149Sjfv				if (hw->bus.lan_id == 0)
1461238149Sjfv					hw->phy.sfp_type =
1462238149Sjfv						ixgbe_sfp_type_1g_sx_core0;
1463238149Sjfv				else
1464238149Sjfv					hw->phy.sfp_type =
1465238149Sjfv						ixgbe_sfp_type_1g_sx_core1;
1466283620Serj			} else if (comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) {
1467283620Serj				if (hw->bus.lan_id == 0)
1468283620Serj					hw->phy.sfp_type =
1469283620Serj						ixgbe_sfp_type_1g_lx_core0;
1470283620Serj				else
1471283620Serj					hw->phy.sfp_type =
1472283620Serj						ixgbe_sfp_type_1g_lx_core1;
1473205720Sjfv			} else {
1474190873Sjfv				hw->phy.sfp_type = ixgbe_sfp_type_unknown;
1475205720Sjfv			}
1476190873Sjfv		}
1477185352Sjfv
1478190873Sjfv		if (hw->phy.sfp_type != stored_sfp_type)
1479190873Sjfv			hw->phy.sfp_setup_needed = TRUE;
1480190873Sjfv
1481185352Sjfv		/* Determine if the SFP+ PHY is dual speed or not. */
1482194875Sjfv		hw->phy.multispeed_fiber = FALSE;
1483190873Sjfv		if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
1484190873Sjfv		   (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
1485190873Sjfv		   ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
1486190873Sjfv		   (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
1487185352Sjfv			hw->phy.multispeed_fiber = TRUE;
1488200239Sjfv
1489185352Sjfv		/* Determine PHY vendor */
1490190873Sjfv		if (hw->phy.type != ixgbe_phy_nl) {
1491185352Sjfv			hw->phy.id = identifier;
1492215911Sjfv			status = hw->phy.ops.read_i2c_eeprom(hw,
1493230775Sjfv						    IXGBE_SFF_VENDOR_OUI_BYTE0,
1494230775Sjfv						    &oui_bytes[0]);
1495215911Sjfv
1496247822Sjfv			if (status != IXGBE_SUCCESS)
1497215911Sjfv				goto err_read_i2c_eeprom;
1498215911Sjfv
1499215911Sjfv			status = hw->phy.ops.read_i2c_eeprom(hw,
1500230775Sjfv						    IXGBE_SFF_VENDOR_OUI_BYTE1,
1501230775Sjfv						    &oui_bytes[1]);
1502215911Sjfv
1503247822Sjfv			if (status != IXGBE_SUCCESS)
1504215911Sjfv				goto err_read_i2c_eeprom;
1505215911Sjfv
1506215911Sjfv			status = hw->phy.ops.read_i2c_eeprom(hw,
1507230775Sjfv						    IXGBE_SFF_VENDOR_OUI_BYTE2,
1508230775Sjfv						    &oui_bytes[2]);
1509185352Sjfv
1510247822Sjfv			if (status != IXGBE_SUCCESS)
1511215911Sjfv				goto err_read_i2c_eeprom;
1512215911Sjfv
1513185352Sjfv			vendor_oui =
1514215911Sjfv			  ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
1515215911Sjfv			   (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
1516215911Sjfv			   (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
1517185352Sjfv
1518185352Sjfv			switch (vendor_oui) {
1519185352Sjfv			case IXGBE_SFF_VENDOR_OUI_TYCO:
1520194875Sjfv				if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
1521205720Sjfv					hw->phy.type =
1522230775Sjfv						    ixgbe_phy_sfp_passive_tyco;
1523185352Sjfv				break;
1524185352Sjfv			case IXGBE_SFF_VENDOR_OUI_FTL:
1525205720Sjfv				if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
1526205720Sjfv					hw->phy.type = ixgbe_phy_sfp_ftl_active;
1527205720Sjfv				else
1528205720Sjfv					hw->phy.type = ixgbe_phy_sfp_ftl;
1529185352Sjfv				break;
1530185352Sjfv			case IXGBE_SFF_VENDOR_OUI_AVAGO:
1531185352Sjfv				hw->phy.type = ixgbe_phy_sfp_avago;
1532185352Sjfv				break;
1533190873Sjfv			case IXGBE_SFF_VENDOR_OUI_INTEL:
1534190873Sjfv				hw->phy.type = ixgbe_phy_sfp_intel;
1535190873Sjfv				break;
1536185352Sjfv			default:
1537194875Sjfv				if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
1538205720Sjfv					hw->phy.type =
1539230775Sjfv						 ixgbe_phy_sfp_passive_unknown;
1540205720Sjfv				else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
1541205720Sjfv					hw->phy.type =
1542205720Sjfv						ixgbe_phy_sfp_active_unknown;
1543185352Sjfv				else
1544185352Sjfv					hw->phy.type = ixgbe_phy_sfp_unknown;
1545185352Sjfv				break;
1546185352Sjfv			}
1547185352Sjfv		}
1548190873Sjfv
1549205720Sjfv		/* Allow any DA cable vendor */
1550205720Sjfv		if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE |
1551205720Sjfv		    IXGBE_SFF_DA_ACTIVE_CABLE)) {
1552194875Sjfv			status = IXGBE_SUCCESS;
1553194875Sjfv			goto out;
1554194875Sjfv		}
1555194875Sjfv
1556215911Sjfv		/* Verify supported 1G SFP modules */
1557215911Sjfv		if (comp_codes_10g == 0 &&
1558215911Sjfv		    !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
1559238149Sjfv		      hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
1560283620Serj		      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
1561283620Serj		      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
1562251964Sjfv		      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
1563238149Sjfv		      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
1564190873Sjfv			hw->phy.type = ixgbe_phy_sfp_unsupported;
1565190873Sjfv			status = IXGBE_ERR_SFP_NOT_SUPPORTED;
1566190873Sjfv			goto out;
1567190873Sjfv		}
1568194875Sjfv
1569194875Sjfv		/* Anything else 82598-based is supported */
1570194875Sjfv		if (hw->mac.type == ixgbe_mac_82598EB) {
1571190873Sjfv			status = IXGBE_SUCCESS;
1572190873Sjfv			goto out;
1573190873Sjfv		}
1574190873Sjfv
1575190873Sjfv		ixgbe_get_device_caps(hw, &enforce_sfp);
1576215911Sjfv		if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
1577251964Sjfv		    !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
1578251964Sjfv		      hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
1579283620Serj		      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
1580283620Serj		      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
1581251964Sjfv		      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
1582251964Sjfv		      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
1583190873Sjfv			/* Make sure we're a supported PHY type */
1584190873Sjfv			if (hw->phy.type == ixgbe_phy_sfp_intel) {
1585190873Sjfv				status = IXGBE_SUCCESS;
1586190873Sjfv			} else {
1587247056Sdes				if (hw->allow_unsupported_sfp == TRUE) {
1588247056Sdes					EWARN(hw, "WARNING: Intel (R) Network "
1589247056Sdes					      "Connections are quality tested "
1590247056Sdes					      "using Intel (R) Ethernet Optics."
1591247056Sdes					      " Using untested modules is not "
1592247056Sdes					      "supported and may cause unstable"
1593247056Sdes					      " operation or damage to the "
1594247056Sdes					      "module or the adapter. Intel "
1595247056Sdes					      "Corporation is not responsible "
1596247056Sdes					      "for any harm caused by using "
1597247056Sdes					      "untested modules.\n", status);
1598247056Sdes					status = IXGBE_SUCCESS;
1599247056Sdes				} else {
1600247056Sdes					DEBUGOUT("SFP+ module not supported\n");
1601247056Sdes					hw->phy.type =
1602247056Sdes						ixgbe_phy_sfp_unsupported;
1603247056Sdes					status = IXGBE_ERR_SFP_NOT_SUPPORTED;
1604247056Sdes				}
1605190873Sjfv			}
1606190873Sjfv		} else {
1607190873Sjfv			status = IXGBE_SUCCESS;
1608190873Sjfv		}
1609185352Sjfv	}
1610185352Sjfv
1611185352Sjfvout:
1612185352Sjfv	return status;
1613215911Sjfv
1614215911Sjfverr_read_i2c_eeprom:
1615215911Sjfv	hw->phy.sfp_type = ixgbe_sfp_type_not_present;
1616215911Sjfv	if (hw->phy.type != ixgbe_phy_nl) {
1617215911Sjfv		hw->phy.id = 0;
1618215911Sjfv		hw->phy.type = ixgbe_phy_unknown;
1619215911Sjfv	}
1620215911Sjfv	return IXGBE_ERR_SFP_NOT_PRESENT;
1621185352Sjfv}
1622185352Sjfv
1623283620Serj/**
1624283620Serj *  ixgbe_get_supported_phy_sfp_layer_generic - Returns physical layer type
1625283620Serj *  @hw: pointer to hardware structure
1626283620Serj *
1627283620Serj *  Determines physical layer capabilities of the current SFP.
1628283620Serj */
1629283620Serjs32 ixgbe_get_supported_phy_sfp_layer_generic(struct ixgbe_hw *hw)
1630283620Serj{
1631283620Serj	u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
1632283620Serj	u8 comp_codes_10g = 0;
1633283620Serj	u8 comp_codes_1g = 0;
1634230775Sjfv
1635283620Serj	DEBUGFUNC("ixgbe_get_supported_phy_sfp_layer_generic");
1636230775Sjfv
1637283620Serj	hw->phy.ops.identify_sfp(hw);
1638283620Serj	if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
1639283620Serj		return physical_layer;
1640283620Serj
1641283620Serj	switch (hw->phy.type) {
1642283620Serj	case ixgbe_phy_sfp_passive_tyco:
1643283620Serj	case ixgbe_phy_sfp_passive_unknown:
1644283620Serj	case ixgbe_phy_qsfp_passive_unknown:
1645283620Serj		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
1646283620Serj		break;
1647283620Serj	case ixgbe_phy_sfp_ftl_active:
1648283620Serj	case ixgbe_phy_sfp_active_unknown:
1649283620Serj	case ixgbe_phy_qsfp_active_unknown:
1650283620Serj		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA;
1651283620Serj		break;
1652283620Serj	case ixgbe_phy_sfp_avago:
1653283620Serj	case ixgbe_phy_sfp_ftl:
1654283620Serj	case ixgbe_phy_sfp_intel:
1655283620Serj	case ixgbe_phy_sfp_unknown:
1656283620Serj		hw->phy.ops.read_i2c_eeprom(hw,
1657283620Serj		      IXGBE_SFF_1GBE_COMP_CODES, &comp_codes_1g);
1658283620Serj		hw->phy.ops.read_i2c_eeprom(hw,
1659283620Serj		      IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g);
1660283620Serj		if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
1661283620Serj			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
1662283620Serj		else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
1663283620Serj			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
1664283620Serj		else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE)
1665283620Serj			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
1666283620Serj		else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE)
1667283620Serj			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_SX;
1668283620Serj		break;
1669283620Serj	case ixgbe_phy_qsfp_intel:
1670283620Serj	case ixgbe_phy_qsfp_unknown:
1671283620Serj		hw->phy.ops.read_i2c_eeprom(hw,
1672283620Serj		      IXGBE_SFF_QSFP_10GBE_COMP, &comp_codes_10g);
1673283620Serj		if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
1674283620Serj			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
1675283620Serj		else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
1676283620Serj			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
1677283620Serj		break;
1678283620Serj	default:
1679283620Serj		break;
1680283620Serj	}
1681283620Serj
1682283620Serj	return physical_layer;
1683283620Serj}
1684283620Serj
1685185352Sjfv/**
1686283620Serj *  ixgbe_identify_qsfp_module_generic - Identifies QSFP modules
1687283620Serj *  @hw: pointer to hardware structure
1688283620Serj *
1689283620Serj *  Searches for and identifies the QSFP module and assigns appropriate PHY type
1690283620Serj **/
1691283620Serjs32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
1692283620Serj{
1693283620Serj	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
1694283620Serj	u32 vendor_oui = 0;
1695283620Serj	enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
1696283620Serj	u8 identifier = 0;
1697283620Serj	u8 comp_codes_1g = 0;
1698283620Serj	u8 comp_codes_10g = 0;
1699283620Serj	u8 oui_bytes[3] = {0, 0, 0};
1700283620Serj	u16 enforce_sfp = 0;
1701283620Serj	u8 connector = 0;
1702283620Serj	u8 cable_length = 0;
1703283620Serj	u8 device_tech = 0;
1704283620Serj	bool active_cable = FALSE;
1705283620Serj
1706283620Serj	DEBUGFUNC("ixgbe_identify_qsfp_module_generic");
1707283620Serj
1708283620Serj	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber_qsfp) {
1709283620Serj		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
1710283620Serj		status = IXGBE_ERR_SFP_NOT_PRESENT;
1711283620Serj		goto out;
1712283620Serj	}
1713283620Serj
1714283620Serj	/* LAN ID is needed for I2C access */
1715283620Serj	hw->mac.ops.set_lan_id(hw);
1716283620Serj
1717283620Serj	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
1718283620Serj					     &identifier);
1719283620Serj
1720283620Serj	if (status != IXGBE_SUCCESS)
1721283620Serj		goto err_read_i2c_eeprom;
1722283620Serj
1723283620Serj	if (identifier != IXGBE_SFF_IDENTIFIER_QSFP_PLUS) {
1724283620Serj		hw->phy.type = ixgbe_phy_sfp_unsupported;
1725283620Serj		status = IXGBE_ERR_SFP_NOT_SUPPORTED;
1726283620Serj		goto out;
1727283620Serj	}
1728283620Serj
1729283620Serj	hw->phy.id = identifier;
1730283620Serj
1731283620Serj	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_10GBE_COMP,
1732283620Serj					     &comp_codes_10g);
1733283620Serj
1734283620Serj	if (status != IXGBE_SUCCESS)
1735283620Serj		goto err_read_i2c_eeprom;
1736283620Serj
1737283620Serj	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_1GBE_COMP,
1738283620Serj					     &comp_codes_1g);
1739283620Serj
1740283620Serj	if (status != IXGBE_SUCCESS)
1741283620Serj		goto err_read_i2c_eeprom;
1742283620Serj
1743283620Serj	if (comp_codes_10g & IXGBE_SFF_QSFP_DA_PASSIVE_CABLE) {
1744283620Serj		hw->phy.type = ixgbe_phy_qsfp_passive_unknown;
1745283620Serj		if (hw->bus.lan_id == 0)
1746283620Serj			hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core0;
1747283620Serj		else
1748283620Serj			hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core1;
1749283620Serj	} else if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE |
1750283620Serj				     IXGBE_SFF_10GBASELR_CAPABLE)) {
1751283620Serj		if (hw->bus.lan_id == 0)
1752283620Serj			hw->phy.sfp_type = ixgbe_sfp_type_srlr_core0;
1753283620Serj		else
1754283620Serj			hw->phy.sfp_type = ixgbe_sfp_type_srlr_core1;
1755283620Serj	} else {
1756283620Serj		if (comp_codes_10g & IXGBE_SFF_QSFP_DA_ACTIVE_CABLE)
1757283620Serj			active_cable = TRUE;
1758283620Serj
1759283620Serj		if (!active_cable) {
1760283620Serj			/* check for active DA cables that pre-date
1761283620Serj			 * SFF-8436 v3.6 */
1762283620Serj			hw->phy.ops.read_i2c_eeprom(hw,
1763283620Serj					IXGBE_SFF_QSFP_CONNECTOR,
1764283620Serj					&connector);
1765283620Serj
1766283620Serj			hw->phy.ops.read_i2c_eeprom(hw,
1767283620Serj					IXGBE_SFF_QSFP_CABLE_LENGTH,
1768283620Serj					&cable_length);
1769283620Serj
1770283620Serj			hw->phy.ops.read_i2c_eeprom(hw,
1771283620Serj					IXGBE_SFF_QSFP_DEVICE_TECH,
1772283620Serj					&device_tech);
1773283620Serj
1774283620Serj			if ((connector ==
1775283620Serj				     IXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE) &&
1776283620Serj			    (cable_length > 0) &&
1777283620Serj			    ((device_tech >> 4) ==
1778283620Serj				     IXGBE_SFF_QSFP_TRANSMITER_850NM_VCSEL))
1779283620Serj				active_cable = TRUE;
1780283620Serj		}
1781283620Serj
1782283620Serj		if (active_cable) {
1783283620Serj			hw->phy.type = ixgbe_phy_qsfp_active_unknown;
1784283620Serj			if (hw->bus.lan_id == 0)
1785283620Serj				hw->phy.sfp_type =
1786283620Serj						ixgbe_sfp_type_da_act_lmt_core0;
1787283620Serj			else
1788283620Serj				hw->phy.sfp_type =
1789283620Serj						ixgbe_sfp_type_da_act_lmt_core1;
1790283620Serj		} else {
1791283620Serj			/* unsupported module type */
1792283620Serj			hw->phy.type = ixgbe_phy_sfp_unsupported;
1793283620Serj			status = IXGBE_ERR_SFP_NOT_SUPPORTED;
1794283620Serj			goto out;
1795283620Serj		}
1796283620Serj	}
1797283620Serj
1798283620Serj	if (hw->phy.sfp_type != stored_sfp_type)
1799283620Serj		hw->phy.sfp_setup_needed = TRUE;
1800283620Serj
1801283620Serj	/* Determine if the QSFP+ PHY is dual speed or not. */
1802283620Serj	hw->phy.multispeed_fiber = FALSE;
1803283620Serj	if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
1804283620Serj	   (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
1805283620Serj	   ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
1806283620Serj	   (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
1807283620Serj		hw->phy.multispeed_fiber = TRUE;
1808283620Serj
1809283620Serj	/* Determine PHY vendor for optical modules */
1810283620Serj	if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE |
1811283620Serj			      IXGBE_SFF_10GBASELR_CAPABLE))  {
1812283620Serj		status = hw->phy.ops.read_i2c_eeprom(hw,
1813283620Serj					    IXGBE_SFF_QSFP_VENDOR_OUI_BYTE0,
1814283620Serj					    &oui_bytes[0]);
1815283620Serj
1816283620Serj		if (status != IXGBE_SUCCESS)
1817283620Serj			goto err_read_i2c_eeprom;
1818283620Serj
1819283620Serj		status = hw->phy.ops.read_i2c_eeprom(hw,
1820283620Serj					    IXGBE_SFF_QSFP_VENDOR_OUI_BYTE1,
1821283620Serj					    &oui_bytes[1]);
1822283620Serj
1823283620Serj		if (status != IXGBE_SUCCESS)
1824283620Serj			goto err_read_i2c_eeprom;
1825283620Serj
1826283620Serj		status = hw->phy.ops.read_i2c_eeprom(hw,
1827283620Serj					    IXGBE_SFF_QSFP_VENDOR_OUI_BYTE2,
1828283620Serj					    &oui_bytes[2]);
1829283620Serj
1830283620Serj		if (status != IXGBE_SUCCESS)
1831283620Serj			goto err_read_i2c_eeprom;
1832283620Serj
1833283620Serj		vendor_oui =
1834283620Serj		  ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
1835283620Serj		   (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
1836283620Serj		   (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
1837283620Serj
1838283620Serj		if (vendor_oui == IXGBE_SFF_VENDOR_OUI_INTEL)
1839283620Serj			hw->phy.type = ixgbe_phy_qsfp_intel;
1840283620Serj		else
1841283620Serj			hw->phy.type = ixgbe_phy_qsfp_unknown;
1842283620Serj
1843283620Serj		ixgbe_get_device_caps(hw, &enforce_sfp);
1844283620Serj		if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
1845283620Serj			/* Make sure we're a supported PHY type */
1846283620Serj			if (hw->phy.type == ixgbe_phy_qsfp_intel) {
1847283620Serj				status = IXGBE_SUCCESS;
1848283620Serj			} else {
1849283620Serj				if (hw->allow_unsupported_sfp == TRUE) {
1850283620Serj					EWARN(hw, "WARNING: Intel (R) Network "
1851283620Serj					      "Connections are quality tested "
1852283620Serj					      "using Intel (R) Ethernet Optics."
1853283620Serj					      " Using untested modules is not "
1854283620Serj					      "supported and may cause unstable"
1855283620Serj					      " operation or damage to the "
1856283620Serj					      "module or the adapter. Intel "
1857283620Serj					      "Corporation is not responsible "
1858283620Serj					      "for any harm caused by using "
1859283620Serj					      "untested modules.\n", status);
1860283620Serj					status = IXGBE_SUCCESS;
1861283620Serj				} else {
1862283620Serj					DEBUGOUT("QSFP module not supported\n");
1863283620Serj					hw->phy.type =
1864283620Serj						ixgbe_phy_sfp_unsupported;
1865283620Serj					status = IXGBE_ERR_SFP_NOT_SUPPORTED;
1866283620Serj				}
1867283620Serj			}
1868283620Serj		} else {
1869283620Serj			status = IXGBE_SUCCESS;
1870283620Serj		}
1871283620Serj	}
1872283620Serj
1873283620Serjout:
1874283620Serj	return status;
1875283620Serj
1876283620Serjerr_read_i2c_eeprom:
1877283620Serj	hw->phy.sfp_type = ixgbe_sfp_type_not_present;
1878283620Serj	hw->phy.id = 0;
1879283620Serj	hw->phy.type = ixgbe_phy_unknown;
1880283620Serj
1881283620Serj	return IXGBE_ERR_SFP_NOT_PRESENT;
1882283620Serj}
1883283620Serj
1884283620Serj
1885283620Serj/**
1886185352Sjfv *  ixgbe_get_sfp_init_sequence_offsets - Provides offset of PHY init sequence
1887185352Sjfv *  @hw: pointer to hardware structure
1888185352Sjfv *  @list_offset: offset to the SFP ID list
1889185352Sjfv *  @data_offset: offset to the SFP data block
1890185352Sjfv *
1891185352Sjfv *  Checks the MAC's EEPROM to see if it supports a given SFP+ module type, if
1892185352Sjfv *  so it returns the offsets to the phy init sequence block.
1893185352Sjfv **/
1894185352Sjfvs32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
1895230775Sjfv					u16 *list_offset,
1896230775Sjfv					u16 *data_offset)
1897185352Sjfv{
1898185352Sjfv	u16 sfp_id;
1899205720Sjfv	u16 sfp_type = hw->phy.sfp_type;
1900185352Sjfv
1901200239Sjfv	DEBUGFUNC("ixgbe_get_sfp_init_sequence_offsets");
1902200239Sjfv
1903185352Sjfv	if (hw->phy.sfp_type == ixgbe_sfp_type_unknown)
1904185352Sjfv		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1905185352Sjfv
1906185352Sjfv	if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
1907185352Sjfv		return IXGBE_ERR_SFP_NOT_PRESENT;
1908185352Sjfv
1909185352Sjfv	if ((hw->device_id == IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM) &&
1910185352Sjfv	    (hw->phy.sfp_type == ixgbe_sfp_type_da_cu))
1911185352Sjfv		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1912185352Sjfv
1913215911Sjfv	/*
1914215911Sjfv	 * Limiting active cables and 1G Phys must be initialized as
1915215911Sjfv	 * SR modules
1916215911Sjfv	 */
1917215911Sjfv	if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 ||
1918283620Serj	    sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
1919238149Sjfv	    sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
1920238149Sjfv	    sfp_type == ixgbe_sfp_type_1g_sx_core0)
1921205720Sjfv		sfp_type = ixgbe_sfp_type_srlr_core0;
1922215911Sjfv	else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 ||
1923283620Serj		 sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
1924238149Sjfv		 sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
1925238149Sjfv		 sfp_type == ixgbe_sfp_type_1g_sx_core1)
1926205720Sjfv		sfp_type = ixgbe_sfp_type_srlr_core1;
1927205720Sjfv
1928185352Sjfv	/* Read offset to PHY init contents */
1929251964Sjfv	if (hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset)) {
1930251964Sjfv		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
1931251964Sjfv			      "eeprom read at offset %d failed",
1932251964Sjfv			      IXGBE_PHY_INIT_OFFSET_NL);
1933251964Sjfv		return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
1934251964Sjfv	}
1935185352Sjfv
1936185352Sjfv	if ((!*list_offset) || (*list_offset == 0xFFFF))
1937190873Sjfv		return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
1938185352Sjfv
1939185352Sjfv	/* Shift offset to first ID word */
1940185352Sjfv	(*list_offset)++;
1941185352Sjfv
1942185352Sjfv	/*
1943185352Sjfv	 * Find the matching SFP ID in the EEPROM
1944185352Sjfv	 * and program the init sequence
1945185352Sjfv	 */
1946251964Sjfv	if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id))
1947251964Sjfv		goto err_phy;
1948185352Sjfv
1949185352Sjfv	while (sfp_id != IXGBE_PHY_INIT_END_NL) {
1950205720Sjfv		if (sfp_id == sfp_type) {
1951185352Sjfv			(*list_offset)++;
1952251964Sjfv			if (hw->eeprom.ops.read(hw, *list_offset, data_offset))
1953251964Sjfv				goto err_phy;
1954185352Sjfv			if ((!*data_offset) || (*data_offset == 0xFFFF)) {
1955185352Sjfv				DEBUGOUT("SFP+ module not supported\n");
1956185352Sjfv				return IXGBE_ERR_SFP_NOT_SUPPORTED;
1957185352Sjfv			} else {
1958185352Sjfv				break;
1959185352Sjfv			}
1960185352Sjfv		} else {
1961185352Sjfv			(*list_offset) += 2;
1962185352Sjfv			if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id))
1963251964Sjfv				goto err_phy;
1964185352Sjfv		}
1965185352Sjfv	}
1966185352Sjfv
1967185352Sjfv	if (sfp_id == IXGBE_PHY_INIT_END_NL) {
1968185352Sjfv		DEBUGOUT("No matching SFP+ module found\n");
1969185352Sjfv		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1970185352Sjfv	}
1971185352Sjfv
1972185352Sjfv	return IXGBE_SUCCESS;
1973251964Sjfv
1974251964Sjfverr_phy:
1975251964Sjfv	ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
1976251964Sjfv		      "eeprom read at offset %d failed", *list_offset);
1977251964Sjfv	return IXGBE_ERR_PHY;
1978185352Sjfv}
1979185352Sjfv
1980190873Sjfv/**
1981190873Sjfv *  ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface
1982190873Sjfv *  @hw: pointer to hardware structure
1983190873Sjfv *  @byte_offset: EEPROM byte offset to read
1984190873Sjfv *  @eeprom_data: value read
1985190873Sjfv *
1986190873Sjfv *  Performs byte read operation to SFP module's EEPROM over I2C interface.
1987190873Sjfv **/
1988190873Sjfvs32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
1989230775Sjfv				  u8 *eeprom_data)
1990190873Sjfv{
1991190873Sjfv	DEBUGFUNC("ixgbe_read_i2c_eeprom_generic");
1992190873Sjfv
1993190873Sjfv	return hw->phy.ops.read_i2c_byte(hw, byte_offset,
1994230775Sjfv					 IXGBE_I2C_EEPROM_DEV_ADDR,
1995230775Sjfv					 eeprom_data);
1996190873Sjfv}
1997190873Sjfv
1998190873Sjfv/**
1999247822Sjfv *  ixgbe_read_i2c_sff8472_generic - Reads 8 bit word over I2C interface
2000247822Sjfv *  @hw: pointer to hardware structure
2001247822Sjfv *  @byte_offset: byte offset at address 0xA2
2002247822Sjfv *  @eeprom_data: value read
2003247822Sjfv *
2004247822Sjfv *  Performs byte read operation to SFP module's SFF-8472 data over I2C
2005247822Sjfv **/
2006247822Sjfvstatic s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
2007247822Sjfv					  u8 *sff8472_data)
2008247822Sjfv{
2009247822Sjfv	return hw->phy.ops.read_i2c_byte(hw, byte_offset,
2010247822Sjfv					 IXGBE_I2C_EEPROM_DEV_ADDR2,
2011247822Sjfv					 sff8472_data);
2012247822Sjfv}
2013247822Sjfv
2014247822Sjfv/**
2015190873Sjfv *  ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
2016190873Sjfv *  @hw: pointer to hardware structure
2017190873Sjfv *  @byte_offset: EEPROM byte offset to write
2018190873Sjfv *  @eeprom_data: value to write
2019190873Sjfv *
2020190873Sjfv *  Performs byte write operation to SFP module's EEPROM over I2C interface.
2021190873Sjfv **/
2022190873Sjfvs32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
2023230775Sjfv				   u8 eeprom_data)
2024190873Sjfv{
2025190873Sjfv	DEBUGFUNC("ixgbe_write_i2c_eeprom_generic");
2026190873Sjfv
2027190873Sjfv	return hw->phy.ops.write_i2c_byte(hw, byte_offset,
2028230775Sjfv					  IXGBE_I2C_EEPROM_DEV_ADDR,
2029230775Sjfv					  eeprom_data);
2030190873Sjfv}
2031190873Sjfv
2032190873Sjfv/**
2033283620Serj * ixgbe_is_sfp_probe - Returns TRUE if SFP is being detected
2034283620Serj * @hw: pointer to hardware structure
2035283620Serj * @offset: eeprom offset to be read
2036283620Serj * @addr: I2C address to be read
2037283620Serj */
2038283620Serjstatic bool ixgbe_is_sfp_probe(struct ixgbe_hw *hw, u8 offset, u8 addr)
2039283620Serj{
2040283620Serj	if (addr == IXGBE_I2C_EEPROM_DEV_ADDR &&
2041283620Serj	    offset == IXGBE_SFF_IDENTIFIER &&
2042283620Serj	    hw->phy.sfp_type == ixgbe_sfp_type_not_present)
2043283620Serj		return TRUE;
2044283620Serj	return FALSE;
2045283620Serj}
2046283620Serj
2047283620Serj/**
2048283620Serj *  ixgbe_read_i2c_byte_generic_int - Reads 8 bit word over I2C
2049190873Sjfv *  @hw: pointer to hardware structure
2050190873Sjfv *  @byte_offset: byte offset to read
2051190873Sjfv *  @data: value read
2052283620Serj *  @lock: TRUE if to take and release semaphore
2053190873Sjfv *
2054190873Sjfv *  Performs byte read operation to SFP module's EEPROM over I2C interface at
2055230775Sjfv *  a specified device address.
2056190873Sjfv **/
2057283620Serjstatic s32 ixgbe_read_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset,
2058283620Serj					   u8 dev_addr, u8 *data, bool lock)
2059190873Sjfv{
2060283620Serj	s32 status;
2061194875Sjfv	u32 max_retry = 10;
2062190873Sjfv	u32 retry = 0;
2063283620Serj	u32 swfw_mask = hw->phy.phy_semaphore_mask;
2064190873Sjfv	bool nack = 1;
2065230775Sjfv	*data = 0;
2066190873Sjfv
2067190873Sjfv	DEBUGFUNC("ixgbe_read_i2c_byte_generic");
2068190873Sjfv
2069283620Serj	if (hw->mac.type >= ixgbe_mac_X550)
2070283620Serj		max_retry = 3;
2071283620Serj	if (ixgbe_is_sfp_probe(hw, byte_offset, dev_addr))
2072283620Serj		max_retry = IXGBE_SFP_DETECT_RETRIES;
2073190873Sjfv
2074190873Sjfv	do {
2075283620Serj		if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
2076283620Serj			return IXGBE_ERR_SWFW_SYNC;
2077194875Sjfv
2078190873Sjfv		ixgbe_i2c_start(hw);
2079190873Sjfv
2080190873Sjfv		/* Device Address and write indication */
2081190873Sjfv		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
2082190873Sjfv		if (status != IXGBE_SUCCESS)
2083190873Sjfv			goto fail;
2084190873Sjfv
2085190873Sjfv		status = ixgbe_get_i2c_ack(hw);
2086190873Sjfv		if (status != IXGBE_SUCCESS)
2087190873Sjfv			goto fail;
2088190873Sjfv
2089190873Sjfv		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
2090190873Sjfv		if (status != IXGBE_SUCCESS)
2091190873Sjfv			goto fail;
2092190873Sjfv
2093190873Sjfv		status = ixgbe_get_i2c_ack(hw);
2094190873Sjfv		if (status != IXGBE_SUCCESS)
2095190873Sjfv			goto fail;
2096190873Sjfv
2097190873Sjfv		ixgbe_i2c_start(hw);
2098190873Sjfv
2099190873Sjfv		/* Device Address and read indication */
2100190873Sjfv		status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1));
2101190873Sjfv		if (status != IXGBE_SUCCESS)
2102190873Sjfv			goto fail;
2103190873Sjfv
2104190873Sjfv		status = ixgbe_get_i2c_ack(hw);
2105190873Sjfv		if (status != IXGBE_SUCCESS)
2106190873Sjfv			goto fail;
2107190873Sjfv
2108190873Sjfv		status = ixgbe_clock_in_i2c_byte(hw, data);
2109190873Sjfv		if (status != IXGBE_SUCCESS)
2110190873Sjfv			goto fail;
2111190873Sjfv
2112190873Sjfv		status = ixgbe_clock_out_i2c_bit(hw, nack);
2113190873Sjfv		if (status != IXGBE_SUCCESS)
2114190873Sjfv			goto fail;
2115190873Sjfv
2116190873Sjfv		ixgbe_i2c_stop(hw);
2117283620Serj		if (lock)
2118283620Serj			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2119283620Serj		return IXGBE_SUCCESS;
2120190873Sjfv
2121190873Sjfvfail:
2122247822Sjfv		ixgbe_i2c_bus_clear(hw);
2123283620Serj		if (lock) {
2124283620Serj			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2125283620Serj			msec_delay(100);
2126283620Serj		}
2127190873Sjfv		retry++;
2128190873Sjfv		if (retry < max_retry)
2129190873Sjfv			DEBUGOUT("I2C byte read error - Retrying.\n");
2130190873Sjfv		else
2131190873Sjfv			DEBUGOUT("I2C byte read error.\n");
2132190873Sjfv
2133190873Sjfv	} while (retry < max_retry);
2134190873Sjfv
2135190873Sjfv	return status;
2136190873Sjfv}
2137190873Sjfv
2138190873Sjfv/**
2139283620Serj *  ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
2140190873Sjfv *  @hw: pointer to hardware structure
2141283620Serj *  @byte_offset: byte offset to read
2142283620Serj *  @data: value read
2143283620Serj *
2144283620Serj *  Performs byte read operation to SFP module's EEPROM over I2C interface at
2145283620Serj *  a specified device address.
2146283620Serj **/
2147283620Serjs32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
2148283620Serj				u8 dev_addr, u8 *data)
2149283620Serj{
2150283620Serj	return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr,
2151283620Serj					       data, TRUE);
2152283620Serj}
2153283620Serj
2154283620Serj/**
2155283620Serj *  ixgbe_read_i2c_byte_generic_unlocked - Reads 8 bit word over I2C
2156283620Serj *  @hw: pointer to hardware structure
2157283620Serj *  @byte_offset: byte offset to read
2158283620Serj *  @data: value read
2159283620Serj *
2160283620Serj *  Performs byte read operation to SFP module's EEPROM over I2C interface at
2161283620Serj *  a specified device address.
2162283620Serj **/
2163283620Serjs32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
2164283620Serj					 u8 dev_addr, u8 *data)
2165283620Serj{
2166283620Serj	return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr,
2167283620Serj					       data, FALSE);
2168283620Serj}
2169283620Serj
2170283620Serj/**
2171283620Serj *  ixgbe_write_i2c_byte_generic_int - Writes 8 bit word over I2C
2172283620Serj *  @hw: pointer to hardware structure
2173190873Sjfv *  @byte_offset: byte offset to write
2174190873Sjfv *  @data: value to write
2175283620Serj *  @lock: TRUE if to take and release semaphore
2176190873Sjfv *
2177190873Sjfv *  Performs byte write operation to SFP module's EEPROM over I2C interface at
2178190873Sjfv *  a specified device address.
2179190873Sjfv **/
2180283620Serjstatic s32 ixgbe_write_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset,
2181283620Serj					    u8 dev_addr, u8 data, bool lock)
2182190873Sjfv{
2183283620Serj	s32 status;
2184190873Sjfv	u32 max_retry = 1;
2185190873Sjfv	u32 retry = 0;
2186283620Serj	u32 swfw_mask = hw->phy.phy_semaphore_mask;
2187190873Sjfv
2188190873Sjfv	DEBUGFUNC("ixgbe_write_i2c_byte_generic");
2189190873Sjfv
2190283620Serj	if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) !=
2191283620Serj	    IXGBE_SUCCESS)
2192283620Serj		return IXGBE_ERR_SWFW_SYNC;
2193190873Sjfv
2194190873Sjfv	do {
2195190873Sjfv		ixgbe_i2c_start(hw);
2196190873Sjfv
2197190873Sjfv		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
2198190873Sjfv		if (status != IXGBE_SUCCESS)
2199190873Sjfv			goto fail;
2200190873Sjfv
2201190873Sjfv		status = ixgbe_get_i2c_ack(hw);
2202190873Sjfv		if (status != IXGBE_SUCCESS)
2203190873Sjfv			goto fail;
2204190873Sjfv
2205190873Sjfv		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
2206190873Sjfv		if (status != IXGBE_SUCCESS)
2207190873Sjfv			goto fail;
2208190873Sjfv
2209190873Sjfv		status = ixgbe_get_i2c_ack(hw);
2210190873Sjfv		if (status != IXGBE_SUCCESS)
2211190873Sjfv			goto fail;
2212190873Sjfv
2213190873Sjfv		status = ixgbe_clock_out_i2c_byte(hw, data);
2214190873Sjfv		if (status != IXGBE_SUCCESS)
2215190873Sjfv			goto fail;
2216190873Sjfv
2217190873Sjfv		status = ixgbe_get_i2c_ack(hw);
2218190873Sjfv		if (status != IXGBE_SUCCESS)
2219190873Sjfv			goto fail;
2220190873Sjfv
2221190873Sjfv		ixgbe_i2c_stop(hw);
2222283620Serj		if (lock)
2223283620Serj			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2224283620Serj		return IXGBE_SUCCESS;
2225190873Sjfv
2226190873Sjfvfail:
2227190873Sjfv		ixgbe_i2c_bus_clear(hw);
2228190873Sjfv		retry++;
2229190873Sjfv		if (retry < max_retry)
2230190873Sjfv			DEBUGOUT("I2C byte write error - Retrying.\n");
2231190873Sjfv		else
2232190873Sjfv			DEBUGOUT("I2C byte write error.\n");
2233190873Sjfv	} while (retry < max_retry);
2234190873Sjfv
2235283620Serj	if (lock)
2236283620Serj		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2237190873Sjfv
2238190873Sjfv	return status;
2239190873Sjfv}
2240190873Sjfv
2241190873Sjfv/**
2242283620Serj *  ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
2243283620Serj *  @hw: pointer to hardware structure
2244283620Serj *  @byte_offset: byte offset to write
2245283620Serj *  @data: value to write
2246283620Serj *
2247283620Serj *  Performs byte write operation to SFP module's EEPROM over I2C interface at
2248283620Serj *  a specified device address.
2249283620Serj **/
2250283620Serjs32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
2251283620Serj				 u8 dev_addr, u8 data)
2252283620Serj{
2253283620Serj	return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr,
2254283620Serj						data, TRUE);
2255283620Serj}
2256283620Serj
2257283620Serj/**
2258283620Serj *  ixgbe_write_i2c_byte_generic_unlocked - Writes 8 bit word over I2C
2259283620Serj *  @hw: pointer to hardware structure
2260283620Serj *  @byte_offset: byte offset to write
2261283620Serj *  @data: value to write
2262283620Serj *
2263283620Serj *  Performs byte write operation to SFP module's EEPROM over I2C interface at
2264283620Serj *  a specified device address.
2265283620Serj **/
2266283620Serjs32 ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
2267283620Serj					  u8 dev_addr, u8 data)
2268283620Serj{
2269283620Serj	return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr,
2270283620Serj						data, FALSE);
2271283620Serj}
2272283620Serj
2273283620Serj/**
2274190873Sjfv *  ixgbe_i2c_start - Sets I2C start condition
2275190873Sjfv *  @hw: pointer to hardware structure
2276190873Sjfv *
2277190873Sjfv *  Sets I2C start condition (High -> Low on SDA while SCL is High)
2278283620Serj *  Set bit-bang mode on X550 hardware.
2279190873Sjfv **/
2280190873Sjfvstatic void ixgbe_i2c_start(struct ixgbe_hw *hw)
2281190873Sjfv{
2282283620Serj	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
2283190873Sjfv
2284190873Sjfv	DEBUGFUNC("ixgbe_i2c_start");
2285190873Sjfv
2286283620Serj	i2cctl |= IXGBE_I2C_BB_EN_BY_MAC(hw);
2287283620Serj
2288190873Sjfv	/* Start condition must begin with data and clock high */
2289190873Sjfv	ixgbe_set_i2c_data(hw, &i2cctl, 1);
2290190873Sjfv	ixgbe_raise_i2c_clk(hw, &i2cctl);
2291190873Sjfv
2292190873Sjfv	/* Setup time for start condition (4.7us) */
2293190873Sjfv	usec_delay(IXGBE_I2C_T_SU_STA);
2294190873Sjfv
2295190873Sjfv	ixgbe_set_i2c_data(hw, &i2cctl, 0);
2296190873Sjfv
2297190873Sjfv	/* Hold time for start condition (4us) */
2298190873Sjfv	usec_delay(IXGBE_I2C_T_HD_STA);
2299190873Sjfv
2300190873Sjfv	ixgbe_lower_i2c_clk(hw, &i2cctl);
2301190873Sjfv
2302190873Sjfv	/* Minimum low period of clock is 4.7 us */
2303190873Sjfv	usec_delay(IXGBE_I2C_T_LOW);
2304190873Sjfv
2305190873Sjfv}
2306190873Sjfv
2307190873Sjfv/**
2308190873Sjfv *  ixgbe_i2c_stop - Sets I2C stop condition
2309190873Sjfv *  @hw: pointer to hardware structure
2310190873Sjfv *
2311190873Sjfv *  Sets I2C stop condition (Low -> High on SDA while SCL is High)
2312283620Serj *  Disables bit-bang mode and negates data output enable on X550
2313283620Serj *  hardware.
2314190873Sjfv **/
2315190873Sjfvstatic void ixgbe_i2c_stop(struct ixgbe_hw *hw)
2316190873Sjfv{
2317283620Serj	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
2318283620Serj	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
2319283620Serj	u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw);
2320283620Serj	u32 bb_en_bit = IXGBE_I2C_BB_EN_BY_MAC(hw);
2321190873Sjfv
2322190873Sjfv	DEBUGFUNC("ixgbe_i2c_stop");
2323190873Sjfv
2324190873Sjfv	/* Stop condition must begin with data low and clock high */
2325190873Sjfv	ixgbe_set_i2c_data(hw, &i2cctl, 0);
2326190873Sjfv	ixgbe_raise_i2c_clk(hw, &i2cctl);
2327190873Sjfv
2328190873Sjfv	/* Setup time for stop condition (4us) */
2329190873Sjfv	usec_delay(IXGBE_I2C_T_SU_STO);
2330190873Sjfv
2331190873Sjfv	ixgbe_set_i2c_data(hw, &i2cctl, 1);
2332190873Sjfv
2333190873Sjfv	/* bus free time between stop and start (4.7us)*/
2334190873Sjfv	usec_delay(IXGBE_I2C_T_BUF);
2335283620Serj
2336283620Serj	if (bb_en_bit || data_oe_bit || clk_oe_bit) {
2337283620Serj		i2cctl &= ~bb_en_bit;
2338283620Serj		i2cctl |= data_oe_bit | clk_oe_bit;
2339283620Serj		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl);
2340283620Serj		IXGBE_WRITE_FLUSH(hw);
2341283620Serj	}
2342190873Sjfv}
2343190873Sjfv
2344190873Sjfv/**
2345190873Sjfv *  ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C
2346190873Sjfv *  @hw: pointer to hardware structure
2347190873Sjfv *  @data: data byte to clock in
2348190873Sjfv *
2349190873Sjfv *  Clocks in one byte data via I2C data/clock
2350190873Sjfv **/
2351190873Sjfvstatic s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
2352190873Sjfv{
2353190873Sjfv	s32 i;
2354190873Sjfv	bool bit = 0;
2355190873Sjfv
2356190873Sjfv	DEBUGFUNC("ixgbe_clock_in_i2c_byte");
2357190873Sjfv
2358283620Serj	*data = 0;
2359190873Sjfv	for (i = 7; i >= 0; i--) {
2360230775Sjfv		ixgbe_clock_in_i2c_bit(hw, &bit);
2361215911Sjfv		*data |= bit << i;
2362190873Sjfv	}
2363190873Sjfv
2364230775Sjfv	return IXGBE_SUCCESS;
2365190873Sjfv}
2366190873Sjfv
2367190873Sjfv/**
2368190873Sjfv *  ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C
2369190873Sjfv *  @hw: pointer to hardware structure
2370190873Sjfv *  @data: data byte clocked out
2371190873Sjfv *
2372190873Sjfv *  Clocks out one byte data via I2C data/clock
2373190873Sjfv **/
2374190873Sjfvstatic s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
2375190873Sjfv{
2376190873Sjfv	s32 status = IXGBE_SUCCESS;
2377190873Sjfv	s32 i;
2378190873Sjfv	u32 i2cctl;
2379283620Serj	bool bit;
2380190873Sjfv
2381190873Sjfv	DEBUGFUNC("ixgbe_clock_out_i2c_byte");
2382190873Sjfv
2383190873Sjfv	for (i = 7; i >= 0; i--) {
2384190873Sjfv		bit = (data >> i) & 0x1;
2385190873Sjfv		status = ixgbe_clock_out_i2c_bit(hw, bit);
2386190873Sjfv
2387190873Sjfv		if (status != IXGBE_SUCCESS)
2388190873Sjfv			break;
2389190873Sjfv	}
2390190873Sjfv
2391190873Sjfv	/* Release SDA line (set high) */
2392283620Serj	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
2393283620Serj	i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw);
2394283620Serj	i2cctl |= IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
2395283620Serj	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl);
2396230775Sjfv	IXGBE_WRITE_FLUSH(hw);
2397190873Sjfv
2398190873Sjfv	return status;
2399190873Sjfv}
2400190873Sjfv
2401190873Sjfv/**
2402190873Sjfv *  ixgbe_get_i2c_ack - Polls for I2C ACK
2403190873Sjfv *  @hw: pointer to hardware structure
2404190873Sjfv *
2405190873Sjfv *  Clocks in/out one bit via I2C data/clock
2406190873Sjfv **/
2407190873Sjfvstatic s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
2408190873Sjfv{
2409283620Serj	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
2410230775Sjfv	s32 status = IXGBE_SUCCESS;
2411190873Sjfv	u32 i = 0;
2412283620Serj	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
2413190873Sjfv	u32 timeout = 10;
2414190873Sjfv	bool ack = 1;
2415190873Sjfv
2416190873Sjfv	DEBUGFUNC("ixgbe_get_i2c_ack");
2417190873Sjfv
2418283620Serj	if (data_oe_bit) {
2419283620Serj		i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw);
2420283620Serj		i2cctl |= data_oe_bit;
2421283620Serj		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl);
2422283620Serj		IXGBE_WRITE_FLUSH(hw);
2423283620Serj	}
2424230775Sjfv	ixgbe_raise_i2c_clk(hw, &i2cctl);
2425190873Sjfv
2426190873Sjfv	/* Minimum high period of clock is 4us */
2427190873Sjfv	usec_delay(IXGBE_I2C_T_HIGH);
2428190873Sjfv
2429190873Sjfv	/* Poll for ACK.  Note that ACK in I2C spec is
2430190873Sjfv	 * transition from 1 to 0 */
2431190873Sjfv	for (i = 0; i < timeout; i++) {
2432283620Serj		i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
2433283620Serj		ack = ixgbe_get_i2c_data(hw, &i2cctl);
2434190873Sjfv
2435190873Sjfv		usec_delay(1);
2436283620Serj		if (!ack)
2437190873Sjfv			break;
2438190873Sjfv	}
2439190873Sjfv
2440283620Serj	if (ack) {
2441283620Serj		DEBUGOUT("I2C ack was not received.\n");
2442190873Sjfv		status = IXGBE_ERR_I2C;
2443190873Sjfv	}
2444190873Sjfv
2445190873Sjfv	ixgbe_lower_i2c_clk(hw, &i2cctl);
2446190873Sjfv
2447190873Sjfv	/* Minimum low period of clock is 4.7 us */
2448190873Sjfv	usec_delay(IXGBE_I2C_T_LOW);
2449190873Sjfv
2450190873Sjfv	return status;
2451190873Sjfv}
2452190873Sjfv
2453190873Sjfv/**
2454190873Sjfv *  ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
2455190873Sjfv *  @hw: pointer to hardware structure
2456190873Sjfv *  @data: read data value
2457190873Sjfv *
2458190873Sjfv *  Clocks in one bit via I2C data/clock
2459190873Sjfv **/
2460190873Sjfvstatic s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
2461190873Sjfv{
2462283620Serj	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
2463283620Serj	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
2464190873Sjfv
2465200239Sjfv	DEBUGFUNC("ixgbe_clock_in_i2c_bit");
2466200239Sjfv
2467283620Serj	if (data_oe_bit) {
2468283620Serj		i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw);
2469283620Serj		i2cctl |= data_oe_bit;
2470283620Serj		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl);
2471283620Serj		IXGBE_WRITE_FLUSH(hw);
2472283620Serj	}
2473230775Sjfv	ixgbe_raise_i2c_clk(hw, &i2cctl);
2474190873Sjfv
2475190873Sjfv	/* Minimum high period of clock is 4us */
2476190873Sjfv	usec_delay(IXGBE_I2C_T_HIGH);
2477190873Sjfv
2478283620Serj	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
2479283620Serj	*data = ixgbe_get_i2c_data(hw, &i2cctl);
2480190873Sjfv
2481190873Sjfv	ixgbe_lower_i2c_clk(hw, &i2cctl);
2482190873Sjfv
2483190873Sjfv	/* Minimum low period of clock is 4.7 us */
2484190873Sjfv	usec_delay(IXGBE_I2C_T_LOW);
2485190873Sjfv
2486230775Sjfv	return IXGBE_SUCCESS;
2487190873Sjfv}
2488190873Sjfv
2489190873Sjfv/**
2490190873Sjfv *  ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
2491190873Sjfv *  @hw: pointer to hardware structure
2492190873Sjfv *  @data: data value to write
2493190873Sjfv *
2494190873Sjfv *  Clocks out one bit via I2C data/clock
2495190873Sjfv **/
2496190873Sjfvstatic s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
2497190873Sjfv{
2498190873Sjfv	s32 status;
2499283620Serj	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
2500190873Sjfv
2501200239Sjfv	DEBUGFUNC("ixgbe_clock_out_i2c_bit");
2502200239Sjfv
2503190873Sjfv	status = ixgbe_set_i2c_data(hw, &i2cctl, data);
2504190873Sjfv	if (status == IXGBE_SUCCESS) {
2505230775Sjfv		ixgbe_raise_i2c_clk(hw, &i2cctl);
2506190873Sjfv
2507190873Sjfv		/* Minimum high period of clock is 4us */
2508190873Sjfv		usec_delay(IXGBE_I2C_T_HIGH);
2509190873Sjfv
2510190873Sjfv		ixgbe_lower_i2c_clk(hw, &i2cctl);
2511190873Sjfv
2512190873Sjfv		/* Minimum low period of clock is 4.7 us.
2513190873Sjfv		 * This also takes care of the data hold time.
2514190873Sjfv		 */
2515190873Sjfv		usec_delay(IXGBE_I2C_T_LOW);
2516190873Sjfv	} else {
2517190873Sjfv		status = IXGBE_ERR_I2C;
2518251964Sjfv		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
2519251964Sjfv			     "I2C data was not set to %X\n", data);
2520190873Sjfv	}
2521190873Sjfv
2522190873Sjfv	return status;
2523190873Sjfv}
2524283620Serj
2525190873Sjfv/**
2526190873Sjfv *  ixgbe_raise_i2c_clk - Raises the I2C SCL clock
2527190873Sjfv *  @hw: pointer to hardware structure
2528190873Sjfv *  @i2cctl: Current value of I2CCTL register
2529190873Sjfv *
2530190873Sjfv *  Raises the I2C clock line '0'->'1'
2531283620Serj *  Negates the I2C clock output enable on X550 hardware.
2532190873Sjfv **/
2533230775Sjfvstatic void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
2534190873Sjfv{
2535283620Serj	u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw);
2536238149Sjfv	u32 i = 0;
2537238149Sjfv	u32 timeout = IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT;
2538238149Sjfv	u32 i2cctl_r = 0;
2539238149Sjfv
2540200239Sjfv	DEBUGFUNC("ixgbe_raise_i2c_clk");
2541200239Sjfv
2542283620Serj	if (clk_oe_bit) {
2543283620Serj		*i2cctl |= clk_oe_bit;
2544283620Serj		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
2545283620Serj	}
2546283620Serj
2547238149Sjfv	for (i = 0; i < timeout; i++) {
2548283620Serj		*i2cctl |= IXGBE_I2C_CLK_OUT_BY_MAC(hw);
2549190873Sjfv
2550283620Serj		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
2551238149Sjfv		IXGBE_WRITE_FLUSH(hw);
2552238149Sjfv		/* SCL rise time (1000ns) */
2553238149Sjfv		usec_delay(IXGBE_I2C_T_RISE);
2554190873Sjfv
2555283620Serj		i2cctl_r = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
2556283620Serj		if (i2cctl_r & IXGBE_I2C_CLK_IN_BY_MAC(hw))
2557238149Sjfv			break;
2558238149Sjfv	}
2559190873Sjfv}
2560190873Sjfv
2561190873Sjfv/**
2562190873Sjfv *  ixgbe_lower_i2c_clk - Lowers the I2C SCL clock
2563190873Sjfv *  @hw: pointer to hardware structure
2564190873Sjfv *  @i2cctl: Current value of I2CCTL register
2565190873Sjfv *
2566190873Sjfv *  Lowers the I2C clock line '1'->'0'
2567283620Serj *  Asserts the I2C clock output enable on X550 hardware.
2568190873Sjfv **/
2569190873Sjfvstatic void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
2570190873Sjfv{
2571200239Sjfv	DEBUGFUNC("ixgbe_lower_i2c_clk");
2572200239Sjfv
2573283620Serj	*i2cctl &= ~(IXGBE_I2C_CLK_OUT_BY_MAC(hw));
2574283620Serj	*i2cctl &= ~IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw);
2575190873Sjfv
2576283620Serj	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
2577230775Sjfv	IXGBE_WRITE_FLUSH(hw);
2578190873Sjfv
2579190873Sjfv	/* SCL fall time (300ns) */
2580190873Sjfv	usec_delay(IXGBE_I2C_T_FALL);
2581190873Sjfv}
2582190873Sjfv
2583190873Sjfv/**
2584190873Sjfv *  ixgbe_set_i2c_data - Sets the I2C data bit
2585190873Sjfv *  @hw: pointer to hardware structure
2586190873Sjfv *  @i2cctl: Current value of I2CCTL register
2587190873Sjfv *  @data: I2C data value (0 or 1) to set
2588190873Sjfv *
2589190873Sjfv *  Sets the I2C data bit
2590283620Serj *  Asserts the I2C data output enable on X550 hardware.
2591190873Sjfv **/
2592190873Sjfvstatic s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
2593190873Sjfv{
2594283620Serj	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
2595190873Sjfv	s32 status = IXGBE_SUCCESS;
2596190873Sjfv
2597200239Sjfv	DEBUGFUNC("ixgbe_set_i2c_data");
2598200239Sjfv
2599190873Sjfv	if (data)
2600283620Serj		*i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw);
2601190873Sjfv	else
2602283620Serj		*i2cctl &= ~(IXGBE_I2C_DATA_OUT_BY_MAC(hw));
2603283620Serj	*i2cctl &= ~data_oe_bit;
2604190873Sjfv
2605283620Serj	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
2606230775Sjfv	IXGBE_WRITE_FLUSH(hw);
2607190873Sjfv
2608190873Sjfv	/* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
2609190873Sjfv	usec_delay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
2610190873Sjfv
2611283620Serj	if (!data)	/* Can't verify data in this case */
2612283620Serj		return IXGBE_SUCCESS;
2613283620Serj	if (data_oe_bit) {
2614283620Serj		*i2cctl |= data_oe_bit;
2615283620Serj		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
2616283620Serj		IXGBE_WRITE_FLUSH(hw);
2617283620Serj	}
2618283620Serj
2619190873Sjfv	/* Verify data was set correctly */
2620283620Serj	*i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
2621283620Serj	if (data != ixgbe_get_i2c_data(hw, i2cctl)) {
2622190873Sjfv		status = IXGBE_ERR_I2C;
2623251964Sjfv		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
2624251964Sjfv			     "Error - I2C data was not set to %X.\n",
2625251964Sjfv			     data);
2626190873Sjfv	}
2627190873Sjfv
2628190873Sjfv	return status;
2629190873Sjfv}
2630190873Sjfv
2631190873Sjfv/**
2632190873Sjfv *  ixgbe_get_i2c_data - Reads the I2C SDA data bit
2633190873Sjfv *  @hw: pointer to hardware structure
2634190873Sjfv *  @i2cctl: Current value of I2CCTL register
2635190873Sjfv *
2636190873Sjfv *  Returns the I2C data bit value
2637283620Serj *  Negates the I2C data output enable on X550 hardware.
2638190873Sjfv **/
2639283620Serjstatic bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl)
2640190873Sjfv{
2641283620Serj	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw);
2642190873Sjfv	bool data;
2643190873Sjfv
2644200239Sjfv	DEBUGFUNC("ixgbe_get_i2c_data");
2645200239Sjfv
2646283620Serj	if (data_oe_bit) {
2647283620Serj		*i2cctl |= data_oe_bit;
2648283620Serj		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl);
2649283620Serj		IXGBE_WRITE_FLUSH(hw);
2650283620Serj		usec_delay(IXGBE_I2C_T_FALL);
2651283620Serj	}
2652283620Serj
2653283620Serj	if (*i2cctl & IXGBE_I2C_DATA_IN_BY_MAC(hw))
2654190873Sjfv		data = 1;
2655190873Sjfv	else
2656190873Sjfv		data = 0;
2657190873Sjfv
2658190873Sjfv	return data;
2659190873Sjfv}
2660190873Sjfv
2661190873Sjfv/**
2662190873Sjfv *  ixgbe_i2c_bus_clear - Clears the I2C bus
2663190873Sjfv *  @hw: pointer to hardware structure
2664190873Sjfv *
2665190873Sjfv *  Clears the I2C bus by sending nine clock pulses.
2666190873Sjfv *  Used when data line is stuck low.
2667190873Sjfv **/
2668190873Sjfvvoid ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
2669190873Sjfv{
2670283620Serj	u32 i2cctl;
2671190873Sjfv	u32 i;
2672190873Sjfv
2673190873Sjfv	DEBUGFUNC("ixgbe_i2c_bus_clear");
2674190873Sjfv
2675190873Sjfv	ixgbe_i2c_start(hw);
2676283620Serj	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw));
2677190873Sjfv
2678190873Sjfv	ixgbe_set_i2c_data(hw, &i2cctl, 1);
2679190873Sjfv
2680190873Sjfv	for (i = 0; i < 9; i++) {
2681190873Sjfv		ixgbe_raise_i2c_clk(hw, &i2cctl);
2682190873Sjfv
2683190873Sjfv		/* Min high period of clock is 4us */
2684190873Sjfv		usec_delay(IXGBE_I2C_T_HIGH);
2685190873Sjfv
2686190873Sjfv		ixgbe_lower_i2c_clk(hw, &i2cctl);
2687190873Sjfv
2688190873Sjfv		/* Min low period of clock is 4.7us*/
2689190873Sjfv		usec_delay(IXGBE_I2C_T_LOW);
2690190873Sjfv	}
2691190873Sjfv
2692190873Sjfv	ixgbe_i2c_start(hw);
2693190873Sjfv
2694190873Sjfv	/* Put the i2c bus back to default state */
2695190873Sjfv	ixgbe_i2c_stop(hw);
2696190873Sjfv}
2697205720Sjfv
2698205720Sjfv/**
2699238149Sjfv *  ixgbe_tn_check_overtemp - Checks if an overtemp occurred.
2700205720Sjfv *  @hw: pointer to hardware structure
2701205720Sjfv *
2702205720Sjfv *  Checks if the LASI temp alarm status was triggered due to overtemp
2703205720Sjfv **/
2704205720Sjfvs32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
2705205720Sjfv{
2706205720Sjfv	s32 status = IXGBE_SUCCESS;
2707205720Sjfv	u16 phy_data = 0;
2708205720Sjfv
2709205720Sjfv	DEBUGFUNC("ixgbe_tn_check_overtemp");
2710205720Sjfv
2711205720Sjfv	if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM)
2712205720Sjfv		goto out;
2713205720Sjfv
2714205720Sjfv	/* Check that the LASI temp alarm status was triggered */
2715205720Sjfv	hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
2716205720Sjfv			     IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_data);
2717205720Sjfv
2718205720Sjfv	if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM))
2719205720Sjfv		goto out;
2720205720Sjfv
2721205720Sjfv	status = IXGBE_ERR_OVERTEMP;
2722251964Sjfv	ERROR_REPORT1(IXGBE_ERROR_CAUTION, "Device over temperature");
2723205720Sjfvout:
2724205720Sjfv	return status;
2725205720Sjfv}
2726283620Serj
2727283620Serj/**
2728283620Serj * ixgbe_set_copper_phy_power - Control power for copper phy
2729283620Serj * @hw: pointer to hardware structure
2730283620Serj * @on: TRUE for on, FALSE for off
2731283620Serj */
2732283620Serjs32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on)
2733283620Serj{
2734283620Serj	u32 status;
2735283620Serj	u16 reg;
2736283620Serj
2737295528Ssmh	if (!on && ixgbe_mng_present(hw))
2738295528Ssmh		return 0;
2739295528Ssmh
2740283620Serj	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
2741283620Serj				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2742283620Serj				      &reg);
2743283620Serj	if (status)
2744283620Serj		return status;
2745283620Serj
2746283620Serj	if (on) {
2747283620Serj		reg &= ~IXGBE_MDIO_PHY_SET_LOW_POWER_MODE;
2748283620Serj	} else {
2749283620Serj		if (ixgbe_check_reset_blocked(hw))
2750283620Serj			return 0;
2751283620Serj		reg |= IXGBE_MDIO_PHY_SET_LOW_POWER_MODE;
2752283620Serj	}
2753283620Serj
2754283620Serj	status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
2755283620Serj				       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2756283620Serj				       reg);
2757283620Serj	return status;
2758283620Serj}
2759