aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2010-10-14 06:37:41 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-17 16:57:44 -0400
commit52b02d04c801fff51ca49ad033210846d1713253 (patch)
tree719c03990321d703b192caf38186e30bb999885e /drivers/net/tg3.c
parentddfc87bfd16f370904c6ff7d23738335dd68d0ce (diff)
tg3: Add EEE support
This patch adds Energy Efficient Ethernet (EEE) support for the 5718 device ID and the 57765 B0 asic revision. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r--drivers/net/tg3.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index afcc593108ce..f2d96ddd464e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1584,6 +1584,17 @@ static void tg3_phy_fini(struct tg3 *tp)
1584 } 1584 }
1585} 1585}
1586 1586
1587static int tg3_phydsp_read(struct tg3 *tp, u32 reg, u32 *val)
1588{
1589 int err;
1590
1591 err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
1592 if (!err)
1593 err = tg3_readphy(tp, MII_TG3_DSP_RW_PORT, val);
1594
1595 return err;
1596}
1597
1587static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val) 1598static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
1588{ 1599{
1589 int err; 1600 int err;
@@ -1747,6 +1758,42 @@ static void tg3_phy_apply_otp(struct tg3 *tp)
1747 tg3_writephy(tp, MII_TG3_AUX_CTRL, phy); 1758 tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
1748} 1759}
1749 1760
1761static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
1762{
1763 u32 val;
1764
1765 if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP))
1766 return;
1767
1768 tp->setlpicnt = 0;
1769
1770 if (tp->link_config.autoneg == AUTONEG_ENABLE &&
1771 current_link_up == 1 &&
1772 (tp->link_config.active_speed == SPEED_1000 ||
1773 (tp->link_config.active_speed == SPEED_100 &&
1774 tp->link_config.active_duplex == DUPLEX_FULL))) {
1775 u32 eeectl;
1776
1777 if (tp->link_config.active_speed == SPEED_1000)
1778 eeectl = TG3_CPMU_EEE_CTRL_EXIT_16_5_US;
1779 else
1780 eeectl = TG3_CPMU_EEE_CTRL_EXIT_36_US;
1781
1782 tw32(TG3_CPMU_EEE_CTRL, eeectl);
1783
1784 tg3_phy_cl45_read(tp, 0x7, TG3_CL45_D7_EEERES_STAT, &val);
1785
1786 if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T ||
1787 val == TG3_CL45_D7_EEERES_STAT_LP_100TX)
1788 tp->setlpicnt = 2;
1789 }
1790
1791 if (!tp->setlpicnt) {
1792 val = tr32(TG3_CPMU_EEE_MODE);
1793 tw32(TG3_CPMU_EEE_MODE, val & ~TG3_CPMU_EEEMD_LPI_ENABLE);
1794 }
1795}
1796
1750static int tg3_wait_macro_done(struct tg3 *tp) 1797static int tg3_wait_macro_done(struct tg3 *tp)
1751{ 1798{
1752 int limit = 100; 1799 int limit = 100;
@@ -2921,6 +2968,44 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
2921 tg3_writephy(tp, MII_TG3_CTRL, new_adv); 2968 tg3_writephy(tp, MII_TG3_CTRL, new_adv);
2922 } 2969 }
2923 2970
2971 if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
2972 u32 val = 0;
2973
2974 tw32(TG3_CPMU_EEE_MODE,
2975 tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
2976
2977 /* Enable SM_DSP clock and tx 6dB coding. */
2978 val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
2979 MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
2980 MII_TG3_AUXCTL_ACTL_TX_6DB;
2981 tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
2982
2983 if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
2984 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
2985 !tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val))
2986 tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2,
2987 val | MII_TG3_DSP_CH34TP2_HIBW01);
2988
2989 if (tp->link_config.autoneg == AUTONEG_ENABLE) {
2990 /* Advertise 100-BaseTX EEE ability */
2991 if (tp->link_config.advertising &
2992 (ADVERTISED_100baseT_Half |
2993 ADVERTISED_100baseT_Full))
2994 val |= TG3_CL45_D7_EEEADV_CAP_100TX;
2995 /* Advertise 1000-BaseT EEE ability */
2996 if (tp->link_config.advertising &
2997 (ADVERTISED_1000baseT_Half |
2998 ADVERTISED_1000baseT_Full))
2999 val |= TG3_CL45_D7_EEEADV_CAP_1000T;
3000 }
3001 tg3_phy_cl45_write(tp, 0x7, TG3_CL45_D7_EEEADV_CAP, val);
3002
3003 /* Turn off SM_DSP clock. */
3004 val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
3005 MII_TG3_AUXCTL_ACTL_TX_6DB;
3006 tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
3007 }
3008
2924 if (tp->link_config.autoneg == AUTONEG_DISABLE && 3009 if (tp->link_config.autoneg == AUTONEG_DISABLE &&
2925 tp->link_config.speed != SPEED_INVALID) { 3010 tp->link_config.speed != SPEED_INVALID) {
2926 u32 bmcr, orig_bmcr; 3011 u32 bmcr, orig_bmcr;
@@ -3282,6 +3367,8 @@ relink:
3282 tw32_f(MAC_MODE, tp->mac_mode); 3367 tw32_f(MAC_MODE, tp->mac_mode);
3283 udelay(40); 3368 udelay(40);
3284 3369
3370 tg3_phy_eee_adjust(tp, current_link_up);
3371
3285 if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { 3372 if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
3286 /* Polled via timer. */ 3373 /* Polled via timer. */
3287 tw32_f(MAC_EVENT, 0); 3374 tw32_f(MAC_EVENT, 0);
@@ -7790,6 +7877,22 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
7790 tw32(TG3_CPMU_LSPD_10MB_CLK, val); 7877 tw32(TG3_CPMU_LSPD_10MB_CLK, val);
7791 } 7878 }
7792 7879
7880 /* Enable MAC control of LPI */
7881 if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
7882 tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL,
7883 TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
7884 TG3_CPMU_EEE_LNKIDL_UART_IDL);
7885
7886 tw32_f(TG3_CPMU_EEE_CTRL,
7887 TG3_CPMU_EEE_CTRL_EXIT_20_1_US);
7888
7889 tw32_f(TG3_CPMU_EEE_MODE,
7890 TG3_CPMU_EEEMD_ERLY_L1_XIT_DET |
7891 TG3_CPMU_EEEMD_LPI_IN_TX |
7892 TG3_CPMU_EEEMD_LPI_IN_RX |
7893 TG3_CPMU_EEEMD_EEE_ENABLE);
7894 }
7895
7793 /* This works around an issue with Athlon chipsets on 7896 /* This works around an issue with Athlon chipsets on
7794 * B3 tigon3 silicon. This bit has no effect on any 7897 * B3 tigon3 silicon. This bit has no effect on any
7795 * other revision. But do not set this on PCI Express 7898 * other revision. But do not set this on PCI Express
@@ -8598,6 +8701,12 @@ static void tg3_timer(unsigned long __opaque)
8598 if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) 8701 if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
8599 tg3_periodic_fetch_stats(tp); 8702 tg3_periodic_fetch_stats(tp);
8600 8703
8704 if (tp->setlpicnt && !--tp->setlpicnt) {
8705 u32 val = tr32(TG3_CPMU_EEE_MODE);
8706 tw32(TG3_CPMU_EEE_MODE,
8707 val | TG3_CPMU_EEEMD_LPI_ENABLE);
8708 }
8709
8601 if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { 8710 if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
8602 u32 mac_stat; 8711 u32 mac_stat;
8603 int phy_event; 8712 int phy_event;
@@ -12432,6 +12541,11 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
12432 } 12541 }
12433 } 12542 }
12434 12543
12544 if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
12545 (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
12546 tp->pci_chip_rev_id != CHIPREV_ID_57765_A0))
12547 tp->phy_flags |= TG3_PHYFLG_EEE_CAP;
12548
12435 if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && 12549 if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
12436 !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) && 12550 !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) &&
12437 !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { 12551 !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {