Subject: Re: patch for if_bge.c
To: None <andreas@planix.com>
From: SAITOH Masanobu <masanobu@iij.ad.jp>
List: current-users
Date: 09/27/2007 09:26:35
----Next_Part(Thu_Sep_27_09_26_35_2007_122)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
BTW, I made a jumbo patch for netbsd-3.
----Next_Part(Thu_Sep_27_09_26_35_2007_122)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="bgefornetbsd-3.dif"
sys/dev/pci/if_bge.c 1.89,1.95,1.97,1.101,1.103,
1.105,1.107,1.117-1.122,
1.128-1.131,1.133-1.135
via patch
sys/dev/pci/if_bgereg.h 1.31,1.34-1.39,1.42-1.43
sys/dev/pci/pcidevs patch
sys/dev/pci/pcidevs.h regen
sys/dev/pci/pcidevs_data regen
Some cleanups(typo, whitespace, debug message).
Add TSO support to bge(4)
Add support for BCM5715, BCM5752M, BCM5754, BCM5755, BCM5786 and 5787.
Add support for BCM5789. Fixes PR/33828 from Pawel Chwalowskibg.
Add support for BCM5753 and BCM5753M Fixes PR kern/36139 from
Mustafa Dogan.
Add and fix some BGE_CHIPIDs. From FreeBSD and OpenBSD.
In bge_ioctl(), don't call bge_init() if the interface is already up
(Makes ifwatchd work on this interface).
BCM5701 B2 requires BGE_QUIRK_ONLY_PHY_1 quirk. From Brian Baird in
PR kern/23778.
Move TX ring full sanity check further up and check the number of DMA
segments from the DMA map, instead of counting the DMA segments in the
for loop and breaking out later.
Unload the DMA map if encountering an error condition.
Fix a NULL reference on failing mbuf allocation.
In bge_start return if IFF_OACTIVE is set in combination with
IFF_RUNNING, drop obscure check for length of interface queue.
Remove message about failing bge_encap, it can happen just too easily
because of full descriptor rings.
Index: pcidevs
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pcidevs,v
retrieving revision 1.701.2.44
diff -u -r1.701.2.44 pcidevs
--- pcidevs 13 Sep 2007 19:47:14 -0000 1.701.2.44
+++ pcidevs 18 Sep 2007 06:58:41 -0000
@@ -1156,42 +1156,65 @@
product BLUESTEEL 5601 0x5601 5601
/* Broadcom products */
+product BROADCOM BCM5752 0x1600 BCM5752 10/100/1000 Ethernet
+product BROADCOM BCM5752M 0x1601 BCM5752M 10/100/1000 Ethernet
+product BROADCOM BCM5709 0x1639 BCM5709 NetXtreme II 1000baseT Ethernet
product BROADCOM BCM5700 0x1644 BCM5700 10/100/1000 Ethernet
product BROADCOM BCM5701 0x1645 BCM5701 10/100/1000 Ethernet
product BROADCOM BCM5702 0x1646 BCM5702 10/100/1000 Ethernet
-product BROADCOM BCM5702X 0x16a6 BCM5702X 10/100/1000 Ethernet
-product BROADCOM BCM5702FE 0x164d BCM5702FE 10/100 Ethernet
product BROADCOM BCM5703 0x1647 BCM5703 10/100/1000 Ethernet
-product BROADCOM BCM5703X 0x16a7 BCM5703X 10/100/1000 Ethernet
-product BROADCOM BCM5703A3 0x16c7 BCM5703 10/100/1000 Ethernet
product BROADCOM BCM5704C 0x1648 BCM5704C 1000baseT Ethernet
+product BROADCOM BCM5704S_ALT 0x1649 BCM5704S 1000baseSX Ethernet
product BROADCOM BCM5706 0x164a BCM5706 NetXtreme II 1000baseT Ethernet
product BROADCOM BCM5708 0x164c BCM5708 NetXtreme II 1000baseT Ethernet
-product BROADCOM BCM5704S 0x16a8 BCM5704S 1000baseX Ethernet
-product BROADCOM BCM5706S 0x16aa BCM5706 NetXtreme II 1000baseSX
-product BROADCOM BCM5708S 0x16ac BCM5708 NetXtreme II 1000baseSX
+product BROADCOM BCM5702FE 0x164d BCM5702FE 10/100 Ethernet
product BROADCOM BCM5705 0x1653 BCM5705 10/100/1000 Ethernet
product BROADCOM BCM5705K 0x1654 BCM5705K 10/100/1000 Ethernet
+product BROADCOM BCM5720 0x1658 BCM5720 NetXtreme 1000baseT Ethernet
+product BROADCOM BCM5721 0x1659 BCM5721 NetXtreme 1000baseT Ethernet
+product BROADCOM BCM5722 0x165a BCM5722 NetXtreme 1000baseT Ethernet
product BROADCOM BCM5705M 0x165d BCM5705M 10/100/1000 Ethernet
-product BROADCOM BCM5705_ALT 0x165e BCM5705 10/100/1000 Ethernet
-product BROADCOM BCM5714 0x1668 BCM5714 10/100/1000 Ethernet
-product BROADCOM BCM5714S 0x1669 BCM5714S 1000baseX Ethernet
-product BROADCOM BCM5715 0x1678 BCM5715 10/100/1000 Ethernet
-product BROADCOM BCM5715S 0x1679 BCM5715S 1000baseX Ethernet
-product BROADCOM BCM5721 0x1659 BCM5721 10/100/1000 Ethernet
+product BROADCOM BCM5705M_ALT 0x165e BCM5705M 10/100/1000 Ethernet
+product BROADCOM BCM5714 0x1668 BCM5714 1000baseT Ethernet
+product BROADCOM BCM5714S 0x1669 BCM5714S 1000baseSX Ethernet
+product BROADCOM BCM5780 0x166a BCM5780 NetXtreme 1000baseT Ethernet
+product BROADCOM BCM5780S 0x166b BCM5780S NetXtreme 1000baseSX Ethernet
+product BROADCOM BCM5705F 0x166e BCM5705F 10/100 Ethernet
+product BROADCOM BCM5754M 0x1672 BCM5754M NetXtreme 1000baseT Ethernet
+product BROADCOM BCM5755M 0x1673 BCM5755M NetXtreme 1000baseT Ethernet
+product BROADCOM BCM5756 0x1674 BCM5756 10/100/1000 Ethernet
product BROADCOM BCM5750 0x1676 BCM5750 10/100/1000 Ethernet
product BROADCOM BCM5751 0x1677 BCM5751 10/100/1000 Ethernet
-product BROADCOM BCM5752 0x1600 BCM5752 10/100/1000 Ethernet
+product BROADCOM BCM5715 0x1678 BCM5715 1000baseT Ethernet
+product BROADCOM BCM5715S 0x1679 BCM5715S 1000baseSX Ethernet
+product BROADCOM BCM5754 0x167a BCM5754 10/100/1000 Ethernet
+product BROADCOM BCM5755 0x167b BCM5755 NetXtreme 1000baseT Ethernet
product BROADCOM BCM5750M 0x167c BCM5750M 10/100/1000 Ethernet
product BROADCOM BCM5751M 0x167d BCM5751M 10/100/1000 Ethernet
-product BROADCOM BCM5780 0x166a BCM5780 1000baseT Ethernet
-product BROADCOM BCM5780S 0x166b BCM5780S 1000baseX Ethernet
+product BROADCOM BCM5751F 0x167e BCM5751F 10/100/1000 Ethernet
+product BROADCOM BCM5787M 0x1693 BCM5787M 10/100/1000 Ethernet
product BROADCOM BCM5782 0x1696 BCM5782 10/100/1000 Ethernet
+product BROADCOM BCM5786 0x169a BCM5786 NetLink 1000baseT Ethernet
+product BROADCOM BCM5787 0x169b BCM5787 NetLink 1000baseT Ethernet
product BROADCOM BCM5788 0x169c BCM5788 10/100/1000 Ethernet
product BROADCOM BCM5789 0x169d BCM5789 10/100/1000 Ethernet
+product BROADCOM BCM5702X 0x16a6 BCM5702X 10/100/1000 Ethernet
+product BROADCOM BCM5703X 0x16a7 BCM5703X 10/100/1000 Ethernet
+product BROADCOM BCM5704S 0x16a8 BCM5704S 1000baseSX Ethernet
+product BROADCOM BCM5706S 0x16aa BCM5706 NetXtreme II 1000baseSX
+product BROADCOM BCM5708S 0x16ac BCM5708 NetXtreme II 1000baseSX
+product BROADCOM BCM5702_ALT 0x16c6 BCM5702 10/100/1000 Ethernet
+product BROADCOM BCM5703_ALT 0x16c7 BCM5703 10/100/1000 Ethernet
+product BROADCOM BCM5781 0x16dd BCM5781 10/100/1000 Ethernet
+product BROADCOM BCM5753 0x16f7 BCM5753 10/100/1000 Ethernet
+product BROADCOM BCM5753M 0x16fd BCM5753M 10/100/1000 Ethernet
+product BROADCOM BCM5753F 0x16fe BCM5753F 10/100 Ethernet
+product BROADCOM BCM5903M 0x16ff BCM5903M 10/100/1000 Ethernet
product BROADCOM BCM4401_B0 0x170c BCM4401-B0 10/100 Ethernet
product BROADCOM BCM5901 0x170d BCM5901 10/100 Ethernet
product BROADCOM BCM5901A2 0x170e BCM5901A 10/100 Ethernet
+product BROADCOM BCM5906 0x1712 BCM5906 NetLink Fast Ethernet
+product BROADCOM BCM5906M 0x1713 BCM5906M NetLink Fast Ethernet
product BROADCOM BCM4401 0x4401 BCM4401 10/100 Ethernet
product BROADCOM 5801 0x5801 5801 Security processor
product BROADCOM 5802 0x5802 5802 Security processor
Index: if_bge.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_bge.c,v
retrieving revision 1.87.2.6
diff -u -r1.87.2.6 if_bge.c
--- if_bge.c 5 Mar 2007 15:07:14 -0000 1.87.2.6
+++ if_bge.c 18 Sep 2007 06:58:41 -0000
@@ -107,11 +107,11 @@
#include <netinet/ip.h>
#endif
-/* XXX TSO */
-#include <netinet/in.h> /* XXX for struct ip */
-#include <netinet/in_systm.h> /* XXX for struct ip */
-#include <netinet/ip.h> /* XXX for struct ip */
-#include <netinet/tcp.h> /* XXX for struct tcphdr */
+/* Headers for TCP Segmentation Offload (TSO) */
+#include <netinet/in_systm.h> /* n_time for <netinet/ip.h>... */
+#include <netinet/in.h> /* ip_{src,dst}, for <netinet/ip.h> */
+#include <netinet/ip.h> /* for struct ip */
+#include <netinet/tcp.h> /* for struct tcphdr */
#if NBPFILTER > 0
@@ -290,28 +290,28 @@
/*
* XXX: how to handle variants based on 5750 and derivatives:
- * 5750 5751, 5721, possibly 5714, 5752, and 5708?, which
+ * 5750 5751, 5721, possibly 5714, 5752, and 5708?, which
* in general behave like a 5705, except with additional quirks.
* This driver's current handling of the 5721 is wrong;
* how we map ASIC revision to "quirks" needs more thought.
* (defined here until the thought is done).
*/
-#define BGE_IS_5750_OR_BEYOND(sc) \
- (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750 || \
- BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714 || \
- BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 || \
+#define BGE_IS_5714_FAMILY(sc) \
+ (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714_A0 || \
BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780 || \
- BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5715)
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714 )
+
+#define BGE_IS_5750_OR_BEYOND(sc) \
+ (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750 || \
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 || \
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 || \
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787 || \
+ BGE_IS_5714_FAMILY(sc) )
#define BGE_IS_5705_OR_BEYOND(sc) \
( ((sc)->bge_quirks & BGE_QUIRK_5705_CORE) || \
BGE_IS_5750_OR_BEYOND(sc) )
-#define BGE_IS_5714_FAMILY(sc) \
- (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714 || \
- BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780 || \
- BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5715)
-
/* following bugs are common to bcm5700 rev B, all flavours */
#define BGE_QUIRK_5700_COMMON \
@@ -780,7 +780,7 @@
state = 4;
sc->bge_cdata.bge_jumbo_buf = (caddr_t)kva;
- DPRINTFN(1,("bge_jumbo_buf = 0x%p\n", sc->bge_cdata.bge_jumbo_buf));
+ DPRINTFN(1,("bge_jumbo_buf = %p\n", sc->bge_cdata.bge_jumbo_buf));
SLIST_INIT(&sc->bge_jfree_listhead);
SLIST_INIT(&sc->bge_jinuse_listhead);
@@ -1179,8 +1179,7 @@
SLIST_INIT(&sc->txdma_list);
for (i = 0; i < BGE_RSLOTS; i++) {
- if (bus_dmamap_create(sc->bge_dmatag,
- /*ETHER_MAX_LEN_JUMBO*/BGE_TXDMA_MAX,
+ if (bus_dmamap_create(sc->bge_dmatag, BGE_TXDMA_MAX,
BGE_NTXSEG, ETHER_MAX_LEN_JUMBO, 0, BUS_DMA_NOWAIT,
&dmamap))
return(ENOBUFS);
@@ -1342,7 +1341,7 @@
(0x2 << BGE_PCIDMARWCTL_WR_WAT_SHIFT));
/* jonathan: alternative from Linux driver */
-#define DMA_CTRL_WRITE_PCIE_H20MARK_128 0x00180000
+#define DMA_CTRL_WRITE_PCIE_H20MARK_128 0x00180000
#define DMA_CTRL_WRITE_PCIE_H20MARK_256 0x00380000
dma_rw_ctl = 0x76000000; /* XXX XXX XXX */;
@@ -1350,19 +1349,18 @@
BGE_PCI_CONF_DEV_CTRL);
DPRINTFN(4, ("%s: pcie mode=0x%x\n", sc->bge_dev.dv_xname, device_ctl));
-#if 0
- if (device_ctl & 0x00e0) {
- dma_rw_ctl |= DMA_CTRL_WRITE_PCIE_H20MARK_256;
+ if ((device_ctl & 0x00e0) && 0) {
+ /*
+ * XXX jonathan@NetBSD.org:
+ * This clause is exactly what the Broadcom-supplied
+ * Linux does; but given overall register programming
+ * by if_bge(4), this larger DMA-write watermark
+ * value causes bcm5721 chips to totally wedge.
+ */
+ dma_rw_ctl |= BGE_PCIDMA_RWCTL_PCIE_WRITE_WATRMARK_256;
} else {
- dma_rw_ctl |= DMA_CTRL_WRITE_PCIE_H20MARK_128;
+ dma_rw_ctl |= BGE_PCIDMA_RWCTL_PCIE_WRITE_WATRMARK_128;
}
-#else
- dma_rw_ctl |= DMA_CTRL_WRITE_PCIE_H20MARK_128;
-#endif
- aprint_error("%s: PCI-Express DMA setting 0x%8x,"
- " expected 0x%08x\n",
- sc->bge_dev.dv_xname, dma_rw_ctl,
- 0x76180000);
} else if (pci_conf_read(pa->pa_pc, pa->pa_tag,BGE_PCI_PCISTATE) &
BGE_PCISTATE_PCI_BUSMODE) {
/* Conventional PCI bus */
@@ -1396,11 +1394,17 @@
else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703) {
dma_rw_ctl &= 0xfffffff0;
dma_rw_ctl |= BGE_PCIDMARWCTL_ONEDMA_ATONCE;
- } else if (BGE_IS_5714_FAMILY(sc)) {
- dma_rw_ctl = BGE_PCI_READ_CMD | BGE_PCI_WRITE_CMD |
- (1 << 20) | (1 << 18) |
- BGE_PCIDMARWCTL_ONEDMA_ATONCE;
- }
+ }
+ else if (BGE_IS_5714_FAMILY(sc)) {
+ dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD;
+ dma_rw_ctl &= ~BGE_PCIDMARWCTL_ONEDMA_ATONCE; /* XXX */
+ /* XXX magic values, Broadcom-supplied Linux driver */
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780)
+ dma_rw_ctl |= (1 << 20) | (1 << 18) |
+ BGE_PCIDMARWCTL_ONEDMA_ATONCE;
+ else
+ dma_rw_ctl |= (1<<20) | (1<<18) | (1 << 15);
+ }
}
pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL, dma_rw_ctl);
@@ -1560,22 +1564,20 @@
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);
+ CSR_WRITE_4(sc, BGE_BMAN_MODE,
+ BGE_BMANMODE_ENABLE|BGE_BMANMODE_LOMBUF_ATTN);
- /* Poll for buffer manager start indication */
- for (i = 0; i < BGE_TIMEOUT; i++) {
- if (CSR_READ_4(sc, BGE_BMAN_MODE) & BGE_BMANMODE_ENABLE)
- break;
- DELAY(10);
- }
+ /* Poll for buffer manager start indication */
+ for (i = 0; i < BGE_TIMEOUT; i++) {
+ if (CSR_READ_4(sc, BGE_BMAN_MODE) & BGE_BMANMODE_ENABLE)
+ break;
+ DELAY(10);
+ }
- if (i == BGE_TIMEOUT) {
- printf("%s: buffer manager failed to start\n",
- sc->bge_dev.dv_xname);
- return(ENXIO);
- }
+ if (i == BGE_TIMEOUT) {
+ printf("%s: buffer manager failed to start\n",
+ sc->bge_dev.dv_xname);
+ return(ENXIO);
}
/* Enable flow-through queues */
@@ -1661,11 +1663,24 @@
}
/*
- * Set the BD ring replentish thresholds. The recommended
+ * Set the BD ring replenish thresholds. The recommended
* values are 1/8th the number of descriptors allocated to
* each ring.
*/
- CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, BGE_STD_RX_RING_CNT/8);
+ i = BGE_STD_RX_RING_CNT / 8;
+
+ /*
+ * Use a value of 8 for the following chips to workaround HW errata.
+ * Some of these chips have been added based on empirical
+ * evidence (they don't work unless this is done).
+ */
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750 ||
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 ||
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787)
+ i = 8;
+
+ CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, i);
CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, BGE_JUMBO_RX_RING_CNT/8);
/*
@@ -1846,36 +1861,42 @@
}
/* Turn on write DMA state machine */
- CSR_WRITE_4(sc, BGE_WDMA_MODE,
- BGE_WDMAMODE_ENABLE|BGE_WDMAMODE_ALL_ATTNS);
+ {
+ uint32_t bge_wdma_mode =
+ BGE_WDMAMODE_ENABLE|BGE_WDMAMODE_ALL_ATTNS;
+
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787)
+ /* Enable host coalescing bug fix; see Linux tg3.c */
+ bge_wdma_mode |= (1 << 29);
+
+ CSR_WRITE_4(sc, BGE_WDMA_MODE, bge_wdma_mode);
+ }
/* Turn on read DMA state machine */
{
uint32_t dma_read_modebits;
-#define DMA_READ_MODE_FIFO_LONG_BURST ((1<<17) || (1 << 16))
-#define DMA_READ_MODE_FIFO_SIZE_128 (1 << 17)
-
dma_read_modebits =
BGE_RDMAMODE_ENABLE | BGE_RDMAMODE_ALL_ATTNS;
-#if 1 /* XXXjrs does this help? check again,2005-nov-14 */
if (sc->bge_pcie && 0) {
- dma_read_modebits |= DMA_READ_MODE_FIFO_LONG_BURST;
+ dma_read_modebits |= BGE_RDMA_MODE_FIFO_LONG_BURST;
} else if ((sc->bge_quirks & BGE_QUIRK_5705_CORE)) {
- dma_read_modebits |= DMA_READ_MODE_FIFO_SIZE_128;
+ dma_read_modebits |= BGE_RDMA_MODE_FIFO_SIZE_128;
}
-#endif
/* XXX broadcom-supplied linux driver; undocumented */
if (BGE_IS_5750_OR_BEYOND(sc)) {
+ /*
+ * XXX: magic values.
+ * From Broadcom-supplied Linux driver; apparently
+ * required to workaround a DMA bug affecting TSO
+ * on bcm575x/bcm5721?
+ */
dma_read_modebits |= (1 << 27);
- printf("dma read modebits: set 575x tso bit: 0x%8x\n",
- dma_read_modebits);
}
- printf("dma read modebits: 0x%8x\n", dma_read_modebits);
CSR_WRITE_4(sc, BGE_RDMA_MODE, dma_read_modebits);
-
}
/* Turn on RX data completion state machine */
@@ -1900,6 +1921,7 @@
/* Turn on send data initiator state machine */
if (BGE_IS_5750_OR_BEYOND(sc)) {
+ /* XXX: magic value from Linux driver */
CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE | 0x08);
} else {
CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
@@ -1961,6 +1983,10 @@
BGE_QUIRK_LINK_STATE_BROKEN|BGE_QUIRK_5700_COMMON,
"BCM5700 B2" },
+ { BGE_CHIPID_BCM5700_B3,
+ BGE_QUIRK_LINK_STATE_BROKEN|BGE_QUIRK_5700_COMMON,
+ "BCM5700 B3" },
+
/* This is treated like a BCM5700 Bx */
{ BGE_CHIPID_BCM5700_ALTIMA,
BGE_QUIRK_LINK_STATE_BROKEN|BGE_QUIRK_5700_COMMON,
@@ -1979,7 +2005,7 @@
"BCM5701 B0" },
{ BGE_CHIPID_BCM5701_B2,
- BGE_QUIRK_PCIX_DMA_ALIGN_BUG,
+ BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_PCIX_DMA_ALIGN_BUG,
"BCM5701 B2" },
{ BGE_CHIPID_BCM5701_B5,
@@ -2002,6 +2028,10 @@
BGE_QUIRK_ONLY_PHY_1,
"BCM5703 A3" },
+ { BGE_CHIPID_BCM5703_B0,
+ BGE_QUIRK_ONLY_PHY_1,
+ "BCM5703 B0" },
+
{ BGE_CHIPID_BCM5704_A0,
BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_FEWER_MBUFS,
"BCM5704 A0" },
@@ -2036,7 +2066,7 @@
{ BGE_CHIPID_BCM5750_A0,
BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
- "BCM5750 A1" },
+ "BCM5750 A0" },
{ BGE_CHIPID_BCM5750_A1,
BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
@@ -2046,13 +2076,29 @@
BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
"BCM5751 A1" },
- { BGE_CHIPID_BCM5715_xx,
+ { BGE_CHIPID_BCM5752_A0,
+ BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
+ "BCM5752 A0" },
+
+ { BGE_CHIPID_BCM5752_A1,
BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
- "BCM5715 xx" },
+ "BCM5752 A1" },
- { BGE_CHIPID_BCM5780_A0,
+ { BGE_CHIPID_BCM5752_A2,
BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
- "BCM5780 xx" },
+ "BCM5752 A2" },
+
+ { BGE_CHIPID_BCM5787_A0,
+ BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
+ "BCM5754/5787 A0" },
+
+ { BGE_CHIPID_BCM5787_A1,
+ BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
+ "BCM5754/5787 A1" },
+
+ { BGE_CHIPID_BCM5787_A2,
+ BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
+ "BCM5754/5787 A2" },
{ 0, 0, NULL }
};
@@ -2086,6 +2132,10 @@
BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
"unknown BCM575x family" },
+ { BGE_ASICREV_BCM5714_A0,
+ BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
+ "unknown BCM5714" },
+
{ BGE_ASICREV_BCM5714,
BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
"unknown BCM5714" },
@@ -2094,14 +2144,17 @@
BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
"unknown BCM5752 family" },
-
- { BGE_ASICREV_BCM5715,
+ { BGE_ASICREV_BCM5755,
BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
- "unknown BCM5715" },
+ "unknown BCM5755" },
{ BGE_ASICREV_BCM5780,
BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
- "unknown BCM5780/BCM5780S" },
+ "unknown BCM5780" },
+
+ { BGE_ASICREV_BCM5787,
+ BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
+ "unknown BCM5787" },
{ 0,
0,
@@ -2185,8 +2238,8 @@
"Broadcom BCM5703X Gigabit Ethernet",
},
{ PCI_VENDOR_BROADCOM,
- PCI_PRODUCT_BROADCOM_BCM5703A3,
- "Broadcom BCM5703A3 Gigabit Ethernet",
+ PCI_PRODUCT_BROADCOM_BCM5703_ALT,
+ "Broadcom BCM5703 Gigabit Ethernet",
},
{ PCI_VENDOR_BROADCOM,
@@ -2207,24 +2260,26 @@
"Broadcom BCM5705K Gigabit Ethernet",
},
{ PCI_VENDOR_BROADCOM,
- PCI_PRODUCT_BROADCOM_BCM5705_ALT,
- "Broadcom BCM5705 Gigabit Ethernet",
+ PCI_PRODUCT_BROADCOM_BCM5705M,
+ "Broadcom BCM5705M Gigabit Ethernet",
},
{ PCI_VENDOR_BROADCOM,
- PCI_PRODUCT_BROADCOM_BCM5705M,
+ PCI_PRODUCT_BROADCOM_BCM5705M_ALT,
"Broadcom BCM5705M Gigabit Ethernet",
},
{ PCI_VENDOR_BROADCOM,
PCI_PRODUCT_BROADCOM_BCM5714,
- "Broadcom BCM5714 Gigabit Ethernet",
+ "Broadcom BCM5714/5715 Gigabit Ethernet",
},
-
{ PCI_VENDOR_BROADCOM,
PCI_PRODUCT_BROADCOM_BCM5715,
- "Broadcom BCM5715 Gigabit Ethernet",
+ "Broadcom BCM5714/5715 Gigabit Ethernet",
+ },
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5789,
+ "Broadcom BCM5789 Gigabit Ethernet",
},
-
{ PCI_VENDOR_BROADCOM,
PCI_PRODUCT_BROADCOM_BCM5721,
@@ -2256,6 +2311,41 @@
"Broadcom BCM5752 Gigabit Ethernet",
},
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5752M,
+ "Broadcom BCM5752M Gigabit Ethernet",
+ },
+
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5753,
+ "Broadcom BCM5753 Gigabit Ethernet",
+ },
+
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5753M,
+ "Broadcom BCM5753M Gigabit Ethernet",
+ },
+
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5754,
+ "Broadcom BCM5754 Gigabit Ethernet",
+ },
+
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5754M,
+ "Broadcom BCM5754M Gigabit Ethernet",
+ },
+
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5755,
+ "Broadcom BCM5755 Gigabit Ethernet",
+ },
+
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5755M,
+ "Broadcom BCM5755M Gigabit Ethernet",
+ },
+
{ PCI_VENDOR_BROADCOM,
PCI_PRODUCT_BROADCOM_BCM5780,
"Broadcom BCM5780 Gigabit Ethernet",
@@ -2269,12 +2359,31 @@
{ PCI_VENDOR_BROADCOM,
PCI_PRODUCT_BROADCOM_BCM5782,
"Broadcom BCM5782 Gigabit Ethernet",
- },
+ },
+
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5786,
+ "Broadcom BCM5786 Gigabit Ethernet",
+ },
+
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5787,
+ "Broadcom BCM5787 Gigabit Ethernet",
+ },
+
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5787M,
+ "Broadcom BCM5787M Gigabit Ethernet",
+ },
{ PCI_VENDOR_BROADCOM,
PCI_PRODUCT_BROADCOM_BCM5788,
"Broadcom BCM5788 Gigabit Ethernet",
},
+ { PCI_VENDOR_BROADCOM,
+ PCI_PRODUCT_BROADCOM_BCM5789,
+ "Broadcom BCM5789 Gigabit Ethernet",
+ },
{ PCI_VENDOR_BROADCOM,
PCI_PRODUCT_BROADCOM_BCM5901,
@@ -2503,9 +2612,6 @@
else
sc->bge_pcie = 0;
- DPRINTFN(4 ,("%s: asic %04x, pcie = %d\n", sc->bge_dev.dv_xname,
- BGE_ASICREV(sc->bge_chipid), sc->bge_pcie)); /* XXX jrs */
-
/* Try to reset the chip. */
DPRINTFN(5, ("bge_reset\n"));
bge_reset(sc);
@@ -2644,7 +2750,7 @@
sc->ethercom.ec_capabilities |=
ETHERCAP_VLAN_HWTAGGING | ETHERCAP_VLAN_MTU;
- if (sc->bge_pcie || BGE_IS_5714_FAMILY(sc))
+ if (sc->bge_pcie)
sc->ethercom.ec_if.if_capabilities |= IFCAP_TSOv4;
/*
@@ -2776,7 +2882,6 @@
{
struct pci_attach_args *pa = &sc->bge_pa;
u_int32_t cachesize, command, pcistate, new_pcistate;
- u_int32_t saved_msi_mode;
int i, val;
/* Save some important PCI state. */
@@ -2788,6 +2893,15 @@
BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|
BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_PCISTATE_RW);
+ /*
+ * Disable the firmware fastboot feature on 5752 ASIC
+ * to avoid firmware timeout.
+ */
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 ||
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787)
+ CSR_WRITE_4(sc, BGE_FASTBOOT_PC, 0);
+
val = BGE_MISCCFG_RESET_CORE_CLOCKS | (65<<1);
/*
* XXX: from FreeBSD/Linux; no documentation
@@ -2801,12 +2915,12 @@
val |= (1<<29);
}
}
- /* Certain bcm5714/HT-2000 chips clobber MSI state on reset */
- saved_msi_mode = 0;
- if (BGE_IS_5714_FAMILY(sc)) {
- saved_msi_mode =
- pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_MSI_CAPID);
- }
+ /*
+ * Write the magic number to the firmware mailbox at 0xb50
+ * so that the driver can synchronize with the firmware.
+ */
+ bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
+
/* Issue global reset */
bge_writereg_ind(sc, BGE_MISC_CFG, val);
@@ -2825,8 +2939,14 @@
pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_UNKNOWN0,
reg | (1 << 15));
}
- /* XXX: Magic Numbers */
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_CONF_DEV_CTRL, 0xf5000);
+ /*
+ * XXX: Magic Numbers.
+ * Sets maximal PCI-e payload and clears any PCI-e errors.
+ * Should be replaced with references to PCI config-space
+ * capability block for PCI-Express.
+ */
+ pci_conf_write(pa->pa_pc, pa->pa_tag,
+ BGE_PCI_CONF_DEV_CTRL, 0xf5000);
}
@@ -2840,28 +2960,13 @@
/* Enable memory arbiter. */
{
- uint32_t marbmode = 0;
- if (BGE_IS_5714_FAMILY(sc)) {
+ uint32_t marbmode = 0;
+ if (BGE_IS_5714_FAMILY(sc)) {
marbmode = CSR_READ_4(sc, BGE_MARB_MODE);
- }
- CSR_WRITE_4(sc, BGE_MARB_MODE, marbmode | BGE_MARBMODE_ENABLE);
- }
-
- if (BGE_IS_5714_FAMILY(sc)) {
- uint32_t msi_mode;
- msi_mode =
- pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_MSI_CAPID);
- msi_mode |= (saved_msi_mode & (1 << 16));
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MSI_CAPID, msi_mode);
+ }
+ CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | marbmode);
}
-
- /*
- * Prevent PXE restart: write a magic number to the
- * general communications memory at 0xB50.
- */
- bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
-
/*
* Poll the value location we just wrote until
* we see the 1's complement of the magic number.
@@ -2878,6 +2983,11 @@
if (i >= BGE_TIMEOUT) {
printf("%s: firmware handshake timed out, val = %x\n",
sc->bge_dev.dv_xname, val);
+ /*
+ * XXX: occasionally fired on bcm5721, but without
+ * apparent harm. For now, keep going if we timeout
+ * against PCI-E devices.
+ */
if (!sc->bge_pcie)
return;
}
@@ -2911,11 +3021,11 @@
/* Enable memory arbiter. */
/* XXX why do this twice? */
{
- uint32_t marbmode = 0;
- if (BGE_IS_5714_FAMILY(sc)) {
+ uint32_t marbmode = 0;
+ if (BGE_IS_5714_FAMILY(sc)) {
marbmode = CSR_READ_4(sc, BGE_MARB_MODE);
- }
- CSR_WRITE_4(sc, BGE_MARB_MODE, marbmode | BGE_MARBMODE_ENABLE);
+ }
+ CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | marbmode);
}
/* Fix up byte swapping */
@@ -3183,7 +3293,7 @@
* Process link state changes.
* Grrr. The link status word in the status block does
* not work correctly on the BCM5700 rev AX and BX chips,
- * according to all avaibable information. Hence, we have
+ * according to all available information. Hence, we have
* to enable MII interrupts in order to properly obtain
* async link changes. Unfortunately, this also means that
* we have to read the MAC status register to detect link
@@ -3395,7 +3505,7 @@
* (thus perhaps avoiding the bcm5700 dma-min bug).
*/
for (last = pkt; last->m_next != NULL; last = last->m_next) {
- (void) 0; /* do nothing*/
+ (void) 0; /* do nothing */
}
/* `last' now points to last in chain. */
@@ -3405,6 +3515,8 @@
/* Allocate new empty mbuf, pad it. Compact later. */
struct mbuf *n;
MGET(n, M_DONTWAIT, MT_DATA);
+ if (n == NULL)
+ return ENOBUFS;
n->m_len = 0;
last->m_next = n;
last = n;
@@ -3550,7 +3662,7 @@
u_int32_t *txidx;
{
struct bge_tx_bd *f = NULL;
- u_int32_t frag, cur, cnt = 0;
+ u_int32_t frag, cur;
u_int16_t csum_flags = 0;
u_int16_t txbd_tso_flags = 0;
struct txdmamap_pool_entry *dma;
@@ -3558,7 +3670,7 @@
int i = 0;
struct m_tag *mtag;
int use_tso, maxsegsize, error;
-
+
cur = frag = *txidx;
if (m_head->m_pkthdr.csum_flags) {
@@ -3643,15 +3755,14 @@
return (ENOBUFS);
}
- /*
- * TCP/IP headers are in the first mbuf; we can do
- * this the easy way.
- */
- iphl =
- M_CSUM_DATA_IPv4_IPHL(m0->m_pkthdr.csum_data);
- hlen = iphl + offset;
- if (__predict_false(m0->m_len <
- (hlen + sizeof(struct tcphdr)))) {
+ /*
+ * TCP/IP headers are in the first mbuf; we can do
+ * this the easy way.
+ */
+ iphl = M_CSUM_DATA_IPv4_IPHL(m0->m_pkthdr.csum_data);
+ hlen = iphl + offset;
+ if (__predict_false(m0->m_len <
+ (hlen + sizeof(struct tcphdr)))) {
struct ip ip;
struct tcphdr th;
@@ -3659,7 +3770,10 @@
"ip/tcp hlen %d, not handled yet\n",
m0->m_len, (int)(hlen+ sizeof(struct tcphdr)));
#ifdef NOTYET
-
+ /*
+ * XXX jonathan@NetBSD.org: untested.
+ * how to force this branch to be taken?
+ */
BGE_EVCNT_INCR(&sc->sc_ev_txtsopain);
m_copydata(m0, offset, sizeof(ip), &ip);
@@ -3679,13 +3793,17 @@
hlen += th.th_off << 2;
iptcp_opt_words = hlen;
#else
+ /*
+ * if_wm "hard" case not yet supported, can we not
+ * mandate it out of existence?
+ */
(void) ip; (void)th; (void) ip_tcp_hlen;
BGE_TSO_PRINTF(("%s: TSO hard case\n",
sc->bge_dev.dv_xname));
return ENOBUFS;
#endif
- } else {
+ } else {
ip = (struct ip *) (mtod(m0, caddr_t) + offset);
th = (struct tcphdr *) (mtod(m0, caddr_t) + hlen);
ip_tcp_hlen = iphl + (th->th_off << 2);
@@ -3694,16 +3812,21 @@
iptcp_opt_words = (ip_tcp_hlen
- sizeof(struct tcphdr)
- sizeof(struct ip)) >> 2;
- }
+ }
if (BGE_IS_5750_OR_BEYOND(sc)) {
th->th_sum = 0;
csum_flags &= ~(BGE_TXBDFLAG_TCP_UDP_CSUM);
} else {
- /* XXXjrs untested */
+ /*
+ * XXX jonathan@NetBSD.org: 5705 untested.
+ * Requires TSO firmware patch for 5701/5703/5704.
+ */
+ th->th_sum = in_cksum_phdr(ip->ip_src.s_addr,
+ ip->ip_dst.s_addr, htons(IPPROTO_TCP));
}
mss = m_head->m_pkthdr.segsz;
- txbd_tso_flags |=
+ txbd_tso_flags |=
BGE_TXBDFLAG_CPU_PRE_DMA |
BGE_TXBDFLAG_CPU_POST_DMA;
@@ -3722,8 +3845,7 @@
if ( BGE_IS_5705_OR_BEYOND(sc)) {
tcp_seg_flags =
iptcp_opt_words << 11;
- }
- else {
+ } else {
txbd_tso_flags |=
iptcp_opt_words << 12;
}
@@ -3748,16 +3870,27 @@
sc->bge_dev.dv_xname, error));
return(ENOBUFS);
}
+ /*
+ * Sanity check: avoid coming within 16 descriptors
+ * of the end of the ring.
+ */
+ if (dmamap->dm_nsegs > (BGE_TX_RING_CNT - sc->bge_txcnt - 16)) {
+ BGE_TSO_PRINTF(("%s: "
+ " dmamap_load_mbuf too close to ring wrap\n",
+ sc->bge_dev.dv_xname));
+ goto fail_unload;
+ }
mtag = sc->ethercom.ec_nvlans ?
m_tag_find(m_head, PACKET_TAG_VLAN, NULL) : NULL;
+ /* Iterate over dmap-map fragments. */
for (i = 0; i < dmamap->dm_nsegs; i++) {
f = &sc->bge_rdata->bge_tx_ring[frag];
if (sc->bge_cdata.bge_tx_chain[frag] != NULL)
break;
-
+
bge_set_hostaddr(&f->bge_addr, dmamap->dm_segs[i].ds_addr);
f->bge_len = dmamap->dm_segs[i].ds_len;
@@ -3787,24 +3920,14 @@
} else {
f->bge_vlan_tag = 0;
}
- /*
- * Sanity check: avoid coming within 16 descriptors
- * of the end of the ring.
- */
- if ((BGE_TX_RING_CNT - (sc->bge_txcnt + cnt)) < 16) {
- DPRINTFN(5, ("%s: Tx ring overfull heuristic\n",
- sc->bge_dev.dv_xname));
- return EAGAIN; /* XXX odd but unique */
- }
cur = frag;
BGE_INC(frag, BGE_TX_RING_CNT);
- cnt++;
}
if (i < dmamap->dm_nsegs) {
BGE_TSO_PRINTF(("%s: reached %d < dm_nsegs %d\n",
sc->bge_dev.dv_xname, i, dmamap->dm_nsegs));
- return ENOBUFS;
+ goto fail_unload;
}
bus_dmamap_sync(sc->bge_dmatag, dmamap, 0, dmamap->dm_mapsize,
@@ -3814,18 +3937,23 @@
BGE_TSO_PRINTF(("%s: frag %d = wrapped id %d?\n",
sc->bge_dev.dv_xname, frag, sc->bge_tx_saved_considx));
- return(ENOBUFS);
+ goto fail_unload;
}
sc->bge_rdata->bge_tx_ring[cur].bge_flags |= BGE_TXBDFLAG_END;
sc->bge_cdata.bge_tx_chain[cur] = m_head;
SLIST_REMOVE_HEAD(&sc->txdma_list, link);
sc->txdma[cur] = dma;
- sc->bge_txcnt += cnt;
+ sc->bge_txcnt += dmamap->dm_nsegs;
*txidx = frag;
return(0);
+
+ fail_unload:
+ bus_dmamap_unload(sc->bge_dmatag, dmamap);
+
+ return ENOBUFS;
}
/*
@@ -3844,7 +3972,7 @@
sc = ifp->if_softc;
- if (!sc->bge_link && ifp->if_snd.ifq_len < 10)
+ if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
return;
prodidx = sc->bge_tx_prodidx;
@@ -3879,9 +4007,6 @@
* for the NIC to drain the ring.
*/
if ((err = bge_encap(sc, m_head, &prodidx)) != 0) {
- if (err != EAGAIN)
- DPRINTFN(4, ("%s: bge_encap failed on len %d, err %d?\n",
- sc->bge_dev.dv_xname, m_head->m_pkthdr.len, err));
ifp->if_flags |= IFF_OACTIVE;
break;
}
@@ -3948,7 +4073,7 @@
/* Specify MTU. */
CSR_WRITE_4(sc, BGE_RX_MTU, ifp->if_mtu +
- ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN);
+ ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN);
/* Load our MAC address. */
m = (u_int16_t *)&(LLADDR(ifp->if_sadl)[0]);
@@ -4111,7 +4236,7 @@
sc->bge_if_flags & IFF_PROMISC) {
BGE_CLRBIT(sc, BGE_RX_MODE,
BGE_RXMODE_RX_PROMISC);
- } else
+ } else if (!(sc->bge_if_flags & IFF_UP))
bge_init(ifp);
} else {
if (ifp->if_flags & IFF_RUNNING) {
Index: if_bgereg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_bgereg.h,v
retrieving revision 1.24.2.5
diff -u -r1.24.2.5 if_bgereg.h
--- if_bgereg.h 5 Mar 2007 15:07:14 -0000 1.24.2.5
+++ if_bgereg.h 18 Sep 2007 06:58:42 -0000
@@ -192,11 +192,16 @@
#define BGE_PCI_UNDI_TX_BD_PRODIDX_LO 0xAC
#define BGE_PCI_ISR_MBX_HI 0xB0
#define BGE_PCI_ISR_MBX_LO 0xB4
-/* XXX: used in PCI-Express code for 575x chips */
+
#define BGE_PCI_UNKNOWN0 0xC4
-#define BGE_PCI_UNKNOWN1 0xD8
-#define BGE_PCI_CONF_DEV_CTRL 0XD8
-#define BGE_PCI_CONF_DEV_STUS 0XDA
+/* XXX:
+ * Used in PCI-Express code for 575x chips.
+ * Should be replaced with checking for a PCI config-space
+ * capability for PCI-Express, and PCI-Express standard
+ * offsets into that capability block.
+ */
+#define BGE_PCI_CONF_DEV_CTRL 0xD8
+#define BGE_PCI_CONF_DEV_STUS 0xDA
/* PCI Misc. Host control register */
@@ -230,8 +235,9 @@
#define BGE_CHIPID_BCM5700_A0 0x70000000
#define BGE_CHIPID_BCM5700_A1 0x70010000
#define BGE_CHIPID_BCM5700_B0 0x71000000
-#define BGE_CHIPID_BCM5700_B1 0x71020000
-#define BGE_CHIPID_BCM5700_B2 0x71030000
+#define BGE_CHIPID_BCM5700_B1 0x71010000
+#define BGE_CHIPID_BCM5700_B2 0x71020000
+#define BGE_CHIPID_BCM5700_B3 0x71030000
#define BGE_CHIPID_BCM5700_ALTIMA 0x71040000
#define BGE_CHIPID_BCM5700_C0 0x72000000
#define BGE_CHIPID_BCM5701_A0 0x00000000 /* grrrr */
@@ -241,41 +247,67 @@
#define BGE_CHIPID_BCM5703_A0 0x10000000
#define BGE_CHIPID_BCM5703_A1 0x10010000
#define BGE_CHIPID_BCM5703_A2 0x10020000
-#define BGE_CHIPID_BCM5703_A3 0x11000000
+#define BGE_CHIPID_BCM5703_A3 0x10030000
+#define BGE_CHIPID_BCM5703_B0 0x11000000
#define BGE_CHIPID_BCM5704_A0 0x20000000
#define BGE_CHIPID_BCM5704_A1 0x20010000
#define BGE_CHIPID_BCM5704_A2 0x20020000
#define BGE_CHIPID_BCM5704_A3 0x20030000
+#define BGE_CHIPID_BCM5704_B0 0x21000000
#define BGE_CHIPID_BCM5705_A0 0x30000000
#define BGE_CHIPID_BCM5705_A1 0x30010000
#define BGE_CHIPID_BCM5705_A2 0x30020000
#define BGE_CHIPID_BCM5705_A3 0x30030000
#define BGE_CHIPID_BCM5750_A0 0x40000000
#define BGE_CHIPID_BCM5750_A1 0x40010000
+#define BGE_CHIPID_BCM5750_A3 0x40030000
+#define BGE_CHIPID_BCM5750_B0 0x40100000
#define BGE_CHIPID_BCM5751_A1 0x41010000
+#define BGE_CHIPID_BCM5750_C0 0x42000000
+#define BGE_CHIPID_BCM5750_C1 0x42010000
+#define BGE_CHIPID_BCM5750_C2 0x42020000
#define BGE_CHIPID_BCM5714_A0 0x50000000
-#define BGE_CHIPID_BCM5715_xx 0x90010000
-#define BGE_CHIPID_BCM5780_A0 0x166a0000
+#define BGE_CHIPID_BCM5752_A0 0x60000000
+#define BGE_CHIPID_BCM5752_A1 0x60010000
+#define BGE_CHIPID_BCM5752_A2 0x60020000
+#define BGE_CHIPID_BCM5714_B0 0x80000000
+#define BGE_CHIPID_BCM5714_B3 0x80030000
+#define BGE_CHIPID_BCM5715_A0 0x90000000
+#define BGE_CHIPID_BCM5715_A1 0x90010000
+#define BGE_CHIPID_BCM5715_A3 0x90030000
+#define BGE_CHIPID_BCM5787_A0 0xb0000000
+#define BGE_CHIPID_BCM5787_A1 0xb0010000
+#define BGE_CHIPID_BCM5787_A2 0xb0020000
+#define BGE_CHIPID_BCM5906_A1 0xc0010000
/* shorthand one */
-#define BGE_ASICREV(x) ((x) >> 28)
-#define BGE_ASICREV_BCM5700 0x07
-#define BGE_ASICREV_BCM5701 0x00
-#define BGE_ASICREV_BCM5703 0x01
-#define BGE_ASICREV_BCM5704 0x02
-#define BGE_ASICREV_BCM5705 0x03
-#define BGE_ASICREV_BCM5750 0x04
-#define BGE_ASICREV_BCM5714 0x05
-#define BGE_ASICREV_BCM5752 0x06
-#define BGE_ASICREV_BCM5780 0x08
-#define BGE_ASICREV_BCM5715 0x09 /* XXX ??? */
+#define BGE_ASICREV(x) ((x) >> 28)
+#define BGE_ASICREV_BCM5700 0x07
+#define BGE_ASICREV_BCM5701 0x00
+#define BGE_ASICREV_BCM5703 0x01
+#define BGE_ASICREV_BCM5704 0x02
+#define BGE_ASICREV_BCM5705 0x03
+#define BGE_ASICREV_BCM5750 0x04
+#define BGE_ASICREV_BCM5714_A0 0x05
+#define BGE_ASICREV_BCM5752 0x06
+/* ASIC revision 0x07 is the original bcm5700 */
+#define BGE_ASICREV_BCM5780 0x08
+#define BGE_ASICREV_BCM5714 0x09
+#define BGE_ASICREV_BCM5755 0x0a
+#define BGE_ASICREV_BCM5787 0x0b
+#define BGE_ASICREV_BCM5706 0x0c
/* chip revisions */
-#define BGE_CHIPREV(x) ((x) >> 24)
-#define BGE_CHIPREV_5700_AX 0x70
-#define BGE_CHIPREV_5700_BX 0x71
-#define BGE_CHIPREV_5700_CX 0x72
-#define BGE_CHIPREV_5701_AX 0x00
+#define BGE_CHIPREV(x) ((x) >> 24)
+#define BGE_CHIPREV_5700_AX 0x70
+#define BGE_CHIPREV_5700_BX 0x71
+#define BGE_CHIPREV_5700_CX 0x72
+#define BGE_CHIPREV_5701_AX 0x00
+#define BGE_CHIPREV_5703_AX 0x10
+#define BGE_CHIPREV_5704_AX 0x20
+#define BGE_CHIPREV_5704_BX 0x21
+#define BGE_CHIPREV_5750_AX 0x40
+#define BGE_CHIPREV_5750_BX 0x41
/* PCI DMA Read/Write Control register */
#define BGE_PCIDMARWCTL_MINDMA 0x000000FF
@@ -293,6 +325,9 @@
#define BGE_PCIDMARWCTL_DFLT_PCI_WR_CMD 0xF0000000
# define BGE_PCIDMA_RWCTL_PCI_WR_CMD_SHIFT 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_PCI_READ_BNDRY_DISABLE 0x00000000
#define BGE_PCI_READ_BNDRY_16BYTES 0x00000100
@@ -1094,7 +1129,7 @@
#define BGE_HCC_RX_COAL_TICKS_INT 0x3C18 /* ticks during interrupt */
#define BGE_HCC_TX_COAL_TICKS_INT 0x3C1C /* ticks during interrupt */
#define BGE_HCC_RX_MAX_COAL_BDS_INT 0x3C20 /* BDs during interrupt */
-#define BGE_HCC_TX_MAX_COAL_BDS_INT 0x3C34 /* BDs during interrupt */
+#define BGE_HCC_TX_MAX_COAL_BDS_INT 0x3C24 /* BDs during interrupt */
#define BGE_HCC_STATS_TICKS 0x3C28
#define BGE_HCC_STATS_ADDR_HI 0x3C30
#define BGE_HCC_STATS_ADDR_LO 0x3C34
@@ -1299,6 +1334,10 @@
#define BGE_RDMAMODE_LOCWRITE_TOOBIG 0x00000200
#define BGE_RDMAMODE_ALL_ATTNS 0x000003FC
+/* Alternate encodings for PCI-Express, from Broadcom-supplied Linux driver */
+#define BGE_RDMA_MODE_FIFO_LONG_BURST ((1<<17) || (1 << 16))
+#define BGE_RDMA_MODE_FIFO_SIZE_128 (1 << 17)
+
/* Read DMA status register */
#define BGE_RDMASTAT_PCI_TGT_ABRT_ATTN 0x00000004
#define BGE_RDMASTAT_PCI_MSTR_ABRT_ATTN 0x00000008
@@ -1625,6 +1664,7 @@
#define BGE_EE_CTL 0x6840
#define BGE_MDI_CTL 0x6844
#define BGE_EE_DELAY 0x6848
+#define BGE_FASTBOOT_PC 0x6894
/*
* XXX: Those names are made up as I have no documentation about it;
* I only know it is only used in the PCI-Express case.
@@ -1764,15 +1804,13 @@
* firmware mailbox at 0xB50 in order to prevent the PXE boot
* code from running.
*/
-#define BGE_MAGIC_NUMBER 0x4B657654
+#define BGE_MAGIC_NUMBER 0x4B657654
typedef struct {
- u_int32_t bge_addr_hi;
- u_int32_t bge_addr_lo;
+ volatile u_int32_t bge_addr_hi;
+ volatile u_int32_t bge_addr_lo;
} bge_hostaddr;
-#define BGE_HOSTADDR(x) (x).bge_addr_lo
-
static __inline void
bge_set_hostaddr(volatile bge_hostaddr *x, bus_addr_t y)
{
@@ -1786,8 +1824,8 @@
/* Ring control block structure */
struct bge_rcb {
bge_hostaddr bge_hostaddr;
- u_int32_t bge_maxlen_flags; /* two 16-bit fields */
- u_int32_t bge_nicaddr;
+ volatile u_int32_t bge_maxlen_flags; /* two 16-bit fields */
+ volatile u_int32_t bge_nicaddr;
};
#define BGE_RCB_MAXLEN_FLAGS(maxlen, flags) ((maxlen) << 16 | (flags))
@@ -1803,15 +1841,15 @@
struct bge_tx_bd {
bge_hostaddr bge_addr;
#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t bge_len;
- u_int16_t bge_flags;
- u_int16_t bge_rsvd;
- u_int16_t bge_vlan_tag;
+ volatile u_int16_t bge_len;
+ volatile u_int16_t bge_flags;
+ volatile u_int16_t bge_rsvd;
+ volatile u_int16_t bge_vlan_tag;
#else
- u_int16_t bge_flags;
- u_int16_t bge_len;
- u_int16_t bge_vlan_tag;
- u_int16_t bge_rsvd;
+ volatile u_int16_t bge_flags;
+ volatile u_int16_t bge_len;
+ volatile u_int16_t bge_vlan_tag;
+ volatile u_int16_t bge_rsvd;
#endif
};
@@ -1835,26 +1873,26 @@
struct bge_rx_bd {
bge_hostaddr bge_addr;
#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t bge_idx;
- u_int16_t bge_len;
- u_int16_t bge_type;
- u_int16_t bge_flags;
- u_int16_t bge_ip_csum;
- u_int16_t bge_tcp_udp_csum;
- u_int16_t bge_error_flag;
- u_int16_t bge_vlan_tag;
+ volatile u_int16_t bge_idx;
+ volatile u_int16_t bge_len;
+ volatile u_int16_t bge_type;
+ volatile u_int16_t bge_flags;
+ volatile u_int16_t bge_ip_csum;
+ volatile u_int16_t bge_tcp_udp_csum;
+ volatile u_int16_t bge_error_flag;
+ volatile u_int16_t bge_vlan_tag;
#else
- u_int16_t bge_len;
- u_int16_t bge_idx;
- u_int16_t bge_flags;
- u_int16_t bge_type;
- u_int16_t bge_tcp_udp_csum;
- u_int16_t bge_ip_csum;
- u_int16_t bge_vlan_tag;
- u_int16_t bge_error_flag;
+ volatile u_int16_t bge_len;
+ volatile u_int16_t bge_idx;
+ volatile u_int16_t bge_flags;
+ volatile u_int16_t bge_type;
+ volatile u_int16_t bge_tcp_udp_csum;
+ volatile u_int16_t bge_ip_csum;
+ volatile u_int16_t bge_vlan_tag;
+ volatile u_int16_t bge_error_flag;
#endif
- u_int32_t bge_rsvd;
- u_int32_t bge_opaque;
+ volatile u_int32_t bge_rsvd;
+ volatile u_int32_t bge_opaque;
};
#define BGE_RXBDFLAG_END 0x0004
@@ -1877,27 +1915,27 @@
struct bge_sts_idx {
#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t bge_tx_cons_idx;
- u_int16_t bge_rx_prod_idx;
+ volatile u_int16_t bge_tx_cons_idx;
+ volatile u_int16_t bge_rx_prod_idx;
#else
- u_int16_t bge_rx_prod_idx;
- u_int16_t bge_tx_cons_idx;
+ volatile u_int16_t bge_rx_prod_idx;
+ volatile u_int16_t bge_tx_cons_idx;
#endif
};
struct bge_status_block {
- u_int32_t bge_status;
- u_int32_t bge_rsvd0;
+ volatile u_int32_t bge_status;
+ volatile u_int32_t bge_rsvd0;
#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t bge_rx_std_cons_idx;
- u_int16_t bge_rx_jumbo_cons_idx;
- u_int16_t bge_rsvd1;
- u_int16_t bge_rx_mini_cons_idx;
+ volatile u_int16_t bge_rx_std_cons_idx;
+ volatile u_int16_t bge_rx_jumbo_cons_idx;
+ volatile u_int16_t bge_rsvd1;
+ volatile u_int16_t bge_rx_mini_cons_idx;
#else
- u_int16_t bge_rx_jumbo_cons_idx;
- u_int16_t bge_rx_std_cons_idx;
- u_int16_t bge_rx_mini_cons_idx;
- u_int16_t bge_rsvd1;
+ volatile u_int16_t bge_rx_jumbo_cons_idx;
+ volatile u_int16_t bge_rx_std_cons_idx;
+ volatile u_int16_t bge_rx_mini_cons_idx;
+ volatile u_int16_t bge_rsvd1;
#endif
struct bge_sts_idx bge_idx[16];
};
@@ -1918,6 +1956,7 @@
#define BCOM_VENDORID 0x14E4
#define BCOM_DEVICEID_BCM5700 0x1644
#define BCOM_DEVICEID_BCM5701 0x1645
+#define BCOM_DEVICEID_BCM5789 0x169d
/*
* Alteon AceNIC PCI vendor/device ID.
@@ -2269,20 +2308,21 @@
* no attempt is made to allocate physically contiguous memory.
*
*/
-#if 0
+#if 0 /* pre-TSO values */
+#define BGE_TXDMA_MAX ETHER_MAX_LEN_JUMBO
#ifdef _LP64
-#define BGE_NTXSEG 30
+#define BGE_NTXSEG 30
#else
-#define BGE_NTXSEG 31
+#define BGE_NTXSEG 31
#endif
-#else /* tso */
+#else /* TSO values */
#define BGE_TXDMA_MAX (round_page(IP_MAXPACKET)) /* for TSO */
#ifdef _LP64
-#define BGE_NTXSEG 120
+#define BGE_NTXSEG 120 /* XXX just a guess */
#else
-#define BGE_NTXSEG 124
+#define BGE_NTXSEG 124 /* XXX just a guess */
#endif
-#endif /* tso */
+#endif /* TSO values */
/*
@@ -2318,7 +2358,7 @@
#define BGE_TXCONS_UNSET 0xFFFF /* impossible value */
struct bge_jpool_entry {
- int slot;
+ int slot;
SLIST_ENTRY(bge_jpool_entry) jpool_entries;
};
@@ -2350,7 +2390,7 @@
struct ifmedia bge_ifmedia; /* media info */
u_int8_t bge_extram; /* has external SSRAM */
u_int8_t bge_tbi;
- u_int8_t bge_rx_alignment_bug;
+ u_int8_t bge_rx_alignment_bug;
u_int8_t bge_pcie; /* on a PCI Express port */
u_int32_t bge_return_ring_cnt;
u_int32_t bge_tx_prodidx;
@@ -2394,7 +2434,7 @@
struct callout bge_timeout;
char *bge_vpd_prodname;
char *bge_vpd_readonly;
- int bge_pending_rxintr_change;
+ int bge_pending_rxintr_change;
SLIST_HEAD(, txdmamap_pool_entry) txdma_list;
struct txdmamap_pool_entry *txdma[BGE_TX_RING_CNT];
void *bge_powerhook;
----Next_Part(Thu_Sep_27_09_26_35_2007_122)----