diff options
author | Auke Kok <auke-jan.h.kok@intel.com> | 2007-09-15 17:07:45 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:51:02 -0400 |
commit | 9a799d71034c4e2b168740c8a8530591011313d5 (patch) | |
tree | ce2dedefe2b101e1e81105a7ca8e3e61321193b6 /drivers/net/ixgbe/ixgbe_phy.c | |
parent | dc029ad97f267cbd1c2e978a443eb5ae93a55328 (diff) |
ixgbe: driver for Intel(R) 82598 PCI-Express 10GbE adapters (v4)
This patch adds support for the Intel 82598 PCI-Express 10GbE
chipset. Devices will be available on the market soon.
This version of the driver is largely the same as the last release:
* Driver uses a single RX and single TX queue, each using 1 MSI-X
irq vector.
* Driver runs in NAPI mode only
* Driver is largely multiqueue-ready (TM)
Changes since 20070803:
* removed wrappers for hardware functions
* incorporated e1000e-style HW api reorganization code
* sparse/checkpatch cleanups, namespace cleanups
* driver prints out extra debugging information at load time
identifying adapter board number, mac, phy types
* removed ixgbe_api.c, ixgbe_api.h, ixgbe_osdep.h
* driver update to 1.1.18
* removed ixgbe.txt which contained no useful info anymore
[ Integrated napi_struct changes from Auke as well... -DaveM ]
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Signed-off-by: Ayyappan Veeraiyan <ayyappan.veeraiyan@intel.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_phy.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_phy.c | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c new file mode 100644 index 000000000000..8002931ae823 --- /dev/null +++ b/drivers/net/ixgbe/ixgbe_phy.c | |||
@@ -0,0 +1,494 @@ | |||
1 | /******************************************************************************* | ||
2 | |||
3 | Intel 10 Gigabit PCI Express Linux driver | ||
4 | Copyright(c) 1999 - 2007 Intel Corporation. | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify it | ||
7 | under the terms and conditions of the GNU General Public License, | ||
8 | version 2, as published by the Free Software Foundation. | ||
9 | |||
10 | This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License along with | ||
16 | this program; if not, write to the Free Software Foundation, Inc., | ||
17 | 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | |||
19 | The full GNU General Public License is included in this distribution in | ||
20 | the file called "COPYING". | ||
21 | |||
22 | Contact Information: | ||
23 | Linux NICS <linux.nics@intel.com> | ||
24 | e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||
25 | Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
26 | |||
27 | *******************************************************************************/ | ||
28 | |||
29 | #include <linux/pci.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/sched.h> | ||
32 | |||
33 | #include "ixgbe_common.h" | ||
34 | #include "ixgbe_phy.h" | ||
35 | |||
36 | static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id); | ||
37 | static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw); | ||
38 | static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr); | ||
39 | static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, | ||
40 | u32 device_type, u16 phy_data); | ||
41 | |||
42 | /** | ||
43 | * ixgbe_identify_phy - Get physical layer module | ||
44 | * @hw: pointer to hardware structure | ||
45 | * | ||
46 | * Determines the physical layer module found on the current adapter. | ||
47 | **/ | ||
48 | s32 ixgbe_identify_phy(struct ixgbe_hw *hw) | ||
49 | { | ||
50 | s32 status = IXGBE_ERR_PHY_ADDR_INVALID; | ||
51 | u32 phy_addr; | ||
52 | |||
53 | for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { | ||
54 | if (ixgbe_validate_phy_addr(hw, phy_addr)) { | ||
55 | hw->phy.addr = phy_addr; | ||
56 | ixgbe_get_phy_id(hw); | ||
57 | hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id); | ||
58 | status = 0; | ||
59 | break; | ||
60 | } | ||
61 | } | ||
62 | return status; | ||
63 | } | ||
64 | |||
65 | /** | ||
66 | * ixgbe_validate_phy_addr - Determines phy address is valid | ||
67 | * @hw: pointer to hardware structure | ||
68 | * | ||
69 | **/ | ||
70 | static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr) | ||
71 | { | ||
72 | u16 phy_id = 0; | ||
73 | bool valid = false; | ||
74 | |||
75 | hw->phy.addr = phy_addr; | ||
76 | ixgbe_read_phy_reg(hw, | ||
77 | IXGBE_MDIO_PHY_ID_HIGH, | ||
78 | IXGBE_MDIO_PMA_PMD_DEV_TYPE, | ||
79 | &phy_id); | ||
80 | |||
81 | if (phy_id != 0xFFFF && phy_id != 0x0) | ||
82 | valid = true; | ||
83 | |||
84 | return valid; | ||
85 | } | ||
86 | |||
87 | /** | ||
88 | * ixgbe_get_phy_id - Get the phy type | ||
89 | * @hw: pointer to hardware structure | ||
90 | * | ||
91 | **/ | ||
92 | static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw) | ||
93 | { | ||
94 | u32 status; | ||
95 | u16 phy_id_high = 0; | ||
96 | u16 phy_id_low = 0; | ||
97 | |||
98 | status = ixgbe_read_phy_reg(hw, | ||
99 | IXGBE_MDIO_PHY_ID_HIGH, | ||
100 | IXGBE_MDIO_PMA_PMD_DEV_TYPE, | ||
101 | &phy_id_high); | ||
102 | |||
103 | if (status == 0) { | ||
104 | hw->phy.id = (u32)(phy_id_high << 16); | ||
105 | status = ixgbe_read_phy_reg(hw, | ||
106 | IXGBE_MDIO_PHY_ID_LOW, | ||
107 | IXGBE_MDIO_PMA_PMD_DEV_TYPE, | ||
108 | &phy_id_low); | ||
109 | hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK); | ||
110 | hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK); | ||
111 | } | ||
112 | |||
113 | return status; | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * ixgbe_get_phy_type_from_id - Get the phy type | ||
118 | * @hw: pointer to hardware structure | ||
119 | * | ||
120 | **/ | ||
121 | static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) | ||
122 | { | ||
123 | enum ixgbe_phy_type phy_type; | ||
124 | |||
125 | switch (phy_id) { | ||
126 | case TN1010_PHY_ID: | ||
127 | phy_type = ixgbe_phy_tn; | ||
128 | break; | ||
129 | case QT2022_PHY_ID: | ||
130 | phy_type = ixgbe_phy_qt; | ||
131 | break; | ||
132 | default: | ||
133 | phy_type = ixgbe_phy_unknown; | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | return phy_type; | ||
138 | } | ||
139 | |||
140 | /** | ||
141 | * ixgbe_reset_phy - Performs a PHY reset | ||
142 | * @hw: pointer to hardware structure | ||
143 | **/ | ||
144 | s32 ixgbe_reset_phy(struct ixgbe_hw *hw) | ||
145 | { | ||
146 | /* | ||
147 | * Perform soft PHY reset to the PHY_XS. | ||
148 | * This will cause a soft reset to the PHY | ||
149 | */ | ||
150 | return ixgbe_write_phy_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, | ||
151 | IXGBE_MDIO_PHY_XS_DEV_TYPE, | ||
152 | IXGBE_MDIO_PHY_XS_RESET); | ||
153 | } | ||
154 | |||
155 | /** | ||
156 | * ixgbe_read_phy_reg - Reads a value from a specified PHY register | ||
157 | * @hw: pointer to hardware structure | ||
158 | * @reg_addr: 32 bit address of PHY register to read | ||
159 | * @phy_data: Pointer to read data from PHY register | ||
160 | **/ | ||
161 | s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, | ||
162 | u32 device_type, u16 *phy_data) | ||
163 | { | ||
164 | u32 command; | ||
165 | u32 i; | ||
166 | u32 timeout = 10; | ||
167 | u32 data; | ||
168 | s32 status = 0; | ||
169 | u16 gssr; | ||
170 | |||
171 | if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) | ||
172 | gssr = IXGBE_GSSR_PHY1_SM; | ||
173 | else | ||
174 | gssr = IXGBE_GSSR_PHY0_SM; | ||
175 | |||
176 | if (ixgbe_acquire_swfw_sync(hw, gssr) != 0) | ||
177 | status = IXGBE_ERR_SWFW_SYNC; | ||
178 | |||
179 | if (status == 0) { | ||
180 | /* Setup and write the address cycle command */ | ||
181 | command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | | ||
182 | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | | ||
183 | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | | ||
184 | (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); | ||
185 | |||
186 | IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); | ||
187 | |||
188 | /* | ||
189 | * Check every 10 usec to see if the address cycle completed. | ||
190 | * The MDI Command bit will clear when the operation is | ||
191 | * complete | ||
192 | */ | ||
193 | for (i = 0; i < timeout; i++) { | ||
194 | udelay(10); | ||
195 | |||
196 | command = IXGBE_READ_REG(hw, IXGBE_MSCA); | ||
197 | |||
198 | if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) | ||
199 | break; | ||
200 | } | ||
201 | |||
202 | if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { | ||
203 | hw_dbg(hw, "PHY address command did not complete.\n"); | ||
204 | status = IXGBE_ERR_PHY; | ||
205 | } | ||
206 | |||
207 | if (status == 0) { | ||
208 | /* | ||
209 | * Address cycle complete, setup and write the read | ||
210 | * command | ||
211 | */ | ||
212 | command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | | ||
213 | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | | ||
214 | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | | ||
215 | (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND)); | ||
216 | |||
217 | IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); | ||
218 | |||
219 | /* | ||
220 | * Check every 10 usec to see if the address cycle | ||
221 | * completed. The MDI Command bit will clear when the | ||
222 | * operation is complete | ||
223 | */ | ||
224 | for (i = 0; i < timeout; i++) { | ||
225 | udelay(10); | ||
226 | |||
227 | command = IXGBE_READ_REG(hw, IXGBE_MSCA); | ||
228 | |||
229 | if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) | ||
230 | break; | ||
231 | } | ||
232 | |||
233 | if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { | ||
234 | hw_dbg(hw, | ||
235 | "PHY read command didn't complete\n"); | ||
236 | status = IXGBE_ERR_PHY; | ||
237 | } else { | ||
238 | /* | ||
239 | * Read operation is complete. Get the data | ||
240 | * from MSRWD | ||
241 | */ | ||
242 | data = IXGBE_READ_REG(hw, IXGBE_MSRWD); | ||
243 | data >>= IXGBE_MSRWD_READ_DATA_SHIFT; | ||
244 | *phy_data = (u16)(data); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | ixgbe_release_swfw_sync(hw, gssr); | ||
249 | } | ||
250 | return status; | ||
251 | } | ||
252 | |||
253 | /** | ||
254 | * ixgbe_write_phy_reg - Writes a value to specified PHY register | ||
255 | * @hw: pointer to hardware structure | ||
256 | * @reg_addr: 32 bit PHY register to write | ||
257 | * @device_type: 5 bit device type | ||
258 | * @phy_data: Data to write to the PHY register | ||
259 | **/ | ||
260 | static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, | ||
261 | u32 device_type, u16 phy_data) | ||
262 | { | ||
263 | u32 command; | ||
264 | u32 i; | ||
265 | u32 timeout = 10; | ||
266 | s32 status = 0; | ||
267 | u16 gssr; | ||
268 | |||
269 | if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) | ||
270 | gssr = IXGBE_GSSR_PHY1_SM; | ||
271 | else | ||
272 | gssr = IXGBE_GSSR_PHY0_SM; | ||
273 | |||
274 | if (ixgbe_acquire_swfw_sync(hw, gssr) != 0) | ||
275 | status = IXGBE_ERR_SWFW_SYNC; | ||
276 | |||
277 | if (status == 0) { | ||
278 | /* Put the data in the MDI single read and write data register*/ | ||
279 | IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data); | ||
280 | |||
281 | /* Setup and write the address cycle command */ | ||
282 | command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | | ||
283 | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | | ||
284 | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | | ||
285 | (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); | ||
286 | |||
287 | IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); | ||
288 | |||
289 | /* | ||
290 | * Check every 10 usec to see if the address cycle completed. | ||
291 | * The MDI Command bit will clear when the operation is | ||
292 | * complete | ||
293 | */ | ||
294 | for (i = 0; i < timeout; i++) { | ||
295 | udelay(10); | ||
296 | |||
297 | command = IXGBE_READ_REG(hw, IXGBE_MSCA); | ||
298 | |||
299 | if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) { | ||
300 | hw_dbg(hw, "PHY address cmd didn't complete\n"); | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | |||
305 | if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) | ||
306 | status = IXGBE_ERR_PHY; | ||
307 | |||
308 | if (status == 0) { | ||
309 | /* | ||
310 | * Address cycle complete, setup and write the write | ||
311 | * command | ||
312 | */ | ||
313 | command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | | ||
314 | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | | ||
315 | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | | ||
316 | (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND)); | ||
317 | |||
318 | IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); | ||
319 | |||
320 | /* | ||
321 | * Check every 10 usec to see if the address cycle | ||
322 | * completed. The MDI Command bit will clear when the | ||
323 | * operation is complete | ||
324 | */ | ||
325 | for (i = 0; i < timeout; i++) { | ||
326 | udelay(10); | ||
327 | |||
328 | command = IXGBE_READ_REG(hw, IXGBE_MSCA); | ||
329 | |||
330 | if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) { | ||
331 | hw_dbg(hw, "PHY write command did not " | ||
332 | "complete.\n"); | ||
333 | break; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) | ||
338 | status = IXGBE_ERR_PHY; | ||
339 | } | ||
340 | |||
341 | ixgbe_release_swfw_sync(hw, gssr); | ||
342 | } | ||
343 | |||
344 | return status; | ||
345 | } | ||
346 | |||
347 | /** | ||
348 | * ixgbe_setup_tnx_phy_link - Set and restart autoneg | ||
349 | * @hw: pointer to hardware structure | ||
350 | * | ||
351 | * Restart autonegotiation and PHY and waits for completion. | ||
352 | **/ | ||
353 | s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw) | ||
354 | { | ||
355 | s32 status = IXGBE_NOT_IMPLEMENTED; | ||
356 | u32 time_out; | ||
357 | u32 max_time_out = 10; | ||
358 | u16 autoneg_speed_selection_register = 0x10; | ||
359 | u16 autoneg_restart_mask = 0x0200; | ||
360 | u16 autoneg_complete_mask = 0x0020; | ||
361 | u16 autoneg_reg = 0; | ||
362 | |||
363 | /* | ||
364 | * Set advertisement settings in PHY based on autoneg_advertised | ||
365 | * settings. If autoneg_advertised = 0, then advertise default values | ||
366 | * txn devices cannot be "forced" to a autoneg 10G and fail. But can | ||
367 | * for a 1G. | ||
368 | */ | ||
369 | ixgbe_read_phy_reg(hw, | ||
370 | autoneg_speed_selection_register, | ||
371 | IXGBE_MDIO_AUTO_NEG_DEV_TYPE, | ||
372 | &autoneg_reg); | ||
373 | |||
374 | if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL) | ||
375 | autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */ | ||
376 | else | ||
377 | autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */ | ||
378 | |||
379 | ixgbe_write_phy_reg(hw, | ||
380 | autoneg_speed_selection_register, | ||
381 | IXGBE_MDIO_AUTO_NEG_DEV_TYPE, | ||
382 | autoneg_reg); | ||
383 | |||
384 | |||
385 | /* Restart PHY autonegotiation and wait for completion */ | ||
386 | ixgbe_read_phy_reg(hw, | ||
387 | IXGBE_MDIO_AUTO_NEG_CONTROL, | ||
388 | IXGBE_MDIO_AUTO_NEG_DEV_TYPE, | ||
389 | &autoneg_reg); | ||
390 | |||
391 | autoneg_reg |= autoneg_restart_mask; | ||
392 | |||
393 | ixgbe_write_phy_reg(hw, | ||
394 | IXGBE_MDIO_AUTO_NEG_CONTROL, | ||
395 | IXGBE_MDIO_AUTO_NEG_DEV_TYPE, | ||
396 | autoneg_reg); | ||
397 | |||
398 | /* Wait for autonegotiation to finish */ | ||
399 | for (time_out = 0; time_out < max_time_out; time_out++) { | ||
400 | udelay(10); | ||
401 | /* Restart PHY autonegotiation and wait for completion */ | ||
402 | status = ixgbe_read_phy_reg(hw, | ||
403 | IXGBE_MDIO_AUTO_NEG_STATUS, | ||
404 | IXGBE_MDIO_AUTO_NEG_DEV_TYPE, | ||
405 | &autoneg_reg); | ||
406 | |||
407 | autoneg_reg &= autoneg_complete_mask; | ||
408 | if (autoneg_reg == autoneg_complete_mask) { | ||
409 | status = 0; | ||
410 | break; | ||
411 | } | ||
412 | } | ||
413 | |||
414 | if (time_out == max_time_out) | ||
415 | status = IXGBE_ERR_LINK_SETUP; | ||
416 | |||
417 | return status; | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * ixgbe_check_tnx_phy_link - Determine link and speed status | ||
422 | * @hw: pointer to hardware structure | ||
423 | * | ||
424 | * Reads the VS1 register to determine if link is up and the current speed for | ||
425 | * the PHY. | ||
426 | **/ | ||
427 | s32 ixgbe_check_tnx_phy_link(struct ixgbe_hw *hw, u32 *speed, | ||
428 | bool *link_up) | ||
429 | { | ||
430 | s32 status = 0; | ||
431 | u32 time_out; | ||
432 | u32 max_time_out = 10; | ||
433 | u16 phy_link = 0; | ||
434 | u16 phy_speed = 0; | ||
435 | u16 phy_data = 0; | ||
436 | |||
437 | /* Initialize speed and link to default case */ | ||
438 | *link_up = false; | ||
439 | *speed = IXGBE_LINK_SPEED_10GB_FULL; | ||
440 | |||
441 | /* | ||
442 | * Check current speed and link status of the PHY register. | ||
443 | * This is a vendor specific register and may have to | ||
444 | * be changed for other copper PHYs. | ||
445 | */ | ||
446 | for (time_out = 0; time_out < max_time_out; time_out++) { | ||
447 | udelay(10); | ||
448 | if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) { | ||
449 | *link_up = true; | ||
450 | if (phy_speed == | ||
451 | IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS) | ||
452 | *speed = IXGBE_LINK_SPEED_1GB_FULL; | ||
453 | break; | ||
454 | } else { | ||
455 | status = ixgbe_read_phy_reg(hw, | ||
456 | IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS, | ||
457 | IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, | ||
458 | &phy_data); | ||
459 | phy_link = phy_data & | ||
460 | IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS; | ||
461 | phy_speed = phy_data & | ||
462 | IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS; | ||
463 | } | ||
464 | } | ||
465 | |||
466 | return status; | ||
467 | } | ||
468 | |||
469 | /** | ||
470 | * ixgbe_setup_tnx_phy_link_speed - Sets the auto advertised capabilities | ||
471 | * @hw: pointer to hardware structure | ||
472 | * @speed: new link speed | ||
473 | * @autoneg: true if autonegotiation enabled | ||
474 | **/ | ||
475 | s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed, | ||
476 | bool autoneg, | ||
477 | bool autoneg_wait_to_complete) | ||
478 | { | ||
479 | /* | ||
480 | * Clear autoneg_advertised and set new values based on input link | ||
481 | * speed. | ||
482 | */ | ||
483 | hw->phy.autoneg_advertised = 0; | ||
484 | |||
485 | if (speed & IXGBE_LINK_SPEED_10GB_FULL) | ||
486 | hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; | ||
487 | if (speed & IXGBE_LINK_SPEED_1GB_FULL) | ||
488 | hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; | ||
489 | |||
490 | /* Setup link based on the new speed settings */ | ||
491 | ixgbe_setup_tnx_phy_link(hw); | ||
492 | |||
493 | return 0; | ||
494 | } | ||