[haiku-commits] haiku: hrev45142 - in src/add-ons/kernel/drivers/network: ipro1000/dev/e1000 wlan/ralinkwifi/dev/ral . rdc/dev/vte

  • From: korli@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 8 Jan 2013 22:46:30 +0100 (CET)

hrev45142 adds 3 changesets to branch 'master'
old head: 82ee340110ec97e4a19db79f37be96d79278f0ae
new head: 713f1b8c050805928cdae527526db5251f1365e4
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=713f1b8+%5E82ee340

----------------------------------------------------------------------------

648db73: Update FreeBSD network drivers with the 9.1 release

                                   [ Jérôme Duval <jerome.duval@xxxxxxxxx> ]

d997b26: ipro1000: Haiku changes to have it compiled again.
  
  * a lot of gcc2 specific changes...

                                   [ Jerome Duval <jerome.duval@xxxxxxxxx> ]

713f1b8: added rdc driver based on vte FreeBSD driver
  
  * built as is.
  * untested, some interrupt handler changes might be needed.

                                   [ Jérôme Duval <jerome.duval@xxxxxxxxx> ]

----------------------------------------------------------------------------

192 files changed, 19548 insertions(+), 6848 deletions(-)
.../kernel/drivers/network/3com/dev/mii/bmtphy.c |    5 +-
.../drivers/network/3com/dev/mii/bmtphyreg.h     |    2 +-
.../kernel/drivers/network/3com/dev/mii/ukphy.c  |    4 +-
.../drivers/network/3com/dev/mii/ukphy_subr.c    |    2 +-
.../kernel/drivers/network/3com/dev/xl/if_xl.c   |   22 +-
.../drivers/network/3com/dev/xl/if_xlreg.h       |    2 +-
.../kernel/drivers/network/3com/dev/xl/xlphy.c   |    2 +-
src/add-ons/kernel/drivers/network/Jamfile       |    1 +
.../drivers/network/ar81xx/dev/ale/if_ale.c      |  131 +-
.../drivers/network/ar81xx/dev/ale/if_alevar.h   |    1 -
.../drivers/network/ar81xx/dev/mii/ukphy.c       |   42 +-
.../drivers/network/ar81xx/dev/mii/ukphy_subr.c  |   26 +-
.../drivers/network/atheros813x/dev/alc/if_alc.c |    2 +-
.../drivers/network/atheros813x/dev/mii/ukphy.c  |    4 +-
.../network/atheros813x/dev/mii/ukphy_subr.c     |    2 +-
.../drivers/network/attansic_l1/dev/age/if_age.c |    4 +-
.../drivers/network/attansic_l1/dev/mii/atphy.c  |    2 +-
.../drivers/network/attansic_l2/dev/ae/if_ae.c   |   30 +-
.../drivers/network/attansic_l2/dev/mii/ukphy.c  |    4 +-
.../network/attansic_l2/dev/mii/ukphy_subr.c     |    2 +-
.../network/broadcom440x/dev/bfe/if_bfe.c        |    6 +-
.../network/broadcom440x/dev/mii/bmtphy.c        |    3 +-
.../network/broadcom570x/dev/bce/if_bcereg.h     |   41 +-
.../network/broadcom570x/dev/bge/if_bge.c        |  406 +-
.../network/broadcom570x/dev/bge/if_bgereg.h     |   83 +-
.../network/broadcom570x/dev/mii/brgphy.c        |   13 +-
.../drivers/network/broadcom570x/dev/mii/ukphy.c |    4 +-
.../network/broadcom570x/dev/mii/ukphy_subr.c    |    2 +-
.../drivers/network/dec21xxx/dev/dc/dcphy.c      |   13 +-
.../drivers/network/dec21xxx/dev/dc/if_dc.c      |  267 +-
.../drivers/network/dec21xxx/dev/dc/if_dcreg.h   |   37 +-
.../drivers/network/dec21xxx/dev/dc/pnphy.c      |    2 +-
.../drivers/network/dec21xxx/dev/de/dc21040reg.h |    2 +-
.../drivers/network/dec21xxx/dev/de/if_de.c      |   13 +-
.../drivers/network/dec21xxx/dev/de/if_devar.h   |    2 +-
.../drivers/network/dec21xxx/dev/mii/acphy.c     |    4 +-
.../drivers/network/dec21xxx/dev/mii/acphyreg.h  |    2 +-
.../drivers/network/dec21xxx/dev/mii/amphy.c     |    4 +-
.../drivers/network/dec21xxx/dev/mii/amphyreg.h  |    2 +-
.../drivers/network/dec21xxx/dev/mii/ukphy.c     |    4 +-
.../network/dec21xxx/dev/mii/ukphy_subr.c        |    2 +-
.../drivers/network/ipro100/dev/fxp/if_fxp.c     |  135 +-
.../drivers/network/ipro100/dev/fxp/if_fxpreg.h  |   20 +-
.../drivers/network/ipro100/dev/fxp/if_fxpvar.h  |    4 +-
.../drivers/network/ipro100/dev/fxp/inphy.c      |    2 +-
.../drivers/network/ipro100/dev/fxp/inphyreg.h   |    2 +-
.../drivers/network/ipro100/dev/fxp/rcvbundl.h   |    2 +-
.../drivers/network/ipro1000/dev/e1000/Jamfile   |    1 +
.../drivers/network/ipro1000/dev/e1000/LICENSE   |    2 +-
.../drivers/network/ipro1000/dev/e1000/README    |    3 +-
.../ipro1000/dev/e1000/e1000_80003es2lan.c       |  231 +-
.../ipro1000/dev/e1000/e1000_80003es2lan.h       |   69 +-
.../network/ipro1000/dev/e1000/e1000_82540.c     |  107 +-
.../network/ipro1000/dev/e1000/e1000_82541.c     |   14 +-
.../network/ipro1000/dev/e1000/e1000_82541.h     |    2 +-
.../network/ipro1000/dev/e1000/e1000_82542.c     |    2 +-
.../network/ipro1000/dev/e1000/e1000_82543.c     |   17 +-
.../network/ipro1000/dev/e1000/e1000_82543.h     |    2 +-
.../network/ipro1000/dev/e1000/e1000_82571.c     |  187 +-
.../network/ipro1000/dev/e1000/e1000_82571.h     |    2 +-
.../network/ipro1000/dev/e1000/e1000_82575.c     | 1336 +++++-
.../network/ipro1000/dev/e1000/e1000_82575.h     |  596 +--
.../network/ipro1000/dev/e1000/e1000_api.c       |   46 +-
.../network/ipro1000/dev/e1000/e1000_api.h       |  158 +-
.../network/ipro1000/dev/e1000/e1000_defines.h   | 2971 ++++++-------
.../network/ipro1000/dev/e1000/e1000_hw.h        |  391 +-
.../network/ipro1000/dev/e1000/e1000_i210.c      |  740 ++++
.../network/ipro1000/dev/e1000/e1000_i210.h      |   80 +
.../network/ipro1000/dev/e1000/e1000_ich8lan.c   |  894 ++--
.../network/ipro1000/dev/e1000/e1000_ich8lan.h   |  349 +-
.../network/ipro1000/dev/e1000/e1000_mac.c       |  706 ++-
.../network/ipro1000/dev/e1000/e1000_mac.h       |   14 +-
.../network/ipro1000/dev/e1000/e1000_manage.c    |  326 +-
.../network/ipro1000/dev/e1000/e1000_manage.h    |   62 +-
.../network/ipro1000/dev/e1000/e1000_mbx.c       |    2 +-
.../network/ipro1000/dev/e1000/e1000_mbx.h       |    2 +-
.../network/ipro1000/dev/e1000/e1000_nvm.c       |   33 +-
.../network/ipro1000/dev/e1000/e1000_nvm.h       |   18 +-
.../network/ipro1000/dev/e1000/e1000_osdep.c     |    2 +-
.../network/ipro1000/dev/e1000/e1000_osdep.h     |   14 +-
.../network/ipro1000/dev/e1000/e1000_phy.c       | 1816 +++++---
.../network/ipro1000/dev/e1000/e1000_phy.h       |  300 +-
.../network/ipro1000/dev/e1000/e1000_regs.h      | 1115 ++---
.../network/ipro1000/dev/e1000/e1000_vf.c        |   62 +-
.../network/ipro1000/dev/e1000/e1000_vf.h        |    2 +-
.../drivers/network/ipro1000/dev/e1000/if_em.c   |  764 ++--
.../drivers/network/ipro1000/dev/e1000/if_em.h   |   11 +-
.../drivers/network/ipro1000/dev/e1000/if_igb.c  |  761 +++-
.../drivers/network/ipro1000/dev/e1000/if_igb.h  |   14 +-
.../drivers/network/ipro1000/dev/e1000/if_lem.c  |  168 +-
.../drivers/network/ipro1000/dev/e1000/if_lem.h  |    8 +-
.../kernel/drivers/network/ipro1000/if_compat.h  |    6 -
.../drivers/network/jmicron2x0/dev/jme/if_jme.c  |    4 +-
.../network/jmicron2x0/dev/jme/if_jmereg.h       |    2 +-
.../network/jmicron2x0/dev/jme/if_jmevar.h       |    2 +-
.../drivers/network/jmicron2x0/dev/mii/jmphy.c   |    4 +-
.../network/jmicron2x0/dev/mii/jmphyreg.h        |    2 +-
.../network/marvell_yukon/dev/mii/e1000phy.c     |    2 +-
.../network/marvell_yukon/dev/mii/ukphy.c        |    4 +-
[ *** stats truncated: 93 lines dropped *** ]

############################################################################

Commit:      648db7333e8d0ae6e0386ba1e71eafb6a793c97d
URL:         http://cgit.haiku-os.org/haiku/commit/?id=648db73
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Thu Jan  3 12:52:09 2013 UTC
Committer:   Jerome Duval <jerome.duval@xxxxxxxxx>
Commit-Date: Tue Jan  8 21:45:30 2013 UTC

