Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci - Add some workarounds for 5717 A0 and 5776[56] ...



details:   https://anonhg.NetBSD.org/src/rev/5f66b28fb361
branches:  trunk
changeset: 785429:5f66b28fb361
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Wed Mar 13 09:44:20 2013 +0000

description:
- Add some workarounds for 5717 A0 and 5776[56] to be stable.
  From Linux tg3 driver.
- Use macro.

diffstat:

 sys/dev/pci/if_bge.c    |  135 ++++++++++++++++++++++++++++++++++++++++++++---
 sys/dev/pci/if_bgereg.h |   84 ++++++++++++++++++++++++++++-
 2 files changed, 205 insertions(+), 14 deletions(-)

diffs (truncated from 384 to 300 lines):

diff -r 8124a8c40539 -r 5f66b28fb361 sys/dev/pci/if_bge.c
--- a/sys/dev/pci/if_bge.c      Wed Mar 13 08:05:46 2013 +0000
+++ b/sys/dev/pci/if_bge.c      Wed Mar 13 09:44:20 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bge.c,v 1.213 2013/03/07 10:57:01 msaitoh Exp $     */
+/*     $NetBSD: if_bge.c,v 1.214 2013/03/13 09:44:20 msaitoh Exp $     */
 
 /*
  * Copyright (c) 2001 Wind River Systems
@@ -79,7 +79,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.213 2013/03/07 10:57:01 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.214 2013/03/13 09:44:20 msaitoh Exp $");
 
 #include "vlan.h"
 
@@ -652,6 +652,8 @@
 #define BGE_IS_5705_PLUS(sc)   ((sc)->bge_flags & BGE_5705_PLUS)
 #define BGE_IS_575X_PLUS(sc)   ((sc)->bge_flags & BGE_575X_PLUS)
 #define BGE_IS_5755_PLUS(sc)   ((sc)->bge_flags & BGE_5755_PLUS)
+#define BGE_IS_5717_PLUS(sc)           ((sc)->bge_flags & BGE_5717_PLUS)
+#define BGE_IS_57765_PLUS(sc)          ((sc)->bge_flags & BGE_57765_PLUS)
 #define BGE_IS_JUMBO_CAPABLE(sc)       ((sc)->bge_flags & BGE_JUMBO_CAPABLE)
 
 static const struct bge_revision {
@@ -717,6 +719,8 @@
        { BGE_CHIPID_BCM5906_A0, "BCM5906 A0" },
        { BGE_CHIPID_BCM5906_A1, "BCM5906 A1" },
        { BGE_CHIPID_BCM5906_A2, "BCM5906 A2" },
+       { BGE_CHIPID_BCM57765_A0, "BCM57765 A0" },
+       { BGE_CHIPID_BCM57765_B0, "BCM57765 B0" },
        { BGE_CHIPID_BCM57780_A0, "BCM57780 A0" },
        { BGE_CHIPID_BCM57780_A1, "BCM57780 A1" },
 
@@ -1793,6 +1797,11 @@
                }
        }
 
+       if (sc->bge_chipid == BGE_CHIPID_BCM57765_A0) {
+               /* tg3 says we have to wait extra time */
+               delay(10 * 1000);
+       }
+
        return 0;
 }
 
@@ -1803,8 +1812,8 @@
 static int
 bge_chipinit(struct bge_softc *sc)
 {
+       uint32_t dma_rw_ctl, mode_ctl, reg;
        int i;
-       uint32_t dma_rw_ctl;
 
        /* Set endianness before we access any non-PCI registers. */
        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
@@ -1828,6 +1837,75 @@
            i < BGE_STATUS_BLOCK_END + 1; i += sizeof(uint32_t))
                BGE_MEMWIN_WRITE(sc->sc_pc, sc->sc_pcitag, i, 0);
 
