bge: Bring in APE support from FreeBSD
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 8 Dec 2013 11:14:09 +0000 (19:14 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 8 Dec 2013 11:23:55 +0000 (19:23 +0800)
Obtained-from: FreeBSD 241438 248226

sys/dev/netif/bge/if_bge.c
sys/dev/netif/bge/if_bgereg.h
sys/dev/netif/bge/if_bgevar.h

index f4199d9..2414705 100644 (file)
@@ -416,6 +416,13 @@ static void        bge_sig_pre_reset(struct bge_softc *, int);
 static void    bge_stop_fw(struct bge_softc *);
 static void    bge_asf_driver_up(struct bge_softc *);
 
+static void    bge_ape_lock_init(struct bge_softc *);
+static void    bge_ape_read_fw_ver(struct bge_softc *);
+static int     bge_ape_lock(struct bge_softc *, int);
+static void    bge_ape_unlock(struct bge_softc *, int);
+static void    bge_ape_send_event(struct bge_softc *, uint32_t);
+static void    bge_ape_driver_state_change(struct bge_softc *, int);
+
 /*
  * Set following tunable to 1 for some IBM blade servers with the DNLK
  * switch module. Auto negotiation is broken for those configurations.
@@ -681,6 +688,9 @@ bge_miibus_readreg(device_t dev, int phy, int reg)
        KASSERT(phy == sc->bge_phyno,
            ("invalid phyno %d, should be %d", phy, sc->bge_phyno));
 
+       if (bge_ape_lock(sc, sc->bge_phy_ape_lock) != 0)
+               return 0;
+
        /* Clear the autopoll bit if set, otherwise may trigger PCI errors. */
        if (sc->bge_mi_mode & BGE_MIMODE_AUTOPOLL) {
                CSR_WRITE_4(sc, BGE_MI_MODE,
@@ -713,6 +723,8 @@ bge_miibus_readreg(device_t dev, int phy, int reg)
                DELAY(80);
        }
 
+       bge_ape_unlock(sc, sc->bge_phy_ape_lock);
+
        if (val & BGE_MICOMM_READFAIL)
                return 0;
 
@@ -732,6 +744,9 @@ bge_miibus_writereg(device_t dev, int phy, int reg, int val)
            (reg == BRGPHY_MII_1000CTL || reg == BRGPHY_MII_AUXCTL))
               return 0;
 
+       if (bge_ape_lock(sc, sc->bge_phy_ape_lock) != 0)
+               return 0;
+
        /* Clear the autopoll bit if set, otherwise may trigger PCI errors. */
        if (sc->bge_mi_mode & BGE_MIMODE_AUTOPOLL) {
                CSR_WRITE_4(sc, BGE_MI_MODE,
@@ -761,6 +776,8 @@ bge_miibus_writereg(device_t dev, int phy, int reg, int val)
                DELAY(80);
        }
 
+       bge_ape_unlock(sc, sc->bge_phy_ape_lock);
+
        return 0;
 }
 
@@ -1833,6 +1850,10 @@ bge_blockinit(struct bge_softc *sc)
        else
                val |= BGE_PORTMODE_MII;
 
+       /* Allow APE to send/receive frames. */
+       if (sc->bge_mfw_flags & BGE_MFW_ON_APE)
+               val |= BGE_MACMODE_APE_RX_EN | BGE_MACMODE_APE_TX_EN;
+
        /* Turn on DMA, clear stats */
        CSR_WRITE_4(sc, BGE_MAC_MODE, val);
        DELAY(40);
@@ -2021,6 +2042,7 @@ bge_attach(device_t dev)
        callout_init_mp(&sc->bge_stat_timer);
        lwkt_serialize_init(&sc->bge_jslot_serializer);
 
+       sc->bge_func_addr = pci_get_function(dev);
        product = pci_get_device(dev);
        vendor = pci_get_vendor(dev);
 
@@ -2271,6 +2293,32 @@ bge_attach(device_t dev)
                }
        }
 
