Module Name: src
Committed By: msaitoh
Date: Wed Feb 3 15:36:36 UTC 2010
Modified Files:
src/sys/dev/pci: if_bge.c if_bgereg.h if_bgevar.h
Log Message:
- Make the initialize sequence close to the document.
- Fix ASF heartbeat sending bug (FreeBSD rev. 1.271 (r202821))
- Use new handshake command for BCM5750 or new controllers (FreeBSD rev. 1.272
(r202822))
To generate a diff of this commit:
cvs rdiff -u -r1.179 -r1.180 src/sys/dev/pci/if_bge.c
cvs rdiff -u -r1.55 -r1.56 src/sys/dev/pci/if_bgereg.h
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/pci/if_bgevar.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.179 src/sys/dev/pci/if_bge.c:1.180
--- src/sys/dev/pci/if_bge.c:1.179 Mon Feb 1 05:38:36 2010
+++ src/sys/dev/pci/if_bge.c Wed Feb 3 15:36:36 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bge.c,v 1.179 2010/02/01 05:38:36 msaitoh Exp $ */
+/* $NetBSD: if_bge.c,v 1.180 2010/02/03 15:36:36 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.179 2010/02/01 05:38:36 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.180 2010/02/03 15:36:36 msaitoh Exp $");
#include "vlan.h"
#include "rnd.h"
@@ -753,7 +753,7 @@
dev = sc->bge_dev;
- val = pci_conf_read(sc->sc_pc, sc->sc_pcitag, sc->bge_expcap
+ val = pci_conf_read(sc->sc_pc, sc->sc_pcitag, sc->bge_pciecap
+ PCI_PCIE_DCSR);
if ((val & PCI_PCIE_DCSR_MAX_READ_REQ) !=
BGE_PCIE_DEVCTL_MAX_READRQ_4096) {
@@ -761,7 +761,7 @@
val);
val &= ~PCI_PCIE_DCSR_MAX_READ_REQ;
val |= BGE_PCIE_DEVCTL_MAX_READRQ_4096;
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, sc->bge_expcap
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, sc->bge_pciecap
+ PCI_PCIE_DCSR, val);
printf("-> 0x%04x\n", val);
}
@@ -1720,6 +1720,48 @@
}
}
+static int
+bge_poll_fw(struct bge_softc *sc)
+{
+ uint32_t val;
+ int i;
+
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
+ for (i = 0; i < BGE_TIMEOUT; i++) {
+ val = CSR_READ_4(sc, BGE_VCPU_STATUS);
+ if (val & BGE_VCPU_STATUS_INIT_DONE)
+ break;
+ DELAY(100);
+ }
+ if (i >= BGE_TIMEOUT) {
+ aprint_error_dev(sc->bge_dev, "reset timed out\n");
+ return -1;
+ }
+ } else if ((sc->bge_flags & BGE_NO_EEPROM) == 0) {
+ /*
+ * Poll the value location we just wrote until
+ * we see the 1's complement of the magic number.
+ * This indicates that the firmware initialization
+ * is complete.
+ * XXX 1000ms for Flash and 10000ms for SEEPROM.
+ */
+ for (i = 0; i < BGE_TIMEOUT; i++) {
+ val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
+ if (val == ~BGE_MAGIC_NUMBER)
+ break;
+ DELAY(10);
+ }
+
+ if (i >= BGE_TIMEOUT) {
+ aprint_error_dev(sc->bge_dev,
+ "firmware handshake timed out, val = %x\n", val);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
/*
* Do endian, PCI and DMA initialization. Also check the on-board ROM
* self-test results.
@@ -1894,7 +1936,7 @@
pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, 0);
- /* Configure mbuf memory pool */
+ /* Step 33: Configure mbuf memory pool */
if (BGE_IS_5700_FAMILY(sc)) {
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_BASEADDR,
BGE_BUFFPOOL_1);
@@ -1910,7 +1952,7 @@
CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LEN, 0x2000);
}
- /* Configure mbuf pool watermarks */
+ /* Step 35: Configure mbuf pool watermarks */
#ifdef ORIG_WPAUL_VALUES
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 24);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 24);
@@ -1939,15 +1981,15 @@
}
#endif
- /* Configure DMA resource watermarks */
+ /* Step 36: Configure DMA resource watermarks */
CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);
CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10);
- /* Enable buffer manager */
+ /* Step 38: Enable buffer manager */
CSR_WRITE_4(sc, BGE_BMAN_MODE,
BGE_BMANMODE_ENABLE | BGE_BMANMODE_LOMBUF_ATTN);
- /* Poll for buffer manager start indication */
+ /* Step 39: Poll for buffer manager start indication */
for (i = 0; i < BGE_TIMEOUT * 2; i++) {
if (CSR_READ_4(sc, BGE_BMAN_MODE) & BGE_BMANMODE_ENABLE)
break;
@@ -1960,7 +2002,7 @@
return ENXIO;
}
- /* Enable flow-through queues */
+ /* Step 40: Enable flow-through queues */
CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF);
CSR_WRITE_4(sc, BGE_FTQ_RESET, 0);
@@ -1977,7 +2019,7 @@
return ENXIO;
}
- /* Initialize the standard RX ring control block */
+ /* Step 41: Initialize the standard RX ring control block */
rcb = &sc->bge_rdata->bge_info.bge_std_rx_rcb;
BGE_HOSTADDR(rcb->bge_hostaddr, BGE_RING_DMA_ADDR(sc, bge_rx_std_ring));
if (BGE_IS_5705_PLUS(sc))
@@ -1992,7 +2034,7 @@
CSR_WRITE_4(sc, BGE_RX_STD_RCB_NICADDR, rcb->bge_nicaddr);
/*
- * Initialize the jumbo RX ring control block
+ * Step 42: Initialize the jumbo RX ring control block
* We set the 'ring disabled' bit in the flags
* field until we're actually ready to start
* using this ring (i.e. once we set the MTU
@@ -2565,7 +2607,7 @@
}
if (pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_PCIEXPRESS,
- &sc->bge_expcap, NULL) != 0) {
+ &sc->bge_pciecap, NULL) != 0) {
/* PCIe */
sc->bge_flags |= BGE_PCIE;
bge_set_max_readrq(sc);
@@ -2573,6 +2615,10 @@
BGE_PCISTATE_PCI_BUSMODE) == 0) {
/* PCI-X */
sc->bge_flags |= BGE_PCIX;
+ if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIX,
+ &sc->bge_pcixcap, NULL) == 0)
+ aprint_error_dev(sc->bge_dev,
+ "unable to find PCIX capability\n");
}
/* chipid */
@@ -2713,7 +2759,7 @@
* SEEPROM check.
* First check if firmware knows we do not have SEEPROM.
*/
- if (prop_dictionary_get_bool(device_properties(self),
+ if (prop_dictionary_get_bool(device_properties(self),
"without-seeprom", &no_seeprom) && no_seeprom)
sc->bge_flags |= BGE_NO_EEPROM;
@@ -2732,7 +2778,7 @@
& BGE_HWCFG_ASF) {
sc->bge_asf_mode |= ASF_ENABLE;
sc->bge_asf_mode |= ASF_STACKUP;
- if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750) {
+ if (BGE_IS_5750_OR_BEYOND(sc)) {
sc->bge_asf_mode |= ASF_NEW_HANDSHAKE;
}
}
@@ -3018,8 +3064,11 @@
static int
bge_reset(struct bge_softc *sc)
{
- uint32_t cachesize, command, pcistate, new_pcistate;
- pcireg_t devctl;
+ uint32_t cachesize, command, pcistate, marbmode;
+#if 0
+ uint32_t new_pcistate;
+#endif
+ pcireg_t devctl, reg;
int i, val;
void (*write_op)(struct bge_softc *, int, int);
@@ -3037,22 +3086,30 @@
command = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD);
pcistate = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE);
+ /* Step 5a: Enable memory arbiter. */
+ marbmode = 0;
+ if (BGE_IS_5714_FAMILY(sc))
+ marbmode = CSR_READ_4(sc, BGE_MARB_MODE);
+ CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | marbmode);
+
+ /* Step 5b-5d: */
pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
BGE_PCIMISCCTL_INDIRECT_ACCESS | BGE_PCIMISCCTL_MASK_PCI_INTR |
BGE_HIF_SWAP_OPTIONS | BGE_PCIMISCCTL_PCISTATE_RW);
- /* Disable fastboot on controllers that support it. */
+ /* XXX ???: Disable fastboot on controllers that support it. */
if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 ||
BGE_IS_5755_PLUS(sc))
CSR_WRITE_4(sc, BGE_FASTBOOT_PC, 0);
/*
- * Write the magic number to SRAM at offset 0xB50.
+ * Step 6: Write the magic number to SRAM at offset 0xB50.
* When firmware finishes its initialization it will
* write ~BGE_MAGIC_NUMBER to the same location.
*/
bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
+ /* Step 7: */
val = BGE_MISCCFG_RESET_CORE_CLOCKS | (65<<1);
/*
* XXX: from FreeBSD/Linux; no documentation
@@ -3071,6 +3128,15 @@
}
}
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
+ i = CSR_READ_4(sc, BGE_VCPU_STATUS);
+ CSR_WRITE_4(sc, BGE_VCPU_STATUS,
+ i | BGE_VCPU_STATUS_DRV_RESET);
+ i = CSR_READ_4(sc, BGE_VCPU_EXT_CTRL);
+ CSR_WRITE_4(sc, BGE_VCPU_EXT_CTRL,
+ i & ~BGE_VCPU_EXT_CTRL_HALT_CPU);
+ }
+
/*
* Set GPHY Power Down Override to leave GPHY
* powered up in D0 uninitialized.
@@ -3078,27 +3144,40 @@
if (BGE_IS_5705_PLUS(sc))
val |= BGE_MISCCFG_KEEP_GPHY_POWER;
+ /* XXX 5721, 5751 and 5752 */
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750)
+ val |= BGE_MISCCFG_GRC_RESET_DISABLE;
+
/* Issue global reset */
write_op(sc, BGE_MISC_CFG, val);
- if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
- i = CSR_READ_4(sc, BGE_VCPU_STATUS);
- CSR_WRITE_4(sc, BGE_VCPU_STATUS,
- i | BGE_VCPU_STATUS_DRV_RESET);
- i = CSR_READ_4(sc, BGE_VCPU_EXT_CTRL);
- CSR_WRITE_4(sc, BGE_VCPU_EXT_CTRL,
- i & ~BGE_VCPU_EXT_CTRL_HALT_CPU);
- }
+ /* Step 8: wait for complete */
+ if (sc->bge_flags & BGE_PCIE)
+ delay(100*1000); /* too big */
+ else
+ delay(100);
- DELAY(1000);
+ /* From Linux: dummy read to flush PCI posted writes */
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD);
+
+ /* Step 9-10: Reset some of the PCI state that got zapped by reset */
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
+ BGE_PCIMISCCTL_INDIRECT_ACCESS | BGE_PCIMISCCTL_MASK_PCI_INTR |
+ BGE_HIF_SWAP_OPTIONS | BGE_PCIMISCCTL_PCISTATE_RW
+ | BGE_PCIMISCCTL_CLOCKCTL_RW);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD, command);
+ write_op(sc, BGE_MISC_CFG, (65 << 1));
+
+ /* Step 11: disable PCI-X Relaxed Ordering. */
+ if (sc->bge_flags & BGE_PCIX) {
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, sc->bge_pcixcap
+ + PCI_PCIX_CMD);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, sc->bge_pcixcap
+ + PCI_PCIX_CMD, reg & ~PCI_PCIX_CMD_RELAXED_ORDER);
+ }
- /*
- * XXX: from FreeBSD/Linux; no documentation
- */
if (sc->bge_flags & BGE_PCIE) {
if (sc->bge_chipid == BGE_CHIPID_BCM5750_A0) {
- pcireg_t reg;
-
DELAY(500000);
/* XXX: Magic Numbers */
reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
@@ -3108,7 +3187,7 @@
reg | (1 << 15));
}
devctl = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
- sc->bge_expcap + PCI_PCIE_DCSR);
+ sc->bge_pciecap + PCI_PCIE_DCSR);
/* Clear enable no snoop and disable relaxed ordering. */
devctl &= ~(0x0010 | PCI_PCIE_DCSR_ENA_NO_SNOOP);
/* Set PCIE max payload size to 128. */
@@ -3117,56 +3196,41 @@
devctl |= PCI_PCIE_DCSR_URD | PCI_PCIE_DCSR_FED
| PCI_PCIE_DCSR_NFED | PCI_PCIE_DCSR_CED;
pci_conf_write(sc->sc_pc, sc->sc_pcitag,
- sc->bge_expcap + PCI_PCIE_DCSR, devctl);
+ sc->bge_pciecap + PCI_PCIE_DCSR, devctl);
}
- /* Reset some of the PCI state that got zapped by reset */
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
- BGE_PCIMISCCTL_INDIRECT_ACCESS | BGE_PCIMISCCTL_MASK_PCI_INTR |
- BGE_HIF_SWAP_OPTIONS | BGE_PCIMISCCTL_PCISTATE_RW);
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ, cachesize);
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD, command);
- write_op(sc, BGE_MISC_CFG, (65 << 1));
+ /* Step 12: Enable memory arbiter. */
+ marbmode = 0;
+ if (BGE_IS_5714_FAMILY(sc))
+ marbmode = CSR_READ_4(sc, BGE_MARB_MODE);
+ CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | marbmode);
- /* Enable memory arbiter. */
- {
- 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, BGE_MARBMODE_ENABLE | marbmode);
+ /* Step 17: Poll until the firmware iitializeation is complete */
+ bge_poll_fw(sc);
+
+ /* XXX 5721, 5751 and 5752 */
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750) {
+ /* Step 19: */
+ BGE_SETBIT(sc, BGE_TLP_CONTROL_REG, 1 << 29 | 1 << 25);
+ /* Step 20: */
+ BGE_SETBIT(sc, BGE_TLP_CONTROL_REG, BGE_TLP_DATA_FIFO_PROTECT);
}
- if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
- for (i = 0; i < BGE_TIMEOUT; i++) {
- val = CSR_READ_4(sc, BGE_VCPU_STATUS);
- if (val & BGE_VCPU_STATUS_INIT_DONE)
- break;
- DELAY(100);
- }
- if (i == BGE_TIMEOUT) {
- aprint_error_dev(sc->bge_dev, "reset timed out\n");
- return 1;
- }
- } else {
- /*
- * Poll the value location we just wrote until
- * we see the 1's complement of the magic number.
- * This indicates that the firmware initialization
- * is complete.
- */
- for (i = 0; i < BGE_TIMEOUT; i++) {
- val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
- if (val == ~BGE_MAGIC_NUMBER)
- break;
- DELAY(10);
- }
+ /*
+ * Step 18: wirte mac mode
+ * XXX Write 0x0c for 5703S and 5704S
+ */
+ CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
- if (i >= BGE_TIMEOUT && (!(sc->bge_flags & BGE_NO_EEPROM)))
- aprint_error_dev(sc->bge_dev,
- "firmware handshake timed out, val = %x\n", val);
- }
+ /* Step 21: 5822 B0 errata */
+ if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5704_BX)
+ BGE_SETBIT(sc, 0x66, 1 << 13 | 1 << 12 | 1 << 10);
+
+ /* Step 23: restore cache line size */
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ, cachesize);
+
+#if 0
/*
* XXX Wait for the value of the PCISTATE register to
* return to its original pre-reset state. This is a
@@ -3187,28 +3251,15 @@
(pcistate & ~BGE_PCISTATE_RESERVED)) {
aprint_error_dev(sc->bge_dev, "pcistate failed to revert\n");
}
-
-#if 0
- /* Enable memory arbiter. */
- /* XXX why do this twice? */
- {
- 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, BGE_MARBMODE_ENABLE | marbmode);
- }
#endif
- /* Fix up byte swapping */
+ /* Step 28: Fix up byte swapping */
CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS);
/* Tell the ASF firmware we are up */
if (sc->bge_asf_mode & ASF_STACKUP)
BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
- CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
-
/*
* The 5704 in TBI mode apparently needs some special
* adjustment to insure the SERDES drive level is set
@@ -3562,7 +3613,7 @@
if (sc->bge_asf_count)
sc->bge_asf_count --;
else {
- sc->bge_asf_count = 5;
+ sc->bge_asf_count = 2;
bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW,
BGE_FW_DRV_ALIVE);
bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_LEN, 4);
@@ -4538,12 +4589,10 @@
BGE_CLRBIT(sc, reg, bit);
- for (i = 0; i < BGE_TIMEOUT; i++) {
+ for (i = 0; i < 1000; i++) {
if ((CSR_READ_4(sc, reg) & bit) == 0)
return;
delay(100);
- if (sc->bge_flags & BGE_PCIE)
- DELAY(1000);
}
/*
Index: src/sys/dev/pci/if_bgereg.h
diff -u src/sys/dev/pci/if_bgereg.h:1.55 src/sys/dev/pci/if_bgereg.h:1.56
--- src/sys/dev/pci/if_bgereg.h:1.55 Thu Jan 28 03:09:13 2010
+++ src/sys/dev/pci/if_bgereg.h Wed Feb 3 15:36:36 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bgereg.h,v 1.55 2010/01/28 03:09:13 msaitoh Exp $ */
+/* $NetBSD: if_bgereg.h,v 1.56 2010/02/03 15:36:36 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2001
@@ -1848,6 +1848,7 @@
#define BGE_MISCCFG_BOARD_ID_MASK 0x0001e000
#define BGE_MISCCFG_EPHY_IDDQ 0x00200000
#define BGE_MISCCFG_KEEP_GPHY_POWER 0x04000000
+#define BGE_MISCCFG_GRC_RESET_DISABLE 0x20000000
#define BGE_32BITTIME_66MHZ (0x41 << 1)
Index: src/sys/dev/pci/if_bgevar.h
diff -u src/sys/dev/pci/if_bgevar.h:1.3 src/sys/dev/pci/if_bgevar.h:1.4
--- src/sys/dev/pci/if_bgevar.h:1.3 Thu Jan 28 03:09:13 2010
+++ src/sys/dev/pci/if_bgevar.h Wed Feb 3 15:36:36 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bgevar.h,v 1.3 2010/01/28 03:09:13 msaitoh Exp $ */
+/* $NetBSD: if_bgevar.h,v 1.4 2010/02/03 15:36:36 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2001
@@ -235,7 +235,8 @@
u_int32_t bge_return_ring_cnt;
u_int32_t bge_tx_prodidx;
bus_dma_tag_t bge_dmatag;
- int bge_expcap;
+ uint32_t bge_pcixcap;
+ uint32_t bge_pciecap;
u_int32_t bge_chipid;
u_int32_t bge_local_ctrl_reg;
uint8_t bge_asf_mode;