Update FreeBSD network drivers with the 9.1 release

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphy.c 
b/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphy.c
index ba4b509..81c2bd2 100644
--- a/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphy.c
+++ b/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphy.c
@@ -56,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/bmtphy.c,v 1.12.10.8.2.1 2010/12/21 
17:09:25 kensmith Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * Driver for the Broadcom BCM5201/BCM5202 "Mini-Theta" PHYs.  This also
@@ -91,8 +91,7 @@ static device_method_t bmtphy_methods[] = {
        DEVMETHOD(device_attach,        bmtphy_attach),
        DEVMETHOD(device_detach,        mii_phy_detach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static devclass_t      bmtphy_devclass;
diff --git a/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphyreg.h 
b/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphyreg.h
index 45ad8e7..6aa141d 100644
--- a/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphyreg.h
+++ b/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphyreg.h
@@ -28,7 +28,7 @@
  *
  *     from NetBSD: bmtphyreg.h,v 1.1 2001/06/02 21:42:10 thorpej Exp
  *
- * $FreeBSD: src/sys/dev/mii/bmtphyreg.h,v 1.2.22.2.2.1 2010/12/21 17:09:25 
kensmith Exp $
+ * $FreeBSD$
  */
 
 #ifndef _DEV_MII_BMTPHYREG_H_
diff --git a/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy.c 
b/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy.c
index 4ecfce2..9d52eb5 100644
--- a/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy.c
+++ b/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy.c
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 
17:09:25 kensmith Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * driver for generic unknown PHYs
@@ -86,7 +86,7 @@ static device_method_t ukphy_methods[] = {
        DEVMETHOD(device_attach,        ukphy_attach),
        DEVMETHOD(device_detach,        mii_phy_detach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static devclass_t ukphy_devclass;
diff --git a/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy_subr.c 
b/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy_subr.c
index 73007e1..5f2f634 100644
--- a/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy_subr.c
+++ b/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy_subr.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 
17:09:25 kensmith Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * Subroutines shared by the ukphy driver and other PHY drivers.
diff --git a/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xl.c 
b/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xl.c
index 77b4c43..989c5a7 100644
--- a/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xl.c
+++ b/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xl.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/xl/if_xl.c,v 1.8.2.7.2.1 2010/12/21 17:09:25 
kensmith Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * 3Com 3c90x Etherlink XL PCI NIC driver
@@ -310,17 +310,13 @@ static device_method_t xl_methods[] = {
        DEVMETHOD(device_suspend,       xl_suspend),
        DEVMETHOD(device_resume,        xl_resume),
 
-       /* bus interface */
-       DEVMETHOD(bus_print_child,      bus_generic_print_child),
-       DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
-
        /* MII interface */
        DEVMETHOD(miibus_readreg,       xl_miibus_readreg),
        DEVMETHOD(miibus_writereg,      xl_miibus_writereg),
        DEVMETHOD(miibus_statchg,       xl_miibus_statchg),
        DEVMETHOD(miibus_mediainit,     xl_miibus_mediainit),
 
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static driver_t xl_driver = {
@@ -331,8 +327,9 @@ static driver_t xl_driver = {
 
 static devclass_t xl_devclass;
 
-DRIVER_MODULE(xl, pci, xl_driver, xl_devclass, 0, 0);
-DRIVER_MODULE(miibus, xl, miibus_driver, miibus_devclass, 0, 0);
+DRIVER_MODULE_ORDERED(xl, pci, xl_driver, xl_devclass, NULL, NULL,
+    SI_ORDER_ANY);
+DRIVER_MODULE(miibus, xl, miibus_driver, miibus_devclass, NULL, NULL);
 
 static void
 xl_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
@@ -2185,12 +2182,9 @@ xl_intr(void *arg)
 #endif
                if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
                        break;
-               if (status & XL_STAT_UP_COMPLETE) {
-                       int     curpkts;
 
-                       curpkts = ifp->if_ipackets;
-                       xl_rxeof(sc);
-                       if (curpkts == ifp->if_ipackets) {
+               if (status & XL_STAT_UP_COMPLETE) {
+                       if (xl_rxeof(sc) == 0) {
                                while (xl_rx_resync(sc))
                                        xl_rxeof(sc);
                        }
@@ -2226,7 +2220,7 @@ xl_intr(void *arg)
        }
 
        if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
-               ifp->if_drv_flags & IFF_DRV_RUNNING) {
+           ifp->if_drv_flags & IFF_DRV_RUNNING) {
                if (sc->xl_type == XL_TYPE_905B)
                        xl_start_90xB_locked(ifp);
                else
diff --git a/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xlreg.h 
b/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xlreg.h
index cd1df20..17457be 100644
--- a/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xlreg.h
+++ b/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xlreg.h
@@ -29,7 +29,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/xl/if_xlreg.h,v 1.1.2.2.2.1 2010/12/21 17:09:25 
kensmith Exp $
+ * $FreeBSD$
  */
 
 #define XL_EE_READ     0x0080  /* read, 5 bit address */
diff --git a/src/add-ons/kernel/drivers/network/3com/dev/xl/xlphy.c 
b/src/add-ons/kernel/drivers/network/3com/dev/xl/xlphy.c
index e5ac9fc..2fe9e0d 100644
--- a/src/add-ons/kernel/drivers/network/3com/dev/xl/xlphy.c
+++ b/src/add-ons/kernel/drivers/network/3com/dev/xl/xlphy.c
@@ -86,7 +86,7 @@ static device_method_t xlphy_methods[] = {
        DEVMETHOD(device_attach,        xlphy_attach),
        DEVMETHOD(device_detach,        mii_phy_detach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static devclass_t xlphy_devclass;
diff --git a/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_ale.c 
b/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_ale.c
index 9c3dfd9..78c0b4e 100644
--- a/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_ale.c
+++ b/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_ale.c
@@ -91,11 +91,11 @@ TUNABLE_INT("hw.ale.msix_disable", &msix_disable);
 /*
  * Devices supported by this driver.
  */
-static struct ale_dev {
+static const struct ale_dev {
        uint16_t        ale_vendorid;
        uint16_t        ale_deviceid;
        const char      *ale_name;
-} ale_devs[] = {
+} const ale_devs[] = {
     { VENDORID_ATHEROS, DEVICEID_ATHEROS_AR81XX,
     "Atheros AR8121/AR8113/AR8114 PCIe Ethernet" },
 };
@@ -115,7 +115,6 @@ static void ale_init_tx_ring(struct ale_softc *);
 static void    ale_int_task(void *, int);
 static int     ale_intr(void *);
 static int     ale_ioctl(struct ifnet *, u_long, caddr_t);
-static void    ale_link_task(void *, int);
 static void    ale_mac_config(struct ale_softc *);
 static int     ale_miibus_readreg(device_t, int, int);
 static void    ale_miibus_statchg(device_t);
@@ -164,7 +163,7 @@ static device_method_t ale_methods[] = {
        DEVMETHOD(miibus_writereg,      ale_miibus_writereg),
        DEVMETHOD(miibus_statchg,       ale_miibus_statchg),
 
-       { NULL, NULL }
+       DEVMETHOD_END
 };
 
 static driver_t ale_driver = {
@@ -175,8 +174,8 @@ static driver_t ale_driver = {
 
 static devclass_t ale_devclass;
 
-DRIVER_MODULE(ale, pci, ale_driver, ale_devclass, 0, 0);
-DRIVER_MODULE(miibus, ale, miibus_driver, miibus_devclass, 0, 0);
+DRIVER_MODULE(ale, pci, ale_driver, ale_devclass, NULL, NULL);
+DRIVER_MODULE(miibus, ale, miibus_driver, miibus_devclass, NULL, NULL);
 
 static struct resource_spec ale_res_spec_mem[] = {
        { SYS_RES_MEMORY,       PCIR_BAR(0),    RF_ACTIVE },
@@ -253,10 +252,45 @@ static void
 ale_miibus_statchg(device_t dev)
 {
        struct ale_softc *sc;
+       struct mii_data *mii;
+       struct ifnet *ifp;
+       uint32_t reg;
 
        sc = device_get_softc(dev);
+       mii = device_get_softc(sc->ale_miibus);
+       ifp = sc->ale_ifp;
+       if (mii == NULL || ifp == NULL ||
+           (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+               return;
+
+       sc->ale_flags &= ~ALE_FLAG_LINK;
+       if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+           (IFM_ACTIVE | IFM_AVALID)) {
+               switch (IFM_SUBTYPE(mii->mii_media_active)) {
+               case IFM_10_T:
+               case IFM_100_TX:
+                       sc->ale_flags |= ALE_FLAG_LINK;
+                       break;
+               case IFM_1000_T:
+                       if ((sc->ale_flags & ALE_FLAG_FASTETHER) == 0)
+                               sc->ale_flags |= ALE_FLAG_LINK;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       /* Stop Rx/Tx MACs. */
+       ale_stop_mac(sc);
 
-       taskqueue_enqueue(taskqueue_swi, &sc->ale_link_task);
+       /* Program MACs with resolved speed/duplex/flow-control. */
+       if ((sc->ale_flags & ALE_FLAG_LINK) != 0) {
+               ale_mac_config(sc);
+               /* Reenable Tx/Rx MACs. */
+               reg = CSR_READ_4(sc, ALE_MAC_CFG);
+               reg |= MAC_CFG_TX_ENB | MAC_CFG_RX_ENB;
+               CSR_WRITE_4(sc, ALE_MAC_CFG, reg);
+       }
 }
 
 static void
@@ -267,12 +301,16 @@ ale_mediastatus(struct ifnet *ifp, struct ifmediareq 
*ifmr)
 
        sc = ifp->if_softc;
        ALE_LOCK(sc);
+       if ((ifp->if_flags & IFF_UP) == 0) {
+               ALE_UNLOCK(sc);
+               return;
+       }
        mii = device_get_softc(sc->ale_miibus);
 
        mii_pollstat(mii);
-       ALE_UNLOCK(sc);
        ifmr->ifm_status = mii->mii_media_status;
        ifmr->ifm_active = mii->mii_media_active;
+       ALE_UNLOCK(sc);
 }
 
 static int
@@ -297,7 +335,7 @@ ale_mediachange(struct ifnet *ifp)
 static int
 ale_probe(device_t dev)
 {
-       struct ale_dev *sp;
+       const struct ale_dev *sp;
        int i;
        uint16_t vendor, devid;
 
@@ -414,7 +452,7 @@ ale_attach(device_t dev)
        struct ale_softc *sc;
        struct ifnet *ifp;
        uint16_t burst;
-       int error, i, msic, msixc;
+       int error, i, msic, msixc, pmc;
        uint32_t rxf_len, txf_len;
 
        error = 0;
@@ -425,7 +463,6 @@ ale_attach(device_t dev)
            MTX_DEF);
        callout_init_mtx(&sc->ale_tick_ch, &sc->ale_mtx, 0);
        TASK_INIT(&sc->ale_int_task, 0, ale_int_task, sc);
-       TASK_INIT(&sc->ale_link_task, 0, ale_link_task, sc);
 
        /* Map the device. */
        pci_enable_busmaster(dev);
@@ -589,18 +626,16 @@ ale_attach(device_t dev)
        IFQ_SET_READY(&ifp->if_snd);
        ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_TSO4;
        ifp->if_hwassist = ALE_CSUM_FEATURES | CSUM_TSO;
-#ifdef ENABLE_WOL
        if (pci_find_cap(dev, PCIY_PMG, &pmc) == 0) {
                sc->ale_flags |= ALE_FLAG_PMCAP;
                ifp->if_capabilities |= IFCAP_WOL_MAGIC | IFCAP_WOL_MCAST;
        }
-#endif
        ifp->if_capenable = ifp->if_capabilities;
 
        /* Set up MII bus. */
        error = mii_attach(dev, &sc->ale_miibus, ifp, ale_mediachange,
            ale_mediastatus, BMSR_DEFCAPMASK, sc->ale_phyaddr, MII_OFFSET_ANY,
-           0);
+           MIIF_DOPAUSE);
        if (error != 0) {
                device_printf(dev, "attaching PHYs failed\n");
                goto fail;
@@ -681,7 +716,6 @@ ale_detach(device_t dev)
                ALE_UNLOCK(sc);
                callout_drain(&sc->ale_tick_ch);
                taskqueue_drain(sc->ale_tq, &sc->ale_int_task);
-               taskqueue_drain(taskqueue_swi, &sc->ale_link_task);
        }
 
        if (sc->ale_tq != NULL) {
@@ -1399,7 +1433,6 @@ ale_shutdown(device_t dev)
 static void
 ale_setlinkspeed(struct ale_softc *sc)
 {
-#ifdef ENABLE_WOL
        struct mii_data *mii;
        int aneg, i;
 
@@ -1458,13 +1491,11 @@ ale_setlinkspeed(struct ale_softc *sc)
        mii->mii_media_status = IFM_AVALID | IFM_ACTIVE;
        mii->mii_media_active = IFM_ETHER | IFM_100_TX | IFM_FDX;
        ale_mac_config(sc);
-#endif
 }
 
 static void
 ale_setwol(struct ale_softc *sc)
 {
-#ifdef ENABLE_WOL
        struct ifnet *ifp;
        uint32_t reg, pmcs;
        uint16_t pmstat;
@@ -1523,7 +1554,6 @@ ale_setwol(struct ale_softc *sc)
        if ((ifp->if_capenable & IFCAP_WOL) != 0)
                pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
        pci_write_config(sc->ale_dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
-#endif
 }
 
 static int
@@ -2017,14 +2047,12 @@ ale_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                                ifp->if_hwassist &= ~CSUM_TSO;
                }
 
-#ifdef ENABLE_WOL
                if ((mask & IFCAP_WOL_MCAST) != 0 &&
                    (ifp->if_capabilities & IFCAP_WOL_MCAST) != 0)
                        ifp->if_capenable ^= IFCAP_WOL_MCAST;
                if ((mask & IFCAP_WOL_MAGIC) != 0 &&
                    (ifp->if_capabilities & IFCAP_WOL_MAGIC) != 0)
                        ifp->if_capenable ^= IFCAP_WOL_MAGIC;
-#endif
                if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
                    (ifp->if_capabilities & IFCAP_VLAN_HWCSUM) != 0)
                        ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
@@ -2073,68 +2101,15 @@ ale_mac_config(struct ale_softc *sc)
        }
        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
                reg |= MAC_CFG_FULL_DUPLEX;
-#ifdef notyet
                if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
                        reg |= MAC_CFG_TX_FC;
                if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
                        reg |= MAC_CFG_RX_FC;
-#endif
        }
        CSR_WRITE_4(sc, ALE_MAC_CFG, reg);
 }
 
 static void
-ale_link_task(void *arg, int pending)
-{
-       struct ale_softc *sc;
-       struct mii_data *mii;
-       struct ifnet *ifp;
-       uint32_t reg;
-
-       sc = (struct ale_softc *)arg;
-
-       ALE_LOCK(sc);
-       mii = device_get_softc(sc->ale_miibus);
-       ifp = sc->ale_ifp;
-       if (mii == NULL || ifp == NULL ||
-           (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
-               ALE_UNLOCK(sc);
-               return;
-       }
-
-       sc->ale_flags &= ~ALE_FLAG_LINK;
-       if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
-           (IFM_ACTIVE | IFM_AVALID)) {
-               switch (IFM_SUBTYPE(mii->mii_media_active)) {
-               case IFM_10_T:
-               case IFM_100_TX:
-                       sc->ale_flags |= ALE_FLAG_LINK;
-                       break;
-               case IFM_1000_T:
-                       if ((sc->ale_flags & ALE_FLAG_FASTETHER) == 0)
-                               sc->ale_flags |= ALE_FLAG_LINK;
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       /* Stop Rx/Tx MACs. */
-       ale_stop_mac(sc);
-
-       /* Program MACs with resolved speed/duplex/flow-control. */
-       if ((sc->ale_flags & ALE_FLAG_LINK) != 0) {
-               ale_mac_config(sc);
-               /* Reenable Tx/Rx MACs. */
-               reg = CSR_READ_4(sc, ALE_MAC_CFG);
-               reg |= MAC_CFG_TX_ENB | MAC_CFG_RX_ENB;
-               CSR_WRITE_4(sc, ALE_MAC_CFG, reg);
-       }
-
-       ALE_UNLOCK(sc);
-}
-
-static void
 ale_stats_clear(struct ale_softc *sc)
 {
        struct smb sb;
@@ -2821,7 +2796,7 @@ ale_init_locked(struct ale_softc *sc)
                    ((rxf_lo << RX_FIFO_PAUSE_THRESH_LO_SHIFT) &
                    RX_FIFO_PAUSE_THRESH_LO_MASK) |
                    ((rxf_hi << RX_FIFO_PAUSE_THRESH_HI_SHIFT) &
-                    RX_FIFO_PAUSE_THRESH_HI_MASK));
+                   RX_FIFO_PAUSE_THRESH_HI_MASK));
        }
 
        /* Disable RSS. */
@@ -2884,14 +2859,14 @@ ale_init_locked(struct ale_softc *sc)
        CSR_WRITE_4(sc, ALE_INTR_STATUS, 0xFFFFFFFF);
        CSR_WRITE_4(sc, ALE_INTR_STATUS, 0);
 
+       ifp->if_drv_flags |= IFF_DRV_RUNNING;
+       ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
        sc->ale_flags &= ~ALE_FLAG_LINK;
        /* Switch to the current media. */
        mii_mediachg(mii);
 
        callout_reset(&sc->ale_tick_ch, hz, ale_tick, sc);
-
-       ifp->if_drv_flags |= IFF_DRV_RUNNING;
-       ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 }
 
 static void
diff --git a/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_alevar.h 
b/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_alevar.h
index dcf48d6..abf2d2e 100644
--- a/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_alevar.h
+++ b/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_alevar.h
@@ -221,7 +221,6 @@ struct ale_softc {
        int                     ale_pagesize;
 
        struct task             ale_int_task;
-       struct task             ale_link_task;
        struct taskqueue        *ale_tq;
        struct mtx              ale_mtx;
 };
diff --git a/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy.c 
b/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy.c
index fc1cf4d..9d52eb5 100644
--- a/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy.c
+++ b/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy.c
@@ -16,13 +16,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the NetBSD
- *     Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -48,11 +41,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by Manuel Bouyer.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -67,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20 2007/01/20 00:52:29 marius 
Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * driver for generic unknown PHYs
@@ -98,7 +86,7 @@ static device_method_t ukphy_methods[] = {
        DEVMETHOD(device_attach,        ukphy_attach),
        DEVMETHOD(device_detach,        mii_phy_detach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static devclass_t ukphy_devclass;
@@ -134,11 +122,9 @@ static int
 ukphy_attach(device_t dev)
 {
        struct mii_softc *sc;
-       struct mii_attach_args *ma;
-       struct mii_data *mii;
 
        sc = device_get_softc(dev);
-       
+
        mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &ukphy_funcs, 1);
        mii_phy_setmedia(sc);
 
@@ -148,30 +134,13 @@ ukphy_attach(device_t dev)
 static int
 ukphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
 {
-       struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
-       int reg;
 
        switch (cmd) {
        case MII_POLLSTAT:
-               /*
-                * If we're not polling our PHY instance, just return.
-                */
-               if (IFM_INST(ife->ifm_media) != sc->mii_inst)
-                       return (0);
                break;
 
        case MII_MEDIACHG:
                /*
-                * If the media indicates a different PHY instance,
-                * isolate ourselves.
-                */
-               if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
-                       reg = PHY_READ(sc, MII_BMCR);
-                       PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
-                       return (0);
-               }
-
-               /*
                 * If the interface is not up, don't do anything.
                 */
                if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
@@ -181,11 +150,6 @@ ukphy_service(struct mii_softc *sc, struct mii_data *mii, 
int cmd)
                break;
 
        case MII_TICK:
-               /*
-                * If we're not currently selected, just return.
-                */
-               if (IFM_INST(ife->ifm_media) != sc->mii_inst)
-                       return (0);
                if (mii_phy_tick(sc) == EJUSTRETURN)
                        return (0);
                break;
diff --git a/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy_subr.c 
b/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy_subr.c
index fb40b75..5f2f634 100644
--- a/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy_subr.c
+++ b/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy_subr.c
@@ -16,13 +16,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the NetBSD
- *     Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -38,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.8.8.1 2006/07/19 04:40:26 
yongari Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * Subroutines shared by the ukphy driver and other PHY drivers.
@@ -111,19 +104,26 @@ ukphy_status(struct mii_softc *phy)
                        mii->mii_media_active |= IFM_1000_T|IFM_FDX;
                else if ((gtcr & GTCR_ADV_1000THDX) &&
                    (gtsr & GTSR_LP_1000THDX))
-                       mii->mii_media_active |= IFM_1000_T;
-               else if (anlpar & ANLPAR_T4)
-                       mii->mii_media_active |= IFM_100_T4;
+                       mii->mii_media_active |= IFM_1000_T|IFM_HDX;
                else if (anlpar & ANLPAR_TX_FD)
                        mii->mii_media_active |= IFM_100_TX|IFM_FDX;
+               else if (anlpar & ANLPAR_T4)
+                       mii->mii_media_active |= IFM_100_T4|IFM_HDX;
                else if (anlpar & ANLPAR_TX)
-                       mii->mii_media_active |= IFM_100_TX;
+                       mii->mii_media_active |= IFM_100_TX|IFM_HDX;
                else if (anlpar & ANLPAR_10_FD)
                        mii->mii_media_active |= IFM_10_T|IFM_FDX;
                else if (anlpar & ANLPAR_10)
-                       mii->mii_media_active |= IFM_10_T;
+                       mii->mii_media_active |= IFM_10_T|IFM_HDX;
                else
                        mii->mii_media_active |= IFM_NONE;
+
+               if ((mii->mii_media_active & IFM_1000_T) != 0 &&
+                   (gtsr & GTSR_MS_RES) != 0)
+                       mii->mii_media_active |= IFM_ETH_MASTER;
+
+               if ((mii->mii_media_active & IFM_FDX) != 0)
+                       mii->mii_media_active |= mii_phy_flowstatus(phy);
        } else
                mii->mii_media_active = ife->ifm_media;
 }
diff --git a/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alc.c 
b/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alc.c
index c13cb18..c73075c 100644
--- a/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alc.c
+++ b/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alc.c
@@ -349,9 +349,9 @@ alc_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
        mii = device_get_softc(sc->alc_miibus);
 
        mii_pollstat(mii);
-       ALC_UNLOCK(sc);
        ifmr->ifm_status = mii->mii_media_status;
        ifmr->ifm_active = mii->mii_media_active;
+       ALC_UNLOCK(sc);
 }
 
 static int
diff --git a/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy.c 
b/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy.c
index 4ecfce2..9d52eb5 100644
--- a/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy.c
+++ b/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy.c
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 
17:09:25 kensmith Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * driver for generic unknown PHYs
@@ -86,7 +86,7 @@ static device_method_t ukphy_methods[] = {
        DEVMETHOD(device_attach,        ukphy_attach),
        DEVMETHOD(device_detach,        mii_phy_detach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static devclass_t ukphy_devclass;
diff --git 
a/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy_subr.c 
b/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy_subr.c
index 73007e1..5f2f634 100644
--- a/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy_subr.c
+++ b/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy_subr.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 
17:09:25 kensmith Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * Subroutines shared by the ukphy driver and other PHY drivers.
diff --git a/src/add-ons/kernel/drivers/network/attansic_l1/dev/age/if_age.c 
b/src/add-ons/kernel/drivers/network/attansic_l1/dev/age/if_age.c
index cecc339..f4287b0 100644
--- a/src/add-ons/kernel/drivers/network/attansic_l1/dev/age/if_age.c
+++ b/src/add-ons/kernel/drivers/network/attansic_l1/dev/age/if_age.c
@@ -282,9 +282,9 @@ age_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
        mii = device_get_softc(sc->age_miibus);
 
        mii_pollstat(mii);
-       AGE_UNLOCK(sc);
        ifmr->ifm_status = mii->mii_media_status;
        ifmr->ifm_active = mii->mii_media_active;
+       AGE_UNLOCK(sc);
 }
 
 /*
@@ -1405,7 +1405,7 @@ age_setwol(struct age_softc *sc)
                                AGE_UNLOCK(sc);
 #ifdef __HAIKU__
                                DELAY(1);
-#else                          
+#else
                                pause("agelnk", hz);
 #endif
                                AGE_LOCK(sc);
diff --git a/src/add-ons/kernel/drivers/network/attansic_l1/dev/mii/atphy.c 
b/src/add-ons/kernel/drivers/network/attansic_l1/dev/mii/atphy.c
index b5cf14f..cca8813 100644
--- a/src/add-ons/kernel/drivers/network/attansic_l1/dev/mii/atphy.c
+++ b/src/add-ons/kernel/drivers/network/attansic_l1/dev/mii/atphy.c
@@ -59,7 +59,7 @@ static device_method_t atphy_methods[] = {
        DEVMETHOD(device_attach,        atphy_attach),
        DEVMETHOD(device_detach,        mii_phy_detach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-       { NULL, NULL }
+       DEVMETHOD_END
 };
 
 static devclass_t atphy_devclass;
diff --git a/src/add-ons/kernel/drivers/network/attansic_l2/dev/ae/if_ae.c 
b/src/add-ons/kernel/drivers/network/attansic_l2/dev/ae/if_ae.c
index 3ab598a..02a1e79 100644
--- a/src/add-ons/kernel/drivers/network/attansic_l2/dev/ae/if_ae.c
+++ b/src/add-ons/kernel/drivers/network/attansic_l2/dev/ae/if_ae.c
@@ -1385,12 +1385,13 @@ ae_pm_init(ae_softc_t *sc)
        /*
         * Configure PME.
         */
-       pci_find_cap(sc->dev, PCIY_PMG, &pmc);
-       pmstat = pci_read_config(sc->dev, pmc + PCIR_POWER_STATUS, 2);
-       pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
-       if ((ifp->if_capenable & IFCAP_WOL) != 0)
-               pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
-       pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
+       if (pci_find_cap(sc->dev, PCIY_PMG, &pmc) == 0) {
+               pmstat = pci_read_config(sc->dev, pmc + PCIR_POWER_STATUS, 2);
+               pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
+               if ((ifp->if_capenable & IFCAP_WOL) != 0)
+                       pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
+               pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
+       }
 }
 
 static int
@@ -1435,7 +1436,7 @@ ae_tx_avail_size(ae_softc_t *sc)
        else
                avail = sc->txd_ack - sc->txd_cur;
 
-       return (avail - 4);     /* 4-byte header. */
+       return (avail);
 }
 
 static int
@@ -1452,7 +1453,7 @@ ae_encap(ae_softc_t *sc, struct mbuf **m_head)
        len = m0->m_pkthdr.len;
        
        if ((sc->flags & AE_FLAG_TXAVAIL) == 0 ||
-           ae_tx_avail_size(sc) < len) {
+           len + sizeof(ae_txd_t) + 3 > ae_tx_avail_size(sc)) {
 #ifdef AE_DEBUG
                if_printf(sc->ifp, "No free Tx available.\n");
 #endif
@@ -1461,11 +1462,10 @@ ae_encap(ae_softc_t *sc, struct mbuf **m_head)
 
        hdr = (ae_txd_t *)(sc->txd_base + sc->txd_cur);
        bzero(hdr, sizeof(*hdr));
-       sc->txd_cur = (sc->txd_cur + 4) % AE_TXD_BUFSIZE_DEFAULT; /* Header
-                                                                    size. */
-       to_end = AE_TXD_BUFSIZE_DEFAULT - sc->txd_cur; /* Space available to
-                                                       * the end of the ring
-                                                       */
+       /* Skip header size. */
+       sc->txd_cur = (sc->txd_cur + sizeof(ae_txd_t)) % AE_TXD_BUFSIZE_DEFAULT;
+       /* Space available to the end of the ring */
+       to_end = AE_TXD_BUFSIZE_DEFAULT - sc->txd_cur;
        if (to_end >= len) {
                m_copydata(m0, 0, len, (caddr_t)(sc->txd_base + sc->txd_cur));
        } else {
@@ -1844,8 +1844,8 @@ ae_tx_intr(ae_softc_t *sc)
                /*
                 * Move txd ack and align on 4-byte boundary.
                 */
-               sc->txd_ack = ((sc->txd_ack + le16toh(txd->len) + 4 + 3) & ~3) %
-                   AE_TXD_BUFSIZE_DEFAULT;
+               sc->txd_ack = ((sc->txd_ack + le16toh(txd->len) +
+                   sizeof(ae_txs_t) + 3) & ~3) % AE_TXD_BUFSIZE_DEFAULT;
 
                if ((flags & AE_TXS_SUCCESS) != 0)
                        ifp->if_opackets++;
diff --git a/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy.c 
b/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy.c
index 4ecfce2..9d52eb5 100644
--- a/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy.c
+++ b/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy.c
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 
17:09:25 kensmith Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * driver for generic unknown PHYs
@@ -86,7 +86,7 @@ static device_method_t ukphy_methods[] = {
        DEVMETHOD(device_attach,        ukphy_attach),
        DEVMETHOD(device_detach,        mii_phy_detach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static devclass_t ukphy_devclass;
diff --git 
a/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy_subr.c 
b/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy_subr.c
index 73007e1..5f2f634 100644
--- a/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy_subr.c
+++ b/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy_subr.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 
17:09:25 kensmith Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * Subroutines shared by the ukphy driver and other PHY drivers.
diff --git a/src/add-ons/kernel/drivers/network/broadcom440x/dev/bfe/if_bfe.c 
b/src/add-ons/kernel/drivers/network/broadcom440x/dev/bfe/if_bfe.c
index 7f970f4..6dd33cd 100644
--- a/src/add-ons/kernel/drivers/network/broadcom440x/dev/bfe/if_bfe.c
+++ b/src/add-ons/kernel/drivers/network/broadcom440x/dev/bfe/if_bfe.c
@@ -137,16 +137,12 @@ static device_method_t bfe_methods[] = {
        DEVMETHOD(device_suspend,       bfe_suspend),
        DEVMETHOD(device_resume,        bfe_resume),
 
-       /* bus interface */
-       DEVMETHOD(bus_print_child,      bus_generic_print_child),
-       DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
-
        /* MII interface */
        DEVMETHOD(miibus_readreg,       bfe_miibus_readreg),
        DEVMETHOD(miibus_writereg,      bfe_miibus_writereg),
        DEVMETHOD(miibus_statchg,       bfe_miibus_statchg),
 
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static driver_t bfe_driver = {
diff --git a/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/bmtphy.c 
b/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/bmtphy.c
index 3f91a61..9af56e9 100644
--- a/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/bmtphy.c
+++ b/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/bmtphy.c
@@ -91,8 +91,7 @@ static device_method_t bmtphy_methods[] = {
        DEVMETHOD(device_attach,        bmtphy_attach),
        DEVMETHOD(device_detach,        mii_phy_detach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static devclass_t      bmtphy_devclass;
diff --git 
a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bce/if_bcereg.h 
b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bce/if_bcereg.h
index f4215db..be20608 100644
--- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bce/if_bcereg.h
+++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bce/if_bcereg.h
@@ -576,7 +576,6 @@ default: DBPRINT(sc, BCE_INSANE_PHY,                        
                \
 #define BCE_CHIP_NUM_5706              0x57060000
 #define BCE_CHIP_NUM_5708              0x57080000
 #define BCE_CHIP_NUM_5709              0x57090000
-#define BCE_CHIP_NUM_5716              0x57160000
 
 #define BCE_CHIP_REV(sc)               (((sc)->bce_chipid) & 0x0000f000)
 #define BCE_CHIP_REV_Ax                        0x00000000
@@ -601,7 +600,6 @@ default: DBPRINT(sc, BCE_INSANE_PHY,                        
                \
 #define BCE_CHIP_ID_5709_B1            0x57091010
 #define BCE_CHIP_ID_5709_B2            0x57091020
 #define BCE_CHIP_ID_5709_C0            0x57092000
-#define BCE_CHIP_ID_5716_C0            0x57162000
 
 #define BCE_CHIP_BOND_ID(sc)           (((sc)->bce_chipid) & 0xf)
 
@@ -816,6 +814,23 @@ struct flash_spec {
 #define BCE_DRV_PULSE_SEQ_MASK                  0x00007fff
 
 #define BCE_MB_ARGS_0                          0x00000014
+#define        BCE_NETLINK_SPEED_10HALF                 (1<<0)
+#define        BCE_NETLINK_SPEED_10FULL                 (1<<1)
+#define        BCE_NETLINK_SPEED_100HALF                (1<<2)
+#define        BCE_NETLINK_SPEED_100FULL                (1<<3)
+#define        BCE_NETLINK_SPEED_1000HALF               (1<<4)
+#define        BCE_NETLINK_SPEED_1000FULL               (1<<5)
+#define        BCE_NETLINK_SPEED_2500HALF               (1<<6)
+#define        BCE_NETLINK_SPEED_2500FULL               (1<<7)
+#define        BCE_NETLINK_SPEED_10GHALF                (1<<8)
+#define        BCE_NETLINK_SPEED_10GFULL                (1<<9)
+#define        BCE_NETLINK_ANEG_ENB                     (1<<10)
+#define        BCE_NETLINK_PHY_APP_REMOTE               (1<<11)
+#define        BCE_NETLINK_FC_PAUSE_SYM                 (1<<12)
+#define        BCE_NETLINK_FC_PAUSE_ASYM                (1<<13)
+#define        BCE_NETLINK_ETH_AT_WIRESPEED             (1<<14)
+#define        BCE_NETLINK_PHY_RESET                    (1<<15)
+
 #define BCE_MB_ARGS_1                          0x00000018
 
 /* Indicate to the firmware not to go into the
@@ -1081,6 +1096,26 @@ struct flash_spec {
 #define BCE_BC_STATE_BC_DBG_CMD_LOOP_CNT_MASK  0xffff
 #define BCE_BC_STATE_BC_DBG_CMD_LOOP_INFINITE  0xffff
 
+#define        BCE_FW_EVT_CODE_MB                      0x00000354
+#define        BCE_FW_EVT_CODE_SW_TIMER_EXPIRE_EVENT   0x00000000
+#define        BCE_FW_EVT_CODE_LINK_EVENT              0x00000001
+
+#define        BCE_DRV_ACK_CAP_MB                      0x00000364
+#define        BCE_DRV_ACK_CAP_SIGNATURE_MAGIC         0x35450000
+
+#define        BCE_FW_CAP_MB                           0x00000368
+#define        BCE_FW_CAP_SIGNATURE_MAGIC              0xaa550000
+#define        BCE_FW_ACK_SIGNATURE_MAGIC              0x52500000
+#define        BCE_FW_CAP_SIGNATURE_MAGIC_MASK         0xffff0000
+#define        BCE_FW_CAP_REMOTE_PHY_CAP               0x00000001
+#define        BCE_FW_CAP_REMOTE_PHY_PRESENT           0x00000002
+#define        BCE_FW_CAP_MFW_KEEP_VLAN                0x00000008
+#define        BCE_FW_CAP_BC_KEEP_VLAN                 0x00000010
+
+#define        BCE_RPHY_SERDES_LINK                    0x00000374
+
+#define        BCE_RPHY_COPPER_LINK                    0x00000378
+
 #define HOST_VIEW_SHMEM_BASE                   0x167c00
 
 /*
@@ -6456,6 +6491,8 @@ struct bce_softc
 #define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG     0x00000100
 #define BCE_PHY_INT_MODE_LINK_READY_FLAG       0x00000200
 #define BCE_PHY_IEEE_CLAUSE_45_FLAG            0x00000400
+#define        BCE_PHY_REMOTE_CAP_FLAG                 0x00000800
+#define        BCE_PHY_REMOTE_PORT_FIBER_FLAG          0x00001000
 
        /* Values that need to be shared with the PHY driver. */
        u32                     bce_shared_hw_cfg;
diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c 
b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c
index d456774..d635000 100644
--- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c
+++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c
@@ -301,6 +301,7 @@ static const struct bge_revision {
        { BGE_CHIPID_BCM5717_A0,        "BCM5717 A0" },
        { BGE_CHIPID_BCM5717_B0,        "BCM5717 B0" },
        { BGE_CHIPID_BCM5719_A0,        "BCM5719 A0" },
+       { BGE_CHIPID_BCM5720_A0,        "BCM5720 A0" },
        { BGE_CHIPID_BCM5755_A0,        "BCM5755 A0" },
        { BGE_CHIPID_BCM5755_A1,        "BCM5755 A1" },
        { BGE_CHIPID_BCM5755_A2,        "BCM5755 A2" },
@@ -349,6 +350,7 @@ static const struct bge_revision const bge_majorrevs[] = {
        { BGE_ASICREV_BCM57780,         "unknown BCM57780" },
        { BGE_ASICREV_BCM5717,          "unknown BCM5717" },
        { BGE_ASICREV_BCM5719,          "unknown BCM5719" },
+       { BGE_ASICREV_BCM5720,          "unknown BCM5720" },
 
        { 0, NULL }
 };
@@ -378,6 +380,9 @@ static void bge_dma_free(struct bge_softc *);
 static int bge_dma_ring_alloc(struct bge_softc *, bus_size_t, bus_size_t,
     bus_dma_tag_t *, uint8_t **, bus_dmamap_t *, bus_addr_t *, const char *);
 
+static void bge_devinfo(struct bge_softc *);
+static int bge_mbox_reorder(struct bge_softc *);
+
 static int bge_get_eaddr_fw(struct bge_softc *sc, uint8_t ether_addr[]);
 static int bge_get_eaddr_mem(struct bge_softc *, uint8_t[]);
 static int bge_get_eaddr_nvram(struct bge_softc *, uint8_t[]);
@@ -437,6 +442,7 @@ static int bge_init_tx_ring(struct bge_softc *);
 
 static int bge_chipinit(struct bge_softc *);
 static int bge_blockinit(struct bge_softc *);
+static uint32_t bge_dma_swap_options(struct bge_softc *);
 
 static int bge_has_eaddr(struct bge_softc *);
 static uint32_t bge_readmem_ind(struct bge_softc *, int);
@@ -492,16 +498,12 @@ static device_method_t bge_methods[] = {
        DEVMETHOD(device_suspend,       bge_suspend),
        DEVMETHOD(device_resume,        bge_resume),
 
-       /* bus interface */
-       DEVMETHOD(bus_print_child,      bus_generic_print_child),
-       DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
-
        /* MII interface */
        DEVMETHOD(miibus_readreg,       bge_miibus_readreg),
        DEVMETHOD(miibus_writereg,      bge_miibus_writereg),
        DEVMETHOD(miibus_statchg,       bge_miibus_statchg),
 
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static driver_t bge_driver = {
@@ -642,6 +644,8 @@ bge_writembx(struct bge_softc *sc, int off, int val)
                off += BGE_LPMBX_IRQ0_HI - BGE_MBX_IRQ0_HI;
 
        CSR_WRITE_4(sc, off, val);
+       if ((sc->bge_flags & BGE_FLAG_MBOX_REORDER) != 0)
+               CSR_READ_4(sc, off);
 }
 
 /*
@@ -1315,15 +1319,17 @@ bge_sig_pre_reset(struct bge_softc *sc, int type)
         * Some chips don't like this so only do this if ASF is enabled
         */
        if (sc->bge_asf_mode)
-               bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
+               bge_writemem_ind(sc, BGE_SRAM_FW_MB, BGE_SRAM_FW_MB_MAGIC);
 
        if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
                switch (type) {
                case BGE_RESET_START:
-                       bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */
+                       bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
+                           BGE_FW_DRV_STATE_START);
                        break;
                case BGE_RESET_STOP:
-                       bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */
+                       bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
+                           BGE_FW_DRV_STATE_UNLOAD);
                        break;
                }
        }
@@ -1336,11 +1342,13 @@ bge_sig_post_reset(struct bge_softc *sc, int type)
        if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
                switch (type) {
                case BGE_RESET_START:
-                       bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000001);
+                       bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
+                           BGE_FW_DRV_STATE_START_DONE);
                        /* START DONE */
                        break;
                case BGE_RESET_STOP:
-                       bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000002);
+                       bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
+                           BGE_FW_DRV_STATE_UNLOAD_DONE);
                        break;
                }
        }
@@ -1353,10 +1361,12 @@ bge_sig_legacy(struct bge_softc *sc, int type)
        if (sc->bge_asf_mode) {
                switch (type) {
                case BGE_RESET_START:
-                       bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */
+                       bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
+                           BGE_FW_DRV_STATE_START);
                        break;
                case BGE_RESET_STOP:
-                       bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */
+                       bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
+                           BGE_FW_DRV_STATE_UNLOAD);
                        break;
                }
        }
@@ -1368,25 +1378,44 @@ bge_stop_fw(struct bge_softc *sc)
        int i;
 
        if (sc->bge_asf_mode) {
-               bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, BGE_FW_PAUSE);
-               CSR_WRITE_4(sc, BGE_CPU_EVENT,
-                   CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));
+               bge_writemem_ind(sc, BGE_SRAM_FW_CMD_MB, BGE_FW_CMD_PAUSE);
+               CSR_WRITE_4(sc, BGE_RX_CPU_EVENT,
+                   CSR_READ_4(sc, BGE_RX_CPU_EVENT) | BGE_RX_CPU_DRV_EVENT);
 
                for (i = 0; i < 100; i++ ) {
-                       if (!(CSR_READ_4(sc, BGE_CPU_EVENT) & (1 << 14)))
+                       if (!(CSR_READ_4(sc, BGE_RX_CPU_EVENT) &
+                           BGE_RX_CPU_DRV_EVENT))
                                break;
                        DELAY(10);
                }
        }
 }
 
+static uint32_t
+bge_dma_swap_options(struct bge_softc *sc)
+{
+       uint32_t dma_options;
+
+       dma_options = BGE_MODECTL_WORDSWAP_NONFRAME |
+           BGE_MODECTL_BYTESWAP_DATA | BGE_MODECTL_WORDSWAP_DATA;
+#if BYTE_ORDER == BIG_ENDIAN
+       dma_options |= BGE_MODECTL_BYTESWAP_NONFRAME;
+#endif
+       if ((sc)->bge_asicrev == BGE_ASICREV_BCM5720)
+               dma_options |= BGE_MODECTL_BYTESWAP_B2HRX_DATA |
+                   BGE_MODECTL_WORDSWAP_B2HRX_DATA | BGE_MODECTL_B2HRX_ENABLE |
+                   BGE_MODECTL_HTX2B_ENABLE;
+
+       return (dma_options);
+}
+
 /*
  * Do endian, PCI and DMA initialization.
  */
 static int
 bge_chipinit(struct bge_softc *sc)
 {
-       uint32_t dma_rw_ctl, misc_ctl;
+       uint32_t dma_rw_ctl, misc_ctl, mode_ctl;
        uint16_t val;
        int i;
 
@@ -1504,9 +1533,8 @@ bge_chipinit(struct bge_softc *sc)
        /*
         * Set up general mode register.
         */
-       CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS |
-           BGE_MODECTL_MAC_ATTN_INTR | BGE_MODECTL_HOST_SEND_BDS |
-           BGE_MODECTL_TX_NO_PHDR_CSUM);
+       mode_ctl = bge_dma_swap_options(sc) | BGE_MODECTL_MAC_ATTN_INTR |
+           BGE_MODECTL_HOST_SEND_BDS | BGE_MODECTL_TX_NO_PHDR_CSUM;
 
        /*
         * BCM5701 B5 have a bug causing data corruption when using
@@ -1516,13 +1544,15 @@ bge_chipinit(struct bge_softc *sc)
         */
        if (sc->bge_asicrev == BGE_ASICREV_BCM5701 &&
            sc->bge_chipid == BGE_CHIPID_BCM5701_B5)
-               BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_FORCE_PCI32);
+               mode_ctl |= BGE_MODECTL_FORCE_PCI32;
 
        /*
         * Tell the firmware the driver is running
         */
        if (sc->bge_asf_mode & ASF_STACKUP)
-               BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+               mode_ctl |= BGE_MODECTL_STACKUP;
+
+       CSR_WRITE_4(sc, BGE_MODE_CTL, mode_ctl);
 
        /*
         * Disable memory write invalidate.  Apparently it is not supported
@@ -1582,8 +1612,7 @@ bge_blockinit(struct bge_softc *sc)
        }
 
        /* Configure mbuf pool watermarks */
-       if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-           sc->bge_asicrev == BGE_ASICREV_BCM57765) {
+       if (BGE_IS_5717_PLUS(sc)) {
                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
                if (sc->bge_ifp->if_mtu > ETHERMTU) {
                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x7e);
@@ -1718,7 +1747,8 @@ bge_blockinit(struct bge_softc *sc)
                    BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);
        }
        if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-           sc->bge_asicrev == BGE_ASICREV_BCM5719)
+           sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5720)
                rcb->bge_nicaddr = BGE_STD_RX_RINGS_5717;
        else
                rcb->bge_nicaddr = BGE_STD_RX_RINGS;
@@ -1751,7 +1781,8 @@ bge_blockinit(struct bge_softc *sc)
                rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,
                    BGE_RCB_FLAG_USE_EXT_RX_BD | BGE_RCB_FLAG_RING_DISABLED);
                if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-                   sc->bge_asicrev == BGE_ASICREV_BCM5719)
+                   sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+                   sc->bge_asicrev == BGE_ASICREV_BCM5720)
                        rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS_5717;
                else
                        rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
@@ -1840,7 +1871,8 @@ bge_blockinit(struct bge_softc *sc)
        RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
        RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
        if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-           sc->bge_asicrev == BGE_ASICREV_BCM5719)
+           sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5720)
                RCB_WRITE_4(sc, vrcb, bge_nicaddr, BGE_SEND_RING_5717);
        else
                RCB_WRITE_4(sc, vrcb, bge_nicaddr,
@@ -1854,7 +1886,8 @@ bge_blockinit(struct bge_softc *sc)
         * return ring control blocks, located in NIC memory.
         */
        if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-           sc->bge_asicrev == BGE_ASICREV_BCM5719) {
+           sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5720) {
                /* Should be 17, use 16 until we get an SRAM map. */
                limit = 16;
        } else if (!BGE_IS_5705_PLUS(sc))
@@ -1898,7 +1931,11 @@ bge_blockinit(struct bge_softc *sc)
            BGE_TX_BACKOFF_SEED_MASK);
 
        /* Set inter-packet gap */
