aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2007-07-11 22:48:29 -0400
committerDavid S. Miller <davem@davemloft.net>2007-07-11 22:48:29 -0400
commit9ef8ca99749784644602535691f8cf201ee2a225 (patch)
tree7836b055d04f88203b8cf563272696d6fe972e95 /drivers
parente8f3f6cad7e423253090887bc4afe7bc844162da (diff)
[TG3]: Enable auto MDI.
This patch adds automatic MDI crossover support when autonegotiation is turned off. Automatic MDI crossover allows link to be established without the use of a crossover cable. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/tg3.c56
-rw-r--r--drivers/net/tg3.h8
2 files changed, 49 insertions, 15 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 1df129aa3299..4f59e5c10c46 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -721,6 +721,44 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
721 return ret; 721 return ret;
722} 722}
723 723
724static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
725{
726 u32 phy;
727
728 if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
729 (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
730 return;
731
732 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
733 u32 ephy;
734
735 if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &ephy)) {
736 tg3_writephy(tp, MII_TG3_EPHY_TEST,
737 ephy | MII_TG3_EPHY_SHADOW_EN);
738 if (!tg3_readphy(tp, MII_TG3_EPHYTST_MISCCTRL, &phy)) {
739 if (enable)
740 phy |= MII_TG3_EPHYTST_MISCCTRL_MDIX;
741 else
742 phy &= ~MII_TG3_EPHYTST_MISCCTRL_MDIX;
743 tg3_writephy(tp, MII_TG3_EPHYTST_MISCCTRL, phy);
744 }
745 tg3_writephy(tp, MII_TG3_EPHY_TEST, ephy);
746 }
747 } else {
748 phy = MII_TG3_AUXCTL_MISC_RDSEL_MISC |
749 MII_TG3_AUXCTL_SHDWSEL_MISC;
750 if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, phy) &&
751 !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy)) {
752 if (enable)
753 phy |= MII_TG3_AUXCTL_MISC_FORCE_AMDIX;
754 else
755 phy &= ~MII_TG3_AUXCTL_MISC_FORCE_AMDIX;
756 phy |= MII_TG3_AUXCTL_MISC_WREN;
757 tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
758 }
759 }
760}
761
724static void tg3_phy_set_wirespeed(struct tg3 *tp) 762static void tg3_phy_set_wirespeed(struct tg3 *tp)
725{ 763{
726 u32 val; 764 u32 val;
@@ -1045,23 +1083,11 @@ out:
1045 } 1083 }
1046 1084
1047 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { 1085 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
1048 u32 phy_reg;
1049
1050 /* adjust output voltage */ 1086 /* adjust output voltage */
1051 tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x12); 1087 tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x12);
1052
1053 if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phy_reg)) {
1054 u32 phy_reg2;
1055
1056 tg3_writephy(tp, MII_TG3_EPHY_TEST,
1057 phy_reg | MII_TG3_EPHY_SHADOW_EN);
1058 /* Enable auto-MDIX */
1059 if (!tg3_readphy(tp, 0x10, &phy_reg2))
1060 tg3_writephy(tp, 0x10, phy_reg2 | 0x4000);
1061 tg3_writephy(tp, MII_TG3_EPHY_TEST, phy_reg);
1062 }
1063 } 1088 }
1064 1089
1090 tg3_phy_toggle_automdix(tp, 1);
1065 tg3_phy_set_wirespeed(tp); 1091 tg3_phy_set_wirespeed(tp);
1066 return 0; 1092 return 0;
1067} 1093}
@@ -8847,14 +8873,14 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
8847 phytest | MII_TG3_EPHY_SHADOW_EN); 8873 phytest | MII_TG3_EPHY_SHADOW_EN);
8848 if (!tg3_readphy(tp, 0x1b, &phy)) 8874 if (!tg3_readphy(tp, 0x1b, &phy))
8849 tg3_writephy(tp, 0x1b, phy & ~0x20); 8875 tg3_writephy(tp, 0x1b, phy & ~0x20);
8850 if (!tg3_readphy(tp, 0x10, &phy))
8851 tg3_writephy(tp, 0x10, phy & ~0x4000);
8852 tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest); 8876 tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest);
8853 } 8877 }
8854 val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100; 8878 val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100;
8855 } else 8879 } else
8856 val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000; 8880 val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000;
8857 8881
8882 tg3_phy_toggle_automdix(tp, 0);
8883
8858 tg3_writephy(tp, MII_BMCR, val); 8884 tg3_writephy(tp, MII_BMCR, val);
8859 udelay(40); 8885 udelay(40);
8860 8886
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index bd9f4f428e5b..e1b9381d3b41 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1642,6 +1642,11 @@
1642 1642
1643#define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */ 1643#define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */
1644 1644
1645#define MII_TG3_AUXCTL_MISC_WREN 0x8000
1646#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX 0x0200
1647#define MII_TG3_AUXCTL_MISC_RDSEL_MISC 0x7000
1648#define MII_TG3_AUXCTL_SHDWSEL_MISC 0x0007
1649
1645#define MII_TG3_AUX_STAT 0x19 /* auxilliary status register */ 1650#define MII_TG3_AUX_STAT 0x19 /* auxilliary status register */
1646#define MII_TG3_AUX_STAT_LPASS 0x0004 1651#define MII_TG3_AUX_STAT_LPASS 0x0004
1647#define MII_TG3_AUX_STAT_SPDMASK 0x0700 1652#define MII_TG3_AUX_STAT_SPDMASK 0x0700
@@ -1667,6 +1672,9 @@
1667#define MII_TG3_EPHY_TEST 0x1f /* 5906 PHY register */ 1672#define MII_TG3_EPHY_TEST 0x1f /* 5906 PHY register */
1668#define MII_TG3_EPHY_SHADOW_EN 0x80 1673#define MII_TG3_EPHY_SHADOW_EN 0x80
1669 1674
1675#define MII_TG3_EPHYTST_MISCCTRL 0x10 /* 5906 EPHY misc ctrl shadow register */
1676#define MII_TG3_EPHYTST_MISCCTRL_MDIX 0x4000
1677
1670#define MII_TG3_TEST1 0x1e 1678#define MII_TG3_TEST1 0x1e
1671#define MII_TG3_TEST1_TRIM_EN 0x0010 1679#define MII_TG3_TEST1_TRIM_EN 0x0010
1672#define MII_TG3_TEST1_CRC_EN 0x8000 1680#define MII_TG3_TEST1_CRC_EN 0x8000