+       /* 5717 workaround from tg3 */
+       if (sc->bge_chipid == BGE_CHIPID_BCM5717_A0) {
+               /* Save */
+               mode_ctl = CSR_READ_4(sc, BGE_MODE_CTL);
+
+               /* Temporary modify MODE_CTL to control TLP */
+               reg = mode_ctl & ~BGE_MODECTL_PCIE_TLPADDRMASK;
+               CSR_WRITE_4(sc, BGE_MODE_CTL, reg | BGE_MODECTL_PCIE_TLPADDR1);
+
+               /* Control TLP */
+               reg = CSR_READ_4(sc, BGE_TLP_CONTROL_REG +
+                   BGE_TLP_PHYCTL1);
+               CSR_WRITE_4(sc, BGE_TLP_CONTROL_REG + BGE_TLP_PHYCTL1,
+                   reg | BGE_TLP_PHYCTL1_EN_L1PLLPD);
+
+               /* Restore */
+               CSR_WRITE_4(sc, BGE_MODE_CTL, mode_ctl);
+       }
+               
+       /* XXX Should we use 57765_FAMILY? */
+       if (BGE_IS_57765_PLUS(sc)) {
+               if (sc->bge_chipid == BGE_CHIPID_BCM57765_A0) {
+                       /* Save */
+                       mode_ctl = CSR_READ_4(sc, BGE_MODE_CTL);
+
+                       /* Temporary modify MODE_CTL to control TLP */
+                       reg = mode_ctl & ~BGE_MODECTL_PCIE_TLPADDRMASK;
+                       CSR_WRITE_4(sc, BGE_MODE_CTL,
+                           reg | BGE_MODECTL_PCIE_TLPADDR1);
+                       
+                       /* Control TLP */
+                       reg = CSR_READ_4(sc, BGE_TLP_CONTROL_REG +
+                           BGE_TLP_PHYCTL5);
+                       CSR_WRITE_4(sc, BGE_TLP_CONTROL_REG + BGE_TLP_PHYCTL5,
+                           reg | BGE_TLP_PHYCTL5_DIS_L2CLKREQ);
+
+                       /* Restore */
+                       CSR_WRITE_4(sc, BGE_MODE_CTL, mode_ctl);
+               }
+               if (BGE_CHIPREV(sc->bge_chipid) != BGE_CHIPREV_57765_AX) {
+                       reg = CSR_READ_4(sc, BGE_CPMU_PADRNG_CTL);
+                       CSR_WRITE_4(sc, BGE_CPMU_PADRNG_CTL,
+                           reg | BGE_CPMU_PADRNG_CTL_RDIV2);
+
+                       /* Save */
+                       mode_ctl = CSR_READ_4(sc, BGE_MODE_CTL);
+
+                       /* Temporary modify MODE_CTL to control TLP */
+                       reg = mode_ctl & ~BGE_MODECTL_PCIE_TLPADDRMASK;
+                       CSR_WRITE_4(sc, BGE_MODE_CTL,
+                           reg | BGE_MODECTL_PCIE_TLPADDR0);
+
+                       /* Control TLP */
+                       reg = CSR_READ_4(sc, BGE_TLP_CONTROL_REG +
+                           BGE_TLP_FTSMAX);
+                       reg &= ~BGE_TLP_FTSMAX_MSK;
+                       CSR_WRITE_4(sc, BGE_TLP_CONTROL_REG + BGE_TLP_FTSMAX,
+                           reg | BGE_TLP_FTSMAX_VAL);
+
+                       /* Restore */
+                       CSR_WRITE_4(sc, BGE_MODE_CTL, mode_ctl);
+               }
+
+               reg = CSR_READ_4(sc, BGE_CPMU_LSPD_10MB_CLK);
+               reg &= ~BGE_CPMU_LSPD_10MB_MACCLK_MASK;
+               reg |= BGE_CPMU_LSPD_10MB_MACCLK_6_25;
+               CSR_WRITE_4(sc, BGE_CPMU_LSPD_10MB_CLK, reg);
+       }
+
        /* Set up the PCI DMA control register. */
        dma_rw_ctl = BGE_PCI_READ_CMD | BGE_PCI_WRITE_CMD;
        if (sc->bge_flags & BGE_PCIE) {
@@ -1894,6 +1972,21 @@
            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)
                dma_rw_ctl &= ~BGE_PCIDMARWCTL_MINDMA;
 