-       CSR_WRITE_4(sc, BGE_TX_LENGTHS, 0x2620);
+       val = 0x2620;
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5720)
+               val |= CSR_READ_4(sc, BGE_TX_LENGTHS) &
+                   (BGE_TXLEN_JMB_FRM_LEN_MSK | BGE_TXLEN_CNT_DN_VAL_MSK);
+       CSR_WRITE_4(sc, BGE_TX_LENGTHS, val);
 
        /*
         * Specify which ring to use for packets that don't match
@@ -2053,6 +2090,17 @@ bge_blockinit(struct bge_softc *sc)
                    sc->bge_asicrev == BGE_ASICREV_BCM57780)
                        val |= BGE_RDMAMODE_TSO6_ENABLE;
        }
+
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
+               val |= CSR_READ_4(sc, BGE_RDMA_MODE) &
+                       BGE_RDMAMODE_H2BNC_VLAN_DET;
+               /*
+                * Allow multiple outstanding read requests from
+                * non-LSO read DMA engine.
+                */
+               val &= ~BGE_RDMAMODE_MULT_DMA_RD_DIS;
+       }
+
        if (sc->bge_asicrev == BGE_ASICREV_BCM5761 ||
            sc->bge_asicrev == BGE_ASICREV_BCM5784 ||
            sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
@@ -2063,7 +2111,8 @@ bge_blockinit(struct bge_softc *sc)
                 * Adjust tx margin to prevent TX data corruption and
                 * fix internal FIFO overflow.
                 */
-               if (sc->bge_asicrev == BGE_ASICREV_BCM5719) {
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+                   sc->bge_asicrev == BGE_ASICREV_BCM5720) {
                        dmactl &= ~(BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK |
                            BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK |
                            BGE_RDMA_RSRVCTRL_TXMRGN_MASK);
@@ -2085,6 +2134,15 @@ bge_blockinit(struct bge_softc *sc)
                    CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) |
                    BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K |
                    BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
+       } else if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
+               /*
+                * Allow 4KB burst length reads for non-LSO frames.
+                * Enable 512B burst length reads for buffer descriptors.
+                */
+               CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL,
+                   CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) |
+                   BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512 |
+                   BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
        }
 
        CSR_WRITE_4(sc, BGE_RDMA_MODE, val);
