Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 May 2011 17:15:57 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r221818 - head/sys/dev/bge
Message-ID:  <201105121715.p4CHFvO1046184@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Thu May 12 17:15:57 2011
New Revision: 221818
URL: http://svn.freebsd.org/changeset/base/221818

Log:
  Add initial BCM5719 support. TSO and jumbo frame was intentionally
  disabled for BCM5719 A0 revision due to known hardware errata.
  Many thanks to Broadcom for continuing support of FreeBSD.
  
  Submitted by:	Geans Pin at Broadcom

Modified:
  head/sys/dev/bge/if_bge.c
  head/sys/dev/bge/if_bgereg.h

Modified: head/sys/dev/bge/if_bge.c
==============================================================================
--- head/sys/dev/bge/if_bge.c	Thu May 12 17:11:31 2011	(r221817)
+++ head/sys/dev/bge/if_bge.c	Thu May 12 17:15:57 2011	(r221818)
@@ -171,6 +171,7 @@ static const struct bge_type {
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5715S },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5717 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5718 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5719 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5720 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5721 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5722 },
@@ -299,6 +300,7 @@ static const struct bge_revision {
 	{ BGE_CHIPID_BCM5715_A3,	"BCM5715 A3" },
 	{ BGE_CHIPID_BCM5717_A0,	"BCM5717 A0" },
 	{ BGE_CHIPID_BCM5717_B0,	"BCM5717 B0" },
+	{ BGE_CHIPID_BCM5719_A0,	"BCM5719 A0" },
 	{ BGE_CHIPID_BCM5755_A0,	"BCM5755 A0" },
 	{ BGE_CHIPID_BCM5755_A1,	"BCM5755 A1" },
 	{ BGE_CHIPID_BCM5755_A2,	"BCM5755 A2" },
@@ -346,6 +348,7 @@ static const struct bge_revision const b
 	{ BGE_ASICREV_BCM57765,		"unknown BCM57765" },
 	{ BGE_ASICREV_BCM57780,		"unknown BCM57780" },
 	{ BGE_ASICREV_BCM5717,		"unknown BCM5717" },
+	{ BGE_ASICREV_BCM5719,		"unknown BCM5719" },
 
 	{ 0, NULL }
 };
@@ -1481,6 +1484,14 @@ bge_chipinit(struct bge_softc *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 (sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
+		    sc->bge_asicrev != BGE_ASICREV_BCM57765)
+			dma_rw_ctl |= BGE_PCIDMARWCTL_TAGGED_STATUS_WA;
 	}
 	pci_write_config(sc->bge_dev, BGE_PCI_DMA_RW_CTL, dma_rw_ctl, 4);
 
@@ -1537,7 +1548,7 @@ bge_blockinit(struct bge_softc *sc)
 	struct bge_rcb *rcb;
 	bus_size_t vrcb;
 	bge_hostaddr taddr;
-	uint32_t val;
+	uint32_t dmactl, val;
 	int i, limit;
 
 	/*
@@ -1594,8 +1605,16 @@ bge_blockinit(struct bge_softc *sc)
 	CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10);
 
 	/* Enable buffer manager */
-	CSR_WRITE_4(sc, BGE_BMAN_MODE,
-	    BGE_BMANMODE_ENABLE | BGE_BMANMODE_LOMBUF_ATTN);
+	val = BGE_BMANMODE_ENABLE | BGE_BMANMODE_LOMBUF_ATTN;
+	/*
+	 * Change the arbitration algorithm of TXMBUF read request to
+	 * round-robin instead of priority based for BCM5719.  When
+	 * TXFIFO is almost empty, RDMA will hold its request until
+	 * TXFIFO is not almost empty.
+	 */
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
+		val |= BGE_BMANMODE_NO_TX_UNDERRUN;
+	CSR_WRITE_4(sc, BGE_BMAN_MODE, val);
 
 	/* Poll for buffer manager start indication */
 	for (i = 0; i < BGE_TIMEOUT; i++) {
@@ -1692,7 +1711,8 @@ bge_blockinit(struct bge_softc *sc)
 		rcb->bge_maxlen_flags =
 		    BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);
 	}
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5717)
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5719)
 		rcb->bge_nicaddr = BGE_STD_RX_RINGS_5717;
 	else
 		rcb->bge_nicaddr = BGE_STD_RX_RINGS;
