Module Name: src Committed By: msaitoh Date: Wed Mar 13 09:44:21 UTC 2013
Modified Files: src/sys/dev/pci: if_bge.c if_bgereg.h Log Message: - Add some workarounds for 5717 A0 and 5776[56] to be stable. From Linux tg3 driver. - Use macro. To generate a diff of this commit: cvs rdiff -u -r1.213 -r1.214 src/sys/dev/pci/if_bge.c cvs rdiff -u -r1.61 -r1.62 src/sys/dev/pci/if_bgereg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/if_bge.c diff -u src/sys/dev/pci/if_bge.c:1.213 src/sys/dev/pci/if_bge.c:1.214 --- src/sys/dev/pci/if_bge.c:1.213 Thu Mar 7 10:57:01 2013 +++ src/sys/dev/pci/if_bge.c Wed Mar 13 09:44:20 2013 @@ -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 @@ static const struct bge_product { #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 @@ static const struct bge_revision { { 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 @@ bge_poll_fw(struct bge_softc *sc) } } + 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 @@ bge_poll_fw(struct bge_softc *sc) 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 @@ bge_chipinit(struct bge_softc *sc) 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_chipinit(struct bge_softc *sc) 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_attach(device_t parent, device_t sel 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 @@ bge_attach(device_t parent, device_t sel 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 @@ bge_reset(struct bge_softc *sc) * 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 @@ bge_reset(struct bge_softc *sc) } 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 @@ bge_debug_info(struct bge_softc *sc) { 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 @@ bge_debug_info(struct bge_softc *sc) 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"); } Index: src/sys/dev/pci/if_bgereg.h diff -u src/sys/dev/pci/if_bgereg.h:1.61 src/sys/dev/pci/if_bgereg.h:1.62 --- src/sys/dev/pci/if_bgereg.h:1.61 Wed Feb 27 14:19:38 2013 +++ src/sys/dev/pci/if_bgereg.h Wed Mar 13 09:44:20 2013 @@ -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 +#define BGE_CPMU_CTRL_GPHY_10MB_RXONLY 0x00010000 + +/* Link Speed 10MB/No Link Power Mode Clock Policy register */ +#define BGE_CPMU_LSPD_10MB_MACCLK_MASK 0x001F0000 +#define BGE_CPMU_LSPD_10MB_MACCLK_6_25 0x00130000 + +/* Link Speed 1000MB Power Mode Clock Policy register */ +#define BGE_CPMU_LSPD_1000MB_MACCLK_62_5 0x00000000 +#define BGE_CPMU_LSPD_1000MB_MACCLK_12_5 0x00110000 +#define BGE_CPMU_LSPD_1000MB_MACCLK_MASK 0x001F0000 + +/* Link Aware Power Mode Clock Policy register */ +#define BGE_CPMU_LNK_AWARE_MACCLK_MASK 0x001F0000 +#define BGE_CPMU_LNK_AWARE_MACCLK_6_25 0x00130000 + +#define BGE_CPMU_HST_ACC_MACCLK_MASK 0x001F0000 +#define BGE_CPMU_HST_ACC_MACCLK_6_25 0x00130000 + +/* Clock Speed Override Policy register */ +#define CPMU_CLCK_ORIDE_MAC_ORIDE_EN 0x80000000 + +/* CPMU Clock Status register */ +#define BGE_CPMU_CLCK_STAT_MAC_CLCK_MASK 0x001F0000 +#define BGE_CPMU_CLCK_STAT_MAC_CLCK_62_5 0x00000000 +#define BGE_CPMU_CLCK_STAT_MAC_CLCK_12_5 0x00110000 +#define BGE_CPMU_CLCK_STAT_MAC_CLCK_6_25 0x00130000 + +/* CPMU Mutex Request register */ +#define BGE_CPMU_MUTEX_REQ_DRIVER 0x00001000 +#define BGE_CPMU_MUTEX_GNT_DRIVER 0x00001000 + +/* CPMU GPHY Strap register */ +#define BGE_CPMU_PHY_STRAP_IS_SERDES 0x00000020 + +/* CPMU Padring Control register */ +#define BGE_CPMU_PADRNG_CTL_RDIV2 0x00040000 + /* * Mbuf Cluster Free registers (has nothing to do with BSD mbufs) */ @@ -1811,6 +1869,13 @@ * Applicable to BCM5721 and BCM5751 only */ #define BGE_TLP_CONTROL_REG 0x7c00 +#define BGE_TLP_FTSMAX 0x000c +#define BGE_TLP_FTSMAX_MSK 0x000000ff +#define BGE_TLP_FTSMAX_VAL 0x0000002c +#define BGE_TLP_PHYCTL1 0x0004 +#define BGE_TLP_PHYCTL1_EN_L1PLLPD 0x00001000 +#define BGE_TLP_PHYCTL5 0x0014 +#define BGE_TLP_PHYCTL5_DIS_L2CLKREQ 0x80000000 #define BGE_TLP_DATA_FIFO_PROTECT 0x02000000 /* @@ -1836,6 +1901,7 @@ #define BGE_MODECTL_STACKUP 0x00010000 #define BGE_MODECTL_HOST_SEND_BDS 0x00020000 #define BGE_MODECTL_TX_NO_PHDR_CSUM 0x00100000 +#define BGE_MODECTL_PCIE_TLPADDR1 0x00400000 #define BGE_MODECTL_RX_NO_PHDR_CSUM 0x00800000 #define BGE_MODECTL_TX_ATTN_INTR 0x01000000 #define BGE_MODECTL_RX_ATTN_INTR 0x02000000 @@ -1843,7 +1909,12 @@ #define BGE_MODECTL_DMA_ATTN_INTR 0x08000000 #define BGE_MODECTL_FLOWCTL_ATTN_INTR 0x10000000 #define BGE_MODECTL_4X_SENDRING_SZ 0x20000000 +#define BGE_MODECTL_PCIE_TLPADDR0 0x20000000 #define BGE_MODECTL_FW_PROCESS_MCASTS 0x40000000 +#define BGE_MODECTL_PCIE_TLPADDR2 0x80000000 +#define BGE_MODECTL_PCIE_TLPADDRMASK (BGE_MODECTL_PCIE_TLPADDR2 | \ + BGE_MODECTL_PCIE_TLPADDR1 | \ + BGE_MODECTL_PCIE_TLPADDR0) /* Misc. config register */ #define BGE_MISCCFG_RESET_CORE_CLOCKS 0x00000001 @@ -2387,4 +2458,7 @@ struct vpd_key { #define BGE_5755_PLUS 0x00800000 #define BGE_5714_FAMILY 0x01000000 #define BGE_5700_FAMILY 0x02000000 -#define BGE_TSO 0x04000000 +#define BGE_5717_PLUS 0x04000000 +#define BGE_57765_PLUS 0x08000000 +#define BGE_CPMU_PRESENT 0x20000000 +#define BGE_TSO 0x80000000