+       /*
+        * Chips with APE need BAR2 access for APE registers/memory.
+        */
+       if (sc->bge_flags & BGE_FLAG_APE) {
+               uint32_t pcistate;
+
+               rid = PCIR_BAR(2);
+               sc->bge_res2 = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+                   RF_ACTIVE);
+               if (sc->bge_res2 == NULL) {
+                       device_printf(dev, "couldn't map BAR2 memory\n");
+                       error = ENXIO;
+                       goto fail;
+               }
+
+               /* Enable APE register/memory access by host driver. */
+               pcistate = pci_read_config(dev, BGE_PCI_PCISTATE, 4);
+               pcistate |= BGE_PCISTATE_ALLOW_APE_CTLSPC_WR |
+                   BGE_PCISTATE_ALLOW_APE_SHMEM_WR |
+                   BGE_PCISTATE_ALLOW_APE_PSPACE_WR;
+               pci_write_config(dev, BGE_PCI_PCISTATE, pcistate, 4);
+
+               bge_ape_lock_init(sc);
+               bge_ape_read_fw_ver(sc);
+       }
+
        /*
         * Allocate interrupt
         */
@@ -2713,6 +2761,10 @@ bge_detach(device_t dev)
                bus_release_resource(dev, SYS_RES_MEMORY,
                    BGE_PCI_BAR0, sc->bge_res);
        }
+       if (sc->bge_res2 != NULL) {
+               bus_release_resource(dev, SYS_RES_MEMORY,
+                   PCIR_BAR(2), sc->bge_res2);
+       }
 
        if (sc->bge_sysctl_tree != NULL)
                sysctl_ctx_free(&sc->bge_sysctl_ctx);
@@ -2731,6 +2783,8 @@ bge_reset(struct bge_softc *sc)
        int i, val = 0;
 
        mac_mode_mask = BGE_MACMODE_HALF_DUPLEX | BGE_MACMODE_PORTMODE;
+       if (sc->bge_mfw_flags & BGE_MFW_ON_APE)
+               mac_mode_mask |= BGE_MACMODE_APE_RX_EN | BGE_MACMODE_APE_TX_EN;
        mac_mode = CSR_READ_4(sc, BGE_MAC_MODE) & mac_mode_mask;
 
        if (BGE_IS_575X_PLUS(sc) && !BGE_IS_5714_FAMILY(sc) &&
@@ -2743,6 +2797,25 @@ bge_reset(struct bge_softc *sc)
                write_op = bge_writereg_ind;
        }
 
+       if (sc->bge_asicrev != BGE_ASICREV_BCM5700 &&
+           sc->bge_asicrev != BGE_ASICREV_BCM5701) {
+               CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_SET1);
+               for (i = 0; i < 8000; i++) {
+                       if (CSR_READ_4(sc, BGE_NVRAM_SWARB) &
+                           BGE_NVRAMSWARB_GNT1)
+                               break;
+                       DELAY(20);
+               }
+               if (i == 8000) {
+                       if (bootverbose) {
+                               if_printf(&sc->arpcom.ac_if,
+                                   "NVRAM lock timedout!\n");
+                       }
+               }
+       }
+       /* Take APE lock when performing reset. */
+       bge_ape_lock(sc, BGE_APE_LOCK_GRC);
+
        /* Save some important PCI state. */
        cachesize = pci_read_config(dev, BGE_PCI_CACHESZ, 4);
        command = pci_read_config(dev, BGE_PCI_CMD, 4);
@@ -2856,6 +2929,11 @@ bge_reset(struct bge_softc *sc)
        if (sc->bge_chipid == BGE_CHIPID_BCM5704_A0 &&
            (sc->bge_flags & BGE_FLAG_PCIX))
                val |= BGE_PCISTATE_RETRY_SAME_DMA;
+       if (sc->bge_mfw_flags & BGE_MFW_ON_APE) {
+               val |= BGE_PCISTATE_ALLOW_APE_CTLSPC_WR |
+                   BGE_PCISTATE_ALLOW_APE_SHMEM_WR |
+                   BGE_PCISTATE_ALLOW_APE_PSPACE_WR;
+       }
        pci_write_config(dev, BGE_PCI_PCISTATE, val, 4);
        pci_write_config(dev, BGE_PCI_CACHESZ, cachesize, 4);
        pci_write_config(dev, BGE_PCI_CMD, command, 4);
@@ -2913,6 +2991,8 @@ bge_reset(struct bge_softc *sc)
        CSR_WRITE_4(sc, BGE_MAC_MODE, val);
        DELAY(40);
 