@@ -1724,7 +1744,8 @@ bge_blockinit(struct bge_softc *sc)
 		    BUS_DMASYNC_PREREAD);
 		rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,
 		    BGE_RCB_FLAG_USE_EXT_RX_BD | BGE_RCB_FLAG_RING_DISABLED);
-		if (sc->bge_asicrev == BGE_ASICREV_BCM5717)
+		if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
+		    sc->bge_asicrev == BGE_ASICREV_BCM5719)
 			rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS_5717;
 		else
 			rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
@@ -1812,7 +1833,8 @@ bge_blockinit(struct bge_softc *sc)
 	BGE_HOSTADDR(taddr, sc->bge_ldata.bge_tx_ring_paddr);
 	RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
 	RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5717)
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5719)
 		RCB_WRITE_4(sc, vrcb, bge_nicaddr, BGE_SEND_RING_5717);
 	else
 		RCB_WRITE_4(sc, vrcb, bge_nicaddr,
@@ -1825,7 +1847,8 @@ bge_blockinit(struct bge_softc *sc)
 	 * 'ring diabled' bit in the flags field of all the receive
 	 * return ring control blocks, located in NIC memory.
 	 */
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5717) {
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5719) {
 		/* Should be 17, use 16 until we get an SRAM map. */
 		limit = 16;
 	} else if (!BGE_IS_5705_PLUS(sc))
@@ -2029,15 +2052,35 @@ bge_blockinit(struct bge_softc *sc)
 	    sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
 	    sc->bge_asicrev == BGE_ASICREV_BCM57780 ||
 	    BGE_IS_5717_PLUS(sc)) {
+		dmactl = CSR_READ_4(sc, BGE_RDMA_RSRVCTRL);
+		/*
+		 * Adjust tx margin to prevent TX data corruption and
+		 * fix internal FIFO overflow.
+		 */
+		if (sc->bge_asicrev == BGE_ASICREV_BCM5719) {
+			dmactl &= ~(BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK |
+			    BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK |
+			    BGE_RDMA_RSRVCTRL_TXMRGN_MASK);
+			dmactl |= BGE_RDMA_RSRVCTRL_FIFO_LWM_1_5K |
+			    BGE_RDMA_RSRVCTRL_FIFO_HWM_1_5K |
+			    BGE_RDMA_RSRVCTRL_TXMRGN_320B;
+		}
 		/*
 		 * Enable fix for read DMA FIFO overruns.
 		 * The fix is to limit the number of RX BDs
 		 * the hardware would fetch at a fime.
 		 */
-		CSR_WRITE_4(sc, BGE_RDMA_RSRVCTRL,
-		    CSR_READ_4(sc, BGE_RDMA_RSRVCTRL) |
+		CSR_WRITE_4(sc, BGE_RDMA_RSRVCTRL, dmactl |
 		    BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
 	}
+
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5719) {
+		CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL,
+		    CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) |
+		    BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K |
+		    BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
+	}
+
 	CSR_WRITE_4(sc, BGE_RDMA_MODE, val);
 	DELAY(40);
 