@@ -2239,6 +2297,7 @@ bge_probe(device_t dev)
                                case BCOM_DEVICEID_BCM5717:
                                case BCOM_DEVICEID_BCM5718:
                                case BCOM_DEVICEID_BCM5719:
+                               case BCOM_DEVICEID_BCM5720:
                                        id = pci_read_config(dev,
                                            BGE_PCI_GEN2_PRODID_ASICREV, 4);
                                        break;
@@ -2310,10 +2369,11 @@ bge_dma_free(struct bge_softc *sc)
 
        if (sc->bge_cdata.bge_rx_mtag)
                bus_dma_tag_destroy(sc->bge_cdata.bge_rx_mtag);
+       if (sc->bge_cdata.bge_mtag_jumbo)
+               bus_dma_tag_destroy(sc->bge_cdata.bge_mtag_jumbo);
        if (sc->bge_cdata.bge_tx_mtag)
                bus_dma_tag_destroy(sc->bge_cdata.bge_tx_mtag);
 
-
        /* Destroy standard RX ring. */
        if (sc->bge_cdata.bge_rx_std_ring_map)
                bus_dmamap_unload(sc->bge_cdata.bge_rx_std_ring_tag,
@@ -2559,10 +2619,10 @@ bge_dma_alloc(struct bge_softc *sc)
                 * XXX
                 * watchdog timeout issue was observed on BCM5704 which
                 * lives behind PCI-X bridge(e.g AMD 8131 PCI-X bridge).
-                * Limiting DMA address space to 32bits seems to address
-                * it.
+                * Both limiting DMA address space to 32bits and flushing
+                * mailbox write seem to address the issue.
                 */
-               if (sc->bge_flags & BGE_FLAG_PCIX)
+               if (sc->bge_pcixcap != 0)
                        lowaddr = BUS_SPACE_MAXADDR_32BIT;
        }
        error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev),
