diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2009-11-19 07:41:42 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-20 13:00:09 -0500 |
commit | 2909c3f79d933b55bf2485addb1dca762210b6af (patch) | |
tree | 59d4a36735433d47c9874f49b5b93c669958f8b6 /drivers/net/igb/e1000_phy.c | |
parent | 164165dad7e607ec359e64b6fae72abbf3640ea6 (diff) |
igb: add support for the 82580 phy
This patch adds support for the phy included in the 82580 silicon family.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/igb/e1000_phy.c')
-rw-r--r-- | drivers/net/igb/e1000_phy.c | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c index 83b706c460b3..b8fbc8558fe2 100644 --- a/drivers/net/igb/e1000_phy.c +++ b/drivers/net/igb/e1000_phy.c | |||
@@ -421,6 +421,57 @@ out: | |||
421 | } | 421 | } |
422 | 422 | ||
423 | /** | 423 | /** |
424 | * igb_copper_link_setup_82580 - Setup 82580 PHY for copper link | ||
425 | * @hw: pointer to the HW structure | ||
426 | * | ||
427 | * Sets up Carrier-sense on Transmit and downshift values. | ||
428 | **/ | ||
429 | s32 igb_copper_link_setup_82580(struct e1000_hw *hw) | ||
430 | { | ||
431 | struct e1000_phy_info *phy = &hw->phy; | ||
432 | s32 ret_val; | ||
433 | u16 phy_data; | ||
434 | |||
435 | |||
436 | if (phy->reset_disable) { | ||
437 | ret_val = 0; | ||
438 | goto out; | ||
439 | } | ||
440 | |||
441 | if (phy->type == e1000_phy_82580) { | ||
442 | ret_val = hw->phy.ops.reset(hw); | ||
443 | if (ret_val) { | ||
444 | hw_dbg("Error resetting the PHY.\n"); | ||
445 | goto out; | ||
446 | } | ||
447 | } | ||
448 | |||
449 | /* Enable CRS on TX. This must be set for half-duplex operation. */ | ||
450 | ret_val = phy->ops.read_reg(hw, I82580_CFG_REG, &phy_data); | ||
451 | if (ret_val) | ||
452 | goto out; | ||
453 | |||
454 | phy_data |= I82580_CFG_ASSERT_CRS_ON_TX; | ||
455 | |||
456 | /* Enable downshift */ | ||
457 | phy_data |= I82580_CFG_ENABLE_DOWNSHIFT; | ||
458 | |||
459 | ret_val = phy->ops.write_reg(hw, I82580_CFG_REG, phy_data); | ||
460 | if (ret_val) | ||
461 | goto out; | ||
462 | |||
463 | /* Set number of link attempts before downshift */ | ||
464 | ret_val = phy->ops.read_reg(hw, I82580_CTRL_REG, &phy_data); | ||
465 | if (ret_val) | ||
466 | goto out; | ||
467 | phy_data &= ~I82580_CTRL_DOWNSHIFT_MASK; | ||
468 | ret_val = phy->ops.write_reg(hw, I82580_CTRL_REG, phy_data); | ||
469 | |||
470 | out: | ||
471 | return ret_val; | ||
472 | } | ||
473 | |||
474 | /** | ||
424 | * igb_copper_link_setup_m88 - Setup m88 PHY's for copper link | 475 | * igb_copper_link_setup_m88 - Setup m88 PHY's for copper link |
425 | * @hw: pointer to the HW structure | 476 | * @hw: pointer to the HW structure |
426 | * | 477 | * |
@@ -1888,3 +1939,194 @@ s32 igb_phy_init_script_igp3(struct e1000_hw *hw) | |||
1888 | return 0; | 1939 | return 0; |
1889 | } | 1940 | } |
1890 | 1941 | ||
1942 | /** | ||
1943 | * igb_check_polarity_82580 - Checks the polarity. | ||
1944 | * @hw: pointer to the HW structure | ||
1945 | * | ||
1946 | * Success returns 0, Failure returns -E1000_ERR_PHY (-2) | ||
1947 | * | ||
1948 | * Polarity is determined based on the PHY specific status register. | ||
1949 | **/ | ||
1950 | s32 igb_check_polarity_82580(struct e1000_hw *hw) | ||
1951 | { | ||
1952 | struct e1000_phy_info *phy = &hw->phy; | ||
1953 | s32 ret_val; | ||
1954 | u16 data; | ||
1955 | |||
1956 | |||
1957 | ret_val = phy->ops.read_reg(hw, I82580_PHY_STATUS_2, &data); | ||
1958 | |||
1959 | if (!ret_val) | ||
1960 | phy->cable_polarity = (data & I82580_PHY_STATUS2_REV_POLARITY) | ||
1961 | ? e1000_rev_polarity_reversed | ||
1962 | : e1000_rev_polarity_normal; | ||
1963 | |||
1964 | return ret_val; | ||
1965 | } | ||
1966 | |||
1967 | /** | ||
1968 | * igb_phy_force_speed_duplex_82580 - Force speed/duplex for I82580 PHY | ||
1969 | * @hw: pointer to the HW structure | ||
1970 | * | ||
1971 | * Calls the PHY setup function to force speed and duplex. Clears the | ||
1972 | * auto-crossover to force MDI manually. Waits for link and returns | ||
1973 | * successful if link up is successful, else -E1000_ERR_PHY (-2). | ||
1974 | **/ | ||
1975 | s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw) | ||
1976 | { | ||
1977 | struct e1000_phy_info *phy = &hw->phy; | ||
1978 | s32 ret_val; | ||
1979 | u16 phy_data; | ||
1980 | bool link; | ||
1981 | |||
1982 | |||
1983 | ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); | ||
1984 | if (ret_val) | ||
1985 | goto out; | ||
1986 | |||
1987 | igb_phy_force_speed_duplex_setup(hw, &phy_data); | ||
1988 | |||
1989 | ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data); | ||
1990 | if (ret_val) | ||
1991 | goto out; | ||
1992 | |||
1993 | /* | ||
1994 | * Clear Auto-Crossover to force MDI manually. 82580 requires MDI | ||
1995 | * forced whenever speed and duplex are forced. | ||
1996 | */ | ||
1997 | ret_val = phy->ops.read_reg(hw, I82580_PHY_CTRL_2, &phy_data); | ||
1998 | if (ret_val) | ||
1999 | goto out; | ||
2000 | |||
2001 | phy_data &= ~I82580_PHY_CTRL2_AUTO_MDIX; | ||
2002 | phy_data &= ~I82580_PHY_CTRL2_FORCE_MDI_MDIX; | ||
2003 | |||
2004 | ret_val = phy->ops.write_reg(hw, I82580_PHY_CTRL_2, phy_data); | ||
2005 | if (ret_val) | ||
2006 | goto out; | ||
2007 | |||
2008 | hw_dbg("I82580_PHY_CTRL_2: %X\n", phy_data); | ||
2009 | |||
2010 | udelay(1); | ||
2011 | |||
2012 | if (phy->autoneg_wait_to_complete) { | ||
2013 | hw_dbg("Waiting for forced speed/duplex link on 82580 phy\n"); | ||
2014 | |||
2015 | ret_val = igb_phy_has_link(hw, | ||
2016 | PHY_FORCE_LIMIT, | ||
2017 | 100000, | ||
2018 | &link); | ||
2019 | if (ret_val) | ||
2020 | goto out; | ||
2021 | |||
2022 | if (!link) | ||
2023 | hw_dbg("Link taking longer than expected.\n"); | ||
2024 | |||
2025 | /* Try once more */ | ||
2026 | ret_val = igb_phy_has_link(hw, | ||
2027 | PHY_FORCE_LIMIT, | ||
2028 | 100000, | ||
2029 | &link); | ||
2030 | if (ret_val) | ||
2031 | goto out; | ||
2032 | } | ||
2033 | |||
2034 | out: | ||
2035 | return ret_val; | ||
2036 | } | ||
2037 | |||
2038 | /** | ||
2039 | * igb_get_phy_info_82580 - Retrieve I82580 PHY information | ||
2040 | * @hw: pointer to the HW structure | ||
2041 | * | ||
2042 | * Read PHY status to determine if link is up. If link is up, then | ||
2043 | * set/determine 10base-T extended distance and polarity correction. Read | ||
2044 | * PHY port status to determine MDI/MDIx and speed. Based on the speed, | ||
2045 | * determine on the cable length, local and remote receiver. | ||
2046 | **/ | ||
2047 | s32 igb_get_phy_info_82580(struct e1000_hw *hw) | ||
2048 | { | ||
2049 | struct e1000_phy_info *phy = &hw->phy; | ||
2050 | s32 ret_val; | ||
2051 | u16 data; | ||
2052 | bool link; | ||
2053 | |||
2054 | |||
2055 | ret_val = igb_phy_has_link(hw, 1, 0, &link); | ||
2056 | if (ret_val) | ||
2057 | goto out; | ||
2058 | |||
2059 | if (!link) { | ||
2060 | hw_dbg("Phy info is only valid if link is up\n"); | ||
2061 | ret_val = -E1000_ERR_CONFIG; | ||
2062 | goto out; | ||
2063 | } | ||
2064 | |||
2065 | phy->polarity_correction = true; | ||
2066 | |||
2067 | ret_val = igb_check_polarity_82580(hw); | ||
2068 | if (ret_val) | ||
2069 | goto out; | ||
2070 | |||
2071 | ret_val = phy->ops.read_reg(hw, I82580_PHY_STATUS_2, &data); | ||
2072 | if (ret_val) | ||
2073 | goto out; | ||
2074 | |||
2075 | phy->is_mdix = (data & I82580_PHY_STATUS2_MDIX) ? true : false; | ||
2076 | |||
2077 | if ((data & I82580_PHY_STATUS2_SPEED_MASK) == | ||
2078 | I82580_PHY_STATUS2_SPEED_1000MBPS) { | ||
2079 | ret_val = hw->phy.ops.get_cable_length(hw); | ||
2080 | if (ret_val) | ||
2081 | goto out; | ||
2082 | |||
2083 | ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data); | ||
2084 | if (ret_val) | ||
2085 | goto out; | ||
2086 | |||
2087 | phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS) | ||
2088 | ? e1000_1000t_rx_status_ok | ||
2089 | : e1000_1000t_rx_status_not_ok; | ||
2090 | |||
2091 | phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS) | ||
2092 | ? e1000_1000t_rx_status_ok | ||
2093 | : e1000_1000t_rx_status_not_ok; | ||
2094 | } else { | ||
2095 | phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; | ||
2096 | phy->local_rx = e1000_1000t_rx_status_undefined; | ||
2097 | phy->remote_rx = e1000_1000t_rx_status_undefined; | ||
2098 | } | ||
2099 | |||
2100 | out: | ||
2101 | return ret_val; | ||
2102 | } | ||
2103 | |||
2104 | /** | ||
2105 | * igb_get_cable_length_82580 - Determine cable length for 82580 PHY | ||
2106 | * @hw: pointer to the HW structure | ||
2107 | * | ||
2108 | * Reads the diagnostic status register and verifies result is valid before | ||
2109 | * placing it in the phy_cable_length field. | ||
2110 | **/ | ||
2111 | s32 igb_get_cable_length_82580(struct e1000_hw *hw) | ||
2112 | { | ||
2113 | struct e1000_phy_info *phy = &hw->phy; | ||
2114 | s32 ret_val; | ||
2115 | u16 phy_data, length; | ||
2116 | |||
2117 | |||
2118 | ret_val = phy->ops.read_reg(hw, I82580_PHY_DIAG_STATUS, &phy_data); | ||
2119 | if (ret_val) | ||
2120 | goto out; | ||
2121 | |||
2122 | length = (phy_data & I82580_DSTATUS_CABLE_LENGTH) >> | ||
2123 | I82580_DSTATUS_CABLE_LENGTH_SHIFT; | ||
2124 | |||
2125 | if (length == E1000_CABLE_LENGTH_UNDEFINED) | ||
2126 | ret_val = -E1000_ERR_PHY; | ||
2127 | |||
2128 | phy->cable_length = length; | ||
2129 | |||
2130 | out: | ||
2131 | return ret_val; | ||
2132 | } | ||