+       if (BGE_IS_5717_PLUS(sc)) {
+               dma_rw_ctl &= ~BGE_PCIDMARWCTL_DIS_CACHE_ALIGNMENT;
+               if (sc->bge_chipid == BGE_CHIPID_BCM57765_A0)
+                       dma_rw_ctl &= ~BGE_PCIDMARWCTL_CRDRDR_RDMA_MRRS_MSK;
+
+               /*
+                * Enable HW workaround for controllers that misinterpret
+                * a status tag update and leave interrupts permanently
+                * disabled.
+                */
+               if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5717 &&
+                   BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57765)
+                       dma_rw_ctl |= BGE_PCIDMARWCTL_TAGGED_STATUS_WA;
+       }
+
        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,
            dma_rw_ctl);
 
@@ -2720,6 +2813,13 @@
            BGE_IS_575X_PLUS(sc))
                sc->bge_flags |= BGE_5705_PLUS;
 
+       if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57765 ||
+           BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57766)
+               sc->bge_flags |= BGE_57765_PLUS;
+
+       if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||
+           BGE_IS_57765_PLUS(sc))
+               sc->bge_flags |= BGE_5717_PLUS;
        /*
         * When using the BCM5701 in PCI-X mode, data corruption has
         * been observed in the first few bytes of some received packets.
@@ -2833,6 +2933,14 @@
        else if (CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL)
                sc->bge_flags |= BGE_NO_EEPROM;
 
+       /* Identify the chips that use an CPMU. */
+       if (BGE_IS_5717_PLUS(sc) ||
+           BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 ||
+           BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761 ||
+           BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785 ||
+           BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780)
+               sc->bge_flags |= BGE_CPMU_PRESENT;
+
        /* Try to reset the chip. */
        DPRINTFN(5, ("bge_reset\n"));
        bge_reset(sc);