@@ -2701,6 +2761,9 @@ bge_can_use_msi(struct bge_softc *sc)
        return 0;
 #endif
 
+       if (sc->bge_msi == 0)
+               return (0);
+
        /* Disable MSI for polling(4). */
 #ifdef DEVICE_POLLING
        return (0);
@@ -2728,6 +2791,102 @@ bge_can_use_msi(struct bge_softc *sc)
 }
 
 static int
+bge_mbox_reorder(struct bge_softc *sc)
+{
+#ifndef __HAIKU__
+       /* Lists of PCI bridges that are known to reorder mailbox writes. */
+       static const struct mbox_reorder {
+               const uint16_t vendor;
+               const uint16_t device;
+               const char *desc;
+       } const mbox_reorder_lists[] = {
+               { 0x1022, 0x7450, "AMD-8131 PCI-X Bridge" },
+       };
+       devclass_t pci, pcib;
+       device_t bus, dev;
+       int i;
+
+       pci = devclass_find("pci");
+       pcib = devclass_find("pcib");
+       dev = sc->bge_dev;
+       bus = device_get_parent(dev);
+       for (;;) {
+               dev = device_get_parent(bus);
+               bus = device_get_parent(dev);
+               if (device_get_devclass(dev) != pcib)
+                       break;
+               for (i = 0; i < nitems(mbox_reorder_lists); i++) {
+                       if (pci_get_vendor(dev) ==
+                           mbox_reorder_lists[i].vendor &&
+                           pci_get_device(dev) ==
+                           mbox_reorder_lists[i].device) {
+                               device_printf(sc->bge_dev,
+                                   "enabling MBOX workaround for %s\n",
+                                   mbox_reorder_lists[i].desc);
+                               return (1);
+                       }
+               }
+               if (device_get_devclass(bus) != pci)
+                       break;
+       }
+#endif
+       return (0);
+}
+
+static void
+bge_devinfo(struct bge_softc *sc)
+{
+       uint32_t cfg, clk;
+
+       device_printf(sc->bge_dev,
+           "CHIP ID 0x%08x; ASIC REV 0x%02x; CHIP REV 0x%02x; ",
+           sc->bge_chipid, sc->bge_asicrev, sc->bge_chiprev);
+       if (sc->bge_flags & BGE_FLAG_PCIE)
+               printf("PCI-E\n");
+       else if (sc->bge_flags & BGE_FLAG_PCIX) {
+               printf("PCI-X ");
+               cfg = CSR_READ_4(sc, BGE_MISC_CFG) & BGE_MISCCFG_BOARD_ID_MASK;
+               if (cfg == BGE_MISCCFG_BOARD_ID_5704CIOBE)
+                       clk = 133;
+               else {
+                       clk = CSR_READ_4(sc, BGE_PCI_CLKCTL) & 0x1F;
+                       switch (clk) {
+                       case 0:
+                               clk = 33;
+                               break;
+                       case 2:
+                               clk = 50;
+                               break;
+                       case 4:
+                               clk = 66;
+                               break;
+                       case 6:
+                               clk = 100;
+                               break;
+                       case 7:
+                               clk = 133;
+                               break;
+                       }
+               }
+               printf("%u MHz\n", clk);
+       } else {
+               if (sc->bge_pcixcap != 0)
+                       printf("PCI on PCI-X ");
+               else
+                       printf("PCI ");
+               cfg = pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE, 4);
+               if (cfg & BGE_PCISTATE_PCI_BUSSPEED)
+                       clk = 66;
+               else
+                       clk = 33;
+               if (cfg & BGE_PCISTATE_32BIT_BUS)
+                       printf("%u MHz; 32bit\n", clk);
+               else
+                       printf("%u MHz; 64bit\n", clk);
+       }
+}
+
+static int
 bge_attach(device_t dev)
 {
        struct ifnet *ifp;
@@ -2769,6 +2928,7 @@ bge_attach(device_t dev)
                case BCOM_DEVICEID_BCM5717:
                case BCOM_DEVICEID_BCM5718:
                case BCOM_DEVICEID_BCM5719:
+               case BCOM_DEVICEID_BCM5720:
                        sc->bge_chipid = pci_read_config(dev,
                            BGE_PCI_GEN2_PRODID_ASICREV, 4);
                        break;
@@ -2800,12 +2960,14 @@ bge_attach(device_t dev)
          * BCM5704  |   1   |   X   |   1   |   X   |
          * BCM5717  |   1   |   8   |   2   |   9   |
          * BCM5719  |   1   |   8   |   2   |   9   |
+         * BCM5720  |   1   |   8   |   2   |   9   |
          *
          * Other addresses may respond but they are not
          * IEEE compliant PHYs and should be ignored.
          */
        if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-           sc->bge_asicrev == BGE_ASICREV_BCM5719) {
+           sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5720) {
                f = pci_get_function(dev);
                if (sc->bge_chipid == BGE_CHIPID_BCM5717_A0) {
                        if (CSR_READ_4(sc, BGE_SGDIG_STS) &
@@ -2840,7 +3002,7 @@ bge_attach(device_t dev)
        switch (sc->bge_asicrev) {
        case BGE_ASICREV_BCM5717:
        case BGE_ASICREV_BCM5719:
-               sc->bge_flags |= BGE_FLAG_SHORT_DMA_BUG;
+       case BGE_ASICREV_BCM5720:
        case BGE_ASICREV_BCM57765:
                sc->bge_flags |= BGE_FLAG_5717_PLUS | BGE_FLAG_5755_PLUS |
                    BGE_FLAG_575X_PLUS | BGE_FLAG_5705_PLUS | BGE_FLAG_JUMBO |
@@ -2875,14 +3037,15 @@ bge_attach(device_t dev)
        case BGE_ASICREV_BCM5752:
        case BGE_ASICREV_BCM5906:
                sc->bge_flags |= BGE_FLAG_575X_PLUS;
-               if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
-                       sc->bge_flags |= BGE_FLAG_SHORT_DMA_BUG;
                /* FALLTHROUGH */
        case BGE_ASICREV_BCM5705:
                sc->bge_flags |= BGE_FLAG_5705_PLUS;
                break;
        }
 
+       /* Add SYSCTLs, requires the chipset family to be set. */
+       bge_add_sysctls(sc);
+
        /* Set various PHY bug flags. */
        if (sc->bge_chipid == BGE_CHIPID_BCM5701_A0 ||
            sc->bge_chipid == BGE_CHIPID_BCM5701_B0)
@@ -2898,6 +3061,7 @@ bge_attach(device_t dev)
            sc->bge_asicrev != BGE_ASICREV_BCM5906 &&
            sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
            sc->bge_asicrev != BGE_ASICREV_BCM5719 &&
+           sc->bge_asicrev != BGE_ASICREV_BCM5720 &&
            sc->bge_asicrev != BGE_ASICREV_BCM5785 &&
            sc->bge_asicrev != BGE_ASICREV_BCM57765 &&
            sc->bge_asicrev != BGE_ASICREV_BCM57780) {
@@ -2930,17 +3094,28 @@ bge_attach(device_t dev)
                sc->bge_mi_mode |= BGE_MIMODE_AUTOPOLL;
 
        /*
-        * All controllers that are not 5755 or higher have 4GB
-        * boundary DMA bug.
+        * All Broadcom controllers have 4GB boundary DMA bug.
         * Whenever an address crosses a multiple of the 4GB boundary
         * (including 4GB, 8Gb, 12Gb, etc.) and makes the transition
         * from 0xX_FFFF_FFFF to 0x(X+1)_0000_0000 an internal DMA
         * state machine will lockup and cause the device to hang.
         */
-       if (BGE_IS_5755_PLUS(sc) == 0)
-               sc->bge_flags |= BGE_FLAG_4G_BNDRY_BUG;
+       sc->bge_flags |= BGE_FLAG_4G_BNDRY_BUG;
+
+       /* BCM5755 or higher and BCM5906 have short DMA bug. */
+       if (BGE_IS_5755_PLUS(sc) || sc->bge_asicrev == BGE_ASICREV_BCM5906)
+               sc->bge_flags |= BGE_FLAG_SHORT_DMA_BUG;
 
-       misccfg = CSR_READ_4(sc, BGE_MISC_CFG) & BGE_MISCCFG_BOARD_ID;
+       /*
+        * BCM5719 cannot handle DMA requests for DMA segments that
+        * have larger than 4KB in size.  However the maximum DMA
+        * segment size created in DMA tag is 4KB for TSO, so we
+        * wouldn't encounter the issue here.
+        */
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
+               sc->bge_flags |= BGE_FLAG_4K_RDMA_BUG;
+
+       misccfg = CSR_READ_4(sc, BGE_MISC_CFG) & BGE_MISCCFG_BOARD_ID_MASK;
        if (sc->bge_asicrev == BGE_ASICREV_BCM5705) {
                if (misccfg == BGE_MISCCFG_BOARD_ID_5788 ||
                    misccfg == BGE_MISCCFG_BOARD_ID_5788M)
@@ -2997,9 +3172,9 @@ bge_attach(device_t dev)
                        sc->bge_flags |= BGE_FLAG_TSO;
        }
 
-       /*
+       /*
         * Check if this is a PCI-X or PCI Express device.
-        */
+        */
        if (pci_find_cap(dev, PCIY_EXPRESS, &reg) == 0) {
                /*
                 * Found a PCI Express capabilities register, this
@@ -3007,7 +3182,8 @@ bge_attach(device_t dev)
                 */
                sc->bge_flags |= BGE_FLAG_PCIE;
                sc->bge_expcap = reg;
-               if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+                   sc->bge_asicrev == BGE_ASICREV_BCM5720)
                        pci_set_max_read_req(dev, 2048);
                else if (pci_get_max_read_req(dev) != 4096)
                        pci_set_max_read_req(dev, 4096);
@@ -3031,6 +3207,16 @@ bge_attach(device_t dev)
        if (BGE_IS_5714_FAMILY(sc) && (sc->bge_flags & BGE_FLAG_PCIX))
                sc->bge_flags |= BGE_FLAG_40BIT_BUG;
        /*
+        * Some PCI-X bridges are known to trigger write reordering to
+        * the mailbox registers. Typical phenomena is watchdog timeouts
+        * caused by out-of-order TX completions.  Enable workaround for
+        * PCI-X devices that live behind these bridges.
+        * Note, PCI-X controllers can run in PCI mode so we can't use
+        * BGE_FLAG_PCIX flag to detect PCI-X controllers.
+        */
+       if (sc->bge_pcixcap != 0 && bge_mbox_reorder(sc) != 0)
+               sc->bge_flags |= BGE_FLAG_MBOX_REORDER;
+       /*
         * Allocate the interrupt, using MSI if possible.  These devices
         * support 8 MSI messages, but only the first one is used in
         * normal operation.
@@ -3069,11 +3255,7 @@ bge_attach(device_t dev)
                goto fail;
        }
 
-       device_printf(dev,
-           "CHIP ID 0x%08x; ASIC REV 0x%02x; CHIP REV 0x%02x; %s\n",
-           sc->bge_chipid, sc->bge_asicrev, sc->bge_chiprev,
-           (sc->bge_flags & BGE_FLAG_PCIX) ? "PCI-X" :
-           ((sc->bge_flags & BGE_FLAG_PCIE) ? "PCI-E" : "PCI"));
+       bge_devinfo(sc);
 
        BGE_LOCK_INIT(sc, device_get_nameunit(dev));
 
@@ -3085,9 +3267,9 @@ bge_attach(device_t dev)
        }
 
        sc->bge_asf_mode = 0;
-       if (bge_allow_asf && (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG)
-           == BGE_MAGIC_NUMBER)) {
-               if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG)
+       if (bge_allow_asf && (bge_readmem_ind(sc, BGE_SRAM_DATA_SIG) ==
+           BGE_SRAM_DATA_SIG_MAGIC)) {
+               if (bge_readmem_ind(sc, BGE_SRAM_DATA_CFG)
                    & BGE_HWCFG_ASF) {
                        sc->bge_asf_mode |= ASF_ENABLE;
                        sc->bge_asf_mode |= ASF_STACKUP;
@@ -3137,8 +3319,6 @@ bge_attach(device_t dev)
                goto fail;
        }
 
-       bge_add_sysctls(sc);
-
        /* Set default tuneable values. */
        sc->bge_stat_ticks = BGE_TICKS_PER_SEC;
        sc->bge_rx_coal_ticks = 150;
@@ -3201,8 +3381,8 @@ bge_attach(device_t dev)
         * by its PCI subsystem ID, as we do below for the SysKonnect
         * SK-9D41.
         */
-       if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) == BGE_MAGIC_NUMBER)
-               hwcfg = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG);
+       if (bge_readmem_ind(sc, BGE_SRAM_DATA_SIG) == BGE_SRAM_DATA_SIG_MAGIC)
+               hwcfg = bge_readmem_ind(sc, BGE_SRAM_DATA_CFG);
        else if ((sc->bge_flags & BGE_FLAG_EADDR) &&
            (sc->bge_asicrev != BGE_ASICREV_BCM5906)) {
                if (bge_read_eeprom(sc, (caddr_t)&hwcfg, BGE_EE_HWCFG_OFFSET,
@@ -3437,9 +3617,9 @@ bge_reset(struct bge_softc *sc)
        /*
         * Write the magic number to SRAM at offset 0xB50.
         * When firmware finishes its initialization it will
-        * write ~BGE_MAGIC_NUMBER to the same location.
+        * write ~BGE_SRAM_FW_MB_MAGIC to the same location.
         */
-       bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
+       bge_writemem_ind(sc, BGE_SRAM_FW_MB, BGE_SRAM_FW_MB_MAGIC);
 
        reset = BGE_MISCCFG_RESET_CORE_CLOCKS | BGE_32BITTIME_66MHZ;
 
@@ -3458,7 +3638,8 @@ bge_reset(struct bge_softc *sc)
         * Set GPHY Power Down Override to leave GPHY
         * powered up in D0 uninitialized.
         */
-       if (BGE_IS_5705_PLUS(sc))
+       if (BGE_IS_5705_PLUS(sc) &&
+           (sc->bge_flags & BGE_FLAG_CPMU_PRESENT) == 0)
                reset |= BGE_MISCCFG_GPHY_PD_OVERRIDE;
 
        /* Issue global reset */
@@ -3487,8 +3668,6 @@ bge_reset(struct bge_softc *sc)
                /* Clear enable no snoop and disable relaxed ordering. */
                devctl &= ~(PCIM_EXP_CTL_RELAXED_ORD_ENABLE |
                    PCIM_EXP_CTL_NOSNOOP_ENABLE);
-               /* Set PCIE max payload size to 128. */
-               devctl &= ~PCIM_EXP_CTL_MAX_PAYLOAD;
                pci_write_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL,
                    devctl, 2);
                /* Clear error status. */
@@ -3563,8 +3742,8 @@ bge_reset(struct bge_softc *sc)
                 */
                for (i = 0; i < BGE_TIMEOUT; i++) {
                        DELAY(10);
-                       val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
-                       if (val == ~BGE_MAGIC_NUMBER)
+                       val = bge_readmem_ind(sc, BGE_SRAM_FW_MB);
+                       if (val == ~BGE_SRAM_FW_MB_MAGIC)
                                break;
                }
 
@@ -3592,8 +3771,7 @@ bge_reset(struct bge_softc *sc)
        }
 
        /* Fix up byte swapping. */
-       CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS |
-           BGE_MODECTL_BYTESWAP_DATA);
+       CSR_WRITE_4(sc, BGE_MODE_CTL, bge_dma_swap_options(sc));
 
        /* Tell the ASF firmware we are up */
        if (sc->bge_asf_mode & ASF_STACKUP)
