aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb/e1000_phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/igb/e1000_phy.c')
-rw-r--r--drivers/net/igb/e1000_phy.c219
1 files changed, 201 insertions, 18 deletions
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index cf1f32300923..d639706eb3f6 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -570,6 +570,89 @@ out:
570} 570}
571 571
572/** 572/**
573 * igb_copper_link_setup_m88_gen2 - Setup m88 PHY's for copper link
574 * @hw: pointer to the HW structure
575 *
576 * Sets up MDI/MDI-X and polarity for i347-AT4, m88e1322 and m88e1112 PHY's.
577 * Also enables and sets the downshift parameters.
578 **/
579s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw)
580{
581 struct e1000_phy_info *phy = &hw->phy;
582 s32 ret_val;
583 u16 phy_data;
584
585 if (phy->reset_disable) {
586 ret_val = 0;
587 goto out;
588 }
589
590 /* Enable CRS on Tx. This must be set for half-duplex operation. */
591 ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
592 if (ret_val)
593 goto out;
594
595 /*
596 * Options:
597 * MDI/MDI-X = 0 (default)
598 * 0 - Auto for all speeds
599 * 1 - MDI mode
600 * 2 - MDI-X mode
601 * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
602 */
603 phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
604
605 switch (phy->mdix) {
606 case 1:
607 phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
608 break;
609 case 2:
610 phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
611 break;
612 case 3:
613 /* M88E1112 does not support this mode) */
614 if (phy->id != M88E1112_E_PHY_ID) {
615 phy_data |= M88E1000_PSCR_AUTO_X_1000T;
616 break;
617 }
618 case 0:
619 default:
620 phy_data |= M88E1000_PSCR_AUTO_X_MODE;
621 break;
622 }
623
624 /*
625 * Options:
626 * disable_polarity_correction = 0 (default)
627 * Automatic Correction for Reversed Cable Polarity
628 * 0 - Disabled
629 * 1 - Enabled
630 */
631 phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
632 if (phy->disable_polarity_correction == 1)
633 phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
634
635 /* Enable downshift and setting it to X6 */
636 phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK;
637 phy_data |= I347AT4_PSCR_DOWNSHIFT_6X;
638 phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE;
639
640 ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
641 if (ret_val)
642 goto out;
643
644 /* Commit the changes. */
645 ret_val = igb_phy_sw_reset(hw);
646 if (ret_val) {
647 hw_dbg("Error committing the PHY changes\n");
648 goto out;
649 }
650
651out:
652 return ret_val;
653}
654
655/**
573 * igb_copper_link_setup_igp - Setup igp PHY's for copper link 656 * igb_copper_link_setup_igp - Setup igp PHY's for copper link
574 * @hw: pointer to the HW structure 657 * @hw: pointer to the HW structure
575 * 658 *
@@ -1124,18 +1207,25 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
1124 goto out; 1207 goto out;
1125 1208
1126 if (!link) { 1209 if (!link) {
1127 /* 1210 if (hw->phy.type != e1000_phy_m88 ||
1128 * We didn't get link. 1211 hw->phy.id == I347AT4_E_PHY_ID ||
1129 * Reset the DSP and cross our fingers. 1212 hw->phy.id == M88E1112_E_PHY_ID) {
1130 */ 1213 hw_dbg("Link taking longer than expected.\n");
1131 ret_val = phy->ops.write_reg(hw, 1214 } else {
1132 M88E1000_PHY_PAGE_SELECT, 1215
1133 0x001d); 1216 /*
1134 if (ret_val) 1217 * We didn't get link.
1135 goto out; 1218 * Reset the DSP and cross our fingers.
1136 ret_val = igb_phy_reset_dsp(hw); 1219 */
1137 if (ret_val) 1220 ret_val = phy->ops.write_reg(hw,
1138 goto out; 1221 M88E1000_PHY_PAGE_SELECT,
1222 0x001d);
1223 if (ret_val)
1224 goto out;
1225 ret_val = igb_phy_reset_dsp(hw);
1226 if (ret_val)
1227 goto out;
1228 }
1139 } 1229 }
1140 1230
1141 /* Try once more */ 1231 /* Try once more */
@@ -1145,6 +1235,11 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
1145 goto out; 1235 goto out;
1146 } 1236 }
1147 1237
1238 if (hw->phy.type != e1000_phy_m88 ||
1239 hw->phy.id == I347AT4_E_PHY_ID ||
1240 hw->phy.id == M88E1112_E_PHY_ID)
1241 goto out;
1242
1148 ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); 1243 ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
1149 if (ret_val) 1244 if (ret_val)
1150 goto out; 1245 goto out;
@@ -1326,7 +1421,7 @@ out:
1326} 1421}
1327 1422
1328/** 1423/**
1329 * igb_check_downshift - Checks whether a downshift in speed occured 1424 * igb_check_downshift - Checks whether a downshift in speed occurred
1330 * @hw: pointer to the HW structure 1425 * @hw: pointer to the HW structure
1331 * 1426 *
1332 * Success returns 0, Failure returns 1 1427 * Success returns 0, Failure returns 1
@@ -1557,6 +1652,93 @@ out:
1557 return ret_val; 1652 return ret_val;
1558} 1653}
1559 1654
1655s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw)
1656{
1657 struct e1000_phy_info *phy = &hw->phy;
1658 s32 ret_val;
1659 u16 phy_data, phy_data2, index, default_page, is_cm;
1660
1661 switch (hw->phy.id) {
1662 case I347AT4_E_PHY_ID:
1663 /* Remember the original page select and set it to 7 */
1664 ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
1665 &default_page);
1666 if (ret_val)
1667 goto out;
1668
1669 ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07);
1670 if (ret_val)
1671 goto out;
1672
1673 /* Get cable length from PHY Cable Diagnostics Control Reg */
1674 ret_val = phy->ops.read_reg(hw, (I347AT4_PCDL + phy->addr),
1675 &phy_data);
1676 if (ret_val)
1677 goto out;
1678
1679 /* Check if the unit of cable length is meters or cm */
1680 ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2);
1681 if (ret_val)
1682 goto out;
1683
1684 is_cm = !(phy_data & I347AT4_PCDC_CABLE_LENGTH_UNIT);
1685
1686 /* Populate the phy structure with cable length in meters */
1687 phy->min_cable_length = phy_data / (is_cm ? 100 : 1);
1688 phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
1689 phy->cable_length = phy_data / (is_cm ? 100 : 1);
1690
1691 /* Reset the page selec to its original value */
1692 ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
1693 default_page);
1694 if (ret_val)
1695 goto out;
1696 break;
1697 case M88E1112_E_PHY_ID:
1698 /* Remember the original page select and set it to 5 */
1699 ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
1700 &default_page);
1701 if (ret_val)
1702 goto out;
1703
1704 ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x05);
1705 if (ret_val)
1706 goto out;
1707
1708 ret_val = phy->ops.read_reg(hw, M88E1112_VCT_DSP_DISTANCE,
1709 &phy_data);
1710 if (ret_val)
1711 goto out;
1712
1713 index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
1714 M88E1000_PSSR_CABLE_LENGTH_SHIFT;
1715 if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
1716 ret_val = -E1000_ERR_PHY;
1717 goto out;
1718 }
1719
1720 phy->min_cable_length = e1000_m88_cable_length_table[index];
1721 phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
1722
1723 phy->cable_length = (phy->min_cable_length +
1724 phy->max_cable_length) / 2;
1725
1726 /* Reset the page select to its original value */
1727 ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
1728 default_page);
1729 if (ret_val)
1730 goto out;
1731
1732 break;
1733 default:
1734 ret_val = -E1000_ERR_PHY;
1735 goto out;
1736 }
1737
1738out:
1739 return ret_val;
1740}
1741
1560/** 1742/**
1561 * igb_get_cable_length_igp_2 - Determine cable length for igp2 PHY 1743 * igb_get_cable_length_igp_2 - Determine cable length for igp2 PHY
1562 * @hw: pointer to the HW structure 1744 * @hw: pointer to the HW structure
@@ -1575,11 +1757,12 @@ s32 igb_get_cable_length_igp_2(struct e1000_hw *hw)
1575 u16 phy_data, i, agc_value = 0; 1757 u16 phy_data, i, agc_value = 0;
1576 u16 cur_agc_index, max_agc_index = 0; 1758 u16 cur_agc_index, max_agc_index = 0;
1577 u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1; 1759 u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
1578 u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = 1760 static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = {
1579 {IGP02E1000_PHY_AGC_A, 1761 IGP02E1000_PHY_AGC_A,
1580 IGP02E1000_PHY_AGC_B, 1762 IGP02E1000_PHY_AGC_B,
1581 IGP02E1000_PHY_AGC_C, 1763 IGP02E1000_PHY_AGC_C,
1582 IGP02E1000_PHY_AGC_D}; 1764 IGP02E1000_PHY_AGC_D
1765 };
1583 1766
1584 /* Read the AGC registers for all channels */ 1767 /* Read the AGC registers for all channels */
1585 for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) { 1768 for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {