Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci - Make the initialize sequence close to the docu...



details:   https://anonhg.NetBSD.org/src/rev/8c4f24b81422
branches:  trunk
changeset: 751403:8c4f24b81422
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Wed Feb 03 15:36:36 2010 +0000

description:
- 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))

diffstat:

 sys/dev/pci/if_bge.c    |  247 ++++++++++++++++++++++++++++-------------------
 sys/dev/pci/if_bgereg.h |    3 +-
 sys/dev/pci/if_bgevar.h |    5 +-
 3 files changed, 153 insertions(+), 102 deletions(-)

diffs (truncated from 491 to 300 lines):

diff -r d83277861bb7 -r 8c4f24b81422 sys/dev/pci/if_bge.c
--- a/sys/dev/pci/if_bge.c      Wed Feb 03 15:34:37 2010 +0000
+++ b/sys/dev/pci/if_bge.c      Wed Feb 03 15:36:36 2010 +0000
@@ -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,16 +3128,6 @@
                }
        }
 
-       /*
-        * Set GPHY Power Down Override to leave GPHY
-        * powered up in D0 uninitialized.
-        */
-       if (BGE_IS_5705_PLUS(sc))
-               val |= BGE_MISCCFG_KEEP_GPHY_POWER;
-
-       /* 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,
@@ -3090,15 +3137,47 @@
                    i & ~BGE_VCPU_EXT_CTRL_HALT_CPU);
        }
 
-       DELAY(1000);
-
        /*
-        * XXX: from FreeBSD/Linux; no documentation
+        * Set GPHY Power Down Override to leave GPHY
+        * powered up in D0 uninitialized.
         */
+       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);
+
+       /* Step 8: wait for complete */
+       if (sc->bge_flags & BGE_PCIE)
+               delay(100*1000); /* too big */
+       else
+               delay(100);
+
+       /* 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);
+       }
+
        if (sc->bge_flags & BGE_PCIE) {
                if (sc->bge_chipid == BGE_CHIPID_BCM5750_A0) {
-                       pcireg_t reg;



Home | Main Index | Thread Index | Old Index