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

Reply via email to