qubes-linux-kernel/patches.drivers/tg3-5785-and-57780-asic-revs-not-working.patch
2011-04-19 22:09:59 +02:00

194 lines
6.3 KiB
Diff

From: Matt Carlson <mcarlson@broadcom.com>
Subject: tg3: 5785 and 57780 asic revs not working
References: bnc#580780
Patch-mainline: Never
There is a known problem with phylib that causes a lot of problems.
Phylib does not load phy modules as it detects devices on the MDIO bus.
If the phylib module gets loaded as a dependancy of tg3, there will be
no opportunity to load the needed broadcom.ko module before tg3 requests
phylib to probe the MDIO bus. The result will be that tg3 will fail to
attach to 5785 and 57780 devices.
There are several known solutions to this problem. (None of these
should go upstream. The upstream fix should be to get phylib to load
modules for devices it encounters.) Only one of them need be applied.
1) Statically link in the broadcom.ko module into the kernel.
2) Add the following to /etc/modprobe.d/local.conf or its equivalent:
install tg3 /sbin/modprobe broadcom; /sbin/modprobe --ignore-install tg3
3) Apply the following patch:
Signed-off-by: Brandon Philips <bphilips@suse.de>
---
drivers/net/tg3.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/tg3.h | 9 +++++
2 files changed, 92 insertions(+)
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1998,6 +1998,58 @@ static int tg3_phy_reset(struct tg3 *tp)
tg3_phy_toggle_apd(tp, false);
out:
+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM50610 ||
+ (tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM50610M) {
+ u32 reg;
+
+ /* Enable SM_DSP clock and tx 6dB coding. */
+ reg = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
+ MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
+ MII_TG3_AUXCTL_ACTL_TX_6DB;
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, reg);
+
+ reg = MII_TG3_DSP_EXP8_REJ2MHz;
+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, reg);
+
+ /* Apply workaround to A0 revision parts only. */
+ if (tp->phy_id == TG3_PHY_ID_BCM50610 ||
+ tp->phy_id == TG3_PHY_ID_BCM50610M) {
+ tg3_phydsp_write(tp, 0x001F, 0x0300);
+ tg3_phydsp_write(tp, 0x601F, 0x0002);
+ tg3_phydsp_write(tp, 0x0F75, 0x003C);
+ tg3_phydsp_write(tp, 0x0F96, 0x0010);
+ tg3_phydsp_write(tp, 0x0F97, 0x0C0C);
+ }
+
+ /* Turn off SM_DSP clock. */
+ reg = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
+ MII_TG3_AUXCTL_ACTL_TX_6DB;
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, reg);
+
+ /* Clear all mode configuration bits. */
+ reg = MII_TG3_MISC_SHDW_WREN |
+ MII_TG3_MISC_SHDW_RGMII_SEL;
+ tg3_writephy(tp, MII_TG3_MISC_SHDW, reg);
+ }
+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM57780) {
+ u32 reg;
+
+ /* Enable SM_DSP clock and tx 6dB coding. */
+ reg = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
+ MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
+ MII_TG3_AUXCTL_ACTL_TX_6DB;
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, reg);
+
+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, MII_TG3_DSP_EXP75);
+ tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &reg);
+ reg |= MII_TG3_DSP_EXP75_SUP_CM_OSC;
+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP75, reg);
+
+ /* Turn off SM_DSP clock. */
+ reg = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
+ MII_TG3_AUXCTL_ACTL_TX_6DB;
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, reg);
+ }
if (tp->phy_flags & TG3_PHYFLG_ADC_BUG) {
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
tg3_phydsp_write(tp, 0x201f, 0x2aaa);
@@ -2054,6 +2106,22 @@ out:
/* adjust output voltage */
tg3_writephy(tp, MII_TG3_FET_PTEST, 0x12);
}
+ else if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
+ u32 brcmtest;
+ if (!tg3_readphy(tp, MII_TG3_FET_TEST, &brcmtest) &&
+ !tg3_writephy(tp, MII_TG3_FET_TEST,
+ brcmtest | MII_TG3_FET_SHADOW_EN)) {
+ u32 val, reg = MII_TG3_FET_SHDW_AUXMODE4;
+
+ if (!tg3_readphy(tp, reg, &val)) {
+ val &= ~MII_TG3_FET_SHDW_AM4_LED_MASK;
+ val |= MII_TG3_FET_SHDW_AM4_LED_MODE1;
+ tg3_writephy(tp, reg, val);
+ }
+
+ tg3_writephy(tp, MII_TG3_FET_TEST, brcmtest);
+ }
+ }
tg3_phy_toggle_automdix(tp, 1);
tg3_phy_set_wirespeed(tp);
@@ -3288,6 +3356,15 @@ relink:
tg3_phy_eee_adjust(tp, current_link_up);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
+ if (tp->link_config.active_speed == SPEED_10)
+ tw32(MAC_MI_STAT,
+ MAC_MI_STAT_10MBPS_MODE |
+ MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
+ else
+ tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
+ }
+
if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
/* Polled via timer. */
tw32_f(MAC_EVENT, 0);
@@ -13411,9 +13488,11 @@ static int __devinit tg3_get_invariants(
GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
+#if 0
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
+#endif
err = tg3_mdio_init(tp);
if (err)
@@ -14203,6 +14282,10 @@ static char * __devinit tg3_phy_string(s
case TG3_PHY_ID_BCM5718S: return "5718S";
case TG3_PHY_ID_BCM57765: return "57765";
case TG3_PHY_ID_BCM5719C: return "5719C";
+ case TG3_PHY_ID_BCM50610: return "50610";
+ case TG3_PHY_ID_BCM50610M: return "50610M";
+ case TG3_PHY_ID_BCMAC131: return "AC131";
+ case TG3_PHY_ID_BCM57780: return "57780";
case TG3_PHY_ID_BCM8002: return "8002/serdes";
case 0: return "serdes";
default: return "unknown";
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2072,6 +2072,7 @@
#define MII_TG3_DSP_EXP8_REJ2MHz 0x0001
#define MII_TG3_DSP_EXP8_AEDW 0x0200
#define MII_TG3_DSP_EXP75 0x0f75
+#define MII_TG3_DSP_EXP75_SUP_CM_OSC 0x0001
#define MII_TG3_DSP_EXP96 0x0f96
#define MII_TG3_DSP_EXP97 0x0f97
@@ -2127,6 +2128,8 @@
#define MII_TG3_MISC_SHDW_SCR5_LPED 0x0010
#define MII_TG3_MISC_SHDW_SCR5_SEL 0x1400
+#define MII_TG3_MISC_SHDW_RGMII_SEL 0x2c00
+
#define MII_TG3_TEST1 0x1e
#define MII_TG3_TEST1_TRIM_EN 0x0010
#define MII_TG3_TEST1_CRC_EN 0x8000
@@ -2144,6 +2147,8 @@
#define MII_TG3_FET_SHDW_MISCCTRL_MDIX 0x4000
#define MII_TG3_FET_SHDW_AUXMODE4 0x1a
+#define MII_TG3_FET_SHDW_AM4_LED_MODE1 0x0001
+#define MII_TG3_FET_SHDW_AM4_LED_MASK 0x0003
#define MII_TG3_FET_SHDW_AUXMODE4_SBPD 0x0008
#define MII_TG3_FET_SHDW_AUXSTAT2 0x1b
@@ -2922,6 +2927,10 @@ struct tg3 {
#define TG3_PHY_ID_BCM5719C 0x5c0d8a20
#define TG3_PHY_ID_BCM5906 0xdc00ac40
#define TG3_PHY_ID_BCM8002 0x60010140
+#define TG3_PHY_ID_BCM50610 0xbc050d60
+#define TG3_PHY_ID_BCM50610M 0xbc050d70
+#define TG3_PHY_ID_BCMAC131 0xbc050c70
+#define TG3_PHY_ID_BCM57780 0x5c0d8990
#define TG3_PHY_ID_INVALID 0xffffffff
#define PHY_ID_RTL8211C 0x001cc910