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 | |
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')
-rw-r--r-- | drivers/net/igb/e1000_hw.h | 1 | ||||
-rw-r--r-- | drivers/net/igb/e1000_phy.c | 242 | ||||
-rw-r--r-- | drivers/net/igb/e1000_phy.h | 32 |
3 files changed, 275 insertions, 0 deletions
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index 2dc929419df0..5deda3e78422 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h | |||
@@ -93,6 +93,7 @@ enum e1000_phy_type { | |||
93 | e1000_phy_gg82563, | 93 | e1000_phy_gg82563, |
94 | e1000_phy_igp_3, | 94 | e1000_phy_igp_3, |
95 | e1000_phy_ife, | 95 | e1000_phy_ife, |
96 | e1000_phy_82580, | ||
96 | }; | 97 | }; |
97 | 98 | ||
98 | enum e1000_bus_type { | 99 | enum e1000_bus_type { |
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 | } | ||
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h index adb9436b7336..e23b0211a203 100644 --- a/drivers/net/igb/e1000_phy.h +++ b/drivers/net/igb/e1000_phy.h | |||
@@ -63,6 +63,11 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations, | |||
63 | s32 igb_phy_init_script_igp3(struct e1000_hw *hw); | 63 | s32 igb_phy_init_script_igp3(struct e1000_hw *hw); |
64 | s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data); | 64 | s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data); |
65 | s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data); | 65 | s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data); |
66 | s32 igb_copper_link_setup_82580(struct e1000_hw *hw); | ||
67 | s32 igb_check_polarity_82580(struct e1000_hw *hw); | ||
68 | s32 igb_get_phy_info_82580(struct e1000_hw *hw); | ||
69 | s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw); | ||
70 | s32 igb_get_cable_length_82580(struct e1000_hw *hw); | ||
66 | 71 | ||
67 | /* IGP01E1000 Specific Registers */ | 72 | /* IGP01E1000 Specific Registers */ |
68 | #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */ | 73 | #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */ |
@@ -77,6 +82,33 @@ s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data); | |||
77 | #define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */ | 82 | #define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */ |
78 | #define IGP01E1000_PSCFR_SMART_SPEED 0x0080 | 83 | #define IGP01E1000_PSCFR_SMART_SPEED 0x0080 |
79 | 84 | ||
85 | #define I82580_ADDR_REG 16 | ||
86 | #define I82580_CFG_REG 22 | ||
87 | #define I82580_CFG_ASSERT_CRS_ON_TX (1 << 15) | ||
88 | #define I82580_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */ | ||
89 | #define I82580_CTRL_REG 23 | ||
90 | #define I82580_CTRL_DOWNSHIFT_MASK (7 << 10) | ||
91 | |||
92 | /* 82580 specific PHY registers */ | ||
93 | #define I82580_PHY_CTRL_2 18 | ||
94 | #define I82580_PHY_LBK_CTRL 19 | ||
95 | #define I82580_PHY_STATUS_2 26 | ||
96 | #define I82580_PHY_DIAG_STATUS 31 | ||
97 | |||
98 | /* I82580 PHY Status 2 */ | ||
99 | #define I82580_PHY_STATUS2_REV_POLARITY 0x0400 | ||
100 | #define I82580_PHY_STATUS2_MDIX 0x0800 | ||
101 | #define I82580_PHY_STATUS2_SPEED_MASK 0x0300 | ||
102 | #define I82580_PHY_STATUS2_SPEED_1000MBPS 0x0200 | ||
103 | #define I82580_PHY_STATUS2_SPEED_100MBPS 0x0100 | ||
104 | |||
105 | /* I82580 PHY Control 2 */ | ||
106 | #define I82580_PHY_CTRL2_AUTO_MDIX 0x0400 | ||
107 | #define I82580_PHY_CTRL2_FORCE_MDI_MDIX 0x0200 | ||
108 | |||
109 | /* I82580 PHY Diagnostics Status */ | ||
110 | #define I82580_DSTATUS_CABLE_LENGTH 0x03FC | ||
111 | #define I82580_DSTATUS_CABLE_LENGTH_SHIFT 2 | ||
80 | /* Enable flexible speed on link-up */ | 112 | /* Enable flexible speed on link-up */ |
81 | #define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */ | 113 | #define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */ |
82 | #define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */ | 114 | #define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */ |