1 /*******************************************************************************
3 Copyright (c) 2001-2007, Intel Corporation
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 3. Neither the name of the Intel Corporation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
32 *******************************************************************************/
35 #include "ixgbe_api.h"
36 #include "ixgbe_common.h"
37 #include "ixgbe_phy.h"
40 * ixgbe_init_shared_code_phy - Initialize PHY shared code
41 * @hw: pointer to hardware structure
43 s32 ixgbe_init_shared_code_phy(struct ixgbe_hw *hw)
45 /* Assign function pointers */
46 ixgbe_assign_func_pointers_phy(hw);
52 * ixgbe_assign_func_pointers_phy - Assigns PHY-specific function pointers
53 * @hw: pointer to hardware structure
55 * Note, generic function pointers have already been assigned, so the
56 * function pointers set here are only for PHY-specific functions.
58 s32 ixgbe_assign_func_pointers_phy(struct ixgbe_hw *hw)
60 hw->func.ixgbe_func_reset_phy =
61 &ixgbe_reset_phy_generic;
62 hw->func.ixgbe_func_read_phy_reg =
63 &ixgbe_read_phy_reg_generic;
64 hw->func.ixgbe_func_write_phy_reg =
65 &ixgbe_write_phy_reg_generic;
66 hw->func.ixgbe_func_identify_phy =
67 &ixgbe_identify_phy_generic;
69 if (ixgbe_get_media_type(hw) == ixgbe_media_type_copper) {
70 /* Call PHY identify routine to get the phy type */
71 ixgbe_identify_phy(hw);
73 switch (hw->phy.type) {
75 hw->func.ixgbe_func_setup_phy_link =
76 &ixgbe_setup_tnx_phy_link;
77 hw->func.ixgbe_func_check_phy_link =
78 &ixgbe_check_tnx_phy_link;
79 hw->func.ixgbe_func_setup_phy_link_speed =
80 &ixgbe_setup_tnx_phy_link_speed;
91 * ixgbe_identify_phy_generic - Get physical layer module
92 * @hw: pointer to hardware structure
94 * Determines the physical layer module found on the current adapter.
96 s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
98 s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
101 for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
102 if (ixgbe_validate_phy_addr(hw, phy_addr)) {
103 hw->phy.addr = phy_addr;
104 ixgbe_get_phy_id(hw);
105 hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id);
106 status = IXGBE_SUCCESS;
114 * ixgbe_validate_phy_addr - Determines phy address is valid
115 * @hw: pointer to hardware structure
118 bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr)
123 hw->phy.addr = phy_addr;
124 ixgbe_read_phy_reg_generic(hw,
125 IXGBE_MDIO_PHY_ID_HIGH,
126 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
129 if (phy_id != 0xFFFF && phy_id != 0x0)
136 * ixgbe_get_phy_id - Get the phy type
137 * @hw: pointer to hardware structure
140 s32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
146 status = ixgbe_read_phy_reg_generic(hw,
147 IXGBE_MDIO_PHY_ID_HIGH,
148 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
151 if (status == IXGBE_SUCCESS) {
152 hw->phy.id = (u32)(phy_id_high << 16);
153 status = ixgbe_read_phy_reg_generic(hw,
154 IXGBE_MDIO_PHY_ID_LOW,
155 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
157 hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
158 hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
165 * ixgbe_get_phy_type_from_id - Get the phy type
166 * @hw: pointer to hardware structure
169 enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
171 enum ixgbe_phy_type phy_type;
175 phy_type = ixgbe_phy_tn;
179 phy_type = ixgbe_phy_qt;
183 phy_type = ixgbe_phy_unknown;
191 * ixgbe_reset_phy_generic - Performs a PHY reset
192 * @hw: pointer to hardware structure
194 s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
197 * Perform soft PHY reset to the PHY_XS.
198 * This will cause a soft reset to the PHY
200 return ixgbe_write_phy_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
201 IXGBE_MDIO_PHY_XS_DEV_TYPE,
202 IXGBE_MDIO_PHY_XS_RESET);
206 * ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register
207 * @hw: pointer to hardware structure
208 * @reg_addr: 32 bit address of PHY register to read
209 * @phy_data: Pointer to read data from PHY register
211 s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
212 u32 device_type, u16 *phy_data)
218 s32 status = IXGBE_SUCCESS;
221 if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
222 gssr = IXGBE_GSSR_PHY1_SM;
224 gssr = IXGBE_GSSR_PHY0_SM;
226 if (ixgbe_acquire_swfw_sync(hw, gssr) != IXGBE_SUCCESS)
227 status = IXGBE_ERR_SWFW_SYNC;
229 if (status == IXGBE_SUCCESS) {
230 /* Setup and write the address cycle command */
231 command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
232 (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
233 (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
234 (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
236 IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
239 * Check every 10 usec to see if the address cycle completed.
240 * The MDI Command bit will clear when the operation is
243 for (i = 0; i < timeout; i++) {
246 command = IXGBE_READ_REG(hw, IXGBE_MSCA);
248 if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) {
253 if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
254 DEBUGFUNC("PHY address command did not complete.\n");
255 status = IXGBE_ERR_PHY;
258 if (status == IXGBE_SUCCESS) {
260 * Address cycle complete, setup and write the read
263 command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
264 (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
265 (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
266 (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
268 IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
271 * Check every 10 usec to see if the address cycle
272 * completed. The MDI Command bit will clear when the
273 * operation is complete
275 for (i = 0; i < timeout; i++) {
278 command = IXGBE_READ_REG(hw, IXGBE_MSCA);
280 if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
284 if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
285 DEBUGFUNC("PHY read command didn't complete\n");
286 status = IXGBE_ERR_PHY;
289 * Read operation is complete. Get the data
292 data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
293 data >>= IXGBE_MSRWD_READ_DATA_SHIFT;
294 *phy_data = (u16)(data);
298 ixgbe_release_swfw_sync(hw, gssr);
304 * ixgbe_write_phy_reg_generic - Writes a value to specified PHY register
305 * @hw: pointer to hardware structure
306 * @reg_addr: 32 bit PHY register to write
307 * @device_type: 5 bit device type
308 * @phy_data: Data to write to the PHY register
310 s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
311 u32 device_type, u16 phy_data)
316 s32 status = IXGBE_SUCCESS;
319 if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
320 gssr = IXGBE_GSSR_PHY1_SM;
322 gssr = IXGBE_GSSR_PHY0_SM;
324 if (ixgbe_acquire_swfw_sync(hw, gssr) != IXGBE_SUCCESS)
325 status = IXGBE_ERR_SWFW_SYNC;
327 if (status == IXGBE_SUCCESS) {
328 /* Put the data in the MDI single read and write data register*/
329 IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data);
331 /* Setup and write the address cycle command */
332 command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
333 (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
334 (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
335 (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
337 IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
340 * Check every 10 usec to see if the address cycle completed.
341 * The MDI Command bit will clear when the operation is
344 for (i = 0; i < timeout; i++) {
347 command = IXGBE_READ_REG(hw, IXGBE_MSCA);
349 if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) {
350 DEBUGFUNC("PHY address cmd didn't complete\n");
355 if ((command & IXGBE_MSCA_MDI_COMMAND) != 0)
356 status = IXGBE_ERR_PHY;
358 if (status == IXGBE_SUCCESS) {
360 * Address cycle complete, setup and write the write
363 command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
364 (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
365 (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
366 (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
368 IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
371 * Check every 10 usec to see if the address cycle
372 * completed. The MDI Command bit will clear when the
373 * operation is complete
375 for (i = 0; i < timeout; i++) {
378 command = IXGBE_READ_REG(hw, IXGBE_MSCA);
380 if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) {
381 DEBUGFUNC("PHY write command did not "
387 if ((command & IXGBE_MSCA_MDI_COMMAND) != 0)
388 status = IXGBE_ERR_PHY;
391 ixgbe_release_swfw_sync(hw, gssr);
398 * ixgbe_setup_phy_link - Restart PHY autoneg
399 * @hw: pointer to hardware structure
401 * Restart autonegotiation and PHY and waits for completion.
403 s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw)
405 return ixgbe_call_func(hw, ixgbe_func_setup_phy_link, (hw),
406 IXGBE_NOT_IMPLEMENTED);
410 * ixgbe_check_phy_link - Determine link and speed status
411 * @hw: pointer to hardware structure
413 * Reads a PHY register to determine if link is up and the current speed for
416 s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
419 return ixgbe_call_func(hw, ixgbe_func_check_phy_link, (hw, speed,
420 link_up), IXGBE_NOT_IMPLEMENTED);
424 * ixgbe_setup_phy_link_speed - Set auto advertise
425 * @hw: pointer to hardware structure
426 * @speed: new link speed
427 * @autoneg: TRUE if autonegotiation enabled
429 * Sets the auto advertised capabilities
431 s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed,
433 bool autoneg_wait_to_complete)
435 return ixgbe_call_func(hw, ixgbe_func_setup_phy_link_speed, (hw, speed,
436 autoneg, autoneg_wait_to_complete),
437 IXGBE_NOT_IMPLEMENTED);
441 * ixgbe_setup_tnx_phy_link - Set and restart autoneg
442 * @hw: pointer to hardware structure
444 * Restart autonegotiation and PHY and waits for completion.
446 s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw)
448 s32 status = IXGBE_NOT_IMPLEMENTED;
450 u32 max_time_out = 10;
451 u16 autoneg_speed_selection_register = 0x10;
452 u16 autoneg_restart_mask = 0x0200;
453 u16 autoneg_complete_mask = 0x0020;
457 * Set advertisement settings in PHY based on autoneg_advertised
458 * settings. If autoneg_advertised = 0, then advertise default values
459 * txn devices cannot be "forced" to a autoneg 10G and fail. But can
462 ixgbe_read_phy_reg(hw,
463 autoneg_speed_selection_register,
464 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
467 if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL)
468 autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */
470 autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */
472 ixgbe_write_phy_reg(hw,
473 autoneg_speed_selection_register,
474 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
478 /* Restart PHY autonegotiation and wait for completion */
479 ixgbe_read_phy_reg(hw,
480 IXGBE_MDIO_AUTO_NEG_CONTROL,
481 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
484 autoneg_reg |= autoneg_restart_mask;
486 ixgbe_write_phy_reg(hw,
487 IXGBE_MDIO_AUTO_NEG_CONTROL,
488 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
491 /* Wait for autonegotiation to finish */
492 for (time_out = 0; time_out < max_time_out; time_out++) {
494 /* Restart PHY autonegotiation and wait for completion */
495 status = ixgbe_read_phy_reg(hw,
496 IXGBE_MDIO_AUTO_NEG_STATUS,
497 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
500 autoneg_reg &= autoneg_complete_mask;
501 if (autoneg_reg == autoneg_complete_mask) {
502 status = IXGBE_SUCCESS;
507 if (time_out == max_time_out)
508 status = IXGBE_ERR_LINK_SETUP;
514 * ixgbe_check_tnx_phy_link - Determine link and speed status
515 * @hw: pointer to hardware structure
517 * Reads the VS1 register to determine if link is up and the current speed for
520 s32 ixgbe_check_tnx_phy_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
523 s32 status = IXGBE_SUCCESS;
525 u32 max_time_out = 10;
530 /* Initialize speed and link to default case */
532 *speed = IXGBE_LINK_SPEED_10GB_FULL;
535 * Check current speed and link status of the PHY register.
536 * This is a vendor specific register and may have to
537 * be changed for other copper PHYs.
539 for (time_out = 0; time_out < max_time_out; time_out++) {
541 if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
544 IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
545 *speed = IXGBE_LINK_SPEED_1GB_FULL;
548 status = ixgbe_read_phy_reg(hw,
549 IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
550 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
552 phy_link = phy_data &
553 IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
554 phy_speed = phy_data &
555 IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
563 * ixgbe_setup_tnx_phy_link_speed - Sets the auto advertised capabilities
564 * @hw: pointer to hardware structure
565 * @speed: new link speed
566 * @autoneg: TRUE if autonegotiation enabled
568 s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed,
570 bool autoneg_wait_to_complete)
572 UNREFERENCED_PARAMETER(autoneg);
573 UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
576 * Clear autoneg_advertised and set new values based on input link
579 hw->phy.autoneg_advertised = 0;
581 if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
582 hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
584 if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
585 hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
588 /* Setup link based on the new speed settings */
589 ixgbe_setup_tnx_phy_link(hw);
591 return IXGBE_SUCCESS;