@@ -2189,6 +2232,7 @@ bge_probe(device_t dev)
 				switch (pci_get_device(dev)) {
 				case BCOM_DEVICEID_BCM5717:
 				case BCOM_DEVICEID_BCM5718:
+				case BCOM_DEVICEID_BCM5719:
 					id = pci_read_config(dev,
 					    BGE_PCI_GEN2_PRODID_ASICREV, 4);
 					break;
@@ -2712,6 +2756,7 @@ bge_attach(device_t dev)
 		switch (pci_get_device(dev)) {
 		case BCOM_DEVICEID_BCM5717:
 		case BCOM_DEVICEID_BCM5718:
+		case BCOM_DEVICEID_BCM5719:
 			sc->bge_chipid = pci_read_config(dev,
 			    BGE_PCI_GEN2_PRODID_ASICREV, 4);
 			break;
@@ -2742,11 +2787,13 @@ bge_attach(device_t dev)
 	  * BCM57XX  |   1   |   X   |   X   |   X   |
 	  * BCM5704  |   1   |   X   |   1   |   X   |
 	  * BCM5717  |   1   |   8   |   2   |   9   |
+	  * BCM5719  |   1   |   8   |   2   |   9   |
 	  *
 	  * Other addresses may respond but they are not
 	  * IEEE compliant PHYs and should be ignored.
 	  */
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5717) {
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5719) {
 		f = pci_get_function(dev);
 		if (sc->bge_chipid == BGE_CHIPID_BCM5717_A0) {
 			if (CSR_READ_4(sc, BGE_SGDIG_STS) &
@@ -2754,7 +2801,7 @@ bge_attach(device_t dev)
 				phy_addr = f + 8;
 			else
 				phy_addr = f + 1;
-		} else if (sc->bge_chipid == BGE_CHIPID_BCM5717_B0) {
+		} else {
 			if (CSR_READ_4(sc, BGE_CPMU_PHY_STRAP) &
 			    BGE_CPMU_PHY_STRAP_IS_SERDES)
 				phy_addr = f + 8;
@@ -2780,11 +2827,17 @@ bge_attach(device_t dev)
 	/* Save chipset family. */
 	switch (sc->bge_asicrev) {
 	case BGE_ASICREV_BCM5717:
+	case BGE_ASICREV_BCM5719:
 		sc->bge_flags |= BGE_FLAG_SHORT_DMA_BUG;
 	case BGE_ASICREV_BCM57765:
 		sc->bge_flags |= BGE_FLAG_5717_PLUS | BGE_FLAG_5755_PLUS |
 		    BGE_FLAG_575X_PLUS | BGE_FLAG_5705_PLUS | BGE_FLAG_JUMBO |
 		    BGE_FLAG_JUMBO_FRAME;
+		if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
+		    sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
+			/* Jumbo frame on BCM5719 A0 does not work. */
+			sc->bge_flags &= ~BGE_FLAG_JUMBO_FRAME;
+		}
 		break;
 	case BGE_ASICREV_BCM5755:
 	case BGE_ASICREV_BCM5761:
@@ -2832,6 +2885,7 @@ bge_attach(device_t dev)
 	if ((BGE_IS_5705_PLUS(sc)) &&
 	    sc->bge_asicrev != BGE_ASICREV_BCM5906 &&
 	    sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
+	    sc->bge_asicrev != BGE_ASICREV_BCM5719 &&
 	    sc->bge_asicrev != BGE_ASICREV_BCM5785 &&
 	    sc->bge_asicrev != BGE_ASICREV_BCM57765 &&
 	    sc->bge_asicrev != BGE_ASICREV_BCM57780) {
@@ -2914,6 +2968,11 @@ bge_attach(device_t dev)
 	if (BGE_IS_5717_PLUS(sc)) {
 		/* BCM5717 requires different TSO configuration. */
 		sc->bge_flags |= BGE_FLAG_TSO3;
+		if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
+		    sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
+			/* TSO on BCM5719 A0 does not work. */
+			sc->bge_flags &= ~BGE_FLAG_TSO3;
+		}
 	} else if (BGE_IS_5755_PLUS(sc)) {
 		/*
 		 * BCM5754 and BCM5787 shares the same ASIC id so
@@ -2936,7 +2995,9 @@ bge_attach(device_t dev)
 		 */
 		sc->bge_flags |= BGE_FLAG_PCIE;
 		sc->bge_expcap = reg;
-		if (pci_get_max_read_req(dev) != 4096)
+		if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
+			pci_set_max_read_req(dev, 2048);
+		else if (pci_get_max_read_req(dev) != 4096)
 			pci_set_max_read_req(dev, 4096);
 	} else {
 		/*

Modified: head/sys/dev/bge/if_bgereg.h
==============================================================================
--- head/sys/dev/bge/if_bgereg.h	Thu May 12 17:11:31 2011	(r221817)
+++ head/sys/dev/bge/if_bgereg.h	Thu May 12 17:15:57 2011	(r221818)
@@ -319,6 +319,7 @@
 #define	BGE_CHIPID_BCM57780_A1		0x57780001
 #define	BGE_CHIPID_BCM5717_A0		0x05717000
 #define	BGE_CHIPID_BCM5717_B0		0x05717100
+#define	BGE_CHIPID_BCM5719_A0		0x05719000
 #define	BGE_CHIPID_BCM57765_A0		0x57785000
 #define	BGE_CHIPID_BCM57765_B0		0x57785100
 
@@ -342,6 +343,7 @@
 #define	BGE_ASICREV_USE_PRODID_REG	0x0f
 /* BGE_PCI_PRODID_ASICREV ASIC rev. identifiers. */
 #define	BGE_ASICREV_BCM5717		0x5717
+#define	BGE_ASICREV_BCM5719		0x5719
 #define	BGE_ASICREV_BCM5761		0x5761
 #define	BGE_ASICREV_BCM5784		0x5784
 #define	BGE_ASICREV_BCM5785		0x5785
@@ -385,6 +387,7 @@
 #define	BGE_PCIDMARWCTL_RD_CMD_SHIFT(x)	((x) << 24)
 #define	BGE_PCIDMARWCTL_WR_CMD_SHIFT(x)	((x) << 28)
 
+#define	BGE_PCIDMARWCTL_TAGGED_STATUS_WA	0x00000080
 #define	BGE_PCIDMARWCTL_CRDRDR_RDMA_MRRS_MSK	0x00000380
 
 #define	BGE_PCI_READ_BNDRY_DISABLE	0x00000000
@@ -1494,6 +1497,7 @@
 #define	BGE_BMANMODE_ATTN		0x00000004
 #define	BGE_BMANMODE_TESTMODE		0x00000008
 #define	BGE_BMANMODE_LOMBUF_ATTN	0x00000010
+#define	BGE_BMANMODE_NO_TX_UNDERRUN	0x80000000
 
 /* Buffer manager status register */
 #define	BGE_BMANSTAT_ERRO		0x00000004
@@ -1506,6 +1510,7 @@
 #define	BGE_RDMA_MODE			0x4800
 #define	BGE_RDMA_STATUS			0x4804
 #define	BGE_RDMA_RSRVCTRL		0x4900
+#define	BGE_RDMA_LSO_CRPTEN_CTRL	0x4910
 
 /* Read DMA mode register */
 #define	BGE_RDMAMODE_RESET		0x00000001
@@ -1540,6 +1545,15 @@
 
 /* Read DMA Reserved Control register */
 #define	BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX	0x00000004
+#define	BGE_RDMA_RSRVCTRL_FIFO_LWM_1_5K	0x00000C00
+#define	BGE_RDMA_RSRVCTRL_FIFO_HWM_1_5K	0x000C0000
+#define	BGE_RDMA_RSRVCTRL_TXMRGN_320B	0x28000000
+#define	BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK	0x00000FF0
+#define	BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK	0x000FF000
+#define	BGE_RDMA_RSRVCTRL_TXMRGN_MASK	0xFFE00000
+
+#define	BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K	0x00030000
+#define	BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K	0x000C0000
 
 /*
  * Write DMA control registers
@@ -2261,6 +2275,7 @@ struct bge_status_block {
 #define	BCOM_DEVICEID_BCM5715S		0x1679
 #define	BCOM_DEVICEID_BCM5717		0x1655
 #define	BCOM_DEVICEID_BCM5718		0x1656
+#define	BCOM_DEVICEID_BCM5719		0x1657
 #define	BCOM_DEVICEID_BCM5720		0x1658
 #define	BCOM_DEVICEID_BCM5721		0x1659
 #define	BCOM_DEVICEID_BCM5722		0x165A



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105121715.p4CHFvO1046184>