@@ -3187,9 +3295,14 @@
         * XXX: from FreeBSD/Linux; no documentation
         */
        if (sc->bge_flags & BGE_PCIE) {
-               if (CSR_READ_4(sc, BGE_PCIE_CTL1) == 0x60)
+               if (BGE_ASICREV(sc->bge_chipid != BGE_ASICREV_BCM5785) &&
+                   !BGE_IS_57765_PLUS(sc) &&
+                   (CSR_READ_4(sc, BGE_PCIE_CTL1) ==
+                       (BGE_PHY_PCIE_LTASS_MODE | BGE_PHY_PCIE_SCRAM_MODE))) {
                        /* PCI Express 1.0 system */
-                       CSR_WRITE_4(sc, BGE_PCIE_CTL1, 0x20);
+                       CSR_WRITE_4(sc, BGE_PHY_TEST_CTRL_REG,
+                           BGE_PHY_PCIE_SCRAM_MODE);
+               }
                if (sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {
                        /*
                         * Prevent PCI Express link training
@@ -3356,11 +3469,9 @@
        }
 
        if (sc->bge_flags & BGE_PCIE &&
+           !BGE_IS_57765_PLUS(sc) &&
            sc->bge_chipid != BGE_CHIPID_BCM5750_A0 &&
-           BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5717 &&
-           BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5785 &&
-           BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57765 &&
-           BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57766) {
+           BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5785) {
                uint32_t v;
 
                /* Enable PCI Express bug fix */
@@ -4966,6 +5077,10 @@
 {
 
        printf("Hardware Flags:\n");
+       if (BGE_IS_57765_PLUS(sc))
+               printf(" - 57765 Plus\n");
+       if (BGE_IS_5717_PLUS(sc))
+               printf(" - 5717 Plus\n");
        if (BGE_IS_5755_PLUS(sc))
                printf(" - 5755 Plus\n");
        if (BGE_IS_575X_PLUS(sc))
@@ -4990,6 +5105,8 @@
                printf(" - No 3 LEDs\n");
        if (sc->bge_flags & BGE_RX_ALIGNBUG)
                printf(" - RX Alignment Bug\n");
+       if (sc->bge_flags & BGE_CPMU_PRESENT)
+               printf(" - CPMU\n");
        if (sc->bge_flags & BGE_TSO)
                printf(" - TSO\n");
 }
diff -r 8124a8c40539 -r 5f66b28fb361 sys/dev/pci/if_bgereg.h
--- a/sys/dev/pci/if_bgereg.h   Wed Mar 13 08:05:46 2013 +0000
+++ b/sys/dev/pci/if_bgereg.h   Wed Mar 13 09:44:20 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bgereg.h,v 1.61 2013/02/27 14:19:38 msaitoh Exp $   */
+/*     $NetBSD: if_bgereg.h,v 1.62 2013/03/13 09:44:20 msaitoh Exp $   */
 /*
  * Copyright (c) 2001 Wind River Systems
  * Copyright (c) 1997, 1998, 1999, 2001
@@ -324,6 +324,9 @@
 #define BGE_CHIPID_BCM57762            0x57766000
 #define BGE_CHIPID_BCM57780_A0         0x57780000
 #define BGE_CHIPID_BCM57780_A1         0x57780001
+#define        BGE_CHIPID_BCM5717_A0           0x05717000
+#define        BGE_CHIPID_BCM57765_A0          0x57785000
+#define        BGE_CHIPID_BCM57765_B0          0x57785100
 
 /* shorthand one */
 #define BGE_ASICREV(x)                 ((x) >> 12)
@@ -361,9 +364,11 @@
 #define BGE_CHIPREV_5704_BX            0x21
 #define BGE_CHIPREV_5750_AX            0x40
 #define BGE_CHIPREV_5750_BX            0x41
+#define BGE_CHIPREV_57765_AX           0x577650
 
 /* PCI DMA Read/Write Control register */
 #define BGE_PCIDMARWCTL_MINDMA         0x000000FF
+#define        BGE_PCIDMARWCTL_DIS_CACHE_ALIGNMENT     0x00000001
 #define BGE_PCIDMARWCTL_RDADRR_BNDRY   0x00000700
 #define BGE_PCIDMARWCTL_WRADDR_BNDRY   0x00003800
 #define BGE_PCIDMARWCTL_ONEDMA_ATONCE  0x0000C000
@@ -381,9 +386,8 @@
 #define BGE_PCIDMARWCTL_RD_CMD_SHIFT(x)        ((x) << 24)
 #define BGE_PCIDMARWCTL_WR_CMD_SHIFT(x)        ((x) << 28)
 
-/* PCI DMA Read/Write Control register, alternate usage for PCI-Express */
-#define BGE_PCIDMA_RWCTL_PCIE_WRITE_WATRMARK_128       0x00180000
-#define BGE_PCIDMA_RWCTL_PCIE_WRITE_WATRMARK_256       0x00380000
+#define        BGE_PCIDMARWCTL_TAGGED_STATUS_WA        0x00000080
+#define        BGE_PCIDMARWCTL_CRDRDR_RDMA_MRRS_MSK    0x00000380
 
 #define BGE_PCI_READ_BNDRY_DISABLE     0x00000000
 #define BGE_PCI_READ_BNDRY_16BYTES     0x00000100
@@ -1171,6 +1175,60 @@
 /* Receive List Selector Status register */
 #define BGE_RXLSSTAT_ERROR             0x00000004
 
+/* Central Power Management Unit (CPMU) register */
+#define        BGE_CPMU_CTRL                   0x3600
+#define        BGE_CPMU_LSPD_10MB_CLK          0x3604
+#define        BGE_CPMU_LSPD_1000MB_CLK        0x360C
+#define        BGE_CPMU_LNK_AWARE_PWRMD        0x3610
+#define        BGE_CPMU_HST_ACC                0x361C
+#define        BGE_CPMU_CLCK_ORIDE             0x3624
+#define        BGE_CPMU_CLCK_STAT              0x3630
+#define        BGE_CPMU_MUTEX_REQ              0x365C
+#define        BGE_CPMU_MUTEX_GNT              0x3660
+#define        BGE_CPMU_PHY_STRAP              0x3664
+#define        BGE_CPMU_PADRNG_CTL             0x3668
+
+/* CPMU Control register */
+#define        BGE_CPMU_CTRL_LINK_IDLE_MODE    0x00000200
+#define        BGE_CPMU_CTRL_LINK_AWARE_MODE   0x00000400
+#define        BGE_CPMU_CTRL_LINK_SPEED_MODE   0x00004000



Home | Main Index | Thread Index | Old Index