xref: /titanic_41/usr/src/uts/common/io/ixgbe/ixgbe_phy.c (revision 0bb073995ac5a95bd35f2dd790df1ea3d8c2d507)
1 /*
2  * CDDL HEADER START
3  *
4  * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
5  * The contents of this file are subject to the terms of the
6  * Common Development and Distribution License (the "License").
7  * You may not use this file except in compliance with the License.
8  *
9  * You can obtain a copy of the license at:
10  *      http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When using or redistributing this file, you may do so under the
15  * License only. No other modification of this header is permitted.
16  *
17  * If applicable, add the following below this CDDL HEADER, with the
18  * fields enclosed by brackets "[]" replaced with your own identifying
19  * information: Portions Copyright [yyyy] [name of copyright owner]
20  *
21  * CDDL HEADER END
22  */
23 
24 /*
25  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms of the CDDL.
27  */
28 
29 /* IntelVersion: 1.37 v2008-03-04 */
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #include "ixgbe_api.h"
34 #include "ixgbe_common.h"
35 #include "ixgbe_phy.h"
36 
37 /*
38  * ixgbe_init_phy_ops_generic - Inits PHY function ptrs
39  * @hw: pointer to the hardware structure
40  *
41  * Initialize the function pointers.
42  */
43 s32
44 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
45 {
46 	struct ixgbe_phy_info *phy = &hw->phy;
47 
48 	/* PHY */
49 	phy->ops.identify = &ixgbe_identify_phy_generic;
50 	phy->ops.reset = &ixgbe_reset_phy_generic;
51 	phy->ops.read_reg = &ixgbe_read_phy_reg_generic;
52 	phy->ops.write_reg = &ixgbe_write_phy_reg_generic;
53 	phy->ops.setup_link = &ixgbe_setup_phy_link_generic;
54 	phy->ops.setup_link_speed = &ixgbe_setup_phy_link_speed_generic;
55 
56 	return (IXGBE_SUCCESS);
57 }
58 
59 /*
60  * ixgbe_identify_phy_generic - Get physical layer module
61  * @hw: pointer to hardware structure
62  *
63  * Determines the physical layer module found on the current adapter.
64  */
65 s32
66 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
67 {
68 	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
69 	u32 phy_addr;
70 
71 	if (hw->phy.type == ixgbe_phy_unknown) {
72 		for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
73 			if (ixgbe_validate_phy_addr(hw, phy_addr)) {
74 				hw->phy.addr = phy_addr;
75 				(void) ixgbe_get_phy_id(hw);
76 				hw->phy.type =
77 				    ixgbe_get_phy_type_from_id(hw->phy.id);
78 				status = IXGBE_SUCCESS;
79 				break;
80 			}
81 		}
82 	} else {
83 		status = IXGBE_SUCCESS;
84 	}
85 
86 	return (status);
87 }
88 
89 /*
90  * ixgbe_validate_phy_addr - Determines phy address is valid
91  * @hw: pointer to hardware structure
92  *
93  */
94 bool
95 ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr)
96 {
97 	u16 phy_id = 0;
98 	bool valid = FALSE;
99 
100 	hw->phy.addr = phy_addr;
101 	hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
102 	    IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id);
103 
104 	if (phy_id != 0xFFFF && phy_id != 0x0)
105 		valid = TRUE;
106 
107 	return (valid);
108 }
109 
110 /*
111  * ixgbe_get_phy_id - Get the phy type
112  * @hw: pointer to hardware structure
113  *
114  */
115 s32
116 ixgbe_get_phy_id(struct ixgbe_hw *hw)
117 {
118 	u32 status;
119 	u16 phy_id_high = 0;
120 	u16 phy_id_low = 0;
121 
122 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
123 	    IXGBE_MDIO_PMA_PMD_DEV_TYPE,
124 	    &phy_id_high);
125 
126 	if (status == IXGBE_SUCCESS) {
127 		hw->phy.id = (u32)(phy_id_high << 16);
128 		status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW,
129 		    IXGBE_MDIO_PMA_PMD_DEV_TYPE,
130 		    &phy_id_low);
131 		hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
132 		hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
133 	}
134 
135 	return (status);
136 }
137 
138 /*
139  * ixgbe_get_phy_type_from_id - Get the phy type
140  * @hw: pointer to hardware structure
141  *
142  */
143 enum ixgbe_phy_type
144 ixgbe_get_phy_type_from_id(u32 phy_id)
145 {
146 	enum ixgbe_phy_type phy_type;
147 
148 	switch (phy_id) {
149 	case QT2022_PHY_ID:
150 		phy_type = ixgbe_phy_qt;
151 		break;
152 	default:
153 		phy_type = ixgbe_phy_unknown;
154 		break;
155 	}
156 
157 	return (phy_type);
158 }
159 
160 /*
161  * ixgbe_reset_phy_generic - Performs a PHY reset
162  * @hw: pointer to hardware structure
163  */
164 s32
165 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
166 {
167 	/*
168 	 * Perform soft PHY reset to the PHY_XS.
169 	 * This will cause a soft reset to the PHY
170 	 */
171 	return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
172 	    IXGBE_MDIO_PHY_XS_DEV_TYPE,
173 	    IXGBE_MDIO_PHY_XS_RESET);
174 }
175 
176 /*
177  * ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register
178  * @hw: pointer to hardware structure
179  * @reg_addr: 32 bit address of PHY register to read
180  * @phy_data: Pointer to read data from PHY register
181  */
182 s32
183 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
184     u32 device_type, u16 *phy_data)
185 {
186 	u32 command;
187 	u32 i;
188 	u32 data;
189 	s32 status = IXGBE_SUCCESS;
190 	u16 gssr;
191 
192 	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
193 		gssr = IXGBE_GSSR_PHY1_SM;
194 	else
195 		gssr = IXGBE_GSSR_PHY0_SM;
196 
197 	if (ixgbe_acquire_swfw_sync(hw, gssr) != IXGBE_SUCCESS)
198 		status = IXGBE_ERR_SWFW_SYNC;
199 
200 	if (status == IXGBE_SUCCESS) {
201 		/* Setup and write the address cycle command */
202 		command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
203 		    (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
204 		    (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
205 		    (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
206 
207 		IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
208 
209 		/*
210 		 * Check every 10 usec to see if the address cycle completed.
211 		 * The MDI Command bit will clear when the operation is
212 		 * complete
213 		 */
214 		for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
215 			usec_delay(10);
216 
217 			command = IXGBE_READ_REG(hw, IXGBE_MSCA);
218 
219 			if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) {
220 				break;
221 			}
222 		}
223 
224 		if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
225 			DEBUGOUT("PHY address command did not complete.\n");
226 			status = IXGBE_ERR_PHY;
227 		}
228 
229 		if (status == IXGBE_SUCCESS) {
230 			/*
231 			 * Address cycle complete, setup and write the read
232 			 * command
233 			 */
234 			command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
235 			    (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
236 			    (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
237 			    (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
238 
239 			IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
240 
241 			/*
242 			 * Check every 10 usec to see if the address cycle
243 			 * completed. The MDI Command bit will clear when the
244 			 * operation is complete
245 			 */
246 			for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
247 				usec_delay(10);
248 
249 				command = IXGBE_READ_REG(hw, IXGBE_MSCA);
250 
251 				if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
252 					break;
253 			}
254 
255 			if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
256 				DEBUGOUT("PHY read command didn't complete\n");
257 				status = IXGBE_ERR_PHY;
258 			} else {
259 				/*
260 				 * Read operation is complete.  Get the data
261 				 * from MSRWD
262 				 */
263 				data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
264 				data >>= IXGBE_MSRWD_READ_DATA_SHIFT;
265 				*phy_data = (u16)(data);
266 			}
267 		}
268 
269 		ixgbe_release_swfw_sync(hw, gssr);
270 	}
271 
272 	return (status);
273 }
274 
275 /*
276  * ixgbe_write_phy_reg_generic - Writes a value to specified PHY register
277  * @hw: pointer to hardware structure
278  * @reg_addr: 32 bit PHY register to write
279  * @device_type: 5 bit device type
280  * @phy_data: Data to write to the PHY register
281  */
282 s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
283     u32 device_type, u16 phy_data)
284 {
285 	u32 command;
286 	u32 i;
287 	s32 status = IXGBE_SUCCESS;
288 	u16 gssr;
289 
290 	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
291 		gssr = IXGBE_GSSR_PHY1_SM;
292 	else
293 		gssr = IXGBE_GSSR_PHY0_SM;
294 
295 	if (ixgbe_acquire_swfw_sync(hw, gssr) != IXGBE_SUCCESS)
296 		status = IXGBE_ERR_SWFW_SYNC;
297 
298 	if (status == IXGBE_SUCCESS) {
299 		/*
300 		 * Put the data in the MDI single read and write data register
301 		 */
302 		IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data);
303 
304 		/* Setup and write the address cycle command */
305 		command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
306 		    (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
307 		    (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
308 		    (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
309 
310 		IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
311 
312 		/*
313 		 * Check every 10 usec to see if the address cycle completed.
314 		 * The MDI Command bit will clear when the operation is
315 		 * complete
316 		 */
317 		for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
318 			usec_delay(10);
319 
320 			command = IXGBE_READ_REG(hw, IXGBE_MSCA);
321 
322 			if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
323 				break;
324 		}
325 
326 		if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
327 			DEBUGOUT("PHY address cmd didn't complete\n");
328 			status = IXGBE_ERR_PHY;
329 		}
330 
331 		if (status == IXGBE_SUCCESS) {
332 			/*
333 			 * Address cycle complete, setup and write the write
334 			 * command
335 			 */
336 			command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
337 			    (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
338 			    (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
339 			    (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
340 
341 			IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
342 
343 			/*
344 			 * Check every 10 usec to see if the address cycle
345 			 * completed. The MDI Command bit will clear when the
346 			 * operation is complete
347 			 */
348 			for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
349 				usec_delay(10);
350 
351 				command = IXGBE_READ_REG(hw, IXGBE_MSCA);
352 
353 				if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
354 					break;
355 			}
356 
357 			if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
358 				DEBUGOUT("PHY address cmd didn't complete\n");
359 				status = IXGBE_ERR_PHY;
360 			}
361 		}
362 
363 		ixgbe_release_swfw_sync(hw, gssr);
364 	}
365 
366 	return (status);
367 }
368 
369 /*
370  * ixgbe_setup_phy_link_generic - Set and restart autoneg
371  * @hw: pointer to hardware structure
372  *
373  * Restart autonegotiation and PHY and waits for completion.
374  */
375 s32
376 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
377 {
378 	s32 status = IXGBE_NOT_IMPLEMENTED;
379 	u32 time_out;
380 	u32 max_time_out = 10;
381 	u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
382 
383 	/*
384 	 * Set advertisement settings in PHY based on autoneg_advertised
385 	 * settings. If autoneg_advertised = 0, then advertise default values
386 	 * tnx devices cannot be "forced" to a autoneg 10G and fail.  But can
387 	 * for a 1G.
388 	 */
389 	hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
390 	    IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
391 
392 	if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL)
393 		autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */
394 	else
395 		autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */
396 
397 	hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
398 	    IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
399 
400 	/* Restart PHY autonegotiation and wait for completion */
401 	hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
402 	    IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
403 
404 	autoneg_reg |= IXGBE_MII_RESTART;
405 
406 	hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
407 	    IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
408 
409 	/* Wait for autonegotiation to finish */
410 	for (time_out = 0; time_out < max_time_out; time_out++) {
411 		usec_delay(10);
412 		/* Restart PHY autonegotiation and wait for completion */
413 		status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
414 		    IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
415 		    &autoneg_reg);
416 
417 		autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE;
418 		if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) {
419 			status = IXGBE_SUCCESS;
420 			break;
421 		}
422 	}
423 
424 	if (time_out == max_time_out)
425 		status = IXGBE_ERR_LINK_SETUP;
426 
427 	return (status);
428 }
429 
430 /*
431  * ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities
432  * @hw: pointer to hardware structure
433  * @speed: new link speed
434  * @autoneg: TRUE if autonegotiation enabled
435  */
436 s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
437     ixgbe_link_speed speed,
438     bool autoneg,
439     bool autoneg_wait_to_complete)
440 {
441 	UNREFERENCED_PARAMETER(autoneg);
442 	UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
443 
444 	/*
445 	 * Clear autoneg_advertised and set new values based on input link
446 	 * speed.
447 	 */
448 	hw->phy.autoneg_advertised = 0;
449 
450 	if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
451 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
452 	}
453 	if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
454 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
455 	}
456 
457 	/* Setup link based on the new speed settings */
458 	hw->phy.ops.setup_link(hw);
459 
460 	return (IXGBE_SUCCESS);
461 }
462