aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/phy.c
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2009-12-02 12:03:18 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-02 22:57:17 -0500
commit0be8401051c716be4533272e983b7eed3d83946d (patch)
tree930068efd2f9ed4ccf1529382f8c59b850f3294e /drivers/net/e1000e/phy.c
parent5eb6f3c70fcc0fb19b9087863e6e29f96a76f3bd (diff)
e1000e: correct ICH/PCH PHY operations function pointers
Some function pointers for a few PHY operations (for 82578 and 82567) and were set incorrectly causing functions to be executed that were accessing incorrect PHY register offsets for that particular device. This patch also moves a few PHY-specific functions from ich8lan.c to the more appropriate phy.c. Signed-off-by: Bruce Allan <bruce.w.allan@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/e1000e/phy.c')
-rw-r--r--drivers/net/e1000e/phy.c191
1 files changed, 177 insertions, 14 deletions
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 67a718862e70..55a2c0acfee7 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -1322,17 +1322,22 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
1322 return ret_val; 1322 return ret_val;
1323 1323
1324 if (!link) { 1324 if (!link) {
1325 /* 1325 if (hw->phy.type != e1000_phy_m88) {
1326 * We didn't get link. 1326 e_dbg("Link taking longer than expected.\n");
1327 * Reset the DSP and cross our fingers. 1327 } else {
1328 */ 1328 /*
1329 ret_val = e1e_wphy(hw, M88E1000_PHY_PAGE_SELECT, 1329 * We didn't get link.
1330 0x001d); 1330 * Reset the DSP and cross our fingers.
1331 if (ret_val) 1331 */
1332 return ret_val; 1332 ret_val = e1e_wphy(hw,
1333 ret_val = e1000e_phy_reset_dsp(hw); 1333 M88E1000_PHY_PAGE_SELECT,
1334 if (ret_val) 1334 0x001d);
1335 return ret_val; 1335 if (ret_val)
1336 return ret_val;
1337 ret_val = e1000e_phy_reset_dsp(hw);
1338 if (ret_val)
1339 return ret_val;
1340 }
1336 } 1341 }
1337 1342
1338 /* Try once more */ 1343 /* Try once more */
@@ -1342,6 +1347,9 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
1342 return ret_val; 1347 return ret_val;
1343 } 1348 }
1344 1349
1350 if (hw->phy.type != e1000_phy_m88)
1351 return 0;
1352
1345 ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); 1353 ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
1346 if (ret_val) 1354 if (ret_val)
1347 return ret_val; 1355 return ret_val;
@@ -1371,6 +1379,73 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
1371} 1379}
1372 1380
1373/** 1381/**
1382 * e1000_phy_force_speed_duplex_ife - Force PHY speed & duplex
1383 * @hw: pointer to the HW structure
1384 *
1385 * Forces the speed and duplex settings of the PHY.
1386 * This is a function pointer entry point only called by
1387 * PHY setup routines.
1388 **/
1389s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
1390{
1391 struct e1000_phy_info *phy = &hw->phy;
1392 s32 ret_val;
1393 u16 data;
1394 bool link;
1395
1396 ret_val = e1e_rphy(hw, PHY_CONTROL, &data);
1397 if (ret_val)
1398 goto out;
1399
1400 e1000e_phy_force_speed_duplex_setup(hw, &data);
1401
1402 ret_val = e1e_wphy(hw, PHY_CONTROL, data);
1403 if (ret_val)
1404 goto out;
1405
1406 /* Disable MDI-X support for 10/100 */
1407 ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
1408 if (ret_val)
1409 goto out;
1410
1411 data &= ~IFE_PMC_AUTO_MDIX;
1412 data &= ~IFE_PMC_FORCE_MDIX;
1413
1414 ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, data);
1415 if (ret_val)
1416 goto out;
1417
1418 e_dbg("IFE PMC: %X\n", data);
1419
1420 udelay(1);
1421
1422 if (phy->autoneg_wait_to_complete) {
1423 e_dbg("Waiting for forced speed/duplex link on IFE phy.\n");
1424
1425 ret_val = e1000e_phy_has_link_generic(hw,
1426 PHY_FORCE_LIMIT,
1427 100000,
1428 &link);
1429 if (ret_val)
1430 goto out;
1431
1432 if (!link)
1433 e_dbg("Link taking longer than expected.\n");
1434
1435 /* Try once more */
1436 ret_val = e1000e_phy_has_link_generic(hw,
1437 PHY_FORCE_LIMIT,
1438 100000,
1439 &link);
1440 if (ret_val)
1441 goto out;
1442 }
1443
1444out:
1445 return ret_val;
1446}
1447
1448/**
1374 * e1000e_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex 1449 * e1000e_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
1375 * @hw: pointer to the HW structure 1450 * @hw: pointer to the HW structure
1376 * @phy_ctrl: pointer to current value of PHY_CONTROL 1451 * @phy_ctrl: pointer to current value of PHY_CONTROL
@@ -1557,7 +1632,7 @@ s32 e1000e_check_downshift(struct e1000_hw *hw)
1557 * 1632 *
1558 * Polarity is determined based on the PHY specific status register. 1633 * Polarity is determined based on the PHY specific status register.
1559 **/ 1634 **/
1560static s32 e1000_check_polarity_m88(struct e1000_hw *hw) 1635s32 e1000_check_polarity_m88(struct e1000_hw *hw)
1561{ 1636{
1562 struct e1000_phy_info *phy = &hw->phy; 1637 struct e1000_phy_info *phy = &hw->phy;
1563 s32 ret_val; 1638 s32 ret_val;
@@ -1582,7 +1657,7 @@ static s32 e1000_check_polarity_m88(struct e1000_hw *hw)
1582 * Polarity is determined based on the PHY port status register, and the 1657 * Polarity is determined based on the PHY port status register, and the
1583 * current speed (since there is no polarity at 100Mbps). 1658 * current speed (since there is no polarity at 100Mbps).
1584 **/ 1659 **/
1585static s32 e1000_check_polarity_igp(struct e1000_hw *hw) 1660s32 e1000_check_polarity_igp(struct e1000_hw *hw)
1586{ 1661{
1587 struct e1000_phy_info *phy = &hw->phy; 1662 struct e1000_phy_info *phy = &hw->phy;
1588 s32 ret_val; 1663 s32 ret_val;
@@ -1620,6 +1695,39 @@ static s32 e1000_check_polarity_igp(struct e1000_hw *hw)
1620} 1695}
1621 1696
1622/** 1697/**
1698 * e1000_check_polarity_ife - Check cable polarity for IFE PHY
1699 * @hw: pointer to the HW structure
1700 *
1701 * Polarity is determined on the polarity reversal feature being enabled.
1702 **/
1703s32 e1000_check_polarity_ife(struct e1000_hw *hw)
1704{
1705 struct e1000_phy_info *phy = &hw->phy;
1706 s32 ret_val;
1707 u16 phy_data, offset, mask;
1708
1709 /*
1710 * Polarity is determined based on the reversal feature being enabled.
1711 */
1712 if (phy->polarity_correction) {
1713 offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
1714 mask = IFE_PESC_POLARITY_REVERSED;
1715 } else {
1716 offset = IFE_PHY_SPECIAL_CONTROL;
1717 mask = IFE_PSC_FORCE_POLARITY;
1718 }
1719
1720 ret_val = e1e_rphy(hw, offset, &phy_data);
1721
1722 if (!ret_val)
1723 phy->cable_polarity = (phy_data & mask)
1724 ? e1000_rev_polarity_reversed
1725 : e1000_rev_polarity_normal;
1726
1727 return ret_val;
1728}
1729
1730/**
1623 * e1000_wait_autoneg - Wait for auto-neg completion 1731 * e1000_wait_autoneg - Wait for auto-neg completion
1624 * @hw: pointer to the HW structure 1732 * @hw: pointer to the HW structure
1625 * 1733 *
@@ -1823,7 +1931,7 @@ s32 e1000e_get_phy_info_m88(struct e1000_hw *hw)
1823 u16 phy_data; 1931 u16 phy_data;
1824 bool link; 1932 bool link;
1825 1933
1826 if (hw->phy.media_type != e1000_media_type_copper) { 1934 if (phy->media_type != e1000_media_type_copper) {
1827 e_dbg("Phy info is only valid for copper media\n"); 1935 e_dbg("Phy info is only valid for copper media\n");
1828 return -E1000_ERR_CONFIG; 1936 return -E1000_ERR_CONFIG;
1829 } 1937 }
@@ -1944,6 +2052,61 @@ s32 e1000e_get_phy_info_igp(struct e1000_hw *hw)
1944} 2052}
1945 2053
1946/** 2054/**
2055 * e1000_get_phy_info_ife - Retrieves various IFE PHY states
2056 * @hw: pointer to the HW structure
2057 *
2058 * Populates "phy" structure with various feature states.
2059 **/
2060s32 e1000_get_phy_info_ife(struct e1000_hw *hw)
2061{
2062 struct e1000_phy_info *phy = &hw->phy;
2063 s32 ret_val;
2064 u16 data;
2065 bool link;
2066
2067 ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
2068 if (ret_val)
2069 goto out;
2070
2071 if (!link) {
2072 e_dbg("Phy info is only valid if link is up\n");
2073 ret_val = -E1000_ERR_CONFIG;
2074 goto out;
2075 }
2076
2077 ret_val = e1e_rphy(hw, IFE_PHY_SPECIAL_CONTROL, &data);
2078 if (ret_val)
2079 goto out;
2080 phy->polarity_correction = (data & IFE_PSC_AUTO_POLARITY_DISABLE)
2081 ? false : true;
2082
2083 if (phy->polarity_correction) {
2084 ret_val = e1000_check_polarity_ife(hw);
2085 if (ret_val)
2086 goto out;
2087 } else {
2088 /* Polarity is forced */
2089 phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY)
2090 ? e1000_rev_polarity_reversed
2091 : e1000_rev_polarity_normal;
2092 }
2093
2094 ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
2095 if (ret_val)
2096 goto out;
2097
2098 phy->is_mdix = (data & IFE_PMC_MDIX_STATUS) ? true : false;
2099
2100 /* The following parameters are undefined for 10/100 operation. */
2101 phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
2102 phy->local_rx = e1000_1000t_rx_status_undefined;
2103 phy->remote_rx = e1000_1000t_rx_status_undefined;
2104
2105out:
2106 return ret_val;
2107}
2108
2109/**
1947 * e1000e_phy_sw_reset - PHY software reset 2110 * e1000e_phy_sw_reset - PHY software reset
1948 * @hw: pointer to the HW structure 2111 * @hw: pointer to the HW structure
1949 * 2112 *