+       bge_ape_unlock(sc, BGE_APE_LOCK_GRC);
+
        if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
                for (i = 0; i < BGE_TIMEOUT; i++) {
                        val = CSR_READ_4(sc, BGE_VCPU_STATUS);
@@ -3769,7 +3849,10 @@ bge_init(void *xsc)
        DELAY(100);
 
        /* Turn on receiver */
-       BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
+       mode = CSR_READ_4(sc, BGE_RX_MODE);
+       if (BGE_IS_5755_PLUS(sc))
+               mode |= BGE_RXMODE_IPV6_ENABLE;
+       CSR_WRITE_4(sc, BGE_RX_MODE, mode | BGE_RXMODE_ENABLE);
        DELAY(10);
 
        /*
@@ -5124,10 +5207,8 @@ bge_sig_pre_reset(struct bge_softc *sc, int type)
                }
        }
 
-#ifdef notyet
        if (type == BGE_RESET_START || type == BGE_RESET_SUSPEND)
                bge_ape_driver_state_change(sc, type);
-#endif
 }
 
 static void
@@ -5163,10 +5244,8 @@ bge_sig_post_reset(struct bge_softc *sc, int type)
                        break;
                }
        }
-#ifdef notyet
        if (type == BGE_RESET_SHUTDOWN)
                bge_ape_driver_state_change(sc, type);
-#endif
 }
 
 static void
@@ -5189,3 +5268,316 @@ bge_asf_driver_up(struct bge_softc *sc)
                }
        }
 }
+
+/*
+ * Clear all stale locks and select the lock for this driver instance.
+ */
+static void
+bge_ape_lock_init(struct bge_softc *sc)
+{
+       uint32_t bit, regbase;
+       int i;
+
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5761)
+               regbase = BGE_APE_LOCK_GRANT;
+       else
+               regbase = BGE_APE_PER_LOCK_GRANT;
+
+       /* Clear any stale locks. */
+       for (i = BGE_APE_LOCK_PHY0; i <= BGE_APE_LOCK_GPIO; i++) {
+               switch (i) {
+               case BGE_APE_LOCK_PHY0:
+               case BGE_APE_LOCK_PHY1:
+               case BGE_APE_LOCK_PHY2:
+               case BGE_APE_LOCK_PHY3:
+                       bit = BGE_APE_LOCK_GRANT_DRIVER0;
+                       break;
+               default:
+                       if (sc->bge_func_addr == 0)
+                               bit = BGE_APE_LOCK_GRANT_DRIVER0;
+                       else
+                               bit = (1 << sc->bge_func_addr);
+               }
+               APE_WRITE_4(sc, regbase + 4 * i, bit);
+       }
+
+       /* Select the PHY lock based on the device's function number. */
+       switch (sc->bge_func_addr) {
+       case 0:
+               sc->bge_phy_ape_lock = BGE_APE_LOCK_PHY0;
+               break;
+       case 1:
+               sc->bge_phy_ape_lock = BGE_APE_LOCK_PHY1;
+               break;
+       case 2:
+               sc->bge_phy_ape_lock = BGE_APE_LOCK_PHY2;
+               break;
+       case 3:
+               sc->bge_phy_ape_lock = BGE_APE_LOCK_PHY3;
+               break;
+       default:
+               device_printf(sc->bge_dev,
+                   "PHY lock not supported on this function\n");
+       }
+}
+
+/*
+ * Check for APE firmware, set flags, and print version info.
+ */
+static void
+bge_ape_read_fw_ver(struct bge_softc *sc)
+{
+       const char *fwtype;
+       uint32_t apedata, features;
+
+       /* Check for a valid APE signature in shared memory. */
+       apedata = APE_READ_4(sc, BGE_APE_SEG_SIG);
+       if (apedata != BGE_APE_SEG_SIG_MAGIC) {
+               device_printf(sc->bge_dev, "no APE signature\n");
+               sc->bge_mfw_flags &= ~BGE_MFW_ON_APE;
+               return;
+       }
+
+       /* Check if APE firmware is running. */
+       apedata = APE_READ_4(sc, BGE_APE_FW_STATUS);
+       if ((apedata & BGE_APE_FW_STATUS_READY) == 0) {
+               device_printf(sc->bge_dev, "APE signature found "
+                   "but FW status not ready! 0x%08x\n", apedata);
+               return;
+       }
+
+       sc->bge_mfw_flags |= BGE_MFW_ON_APE;
+
+       /* Fetch the APE firwmare type and version. */
+       apedata = APE_READ_4(sc, BGE_APE_FW_VERSION);
+       features = APE_READ_4(sc, BGE_APE_FW_FEATURES);
+       if ((features & BGE_APE_FW_FEATURE_NCSI) != 0) {
+               sc->bge_mfw_flags |= BGE_MFW_TYPE_NCSI;
+               fwtype = "NCSI";
+       } else if ((features & BGE_APE_FW_FEATURE_DASH) != 0) {
+               sc->bge_mfw_flags |= BGE_MFW_TYPE_DASH;
+               fwtype = "DASH";
+       } else
+               fwtype = "UNKN";
+
+       /* Print the APE firmware version. */
+       device_printf(sc->bge_dev, "APE FW version: %s v%d.%d.%d.%d\n",
+           fwtype,
+           (apedata & BGE_APE_FW_VERSION_MAJMSK) >> BGE_APE_FW_VERSION_MAJSFT,
+           (apedata & BGE_APE_FW_VERSION_MINMSK) >> BGE_APE_FW_VERSION_MINSFT,
+           (apedata & BGE_APE_FW_VERSION_REVMSK) >> BGE_APE_FW_VERSION_REVSFT,
+           (apedata & BGE_APE_FW_VERSION_BLDMSK));
+}
+
+static int
+bge_ape_lock(struct bge_softc *sc, int locknum)
+{
+       uint32_t bit, gnt, req, status;
+       int i, off;
+
+       if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) == 0)
+               return (0);
+
+       /* Lock request/grant registers have different bases. */
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5761) {
+               req = BGE_APE_LOCK_REQ;
+               gnt = BGE_APE_LOCK_GRANT;
+       } else {
+               req = BGE_APE_PER_LOCK_REQ;
+               gnt = BGE_APE_PER_LOCK_GRANT;
+       }
+
+       off = 4 * locknum;
+
+       switch (locknum) {
+       case BGE_APE_LOCK_GPIO:
+               /* Lock required when using GPIO. */
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5761)
+                       return (0);
+               if (sc->bge_func_addr == 0)
+                       bit = BGE_APE_LOCK_REQ_DRIVER0;
+               else
+                       bit = (1 << sc->bge_func_addr);
+               break;
+       case BGE_APE_LOCK_GRC:
+               /* Lock required to reset the device. */
+               if (sc->bge_func_addr == 0)
+                       bit = BGE_APE_LOCK_REQ_DRIVER0;
+               else
+                       bit = (1 << sc->bge_func_addr);
+               break;
+       case BGE_APE_LOCK_MEM:
+               /* Lock required when accessing certain APE memory. */
+               if (sc->bge_func_addr == 0)
+                       bit = BGE_APE_LOCK_REQ_DRIVER0;
+               else
+                       bit = (1 << sc->bge_func_addr);
+               break;
+       case BGE_APE_LOCK_PHY0:
+       case BGE_APE_LOCK_PHY1:
+       case BGE_APE_LOCK_PHY2:
+       case BGE_APE_LOCK_PHY3:
+               /* Lock required when accessing PHYs. */
+               bit = BGE_APE_LOCK_REQ_DRIVER0;
+               break;
+       default:
+               return (EINVAL);
+       }
+
+       /* Request a lock. */
+       APE_WRITE_4(sc, req + off, bit);
+
+       /* Wait up to 1 second to acquire lock. */
+       for (i = 0; i < 20000; i++) {
+               status = APE_READ_4(sc, gnt + off);
+               if (status == bit)
+                       break;
+               DELAY(50);
+       }
+
+       /* Handle any errors. */
+       if (status != bit) {
+               device_printf(sc->bge_dev, "APE lock %d request failed! "
+                   "request = 0x%04x[0x%04x], status = 0x%04x[0x%04x]\n",
+                   locknum, req + off, bit & 0xFFFF, gnt + off,
+                   status & 0xFFFF);
+               /* Revoke the lock request. */
+               APE_WRITE_4(sc, gnt + off, bit);
+               return (EBUSY);
+       }
+
+       return (0);
+}
+
+static void
+bge_ape_unlock(struct bge_softc *sc, int locknum)
+{
+       uint32_t bit, gnt;
+       int off;
+
+       if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) == 0)
+               return;
+
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5761)
+               gnt = BGE_APE_LOCK_GRANT;
+       else
+               gnt = BGE_APE_PER_LOCK_GRANT;
+
+       off = 4 * locknum;
+
+       switch (locknum) {
+       case BGE_APE_LOCK_GPIO:
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5761)
+                       return;
+               if (sc->bge_func_addr == 0)
+                       bit = BGE_APE_LOCK_GRANT_DRIVER0;
+               else
+                       bit = (1 << sc->bge_func_addr);
+               break;
+       case BGE_APE_LOCK_GRC:
+               if (sc->bge_func_addr == 0)
+                       bit = BGE_APE_LOCK_GRANT_DRIVER0;
+               else
+                       bit = (1 << sc->bge_func_addr);
+               break;
+       case BGE_APE_LOCK_MEM:
+               if (sc->bge_func_addr == 0)
+                       bit = BGE_APE_LOCK_GRANT_DRIVER0;
+               else
+                       bit = (1 << sc->bge_func_addr);
+               break;
+       case BGE_APE_LOCK_PHY0:
+       case BGE_APE_LOCK_PHY1:
+       case BGE_APE_LOCK_PHY2:
+       case BGE_APE_LOCK_PHY3:
+               bit = BGE_APE_LOCK_GRANT_DRIVER0;
+               break;
+       default:
+               return;
+       }
+
+       APE_WRITE_4(sc, gnt + off, bit);
+}
+
+/*
+ * Send an event to the APE firmware.
+ */
+static void
+bge_ape_send_event(struct bge_softc *sc, uint32_t event)
+{
+       uint32_t apedata;
+       int i;
+
+       /* NCSI does not support APE events. */
+       if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) == 0)
+               return;
+
+       /* Wait up to 1ms for APE to service previous event. */
+       for (i = 10; i > 0; i--) {
+               if (bge_ape_lock(sc, BGE_APE_LOCK_MEM) != 0)
+                       break;
+               apedata = APE_READ_4(sc, BGE_APE_EVENT_STATUS);
+               if ((apedata & BGE_APE_EVENT_STATUS_EVENT_PENDING) == 0) {
+                       APE_WRITE_4(sc, BGE_APE_EVENT_STATUS, event |
+                           BGE_APE_EVENT_STATUS_EVENT_PENDING);
+                       bge_ape_unlock(sc, BGE_APE_LOCK_MEM);
+                       APE_WRITE_4(sc, BGE_APE_EVENT, BGE_APE_EVENT_1);
+                       break;
+               }
+               bge_ape_unlock(sc, BGE_APE_LOCK_MEM);
+               DELAY(100);
+       }
+       if (i == 0)
+               device_printf(sc->bge_dev, "APE event 0x%08x send timed out\n",
+                   event);
+}
+
+static void
+bge_ape_driver_state_change(struct bge_softc *sc, int kind)
+{
+       uint32_t apedata, event;
+
+       if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) == 0)
+               return;
+
+       switch (kind) {
+       case BGE_RESET_START:
+               /* If this is the first load, clear the load counter. */
+               apedata = APE_READ_4(sc, BGE_APE_HOST_SEG_SIG);
+               if (apedata != BGE_APE_HOST_SEG_SIG_MAGIC)
+                       APE_WRITE_4(sc, BGE_APE_HOST_INIT_COUNT, 0);
+               else {
+                       apedata = APE_READ_4(sc, BGE_APE_HOST_INIT_COUNT);
+                       APE_WRITE_4(sc, BGE_APE_HOST_INIT_COUNT, ++apedata);
+               }
+               APE_WRITE_4(sc, BGE_APE_HOST_SEG_SIG,
+                   BGE_APE_HOST_SEG_SIG_MAGIC);
+               APE_WRITE_4(sc, BGE_APE_HOST_SEG_LEN,
+                   BGE_APE_HOST_SEG_LEN_MAGIC);
+
+               /* Add some version info if bge(4) supports it. */
+               APE_WRITE_4(sc, BGE_APE_HOST_DRIVER_ID,
+                   BGE_APE_HOST_DRIVER_ID_MAGIC(1, 0));
+               APE_WRITE_4(sc, BGE_APE_HOST_BEHAVIOR,
+                   BGE_APE_HOST_BEHAV_NO_PHYLOCK);
+               APE_WRITE_4(sc, BGE_APE_HOST_HEARTBEAT_INT_MS,
+                   BGE_APE_HOST_HEARTBEAT_INT_DISABLE);
+               APE_WRITE_4(sc, BGE_APE_HOST_DRVR_STATE,
+                   BGE_APE_HOST_DRVR_STATE_START);
+               event = BGE_APE_EVENT_STATUS_STATE_START;
+               break;
+       case BGE_RESET_SHUTDOWN:
+               APE_WRITE_4(sc, BGE_APE_HOST_DRVR_STATE,
+                   BGE_APE_HOST_DRVR_STATE_UNLOAD);
+               event = BGE_APE_EVENT_STATUS_STATE_UNLOAD;
+               break;
+       case BGE_RESET_SUSPEND:
+               event = BGE_APE_EVENT_STATUS_STATE_SUSPEND;
+               break;
+       default:
+               return;
+       }
+
+       bge_ape_send_event(sc, event | BGE_APE_EVENT_STATUS_DRIVER_EVNT |
+           BGE_APE_EVENT_STATUS_STATE_CHNGE);
+}
index 2453f2a..f0cb37e 100644 (file)
 #define BGE_PCISTATE_FLATVIEW_MODE     0x00000100
 #define BGE_PCISTATE_PCI_TGT_RETRY_MAX 0x00000E00
 #define        BGE_PCISTATE_RETRY_SAME_DMA     0x00002000
