xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /* Copyright(c) 1999 - 2018 Intel Corporation. */
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include <linux/pci.h>
5*4882a593Smuzhiyun #include <linux/delay.h>
6*4882a593Smuzhiyun #include <linux/iopoll.h>
7*4882a593Smuzhiyun #include <linux/sched.h>
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include "ixgbe.h"
10*4882a593Smuzhiyun #include "ixgbe_phy.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun static void ixgbe_i2c_start(struct ixgbe_hw *hw);
13*4882a593Smuzhiyun static void ixgbe_i2c_stop(struct ixgbe_hw *hw);
14*4882a593Smuzhiyun static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data);
15*4882a593Smuzhiyun static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data);
16*4882a593Smuzhiyun static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw);
17*4882a593Smuzhiyun static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data);
18*4882a593Smuzhiyun static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data);
19*4882a593Smuzhiyun static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
20*4882a593Smuzhiyun static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
21*4882a593Smuzhiyun static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
22*4882a593Smuzhiyun static bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl);
23*4882a593Smuzhiyun static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
24*4882a593Smuzhiyun static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
25*4882a593Smuzhiyun static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
26*4882a593Smuzhiyun static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw);
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun /**
29*4882a593Smuzhiyun  *  ixgbe_out_i2c_byte_ack - Send I2C byte with ack
30*4882a593Smuzhiyun  *  @hw: pointer to the hardware structure
31*4882a593Smuzhiyun  *  @byte: byte to send
32*4882a593Smuzhiyun  *
33*4882a593Smuzhiyun  *  Returns an error code on error.
34*4882a593Smuzhiyun  **/
ixgbe_out_i2c_byte_ack(struct ixgbe_hw * hw,u8 byte)35*4882a593Smuzhiyun static s32 ixgbe_out_i2c_byte_ack(struct ixgbe_hw *hw, u8 byte)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun 	s32 status;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 	status = ixgbe_clock_out_i2c_byte(hw, byte);
40*4882a593Smuzhiyun 	if (status)
41*4882a593Smuzhiyun 		return status;
42*4882a593Smuzhiyun 	return ixgbe_get_i2c_ack(hw);
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun /**
46*4882a593Smuzhiyun  *  ixgbe_in_i2c_byte_ack - Receive an I2C byte and send ack
47*4882a593Smuzhiyun  *  @hw: pointer to the hardware structure
48*4882a593Smuzhiyun  *  @byte: pointer to a u8 to receive the byte
49*4882a593Smuzhiyun  *
50*4882a593Smuzhiyun  *  Returns an error code on error.
51*4882a593Smuzhiyun  **/
ixgbe_in_i2c_byte_ack(struct ixgbe_hw * hw,u8 * byte)52*4882a593Smuzhiyun static s32 ixgbe_in_i2c_byte_ack(struct ixgbe_hw *hw, u8 *byte)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun 	s32 status;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	status = ixgbe_clock_in_i2c_byte(hw, byte);
57*4882a593Smuzhiyun 	if (status)
58*4882a593Smuzhiyun 		return status;
59*4882a593Smuzhiyun 	/* ACK */
60*4882a593Smuzhiyun 	return ixgbe_clock_out_i2c_bit(hw, false);
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun /**
64*4882a593Smuzhiyun  *  ixgbe_ones_comp_byte_add - Perform one's complement addition
65*4882a593Smuzhiyun  *  @add1: addend 1
66*4882a593Smuzhiyun  *  @add2: addend 2
67*4882a593Smuzhiyun  *
68*4882a593Smuzhiyun  *  Returns one's complement 8-bit sum.
69*4882a593Smuzhiyun  **/
ixgbe_ones_comp_byte_add(u8 add1,u8 add2)70*4882a593Smuzhiyun static u8 ixgbe_ones_comp_byte_add(u8 add1, u8 add2)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	u16 sum = add1 + add2;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	sum = (sum & 0xFF) + (sum >> 8);
75*4882a593Smuzhiyun 	return sum & 0xFF;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /**
79*4882a593Smuzhiyun  *  ixgbe_read_i2c_combined_generic_int - Perform I2C read combined operation
80*4882a593Smuzhiyun  *  @hw: pointer to the hardware structure
81*4882a593Smuzhiyun  *  @addr: I2C bus address to read from
82*4882a593Smuzhiyun  *  @reg: I2C device register to read from
83*4882a593Smuzhiyun  *  @val: pointer to location to receive read value
84*4882a593Smuzhiyun  *  @lock: true if to take and release semaphore
85*4882a593Smuzhiyun  *
86*4882a593Smuzhiyun  *  Returns an error code on error.
87*4882a593Smuzhiyun  */
ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 * val,bool lock)88*4882a593Smuzhiyun s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr,
89*4882a593Smuzhiyun 					u16 reg, u16 *val, bool lock)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
92*4882a593Smuzhiyun 	int max_retry = 3;
93*4882a593Smuzhiyun 	int retry = 0;
94*4882a593Smuzhiyun 	u8 csum_byte;
95*4882a593Smuzhiyun 	u8 high_bits;
96*4882a593Smuzhiyun 	u8 low_bits;
97*4882a593Smuzhiyun 	u8 reg_high;
98*4882a593Smuzhiyun 	u8 csum;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	reg_high = ((reg >> 7) & 0xFE) | 1;     /* Indicate read combined */
101*4882a593Smuzhiyun 	csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF);
102*4882a593Smuzhiyun 	csum = ~csum;
103*4882a593Smuzhiyun 	do {
104*4882a593Smuzhiyun 		if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
105*4882a593Smuzhiyun 			return IXGBE_ERR_SWFW_SYNC;
106*4882a593Smuzhiyun 		ixgbe_i2c_start(hw);
107*4882a593Smuzhiyun 		/* Device Address and write indication */
108*4882a593Smuzhiyun 		if (ixgbe_out_i2c_byte_ack(hw, addr))
109*4882a593Smuzhiyun 			goto fail;
110*4882a593Smuzhiyun 		/* Write bits 14:8 */
111*4882a593Smuzhiyun 		if (ixgbe_out_i2c_byte_ack(hw, reg_high))
112*4882a593Smuzhiyun 			goto fail;
113*4882a593Smuzhiyun 		/* Write bits 7:0 */
114*4882a593Smuzhiyun 		if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF))
115*4882a593Smuzhiyun 			goto fail;
116*4882a593Smuzhiyun 		/* Write csum */
117*4882a593Smuzhiyun 		if (ixgbe_out_i2c_byte_ack(hw, csum))
118*4882a593Smuzhiyun 			goto fail;
119*4882a593Smuzhiyun 		/* Re-start condition */
120*4882a593Smuzhiyun 		ixgbe_i2c_start(hw);
121*4882a593Smuzhiyun 		/* Device Address and read indication */
122*4882a593Smuzhiyun 		if (ixgbe_out_i2c_byte_ack(hw, addr | 1))
123*4882a593Smuzhiyun 			goto fail;
124*4882a593Smuzhiyun 		/* Get upper bits */
125*4882a593Smuzhiyun 		if (ixgbe_in_i2c_byte_ack(hw, &high_bits))
126*4882a593Smuzhiyun 			goto fail;
127*4882a593Smuzhiyun 		/* Get low bits */
128*4882a593Smuzhiyun 		if (ixgbe_in_i2c_byte_ack(hw, &low_bits))
129*4882a593Smuzhiyun 			goto fail;
130*4882a593Smuzhiyun 		/* Get csum */
131*4882a593Smuzhiyun 		if (ixgbe_clock_in_i2c_byte(hw, &csum_byte))
132*4882a593Smuzhiyun 			goto fail;
133*4882a593Smuzhiyun 		/* NACK */
134*4882a593Smuzhiyun 		if (ixgbe_clock_out_i2c_bit(hw, false))
135*4882a593Smuzhiyun 			goto fail;
136*4882a593Smuzhiyun 		ixgbe_i2c_stop(hw);
137*4882a593Smuzhiyun 		if (lock)
138*4882a593Smuzhiyun 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
139*4882a593Smuzhiyun 		*val = (high_bits << 8) | low_bits;
140*4882a593Smuzhiyun 		return 0;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun fail:
143*4882a593Smuzhiyun 		ixgbe_i2c_bus_clear(hw);
144*4882a593Smuzhiyun 		if (lock)
145*4882a593Smuzhiyun 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
146*4882a593Smuzhiyun 		retry++;
147*4882a593Smuzhiyun 		if (retry < max_retry)
148*4882a593Smuzhiyun 			hw_dbg(hw, "I2C byte read combined error - Retry.\n");
149*4882a593Smuzhiyun 		else
150*4882a593Smuzhiyun 			hw_dbg(hw, "I2C byte read combined error.\n");
151*4882a593Smuzhiyun 	} while (retry < max_retry);
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	return IXGBE_ERR_I2C;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun /**
157*4882a593Smuzhiyun  *  ixgbe_write_i2c_combined_generic_int - Perform I2C write combined operation
158*4882a593Smuzhiyun  *  @hw: pointer to the hardware structure
159*4882a593Smuzhiyun  *  @addr: I2C bus address to write to
160*4882a593Smuzhiyun  *  @reg: I2C device register to write to
161*4882a593Smuzhiyun  *  @val: value to write
162*4882a593Smuzhiyun  *  @lock: true if to take and release semaphore
163*4882a593Smuzhiyun  *
164*4882a593Smuzhiyun  *  Returns an error code on error.
165*4882a593Smuzhiyun  */
ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 val,bool lock)166*4882a593Smuzhiyun s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr,
167*4882a593Smuzhiyun 					 u16 reg, u16 val, bool lock)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
170*4882a593Smuzhiyun 	int max_retry = 1;
171*4882a593Smuzhiyun 	int retry = 0;
172*4882a593Smuzhiyun 	u8 reg_high;
173*4882a593Smuzhiyun 	u8 csum;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	reg_high = (reg >> 7) & 0xFE;   /* Indicate write combined */
176*4882a593Smuzhiyun 	csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF);
177*4882a593Smuzhiyun 	csum = ixgbe_ones_comp_byte_add(csum, val >> 8);
178*4882a593Smuzhiyun 	csum = ixgbe_ones_comp_byte_add(csum, val & 0xFF);
179*4882a593Smuzhiyun 	csum = ~csum;
180*4882a593Smuzhiyun 	do {
181*4882a593Smuzhiyun 		if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
182*4882a593Smuzhiyun 			return IXGBE_ERR_SWFW_SYNC;
183*4882a593Smuzhiyun 		ixgbe_i2c_start(hw);
184*4882a593Smuzhiyun 		/* Device Address and write indication */
185*4882a593Smuzhiyun 		if (ixgbe_out_i2c_byte_ack(hw, addr))
186*4882a593Smuzhiyun 			goto fail;
187*4882a593Smuzhiyun 		/* Write bits 14:8 */
188*4882a593Smuzhiyun 		if (ixgbe_out_i2c_byte_ack(hw, reg_high))
189*4882a593Smuzhiyun 			goto fail;
190*4882a593Smuzhiyun 		/* Write bits 7:0 */
191*4882a593Smuzhiyun 		if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF))
192*4882a593Smuzhiyun 			goto fail;
193*4882a593Smuzhiyun 		/* Write data 15:8 */
194*4882a593Smuzhiyun 		if (ixgbe_out_i2c_byte_ack(hw, val >> 8))
195*4882a593Smuzhiyun 			goto fail;
196*4882a593Smuzhiyun 		/* Write data 7:0 */
197*4882a593Smuzhiyun 		if (ixgbe_out_i2c_byte_ack(hw, val & 0xFF))
198*4882a593Smuzhiyun 			goto fail;
199*4882a593Smuzhiyun 		/* Write csum */
200*4882a593Smuzhiyun 		if (ixgbe_out_i2c_byte_ack(hw, csum))
201*4882a593Smuzhiyun 			goto fail;
202*4882a593Smuzhiyun 		ixgbe_i2c_stop(hw);
203*4882a593Smuzhiyun 		if (lock)
204*4882a593Smuzhiyun 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
205*4882a593Smuzhiyun 		return 0;
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun fail:
208*4882a593Smuzhiyun 		ixgbe_i2c_bus_clear(hw);
209*4882a593Smuzhiyun 		if (lock)
210*4882a593Smuzhiyun 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
211*4882a593Smuzhiyun 		retry++;
212*4882a593Smuzhiyun 		if (retry < max_retry)
213*4882a593Smuzhiyun 			hw_dbg(hw, "I2C byte write combined error - Retry.\n");
214*4882a593Smuzhiyun 		else
215*4882a593Smuzhiyun 			hw_dbg(hw, "I2C byte write combined error.\n");
216*4882a593Smuzhiyun 	} while (retry < max_retry);
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	return IXGBE_ERR_I2C;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun /**
222*4882a593Smuzhiyun  *  ixgbe_probe_phy - Probe a single address for a PHY
223*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
224*4882a593Smuzhiyun  *  @phy_addr: PHY address to probe
225*4882a593Smuzhiyun  *
226*4882a593Smuzhiyun  *  Returns true if PHY found
227*4882a593Smuzhiyun  **/
ixgbe_probe_phy(struct ixgbe_hw * hw,u16 phy_addr)228*4882a593Smuzhiyun static bool ixgbe_probe_phy(struct ixgbe_hw *hw, u16 phy_addr)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	u16 ext_ability = 0;
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	hw->phy.mdio.prtad = phy_addr;
233*4882a593Smuzhiyun 	if (mdio45_probe(&hw->phy.mdio, phy_addr) != 0)
234*4882a593Smuzhiyun 		return false;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	if (ixgbe_get_phy_id(hw))
237*4882a593Smuzhiyun 		return false;
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id);
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	if (hw->phy.type == ixgbe_phy_unknown) {
242*4882a593Smuzhiyun 		hw->phy.ops.read_reg(hw,
243*4882a593Smuzhiyun 				     MDIO_PMA_EXTABLE,
244*4882a593Smuzhiyun 				     MDIO_MMD_PMAPMD,
245*4882a593Smuzhiyun 				     &ext_ability);
246*4882a593Smuzhiyun 		if (ext_ability &
247*4882a593Smuzhiyun 		    (MDIO_PMA_EXTABLE_10GBT |
248*4882a593Smuzhiyun 		     MDIO_PMA_EXTABLE_1000BT))
249*4882a593Smuzhiyun 			hw->phy.type = ixgbe_phy_cu_unknown;
250*4882a593Smuzhiyun 		else
251*4882a593Smuzhiyun 			hw->phy.type = ixgbe_phy_generic;
252*4882a593Smuzhiyun 	}
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	return true;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun /**
258*4882a593Smuzhiyun  *  ixgbe_identify_phy_generic - Get physical layer module
259*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
260*4882a593Smuzhiyun  *
261*4882a593Smuzhiyun  *  Determines the physical layer module found on the current adapter.
262*4882a593Smuzhiyun  **/
ixgbe_identify_phy_generic(struct ixgbe_hw * hw)263*4882a593Smuzhiyun s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun 	u32 phy_addr;
266*4882a593Smuzhiyun 	u32 status = IXGBE_ERR_PHY_ADDR_INVALID;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	if (!hw->phy.phy_semaphore_mask) {
269*4882a593Smuzhiyun 		if (hw->bus.lan_id)
270*4882a593Smuzhiyun 			hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
271*4882a593Smuzhiyun 		else
272*4882a593Smuzhiyun 			hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
273*4882a593Smuzhiyun 	}
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	if (hw->phy.type != ixgbe_phy_unknown)
276*4882a593Smuzhiyun 		return 0;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	if (hw->phy.nw_mng_if_sel) {
279*4882a593Smuzhiyun 		phy_addr = (hw->phy.nw_mng_if_sel &
280*4882a593Smuzhiyun 			    IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >>
281*4882a593Smuzhiyun 			   IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT;
282*4882a593Smuzhiyun 		if (ixgbe_probe_phy(hw, phy_addr))
283*4882a593Smuzhiyun 			return 0;
284*4882a593Smuzhiyun 		else
285*4882a593Smuzhiyun 			return IXGBE_ERR_PHY_ADDR_INVALID;
286*4882a593Smuzhiyun 	}
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
289*4882a593Smuzhiyun 		if (ixgbe_probe_phy(hw, phy_addr)) {
290*4882a593Smuzhiyun 			status = 0;
291*4882a593Smuzhiyun 			break;
292*4882a593Smuzhiyun 		}
293*4882a593Smuzhiyun 	}
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	/* Certain media types do not have a phy so an address will not
296*4882a593Smuzhiyun 	 * be found and the code will take this path.  Caller has to
297*4882a593Smuzhiyun 	 * decide if it is an error or not.
298*4882a593Smuzhiyun 	 */
299*4882a593Smuzhiyun 	if (status)
300*4882a593Smuzhiyun 		hw->phy.mdio.prtad = MDIO_PRTAD_NONE;
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	return status;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun /**
306*4882a593Smuzhiyun  * ixgbe_check_reset_blocked - check status of MNG FW veto bit
307*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
308*4882a593Smuzhiyun  *
309*4882a593Smuzhiyun  * This function checks the MMNGC.MNG_VETO bit to see if there are
310*4882a593Smuzhiyun  * any constraints on link from manageability.  For MAC's that don't
311*4882a593Smuzhiyun  * have this bit just return false since the link can not be blocked
312*4882a593Smuzhiyun  * via this method.
313*4882a593Smuzhiyun  **/
ixgbe_check_reset_blocked(struct ixgbe_hw * hw)314*4882a593Smuzhiyun bool ixgbe_check_reset_blocked(struct ixgbe_hw *hw)
315*4882a593Smuzhiyun {
316*4882a593Smuzhiyun 	u32 mmngc;
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	/* If we don't have this bit, it can't be blocking */
319*4882a593Smuzhiyun 	if (hw->mac.type == ixgbe_mac_82598EB)
320*4882a593Smuzhiyun 		return false;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	mmngc = IXGBE_READ_REG(hw, IXGBE_MMNGC);
323*4882a593Smuzhiyun 	if (mmngc & IXGBE_MMNGC_MNG_VETO) {
324*4882a593Smuzhiyun 		hw_dbg(hw, "MNG_VETO bit detected.\n");
325*4882a593Smuzhiyun 		return true;
326*4882a593Smuzhiyun 	}
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	return false;
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun /**
332*4882a593Smuzhiyun  *  ixgbe_get_phy_id - Get the phy type
333*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
334*4882a593Smuzhiyun  *
335*4882a593Smuzhiyun  **/
ixgbe_get_phy_id(struct ixgbe_hw * hw)336*4882a593Smuzhiyun static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun 	s32 status;
339*4882a593Smuzhiyun 	u16 phy_id_high = 0;
340*4882a593Smuzhiyun 	u16 phy_id_low = 0;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	status = hw->phy.ops.read_reg(hw, MDIO_DEVID1, MDIO_MMD_PMAPMD,
343*4882a593Smuzhiyun 				      &phy_id_high);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	if (!status) {
346*4882a593Smuzhiyun 		hw->phy.id = (u32)(phy_id_high << 16);
347*4882a593Smuzhiyun 		status = hw->phy.ops.read_reg(hw, MDIO_DEVID2, MDIO_MMD_PMAPMD,
348*4882a593Smuzhiyun 					      &phy_id_low);
349*4882a593Smuzhiyun 		hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
350*4882a593Smuzhiyun 		hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
351*4882a593Smuzhiyun 	}
352*4882a593Smuzhiyun 	return status;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun /**
356*4882a593Smuzhiyun  *  ixgbe_get_phy_type_from_id - Get the phy type
357*4882a593Smuzhiyun  *  @phy_id: hardware phy id
358*4882a593Smuzhiyun  *
359*4882a593Smuzhiyun  **/
ixgbe_get_phy_type_from_id(u32 phy_id)360*4882a593Smuzhiyun static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
361*4882a593Smuzhiyun {
362*4882a593Smuzhiyun 	enum ixgbe_phy_type phy_type;
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	switch (phy_id) {
365*4882a593Smuzhiyun 	case TN1010_PHY_ID:
366*4882a593Smuzhiyun 		phy_type = ixgbe_phy_tn;
367*4882a593Smuzhiyun 		break;
368*4882a593Smuzhiyun 	case X550_PHY_ID2:
369*4882a593Smuzhiyun 	case X550_PHY_ID3:
370*4882a593Smuzhiyun 	case X540_PHY_ID:
371*4882a593Smuzhiyun 		phy_type = ixgbe_phy_aq;
372*4882a593Smuzhiyun 		break;
373*4882a593Smuzhiyun 	case QT2022_PHY_ID:
374*4882a593Smuzhiyun 		phy_type = ixgbe_phy_qt;
375*4882a593Smuzhiyun 		break;
376*4882a593Smuzhiyun 	case ATH_PHY_ID:
377*4882a593Smuzhiyun 		phy_type = ixgbe_phy_nl;
378*4882a593Smuzhiyun 		break;
379*4882a593Smuzhiyun 	case X557_PHY_ID:
380*4882a593Smuzhiyun 	case X557_PHY_ID2:
381*4882a593Smuzhiyun 		phy_type = ixgbe_phy_x550em_ext_t;
382*4882a593Smuzhiyun 		break;
383*4882a593Smuzhiyun 	default:
384*4882a593Smuzhiyun 		phy_type = ixgbe_phy_unknown;
385*4882a593Smuzhiyun 		break;
386*4882a593Smuzhiyun 	}
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	return phy_type;
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun /**
392*4882a593Smuzhiyun  *  ixgbe_reset_phy_generic - Performs a PHY reset
393*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
394*4882a593Smuzhiyun  **/
ixgbe_reset_phy_generic(struct ixgbe_hw * hw)395*4882a593Smuzhiyun s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
396*4882a593Smuzhiyun {
397*4882a593Smuzhiyun 	u32 i;
398*4882a593Smuzhiyun 	u16 ctrl = 0;
399*4882a593Smuzhiyun 	s32 status = 0;
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	if (hw->phy.type == ixgbe_phy_unknown)
402*4882a593Smuzhiyun 		status = ixgbe_identify_phy_generic(hw);
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	if (status != 0 || hw->phy.type == ixgbe_phy_none)
405*4882a593Smuzhiyun 		return status;
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	/* Don't reset PHY if it's shut down due to overtemp. */
408*4882a593Smuzhiyun 	if (!hw->phy.reset_if_overtemp &&
409*4882a593Smuzhiyun 	    (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw)))
410*4882a593Smuzhiyun 		return 0;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	/* Blocked by MNG FW so bail */
413*4882a593Smuzhiyun 	if (ixgbe_check_reset_blocked(hw))
414*4882a593Smuzhiyun 		return 0;
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	/*
417*4882a593Smuzhiyun 	 * Perform soft PHY reset to the PHY_XS.
418*4882a593Smuzhiyun 	 * This will cause a soft reset to the PHY
419*4882a593Smuzhiyun 	 */
420*4882a593Smuzhiyun 	hw->phy.ops.write_reg(hw, MDIO_CTRL1,
421*4882a593Smuzhiyun 			      MDIO_MMD_PHYXS,
422*4882a593Smuzhiyun 			      MDIO_CTRL1_RESET);
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	/*
425*4882a593Smuzhiyun 	 * Poll for reset bit to self-clear indicating reset is complete.
426*4882a593Smuzhiyun 	 * Some PHYs could take up to 3 seconds to complete and need about
427*4882a593Smuzhiyun 	 * 1.7 usec delay after the reset is complete.
428*4882a593Smuzhiyun 	 */
429*4882a593Smuzhiyun 	for (i = 0; i < 30; i++) {
430*4882a593Smuzhiyun 		msleep(100);
431*4882a593Smuzhiyun 		if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
432*4882a593Smuzhiyun 			status = hw->phy.ops.read_reg(hw,
433*4882a593Smuzhiyun 						  IXGBE_MDIO_TX_VENDOR_ALARMS_3,
434*4882a593Smuzhiyun 						  MDIO_MMD_PMAPMD, &ctrl);
435*4882a593Smuzhiyun 			if (status)
436*4882a593Smuzhiyun 				return status;
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 			if (ctrl & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
439*4882a593Smuzhiyun 				udelay(2);
440*4882a593Smuzhiyun 				break;
441*4882a593Smuzhiyun 			}
442*4882a593Smuzhiyun 		} else {
443*4882a593Smuzhiyun 			status = hw->phy.ops.read_reg(hw, MDIO_CTRL1,
444*4882a593Smuzhiyun 						      MDIO_MMD_PHYXS, &ctrl);
445*4882a593Smuzhiyun 			if (status)
446*4882a593Smuzhiyun 				return status;
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 			if (!(ctrl & MDIO_CTRL1_RESET)) {
449*4882a593Smuzhiyun 				udelay(2);
450*4882a593Smuzhiyun 				break;
451*4882a593Smuzhiyun 			}
452*4882a593Smuzhiyun 		}
453*4882a593Smuzhiyun 	}
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	if (ctrl & MDIO_CTRL1_RESET) {
456*4882a593Smuzhiyun 		hw_dbg(hw, "PHY reset polling failed to complete.\n");
457*4882a593Smuzhiyun 		return IXGBE_ERR_RESET_FAILED;
458*4882a593Smuzhiyun 	}
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	return 0;
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun /**
464*4882a593Smuzhiyun  *  ixgbe_read_phy_mdi - Reads a value from a specified PHY register without
465*4882a593Smuzhiyun  *  the SWFW lock
466*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
467*4882a593Smuzhiyun  *  @reg_addr: 32 bit address of PHY register to read
468*4882a593Smuzhiyun  *  @device_type: 5 bit device type
469*4882a593Smuzhiyun  *  @phy_data: Pointer to read data from PHY register
470*4882a593Smuzhiyun  **/
ixgbe_read_phy_reg_mdi(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 * phy_data)471*4882a593Smuzhiyun s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
472*4882a593Smuzhiyun 		       u16 *phy_data)
473*4882a593Smuzhiyun {
474*4882a593Smuzhiyun 	u32 i, data, command;
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun 	/* Setup and write the address cycle command */
477*4882a593Smuzhiyun 	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
478*4882a593Smuzhiyun 		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
479*4882a593Smuzhiyun 		   (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
480*4882a593Smuzhiyun 		   (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 	/* Check every 10 usec to see if the address cycle completed.
485*4882a593Smuzhiyun 	 * The MDI Command bit will clear when the operation is
486*4882a593Smuzhiyun 	 * complete
487*4882a593Smuzhiyun 	 */
488*4882a593Smuzhiyun 	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
489*4882a593Smuzhiyun 		udelay(10);
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
492*4882a593Smuzhiyun 		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
493*4882a593Smuzhiyun 				break;
494*4882a593Smuzhiyun 	}
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
498*4882a593Smuzhiyun 		hw_dbg(hw, "PHY address command did not complete.\n");
499*4882a593Smuzhiyun 		return IXGBE_ERR_PHY;
500*4882a593Smuzhiyun 	}
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	/* Address cycle complete, setup and write the read
503*4882a593Smuzhiyun 	 * command
504*4882a593Smuzhiyun 	 */
505*4882a593Smuzhiyun 	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
506*4882a593Smuzhiyun 		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
507*4882a593Smuzhiyun 		   (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
508*4882a593Smuzhiyun 		   (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun 	/* Check every 10 usec to see if the address cycle
513*4882a593Smuzhiyun 	 * completed. The MDI Command bit will clear when the
514*4882a593Smuzhiyun 	 * operation is complete
515*4882a593Smuzhiyun 	 */
516*4882a593Smuzhiyun 	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
517*4882a593Smuzhiyun 		udelay(10);
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
520*4882a593Smuzhiyun 		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
521*4882a593Smuzhiyun 			break;
522*4882a593Smuzhiyun 	}
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
525*4882a593Smuzhiyun 		hw_dbg(hw, "PHY read command didn't complete\n");
526*4882a593Smuzhiyun 		return IXGBE_ERR_PHY;
527*4882a593Smuzhiyun 	}
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	/* Read operation is complete.  Get the data
530*4882a593Smuzhiyun 	 * from MSRWD
531*4882a593Smuzhiyun 	 */
532*4882a593Smuzhiyun 	data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
533*4882a593Smuzhiyun 	data >>= IXGBE_MSRWD_READ_DATA_SHIFT;
534*4882a593Smuzhiyun 	*phy_data = (u16)(data);
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 	return 0;
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun /**
540*4882a593Smuzhiyun  *  ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register
541*4882a593Smuzhiyun  *  using the SWFW lock - this function is needed in most cases
542*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
543*4882a593Smuzhiyun  *  @reg_addr: 32 bit address of PHY register to read
544*4882a593Smuzhiyun  *  @device_type: 5 bit device type
545*4882a593Smuzhiyun  *  @phy_data: Pointer to read data from PHY register
546*4882a593Smuzhiyun  **/
ixgbe_read_phy_reg_generic(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 * phy_data)547*4882a593Smuzhiyun s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
548*4882a593Smuzhiyun 			       u32 device_type, u16 *phy_data)
549*4882a593Smuzhiyun {
550*4882a593Smuzhiyun 	s32 status;
551*4882a593Smuzhiyun 	u32 gssr = hw->phy.phy_semaphore_mask;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == 0) {
554*4882a593Smuzhiyun 		status = ixgbe_read_phy_reg_mdi(hw, reg_addr, device_type,
555*4882a593Smuzhiyun 						phy_data);
556*4882a593Smuzhiyun 		hw->mac.ops.release_swfw_sync(hw, gssr);
557*4882a593Smuzhiyun 	} else {
558*4882a593Smuzhiyun 		return IXGBE_ERR_SWFW_SYNC;
559*4882a593Smuzhiyun 	}
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	return status;
562*4882a593Smuzhiyun }
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun /**
565*4882a593Smuzhiyun  *  ixgbe_write_phy_reg_mdi - Writes a value to specified PHY register
566*4882a593Smuzhiyun  *  without SWFW lock
567*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
568*4882a593Smuzhiyun  *  @reg_addr: 32 bit PHY register to write
569*4882a593Smuzhiyun  *  @device_type: 5 bit device type
570*4882a593Smuzhiyun  *  @phy_data: Data to write to the PHY register
571*4882a593Smuzhiyun  **/
ixgbe_write_phy_reg_mdi(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 phy_data)572*4882a593Smuzhiyun s32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr,
573*4882a593Smuzhiyun 				u32 device_type, u16 phy_data)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun 	u32 i, command;
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	/* Put the data in the MDI single read and write data register*/
578*4882a593Smuzhiyun 	IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data);
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	/* Setup and write the address cycle command */
581*4882a593Smuzhiyun 	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
582*4882a593Smuzhiyun 		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
583*4882a593Smuzhiyun 		   (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
584*4882a593Smuzhiyun 		   (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun 	/*
589*4882a593Smuzhiyun 	 * Check every 10 usec to see if the address cycle completed.
590*4882a593Smuzhiyun 	 * The MDI Command bit will clear when the operation is
591*4882a593Smuzhiyun 	 * complete
592*4882a593Smuzhiyun 	 */
593*4882a593Smuzhiyun 	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
594*4882a593Smuzhiyun 		udelay(10);
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
597*4882a593Smuzhiyun 		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
598*4882a593Smuzhiyun 			break;
599*4882a593Smuzhiyun 	}
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
602*4882a593Smuzhiyun 		hw_dbg(hw, "PHY address cmd didn't complete\n");
603*4882a593Smuzhiyun 		return IXGBE_ERR_PHY;
604*4882a593Smuzhiyun 	}
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	/*
607*4882a593Smuzhiyun 	 * Address cycle complete, setup and write the write
608*4882a593Smuzhiyun 	 * command
609*4882a593Smuzhiyun 	 */
610*4882a593Smuzhiyun 	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
611*4882a593Smuzhiyun 		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
612*4882a593Smuzhiyun 		   (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
613*4882a593Smuzhiyun 		   (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun 	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 	/* Check every 10 usec to see if the address cycle
618*4882a593Smuzhiyun 	 * completed. The MDI Command bit will clear when the
619*4882a593Smuzhiyun 	 * operation is complete
620*4882a593Smuzhiyun 	 */
621*4882a593Smuzhiyun 	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
622*4882a593Smuzhiyun 		udelay(10);
623*4882a593Smuzhiyun 
624*4882a593Smuzhiyun 		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
625*4882a593Smuzhiyun 		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
626*4882a593Smuzhiyun 			break;
627*4882a593Smuzhiyun 	}
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
630*4882a593Smuzhiyun 		hw_dbg(hw, "PHY write cmd didn't complete\n");
631*4882a593Smuzhiyun 		return IXGBE_ERR_PHY;
632*4882a593Smuzhiyun 	}
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	return 0;
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun /**
638*4882a593Smuzhiyun  *  ixgbe_write_phy_reg_generic - Writes a value to specified PHY register
639*4882a593Smuzhiyun  *  using SWFW lock- this function is needed in most cases
640*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
641*4882a593Smuzhiyun  *  @reg_addr: 32 bit PHY register to write
642*4882a593Smuzhiyun  *  @device_type: 5 bit device type
643*4882a593Smuzhiyun  *  @phy_data: Data to write to the PHY register
644*4882a593Smuzhiyun  **/
ixgbe_write_phy_reg_generic(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 phy_data)645*4882a593Smuzhiyun s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
646*4882a593Smuzhiyun 				u32 device_type, u16 phy_data)
647*4882a593Smuzhiyun {
648*4882a593Smuzhiyun 	s32 status;
649*4882a593Smuzhiyun 	u32 gssr = hw->phy.phy_semaphore_mask;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == 0) {
652*4882a593Smuzhiyun 		status = ixgbe_write_phy_reg_mdi(hw, reg_addr, device_type,
653*4882a593Smuzhiyun 						 phy_data);
654*4882a593Smuzhiyun 		hw->mac.ops.release_swfw_sync(hw, gssr);
655*4882a593Smuzhiyun 	} else {
656*4882a593Smuzhiyun 		return IXGBE_ERR_SWFW_SYNC;
657*4882a593Smuzhiyun 	}
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun 	return status;
660*4882a593Smuzhiyun }
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun #define IXGBE_HW_READ_REG(addr) IXGBE_READ_REG(hw, addr)
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun /**
665*4882a593Smuzhiyun  *  ixgbe_msca_cmd - Write the command register and poll for completion/timeout
666*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
667*4882a593Smuzhiyun  *  @cmd: command register value to write
668*4882a593Smuzhiyun  **/
ixgbe_msca_cmd(struct ixgbe_hw * hw,u32 cmd)669*4882a593Smuzhiyun static s32 ixgbe_msca_cmd(struct ixgbe_hw *hw, u32 cmd)
670*4882a593Smuzhiyun {
671*4882a593Smuzhiyun 	IXGBE_WRITE_REG(hw, IXGBE_MSCA, cmd);
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun 	return readx_poll_timeout(IXGBE_HW_READ_REG, IXGBE_MSCA, cmd,
674*4882a593Smuzhiyun 				  !(cmd & IXGBE_MSCA_MDI_COMMAND), 10,
675*4882a593Smuzhiyun 				  10 * IXGBE_MDIO_COMMAND_TIMEOUT);
676*4882a593Smuzhiyun }
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun /**
679*4882a593Smuzhiyun  *  ixgbe_mii_bus_read_generic - Read a clause 22/45 register with gssr flags
680*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
681*4882a593Smuzhiyun  *  @addr: address
682*4882a593Smuzhiyun  *  @regnum: register number
683*4882a593Smuzhiyun  *  @gssr: semaphore flags to acquire
684*4882a593Smuzhiyun  **/
ixgbe_mii_bus_read_generic(struct ixgbe_hw * hw,int addr,int regnum,u32 gssr)685*4882a593Smuzhiyun static s32 ixgbe_mii_bus_read_generic(struct ixgbe_hw *hw, int addr,
686*4882a593Smuzhiyun 				      int regnum, u32 gssr)
687*4882a593Smuzhiyun {
688*4882a593Smuzhiyun 	u32 hwaddr, cmd;
689*4882a593Smuzhiyun 	s32 data;
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun 	if (hw->mac.ops.acquire_swfw_sync(hw, gssr))
692*4882a593Smuzhiyun 		return -EBUSY;
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 	hwaddr = addr << IXGBE_MSCA_PHY_ADDR_SHIFT;
695*4882a593Smuzhiyun 	if (regnum & MII_ADDR_C45) {
696*4882a593Smuzhiyun 		hwaddr |= regnum & GENMASK(21, 0);
697*4882a593Smuzhiyun 		cmd = hwaddr | IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND;
698*4882a593Smuzhiyun 	} else {
699*4882a593Smuzhiyun 		hwaddr |= (regnum & GENMASK(5, 0)) << IXGBE_MSCA_DEV_TYPE_SHIFT;
700*4882a593Smuzhiyun 		cmd = hwaddr | IXGBE_MSCA_OLD_PROTOCOL |
701*4882a593Smuzhiyun 			IXGBE_MSCA_READ_AUTOINC | IXGBE_MSCA_MDI_COMMAND;
702*4882a593Smuzhiyun 	}
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 	data = ixgbe_msca_cmd(hw, cmd);
705*4882a593Smuzhiyun 	if (data < 0)
706*4882a593Smuzhiyun 		goto mii_bus_read_done;
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun 	/* For a clause 45 access the address cycle just completed, we still
709*4882a593Smuzhiyun 	 * need to do the read command, otherwise just get the data
710*4882a593Smuzhiyun 	 */
711*4882a593Smuzhiyun 	if (!(regnum & MII_ADDR_C45))
712*4882a593Smuzhiyun 		goto do_mii_bus_read;
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	cmd = hwaddr | IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND;
715*4882a593Smuzhiyun 	data = ixgbe_msca_cmd(hw, cmd);
716*4882a593Smuzhiyun 	if (data < 0)
717*4882a593Smuzhiyun 		goto mii_bus_read_done;
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun do_mii_bus_read:
720*4882a593Smuzhiyun 	data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
721*4882a593Smuzhiyun 	data = (data >> IXGBE_MSRWD_READ_DATA_SHIFT) & GENMASK(16, 0);
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun mii_bus_read_done:
724*4882a593Smuzhiyun 	hw->mac.ops.release_swfw_sync(hw, gssr);
725*4882a593Smuzhiyun 	return data;
726*4882a593Smuzhiyun }
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun /**
729*4882a593Smuzhiyun  *  ixgbe_mii_bus_write_generic - Write a clause 22/45 register with gssr flags
730*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
731*4882a593Smuzhiyun  *  @addr: address
732*4882a593Smuzhiyun  *  @regnum: register number
733*4882a593Smuzhiyun  *  @val: value to write
734*4882a593Smuzhiyun  *  @gssr: semaphore flags to acquire
735*4882a593Smuzhiyun  **/
ixgbe_mii_bus_write_generic(struct ixgbe_hw * hw,int addr,int regnum,u16 val,u32 gssr)736*4882a593Smuzhiyun static s32 ixgbe_mii_bus_write_generic(struct ixgbe_hw *hw, int addr,
737*4882a593Smuzhiyun 				       int regnum, u16 val, u32 gssr)
738*4882a593Smuzhiyun {
739*4882a593Smuzhiyun 	u32 hwaddr, cmd;
740*4882a593Smuzhiyun 	s32 err;
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 	if (hw->mac.ops.acquire_swfw_sync(hw, gssr))
743*4882a593Smuzhiyun 		return -EBUSY;
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)val);
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 	hwaddr = addr << IXGBE_MSCA_PHY_ADDR_SHIFT;
748*4882a593Smuzhiyun 	if (regnum & MII_ADDR_C45) {
749*4882a593Smuzhiyun 		hwaddr |= regnum & GENMASK(21, 0);
750*4882a593Smuzhiyun 		cmd = hwaddr | IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND;
751*4882a593Smuzhiyun 	} else {
752*4882a593Smuzhiyun 		hwaddr |= (regnum & GENMASK(5, 0)) << IXGBE_MSCA_DEV_TYPE_SHIFT;
753*4882a593Smuzhiyun 		cmd = hwaddr | IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_WRITE |
754*4882a593Smuzhiyun 			IXGBE_MSCA_MDI_COMMAND;
755*4882a593Smuzhiyun 	}
756*4882a593Smuzhiyun 
757*4882a593Smuzhiyun 	/* For clause 45 this is an address cycle, for clause 22 this is the
758*4882a593Smuzhiyun 	 * entire transaction
759*4882a593Smuzhiyun 	 */
760*4882a593Smuzhiyun 	err = ixgbe_msca_cmd(hw, cmd);
761*4882a593Smuzhiyun 	if (err < 0 || !(regnum & MII_ADDR_C45))
762*4882a593Smuzhiyun 		goto mii_bus_write_done;
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun 	cmd = hwaddr | IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND;
765*4882a593Smuzhiyun 	err = ixgbe_msca_cmd(hw, cmd);
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun mii_bus_write_done:
768*4882a593Smuzhiyun 	hw->mac.ops.release_swfw_sync(hw, gssr);
769*4882a593Smuzhiyun 	return err;
770*4882a593Smuzhiyun }
771*4882a593Smuzhiyun 
772*4882a593Smuzhiyun /**
773*4882a593Smuzhiyun  *  ixgbe_mii_bus_read - Read a clause 22/45 register
774*4882a593Smuzhiyun  *  @bus: pointer to mii_bus structure which points to our driver private
775*4882a593Smuzhiyun  *  @addr: address
776*4882a593Smuzhiyun  *  @regnum: register number
777*4882a593Smuzhiyun  **/
ixgbe_mii_bus_read(struct mii_bus * bus,int addr,int regnum)778*4882a593Smuzhiyun static s32 ixgbe_mii_bus_read(struct mii_bus *bus, int addr, int regnum)
779*4882a593Smuzhiyun {
780*4882a593Smuzhiyun 	struct ixgbe_adapter *adapter = bus->priv;
781*4882a593Smuzhiyun 	struct ixgbe_hw *hw = &adapter->hw;
782*4882a593Smuzhiyun 	u32 gssr = hw->phy.phy_semaphore_mask;
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun 	return ixgbe_mii_bus_read_generic(hw, addr, regnum, gssr);
785*4882a593Smuzhiyun }
786*4882a593Smuzhiyun 
787*4882a593Smuzhiyun /**
788*4882a593Smuzhiyun  *  ixgbe_mii_bus_write - Write a clause 22/45 register
789*4882a593Smuzhiyun  *  @bus: pointer to mii_bus structure which points to our driver private
790*4882a593Smuzhiyun  *  @addr: address
791*4882a593Smuzhiyun  *  @regnum: register number
792*4882a593Smuzhiyun  *  @val: value to write
793*4882a593Smuzhiyun  **/
ixgbe_mii_bus_write(struct mii_bus * bus,int addr,int regnum,u16 val)794*4882a593Smuzhiyun static s32 ixgbe_mii_bus_write(struct mii_bus *bus, int addr, int regnum,
795*4882a593Smuzhiyun 			       u16 val)
796*4882a593Smuzhiyun {
797*4882a593Smuzhiyun 	struct ixgbe_adapter *adapter = bus->priv;
798*4882a593Smuzhiyun 	struct ixgbe_hw *hw = &adapter->hw;
799*4882a593Smuzhiyun 	u32 gssr = hw->phy.phy_semaphore_mask;
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun 	return ixgbe_mii_bus_write_generic(hw, addr, regnum, val, gssr);
802*4882a593Smuzhiyun }
803*4882a593Smuzhiyun 
804*4882a593Smuzhiyun /**
805*4882a593Smuzhiyun  *  ixgbe_x550em_a_mii_bus_read - Read a clause 22/45 register on x550em_a
806*4882a593Smuzhiyun  *  @bus: pointer to mii_bus structure which points to our driver private
807*4882a593Smuzhiyun  *  @addr: address
808*4882a593Smuzhiyun  *  @regnum: register number
809*4882a593Smuzhiyun  **/
ixgbe_x550em_a_mii_bus_read(struct mii_bus * bus,int addr,int regnum)810*4882a593Smuzhiyun static s32 ixgbe_x550em_a_mii_bus_read(struct mii_bus *bus, int addr,
811*4882a593Smuzhiyun 				       int regnum)
812*4882a593Smuzhiyun {
813*4882a593Smuzhiyun 	struct ixgbe_adapter *adapter = bus->priv;
814*4882a593Smuzhiyun 	struct ixgbe_hw *hw = &adapter->hw;
815*4882a593Smuzhiyun 	u32 gssr = hw->phy.phy_semaphore_mask;
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun 	gssr |= IXGBE_GSSR_TOKEN_SM | IXGBE_GSSR_PHY0_SM;
818*4882a593Smuzhiyun 	return ixgbe_mii_bus_read_generic(hw, addr, regnum, gssr);
819*4882a593Smuzhiyun }
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun /**
822*4882a593Smuzhiyun  *  ixgbe_x550em_a_mii_bus_write - Write a clause 22/45 register on x550em_a
823*4882a593Smuzhiyun  *  @bus: pointer to mii_bus structure which points to our driver private
824*4882a593Smuzhiyun  *  @addr: address
825*4882a593Smuzhiyun  *  @regnum: register number
826*4882a593Smuzhiyun  *  @val: value to write
827*4882a593Smuzhiyun  **/
ixgbe_x550em_a_mii_bus_write(struct mii_bus * bus,int addr,int regnum,u16 val)828*4882a593Smuzhiyun static s32 ixgbe_x550em_a_mii_bus_write(struct mii_bus *bus, int addr,
829*4882a593Smuzhiyun 					int regnum, u16 val)
830*4882a593Smuzhiyun {
831*4882a593Smuzhiyun 	struct ixgbe_adapter *adapter = bus->priv;
832*4882a593Smuzhiyun 	struct ixgbe_hw *hw = &adapter->hw;
833*4882a593Smuzhiyun 	u32 gssr = hw->phy.phy_semaphore_mask;
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun 	gssr |= IXGBE_GSSR_TOKEN_SM | IXGBE_GSSR_PHY0_SM;
836*4882a593Smuzhiyun 	return ixgbe_mii_bus_write_generic(hw, addr, regnum, val, gssr);
837*4882a593Smuzhiyun }
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun /**
840*4882a593Smuzhiyun  * ixgbe_get_first_secondary_devfn - get first device downstream of root port
841*4882a593Smuzhiyun  * @devfn: PCI_DEVFN of root port on domain 0, bus 0
842*4882a593Smuzhiyun  *
843*4882a593Smuzhiyun  * Returns pci_dev pointer to PCI_DEVFN(0, 0) on subordinate side of root
844*4882a593Smuzhiyun  * on domain 0, bus 0, devfn = 'devfn'
845*4882a593Smuzhiyun  **/
ixgbe_get_first_secondary_devfn(unsigned int devfn)846*4882a593Smuzhiyun static struct pci_dev *ixgbe_get_first_secondary_devfn(unsigned int devfn)
847*4882a593Smuzhiyun {
848*4882a593Smuzhiyun 	struct pci_dev *rp_pdev;
849*4882a593Smuzhiyun 	int bus;
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun 	rp_pdev = pci_get_domain_bus_and_slot(0, 0, devfn);
852*4882a593Smuzhiyun 	if (rp_pdev && rp_pdev->subordinate) {
853*4882a593Smuzhiyun 		bus = rp_pdev->subordinate->number;
854*4882a593Smuzhiyun 		return pci_get_domain_bus_and_slot(0, bus, 0);
855*4882a593Smuzhiyun 	}
856*4882a593Smuzhiyun 
857*4882a593Smuzhiyun 	return NULL;
858*4882a593Smuzhiyun }
859*4882a593Smuzhiyun 
860*4882a593Smuzhiyun /**
861*4882a593Smuzhiyun  * ixgbe_x550em_a_has_mii - is this the first ixgbe x550em_a PCI function?
862*4882a593Smuzhiyun  * @hw: pointer to hardware structure
863*4882a593Smuzhiyun  *
864*4882a593Smuzhiyun  * Returns true if hw points to lowest numbered PCI B:D.F x550_em_a device in
865*4882a593Smuzhiyun  * the SoC.  There are up to 4 MACs sharing a single MDIO bus on the x550em_a,
866*4882a593Smuzhiyun  * but we only want to register one MDIO bus.
867*4882a593Smuzhiyun  **/
ixgbe_x550em_a_has_mii(struct ixgbe_hw * hw)868*4882a593Smuzhiyun static bool ixgbe_x550em_a_has_mii(struct ixgbe_hw *hw)
869*4882a593Smuzhiyun {
870*4882a593Smuzhiyun 	struct ixgbe_adapter *adapter = hw->back;
871*4882a593Smuzhiyun 	struct pci_dev *pdev = adapter->pdev;
872*4882a593Smuzhiyun 	struct pci_dev *func0_pdev;
873*4882a593Smuzhiyun 
874*4882a593Smuzhiyun 	/* For the C3000 family of SoCs (x550em_a) the internal ixgbe devices
875*4882a593Smuzhiyun 	 * are always downstream of root ports @ 0000:00:16.0 & 0000:00:17.0
876*4882a593Smuzhiyun 	 * It's not valid for function 0 to be disabled and function 1 is up,
877*4882a593Smuzhiyun 	 * so the lowest numbered ixgbe dev will be device 0 function 0 on one
878*4882a593Smuzhiyun 	 * of those two root ports
879*4882a593Smuzhiyun 	 */
880*4882a593Smuzhiyun 	func0_pdev = ixgbe_get_first_secondary_devfn(PCI_DEVFN(0x16, 0));
881*4882a593Smuzhiyun 	if (func0_pdev) {
882*4882a593Smuzhiyun 		if (func0_pdev == pdev)
883*4882a593Smuzhiyun 			return true;
884*4882a593Smuzhiyun 		else
885*4882a593Smuzhiyun 			return false;
886*4882a593Smuzhiyun 	}
887*4882a593Smuzhiyun 	func0_pdev = ixgbe_get_first_secondary_devfn(PCI_DEVFN(0x17, 0));
888*4882a593Smuzhiyun 	if (func0_pdev == pdev)
889*4882a593Smuzhiyun 		return true;
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun 	return false;
892*4882a593Smuzhiyun }
893*4882a593Smuzhiyun 
894*4882a593Smuzhiyun /**
895*4882a593Smuzhiyun  * ixgbe_mii_bus_init - mii_bus structure setup
896*4882a593Smuzhiyun  * @hw: pointer to hardware structure
897*4882a593Smuzhiyun  *
898*4882a593Smuzhiyun  * Returns 0 on success, negative on failure
899*4882a593Smuzhiyun  *
900*4882a593Smuzhiyun  * ixgbe_mii_bus_init initializes a mii_bus structure in adapter
901*4882a593Smuzhiyun  **/
ixgbe_mii_bus_init(struct ixgbe_hw * hw)902*4882a593Smuzhiyun s32 ixgbe_mii_bus_init(struct ixgbe_hw *hw)
903*4882a593Smuzhiyun {
904*4882a593Smuzhiyun 	s32 (*write)(struct mii_bus *bus, int addr, int regnum, u16 val);
905*4882a593Smuzhiyun 	s32 (*read)(struct mii_bus *bus, int addr, int regnum);
906*4882a593Smuzhiyun 	struct ixgbe_adapter *adapter = hw->back;
907*4882a593Smuzhiyun 	struct pci_dev *pdev = adapter->pdev;
908*4882a593Smuzhiyun 	struct device *dev = &adapter->netdev->dev;
909*4882a593Smuzhiyun 	struct mii_bus *bus;
910*4882a593Smuzhiyun 
911*4882a593Smuzhiyun 	switch (hw->device_id) {
912*4882a593Smuzhiyun 	/* C3000 SoCs */
913*4882a593Smuzhiyun 	case IXGBE_DEV_ID_X550EM_A_KR:
914*4882a593Smuzhiyun 	case IXGBE_DEV_ID_X550EM_A_KR_L:
915*4882a593Smuzhiyun 	case IXGBE_DEV_ID_X550EM_A_SFP_N:
916*4882a593Smuzhiyun 	case IXGBE_DEV_ID_X550EM_A_SGMII:
917*4882a593Smuzhiyun 	case IXGBE_DEV_ID_X550EM_A_SGMII_L:
918*4882a593Smuzhiyun 	case IXGBE_DEV_ID_X550EM_A_10G_T:
919*4882a593Smuzhiyun 	case IXGBE_DEV_ID_X550EM_A_SFP:
920*4882a593Smuzhiyun 	case IXGBE_DEV_ID_X550EM_A_1G_T:
921*4882a593Smuzhiyun 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
922*4882a593Smuzhiyun 		if (!ixgbe_x550em_a_has_mii(hw))
923*4882a593Smuzhiyun 			return 0;
924*4882a593Smuzhiyun 		read = &ixgbe_x550em_a_mii_bus_read;
925*4882a593Smuzhiyun 		write = &ixgbe_x550em_a_mii_bus_write;
926*4882a593Smuzhiyun 		break;
927*4882a593Smuzhiyun 	default:
928*4882a593Smuzhiyun 		read = &ixgbe_mii_bus_read;
929*4882a593Smuzhiyun 		write = &ixgbe_mii_bus_write;
930*4882a593Smuzhiyun 		break;
931*4882a593Smuzhiyun 	}
932*4882a593Smuzhiyun 
933*4882a593Smuzhiyun 	bus = devm_mdiobus_alloc(dev);
934*4882a593Smuzhiyun 	if (!bus)
935*4882a593Smuzhiyun 		return -ENOMEM;
936*4882a593Smuzhiyun 
937*4882a593Smuzhiyun 	bus->read = read;
938*4882a593Smuzhiyun 	bus->write = write;
939*4882a593Smuzhiyun 
940*4882a593Smuzhiyun 	/* Use the position of the device in the PCI hierarchy as the id */
941*4882a593Smuzhiyun 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mdio-%s", ixgbe_driver_name,
942*4882a593Smuzhiyun 		 pci_name(pdev));
943*4882a593Smuzhiyun 
944*4882a593Smuzhiyun 	bus->name = "ixgbe-mdio";
945*4882a593Smuzhiyun 	bus->priv = adapter;
946*4882a593Smuzhiyun 	bus->parent = dev;
947*4882a593Smuzhiyun 	bus->phy_mask = GENMASK(31, 0);
948*4882a593Smuzhiyun 
949*4882a593Smuzhiyun 	/* Support clause 22/45 natively.  ixgbe_probe() sets MDIO_EMULATE_C22
950*4882a593Smuzhiyun 	 * unfortunately that causes some clause 22 frames to be sent with
951*4882a593Smuzhiyun 	 * clause 45 addressing.  We don't want that.
952*4882a593Smuzhiyun 	 */
953*4882a593Smuzhiyun 	hw->phy.mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22;
954*4882a593Smuzhiyun 
955*4882a593Smuzhiyun 	adapter->mii_bus = bus;
956*4882a593Smuzhiyun 	return mdiobus_register(bus);
957*4882a593Smuzhiyun }
958*4882a593Smuzhiyun 
959*4882a593Smuzhiyun /**
960*4882a593Smuzhiyun  *  ixgbe_setup_phy_link_generic - Set and restart autoneg
961*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
962*4882a593Smuzhiyun  *
963*4882a593Smuzhiyun  *  Restart autonegotiation and PHY and waits for completion.
964*4882a593Smuzhiyun  **/
ixgbe_setup_phy_link_generic(struct ixgbe_hw * hw)965*4882a593Smuzhiyun s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
966*4882a593Smuzhiyun {
967*4882a593Smuzhiyun 	s32 status = 0;
968*4882a593Smuzhiyun 	u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
969*4882a593Smuzhiyun 	bool autoneg = false;
970*4882a593Smuzhiyun 	ixgbe_link_speed speed;
971*4882a593Smuzhiyun 
972*4882a593Smuzhiyun 	ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
973*4882a593Smuzhiyun 
974*4882a593Smuzhiyun 	/* Set or unset auto-negotiation 10G advertisement */
975*4882a593Smuzhiyun 	hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL, MDIO_MMD_AN, &autoneg_reg);
976*4882a593Smuzhiyun 
977*4882a593Smuzhiyun 	autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G;
978*4882a593Smuzhiyun 	if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) &&
979*4882a593Smuzhiyun 	    (speed & IXGBE_LINK_SPEED_10GB_FULL))
980*4882a593Smuzhiyun 		autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
981*4882a593Smuzhiyun 
982*4882a593Smuzhiyun 	hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL, MDIO_MMD_AN, autoneg_reg);
983*4882a593Smuzhiyun 
984*4882a593Smuzhiyun 	hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
985*4882a593Smuzhiyun 			     MDIO_MMD_AN, &autoneg_reg);
986*4882a593Smuzhiyun 
987*4882a593Smuzhiyun 	if (hw->mac.type == ixgbe_mac_X550) {
988*4882a593Smuzhiyun 		/* Set or unset auto-negotiation 5G advertisement */
989*4882a593Smuzhiyun 		autoneg_reg &= ~IXGBE_MII_5GBASE_T_ADVERTISE;
990*4882a593Smuzhiyun 		if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL) &&
991*4882a593Smuzhiyun 		    (speed & IXGBE_LINK_SPEED_5GB_FULL))
992*4882a593Smuzhiyun 			autoneg_reg |= IXGBE_MII_5GBASE_T_ADVERTISE;
993*4882a593Smuzhiyun 
994*4882a593Smuzhiyun 		/* Set or unset auto-negotiation 2.5G advertisement */
995*4882a593Smuzhiyun 		autoneg_reg &= ~IXGBE_MII_2_5GBASE_T_ADVERTISE;
996*4882a593Smuzhiyun 		if ((hw->phy.autoneg_advertised &
997*4882a593Smuzhiyun 		     IXGBE_LINK_SPEED_2_5GB_FULL) &&
998*4882a593Smuzhiyun 		    (speed & IXGBE_LINK_SPEED_2_5GB_FULL))
999*4882a593Smuzhiyun 			autoneg_reg |= IXGBE_MII_2_5GBASE_T_ADVERTISE;
1000*4882a593Smuzhiyun 	}
1001*4882a593Smuzhiyun 
1002*4882a593Smuzhiyun 	/* Set or unset auto-negotiation 1G advertisement */
1003*4882a593Smuzhiyun 	autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE;
1004*4882a593Smuzhiyun 	if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) &&
1005*4882a593Smuzhiyun 	    (speed & IXGBE_LINK_SPEED_1GB_FULL))
1006*4882a593Smuzhiyun 		autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE;
1007*4882a593Smuzhiyun 
1008*4882a593Smuzhiyun 	hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
1009*4882a593Smuzhiyun 			      MDIO_MMD_AN, autoneg_reg);
1010*4882a593Smuzhiyun 
1011*4882a593Smuzhiyun 	/* Set or unset auto-negotiation 100M advertisement */
1012*4882a593Smuzhiyun 	hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, &autoneg_reg);
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun 	autoneg_reg &= ~(ADVERTISE_100FULL | ADVERTISE_100HALF);
1015*4882a593Smuzhiyun 	if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) &&
1016*4882a593Smuzhiyun 	    (speed & IXGBE_LINK_SPEED_100_FULL))
1017*4882a593Smuzhiyun 		autoneg_reg |= ADVERTISE_100FULL;
1018*4882a593Smuzhiyun 
1019*4882a593Smuzhiyun 	hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, autoneg_reg);
1020*4882a593Smuzhiyun 
1021*4882a593Smuzhiyun 	/* Blocked by MNG FW so don't reset PHY */
1022*4882a593Smuzhiyun 	if (ixgbe_check_reset_blocked(hw))
1023*4882a593Smuzhiyun 		return 0;
1024*4882a593Smuzhiyun 
1025*4882a593Smuzhiyun 	/* Restart PHY autonegotiation and wait for completion */
1026*4882a593Smuzhiyun 	hw->phy.ops.read_reg(hw, MDIO_CTRL1,
1027*4882a593Smuzhiyun 			     MDIO_MMD_AN, &autoneg_reg);
1028*4882a593Smuzhiyun 
1029*4882a593Smuzhiyun 	autoneg_reg |= MDIO_AN_CTRL1_RESTART;
1030*4882a593Smuzhiyun 
1031*4882a593Smuzhiyun 	hw->phy.ops.write_reg(hw, MDIO_CTRL1,
1032*4882a593Smuzhiyun 			      MDIO_MMD_AN, autoneg_reg);
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun 	return status;
1035*4882a593Smuzhiyun }
1036*4882a593Smuzhiyun 
1037*4882a593Smuzhiyun /**
1038*4882a593Smuzhiyun  *  ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities
1039*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
1040*4882a593Smuzhiyun  *  @speed: new link speed
1041*4882a593Smuzhiyun  *  @autoneg_wait_to_complete: unused
1042*4882a593Smuzhiyun  **/
ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)1043*4882a593Smuzhiyun s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
1044*4882a593Smuzhiyun 				       ixgbe_link_speed speed,
1045*4882a593Smuzhiyun 				       bool autoneg_wait_to_complete)
1046*4882a593Smuzhiyun {
1047*4882a593Smuzhiyun 	/* Clear autoneg_advertised and set new values based on input link
1048*4882a593Smuzhiyun 	 * speed.
1049*4882a593Smuzhiyun 	 */
1050*4882a593Smuzhiyun 	hw->phy.autoneg_advertised = 0;
1051*4882a593Smuzhiyun 
1052*4882a593Smuzhiyun 	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
1053*4882a593Smuzhiyun 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
1054*4882a593Smuzhiyun 
1055*4882a593Smuzhiyun 	if (speed & IXGBE_LINK_SPEED_5GB_FULL)
1056*4882a593Smuzhiyun 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_5GB_FULL;
1057*4882a593Smuzhiyun 
1058*4882a593Smuzhiyun 	if (speed & IXGBE_LINK_SPEED_2_5GB_FULL)
1059*4882a593Smuzhiyun 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_2_5GB_FULL;
1060*4882a593Smuzhiyun 
1061*4882a593Smuzhiyun 	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
1062*4882a593Smuzhiyun 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
1063*4882a593Smuzhiyun 
1064*4882a593Smuzhiyun 	if (speed & IXGBE_LINK_SPEED_100_FULL)
1065*4882a593Smuzhiyun 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
1066*4882a593Smuzhiyun 
1067*4882a593Smuzhiyun 	if (speed & IXGBE_LINK_SPEED_10_FULL)
1068*4882a593Smuzhiyun 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10_FULL;
1069*4882a593Smuzhiyun 
1070*4882a593Smuzhiyun 	/* Setup link based on the new speed settings */
1071*4882a593Smuzhiyun 	if (hw->phy.ops.setup_link)
1072*4882a593Smuzhiyun 		hw->phy.ops.setup_link(hw);
1073*4882a593Smuzhiyun 
1074*4882a593Smuzhiyun 	return 0;
1075*4882a593Smuzhiyun }
1076*4882a593Smuzhiyun 
1077*4882a593Smuzhiyun /**
1078*4882a593Smuzhiyun  * ixgbe_get_copper_speeds_supported - Get copper link speed from phy
1079*4882a593Smuzhiyun  * @hw: pointer to hardware structure
1080*4882a593Smuzhiyun  *
1081*4882a593Smuzhiyun  * Determines the supported link capabilities by reading the PHY auto
1082*4882a593Smuzhiyun  * negotiation register.
1083*4882a593Smuzhiyun  */
ixgbe_get_copper_speeds_supported(struct ixgbe_hw * hw)1084*4882a593Smuzhiyun static s32 ixgbe_get_copper_speeds_supported(struct ixgbe_hw *hw)
1085*4882a593Smuzhiyun {
1086*4882a593Smuzhiyun 	u16 speed_ability;
1087*4882a593Smuzhiyun 	s32 status;
1088*4882a593Smuzhiyun 
1089*4882a593Smuzhiyun 	status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD,
1090*4882a593Smuzhiyun 				      &speed_ability);
1091*4882a593Smuzhiyun 	if (status)
1092*4882a593Smuzhiyun 		return status;
1093*4882a593Smuzhiyun 
1094*4882a593Smuzhiyun 	if (speed_ability & MDIO_SPEED_10G)
1095*4882a593Smuzhiyun 		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10GB_FULL;
1096*4882a593Smuzhiyun 	if (speed_ability & MDIO_PMA_SPEED_1000)
1097*4882a593Smuzhiyun 		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_1GB_FULL;
1098*4882a593Smuzhiyun 	if (speed_ability & MDIO_PMA_SPEED_100)
1099*4882a593Smuzhiyun 		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_100_FULL;
1100*4882a593Smuzhiyun 
1101*4882a593Smuzhiyun 	switch (hw->mac.type) {
1102*4882a593Smuzhiyun 	case ixgbe_mac_X550:
1103*4882a593Smuzhiyun 		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL;
1104*4882a593Smuzhiyun 		hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL;
1105*4882a593Smuzhiyun 		break;
1106*4882a593Smuzhiyun 	case ixgbe_mac_X550EM_x:
1107*4882a593Smuzhiyun 	case ixgbe_mac_x550em_a:
1108*4882a593Smuzhiyun 		hw->phy.speeds_supported &= ~IXGBE_LINK_SPEED_100_FULL;
1109*4882a593Smuzhiyun 		break;
1110*4882a593Smuzhiyun 	default:
1111*4882a593Smuzhiyun 		break;
1112*4882a593Smuzhiyun 	}
1113*4882a593Smuzhiyun 
1114*4882a593Smuzhiyun 	return 0;
1115*4882a593Smuzhiyun }
1116*4882a593Smuzhiyun 
1117*4882a593Smuzhiyun /**
1118*4882a593Smuzhiyun  * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities
1119*4882a593Smuzhiyun  * @hw: pointer to hardware structure
1120*4882a593Smuzhiyun  * @speed: pointer to link speed
1121*4882a593Smuzhiyun  * @autoneg: boolean auto-negotiation value
1122*4882a593Smuzhiyun  */
ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * autoneg)1123*4882a593Smuzhiyun s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
1124*4882a593Smuzhiyun 					       ixgbe_link_speed *speed,
1125*4882a593Smuzhiyun 					       bool *autoneg)
1126*4882a593Smuzhiyun {
1127*4882a593Smuzhiyun 	s32 status = 0;
1128*4882a593Smuzhiyun 
1129*4882a593Smuzhiyun 	*autoneg = true;
1130*4882a593Smuzhiyun 	if (!hw->phy.speeds_supported)
1131*4882a593Smuzhiyun 		status = ixgbe_get_copper_speeds_supported(hw);
1132*4882a593Smuzhiyun 
1133*4882a593Smuzhiyun 	*speed = hw->phy.speeds_supported;
1134*4882a593Smuzhiyun 	return status;
1135*4882a593Smuzhiyun }
1136*4882a593Smuzhiyun 
1137*4882a593Smuzhiyun /**
1138*4882a593Smuzhiyun  *  ixgbe_check_phy_link_tnx - Determine link and speed status
1139*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
1140*4882a593Smuzhiyun  *  @speed: link speed
1141*4882a593Smuzhiyun  *  @link_up: status of link
1142*4882a593Smuzhiyun  *
1143*4882a593Smuzhiyun  *  Reads the VS1 register to determine if link is up and the current speed for
1144*4882a593Smuzhiyun  *  the PHY.
1145*4882a593Smuzhiyun  **/
ixgbe_check_phy_link_tnx(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * link_up)1146*4882a593Smuzhiyun s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
1147*4882a593Smuzhiyun 			     bool *link_up)
1148*4882a593Smuzhiyun {
1149*4882a593Smuzhiyun 	s32 status;
1150*4882a593Smuzhiyun 	u32 time_out;
1151*4882a593Smuzhiyun 	u32 max_time_out = 10;
1152*4882a593Smuzhiyun 	u16 phy_link = 0;
1153*4882a593Smuzhiyun 	u16 phy_speed = 0;
1154*4882a593Smuzhiyun 	u16 phy_data = 0;
1155*4882a593Smuzhiyun 
1156*4882a593Smuzhiyun 	/* Initialize speed and link to default case */
1157*4882a593Smuzhiyun 	*link_up = false;
1158*4882a593Smuzhiyun 	*speed = IXGBE_LINK_SPEED_10GB_FULL;
1159*4882a593Smuzhiyun 
1160*4882a593Smuzhiyun 	/*
1161*4882a593Smuzhiyun 	 * Check current speed and link status of the PHY register.
1162*4882a593Smuzhiyun 	 * This is a vendor specific register and may have to
1163*4882a593Smuzhiyun 	 * be changed for other copper PHYs.
1164*4882a593Smuzhiyun 	 */
1165*4882a593Smuzhiyun 	for (time_out = 0; time_out < max_time_out; time_out++) {
1166*4882a593Smuzhiyun 		udelay(10);
1167*4882a593Smuzhiyun 		status = hw->phy.ops.read_reg(hw,
1168*4882a593Smuzhiyun 					      MDIO_STAT1,
1169*4882a593Smuzhiyun 					      MDIO_MMD_VEND1,
1170*4882a593Smuzhiyun 					      &phy_data);
1171*4882a593Smuzhiyun 		phy_link = phy_data &
1172*4882a593Smuzhiyun 			    IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
1173*4882a593Smuzhiyun 		phy_speed = phy_data &
1174*4882a593Smuzhiyun 			    IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
1175*4882a593Smuzhiyun 		if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
1176*4882a593Smuzhiyun 			*link_up = true;
1177*4882a593Smuzhiyun 			if (phy_speed ==
1178*4882a593Smuzhiyun 			    IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
1179*4882a593Smuzhiyun 				*speed = IXGBE_LINK_SPEED_1GB_FULL;
1180*4882a593Smuzhiyun 			break;
1181*4882a593Smuzhiyun 		}
1182*4882a593Smuzhiyun 	}
1183*4882a593Smuzhiyun 
1184*4882a593Smuzhiyun 	return status;
1185*4882a593Smuzhiyun }
1186*4882a593Smuzhiyun 
1187*4882a593Smuzhiyun /**
1188*4882a593Smuzhiyun  *	ixgbe_setup_phy_link_tnx - Set and restart autoneg
1189*4882a593Smuzhiyun  *	@hw: pointer to hardware structure
1190*4882a593Smuzhiyun  *
1191*4882a593Smuzhiyun  *	Restart autonegotiation and PHY and waits for completion.
1192*4882a593Smuzhiyun  *      This function always returns success, this is nessary since
1193*4882a593Smuzhiyun  *	it is called via a function pointer that could call other
1194*4882a593Smuzhiyun  *	functions that could return an error.
1195*4882a593Smuzhiyun  **/
ixgbe_setup_phy_link_tnx(struct ixgbe_hw * hw)1196*4882a593Smuzhiyun s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
1197*4882a593Smuzhiyun {
1198*4882a593Smuzhiyun 	u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
1199*4882a593Smuzhiyun 	bool autoneg = false;
1200*4882a593Smuzhiyun 	ixgbe_link_speed speed;
1201*4882a593Smuzhiyun 
1202*4882a593Smuzhiyun 	ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
1203*4882a593Smuzhiyun 
1204*4882a593Smuzhiyun 	if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
1205*4882a593Smuzhiyun 		/* Set or unset auto-negotiation 10G advertisement */
1206*4882a593Smuzhiyun 		hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL,
1207*4882a593Smuzhiyun 				     MDIO_MMD_AN,
1208*4882a593Smuzhiyun 				     &autoneg_reg);
1209*4882a593Smuzhiyun 
1210*4882a593Smuzhiyun 		autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G;
1211*4882a593Smuzhiyun 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
1212*4882a593Smuzhiyun 			autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
1213*4882a593Smuzhiyun 
1214*4882a593Smuzhiyun 		hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL,
1215*4882a593Smuzhiyun 				      MDIO_MMD_AN,
1216*4882a593Smuzhiyun 				      autoneg_reg);
1217*4882a593Smuzhiyun 	}
1218*4882a593Smuzhiyun 
1219*4882a593Smuzhiyun 	if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
1220*4882a593Smuzhiyun 		/* Set or unset auto-negotiation 1G advertisement */
1221*4882a593Smuzhiyun 		hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
1222*4882a593Smuzhiyun 				     MDIO_MMD_AN,
1223*4882a593Smuzhiyun 				     &autoneg_reg);
1224*4882a593Smuzhiyun 
1225*4882a593Smuzhiyun 		autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
1226*4882a593Smuzhiyun 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
1227*4882a593Smuzhiyun 			autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
1228*4882a593Smuzhiyun 
1229*4882a593Smuzhiyun 		hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
1230*4882a593Smuzhiyun 				      MDIO_MMD_AN,
1231*4882a593Smuzhiyun 				      autoneg_reg);
1232*4882a593Smuzhiyun 	}
1233*4882a593Smuzhiyun 
1234*4882a593Smuzhiyun 	if (speed & IXGBE_LINK_SPEED_100_FULL) {
1235*4882a593Smuzhiyun 		/* Set or unset auto-negotiation 100M advertisement */
1236*4882a593Smuzhiyun 		hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE,
1237*4882a593Smuzhiyun 				     MDIO_MMD_AN,
1238*4882a593Smuzhiyun 				     &autoneg_reg);
1239*4882a593Smuzhiyun 
1240*4882a593Smuzhiyun 		autoneg_reg &= ~(ADVERTISE_100FULL |
1241*4882a593Smuzhiyun 				 ADVERTISE_100HALF);
1242*4882a593Smuzhiyun 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
1243*4882a593Smuzhiyun 			autoneg_reg |= ADVERTISE_100FULL;
1244*4882a593Smuzhiyun 
1245*4882a593Smuzhiyun 		hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
1246*4882a593Smuzhiyun 				      MDIO_MMD_AN,
1247*4882a593Smuzhiyun 				      autoneg_reg);
1248*4882a593Smuzhiyun 	}
1249*4882a593Smuzhiyun 
1250*4882a593Smuzhiyun 	/* Blocked by MNG FW so don't reset PHY */
1251*4882a593Smuzhiyun 	if (ixgbe_check_reset_blocked(hw))
1252*4882a593Smuzhiyun 		return 0;
1253*4882a593Smuzhiyun 
1254*4882a593Smuzhiyun 	/* Restart PHY autonegotiation and wait for completion */
1255*4882a593Smuzhiyun 	hw->phy.ops.read_reg(hw, MDIO_CTRL1,
1256*4882a593Smuzhiyun 			     MDIO_MMD_AN, &autoneg_reg);
1257*4882a593Smuzhiyun 
1258*4882a593Smuzhiyun 	autoneg_reg |= MDIO_AN_CTRL1_RESTART;
1259*4882a593Smuzhiyun 
1260*4882a593Smuzhiyun 	hw->phy.ops.write_reg(hw, MDIO_CTRL1,
1261*4882a593Smuzhiyun 			      MDIO_MMD_AN, autoneg_reg);
1262*4882a593Smuzhiyun 	return 0;
1263*4882a593Smuzhiyun }
1264*4882a593Smuzhiyun 
1265*4882a593Smuzhiyun /**
1266*4882a593Smuzhiyun  *  ixgbe_reset_phy_nl - Performs a PHY reset
1267*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
1268*4882a593Smuzhiyun  **/
ixgbe_reset_phy_nl(struct ixgbe_hw * hw)1269*4882a593Smuzhiyun s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
1270*4882a593Smuzhiyun {
1271*4882a593Smuzhiyun 	u16 phy_offset, control, eword, edata, block_crc;
1272*4882a593Smuzhiyun 	bool end_data = false;
1273*4882a593Smuzhiyun 	u16 list_offset, data_offset;
1274*4882a593Smuzhiyun 	u16 phy_data = 0;
1275*4882a593Smuzhiyun 	s32 ret_val;
1276*4882a593Smuzhiyun 	u32 i;
1277*4882a593Smuzhiyun 
1278*4882a593Smuzhiyun 	/* Blocked by MNG FW so bail */
1279*4882a593Smuzhiyun 	if (ixgbe_check_reset_blocked(hw))
1280*4882a593Smuzhiyun 		return 0;
1281*4882a593Smuzhiyun 
1282*4882a593Smuzhiyun 	hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &phy_data);
1283*4882a593Smuzhiyun 
1284*4882a593Smuzhiyun 	/* reset the PHY and poll for completion */
1285*4882a593Smuzhiyun 	hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
1286*4882a593Smuzhiyun 			      (phy_data | MDIO_CTRL1_RESET));
1287*4882a593Smuzhiyun 
1288*4882a593Smuzhiyun 	for (i = 0; i < 100; i++) {
1289*4882a593Smuzhiyun 		hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
1290*4882a593Smuzhiyun 				     &phy_data);
1291*4882a593Smuzhiyun 		if ((phy_data & MDIO_CTRL1_RESET) == 0)
1292*4882a593Smuzhiyun 			break;
1293*4882a593Smuzhiyun 		usleep_range(10000, 20000);
1294*4882a593Smuzhiyun 	}
1295*4882a593Smuzhiyun 
1296*4882a593Smuzhiyun 	if ((phy_data & MDIO_CTRL1_RESET) != 0) {
1297*4882a593Smuzhiyun 		hw_dbg(hw, "PHY reset did not complete.\n");
1298*4882a593Smuzhiyun 		return IXGBE_ERR_PHY;
1299*4882a593Smuzhiyun 	}
1300*4882a593Smuzhiyun 
1301*4882a593Smuzhiyun 	/* Get init offsets */
1302*4882a593Smuzhiyun 	ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
1303*4882a593Smuzhiyun 						      &data_offset);
1304*4882a593Smuzhiyun 	if (ret_val)
1305*4882a593Smuzhiyun 		return ret_val;
1306*4882a593Smuzhiyun 
1307*4882a593Smuzhiyun 	ret_val = hw->eeprom.ops.read(hw, data_offset, &block_crc);
1308*4882a593Smuzhiyun 	data_offset++;
1309*4882a593Smuzhiyun 	while (!end_data) {
1310*4882a593Smuzhiyun 		/*
1311*4882a593Smuzhiyun 		 * Read control word from PHY init contents offset
1312*4882a593Smuzhiyun 		 */
1313*4882a593Smuzhiyun 		ret_val = hw->eeprom.ops.read(hw, data_offset, &eword);
1314*4882a593Smuzhiyun 		if (ret_val)
1315*4882a593Smuzhiyun 			goto err_eeprom;
1316*4882a593Smuzhiyun 		control = (eword & IXGBE_CONTROL_MASK_NL) >>
1317*4882a593Smuzhiyun 			   IXGBE_CONTROL_SHIFT_NL;
1318*4882a593Smuzhiyun 		edata = eword & IXGBE_DATA_MASK_NL;
1319*4882a593Smuzhiyun 		switch (control) {
1320*4882a593Smuzhiyun 		case IXGBE_DELAY_NL:
1321*4882a593Smuzhiyun 			data_offset++;
1322*4882a593Smuzhiyun 			hw_dbg(hw, "DELAY: %d MS\n", edata);
1323*4882a593Smuzhiyun 			usleep_range(edata * 1000, edata * 2000);
1324*4882a593Smuzhiyun 			break;
1325*4882a593Smuzhiyun 		case IXGBE_DATA_NL:
1326*4882a593Smuzhiyun 			hw_dbg(hw, "DATA:\n");
1327*4882a593Smuzhiyun 			data_offset++;
1328*4882a593Smuzhiyun 			ret_val = hw->eeprom.ops.read(hw, data_offset++,
1329*4882a593Smuzhiyun 						      &phy_offset);
1330*4882a593Smuzhiyun 			if (ret_val)
1331*4882a593Smuzhiyun 				goto err_eeprom;
1332*4882a593Smuzhiyun 			for (i = 0; i < edata; i++) {
1333*4882a593Smuzhiyun 				ret_val = hw->eeprom.ops.read(hw, data_offset,
1334*4882a593Smuzhiyun 							      &eword);
1335*4882a593Smuzhiyun 				if (ret_val)
1336*4882a593Smuzhiyun 					goto err_eeprom;
1337*4882a593Smuzhiyun 				hw->phy.ops.write_reg(hw, phy_offset,
1338*4882a593Smuzhiyun 						      MDIO_MMD_PMAPMD, eword);
1339*4882a593Smuzhiyun 				hw_dbg(hw, "Wrote %4.4x to %4.4x\n", eword,
1340*4882a593Smuzhiyun 				       phy_offset);
1341*4882a593Smuzhiyun 				data_offset++;
1342*4882a593Smuzhiyun 				phy_offset++;
1343*4882a593Smuzhiyun 			}
1344*4882a593Smuzhiyun 			break;
1345*4882a593Smuzhiyun 		case IXGBE_CONTROL_NL:
1346*4882a593Smuzhiyun 			data_offset++;
1347*4882a593Smuzhiyun 			hw_dbg(hw, "CONTROL:\n");
1348*4882a593Smuzhiyun 			if (edata == IXGBE_CONTROL_EOL_NL) {
1349*4882a593Smuzhiyun 				hw_dbg(hw, "EOL\n");
1350*4882a593Smuzhiyun 				end_data = true;
1351*4882a593Smuzhiyun 			} else if (edata == IXGBE_CONTROL_SOL_NL) {
1352*4882a593Smuzhiyun 				hw_dbg(hw, "SOL\n");
1353*4882a593Smuzhiyun 			} else {
1354*4882a593Smuzhiyun 				hw_dbg(hw, "Bad control value\n");
1355*4882a593Smuzhiyun 				return IXGBE_ERR_PHY;
1356*4882a593Smuzhiyun 			}
1357*4882a593Smuzhiyun 			break;
1358*4882a593Smuzhiyun 		default:
1359*4882a593Smuzhiyun 			hw_dbg(hw, "Bad control type\n");
1360*4882a593Smuzhiyun 			return IXGBE_ERR_PHY;
1361*4882a593Smuzhiyun 		}
1362*4882a593Smuzhiyun 	}
1363*4882a593Smuzhiyun 
1364*4882a593Smuzhiyun 	return ret_val;
1365*4882a593Smuzhiyun 
1366*4882a593Smuzhiyun err_eeprom:
1367*4882a593Smuzhiyun 	hw_err(hw, "eeprom read at offset %d failed\n", data_offset);
1368*4882a593Smuzhiyun 	return IXGBE_ERR_PHY;
1369*4882a593Smuzhiyun }
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun /**
1372*4882a593Smuzhiyun  *  ixgbe_identify_module_generic - Identifies module type
1373*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
1374*4882a593Smuzhiyun  *
1375*4882a593Smuzhiyun  *  Determines HW type and calls appropriate function.
1376*4882a593Smuzhiyun  **/
ixgbe_identify_module_generic(struct ixgbe_hw * hw)1377*4882a593Smuzhiyun s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw)
1378*4882a593Smuzhiyun {
1379*4882a593Smuzhiyun 	switch (hw->mac.ops.get_media_type(hw)) {
1380*4882a593Smuzhiyun 	case ixgbe_media_type_fiber:
1381*4882a593Smuzhiyun 		return ixgbe_identify_sfp_module_generic(hw);
1382*4882a593Smuzhiyun 	case ixgbe_media_type_fiber_qsfp:
1383*4882a593Smuzhiyun 		return ixgbe_identify_qsfp_module_generic(hw);
1384*4882a593Smuzhiyun 	default:
1385*4882a593Smuzhiyun 		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
1386*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NOT_PRESENT;
1387*4882a593Smuzhiyun 	}
1388*4882a593Smuzhiyun 
1389*4882a593Smuzhiyun 	return IXGBE_ERR_SFP_NOT_PRESENT;
1390*4882a593Smuzhiyun }
1391*4882a593Smuzhiyun 
1392*4882a593Smuzhiyun /**
1393*4882a593Smuzhiyun  *  ixgbe_identify_sfp_module_generic - Identifies SFP modules
1394*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
1395*4882a593Smuzhiyun  *
1396*4882a593Smuzhiyun  *  Searches for and identifies the SFP module and assigns appropriate PHY type.
1397*4882a593Smuzhiyun  **/
ixgbe_identify_sfp_module_generic(struct ixgbe_hw * hw)1398*4882a593Smuzhiyun s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
1399*4882a593Smuzhiyun {
1400*4882a593Smuzhiyun 	struct ixgbe_adapter *adapter = hw->back;
1401*4882a593Smuzhiyun 	s32 status;
1402*4882a593Smuzhiyun 	u32 vendor_oui = 0;
1403*4882a593Smuzhiyun 	enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
1404*4882a593Smuzhiyun 	u8 identifier = 0;
1405*4882a593Smuzhiyun 	u8 comp_codes_1g = 0;
1406*4882a593Smuzhiyun 	u8 comp_codes_10g = 0;
1407*4882a593Smuzhiyun 	u8 oui_bytes[3] = {0, 0, 0};
1408*4882a593Smuzhiyun 	u8 cable_tech = 0;
1409*4882a593Smuzhiyun 	u8 cable_spec = 0;
1410*4882a593Smuzhiyun 	u16 enforce_sfp = 0;
1411*4882a593Smuzhiyun 
1412*4882a593Smuzhiyun 	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) {
1413*4882a593Smuzhiyun 		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
1414*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NOT_PRESENT;
1415*4882a593Smuzhiyun 	}
1416*4882a593Smuzhiyun 
1417*4882a593Smuzhiyun 	/* LAN ID is needed for sfp_type determination */
1418*4882a593Smuzhiyun 	hw->mac.ops.set_lan_id(hw);
1419*4882a593Smuzhiyun 
1420*4882a593Smuzhiyun 	status = hw->phy.ops.read_i2c_eeprom(hw,
1421*4882a593Smuzhiyun 					     IXGBE_SFF_IDENTIFIER,
1422*4882a593Smuzhiyun 					     &identifier);
1423*4882a593Smuzhiyun 
1424*4882a593Smuzhiyun 	if (status)
1425*4882a593Smuzhiyun 		goto err_read_i2c_eeprom;
1426*4882a593Smuzhiyun 
1427*4882a593Smuzhiyun 	if (identifier != IXGBE_SFF_IDENTIFIER_SFP) {
1428*4882a593Smuzhiyun 		hw->phy.type = ixgbe_phy_sfp_unsupported;
1429*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1430*4882a593Smuzhiyun 	}
1431*4882a593Smuzhiyun 	status = hw->phy.ops.read_i2c_eeprom(hw,
1432*4882a593Smuzhiyun 					     IXGBE_SFF_1GBE_COMP_CODES,
1433*4882a593Smuzhiyun 					     &comp_codes_1g);
1434*4882a593Smuzhiyun 
1435*4882a593Smuzhiyun 	if (status)
1436*4882a593Smuzhiyun 		goto err_read_i2c_eeprom;
1437*4882a593Smuzhiyun 
1438*4882a593Smuzhiyun 	status = hw->phy.ops.read_i2c_eeprom(hw,
1439*4882a593Smuzhiyun 					     IXGBE_SFF_10GBE_COMP_CODES,
1440*4882a593Smuzhiyun 					     &comp_codes_10g);
1441*4882a593Smuzhiyun 
1442*4882a593Smuzhiyun 	if (status)
1443*4882a593Smuzhiyun 		goto err_read_i2c_eeprom;
1444*4882a593Smuzhiyun 	status = hw->phy.ops.read_i2c_eeprom(hw,
1445*4882a593Smuzhiyun 					     IXGBE_SFF_CABLE_TECHNOLOGY,
1446*4882a593Smuzhiyun 					     &cable_tech);
1447*4882a593Smuzhiyun 
1448*4882a593Smuzhiyun 	if (status)
1449*4882a593Smuzhiyun 		goto err_read_i2c_eeprom;
1450*4882a593Smuzhiyun 
1451*4882a593Smuzhiyun 	 /* ID Module
1452*4882a593Smuzhiyun 	  * =========
1453*4882a593Smuzhiyun 	  * 0   SFP_DA_CU
1454*4882a593Smuzhiyun 	  * 1   SFP_SR
1455*4882a593Smuzhiyun 	  * 2   SFP_LR
1456*4882a593Smuzhiyun 	  * 3   SFP_DA_CORE0 - 82599-specific
1457*4882a593Smuzhiyun 	  * 4   SFP_DA_CORE1 - 82599-specific
1458*4882a593Smuzhiyun 	  * 5   SFP_SR/LR_CORE0 - 82599-specific
1459*4882a593Smuzhiyun 	  * 6   SFP_SR/LR_CORE1 - 82599-specific
1460*4882a593Smuzhiyun 	  * 7   SFP_act_lmt_DA_CORE0 - 82599-specific
1461*4882a593Smuzhiyun 	  * 8   SFP_act_lmt_DA_CORE1 - 82599-specific
1462*4882a593Smuzhiyun 	  * 9   SFP_1g_cu_CORE0 - 82599-specific
1463*4882a593Smuzhiyun 	  * 10  SFP_1g_cu_CORE1 - 82599-specific
1464*4882a593Smuzhiyun 	  * 11  SFP_1g_sx_CORE0 - 82599-specific
1465*4882a593Smuzhiyun 	  * 12  SFP_1g_sx_CORE1 - 82599-specific
1466*4882a593Smuzhiyun 	  */
1467*4882a593Smuzhiyun 	if (hw->mac.type == ixgbe_mac_82598EB) {
1468*4882a593Smuzhiyun 		if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
1469*4882a593Smuzhiyun 			hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
1470*4882a593Smuzhiyun 		else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
1471*4882a593Smuzhiyun 			hw->phy.sfp_type = ixgbe_sfp_type_sr;
1472*4882a593Smuzhiyun 		else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
1473*4882a593Smuzhiyun 			hw->phy.sfp_type = ixgbe_sfp_type_lr;
1474*4882a593Smuzhiyun 		else
1475*4882a593Smuzhiyun 			hw->phy.sfp_type = ixgbe_sfp_type_unknown;
1476*4882a593Smuzhiyun 	} else {
1477*4882a593Smuzhiyun 		if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
1478*4882a593Smuzhiyun 			if (hw->bus.lan_id == 0)
1479*4882a593Smuzhiyun 				hw->phy.sfp_type =
1480*4882a593Smuzhiyun 					     ixgbe_sfp_type_da_cu_core0;
1481*4882a593Smuzhiyun 			else
1482*4882a593Smuzhiyun 				hw->phy.sfp_type =
1483*4882a593Smuzhiyun 					     ixgbe_sfp_type_da_cu_core1;
1484*4882a593Smuzhiyun 		} else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) {
1485*4882a593Smuzhiyun 			hw->phy.ops.read_i2c_eeprom(
1486*4882a593Smuzhiyun 					hw, IXGBE_SFF_CABLE_SPEC_COMP,
1487*4882a593Smuzhiyun 					&cable_spec);
1488*4882a593Smuzhiyun 			if (cable_spec &
1489*4882a593Smuzhiyun 			    IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) {
1490*4882a593Smuzhiyun 				if (hw->bus.lan_id == 0)
1491*4882a593Smuzhiyun 					hw->phy.sfp_type =
1492*4882a593Smuzhiyun 					ixgbe_sfp_type_da_act_lmt_core0;
1493*4882a593Smuzhiyun 				else
1494*4882a593Smuzhiyun 					hw->phy.sfp_type =
1495*4882a593Smuzhiyun 					ixgbe_sfp_type_da_act_lmt_core1;
1496*4882a593Smuzhiyun 			} else {
1497*4882a593Smuzhiyun 				hw->phy.sfp_type =
1498*4882a593Smuzhiyun 						ixgbe_sfp_type_unknown;
1499*4882a593Smuzhiyun 			}
1500*4882a593Smuzhiyun 		} else if (comp_codes_10g &
1501*4882a593Smuzhiyun 			   (IXGBE_SFF_10GBASESR_CAPABLE |
1502*4882a593Smuzhiyun 			    IXGBE_SFF_10GBASELR_CAPABLE)) {
1503*4882a593Smuzhiyun 			if (hw->bus.lan_id == 0)
1504*4882a593Smuzhiyun 				hw->phy.sfp_type =
1505*4882a593Smuzhiyun 					      ixgbe_sfp_type_srlr_core0;
1506*4882a593Smuzhiyun 			else
1507*4882a593Smuzhiyun 				hw->phy.sfp_type =
1508*4882a593Smuzhiyun 					      ixgbe_sfp_type_srlr_core1;
1509*4882a593Smuzhiyun 		} else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) {
1510*4882a593Smuzhiyun 			if (hw->bus.lan_id == 0)
1511*4882a593Smuzhiyun 				hw->phy.sfp_type =
1512*4882a593Smuzhiyun 					ixgbe_sfp_type_1g_cu_core0;
1513*4882a593Smuzhiyun 			else
1514*4882a593Smuzhiyun 				hw->phy.sfp_type =
1515*4882a593Smuzhiyun 					ixgbe_sfp_type_1g_cu_core1;
1516*4882a593Smuzhiyun 		} else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) {
1517*4882a593Smuzhiyun 			if (hw->bus.lan_id == 0)
1518*4882a593Smuzhiyun 				hw->phy.sfp_type =
1519*4882a593Smuzhiyun 					ixgbe_sfp_type_1g_sx_core0;
1520*4882a593Smuzhiyun 			else
1521*4882a593Smuzhiyun 				hw->phy.sfp_type =
1522*4882a593Smuzhiyun 					ixgbe_sfp_type_1g_sx_core1;
1523*4882a593Smuzhiyun 		} else if (comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) {
1524*4882a593Smuzhiyun 			if (hw->bus.lan_id == 0)
1525*4882a593Smuzhiyun 				hw->phy.sfp_type =
1526*4882a593Smuzhiyun 					ixgbe_sfp_type_1g_lx_core0;
1527*4882a593Smuzhiyun 			else
1528*4882a593Smuzhiyun 				hw->phy.sfp_type =
1529*4882a593Smuzhiyun 					ixgbe_sfp_type_1g_lx_core1;
1530*4882a593Smuzhiyun 		} else {
1531*4882a593Smuzhiyun 			hw->phy.sfp_type = ixgbe_sfp_type_unknown;
1532*4882a593Smuzhiyun 		}
1533*4882a593Smuzhiyun 	}
1534*4882a593Smuzhiyun 
1535*4882a593Smuzhiyun 	if (hw->phy.sfp_type != stored_sfp_type)
1536*4882a593Smuzhiyun 		hw->phy.sfp_setup_needed = true;
1537*4882a593Smuzhiyun 
1538*4882a593Smuzhiyun 	/* Determine if the SFP+ PHY is dual speed or not. */
1539*4882a593Smuzhiyun 	hw->phy.multispeed_fiber = false;
1540*4882a593Smuzhiyun 	if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
1541*4882a593Smuzhiyun 	     (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
1542*4882a593Smuzhiyun 	    ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
1543*4882a593Smuzhiyun 	     (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
1544*4882a593Smuzhiyun 		hw->phy.multispeed_fiber = true;
1545*4882a593Smuzhiyun 
1546*4882a593Smuzhiyun 	/* Determine PHY vendor */
1547*4882a593Smuzhiyun 	if (hw->phy.type != ixgbe_phy_nl) {
1548*4882a593Smuzhiyun 		hw->phy.id = identifier;
1549*4882a593Smuzhiyun 		status = hw->phy.ops.read_i2c_eeprom(hw,
1550*4882a593Smuzhiyun 					    IXGBE_SFF_VENDOR_OUI_BYTE0,
1551*4882a593Smuzhiyun 					    &oui_bytes[0]);
1552*4882a593Smuzhiyun 
1553*4882a593Smuzhiyun 		if (status != 0)
1554*4882a593Smuzhiyun 			goto err_read_i2c_eeprom;
1555*4882a593Smuzhiyun 
1556*4882a593Smuzhiyun 		status = hw->phy.ops.read_i2c_eeprom(hw,
1557*4882a593Smuzhiyun 					    IXGBE_SFF_VENDOR_OUI_BYTE1,
1558*4882a593Smuzhiyun 					    &oui_bytes[1]);
1559*4882a593Smuzhiyun 
1560*4882a593Smuzhiyun 		if (status != 0)
1561*4882a593Smuzhiyun 			goto err_read_i2c_eeprom;
1562*4882a593Smuzhiyun 
1563*4882a593Smuzhiyun 		status = hw->phy.ops.read_i2c_eeprom(hw,
1564*4882a593Smuzhiyun 					    IXGBE_SFF_VENDOR_OUI_BYTE2,
1565*4882a593Smuzhiyun 					    &oui_bytes[2]);
1566*4882a593Smuzhiyun 
1567*4882a593Smuzhiyun 		if (status != 0)
1568*4882a593Smuzhiyun 			goto err_read_i2c_eeprom;
1569*4882a593Smuzhiyun 
1570*4882a593Smuzhiyun 		vendor_oui =
1571*4882a593Smuzhiyun 		  ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
1572*4882a593Smuzhiyun 		   (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
1573*4882a593Smuzhiyun 		   (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
1574*4882a593Smuzhiyun 
1575*4882a593Smuzhiyun 		switch (vendor_oui) {
1576*4882a593Smuzhiyun 		case IXGBE_SFF_VENDOR_OUI_TYCO:
1577*4882a593Smuzhiyun 			if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
1578*4882a593Smuzhiyun 				hw->phy.type =
1579*4882a593Smuzhiyun 					    ixgbe_phy_sfp_passive_tyco;
1580*4882a593Smuzhiyun 			break;
1581*4882a593Smuzhiyun 		case IXGBE_SFF_VENDOR_OUI_FTL:
1582*4882a593Smuzhiyun 			if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
1583*4882a593Smuzhiyun 				hw->phy.type = ixgbe_phy_sfp_ftl_active;
1584*4882a593Smuzhiyun 			else
1585*4882a593Smuzhiyun 				hw->phy.type = ixgbe_phy_sfp_ftl;
1586*4882a593Smuzhiyun 			break;
1587*4882a593Smuzhiyun 		case IXGBE_SFF_VENDOR_OUI_AVAGO:
1588*4882a593Smuzhiyun 			hw->phy.type = ixgbe_phy_sfp_avago;
1589*4882a593Smuzhiyun 			break;
1590*4882a593Smuzhiyun 		case IXGBE_SFF_VENDOR_OUI_INTEL:
1591*4882a593Smuzhiyun 			hw->phy.type = ixgbe_phy_sfp_intel;
1592*4882a593Smuzhiyun 			break;
1593*4882a593Smuzhiyun 		default:
1594*4882a593Smuzhiyun 			if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
1595*4882a593Smuzhiyun 				hw->phy.type =
1596*4882a593Smuzhiyun 					 ixgbe_phy_sfp_passive_unknown;
1597*4882a593Smuzhiyun 			else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
1598*4882a593Smuzhiyun 				hw->phy.type =
1599*4882a593Smuzhiyun 					ixgbe_phy_sfp_active_unknown;
1600*4882a593Smuzhiyun 			else
1601*4882a593Smuzhiyun 				hw->phy.type = ixgbe_phy_sfp_unknown;
1602*4882a593Smuzhiyun 			break;
1603*4882a593Smuzhiyun 		}
1604*4882a593Smuzhiyun 	}
1605*4882a593Smuzhiyun 
1606*4882a593Smuzhiyun 	/* Allow any DA cable vendor */
1607*4882a593Smuzhiyun 	if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE |
1608*4882a593Smuzhiyun 	    IXGBE_SFF_DA_ACTIVE_CABLE))
1609*4882a593Smuzhiyun 		return 0;
1610*4882a593Smuzhiyun 
1611*4882a593Smuzhiyun 	/* Verify supported 1G SFP modules */
1612*4882a593Smuzhiyun 	if (comp_codes_10g == 0 &&
1613*4882a593Smuzhiyun 	    !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
1614*4882a593Smuzhiyun 	      hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
1615*4882a593Smuzhiyun 	      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
1616*4882a593Smuzhiyun 	      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
1617*4882a593Smuzhiyun 	      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
1618*4882a593Smuzhiyun 	      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
1619*4882a593Smuzhiyun 		hw->phy.type = ixgbe_phy_sfp_unsupported;
1620*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1621*4882a593Smuzhiyun 	}
1622*4882a593Smuzhiyun 
1623*4882a593Smuzhiyun 	/* Anything else 82598-based is supported */
1624*4882a593Smuzhiyun 	if (hw->mac.type == ixgbe_mac_82598EB)
1625*4882a593Smuzhiyun 		return 0;
1626*4882a593Smuzhiyun 
1627*4882a593Smuzhiyun 	hw->mac.ops.get_device_caps(hw, &enforce_sfp);
1628*4882a593Smuzhiyun 	if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
1629*4882a593Smuzhiyun 	    !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
1630*4882a593Smuzhiyun 	      hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
1631*4882a593Smuzhiyun 	      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
1632*4882a593Smuzhiyun 	      hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
1633*4882a593Smuzhiyun 	      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
1634*4882a593Smuzhiyun 	      hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
1635*4882a593Smuzhiyun 		/* Make sure we're a supported PHY type */
1636*4882a593Smuzhiyun 		if (hw->phy.type == ixgbe_phy_sfp_intel)
1637*4882a593Smuzhiyun 			return 0;
1638*4882a593Smuzhiyun 		if (hw->allow_unsupported_sfp) {
1639*4882a593Smuzhiyun 			e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics.  Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter.  Intel Corporation is not responsible for any harm caused by using untested modules.\n");
1640*4882a593Smuzhiyun 			return 0;
1641*4882a593Smuzhiyun 		}
1642*4882a593Smuzhiyun 		hw_dbg(hw, "SFP+ module not supported\n");
1643*4882a593Smuzhiyun 		hw->phy.type = ixgbe_phy_sfp_unsupported;
1644*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1645*4882a593Smuzhiyun 	}
1646*4882a593Smuzhiyun 	return 0;
1647*4882a593Smuzhiyun 
1648*4882a593Smuzhiyun err_read_i2c_eeprom:
1649*4882a593Smuzhiyun 	hw->phy.sfp_type = ixgbe_sfp_type_not_present;
1650*4882a593Smuzhiyun 	if (hw->phy.type != ixgbe_phy_nl) {
1651*4882a593Smuzhiyun 		hw->phy.id = 0;
1652*4882a593Smuzhiyun 		hw->phy.type = ixgbe_phy_unknown;
1653*4882a593Smuzhiyun 	}
1654*4882a593Smuzhiyun 	return IXGBE_ERR_SFP_NOT_PRESENT;
1655*4882a593Smuzhiyun }
1656*4882a593Smuzhiyun 
1657*4882a593Smuzhiyun /**
1658*4882a593Smuzhiyun  * ixgbe_identify_qsfp_module_generic - Identifies QSFP modules
1659*4882a593Smuzhiyun  * @hw: pointer to hardware structure
1660*4882a593Smuzhiyun  *
1661*4882a593Smuzhiyun  * Searches for and identifies the QSFP module and assigns appropriate PHY type
1662*4882a593Smuzhiyun  **/
ixgbe_identify_qsfp_module_generic(struct ixgbe_hw * hw)1663*4882a593Smuzhiyun static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
1664*4882a593Smuzhiyun {
1665*4882a593Smuzhiyun 	struct ixgbe_adapter *adapter = hw->back;
1666*4882a593Smuzhiyun 	s32 status;
1667*4882a593Smuzhiyun 	u32 vendor_oui = 0;
1668*4882a593Smuzhiyun 	enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
1669*4882a593Smuzhiyun 	u8 identifier = 0;
1670*4882a593Smuzhiyun 	u8 comp_codes_1g = 0;
1671*4882a593Smuzhiyun 	u8 comp_codes_10g = 0;
1672*4882a593Smuzhiyun 	u8 oui_bytes[3] = {0, 0, 0};
1673*4882a593Smuzhiyun 	u16 enforce_sfp = 0;
1674*4882a593Smuzhiyun 	u8 connector = 0;
1675*4882a593Smuzhiyun 	u8 cable_length = 0;
1676*4882a593Smuzhiyun 	u8 device_tech = 0;
1677*4882a593Smuzhiyun 	bool active_cable = false;
1678*4882a593Smuzhiyun 
1679*4882a593Smuzhiyun 	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber_qsfp) {
1680*4882a593Smuzhiyun 		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
1681*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NOT_PRESENT;
1682*4882a593Smuzhiyun 	}
1683*4882a593Smuzhiyun 
1684*4882a593Smuzhiyun 	/* LAN ID is needed for sfp_type determination */
1685*4882a593Smuzhiyun 	hw->mac.ops.set_lan_id(hw);
1686*4882a593Smuzhiyun 
1687*4882a593Smuzhiyun 	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
1688*4882a593Smuzhiyun 					     &identifier);
1689*4882a593Smuzhiyun 
1690*4882a593Smuzhiyun 	if (status != 0)
1691*4882a593Smuzhiyun 		goto err_read_i2c_eeprom;
1692*4882a593Smuzhiyun 
1693*4882a593Smuzhiyun 	if (identifier != IXGBE_SFF_IDENTIFIER_QSFP_PLUS) {
1694*4882a593Smuzhiyun 		hw->phy.type = ixgbe_phy_sfp_unsupported;
1695*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1696*4882a593Smuzhiyun 	}
1697*4882a593Smuzhiyun 
1698*4882a593Smuzhiyun 	hw->phy.id = identifier;
1699*4882a593Smuzhiyun 
1700*4882a593Smuzhiyun 	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_10GBE_COMP,
1701*4882a593Smuzhiyun 					     &comp_codes_10g);
1702*4882a593Smuzhiyun 
1703*4882a593Smuzhiyun 	if (status != 0)
1704*4882a593Smuzhiyun 		goto err_read_i2c_eeprom;
1705*4882a593Smuzhiyun 
1706*4882a593Smuzhiyun 	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_1GBE_COMP,
1707*4882a593Smuzhiyun 					     &comp_codes_1g);
1708*4882a593Smuzhiyun 
1709*4882a593Smuzhiyun 	if (status != 0)
1710*4882a593Smuzhiyun 		goto err_read_i2c_eeprom;
1711*4882a593Smuzhiyun 
1712*4882a593Smuzhiyun 	if (comp_codes_10g & IXGBE_SFF_QSFP_DA_PASSIVE_CABLE) {
1713*4882a593Smuzhiyun 		hw->phy.type = ixgbe_phy_qsfp_passive_unknown;
1714*4882a593Smuzhiyun 		if (hw->bus.lan_id == 0)
1715*4882a593Smuzhiyun 			hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core0;
1716*4882a593Smuzhiyun 		else
1717*4882a593Smuzhiyun 			hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core1;
1718*4882a593Smuzhiyun 	} else if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE |
1719*4882a593Smuzhiyun 				     IXGBE_SFF_10GBASELR_CAPABLE)) {
1720*4882a593Smuzhiyun 		if (hw->bus.lan_id == 0)
1721*4882a593Smuzhiyun 			hw->phy.sfp_type = ixgbe_sfp_type_srlr_core0;
1722*4882a593Smuzhiyun 		else
1723*4882a593Smuzhiyun 			hw->phy.sfp_type = ixgbe_sfp_type_srlr_core1;
1724*4882a593Smuzhiyun 	} else {
1725*4882a593Smuzhiyun 		if (comp_codes_10g & IXGBE_SFF_QSFP_DA_ACTIVE_CABLE)
1726*4882a593Smuzhiyun 			active_cable = true;
1727*4882a593Smuzhiyun 
1728*4882a593Smuzhiyun 		if (!active_cable) {
1729*4882a593Smuzhiyun 			/* check for active DA cables that pre-date
1730*4882a593Smuzhiyun 			 * SFF-8436 v3.6
1731*4882a593Smuzhiyun 			 */
1732*4882a593Smuzhiyun 			hw->phy.ops.read_i2c_eeprom(hw,
1733*4882a593Smuzhiyun 					IXGBE_SFF_QSFP_CONNECTOR,
1734*4882a593Smuzhiyun 					&connector);
1735*4882a593Smuzhiyun 
1736*4882a593Smuzhiyun 			hw->phy.ops.read_i2c_eeprom(hw,
1737*4882a593Smuzhiyun 					IXGBE_SFF_QSFP_CABLE_LENGTH,
1738*4882a593Smuzhiyun 					&cable_length);
1739*4882a593Smuzhiyun 
1740*4882a593Smuzhiyun 			hw->phy.ops.read_i2c_eeprom(hw,
1741*4882a593Smuzhiyun 					IXGBE_SFF_QSFP_DEVICE_TECH,
1742*4882a593Smuzhiyun 					&device_tech);
1743*4882a593Smuzhiyun 
1744*4882a593Smuzhiyun 			if ((connector ==
1745*4882a593Smuzhiyun 				     IXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE) &&
1746*4882a593Smuzhiyun 			    (cable_length > 0) &&
1747*4882a593Smuzhiyun 			    ((device_tech >> 4) ==
1748*4882a593Smuzhiyun 				     IXGBE_SFF_QSFP_TRANSMITER_850NM_VCSEL))
1749*4882a593Smuzhiyun 				active_cable = true;
1750*4882a593Smuzhiyun 		}
1751*4882a593Smuzhiyun 
1752*4882a593Smuzhiyun 		if (active_cable) {
1753*4882a593Smuzhiyun 			hw->phy.type = ixgbe_phy_qsfp_active_unknown;
1754*4882a593Smuzhiyun 			if (hw->bus.lan_id == 0)
1755*4882a593Smuzhiyun 				hw->phy.sfp_type =
1756*4882a593Smuzhiyun 						ixgbe_sfp_type_da_act_lmt_core0;
1757*4882a593Smuzhiyun 			else
1758*4882a593Smuzhiyun 				hw->phy.sfp_type =
1759*4882a593Smuzhiyun 						ixgbe_sfp_type_da_act_lmt_core1;
1760*4882a593Smuzhiyun 		} else {
1761*4882a593Smuzhiyun 			/* unsupported module type */
1762*4882a593Smuzhiyun 			hw->phy.type = ixgbe_phy_sfp_unsupported;
1763*4882a593Smuzhiyun 			return IXGBE_ERR_SFP_NOT_SUPPORTED;
1764*4882a593Smuzhiyun 		}
1765*4882a593Smuzhiyun 	}
1766*4882a593Smuzhiyun 
1767*4882a593Smuzhiyun 	if (hw->phy.sfp_type != stored_sfp_type)
1768*4882a593Smuzhiyun 		hw->phy.sfp_setup_needed = true;
1769*4882a593Smuzhiyun 
1770*4882a593Smuzhiyun 	/* Determine if the QSFP+ PHY is dual speed or not. */
1771*4882a593Smuzhiyun 	hw->phy.multispeed_fiber = false;
1772*4882a593Smuzhiyun 	if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
1773*4882a593Smuzhiyun 	     (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
1774*4882a593Smuzhiyun 	    ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
1775*4882a593Smuzhiyun 	     (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
1776*4882a593Smuzhiyun 		hw->phy.multispeed_fiber = true;
1777*4882a593Smuzhiyun 
1778*4882a593Smuzhiyun 	/* Determine PHY vendor for optical modules */
1779*4882a593Smuzhiyun 	if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE |
1780*4882a593Smuzhiyun 			      IXGBE_SFF_10GBASELR_CAPABLE)) {
1781*4882a593Smuzhiyun 		status = hw->phy.ops.read_i2c_eeprom(hw,
1782*4882a593Smuzhiyun 					IXGBE_SFF_QSFP_VENDOR_OUI_BYTE0,
1783*4882a593Smuzhiyun 					&oui_bytes[0]);
1784*4882a593Smuzhiyun 
1785*4882a593Smuzhiyun 		if (status != 0)
1786*4882a593Smuzhiyun 			goto err_read_i2c_eeprom;
1787*4882a593Smuzhiyun 
1788*4882a593Smuzhiyun 		status = hw->phy.ops.read_i2c_eeprom(hw,
1789*4882a593Smuzhiyun 					IXGBE_SFF_QSFP_VENDOR_OUI_BYTE1,
1790*4882a593Smuzhiyun 					&oui_bytes[1]);
1791*4882a593Smuzhiyun 
1792*4882a593Smuzhiyun 		if (status != 0)
1793*4882a593Smuzhiyun 			goto err_read_i2c_eeprom;
1794*4882a593Smuzhiyun 
1795*4882a593Smuzhiyun 		status = hw->phy.ops.read_i2c_eeprom(hw,
1796*4882a593Smuzhiyun 					IXGBE_SFF_QSFP_VENDOR_OUI_BYTE2,
1797*4882a593Smuzhiyun 					&oui_bytes[2]);
1798*4882a593Smuzhiyun 
1799*4882a593Smuzhiyun 		if (status != 0)
1800*4882a593Smuzhiyun 			goto err_read_i2c_eeprom;
1801*4882a593Smuzhiyun 
1802*4882a593Smuzhiyun 		vendor_oui =
1803*4882a593Smuzhiyun 			((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
1804*4882a593Smuzhiyun 			 (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
1805*4882a593Smuzhiyun 			 (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
1806*4882a593Smuzhiyun 
1807*4882a593Smuzhiyun 		if (vendor_oui == IXGBE_SFF_VENDOR_OUI_INTEL)
1808*4882a593Smuzhiyun 			hw->phy.type = ixgbe_phy_qsfp_intel;
1809*4882a593Smuzhiyun 		else
1810*4882a593Smuzhiyun 			hw->phy.type = ixgbe_phy_qsfp_unknown;
1811*4882a593Smuzhiyun 
1812*4882a593Smuzhiyun 		hw->mac.ops.get_device_caps(hw, &enforce_sfp);
1813*4882a593Smuzhiyun 		if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
1814*4882a593Smuzhiyun 			/* Make sure we're a supported PHY type */
1815*4882a593Smuzhiyun 			if (hw->phy.type == ixgbe_phy_qsfp_intel)
1816*4882a593Smuzhiyun 				return 0;
1817*4882a593Smuzhiyun 			if (hw->allow_unsupported_sfp) {
1818*4882a593Smuzhiyun 				e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n");
1819*4882a593Smuzhiyun 				return 0;
1820*4882a593Smuzhiyun 			}
1821*4882a593Smuzhiyun 			hw_dbg(hw, "QSFP module not supported\n");
1822*4882a593Smuzhiyun 			hw->phy.type = ixgbe_phy_sfp_unsupported;
1823*4882a593Smuzhiyun 			return IXGBE_ERR_SFP_NOT_SUPPORTED;
1824*4882a593Smuzhiyun 		}
1825*4882a593Smuzhiyun 		return 0;
1826*4882a593Smuzhiyun 	}
1827*4882a593Smuzhiyun 	return 0;
1828*4882a593Smuzhiyun 
1829*4882a593Smuzhiyun err_read_i2c_eeprom:
1830*4882a593Smuzhiyun 	hw->phy.sfp_type = ixgbe_sfp_type_not_present;
1831*4882a593Smuzhiyun 	hw->phy.id = 0;
1832*4882a593Smuzhiyun 	hw->phy.type = ixgbe_phy_unknown;
1833*4882a593Smuzhiyun 
1834*4882a593Smuzhiyun 	return IXGBE_ERR_SFP_NOT_PRESENT;
1835*4882a593Smuzhiyun }
1836*4882a593Smuzhiyun 
1837*4882a593Smuzhiyun /**
1838*4882a593Smuzhiyun  *  ixgbe_get_sfp_init_sequence_offsets - Provides offset of PHY init sequence
1839*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
1840*4882a593Smuzhiyun  *  @list_offset: offset to the SFP ID list
1841*4882a593Smuzhiyun  *  @data_offset: offset to the SFP data block
1842*4882a593Smuzhiyun  *
1843*4882a593Smuzhiyun  *  Checks the MAC's EEPROM to see if it supports a given SFP+ module type, if
1844*4882a593Smuzhiyun  *  so it returns the offsets to the phy init sequence block.
1845*4882a593Smuzhiyun  **/
ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw * hw,u16 * list_offset,u16 * data_offset)1846*4882a593Smuzhiyun s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
1847*4882a593Smuzhiyun 					u16 *list_offset,
1848*4882a593Smuzhiyun 					u16 *data_offset)
1849*4882a593Smuzhiyun {
1850*4882a593Smuzhiyun 	u16 sfp_id;
1851*4882a593Smuzhiyun 	u16 sfp_type = hw->phy.sfp_type;
1852*4882a593Smuzhiyun 
1853*4882a593Smuzhiyun 	if (hw->phy.sfp_type == ixgbe_sfp_type_unknown)
1854*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1855*4882a593Smuzhiyun 
1856*4882a593Smuzhiyun 	if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
1857*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NOT_PRESENT;
1858*4882a593Smuzhiyun 
1859*4882a593Smuzhiyun 	if ((hw->device_id == IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM) &&
1860*4882a593Smuzhiyun 	    (hw->phy.sfp_type == ixgbe_sfp_type_da_cu))
1861*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1862*4882a593Smuzhiyun 
1863*4882a593Smuzhiyun 	/*
1864*4882a593Smuzhiyun 	 * Limiting active cables and 1G Phys must be initialized as
1865*4882a593Smuzhiyun 	 * SR modules
1866*4882a593Smuzhiyun 	 */
1867*4882a593Smuzhiyun 	if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 ||
1868*4882a593Smuzhiyun 	    sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
1869*4882a593Smuzhiyun 	    sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
1870*4882a593Smuzhiyun 	    sfp_type == ixgbe_sfp_type_1g_sx_core0)
1871*4882a593Smuzhiyun 		sfp_type = ixgbe_sfp_type_srlr_core0;
1872*4882a593Smuzhiyun 	else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 ||
1873*4882a593Smuzhiyun 		 sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
1874*4882a593Smuzhiyun 		 sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
1875*4882a593Smuzhiyun 		 sfp_type == ixgbe_sfp_type_1g_sx_core1)
1876*4882a593Smuzhiyun 		sfp_type = ixgbe_sfp_type_srlr_core1;
1877*4882a593Smuzhiyun 
1878*4882a593Smuzhiyun 	/* Read offset to PHY init contents */
1879*4882a593Smuzhiyun 	if (hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset)) {
1880*4882a593Smuzhiyun 		hw_err(hw, "eeprom read at %d failed\n",
1881*4882a593Smuzhiyun 		       IXGBE_PHY_INIT_OFFSET_NL);
1882*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
1883*4882a593Smuzhiyun 	}
1884*4882a593Smuzhiyun 
1885*4882a593Smuzhiyun 	if ((!*list_offset) || (*list_offset == 0xFFFF))
1886*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
1887*4882a593Smuzhiyun 
1888*4882a593Smuzhiyun 	/* Shift offset to first ID word */
1889*4882a593Smuzhiyun 	(*list_offset)++;
1890*4882a593Smuzhiyun 
1891*4882a593Smuzhiyun 	/*
1892*4882a593Smuzhiyun 	 * Find the matching SFP ID in the EEPROM
1893*4882a593Smuzhiyun 	 * and program the init sequence
1894*4882a593Smuzhiyun 	 */
1895*4882a593Smuzhiyun 	if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id))
1896*4882a593Smuzhiyun 		goto err_phy;
1897*4882a593Smuzhiyun 
1898*4882a593Smuzhiyun 	while (sfp_id != IXGBE_PHY_INIT_END_NL) {
1899*4882a593Smuzhiyun 		if (sfp_id == sfp_type) {
1900*4882a593Smuzhiyun 			(*list_offset)++;
1901*4882a593Smuzhiyun 			if (hw->eeprom.ops.read(hw, *list_offset, data_offset))
1902*4882a593Smuzhiyun 				goto err_phy;
1903*4882a593Smuzhiyun 			if ((!*data_offset) || (*data_offset == 0xFFFF)) {
1904*4882a593Smuzhiyun 				hw_dbg(hw, "SFP+ module not supported\n");
1905*4882a593Smuzhiyun 				return IXGBE_ERR_SFP_NOT_SUPPORTED;
1906*4882a593Smuzhiyun 			} else {
1907*4882a593Smuzhiyun 				break;
1908*4882a593Smuzhiyun 			}
1909*4882a593Smuzhiyun 		} else {
1910*4882a593Smuzhiyun 			(*list_offset) += 2;
1911*4882a593Smuzhiyun 			if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id))
1912*4882a593Smuzhiyun 				goto err_phy;
1913*4882a593Smuzhiyun 		}
1914*4882a593Smuzhiyun 	}
1915*4882a593Smuzhiyun 
1916*4882a593Smuzhiyun 	if (sfp_id == IXGBE_PHY_INIT_END_NL) {
1917*4882a593Smuzhiyun 		hw_dbg(hw, "No matching SFP+ module found\n");
1918*4882a593Smuzhiyun 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1919*4882a593Smuzhiyun 	}
1920*4882a593Smuzhiyun 
1921*4882a593Smuzhiyun 	return 0;
1922*4882a593Smuzhiyun 
1923*4882a593Smuzhiyun err_phy:
1924*4882a593Smuzhiyun 	hw_err(hw, "eeprom read at offset %d failed\n", *list_offset);
1925*4882a593Smuzhiyun 	return IXGBE_ERR_PHY;
1926*4882a593Smuzhiyun }
1927*4882a593Smuzhiyun 
1928*4882a593Smuzhiyun /**
1929*4882a593Smuzhiyun  *  ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface
1930*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
1931*4882a593Smuzhiyun  *  @byte_offset: EEPROM byte offset to read
1932*4882a593Smuzhiyun  *  @eeprom_data: value read
1933*4882a593Smuzhiyun  *
1934*4882a593Smuzhiyun  *  Performs byte read operation to SFP module's EEPROM over I2C interface.
1935*4882a593Smuzhiyun  **/
ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw * hw,u8 byte_offset,u8 * eeprom_data)1936*4882a593Smuzhiyun s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
1937*4882a593Smuzhiyun 				  u8 *eeprom_data)
1938*4882a593Smuzhiyun {
1939*4882a593Smuzhiyun 	return hw->phy.ops.read_i2c_byte(hw, byte_offset,
1940*4882a593Smuzhiyun 					 IXGBE_I2C_EEPROM_DEV_ADDR,
1941*4882a593Smuzhiyun 					 eeprom_data);
1942*4882a593Smuzhiyun }
1943*4882a593Smuzhiyun 
1944*4882a593Smuzhiyun /**
1945*4882a593Smuzhiyun  *  ixgbe_read_i2c_sff8472_generic - Reads 8 bit word over I2C interface
1946*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
1947*4882a593Smuzhiyun  *  @byte_offset: byte offset at address 0xA2
1948*4882a593Smuzhiyun  *  @sff8472_data: value read
1949*4882a593Smuzhiyun  *
1950*4882a593Smuzhiyun  *  Performs byte read operation to SFP module's SFF-8472 data over I2C
1951*4882a593Smuzhiyun  **/
ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw * hw,u8 byte_offset,u8 * sff8472_data)1952*4882a593Smuzhiyun s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
1953*4882a593Smuzhiyun 				   u8 *sff8472_data)
1954*4882a593Smuzhiyun {
1955*4882a593Smuzhiyun 	return hw->phy.ops.read_i2c_byte(hw, byte_offset,
1956*4882a593Smuzhiyun 					 IXGBE_I2C_EEPROM_DEV_ADDR2,
1957*4882a593Smuzhiyun 					 sff8472_data);
1958*4882a593Smuzhiyun }
1959*4882a593Smuzhiyun 
1960*4882a593Smuzhiyun /**
1961*4882a593Smuzhiyun  *  ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
1962*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
1963*4882a593Smuzhiyun  *  @byte_offset: EEPROM byte offset to write
1964*4882a593Smuzhiyun  *  @eeprom_data: value to write
1965*4882a593Smuzhiyun  *
1966*4882a593Smuzhiyun  *  Performs byte write operation to SFP module's EEPROM over I2C interface.
1967*4882a593Smuzhiyun  **/
ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw * hw,u8 byte_offset,u8 eeprom_data)1968*4882a593Smuzhiyun s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
1969*4882a593Smuzhiyun 				   u8 eeprom_data)
1970*4882a593Smuzhiyun {
1971*4882a593Smuzhiyun 	return hw->phy.ops.write_i2c_byte(hw, byte_offset,
1972*4882a593Smuzhiyun 					  IXGBE_I2C_EEPROM_DEV_ADDR,
1973*4882a593Smuzhiyun 					  eeprom_data);
1974*4882a593Smuzhiyun }
1975*4882a593Smuzhiyun 
1976*4882a593Smuzhiyun /**
1977*4882a593Smuzhiyun  * ixgbe_is_sfp_probe - Returns true if SFP is being detected
1978*4882a593Smuzhiyun  * @hw: pointer to hardware structure
1979*4882a593Smuzhiyun  * @offset: eeprom offset to be read
1980*4882a593Smuzhiyun  * @addr: I2C address to be read
1981*4882a593Smuzhiyun  */
ixgbe_is_sfp_probe(struct ixgbe_hw * hw,u8 offset,u8 addr)1982*4882a593Smuzhiyun static bool ixgbe_is_sfp_probe(struct ixgbe_hw *hw, u8 offset, u8 addr)
1983*4882a593Smuzhiyun {
1984*4882a593Smuzhiyun 	if (addr == IXGBE_I2C_EEPROM_DEV_ADDR &&
1985*4882a593Smuzhiyun 	    offset == IXGBE_SFF_IDENTIFIER &&
1986*4882a593Smuzhiyun 	    hw->phy.sfp_type == ixgbe_sfp_type_not_present)
1987*4882a593Smuzhiyun 		return true;
1988*4882a593Smuzhiyun 	return false;
1989*4882a593Smuzhiyun }
1990*4882a593Smuzhiyun 
1991*4882a593Smuzhiyun /**
1992*4882a593Smuzhiyun  *  ixgbe_read_i2c_byte_generic_int - Reads 8 bit word over I2C
1993*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
1994*4882a593Smuzhiyun  *  @byte_offset: byte offset to read
1995*4882a593Smuzhiyun  *  @dev_addr: device address
1996*4882a593Smuzhiyun  *  @data: value read
1997*4882a593Smuzhiyun  *  @lock: true if to take and release semaphore
1998*4882a593Smuzhiyun  *
1999*4882a593Smuzhiyun  *  Performs byte read operation to SFP module's EEPROM over I2C interface at
2000*4882a593Smuzhiyun  *  a specified device address.
2001*4882a593Smuzhiyun  */
ixgbe_read_i2c_byte_generic_int(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 * data,bool lock)2002*4882a593Smuzhiyun static s32 ixgbe_read_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset,
2003*4882a593Smuzhiyun 					   u8 dev_addr, u8 *data, bool lock)
2004*4882a593Smuzhiyun {
2005*4882a593Smuzhiyun 	s32 status;
2006*4882a593Smuzhiyun 	u32 max_retry = 10;
2007*4882a593Smuzhiyun 	u32 retry = 0;
2008*4882a593Smuzhiyun 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
2009*4882a593Smuzhiyun 	bool nack = true;
2010*4882a593Smuzhiyun 
2011*4882a593Smuzhiyun 	if (hw->mac.type >= ixgbe_mac_X550)
2012*4882a593Smuzhiyun 		max_retry = 3;
2013*4882a593Smuzhiyun 	if (ixgbe_is_sfp_probe(hw, byte_offset, dev_addr))
2014*4882a593Smuzhiyun 		max_retry = IXGBE_SFP_DETECT_RETRIES;
2015*4882a593Smuzhiyun 
2016*4882a593Smuzhiyun 	*data = 0;
2017*4882a593Smuzhiyun 
2018*4882a593Smuzhiyun 	do {
2019*4882a593Smuzhiyun 		if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
2020*4882a593Smuzhiyun 			return IXGBE_ERR_SWFW_SYNC;
2021*4882a593Smuzhiyun 
2022*4882a593Smuzhiyun 		ixgbe_i2c_start(hw);
2023*4882a593Smuzhiyun 
2024*4882a593Smuzhiyun 		/* Device Address and write indication */
2025*4882a593Smuzhiyun 		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
2026*4882a593Smuzhiyun 		if (status != 0)
2027*4882a593Smuzhiyun 			goto fail;
2028*4882a593Smuzhiyun 
2029*4882a593Smuzhiyun 		status = ixgbe_get_i2c_ack(hw);
2030*4882a593Smuzhiyun 		if (status != 0)
2031*4882a593Smuzhiyun 			goto fail;
2032*4882a593Smuzhiyun 
2033*4882a593Smuzhiyun 		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
2034*4882a593Smuzhiyun 		if (status != 0)
2035*4882a593Smuzhiyun 			goto fail;
2036*4882a593Smuzhiyun 
2037*4882a593Smuzhiyun 		status = ixgbe_get_i2c_ack(hw);
2038*4882a593Smuzhiyun 		if (status != 0)
2039*4882a593Smuzhiyun 			goto fail;
2040*4882a593Smuzhiyun 
2041*4882a593Smuzhiyun 		ixgbe_i2c_start(hw);
2042*4882a593Smuzhiyun 
2043*4882a593Smuzhiyun 		/* Device Address and read indication */
2044*4882a593Smuzhiyun 		status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1));
2045*4882a593Smuzhiyun 		if (status != 0)
2046*4882a593Smuzhiyun 			goto fail;
2047*4882a593Smuzhiyun 
2048*4882a593Smuzhiyun 		status = ixgbe_get_i2c_ack(hw);
2049*4882a593Smuzhiyun 		if (status != 0)
2050*4882a593Smuzhiyun 			goto fail;
2051*4882a593Smuzhiyun 
2052*4882a593Smuzhiyun 		status = ixgbe_clock_in_i2c_byte(hw, data);
2053*4882a593Smuzhiyun 		if (status != 0)
2054*4882a593Smuzhiyun 			goto fail;
2055*4882a593Smuzhiyun 
2056*4882a593Smuzhiyun 		status = ixgbe_clock_out_i2c_bit(hw, nack);
2057*4882a593Smuzhiyun 		if (status != 0)
2058*4882a593Smuzhiyun 			goto fail;
2059*4882a593Smuzhiyun 
2060*4882a593Smuzhiyun 		ixgbe_i2c_stop(hw);
2061*4882a593Smuzhiyun 		if (lock)
2062*4882a593Smuzhiyun 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2063*4882a593Smuzhiyun 		return 0;
2064*4882a593Smuzhiyun 
2065*4882a593Smuzhiyun fail:
2066*4882a593Smuzhiyun 		ixgbe_i2c_bus_clear(hw);
2067*4882a593Smuzhiyun 		if (lock) {
2068*4882a593Smuzhiyun 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2069*4882a593Smuzhiyun 			msleep(100);
2070*4882a593Smuzhiyun 		}
2071*4882a593Smuzhiyun 		retry++;
2072*4882a593Smuzhiyun 		if (retry < max_retry)
2073*4882a593Smuzhiyun 			hw_dbg(hw, "I2C byte read error - Retrying.\n");
2074*4882a593Smuzhiyun 		else
2075*4882a593Smuzhiyun 			hw_dbg(hw, "I2C byte read error.\n");
2076*4882a593Smuzhiyun 
2077*4882a593Smuzhiyun 	} while (retry < max_retry);
2078*4882a593Smuzhiyun 
2079*4882a593Smuzhiyun 	return status;
2080*4882a593Smuzhiyun }
2081*4882a593Smuzhiyun 
2082*4882a593Smuzhiyun /**
2083*4882a593Smuzhiyun  *  ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
2084*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2085*4882a593Smuzhiyun  *  @byte_offset: byte offset to read
2086*4882a593Smuzhiyun  *  @dev_addr: device address
2087*4882a593Smuzhiyun  *  @data: value read
2088*4882a593Smuzhiyun  *
2089*4882a593Smuzhiyun  *  Performs byte read operation to SFP module's EEPROM over I2C interface at
2090*4882a593Smuzhiyun  *  a specified device address.
2091*4882a593Smuzhiyun  */
ixgbe_read_i2c_byte_generic(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 * data)2092*4882a593Smuzhiyun s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
2093*4882a593Smuzhiyun 				u8 dev_addr, u8 *data)
2094*4882a593Smuzhiyun {
2095*4882a593Smuzhiyun 	return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr,
2096*4882a593Smuzhiyun 					       data, true);
2097*4882a593Smuzhiyun }
2098*4882a593Smuzhiyun 
2099*4882a593Smuzhiyun /**
2100*4882a593Smuzhiyun  *  ixgbe_read_i2c_byte_generic_unlocked - Reads 8 bit word over I2C
2101*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2102*4882a593Smuzhiyun  *  @byte_offset: byte offset to read
2103*4882a593Smuzhiyun  *  @dev_addr: device address
2104*4882a593Smuzhiyun  *  @data: value read
2105*4882a593Smuzhiyun  *
2106*4882a593Smuzhiyun  *  Performs byte read operation to SFP module's EEPROM over I2C interface at
2107*4882a593Smuzhiyun  *  a specified device address.
2108*4882a593Smuzhiyun  */
ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 * data)2109*4882a593Smuzhiyun s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
2110*4882a593Smuzhiyun 					 u8 dev_addr, u8 *data)
2111*4882a593Smuzhiyun {
2112*4882a593Smuzhiyun 	return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr,
2113*4882a593Smuzhiyun 					       data, false);
2114*4882a593Smuzhiyun }
2115*4882a593Smuzhiyun 
2116*4882a593Smuzhiyun /**
2117*4882a593Smuzhiyun  *  ixgbe_write_i2c_byte_generic_int - Writes 8 bit word over I2C
2118*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2119*4882a593Smuzhiyun  *  @byte_offset: byte offset to write
2120*4882a593Smuzhiyun  *  @dev_addr: device address
2121*4882a593Smuzhiyun  *  @data: value to write
2122*4882a593Smuzhiyun  *  @lock: true if to take and release semaphore
2123*4882a593Smuzhiyun  *
2124*4882a593Smuzhiyun  *  Performs byte write operation to SFP module's EEPROM over I2C interface at
2125*4882a593Smuzhiyun  *  a specified device address.
2126*4882a593Smuzhiyun  */
ixgbe_write_i2c_byte_generic_int(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 data,bool lock)2127*4882a593Smuzhiyun static s32 ixgbe_write_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset,
2128*4882a593Smuzhiyun 					    u8 dev_addr, u8 data, bool lock)
2129*4882a593Smuzhiyun {
2130*4882a593Smuzhiyun 	s32 status;
2131*4882a593Smuzhiyun 	u32 max_retry = 1;
2132*4882a593Smuzhiyun 	u32 retry = 0;
2133*4882a593Smuzhiyun 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
2134*4882a593Smuzhiyun 
2135*4882a593Smuzhiyun 	if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
2136*4882a593Smuzhiyun 		return IXGBE_ERR_SWFW_SYNC;
2137*4882a593Smuzhiyun 
2138*4882a593Smuzhiyun 	do {
2139*4882a593Smuzhiyun 		ixgbe_i2c_start(hw);
2140*4882a593Smuzhiyun 
2141*4882a593Smuzhiyun 		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
2142*4882a593Smuzhiyun 		if (status != 0)
2143*4882a593Smuzhiyun 			goto fail;
2144*4882a593Smuzhiyun 
2145*4882a593Smuzhiyun 		status = ixgbe_get_i2c_ack(hw);
2146*4882a593Smuzhiyun 		if (status != 0)
2147*4882a593Smuzhiyun 			goto fail;
2148*4882a593Smuzhiyun 
2149*4882a593Smuzhiyun 		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
2150*4882a593Smuzhiyun 		if (status != 0)
2151*4882a593Smuzhiyun 			goto fail;
2152*4882a593Smuzhiyun 
2153*4882a593Smuzhiyun 		status = ixgbe_get_i2c_ack(hw);
2154*4882a593Smuzhiyun 		if (status != 0)
2155*4882a593Smuzhiyun 			goto fail;
2156*4882a593Smuzhiyun 
2157*4882a593Smuzhiyun 		status = ixgbe_clock_out_i2c_byte(hw, data);
2158*4882a593Smuzhiyun 		if (status != 0)
2159*4882a593Smuzhiyun 			goto fail;
2160*4882a593Smuzhiyun 
2161*4882a593Smuzhiyun 		status = ixgbe_get_i2c_ack(hw);
2162*4882a593Smuzhiyun 		if (status != 0)
2163*4882a593Smuzhiyun 			goto fail;
2164*4882a593Smuzhiyun 
2165*4882a593Smuzhiyun 		ixgbe_i2c_stop(hw);
2166*4882a593Smuzhiyun 		if (lock)
2167*4882a593Smuzhiyun 			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2168*4882a593Smuzhiyun 		return 0;
2169*4882a593Smuzhiyun 
2170*4882a593Smuzhiyun fail:
2171*4882a593Smuzhiyun 		ixgbe_i2c_bus_clear(hw);
2172*4882a593Smuzhiyun 		retry++;
2173*4882a593Smuzhiyun 		if (retry < max_retry)
2174*4882a593Smuzhiyun 			hw_dbg(hw, "I2C byte write error - Retrying.\n");
2175*4882a593Smuzhiyun 		else
2176*4882a593Smuzhiyun 			hw_dbg(hw, "I2C byte write error.\n");
2177*4882a593Smuzhiyun 	} while (retry < max_retry);
2178*4882a593Smuzhiyun 
2179*4882a593Smuzhiyun 	if (lock)
2180*4882a593Smuzhiyun 		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2181*4882a593Smuzhiyun 
2182*4882a593Smuzhiyun 	return status;
2183*4882a593Smuzhiyun }
2184*4882a593Smuzhiyun 
2185*4882a593Smuzhiyun /**
2186*4882a593Smuzhiyun  *  ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
2187*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2188*4882a593Smuzhiyun  *  @byte_offset: byte offset to write
2189*4882a593Smuzhiyun  *  @dev_addr: device address
2190*4882a593Smuzhiyun  *  @data: value to write
2191*4882a593Smuzhiyun  *
2192*4882a593Smuzhiyun  *  Performs byte write operation to SFP module's EEPROM over I2C interface at
2193*4882a593Smuzhiyun  *  a specified device address.
2194*4882a593Smuzhiyun  */
ixgbe_write_i2c_byte_generic(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 data)2195*4882a593Smuzhiyun s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
2196*4882a593Smuzhiyun 				 u8 dev_addr, u8 data)
2197*4882a593Smuzhiyun {
2198*4882a593Smuzhiyun 	return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr,
2199*4882a593Smuzhiyun 						data, true);
2200*4882a593Smuzhiyun }
2201*4882a593Smuzhiyun 
2202*4882a593Smuzhiyun /**
2203*4882a593Smuzhiyun  *  ixgbe_write_i2c_byte_generic_unlocked - Writes 8 bit word over I2C
2204*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2205*4882a593Smuzhiyun  *  @byte_offset: byte offset to write
2206*4882a593Smuzhiyun  *  @dev_addr: device address
2207*4882a593Smuzhiyun  *  @data: value to write
2208*4882a593Smuzhiyun  *
2209*4882a593Smuzhiyun  *  Performs byte write operation to SFP module's EEPROM over I2C interface at
2210*4882a593Smuzhiyun  *  a specified device address.
2211*4882a593Smuzhiyun  */
ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw * hw,u8 byte_offset,u8 dev_addr,u8 data)2212*4882a593Smuzhiyun s32 ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
2213*4882a593Smuzhiyun 					  u8 dev_addr, u8 data)
2214*4882a593Smuzhiyun {
2215*4882a593Smuzhiyun 	return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr,
2216*4882a593Smuzhiyun 						data, false);
2217*4882a593Smuzhiyun }
2218*4882a593Smuzhiyun 
2219*4882a593Smuzhiyun /**
2220*4882a593Smuzhiyun  *  ixgbe_i2c_start - Sets I2C start condition
2221*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2222*4882a593Smuzhiyun  *
2223*4882a593Smuzhiyun  *  Sets I2C start condition (High -> Low on SDA while SCL is High)
2224*4882a593Smuzhiyun  *  Set bit-bang mode on X550 hardware.
2225*4882a593Smuzhiyun  **/
ixgbe_i2c_start(struct ixgbe_hw * hw)2226*4882a593Smuzhiyun static void ixgbe_i2c_start(struct ixgbe_hw *hw)
2227*4882a593Smuzhiyun {
2228*4882a593Smuzhiyun 	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
2229*4882a593Smuzhiyun 
2230*4882a593Smuzhiyun 	i2cctl |= IXGBE_I2C_BB_EN(hw);
2231*4882a593Smuzhiyun 
2232*4882a593Smuzhiyun 	/* Start condition must begin with data and clock high */
2233*4882a593Smuzhiyun 	ixgbe_set_i2c_data(hw, &i2cctl, 1);
2234*4882a593Smuzhiyun 	ixgbe_raise_i2c_clk(hw, &i2cctl);
2235*4882a593Smuzhiyun 
2236*4882a593Smuzhiyun 	/* Setup time for start condition (4.7us) */
2237*4882a593Smuzhiyun 	udelay(IXGBE_I2C_T_SU_STA);
2238*4882a593Smuzhiyun 
2239*4882a593Smuzhiyun 	ixgbe_set_i2c_data(hw, &i2cctl, 0);
2240*4882a593Smuzhiyun 
2241*4882a593Smuzhiyun 	/* Hold time for start condition (4us) */
2242*4882a593Smuzhiyun 	udelay(IXGBE_I2C_T_HD_STA);
2243*4882a593Smuzhiyun 
2244*4882a593Smuzhiyun 	ixgbe_lower_i2c_clk(hw, &i2cctl);
2245*4882a593Smuzhiyun 
2246*4882a593Smuzhiyun 	/* Minimum low period of clock is 4.7 us */
2247*4882a593Smuzhiyun 	udelay(IXGBE_I2C_T_LOW);
2248*4882a593Smuzhiyun 
2249*4882a593Smuzhiyun }
2250*4882a593Smuzhiyun 
2251*4882a593Smuzhiyun /**
2252*4882a593Smuzhiyun  *  ixgbe_i2c_stop - Sets I2C stop condition
2253*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2254*4882a593Smuzhiyun  *
2255*4882a593Smuzhiyun  *  Sets I2C stop condition (Low -> High on SDA while SCL is High)
2256*4882a593Smuzhiyun  *  Disables bit-bang mode and negates data output enable on X550
2257*4882a593Smuzhiyun  *  hardware.
2258*4882a593Smuzhiyun  **/
ixgbe_i2c_stop(struct ixgbe_hw * hw)2259*4882a593Smuzhiyun static void ixgbe_i2c_stop(struct ixgbe_hw *hw)
2260*4882a593Smuzhiyun {
2261*4882a593Smuzhiyun 	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
2262*4882a593Smuzhiyun 	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN(hw);
2263*4882a593Smuzhiyun 	u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN(hw);
2264*4882a593Smuzhiyun 	u32 bb_en_bit = IXGBE_I2C_BB_EN(hw);
2265*4882a593Smuzhiyun 
2266*4882a593Smuzhiyun 	/* Stop condition must begin with data low and clock high */
2267*4882a593Smuzhiyun 	ixgbe_set_i2c_data(hw, &i2cctl, 0);
2268*4882a593Smuzhiyun 	ixgbe_raise_i2c_clk(hw, &i2cctl);
2269*4882a593Smuzhiyun 
2270*4882a593Smuzhiyun 	/* Setup time for stop condition (4us) */
2271*4882a593Smuzhiyun 	udelay(IXGBE_I2C_T_SU_STO);
2272*4882a593Smuzhiyun 
2273*4882a593Smuzhiyun 	ixgbe_set_i2c_data(hw, &i2cctl, 1);
2274*4882a593Smuzhiyun 
2275*4882a593Smuzhiyun 	/* bus free time between stop and start (4.7us)*/
2276*4882a593Smuzhiyun 	udelay(IXGBE_I2C_T_BUF);
2277*4882a593Smuzhiyun 
2278*4882a593Smuzhiyun 	if (bb_en_bit || data_oe_bit || clk_oe_bit) {
2279*4882a593Smuzhiyun 		i2cctl &= ~bb_en_bit;
2280*4882a593Smuzhiyun 		i2cctl |= data_oe_bit | clk_oe_bit;
2281*4882a593Smuzhiyun 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), i2cctl);
2282*4882a593Smuzhiyun 		IXGBE_WRITE_FLUSH(hw);
2283*4882a593Smuzhiyun 	}
2284*4882a593Smuzhiyun }
2285*4882a593Smuzhiyun 
2286*4882a593Smuzhiyun /**
2287*4882a593Smuzhiyun  *  ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C
2288*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2289*4882a593Smuzhiyun  *  @data: data byte to clock in
2290*4882a593Smuzhiyun  *
2291*4882a593Smuzhiyun  *  Clocks in one byte data via I2C data/clock
2292*4882a593Smuzhiyun  **/
ixgbe_clock_in_i2c_byte(struct ixgbe_hw * hw,u8 * data)2293*4882a593Smuzhiyun static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
2294*4882a593Smuzhiyun {
2295*4882a593Smuzhiyun 	s32 i;
2296*4882a593Smuzhiyun 	bool bit = false;
2297*4882a593Smuzhiyun 
2298*4882a593Smuzhiyun 	*data = 0;
2299*4882a593Smuzhiyun 	for (i = 7; i >= 0; i--) {
2300*4882a593Smuzhiyun 		ixgbe_clock_in_i2c_bit(hw, &bit);
2301*4882a593Smuzhiyun 		*data |= bit << i;
2302*4882a593Smuzhiyun 	}
2303*4882a593Smuzhiyun 
2304*4882a593Smuzhiyun 	return 0;
2305*4882a593Smuzhiyun }
2306*4882a593Smuzhiyun 
2307*4882a593Smuzhiyun /**
2308*4882a593Smuzhiyun  *  ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C
2309*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2310*4882a593Smuzhiyun  *  @data: data byte clocked out
2311*4882a593Smuzhiyun  *
2312*4882a593Smuzhiyun  *  Clocks out one byte data via I2C data/clock
2313*4882a593Smuzhiyun  **/
ixgbe_clock_out_i2c_byte(struct ixgbe_hw * hw,u8 data)2314*4882a593Smuzhiyun static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
2315*4882a593Smuzhiyun {
2316*4882a593Smuzhiyun 	s32 status;
2317*4882a593Smuzhiyun 	s32 i;
2318*4882a593Smuzhiyun 	u32 i2cctl;
2319*4882a593Smuzhiyun 	bool bit = false;
2320*4882a593Smuzhiyun 
2321*4882a593Smuzhiyun 	for (i = 7; i >= 0; i--) {
2322*4882a593Smuzhiyun 		bit = (data >> i) & 0x1;
2323*4882a593Smuzhiyun 		status = ixgbe_clock_out_i2c_bit(hw, bit);
2324*4882a593Smuzhiyun 
2325*4882a593Smuzhiyun 		if (status != 0)
2326*4882a593Smuzhiyun 			break;
2327*4882a593Smuzhiyun 	}
2328*4882a593Smuzhiyun 
2329*4882a593Smuzhiyun 	/* Release SDA line (set high) */
2330*4882a593Smuzhiyun 	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
2331*4882a593Smuzhiyun 	i2cctl |= IXGBE_I2C_DATA_OUT(hw);
2332*4882a593Smuzhiyun 	i2cctl |= IXGBE_I2C_DATA_OE_N_EN(hw);
2333*4882a593Smuzhiyun 	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), i2cctl);
2334*4882a593Smuzhiyun 	IXGBE_WRITE_FLUSH(hw);
2335*4882a593Smuzhiyun 
2336*4882a593Smuzhiyun 	return status;
2337*4882a593Smuzhiyun }
2338*4882a593Smuzhiyun 
2339*4882a593Smuzhiyun /**
2340*4882a593Smuzhiyun  *  ixgbe_get_i2c_ack - Polls for I2C ACK
2341*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2342*4882a593Smuzhiyun  *
2343*4882a593Smuzhiyun  *  Clocks in/out one bit via I2C data/clock
2344*4882a593Smuzhiyun  **/
ixgbe_get_i2c_ack(struct ixgbe_hw * hw)2345*4882a593Smuzhiyun static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
2346*4882a593Smuzhiyun {
2347*4882a593Smuzhiyun 	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN(hw);
2348*4882a593Smuzhiyun 	s32 status = 0;
2349*4882a593Smuzhiyun 	u32 i = 0;
2350*4882a593Smuzhiyun 	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
2351*4882a593Smuzhiyun 	u32 timeout = 10;
2352*4882a593Smuzhiyun 	bool ack = true;
2353*4882a593Smuzhiyun 
2354*4882a593Smuzhiyun 	if (data_oe_bit) {
2355*4882a593Smuzhiyun 		i2cctl |= IXGBE_I2C_DATA_OUT(hw);
2356*4882a593Smuzhiyun 		i2cctl |= data_oe_bit;
2357*4882a593Smuzhiyun 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), i2cctl);
2358*4882a593Smuzhiyun 		IXGBE_WRITE_FLUSH(hw);
2359*4882a593Smuzhiyun 	}
2360*4882a593Smuzhiyun 	ixgbe_raise_i2c_clk(hw, &i2cctl);
2361*4882a593Smuzhiyun 
2362*4882a593Smuzhiyun 	/* Minimum high period of clock is 4us */
2363*4882a593Smuzhiyun 	udelay(IXGBE_I2C_T_HIGH);
2364*4882a593Smuzhiyun 
2365*4882a593Smuzhiyun 	/* Poll for ACK.  Note that ACK in I2C spec is
2366*4882a593Smuzhiyun 	 * transition from 1 to 0 */
2367*4882a593Smuzhiyun 	for (i = 0; i < timeout; i++) {
2368*4882a593Smuzhiyun 		i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
2369*4882a593Smuzhiyun 		ack = ixgbe_get_i2c_data(hw, &i2cctl);
2370*4882a593Smuzhiyun 
2371*4882a593Smuzhiyun 		udelay(1);
2372*4882a593Smuzhiyun 		if (ack == 0)
2373*4882a593Smuzhiyun 			break;
2374*4882a593Smuzhiyun 	}
2375*4882a593Smuzhiyun 
2376*4882a593Smuzhiyun 	if (ack == 1) {
2377*4882a593Smuzhiyun 		hw_dbg(hw, "I2C ack was not received.\n");
2378*4882a593Smuzhiyun 		status = IXGBE_ERR_I2C;
2379*4882a593Smuzhiyun 	}
2380*4882a593Smuzhiyun 
2381*4882a593Smuzhiyun 	ixgbe_lower_i2c_clk(hw, &i2cctl);
2382*4882a593Smuzhiyun 
2383*4882a593Smuzhiyun 	/* Minimum low period of clock is 4.7 us */
2384*4882a593Smuzhiyun 	udelay(IXGBE_I2C_T_LOW);
2385*4882a593Smuzhiyun 
2386*4882a593Smuzhiyun 	return status;
2387*4882a593Smuzhiyun }
2388*4882a593Smuzhiyun 
2389*4882a593Smuzhiyun /**
2390*4882a593Smuzhiyun  *  ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
2391*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2392*4882a593Smuzhiyun  *  @data: read data value
2393*4882a593Smuzhiyun  *
2394*4882a593Smuzhiyun  *  Clocks in one bit via I2C data/clock
2395*4882a593Smuzhiyun  **/
ixgbe_clock_in_i2c_bit(struct ixgbe_hw * hw,bool * data)2396*4882a593Smuzhiyun static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
2397*4882a593Smuzhiyun {
2398*4882a593Smuzhiyun 	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
2399*4882a593Smuzhiyun 	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN(hw);
2400*4882a593Smuzhiyun 
2401*4882a593Smuzhiyun 	if (data_oe_bit) {
2402*4882a593Smuzhiyun 		i2cctl |= IXGBE_I2C_DATA_OUT(hw);
2403*4882a593Smuzhiyun 		i2cctl |= data_oe_bit;
2404*4882a593Smuzhiyun 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), i2cctl);
2405*4882a593Smuzhiyun 		IXGBE_WRITE_FLUSH(hw);
2406*4882a593Smuzhiyun 	}
2407*4882a593Smuzhiyun 	ixgbe_raise_i2c_clk(hw, &i2cctl);
2408*4882a593Smuzhiyun 
2409*4882a593Smuzhiyun 	/* Minimum high period of clock is 4us */
2410*4882a593Smuzhiyun 	udelay(IXGBE_I2C_T_HIGH);
2411*4882a593Smuzhiyun 
2412*4882a593Smuzhiyun 	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
2413*4882a593Smuzhiyun 	*data = ixgbe_get_i2c_data(hw, &i2cctl);
2414*4882a593Smuzhiyun 
2415*4882a593Smuzhiyun 	ixgbe_lower_i2c_clk(hw, &i2cctl);
2416*4882a593Smuzhiyun 
2417*4882a593Smuzhiyun 	/* Minimum low period of clock is 4.7 us */
2418*4882a593Smuzhiyun 	udelay(IXGBE_I2C_T_LOW);
2419*4882a593Smuzhiyun 
2420*4882a593Smuzhiyun 	return 0;
2421*4882a593Smuzhiyun }
2422*4882a593Smuzhiyun 
2423*4882a593Smuzhiyun /**
2424*4882a593Smuzhiyun  *  ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
2425*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2426*4882a593Smuzhiyun  *  @data: data value to write
2427*4882a593Smuzhiyun  *
2428*4882a593Smuzhiyun  *  Clocks out one bit via I2C data/clock
2429*4882a593Smuzhiyun  **/
ixgbe_clock_out_i2c_bit(struct ixgbe_hw * hw,bool data)2430*4882a593Smuzhiyun static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
2431*4882a593Smuzhiyun {
2432*4882a593Smuzhiyun 	s32 status;
2433*4882a593Smuzhiyun 	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
2434*4882a593Smuzhiyun 
2435*4882a593Smuzhiyun 	status = ixgbe_set_i2c_data(hw, &i2cctl, data);
2436*4882a593Smuzhiyun 	if (status == 0) {
2437*4882a593Smuzhiyun 		ixgbe_raise_i2c_clk(hw, &i2cctl);
2438*4882a593Smuzhiyun 
2439*4882a593Smuzhiyun 		/* Minimum high period of clock is 4us */
2440*4882a593Smuzhiyun 		udelay(IXGBE_I2C_T_HIGH);
2441*4882a593Smuzhiyun 
2442*4882a593Smuzhiyun 		ixgbe_lower_i2c_clk(hw, &i2cctl);
2443*4882a593Smuzhiyun 
2444*4882a593Smuzhiyun 		/* Minimum low period of clock is 4.7 us.
2445*4882a593Smuzhiyun 		 * This also takes care of the data hold time.
2446*4882a593Smuzhiyun 		 */
2447*4882a593Smuzhiyun 		udelay(IXGBE_I2C_T_LOW);
2448*4882a593Smuzhiyun 	} else {
2449*4882a593Smuzhiyun 		hw_dbg(hw, "I2C data was not set to %X\n", data);
2450*4882a593Smuzhiyun 		return IXGBE_ERR_I2C;
2451*4882a593Smuzhiyun 	}
2452*4882a593Smuzhiyun 
2453*4882a593Smuzhiyun 	return 0;
2454*4882a593Smuzhiyun }
2455*4882a593Smuzhiyun /**
2456*4882a593Smuzhiyun  *  ixgbe_raise_i2c_clk - Raises the I2C SCL clock
2457*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2458*4882a593Smuzhiyun  *  @i2cctl: Current value of I2CCTL register
2459*4882a593Smuzhiyun  *
2460*4882a593Smuzhiyun  *  Raises the I2C clock line '0'->'1'
2461*4882a593Smuzhiyun  *  Negates the I2C clock output enable on X550 hardware.
2462*4882a593Smuzhiyun  **/
ixgbe_raise_i2c_clk(struct ixgbe_hw * hw,u32 * i2cctl)2463*4882a593Smuzhiyun static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
2464*4882a593Smuzhiyun {
2465*4882a593Smuzhiyun 	u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN(hw);
2466*4882a593Smuzhiyun 	u32 i = 0;
2467*4882a593Smuzhiyun 	u32 timeout = IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT;
2468*4882a593Smuzhiyun 	u32 i2cctl_r = 0;
2469*4882a593Smuzhiyun 
2470*4882a593Smuzhiyun 	if (clk_oe_bit) {
2471*4882a593Smuzhiyun 		*i2cctl |= clk_oe_bit;
2472*4882a593Smuzhiyun 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
2473*4882a593Smuzhiyun 	}
2474*4882a593Smuzhiyun 
2475*4882a593Smuzhiyun 	for (i = 0; i < timeout; i++) {
2476*4882a593Smuzhiyun 		*i2cctl |= IXGBE_I2C_CLK_OUT(hw);
2477*4882a593Smuzhiyun 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
2478*4882a593Smuzhiyun 		IXGBE_WRITE_FLUSH(hw);
2479*4882a593Smuzhiyun 		/* SCL rise time (1000ns) */
2480*4882a593Smuzhiyun 		udelay(IXGBE_I2C_T_RISE);
2481*4882a593Smuzhiyun 
2482*4882a593Smuzhiyun 		i2cctl_r = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
2483*4882a593Smuzhiyun 		if (i2cctl_r & IXGBE_I2C_CLK_IN(hw))
2484*4882a593Smuzhiyun 			break;
2485*4882a593Smuzhiyun 	}
2486*4882a593Smuzhiyun }
2487*4882a593Smuzhiyun 
2488*4882a593Smuzhiyun /**
2489*4882a593Smuzhiyun  *  ixgbe_lower_i2c_clk - Lowers the I2C SCL clock
2490*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2491*4882a593Smuzhiyun  *  @i2cctl: Current value of I2CCTL register
2492*4882a593Smuzhiyun  *
2493*4882a593Smuzhiyun  *  Lowers the I2C clock line '1'->'0'
2494*4882a593Smuzhiyun  *  Asserts the I2C clock output enable on X550 hardware.
2495*4882a593Smuzhiyun  **/
ixgbe_lower_i2c_clk(struct ixgbe_hw * hw,u32 * i2cctl)2496*4882a593Smuzhiyun static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
2497*4882a593Smuzhiyun {
2498*4882a593Smuzhiyun 
2499*4882a593Smuzhiyun 	*i2cctl &= ~IXGBE_I2C_CLK_OUT(hw);
2500*4882a593Smuzhiyun 	*i2cctl &= ~IXGBE_I2C_CLK_OE_N_EN(hw);
2501*4882a593Smuzhiyun 
2502*4882a593Smuzhiyun 	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
2503*4882a593Smuzhiyun 	IXGBE_WRITE_FLUSH(hw);
2504*4882a593Smuzhiyun 
2505*4882a593Smuzhiyun 	/* SCL fall time (300ns) */
2506*4882a593Smuzhiyun 	udelay(IXGBE_I2C_T_FALL);
2507*4882a593Smuzhiyun }
2508*4882a593Smuzhiyun 
2509*4882a593Smuzhiyun /**
2510*4882a593Smuzhiyun  *  ixgbe_set_i2c_data - Sets the I2C data bit
2511*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2512*4882a593Smuzhiyun  *  @i2cctl: Current value of I2CCTL register
2513*4882a593Smuzhiyun  *  @data: I2C data value (0 or 1) to set
2514*4882a593Smuzhiyun  *
2515*4882a593Smuzhiyun  *  Sets the I2C data bit
2516*4882a593Smuzhiyun  *  Asserts the I2C data output enable on X550 hardware.
2517*4882a593Smuzhiyun  **/
ixgbe_set_i2c_data(struct ixgbe_hw * hw,u32 * i2cctl,bool data)2518*4882a593Smuzhiyun static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
2519*4882a593Smuzhiyun {
2520*4882a593Smuzhiyun 	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN(hw);
2521*4882a593Smuzhiyun 
2522*4882a593Smuzhiyun 	if (data)
2523*4882a593Smuzhiyun 		*i2cctl |= IXGBE_I2C_DATA_OUT(hw);
2524*4882a593Smuzhiyun 	else
2525*4882a593Smuzhiyun 		*i2cctl &= ~IXGBE_I2C_DATA_OUT(hw);
2526*4882a593Smuzhiyun 	*i2cctl &= ~data_oe_bit;
2527*4882a593Smuzhiyun 
2528*4882a593Smuzhiyun 	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
2529*4882a593Smuzhiyun 	IXGBE_WRITE_FLUSH(hw);
2530*4882a593Smuzhiyun 
2531*4882a593Smuzhiyun 	/* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
2532*4882a593Smuzhiyun 	udelay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
2533*4882a593Smuzhiyun 
2534*4882a593Smuzhiyun 	if (!data)	/* Can't verify data in this case */
2535*4882a593Smuzhiyun 		return 0;
2536*4882a593Smuzhiyun 	if (data_oe_bit) {
2537*4882a593Smuzhiyun 		*i2cctl |= data_oe_bit;
2538*4882a593Smuzhiyun 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
2539*4882a593Smuzhiyun 		IXGBE_WRITE_FLUSH(hw);
2540*4882a593Smuzhiyun 	}
2541*4882a593Smuzhiyun 
2542*4882a593Smuzhiyun 	/* Verify data was set correctly */
2543*4882a593Smuzhiyun 	*i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
2544*4882a593Smuzhiyun 	if (data != ixgbe_get_i2c_data(hw, i2cctl)) {
2545*4882a593Smuzhiyun 		hw_dbg(hw, "Error - I2C data was not set to %X.\n", data);
2546*4882a593Smuzhiyun 		return IXGBE_ERR_I2C;
2547*4882a593Smuzhiyun 	}
2548*4882a593Smuzhiyun 
2549*4882a593Smuzhiyun 	return 0;
2550*4882a593Smuzhiyun }
2551*4882a593Smuzhiyun 
2552*4882a593Smuzhiyun /**
2553*4882a593Smuzhiyun  *  ixgbe_get_i2c_data - Reads the I2C SDA data bit
2554*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2555*4882a593Smuzhiyun  *  @i2cctl: Current value of I2CCTL register
2556*4882a593Smuzhiyun  *
2557*4882a593Smuzhiyun  *  Returns the I2C data bit value
2558*4882a593Smuzhiyun  *  Negates the I2C data output enable on X550 hardware.
2559*4882a593Smuzhiyun  **/
ixgbe_get_i2c_data(struct ixgbe_hw * hw,u32 * i2cctl)2560*4882a593Smuzhiyun static bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl)
2561*4882a593Smuzhiyun {
2562*4882a593Smuzhiyun 	u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN(hw);
2563*4882a593Smuzhiyun 
2564*4882a593Smuzhiyun 	if (data_oe_bit) {
2565*4882a593Smuzhiyun 		*i2cctl |= data_oe_bit;
2566*4882a593Smuzhiyun 		IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
2567*4882a593Smuzhiyun 		IXGBE_WRITE_FLUSH(hw);
2568*4882a593Smuzhiyun 		udelay(IXGBE_I2C_T_FALL);
2569*4882a593Smuzhiyun 	}
2570*4882a593Smuzhiyun 
2571*4882a593Smuzhiyun 	if (*i2cctl & IXGBE_I2C_DATA_IN(hw))
2572*4882a593Smuzhiyun 		return true;
2573*4882a593Smuzhiyun 	return false;
2574*4882a593Smuzhiyun }
2575*4882a593Smuzhiyun 
2576*4882a593Smuzhiyun /**
2577*4882a593Smuzhiyun  *  ixgbe_i2c_bus_clear - Clears the I2C bus
2578*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2579*4882a593Smuzhiyun  *
2580*4882a593Smuzhiyun  *  Clears the I2C bus by sending nine clock pulses.
2581*4882a593Smuzhiyun  *  Used when data line is stuck low.
2582*4882a593Smuzhiyun  **/
ixgbe_i2c_bus_clear(struct ixgbe_hw * hw)2583*4882a593Smuzhiyun static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
2584*4882a593Smuzhiyun {
2585*4882a593Smuzhiyun 	u32 i2cctl;
2586*4882a593Smuzhiyun 	u32 i;
2587*4882a593Smuzhiyun 
2588*4882a593Smuzhiyun 	ixgbe_i2c_start(hw);
2589*4882a593Smuzhiyun 	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
2590*4882a593Smuzhiyun 
2591*4882a593Smuzhiyun 	ixgbe_set_i2c_data(hw, &i2cctl, 1);
2592*4882a593Smuzhiyun 
2593*4882a593Smuzhiyun 	for (i = 0; i < 9; i++) {
2594*4882a593Smuzhiyun 		ixgbe_raise_i2c_clk(hw, &i2cctl);
2595*4882a593Smuzhiyun 
2596*4882a593Smuzhiyun 		/* Min high period of clock is 4us */
2597*4882a593Smuzhiyun 		udelay(IXGBE_I2C_T_HIGH);
2598*4882a593Smuzhiyun 
2599*4882a593Smuzhiyun 		ixgbe_lower_i2c_clk(hw, &i2cctl);
2600*4882a593Smuzhiyun 
2601*4882a593Smuzhiyun 		/* Min low period of clock is 4.7us*/
2602*4882a593Smuzhiyun 		udelay(IXGBE_I2C_T_LOW);
2603*4882a593Smuzhiyun 	}
2604*4882a593Smuzhiyun 
2605*4882a593Smuzhiyun 	ixgbe_i2c_start(hw);
2606*4882a593Smuzhiyun 
2607*4882a593Smuzhiyun 	/* Put the i2c bus back to default state */
2608*4882a593Smuzhiyun 	ixgbe_i2c_stop(hw);
2609*4882a593Smuzhiyun }
2610*4882a593Smuzhiyun 
2611*4882a593Smuzhiyun /**
2612*4882a593Smuzhiyun  *  ixgbe_tn_check_overtemp - Checks if an overtemp occurred.
2613*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2614*4882a593Smuzhiyun  *
2615*4882a593Smuzhiyun  *  Checks if the LASI temp alarm status was triggered due to overtemp
2616*4882a593Smuzhiyun  **/
ixgbe_tn_check_overtemp(struct ixgbe_hw * hw)2617*4882a593Smuzhiyun s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
2618*4882a593Smuzhiyun {
2619*4882a593Smuzhiyun 	u16 phy_data = 0;
2620*4882a593Smuzhiyun 
2621*4882a593Smuzhiyun 	if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM)
2622*4882a593Smuzhiyun 		return 0;
2623*4882a593Smuzhiyun 
2624*4882a593Smuzhiyun 	/* Check that the LASI temp alarm status was triggered */
2625*4882a593Smuzhiyun 	hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
2626*4882a593Smuzhiyun 			     MDIO_MMD_PMAPMD, &phy_data);
2627*4882a593Smuzhiyun 
2628*4882a593Smuzhiyun 	if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM))
2629*4882a593Smuzhiyun 		return 0;
2630*4882a593Smuzhiyun 
2631*4882a593Smuzhiyun 	return IXGBE_ERR_OVERTEMP;
2632*4882a593Smuzhiyun }
2633*4882a593Smuzhiyun 
2634*4882a593Smuzhiyun /** ixgbe_set_copper_phy_power - Control power for copper phy
2635*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
2636*4882a593Smuzhiyun  *  @on: true for on, false for off
2637*4882a593Smuzhiyun  **/
ixgbe_set_copper_phy_power(struct ixgbe_hw * hw,bool on)2638*4882a593Smuzhiyun s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on)
2639*4882a593Smuzhiyun {
2640*4882a593Smuzhiyun 	u32 status;
2641*4882a593Smuzhiyun 	u16 reg;
2642*4882a593Smuzhiyun 
2643*4882a593Smuzhiyun 	/* Bail if we don't have copper phy */
2644*4882a593Smuzhiyun 	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
2645*4882a593Smuzhiyun 		return 0;
2646*4882a593Smuzhiyun 
2647*4882a593Smuzhiyun 	if (!on && ixgbe_mng_present(hw))
2648*4882a593Smuzhiyun 		return 0;
2649*4882a593Smuzhiyun 
2650*4882a593Smuzhiyun 	status = hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_VEND1, &reg);
2651*4882a593Smuzhiyun 	if (status)
2652*4882a593Smuzhiyun 		return status;
2653*4882a593Smuzhiyun 
2654*4882a593Smuzhiyun 	if (on) {
2655*4882a593Smuzhiyun 		reg &= ~IXGBE_MDIO_PHY_SET_LOW_POWER_MODE;
2656*4882a593Smuzhiyun 	} else {
2657*4882a593Smuzhiyun 		if (ixgbe_check_reset_blocked(hw))
2658*4882a593Smuzhiyun 			return 0;
2659*4882a593Smuzhiyun 		reg |= IXGBE_MDIO_PHY_SET_LOW_POWER_MODE;
2660*4882a593Smuzhiyun 	}
2661*4882a593Smuzhiyun 
2662*4882a593Smuzhiyun 	status = hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_VEND1, reg);
2663*4882a593Smuzhiyun 	return status;
2664*4882a593Smuzhiyun }
2665