Author: nwhitehorn
Date: Fri May  6 03:26:24 2011
New Revision: 221519
URL: http://svn.freebsd.org/changeset/base/221519

Log:
  Do not use Open Firmware to open the device and instead program its start
  on our own. This prevents hangs at boot when using a bm(4) NIC where the
  cable is not plugged in at boot time.
  
  Obtained from:        NetBSD
  MFC after:    1 week

Modified:
  head/sys/dev/bm/if_bm.c
  head/sys/powerpc/powermac/macio.c
  head/sys/powerpc/powermac/maciovar.h

Modified: head/sys/dev/bm/if_bm.c
==============================================================================
--- head/sys/dev/bm/if_bm.c     Fri May  6 02:45:02 2011        (r221518)
+++ head/sys/dev/bm/if_bm.c     Fri May  6 03:26:24 2011        (r221519)
@@ -558,6 +558,7 @@ bm_attach(device_t dev)
        }
 
        /* alloc interrupt */
+       bm_disable_interrupts(sc);
 
        sc->sc_txdmairqid = BM_TXDMA_INTERRUPT;
        sc->sc_txdmairq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
@@ -591,9 +592,6 @@ bm_attach(device_t dev)
        eaddr = sc->sc_enaddr;
        OF_getprop(node, "local-mac-address", eaddr, ETHER_ADDR_LEN);
 
-       /* reset the adapter  */
-       bm_chip_setup(sc);
-
        /*
         * Setup MII
         * On Apple BMAC controllers, we end up in a weird state of
@@ -608,6 +606,9 @@ bm_attach(device_t dev)
                return (error);
        }
 
+       /* reset the adapter  */
+       bm_chip_setup(sc);
+
        sc->sc_mii = device_get_softc(sc->sc_miibus);
 
        if_initname(ifp, device_get_name(sc->sc_dev),
@@ -1129,31 +1130,26 @@ bm_chip_setup(struct bm_softc *sc)
 {
        uint16_t reg;
        uint16_t *eaddr_sect;
-       char path[128];
-       ihandle_t bmac_ih;
+       struct mii_data *mii;
+       struct mii_softc *miisc;
 
        eaddr_sect = (uint16_t *)(sc->sc_enaddr);
+       dbdma_stop(sc->sc_txdma);
+       dbdma_stop(sc->sc_rxdma);
 
-       /* 
-        * Enable BMAC cell by opening and closing its OF node. This enables 
-        * the cell in macio as a side effect. We should probably directly 
-        * twiddle the FCR bits, but we lack a good interface for this at the
-        * present time. 
-        */
-
-       OF_package_to_path(ofw_bus_get_node(sc->sc_dev), path, sizeof(path));
-       bmac_ih = OF_open(path);
-       if (bmac_ih == -1) {
-               device_printf(sc->sc_dev,
-                   "Enabling BMAC cell failed! Hoping it's already active.\n");
-       } else {
-               OF_close(bmac_ih);
+       /* Reset MII */
+       mii = device_get_softc(sc->sc_miibus);
+       LIST_FOREACH(miisc, &mii->mii_phys, mii_list) {
+               PHY_RESET(miisc);
+               PHY_WRITE(miisc, MII_BMCR, PHY_READ(miisc, MII_BMCR) &
+                   ~BMCR_ISO);
        }
 
        /* Reset chip */
        CSR_WRITE_2(sc, BM_RX_RESET, 0x0000);
        CSR_WRITE_2(sc, BM_TX_RESET, 0x0001);
        do {
+               DELAY(10);
                reg = CSR_READ_2(sc, BM_TX_RESET);
        } while (reg & 0x0001);
 

Modified: head/sys/powerpc/powermac/macio.c
==============================================================================
--- head/sys/powerpc/powermac/macio.c   Fri May  6 02:45:02 2011        
(r221518)
+++ head/sys/powerpc/powermac/macio.c   Fri May  6 03:26:24 2011        
(r221519)
@@ -65,6 +65,10 @@ struct macio_softc {
        vm_offset_t  sc_base;
        vm_offset_t  sc_size;
        struct rman  sc_mem_rman;
+
+       /* FCR registers */
+       int          sc_memrid;
+       struct resource *sc_memr;
 };
 
 static MALLOC_DEFINE(M_MACIO, "macio", "macio device information");
@@ -296,6 +300,10 @@ macio_attach(device_t dev)
        sc->sc_base = reg[2];
        sc->sc_size = MACIO_REG_SIZE;
 
+       sc->sc_memrid = PCIR_BAR(0);
+       sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+           &sc->sc_memrid, RF_ACTIVE);
+
        sc->sc_mem_rman.rm_type = RMAN_ARRAY;
        sc->sc_mem_rman.rm_descr = "MacIO Device Memory";
        error = rman_init(&sc->sc_mem_rman);
@@ -347,6 +355,29 @@ macio_attach(device_t dev)
                        continue;
                }
                device_set_ivars(cdev, dinfo);
+
+               /* Set FCRs to enable some devices */
+               if (sc->sc_memr == NULL)
+                       continue;
+
+               if (strcmp(ofw_bus_get_name(cdev), "bmac") == 0 ||
+                   strcmp(ofw_bus_get_compat(cdev), "bmac+") == 0) {
+                       uint32_t fcr;
+
+                       fcr = bus_read_4(sc->sc_memr, HEATHROW_FCR);
+
+                       fcr |= FCR_ENET_ENABLE & ~FCR_ENET_RESET;
+                       bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr);
+                       DELAY(50000);
+                       fcr |= FCR_ENET_RESET;
+                       bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr);
+                       DELAY(50000);
+                       fcr &= ~FCR_ENET_RESET;
+                       bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr);
+                       DELAY(50000);
+                       
+                       bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr);
+               }
        }
 
        return (bus_generic_attach(dev));

Modified: head/sys/powerpc/powermac/maciovar.h
==============================================================================
--- head/sys/powerpc/powermac/maciovar.h        Fri May  6 02:45:02 2011        
(r221518)
+++ head/sys/powerpc/powermac/maciovar.h        Fri May  6 03:26:24 2011        
(r221519)
@@ -38,6 +38,16 @@
 #define MACIO_REG_SIZE  0x7ffff
 
 /*
+ * Feature Control Registers (FCR)
+ */
+#define HEATHROW_FCR   0x38
+#define KEYLARGO_FCR0  0x38
+#define KEYLARGO_FCR1  0x3c
+
+#define FCR_ENET_ENABLE        0x60000000
+#define FCR_ENET_RESET 0x80000000
+
+/*
  * Format of a macio reg property entry.
  */
 struct macio_reg {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to