@@ -3624,6 +3802,10 @@ bge_reset(struct bge_softc *sc)
        }
        DELAY(10000);
 
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5720)
+               BGE_CLRBIT(sc, BGE_CPMU_CLCK_ORIDE,
+                   CPMU_CLCK_ORIDE_MAC_ORIDE_EN);
+
        return (0);
 }
 
@@ -4007,7 +4189,7 @@ bge_intr_task(void *arg, int pending)
        if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
                /* Check TX ring producer/consumer. */
                bge_txeof(sc, tx_cons);
-               if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+               if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
                        bge_start_locked(ifp);
        }
        BGE_UNLOCK(sc);
@@ -4103,12 +4285,14 @@ bge_asf_driver_up(struct bge_softc *sc)
                        sc->bge_asf_count --;
                else {
                        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);
-                       bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_DATA, 3);
-                       CSR_WRITE_4(sc, BGE_CPU_EVENT,
-                           CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));
+                       bge_writemem_ind(sc, BGE_SRAM_FW_CMD_MB,
+                           BGE_FW_CMD_DRV_ALIVE);
+                       bge_writemem_ind(sc, BGE_SRAM_FW_CMD_LEN_MB, 4);
+                       bge_writemem_ind(sc, BGE_SRAM_FW_CMD_DATA_MB,
+                           BGE_FW_HB_TIMEOUT_SEC);
+                       CSR_WRITE_4(sc, BGE_RX_CPU_EVENT,
+                           CSR_READ_4(sc, BGE_RX_CPU_EVENT) |
+                           BGE_RX_CPU_DRV_EVENT);
                }
        }
 }
@@ -4124,7 +4308,7 @@ bge_tick(void *xsc)
        /* Synchronize with possible callout reset/stop. */
        if (callout_pending(&sc->bge_stat_ch) ||
            !callout_active(&sc->bge_stat_ch))
-               return;
+               return;
 
        if (BGE_IS_5705_PLUS(sc))
                bge_stats_update_regs(sc);
@@ -4239,8 +4423,30 @@ bge_stats_update_regs(struct bge_softc *sc)
            CSR_READ_4(sc, BGE_RXLP_LOCSTAT_DMA_HPWRQ_FULL);
        stats->NoMoreRxBDs +=
            CSR_READ_4(sc, BGE_RXLP_LOCSTAT_OUT_OF_BDS);
-       stats->InputDiscards +=
-           CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS);
+       /*
+        * XXX
+        * Unlike other controllers, BGE_RXLP_LOCSTAT_IFIN_DROPS
+        * counter of BCM5717, BCM5718, BCM5719 A0 and BCM5720 A0
+        * includes number of unwanted multicast frames.  This comes
+        * from silicon bug and known workaround to get rough(not
+        * exact) counter is to enable interrupt on MBUF low water
+        * attention.  This can be accomplished by setting
+        * BGE_HCCMODE_ATTN bit of BGE_HCC_MODE,
+        * BGE_BMANMODE_LOMBUF_ATTN bit of BGE_BMAN_MODE and
+        * BGE_MODECTL_FLOWCTL_ATTN_INTR bit of BGE_MODE_CTL.
+        * However that change would generate more interrupts and
+        * there are still possibilities of losing multiple frames
+        * during BGE_MODECTL_FLOWCTL_ATTN_INTR interrupt handling.
+        * Given that the workaround still would not get correct
+        * counter I don't think it's worth to implement it.  So
+        * ignore reading the counter on controllers that have the
+        * silicon bug.
+        */
+       if (sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
+           sc->bge_chipid != BGE_CHIPID_BCM5719_A0 &&
+           sc->bge_chipid != BGE_CHIPID_BCM5720_A0)
+               stats->InputDiscards +=
+                   CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS);
        stats->InputErrors +=
            CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_ERRORS);
        stats->RecvThresholdHit +=
@@ -4311,6 +4517,12 @@ bge_stats_update(struct bge_softc *sc)
        ifp->if_collisions += (uint32_t)(cnt - sc->bge_tx_collisions);
        sc->bge_tx_collisions = cnt;
 
+       cnt = READ_STAT(sc, stats, nicNoMoreRxBDs.bge_addr_lo);
+       ifp->if_ierrors += (uint32_t)(cnt - sc->bge_rx_nobds);
+       sc->bge_rx_nobds = cnt;
+       cnt = READ_STAT(sc, stats, ifInErrors.bge_addr_lo);
+       ifp->if_ierrors += (uint32_t)(cnt - sc->bge_rx_inerrs);
+       sc->bge_rx_inerrs = cnt;
        cnt = READ_STAT(sc, stats, ifInDiscards.bge_addr_lo);
        ifp->if_ierrors += (uint32_t)(cnt - sc->bge_rx_discards);
        sc->bge_rx_discards = cnt;
@@ -4836,6 +5048,11 @@ bge_init_locked(struct bge_softc *sc)
        mode = CSR_READ_4(sc, BGE_TX_MODE);
        if (BGE_IS_5755_PLUS(sc) || sc->bge_asicrev == BGE_ASICREV_BCM5906)
                mode |= BGE_TXMODE_MBUF_LOCKUP_FIX;
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
+               mode &= ~(BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
+               mode |= CSR_READ_4(sc, BGE_TX_MODE) &
+                   (BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
+       }
        /* Turn on transmitter. */
        CSR_WRITE_4(sc, BGE_TX_MODE, mode | BGE_TXMODE_ENABLE);
 
@@ -5048,7 +5265,7 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
                                break;
                        }
                } else if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU) {
-                       error = EINVAL; 
+                       error = EINVAL;
                        break;
                }
                BGE_LOCK(sc);
@@ -5536,6 +5753,12 @@ bge_add_sysctls(struct bge_softc *sc)
            "Number of fragmented TX buffers of a frame allowed before "
            "forced collapsing");
 
+       sc->bge_msi = 1;
+       snprintf(tn, sizeof(tn), "dev.bge.%d.msi", unit);
+       TUNABLE_INT_FETCH(tn, &sc->bge_msi);
+       SYSCTL_ADD_INT(ctx, children, OID_AUTO, "msi",
+           CTLFLAG_RD, &sc->bge_msi, 0, "Enable MSI");
+
        /*
         * It seems all Broadcom controllers have a bug that can generate UDP
         * datagrams with checksum value 0 when TX UDP checksum offloading is
@@ -5809,8 +6032,7 @@ bge_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
 {
        struct bge_softc *sc;
        uint16_t *sbdata;
-       int error;
-       int result;
+       int error, result, sbsz;
        int i, j;
 
        result = -1;
@@ -5821,14 +6043,21 @@ bge_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
        if (result == 1) {
                sc = (struct bge_softc *)arg1;
 
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
+                   sc->bge_chipid != BGE_CHIPID_BCM5700_C0)
+                       sbsz = BGE_STATUS_BLK_SZ;
+               else
+                       sbsz = 32;
                sbdata = (uint16_t *)sc->bge_ldata.bge_status_block;
                printf("Status Block:\n");
-               for (i = 0x0; i < (BGE_STATUS_BLK_SZ / 4); ) {
+               BGE_LOCK(sc);
+               bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+                   sc->bge_cdata.bge_status_map,
+                   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+               for (i = 0x0; i < sbsz / sizeof(uint16_t); ) {
                        printf("%06x:", i);
-                       for (j = 0; j < 8; j++) {
-                               printf(" %04x", sbdata[i]);
-                               i += 4;
-                       }
+                       for (j = 0; j < 8; j++)
+                               printf(" %04x", sbdata[i++]);
                        printf("\n");
                }
 
@@ -5841,8 +6070,11 @@ bge_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
                        }
                        printf("\n");
                }
+               BGE_UNLOCK(sc);
 
                printf("Hardware Flags:\n");
+               if (BGE_IS_5717_PLUS(sc))
+                       printf(" - 5717 Plus\n");
                if (BGE_IS_5755_PLUS(sc))
                        printf(" - 5755 Plus\n");
                if (BGE_IS_575X_PLUS(sc))
@@ -5932,11 +6164,11 @@ bge_get_eaddr_mem(struct bge_softc *sc, uint8_t 
ether_addr[])
 {
        uint32_t mac_addr;
 
-       mac_addr = bge_readmem_ind(sc, 0x0c14);
+       mac_addr = bge_readmem_ind(sc, BGE_SRAM_MAC_ADDR_HIGH_MB);
        if ((mac_addr >> 16) == 0x484b) {
                ether_addr[0] = (uint8_t)(mac_addr >> 8);
                ether_addr[1] = (uint8_t)mac_addr;
-               mac_addr = bge_readmem_ind(sc, 0x0c18);
+               mac_addr = bge_readmem_ind(sc, BGE_SRAM_MAC_ADDR_LOW_MB);
                ether_addr[2] = (uint8_t)(mac_addr >> 24);
                ether_addr[3] = (uint8_t)(mac_addr >> 16);
                ether_addr[4] = (uint8_t)(mac_addr >> 8);
diff --git 
a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h 
b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h
index 889efce..4413775 100644
--- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h
+++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h
@@ -71,12 +71,15 @@
 #define        BGE_STATS_BLOCK_END             0x00000AFF
 #define        BGE_STATUS_BLOCK                0x00000B00
 #define        BGE_STATUS_BLOCK_END            0x00000B4F
-#define        BGE_SOFTWARE_GENCOMM            0x00000B50
-#define        BGE_SOFTWARE_GENCOMM_SIG        0x00000B54
-#define        BGE_SOFTWARE_GENCOMM_NICCFG     0x00000B58
-#define        BGE_SOFTWARE_GENCOMM_FW         0x00000B78
-#define        BGE_SOFTWARE_GENNCOMM_FW_LEN    0x00000B7C
-#define        BGE_SOFTWARE_GENNCOMM_FW_DATA   0x00000B80
+#define        BGE_SRAM_FW_MB                  0x00000B50
+#define        BGE_SRAM_DATA_SIG               0x00000B54
+#define        BGE_SRAM_DATA_CFG               0x00000B58
+#define        BGE_SRAM_FW_CMD_MB              0x00000B78
+#define        BGE_SRAM_FW_CMD_LEN_MB          0x00000B7C
+#define        BGE_SRAM_FW_CMD_DATA_MB         0x00000B80
+#define        BGE_SRAM_FW_DRV_STATE_MB        0x00000C04
+#define        BGE_SRAM_MAC_ADDR_HIGH_MB       0x00000C14
+#define        BGE_SRAM_MAC_ADDR_LOW_MB        0x00000C18
 #define        BGE_SOFTWARE_GENCOMM_END        0x00000FFF
 #define        BGE_UNMAPPED                    0x00001000
 #define        BGE_UNMAPPED_END                0x00001FFF
@@ -87,8 +90,24 @@
 #define        BGE_SEND_RING_1_TO_4_END        0x00005FFF
 
 /* Firmware interface */
-#define        BGE_FW_DRV_ALIVE                0x00000001
-#define        BGE_FW_PAUSE                    0x00000002
+#define        BGE_SRAM_DATA_SIG_MAGIC         0x4B657654      /* 'KevT' */
+
+#define        BGE_FW_CMD_DRV_ALIVE            0x00000001
+#define        BGE_FW_CMD_PAUSE                0x00000002
+#define        BGE_FW_CMD_IPV4_ADDR_CHANGE     0x00000003
+#define        BGE_FW_CMD_IPV6_ADDR_CHANGE     0x00000004
+#define        BGE_FW_CMD_LINK_UPDATE          0x0000000C
+#define        BGE_FW_CMD_DRV_ALIVE2           0x0000000D
+#define        BGE_FW_CMD_DRV_ALIVE3           0x0000000E
+
+#define        BGE_FW_HB_TIMEOUT_SEC           3
+
+#define        BGE_FW_DRV_STATE_START          0x00000001
+#define        BGE_FW_DRV_STATE_START_DONE     0x80000001
+#define        BGE_FW_DRV_STATE_UNLOAD         0x00000002
+#define        BGE_FW_DRV_STATE_UNLOAD_DONE    0x80000002
+#define        BGE_FW_DRV_STATE_WOL            0x00000003
+#define        BGE_FW_DRV_STATE_SUSPEND        0x00000004
 
 /* Mappings for internal memory configuration */
 #define        BGE_STD_RX_RINGS                0x00006000