+#define        BGE_PCISTATE_ALLOW_APE_CTLSPC_WR 0x00010000
+#define        BGE_PCISTATE_ALLOW_APE_SHMEM_WR 0x00020000
+#define        BGE_PCISTATE_ALLOW_APE_PSPACE_WR 0x00040000
 
 /*
  * PCI Clock Control register -- note, this register is read only
 #define BGE_PCICLOCKCTL_SYSPLL_DISABLE 0x00008000
 #define BGE_PCICLOCKCTL_BIST_ENABLE    0x00010000
 
+/* BAR0 (MAC) Register Definitions */
 
 /*
  * High priority mailbox registers
 #define BGE_MACMODE_TXDMA_ENB          0x00200000
 #define BGE_MACMODE_RXDMA_ENB          0x00400000
 #define BGE_MACMODE_FRMHDR_DMA_ENB     0x00800000
+#define        BGE_MACMODE_APE_RX_EN           0x08000000
+#define        BGE_MACMODE_APE_TX_EN           0x10000000
 
 #define BGE_PORTMODE_NONE              0x00000000
 #define BGE_PORTMODE_MII               0x00000004
 #define BGE_RXMODE_RSS_TCP_IPV6_HASH   0x00080000
 #define BGE_RXMODE_RSS_HASH_MASK_BITS  0x00700000
 #define BGE_RXMODE_RSS_ENABLE          0x00800000
+#define        BGE_RXMODE_IPV6_ENABLE          0x01000000
 
 /* Receive MAC status register */
 #define BGE_RXSTAT_REMOTE_XOFFED       0x00000001
 #define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K    0x00030000
 #define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K   0x000C0000
 
+/* BD Read DMA Mode register */
+#define        BGE_RDMA_BD_MODE                0x4A00
+/* BD Read DMA Mode status register */
+#define        BGE_RDMA_BD_STATUS              0x4A04
+
+#define        BGE_RDMA_BD_MODE_RESET          0x00000001
+#define        BGE_RDMA_BD_MODE_ENABLE         0x00000002
+
+/* Non-LSO Read DMA Mode register */
+#define        BGE_RDMA_NON_LSO_MODE           0x4B00
+/* Non-LSO Read DMA Mode status register */
+#define        BGE_RDMA_NON_LSO_STATUS         0x4B04
+
+#define        BGE_RDMA_NON_LSO_MODE_RESET     0x00000001
+#define        BGE_RDMA_NON_LSO_MODE_ENABLE    0x00000002
+
 /*
  * Write DMA control registers
  */
 #define BGE_MEMWIN_START               0x00008000
 #define BGE_MEMWIN_END                 0x0000FFFF
 
+/* BAR1 (APE) Register Definitions */
+
+#define        BGE_APE_GPIO_MSG                0x0008
+#define        BGE_APE_EVENT                   0x000C
+#define        BGE_APE_LOCK_REQ                0x002C
+#define        BGE_APE_LOCK_GRANT              0x004C
+
+#define        BGE_APE_GPIO_MSG_SHIFT          4
+
+#define        BGE_APE_EVENT_1                 0x00000001
+
+#define        BGE_APE_LOCK_REQ_DRIVER0        0x00001000
+
+#define        BGE_APE_LOCK_GRANT_DRIVER0      0x00001000
+
+/* APE Shared Memory block (writable by APE only) */
+#define        BGE_APE_SEG_SIG                 0x4000
+#define        BGE_APE_FW_STATUS               0x400C
+#define        BGE_APE_FW_FEATURES             0x4010
+#define        BGE_APE_FW_BEHAVIOR             0x4014
+#define        BGE_APE_FW_VERSION              0x4018
+#define        BGE_APE_FW_HEARTBEAT_INTERVAL   0x4024
+#define        BGE_APE_FW_HEARTBEAT            0x4028
+#define        BGE_APE_FW_ERROR_FLAGS          0x4074
+
+#define        BGE_APE_SEG_SIG_MAGIC           0x41504521
+
+#define        BGE_APE_FW_STATUS_READY         0x00000100
+
+#define        BGE_APE_FW_FEATURE_DASH         0x00000001
+#define        BGE_APE_FW_FEATURE_NCSI         0x00000002
+
+#define        BGE_APE_FW_VERSION_MAJMSK       0xFF000000
+#define        BGE_APE_FW_VERSION_MAJSFT       24
+#define        BGE_APE_FW_VERSION_MINMSK       0x00FF0000
+#define        BGE_APE_FW_VERSION_MINSFT       16
+#define        BGE_APE_FW_VERSION_REVMSK       0x0000FF00
+#define        BGE_APE_FW_VERSION_REVSFT       8
+#define        BGE_APE_FW_VERSION_BLDMSK       0x000000FF
+
+/* Host Shared Memory block (writable by host only) */
+#define        BGE_APE_HOST_SEG_SIG            0x4200
+#define        BGE_APE_HOST_SEG_LEN            0x4204
+#define        BGE_APE_HOST_INIT_COUNT         0x4208
+#define        BGE_APE_HOST_DRIVER_ID          0x420C
+#define        BGE_APE_HOST_BEHAVIOR           0x4210
+#define        BGE_APE_HOST_HEARTBEAT_INT_MS   0x4214
+#define        BGE_APE_HOST_HEARTBEAT_COUNT    0x4218
+#define        BGE_APE_HOST_DRVR_STATE         0x421C
+#define        BGE_APE_HOST_WOL_SPEED          0x4224
+
+#define        BGE_APE_HOST_SEG_SIG_MAGIC      0x484F5354
+
+#define        BGE_APE_HOST_SEG_LEN_MAGIC      0x00000020
+
+#define        BGE_APE_HOST_DRIVER_ID_FBSD     0xF6000000
+#define        BGE_APE_HOST_DRIVER_ID_MAGIC(maj, min)                          \
+       (BGE_APE_HOST_DRIVER_ID_FBSD |                                  \
+       ((maj) & 0xffd) << 16 | ((min) & 0xff) << 8)
+
+#define        BGE_APE_HOST_BEHAV_NO_PHYLOCK   0x00000001
+
+#define        BGE_APE_HOST_HEARTBEAT_INT_DISABLE      0
+#define        BGE_APE_HOST_HEARTBEAT_INT_5SEC 5000
+
+#define        BGE_APE_HOST_DRVR_STATE_START   0x00000001
+#define        BGE_APE_HOST_DRVR_STATE_UNLOAD  0x00000002
+#define        BGE_APE_HOST_DRVR_STATE_WOL     0x00000003
+#define        BGE_APE_HOST_DRVR_STATE_SUSPEND 0x00000004
+
+#define        BGE_APE_HOST_WOL_SPEED_AUTO     0x00008000
+
+#define        BGE_APE_EVENT_STATUS            0x4300
+
+#define        BGE_APE_EVENT_STATUS_DRIVER_EVNT        0x00000010
+#define        BGE_APE_EVENT_STATUS_STATE_CHNGE        0x00000500
+#define        BGE_APE_EVENT_STATUS_STATE_START        0x00010000
+#define        BGE_APE_EVENT_STATUS_STATE_UNLOAD       0x00020000
+#define        BGE_APE_EVENT_STATUS_STATE_WOL          0x00030000
+#define        BGE_APE_EVENT_STATUS_STATE_SUSPEND      0x00040000
+#define        BGE_APE_EVENT_STATUS_EVENT_PENDING      0x80000000
+
+#define        BGE_APE_DEBUG_LOG               0x4E00
+#define        BGE_APE_DEBUG_LOG_LEN           0x0100
+
+#define        BGE_APE_PER_LOCK_REQ            0x8400
+#define        BGE_APE_PER_LOCK_GRANT          0x8420
+
+#define        BGE_APE_LOCK_PER_REQ_DRIVER0    0x00001000
+#define        BGE_APE_LOCK_PER_REQ_DRIVER1    0x00000002
+#define        BGE_APE_LOCK_PER_REQ_DRIVER2    0x00000004
+#define        BGE_APE_LOCK_PER_REQ_DRIVER3    0x00000008
+
+#define        BGE_APE_PER_LOCK_GRANT_DRIVER0  0x00001000
+#define        BGE_APE_PER_LOCK_GRANT_DRIVER1  0x00000002
+#define        BGE_APE_PER_LOCK_GRANT_DRIVER2  0x00000004
+#define        BGE_APE_PER_LOCK_GRANT_DRIVER3  0x00000008
+
+/* APE Mutex Resources */
+#define        BGE_APE_LOCK_PHY0               0
+#define        BGE_APE_LOCK_GRC                1
+#define        BGE_APE_LOCK_PHY1               2
+#define        BGE_APE_LOCK_PHY2               3
+#define        BGE_APE_LOCK_MEM                4
+#define        BGE_APE_LOCK_PHY3               5
+#define        BGE_APE_LOCK_GPIO               7
+
 /*
  * PCI-E Core Private Register Access to TL, DL & PL
  */
index 4cc0f68..eff3741 100644 (file)
@@ -67,8 +67,9 @@ struct bge_gib {
 #define BGE_INC(x, y)          (x) = ((x) + 1) % (y)
 
 /*
- * Register access macros. The Tigon always uses memory mapped register
- * accesses and all registers must be accessed with 32 bit operations.
+ * BAR0 MAC register access macros.  The Tigon always uses memory mapped
+ * register accesses and all registers must be accessed with 32 bit
+ * operations.
  */
 
 #define CSR_WRITE_4(sc, reg, val)      \
@@ -83,6 +84,18 @@ struct bge_gib {
 #define BGE_CLRBIT(sc, reg, x) \
        CSR_WRITE_4(sc, reg, (CSR_READ_4(sc, reg) & ~x))
 
+/* BAR2 APE register access macros. */
+#define        APE_WRITE_4(sc, reg, val)       \
+       bus_write_4(sc->bge_res2, reg, val)
+
+#define        APE_READ_4(sc, reg)             \
+       bus_read_4(sc->bge_res2, reg)
+
+#define        APE_SETBIT(sc, reg, x)  \
+       APE_WRITE_4(sc, reg, (APE_READ_4(sc, reg) | (x)))
+#define        APE_CLRBIT(sc, reg, x)  \
+       APE_WRITE_4(sc, reg, (APE_READ_4(sc, reg) & ~(x)))
+
 #define BGE_MEMWIN_READ(sc, x, val)                            \
 do {                                                           \
        pci_write_config(sc->bge_dev, BGE_PCI_MEMWIN_BASEADDR,  \
@@ -200,7 +213,8 @@ struct bge_softc {
        struct resource         *bge_irq;
        int                     bge_irq_type;
        int                     bge_irq_rid;
-       struct resource         *bge_res;
+       struct resource         *bge_res;       /* MAC mapped I/O */
+       struct resource         *bge_res2;      /* APE mapped I/O */
        struct ifmedia          bge_ifmedia;    /* TBI media info */
        int                     bge_pcixcap;
        int                     bge_pciecap;
@@ -229,6 +243,14 @@ struct bge_softc {
 #define BGE_FLAG_SHORTDMA      0x40000000
 #define BGE_FLAG_STATUS_TAG    0x80000000
 
+       uint32_t                bge_mfw_flags;  /* Management F/W flags */
+#define        BGE_MFW_ON_RXCPU        0x00000001
+#define        BGE_MFW_ON_APE          0x00000002
+#define        BGE_MFW_TYPE_NCSI       0x00000004
+#define        BGE_MFW_TYPE_DASH       0x00000008
+       int                     bge_phy_ape_lock;
+       int                     bge_func_addr;
+
        uint32_t                bge_chipid;
        uint8_t                 bge_asf_mode;
 #define ASF_ENABLE             0x01