@@ -239,15 +258,6 @@
 #define        BGE_PCIMISCCTL_ASICREV_SHIFT    16
 
 #define        BGE_HIF_SWAP_OPTIONS    (BGE_PCIMISCCTL_ENDIAN_WORDSWAP)
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define        BGE_DMA_SWAP_OPTIONS \
-       BGE_MODECTL_WORDSWAP_NONFRAME| \
-       BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA
-#else
-#define        BGE_DMA_SWAP_OPTIONS \
-       BGE_MODECTL_WORDSWAP_NONFRAME|BGE_MODECTL_BYTESWAP_NONFRAME| \
-       BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA
-#endif
 
 #define        BGE_INIT \
        (BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_CLEAR_INTA| \
@@ -320,6 +330,7 @@
 #define        BGE_CHIPID_BCM5717_A0           0x05717000
 #define        BGE_CHIPID_BCM5717_B0           0x05717100
 #define        BGE_CHIPID_BCM5719_A0           0x05719000
+#define        BGE_CHIPID_BCM5720_A0           0x05720000
 #define        BGE_CHIPID_BCM57765_A0          0x57785000
 #define        BGE_CHIPID_BCM57765_B0          0x57785100
 
@@ -344,6 +355,7 @@
 /* BGE_PCI_PRODID_ASICREV ASIC rev. identifiers. */
 #define        BGE_ASICREV_BCM5717             0x5717
 #define        BGE_ASICREV_BCM5719             0x5719
+#define        BGE_ASICREV_BCM5720             0x5720
 #define        BGE_ASICREV_BCM5761             0x5761
 #define        BGE_ASICREV_BCM5784             0x5784
 #define        BGE_ASICREV_BCM5785             0x5785
@@ -788,6 +800,8 @@
 #define        BGE_TXMODE_BIGBACKOFF_ENABLE    0x00000020
 #define        BGE_TXMODE_LONGPAUSE_ENABLE     0x00000040
 #define        BGE_TXMODE_MBUF_LOCKUP_FIX      0x00000100
+#define        BGE_TXMODE_JMB_FRM_LEN          0x00400000
+#define        BGE_TXMODE_CNT_DN_MODE          0x00800000
 
 /* Transmit MAC status register */
 #define        BGE_TXSTAT_RX_XOFFED            0x00000001
@@ -801,6 +815,8 @@
 #define        BGE_TXLEN_SLOTTIME              0x000000FF
 #define        BGE_TXLEN_IPG                   0x00000F00
 #define        BGE_TXLEN_CRS                   0x00003000
+#define        BGE_TXLEN_JMB_FRM_LEN_MSK       0x00FF0000
+#define        BGE_TXLEN_CNT_DN_VAL_MSK        0xFF000000
 
 /* Receive MAC mode register */
 #define        BGE_RXMODE_RESET                0x00000001
@@ -1258,6 +1274,7 @@
 #define        BGE_CPMU_LSPD_1000MB_CLK        0x360C
 #define        BGE_CPMU_LNK_AWARE_PWRMD        0x3610
 #define        BGE_CPMU_HST_ACC                0x361C
+#define        BGE_CPMU_CLCK_ORIDE             0x3624
 #define        BGE_CPMU_CLCK_STAT              0x3630
 #define        BGE_CPMU_MUTEX_REQ              0x365C
 #define        BGE_CPMU_MUTEX_GNT              0x3660
@@ -1285,6 +1302,9 @@
 #define        BGE_CPMU_HST_ACC_MACCLK_MASK    0x001F0000
 #define        BGE_CPMU_HST_ACC_MACCLK_6_25    0x00130000
 
+/* Clock Speed Override Policy register */
+#define        CPMU_CLCK_ORIDE_MAC_ORIDE_EN    0x80000000
+
 /* CPMU Clock Status register */
 #define        BGE_CPMU_CLCK_STAT_MAC_CLCK_MASK        0x001F0000
 #define        BGE_CPMU_CLCK_STAT_MAC_CLCK_62_5        0x00000000
@@ -1532,6 +1552,7 @@
 #define        BGE_RDMAMODE_MULT_DMA_RD_DIS    0x01000000
 #define        BGE_RDMAMODE_TSO4_ENABLE        0x08000000
 #define        BGE_RDMAMODE_TSO6_ENABLE        0x10000000
+#define        BGE_RDMAMODE_H2BNC_VLAN_DET     0x20000000
 
 /* Read DMA status register */
 #define        BGE_RDMASTAT_PCI_TGT_ABRT_ATTN  0x00000004
@@ -1552,6 +1573,7 @@
 #define        BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK 0x000FF000
 #define        BGE_RDMA_RSRVCTRL_TXMRGN_MASK   0xFFE00000
 
+#define        BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512    0x00020000
 #define        BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K     0x00030000
 #define        BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K    0x000C0000
 
@@ -1875,7 +1897,8 @@
 #define        BGE_MODE_CTL                    0x6800
 #define        BGE_MISC_CFG                    0x6804
 #define        BGE_MISC_LOCAL_CTL              0x6808
-#define        BGE_CPU_EVENT                   0x6810
+#define        BGE_RX_CPU_EVENT                0x6810
+#define        BGE_TX_CPU_EVENT                0x6820
 #define        BGE_EE_ADDR                     0x6838
 #define        BGE_EE_DATA                     0x683C
 #define        BGE_EE_CTL                      0x6840
@@ -1883,6 +1906,8 @@
 #define        BGE_EE_DELAY                    0x6848
 #define        BGE_FASTBOOT_PC                 0x6894
 
+#define        BGE_RX_CPU_DRV_EVENT            0x00004000
+
 /*
  * NVRAM Control registers
  */
@@ -1939,14 +1964,18 @@
 #define        BGE_MODECTL_WORDSWAP_NONFRAME   0x00000004
 #define        BGE_MODECTL_BYTESWAP_DATA       0x00000010
 #define        BGE_MODECTL_WORDSWAP_DATA       0x00000020
+#define        BGE_MODECTL_BYTESWAP_B2HRX_DATA 0x00000040
+#define        BGE_MODECTL_WORDSWAP_B2HRX_DATA 0x00000080
 #define        BGE_MODECTL_NO_FRAME_CRACKING   0x00000200
 #define        BGE_MODECTL_NO_RX_CRC           0x00000400
 #define        BGE_MODECTL_RX_BADFRAMES        0x00000800
 #define        BGE_MODECTL_NO_TX_INTR          0x00002000
 #define        BGE_MODECTL_NO_RX_INTR          0x00004000
 #define        BGE_MODECTL_FORCE_PCI32         0x00008000
+#define        BGE_MODECTL_B2HRX_ENABLE        0x00008000
 #define        BGE_MODECTL_STACKUP             0x00010000
 #define        BGE_MODECTL_HOST_SEND_BDS       0x00020000
+#define        BGE_MODECTL_HTX2B_ENABLE        0x00040000
 #define        BGE_MODECTL_TX_NO_PHDR_CSUM     0x00100000
 #define        BGE_MODECTL_RX_NO_PHDR_CSUM     0x00800000
 #define        BGE_MODECTL_TX_ATTN_INTR        0x01000000
@@ -1960,7 +1989,9 @@
 /* Misc. config register */
 #define        BGE_MISCCFG_RESET_CORE_CLOCKS   0x00000001
 #define        BGE_MISCCFG_TIMER_PRESCALER     0x000000FE
-#define        BGE_MISCCFG_BOARD_ID            0x0001E000
+#define        BGE_MISCCFG_BOARD_ID_MASK       0x0001E000
+#define        BGE_MISCCFG_BOARD_ID_5704       0x00000000
+#define        BGE_MISCCFG_BOARD_ID_5704CIOBE  0x00004000
 #define        BGE_MISCCFG_BOARD_ID_5788       0x00010000
 #define        BGE_MISCCFG_BOARD_ID_5788M      0x00018000
 #define        BGE_MISCCFG_EPHY_IDDQ           0x00200000
@@ -2052,10 +2083,10 @@
  * This magic number is written to the firmware mailbox at 0xb50
  * before a software reset is issued.  After the internal firmware
  * has completed its initialization it will write the opposite of
- * this value, ~BGE_MAGIC_NUMBER, to the same location, allowing the
- * driver to synchronize with the firmware.
+ * this value, ~BGE_SRAM_FW_MB_MAGIC, to the same location,
+ * allowing the driver to synchronize with the firmware.
  */
-#define        BGE_MAGIC_NUMBER                0x4B657654
+#define        BGE_SRAM_FW_MB_MAGIC    0x4B657654
 
 typedef struct {
        uint32_t                bge_addr_hi;
@@ -2276,7 +2307,8 @@ struct bge_status_block {
 #define        BCOM_DEVICEID_BCM5717           0x1655
 #define        BCOM_DEVICEID_BCM5718           0x1656
 #define        BCOM_DEVICEID_BCM5719           0x1657
-#define        BCOM_DEVICEID_BCM5720           0x1658
+#define        BCOM_DEVICEID_BCM5720_PP        0x1658  /* Not released to 
public. */
+#define        BCOM_DEVICEID_BCM5720           0x165F
 #define        BCOM_DEVICEID_BCM5721           0x1659
 #define        BCOM_DEVICEID_BCM5722           0x165A
 #define        BCOM_DEVICEID_BCM5723           0x165B
@@ -2797,6 +2829,8 @@ struct bge_softc {
 #define        BGE_FLAG_4G_BNDRY_BUG   0x02000000
 #define        BGE_FLAG_RX_ALIGNBUG    0x04000000
 #define        BGE_FLAG_SHORT_DMA_BUG  0x08000000
+#define        BGE_FLAG_4K_RDMA_BUG    0x10000000
+#define        BGE_FLAG_MBOX_REORDER   0x20000000
        uint32_t                bge_phy_flags;
 #define        BGE_PHY_NO_WIRESPEED    0x00000001
 #define        BGE_PHY_ADC_BUG         0x00000002
@@ -2833,9 +2867,12 @@ struct bge_softc {
        int                     bge_timer;
        int                     bge_forced_collapse;
        int                     bge_forced_udpcsum;
+       int                     bge_msi;
        int                     bge_csum_features;
        struct callout          bge_stat_ch;
        uint32_t                bge_rx_discards;
+       uint32_t                bge_rx_inerrs;
+       uint32_t                bge_rx_nobds;
        uint32_t                bge_tx_discards;
        uint32_t                bge_tx_collisions;
 #ifdef DEVICE_POLLING
diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphy.c 
b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphy.c
index 88090b7..57646e5 100644
--- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphy.c
+++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphy.c
@@ -82,7 +82,7 @@ static device_method_t brgphy_methods[] = {
        DEVMETHOD(device_attach,        brgphy_attach),
        DEVMETHOD(device_detach,        mii_phy_detach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static devclass_t brgphy_devclass;
@@ -139,9 +139,14 @@ static const struct mii_phydesc brgphys[] = {
        MII_PHY_DESC(BROADCOM2, BCM5754),
        MII_PHY_DESC(BROADCOM2, BCM5761),
        MII_PHY_DESC(BROADCOM2, BCM5784),
+#ifdef notyet  /* better handled by ukphy(4) until WARs are implemented */
+       MII_PHY_DESC(BROADCOM2, BCM5785),
+#endif
        MII_PHY_DESC(BROADCOM3, BCM5717C),
        MII_PHY_DESC(BROADCOM3, BCM5719C),
+       MII_PHY_DESC(BROADCOM3, BCM5720C),
        MII_PHY_DESC(BROADCOM3, BCM57765),
+       MII_PHY_DESC(BROADCOM3, BCM57780),
        MII_PHY_DESC(xxBROADCOM_ALT1, BCM5906),
        MII_PHY_END
 };
@@ -221,7 +226,8 @@ brgphy_attach(device_t dev)
                                sc->mii_flags |= MIIF_HAVEFIBER;
                        }
                        break;
-               } break;
+               }
+               break;
        case MII_OUI_BROADCOM2:
                switch (sc->mii_mpd_model) {
                case MII_MODEL_BROADCOM2_BCM5708S:
@@ -938,7 +944,8 @@ brgphy_reset(struct mii_softc *sc)
                if (bge_sc->bge_phy_flags & BGE_PHY_JITTER_BUG)
                        brgphy_fixup_jitter_bug(sc);
 
-               brgphy_jumbo_settings(sc, ifp->if_mtu);
+               if (bge_sc->bge_flags & BGE_FLAG_JUMBO)
+                       brgphy_jumbo_settings(sc, ifp->if_mtu);
 
                if ((bge_sc->bge_phy_flags & BGE_PHY_NO_WIRESPEED) == 0)
                        brgphy_ethernet_wirespeed(sc);
diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy.c 
b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy.c
index 4ecfce2..9d52eb5 100644
--- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy.c
+++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy.c
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 
17:09:25 kensmith Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * driver for generic unknown PHYs
@@ -86,7 +86,7 @@ static device_method_t ukphy_methods[] = {
        DEVMETHOD(device_attach,        ukphy_attach),
        DEVMETHOD(device_detach,        mii_phy_detach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static devclass_t ukphy_devclass;
diff --git 
a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy_subr.c 
b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy_subr.c
index 73007e1..5f2f634 100644
--- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy_subr.c
+++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy_subr.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 
17:09:25 kensmith Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * Subroutines shared by the ukphy driver and other PHY drivers.
diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/dcphy.c 
b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/dcphy.c
index 5c60ad5..a05f2ed 100644
--- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/dcphy.c
+++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/dcphy.c
@@ -95,7 +95,7 @@ static device_method_t dcphy_methods[] = {
        DEVMETHOD(device_attach,        dcphy_attach),
        DEVMETHOD(device_detach,        mii_phy_detach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static devclass_t dcphy_devclass;
@@ -294,7 +294,7 @@ static void
 dcphy_status(struct mii_softc *sc)
 {
        struct mii_data *mii = sc->mii_pdata;
-       int reg, anlpar, tstat = 0;
+       int anlpar, tstat;
        struct dc_softc         *dc_sc;
 
        dc_sc = mii->mii_ifp->if_softc;
@@ -305,13 +305,12 @@ dcphy_status(struct mii_softc *sc)
        if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
                return;
 
-       reg = CSR_READ_4(dc_sc, DC_10BTSTAT);
-       if (!(reg & DC_TSTAT_LS10) || !(reg & DC_TSTAT_LS100))
+       tstat = CSR_READ_4(dc_sc, DC_10BTSTAT);
+       if (!(tstat & DC_TSTAT_LS10) || !(tstat & DC_TSTAT_LS100))
                mii->mii_media_status |= IFM_ACTIVE;
 
        if (CSR_READ_4(dc_sc, DC_10BTCTRL) & DC_TCTL_AUTONEGENBL) {
                /* Erg, still trying, I guess... */
-               tstat = CSR_READ_4(dc_sc, DC_10BTSTAT);
                if ((tstat & DC_TSTAT_ANEGSTAT) != DC_ASTAT_AUTONEGCMP) {
                        if ((DC_IS_MACRONIX(dc_sc) || DC_IS_PNICII(dc_sc)) &&
                            (tstat & DC_TSTAT_ANEGSTAT) == DC_ASTAT_DISABLE)
@@ -351,9 +350,9 @@ dcphy_status(struct mii_softc *sc)
                 * and hope that the user is clever enough to manually
                 * change the media settings if we're wrong.
                 */
-               if (!(reg & DC_TSTAT_LS100))
+               if (!(tstat & DC_TSTAT_LS100))
                        mii->mii_media_active |= IFM_100_TX | IFM_HDX;
-               else if (!(reg & DC_TSTAT_LS10))
+               else if (!(tstat & DC_TSTAT_LS10))
                        mii->mii_media_active |= IFM_10_T | IFM_HDX;
                else
                        mii->mii_media_active |= IFM_NONE;
diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dc.c 
b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dc.c
index 4945a0e..41d9ea3 100644
--- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dc.c
+++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dc.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/dc/if_dc.c,v 1.201.2.3.2.1 2010/12/21 17:09:25 
kensmith Exp $");
+__FBSDID("$FreeBSD$");
 
 /*
  * DEC "tulip" clone ethernet driver. Supports the DEC/Intel 21143
@@ -225,6 +225,10 @@ static const struct dc_type const dc_devs[] = {
                "Linksys PCMPC200 CardBus 10/100" },
        { DC_DEVID(DC_VENDORID_LINKSYS, DC_DEVICEID_PCMPC200_AB09), 0,
                "Linksys PCMPC200 CardBus 10/100" },
+       { DC_DEVID(DC_VENDORID_ULI, DC_DEVICEID_M5261), 0,
+               "ULi M5261 FastEthernet" },
+       { DC_DEVID(DC_VENDORID_ULI, DC_DEVICEID_M5263), 0,
+               "ULi M5263 FastEthernet" },
        { 0, 0, NULL }
 };
 
@@ -253,6 +257,7 @@ static void dc_stop(struct dc_softc *);
 static void dc_watchdog(void *);
 static int dc_shutdown(device_t);
 static int dc_ifmedia_upd(struct ifnet *);
+static int dc_ifmedia_upd_locked(struct dc_softc *);
 static void dc_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 
 static int dc_dma_alloc(struct dc_softc *);
@@ -280,6 +285,7 @@ static uint32_t dc_mchash_be(const uint8_t *);
 static void dc_setfilt_21143(struct dc_softc *);
 static void dc_setfilt_asix(struct dc_softc *);
 static void dc_setfilt_admtek(struct dc_softc *);
+static void dc_setfilt_uli(struct dc_softc *);
 static void dc_setfilt_xircom(struct dc_softc *);
 
 static void dc_setfilt(struct dc_softc *);
@@ -331,17 +337,13 @@ static device_method_t dc_methods[] = {
        DEVMETHOD(device_resume,        dc_resume),
        DEVMETHOD(device_shutdown,      dc_shutdown),
 
-       /* bus interface */
-       DEVMETHOD(bus_print_child,      bus_generic_print_child),
-       DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
-
        /* MII interface */
        DEVMETHOD(miibus_readreg,       dc_miibus_readreg),
        DEVMETHOD(miibus_writereg,      dc_miibus_writereg),
        DEVMETHOD(miibus_statchg,       dc_miibus_statchg),
        DEVMETHOD(miibus_mediainit,     dc_miibus_mediainit),
 
-       { 0, 0 }
+       DEVMETHOD_END
 };
 
 static driver_t dc_driver = {
@@ -352,8 +354,9 @@ static driver_t dc_driver = {
 
 static devclass_t dc_devclass;
 
-DRIVER_MODULE(dc, pci, dc_driver, dc_devclass, 0, 0);
-DRIVER_MODULE(miibus, dc, miibus_driver, miibus_devclass, 0, 0);
+DRIVER_MODULE_ORDERED(dc, pci, dc_driver, dc_devclass, NULL, NULL,
+    SI_ORDER_ANY);
+DRIVER_MODULE(miibus, dc, miibus_driver, miibus_devclass, NULL, NULL);
 
 #define        DC_SETBIT(sc, reg, x)                           \
        CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | (x))
@@ -700,6 +703,23 @@ dc_miibus_readreg(device_t dev, int phy, int reg)
                return (0);
        }
 
+       if (sc->dc_type == DC_TYPE_ULI_M5263) {
+               CSR_WRITE_4(sc, DC_ROM,
+                   ((phy << DC_ULI_PHY_ADDR_SHIFT) & DC_ULI_PHY_ADDR_MASK) |
+                   ((reg << DC_ULI_PHY_REG_SHIFT) & DC_ULI_PHY_REG_MASK) |
+                   DC_ULI_PHY_OP_READ);
+               for (i = 0; i < DC_TIMEOUT; i++) {
+                       DELAY(1);
+                       rval = CSR_READ_4(sc, DC_ROM);
+                       if ((rval & DC_ULI_PHY_OP_DONE) != 0) {
+                               return (rval & DC_ULI_PHY_DATA_MASK);
+                       }
+               }
+               if (i == DC_TIMEOUT)
+                       device_printf(dev, "phy read timed out\n");
+               return (0);
+       }
+
        if (DC_IS_COMET(sc)) {
                switch (reg) {
                case MII_BMCR:
@@ -765,6 +785,16 @@ dc_miibus_writereg(device_t dev, int phy, int reg, int 
data)
                return (0);
        }
 
+       if (sc->dc_type == DC_TYPE_ULI_M5263) {
+               CSR_WRITE_4(sc, DC_ROM,
+                   ((phy << DC_ULI_PHY_ADDR_SHIFT) & DC_ULI_PHY_ADDR_MASK) |
+                   ((reg << DC_ULI_PHY_REG_SHIFT) & DC_ULI_PHY_REG_MASK) |
+                   ((data << DC_ULI_PHY_DATA_SHIFT) & DC_ULI_PHY_DATA_MASK) |
+                   DC_ULI_PHY_OP_WRITE);
+               DELAY(1);
+               return (0);
+       }
+
        if (DC_IS_COMET(sc)) {
                switch (reg) {
                case MII_BMCR:
@@ -827,12 +857,11 @@ dc_miibus_statchg(device_t dev)
                return;
 
        ifm = &mii->mii_media;
-       if (DC_IS_DAVICOM(sc) &&
-           IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1) {
+       if (DC_IS_DAVICOM(sc) && IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1) {
                dc_setcfg(sc, ifm->ifm_media);
-               sc->dc_if_media = ifm->ifm_media;
                return;
-       }
+       } else if (!DC_IS_ADMTEK(sc))
+               dc_setcfg(sc, mii->mii_media_active);
 
        sc->dc_link = 0;
        if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
@@ -842,17 +871,8 @@ dc_miibus_statchg(device_t dev)
                case IFM_100_TX:
                        sc->dc_link = 1;
                        break;
-               default:
-                       break;
                }
        }
-       if (sc->dc_link == 0)
-               return;
-
-       sc->dc_if_media = mii->mii_media_active;
-       if (DC_IS_ADMTEK(sc))
-               return;
-       dc_setcfg(sc, mii->mii_media_active);
 }
 
 /*
@@ -1148,6 +1168,97 @@ dc_setfilt_asix(struct dc_softc *sc)
 }
 
 static void
+dc_setfilt_uli(struct dc_softc *sc)
+{
+       uint8_t eaddr[ETHER_ADDR_LEN];
+       struct ifnet *ifp;
+       struct ifmultiaddr *ifma;
+       struct dc_desc *sframe;
+       uint32_t filter, *sp;
+       uint8_t *ma;
+       int i, mcnt;
+
+       ifp = sc->dc_ifp;
+
+       i = sc->dc_cdata.dc_tx_prod;
+       DC_INC(sc->dc_cdata.dc_tx_prod, DC_TX_LIST_CNT);
+       sc->dc_cdata.dc_tx_cnt++;
+       sframe = &sc->dc_ldata.dc_tx_list[i];
+       sp = sc->dc_cdata.dc_sbuf;
+       bzero(sp, DC_SFRAME_LEN);
+
+       sframe->dc_data = htole32(DC_ADDR_LO(sc->dc_saddr));
+       sframe->dc_ctl = htole32(DC_SFRAME_LEN | DC_TXCTL_SETUP |
+           DC_TXCTL_TLINK | DC_FILTER_PERFECT | DC_TXCTL_FINT);
+
+       sc->dc_cdata.dc_tx_chain[i] = (struct mbuf *)sc->dc_cdata.dc_sbuf;
+
+       /* Set station address. */
+       bcopy(IF_LLADDR(sc->dc_ifp), eaddr, ETHER_ADDR_LEN);
+       *sp++ = DC_SP_MAC(eaddr[1] << 8 | eaddr[0]);
+       *sp++ = DC_SP_MAC(eaddr[3] << 8 | eaddr[2]);
+       *sp++ = DC_SP_MAC(eaddr[5] << 8 | eaddr[4]);
+
+       /* Set broadcast address. */
+       *sp++ = DC_SP_MAC(0xFFFF);
+       *sp++ = DC_SP_MAC(0xFFFF);
+       *sp++ = DC_SP_MAC(0xFFFF);
+
+       /* Extract current filter configuration. */
+       filter = CSR_READ_4(sc, DC_NETCFG);
+       filter &= ~(DC_NETCFG_RX_PROMISC | DC_NETCFG_RX_ALLMULTI);
+
+       /* Now build perfect filters. */
+       mcnt = 0;
+       if_maddr_rlock(ifp);
+       TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+               if (ifma->ifma_addr->sa_family != AF_LINK)
+                       continue;
+               if (mcnt >= DC_ULI_FILTER_NPERF) {
+                       filter |= DC_NETCFG_RX_ALLMULTI;
+                       break;
+               }
+               ma = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
+               *sp++ = DC_SP_MAC(ma[1] << 8 | ma[0]);
+               *sp++ = DC_SP_MAC(ma[3] << 8 | ma[2]);
+               *sp++ = DC_SP_MAC(ma[5] << 8 | ma[4]);
+               mcnt++;
+       }
+       if_maddr_runlock(ifp);
+
+       for (; mcnt < DC_ULI_FILTER_NPERF; mcnt++) {
+               *sp++ = DC_SP_MAC(0xFFFF);
+               *sp++ = DC_SP_MAC(0xFFFF);
+               *sp++ = DC_SP_MAC(0xFFFF);
+       }
+
+       if (filter & (DC_NETCFG_TX_ON | DC_NETCFG_RX_ON))
+               CSR_WRITE_4(sc, DC_NETCFG,
+                   filter & ~(DC_NETCFG_TX_ON | DC_NETCFG_RX_ON));
+       if (ifp->if_flags & IFF_PROMISC)
+               filter |= DC_NETCFG_RX_PROMISC | DC_NETCFG_RX_ALLMULTI;
+       if (ifp->if_flags & IFF_ALLMULTI)
+               filter |= DC_NETCFG_RX_ALLMULTI;
+       CSR_WRITE_4(sc, DC_NETCFG,
+           filter & ~(DC_NETCFG_TX_ON | DC_NETCFG_RX_ON));
+       if (filter & (DC_NETCFG_TX_ON | DC_NETCFG_RX_ON))
+               CSR_WRITE_4(sc, DC_NETCFG, filter);
+
+       sframe->dc_status = htole32(DC_TXSTAT_OWN);
+       bus_dmamap_sync(sc->dc_tx_ltag, sc->dc_tx_lmap, BUS_DMASYNC_PREREAD |
+           BUS_DMASYNC_PREWRITE);
+       bus_dmamap_sync(sc->dc_stag, sc->dc_smap, BUS_DMASYNC_PREWRITE);
+       CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF);
+
+       /*
+        * Wait some time...
+        */
+       DELAY(1000);
+
+       sc->dc_wdog_timer = 5;
+}
+
+static void
 dc_setfilt_xircom(struct dc_softc *sc)
 {
        uint16_t eaddr[(ETHER_ADDR_LEN+1)/2];
@@ -1235,6 +1346,9 @@ dc_setfilt(struct dc_softc *sc)
        if (DC_IS_ADMTEK(sc))
                dc_setfilt_admtek(sc);
 
+       if (DC_IS_ULI(sc))
+               dc_setfilt_uli(sc);
+
        if (DC_IS_XIRCOM(sc))
                dc_setfilt_xircom(sc);
 }
@@ -1403,7 +1517,7 @@ dc_reset(struct dc_softc *sc)
        }
 
        if (DC_IS_ASIX(sc) || DC_IS_ADMTEK(sc) || DC_IS_CONEXANT(sc) ||
-           DC_IS_XIRCOM(sc) || DC_IS_INTEL(sc)) {
+           DC_IS_XIRCOM(sc) || DC_IS_INTEL(sc) || DC_IS_ULI(sc)) {
                DELAY(10000);
                DC_CLRBIT(sc, DC_BUSCTL, DC_BUSCTL_RESET);
                i = 0;
@@ -1615,7 +1729,7 @@ dc_read_srom(struct dc_softc *sc, int bits)
        int size;
 
        size = DC_ROM_SIZE(bits);
-       sc->dc_srom = malloc(size, M_DEVBUF, M_NOWAIT);
+       sc->dc_srom = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
        if (sc->dc_srom == NULL) {
                device_printf(sc->dc_dev, "Could not allocate SROM buffer\n");
                return (ENOMEM);
@@ -1909,7 +2023,8 @@ dc_attach(device_t dev)
        struct ifnet *ifp;
        struct dc_mediainfo *m;
        uint32_t reg, revision;
-       int error, mac_offset, phy, rid, tmp;
+       uint16_t *srom;
+       int error, mac_offset, n, phy, rid, tmp;
        uint8_t *mac;
 
        sc = device_get_softc(dev);
@@ -2089,6 +2204,21 @@ dc_attach(device_t dev)
                if (error != 0)
                        goto fail;
                break;
+       case DC_DEVID(DC_VENDORID_ULI, DC_DEVICEID_M5261):
+       case DC_DEVID(DC_VENDORID_ULI, DC_DEVICEID_M5263):
+               if (sc->dc_info->dc_devid ==
+                   DC_DEVID(DC_VENDORID_ULI, DC_DEVICEID_M5261))
+                       sc->dc_type = DC_TYPE_ULI_M5261;
+               else
+                       sc->dc_type = DC_TYPE_ULI_M5263;
+               /* TX buffers should be aligned on 4 byte boundary. */
+               sc->dc_flags |= DC_TX_INTR_ALWAYS | DC_TX_COALESCE |
+                   DC_TX_ALIGN;
+               sc->dc_pmode = DC_PMODE_MII;
+               error = dc_read_srom(sc, sc->dc_romwidth);
+               if (error != 0)
+                       goto fail;
+               break;
        default:
                device_printf(dev, "unknown device: %x\n",
                    sc->dc_info->dc_devid);
@@ -2186,6 +2316,33 @@ dc_attach(device_t dev)
                }
                bcopy(mac, eaddr, ETHER_ADDR_LEN);

[ *** diff truncated: 34766 lines dropped *** ]


############################################################################

Commit:      d997b26243cfe0d1f7edabb2bd3874340539b60d
URL:         http://cgit.haiku-os.org/haiku/commit/?id=d997b26
Author:      Jerome Duval <jerome.duval@xxxxxxxxx>
Date:        Mon Jan  7 22:51:42 2013 UTC

ipro1000: Haiku changes to have it compiled again.

* a lot of gcc2 specific changes...

----------------------------------------------------------------------------

############################################################################

Revision:    hrev45142
Commit:      713f1b8c050805928cdae527526db5251f1365e4
URL:         http://cgit.haiku-os.org/haiku/commit/?id=713f1b8
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Thu Jan  3 13:48:18 2013 UTC
Committer:   Jerome Duval <jerome.duval@xxxxxxxxx>
Commit-Date: Tue Jan  8 21:45:31 2013 UTC

added rdc driver based on vte FreeBSD driver

* built as is.
* untested, some interrupt handler changes might be needed.

----------------------------------------------------------------------------


Other related posts: