[haiku-commits] haiku: hrev51546 - in src: add-ons/kernel/drivers/network/ipro1000/dev/e1000 libs/compat/freebsd11_network libs/compat/freebsd11_network/compat/sys libs/compat/freebsd11_network/compat/net libs/compat/freebsd11_network/compat/dev/pci

  • From: jerome.duval@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 15 Nov 2017 21:25:27 +0100 (CET)

hrev51546 adds 3 changesets to branch 'master'
old head: 9a50e01ea66b83ee7b2b122724ea5e3f3df3d8cb
new head: b3fb200fe3116bc6f94feaf95a2149372b3e1dc0
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=b3fb200fe311+%5E9a50e01ea66b

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

f9a21cf8ba5b: freebsd11_network: copy freebsd_network from 9.3.

078cb1083454: freebsd11_network: adapt code based on needs of the e1000 R11.1 
driver.

b3fb200fe311: ipro1000: Update with the 11.1 release of the e1000 driver.
  
  * switch compat layer.
  * tested on Qemu and Intel I217-LM.

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

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

173 files changed, 26681 insertions(+), 3207 deletions(-)
.../drivers/network/ipro1000/dev/e1000/Jamfile   |    4 +-
.../ipro1000/dev/e1000/e1000_80003es2lan.c       |  381 ++--
.../ipro1000/dev/e1000/e1000_80003es2lan.h       |   12 +-
.../network/ipro1000/dev/e1000/e1000_82540.c     |   12 +-
.../network/ipro1000/dev/e1000/e1000_82541.c     |  299 ++-
.../network/ipro1000/dev/e1000/e1000_82541.h     |   76 +-
.../network/ipro1000/dev/e1000/e1000_82542.c     |   49 +-
.../network/ipro1000/dev/e1000/e1000_82543.c     |  153 +-
.../network/ipro1000/dev/e1000/e1000_82543.h     |   28 +-
.../network/ipro1000/dev/e1000/e1000_82571.c     |   37 +-
.../network/ipro1000/dev/e1000/e1000_82571.h     |   35 +-
.../network/ipro1000/dev/e1000/e1000_82575.c     |  618 +++++-
.../network/ipro1000/dev/e1000/e1000_82575.h     |   12 +-
.../network/ipro1000/dev/e1000/e1000_api.c       |   31 +-
.../network/ipro1000/dev/e1000/e1000_api.h       |   20 +-
.../network/ipro1000/dev/e1000/e1000_defines.h   |   68 +-
.../network/ipro1000/dev/e1000/e1000_hw.h        |   54 +-
.../network/ipro1000/dev/e1000/e1000_i210.c      |  392 +++-
.../network/ipro1000/dev/e1000/e1000_i210.h      |   23 +-
.../network/ipro1000/dev/e1000/e1000_ich8lan.c   | 2009 ++++++++++++++----
.../network/ipro1000/dev/e1000/e1000_ich8lan.h   |  105 +-
.../network/ipro1000/dev/e1000/e1000_mac.c       |   55 +-
.../network/ipro1000/dev/e1000/e1000_mac.h       |    5 +-
.../network/ipro1000/dev/e1000/e1000_manage.c    |   10 +-
.../network/ipro1000/dev/e1000/e1000_manage.h    |    2 +-
.../network/ipro1000/dev/e1000/e1000_mbx.c       |   71 +-
.../network/ipro1000/dev/e1000/e1000_mbx.h       |   78 +-
.../network/ipro1000/dev/e1000/e1000_nvm.c       |   26 +-
.../network/ipro1000/dev/e1000/e1000_nvm.h       |    4 +-
.../network/ipro1000/dev/e1000/e1000_osdep.c     |    2 +-
.../network/ipro1000/dev/e1000/e1000_osdep.h     |   32 +-
.../network/ipro1000/dev/e1000/e1000_phy.c       |  324 ++-
.../network/ipro1000/dev/e1000/e1000_phy.h       |   22 +-
.../network/ipro1000/dev/e1000/e1000_regs.h      |   31 +-
.../network/ipro1000/dev/e1000/e1000_vf.c        |   15 +-
.../network/ipro1000/dev/e1000/e1000_vf.h        |  108 +-
.../drivers/network/ipro1000/dev/e1000/if_em.c   | 1798 ++++++++++------
.../drivers/network/ipro1000/dev/e1000/if_em.h   |   93 +-
.../drivers/network/ipro1000/dev/e1000/if_igb.c  | 1740 +++++++++------
.../drivers/network/ipro1000/dev/e1000/if_igb.h  |  332 +--
.../drivers/network/ipro1000/dev/e1000/if_lem.c  |  687 ++++--
.../drivers/network/ipro1000/dev/e1000/if_lem.h  |   46 +-
src/libs/compat/Jamfile                          |    1 +
src/libs/compat/freebsd11_network/Condvar.cpp    |   81 +
src/libs/compat/freebsd11_network/Condvar.h      |   26 +
src/libs/compat/freebsd11_network/Jamfile        |   66 +
src/libs/compat/freebsd11_network/Unit.cpp       |   59 +
src/libs/compat/freebsd11_network/bus.cpp        |  950 +++++++++
src/libs/compat/freebsd11_network/callout.cpp    |  238 +++
src/libs/compat/freebsd11_network/clock.c        |   44 +
src/libs/compat/freebsd11_network/compat.c       |  659 ++++++
.../freebsd11_network/compat/altq/if_altq.h      |   43 +
.../freebsd11_network/compat/dev/mii/mii.h       |  202 ++
.../compat/dev/mii/mii_bitbang.h                 |   54 +
.../freebsd11_network/compat/dev/mii/miidevs     |  325 +++
.../freebsd11_network/compat/dev/mii/miivar.h    |  315 +++
.../freebsd11_network/compat/dev/ofw/openfirm.h  |    0
.../freebsd11_network/compat/dev/pci/pcireg.h    |  988 +++++++++
.../freebsd11_network/compat/dev/pci/pcivar.h    |   69 +
.../freebsd11_network/compat/machine/_bus.h      |   32 +
.../freebsd11_network/compat/machine/atomic.h    |   32 +
.../freebsd11_network/compat/machine/bus.h       |  349 +++
.../freebsd11_network/compat/machine/bus_dma.h   |   11 +
.../freebsd11_network/compat/machine/clock.h     |    9 +
.../freebsd11_network/compat/machine/cpufunc.h   |   43 +
.../freebsd11_network/compat/machine/endian.h    |   12 +
.../freebsd11_network/compat/machine/in_cksum.h  |   32 +
.../freebsd11_network/compat/machine/md_var.h    |    0
.../compat/machine/ofw_machdep.h                 |    0
.../freebsd11_network/compat/machine/resource.h  |   14 +
.../freebsd11_network/compat/machine/stdarg.h    |   12 +
.../compat/freebsd11_network/compat/miibus_if.h  |    0
.../compat/freebsd11_network/compat/net/bpf.h    |   32 +
.../freebsd11_network/compat/net/ethernet.h      |  405 ++++
.../compat/freebsd11_network/compat/net/if.h     |  110 +
.../compat/freebsd11_network/compat/net/if_arp.h |  115 +
.../compat/freebsd11_network/compat/net/if_llc.h |  161 ++
.../freebsd11_network/compat/net/if_media.h      |  672 ++++++
.../freebsd11_network/compat/net/if_types.h      |   14 +
.../compat/freebsd11_network/compat/net/if_var.h |  841 ++++++++
.../freebsd11_network/compat/net/if_vlan_var.h   |  135 ++
.../compat/freebsd11_network/compat/net/route.h  |   24 +
.../compat/freebsd11_network/compat/net/vnet.h   |  496 +++++
.../freebsd11_network/compat/netinet/if_ether.h  |   13 +
.../freebsd11_network/compat/netinet/in_systm.h  |    0
.../freebsd11_network/compat/netinet/in_var.h    |   11 +
.../compat/security/mac/mac_framework.h          |    9 +
.../freebsd11_network/compat/sys/_bus_dma.h      |   62 +
.../compat/freebsd11_network/compat/sys/_mutex.h |   26 +
.../compat/freebsd11_network/compat/sys/_task.h  |   24 +
.../freebsd11_network/compat/sys/_timeval.h      |   11 +
.../compat/freebsd11_network/compat/sys/_types.h |   20 +
.../compat/freebsd11_network/compat/sys/bus.h    |  159 ++
.../freebsd11_network/compat/sys/bus_dma.h       |  271 +++
.../freebsd11_network/compat/sys/callout.h       |   45 +
.../compat/freebsd11_network/compat/sys/cdefs.h  |  310 +++
.../freebsd11_network/compat/sys/condvar.h       |   31 +
.../freebsd11_network/compat/sys/counter.h       |   12 +
.../compat/freebsd11_network/compat/sys/ctype.h  |   11 +
[ *** stats truncated: 74 lines dropped *** ]

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

Commit:      f9a21cf8ba5b5230f3a3e4fdc52144769854d832
URL:         http://cgit.haiku-os.org/haiku/commit/?id=f9a21cf8ba5b
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Tue Nov 14 20:20:20 2017 UTC

freebsd11_network: copy freebsd_network from 9.3.

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

diff --git a/src/libs/compat/freebsd11_network/Condvar.cpp 
b/src/libs/compat/freebsd11_network/Condvar.cpp
new file mode 100644
index 0000000..9cb5be1
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/Condvar.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2009 Colin Günther, coling@xxxxxx
+ * All Rights Reserved. Distributed under the terms of the MIT License.
+ */
+
+
+extern "C" {
+#include <compat/sys/condvar.h>
+#include <compat/sys/kernel.h>
+}
+
+#include "Condvar.h"
+
+
+void
+conditionInit(struct cv* variable, const char* description)
+{
+       variable->condition.Init(variable, description);
+}
+
+
+void
+conditionPublish(struct cv* variable, const void* waitChannel,
+       const char* description)
+{
+       variable->condition.Publish(waitChannel, description);
+}
+
+
+void
+conditionUnpublish(struct cv* variable)
+{
+       variable->condition.Unpublish();
+}
+
+
+int
+conditionTimedWait(struct cv* variable, const int timeout)
+{
+       status_t status = variable->condition.Wait(B_RELATIVE_TIMEOUT,
+               ticks_to_usecs(timeout));
+
+       if (status != B_OK)
+               status = EWOULDBLOCK;
+       return status;
+}
+
+
+void
+conditionWait(struct cv* variable)
+{
+       variable->condition.Wait();
+}
+
+
+void
+conditionNotifyOne(struct cv* variable)
+{
+       variable->condition.NotifyOne();
+}
+
+
+int
+publishedConditionTimedWait(const void* waitChannel, const int timeout)
+{
+       ConditionVariableEntry variableEntry;
+
+       status_t status = variableEntry.Wait(waitChannel, B_RELATIVE_TIMEOUT,
+               ticks_to_usecs(timeout));
+
+       if (status != B_OK)
+               status = EWOULDBLOCK;
+       return status;
+}
+
+
+void
+publishedConditionNotifyAll(const void* waitChannel)
+{
+       ConditionVariable::NotifyAll(waitChannel, B_OK);
+}
diff --git a/src/libs/compat/freebsd11_network/Condvar.h 
b/src/libs/compat/freebsd11_network/Condvar.h
new file mode 100644
index 0000000..bff1b0d
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/Condvar.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2009 Colin Günther, coling@xxxxxx
+ * All Rights Reserved. Distributed under the terms of the MIT License.
+ */
+#ifndef CONDVAR_H_
+#define CONDVAR_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void conditionInit(struct cv*, const char*);
+void conditionPublish(struct cv*, const void*, const char*);
+void conditionUnpublish(struct cv*);
+int conditionTimedWait(struct cv*, const int);
+void conditionWait(struct cv*);
+void conditionNotifyOne(struct cv*);
+int publishedConditionTimedWait(const void*, const int);
+void publishedConditionNotifyAll(const void*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONDVAR_H_ */
diff --git a/src/libs/compat/freebsd11_network/Jamfile 
b/src/libs/compat/freebsd11_network/Jamfile
new file mode 100644
index 0000000..3d7b496
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/Jamfile
@@ -0,0 +1,65 @@
+SubDir HAIKU_TOP src libs compat freebsd_network ;
+
+UseHeaders [ FDirName $(SUBDIR) ] : true ;
+UseHeaders [ FDirName $(SUBDIR) compat ] : true ;
+UsePrivateHeaders net ;
+UsePrivateKernelHeaders ;
+UseHeaders $(HAIKU_PRIVATE_KERNEL_HEADERS) : true ;
+
+# Enabling C++ structures in C only code
+Includes [ FGristFiles kernel_c++_structs.h ]
+       : <src!system!kernel>kernel_c++_struct_sizes.h ;
+
+SubDirCcFlags [ FDefines _KERNEL=1 _XOPEN_SOURCE ] ;
+
+KernelStaticLibrary libfreebsd_network.a :
+       bus.cpp
+       callout.cpp
+       clock.c
+       compat.c
+       compat_cpp.cpp
+       condvar.c
+       Condvar.cpp
+       device.c
+       driver.c
+       eventhandler.c
+       fbsd_busdma_x86.c
+       fbsd_ether.c
+       fbsd_if_media.c
+       fbsd_mbuf.c
+       fbsd_mbuf2.c
+       fbsd_mii.c
+       fbsd_mii_bitbang.c
+       fbsd_mii_physubr.c
+       fbsd_time.c
+       firmware.c
+       if.c
+       libkern.c
+       mbuf.c
+       mii.c
+       mutex.c
+       priv.cpp
+       synch.c
+       systm.c
+       taskqueue.c
+       unit.c
+       Unit.cpp
+       ;
+
+rule MIIHeaderGen
+{
+       SEARCH on $(2) = [ FDirName $(SUBDIR) compat dev mii ] ;
+       SEARCH on $(3) = $(SEARCH_SOURCE) ;
+
+       Depends $(1) : $(2) $(3) ;
+       MakeLocateArch $(<) ;
+       MIIHeaderGen1 $(1) : $(2) $(3) ;
+       LocalClean clean : $(<) ;
+}
+
+actions MIIHeaderGen1
+{
+       gawk -v HEADERFILE=$(1) -f $(2[2]) $(2[1])
+}
+
+MIIHeaderGen [ FGristFiles miidevs.h ] : miidevs : miidevs2h.awk ;
diff --git a/src/libs/compat/freebsd11_network/Unit.cpp 
b/src/libs/compat/freebsd11_network/Unit.cpp
new file mode 100644
index 0000000..390878e
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/Unit.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 Colin Günther, coling@xxxxxx
+ * All Rights Reserved. Distributed under the terms of the MIT License.
+ *
+ */
+
+
+/*! Wrapper functions for accessing the number buffer.*/
+
+
+#include "unit.h"
+
+#include <util/RadixBitmap.h>
+
+
+#define ID_STORE_FULL -1
+
+
+status_t
+_new_unrhdr_buffer(struct unrhdr* idStore, uint32 maxIdCount)
+{
+       status_t status = B_OK;
+
+       idStore->idBuffer = radix_bitmap_create(maxIdCount);
+       if (idStore->idBuffer == NULL)
+               status = B_NO_MEMORY;
+
+       return status;
+}
+
+
+void
+_delete_unrhdr_buffer_locked(struct unrhdr* idStore)
+{
+       radix_bitmap_destroy(idStore->idBuffer);
+}
+
+
+int
+_alloc_unr_locked(struct unrhdr* idStore)
+{
+       radix_slot_t slotIndex;
+       int id = ID_STORE_FULL;
+
+       slotIndex = radix_bitmap_alloc(idStore->idBuffer, 1);
+       if (slotIndex != RADIX_SLOT_NONE)
+               id = slotIndex + idStore->idBias;
+
+       return id;
+}
+
+
+void
+_free_unr_locked(struct unrhdr* idStore, u_int identity)
+{
+       uint32 slotIndex = (int32)identity - idStore->idBias;
+
+       radix_bitmap_dealloc(idStore->idBuffer, slotIndex, 1);
+}
diff --git a/src/libs/compat/freebsd11_network/bus.cpp 
b/src/libs/compat/freebsd11_network/bus.cpp
new file mode 100644
index 0000000..4a77a0a
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/bus.cpp
@@ -0,0 +1,940 @@
+/*
+ * Copyright 2007, Hugo Santos. All Rights Reserved.
+ * Copyright 2004, Marcus Overhagen. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+extern "C" {
+#include "device.h"
+}
+
+#include <stdlib.h>
+
+#include <algorithm>
+
+#include <arch/cpu.h>
+
+extern "C" {
+#include <compat/dev/pci/pcireg.h>
+#include <compat/dev/pci/pcivar.h>
+#include <compat/machine/resource.h>
+#include <compat/sys/mutex.h>
+#include <compat/machine/bus.h>
+#include <compat/sys/rman.h>
+#include <compat/sys/bus.h>
+}
+
+// private kernel header to get B_NO_HANDLED_INFO
+#include <int.h>
+
+#include <PCI_x86.h>
+
+
+//#define DEBUG_BUS_SPACE_RW
+#ifdef DEBUG_BUS_SPACE_RW
+#      define TRACE_BUS_SPACE_RW(x) driver_printf x
+#else
+#      define TRACE_BUS_SPACE_RW(x)
+#endif
+
+//#define DEBUG_PCI
+#ifdef DEBUG_PCI
+#      define TRACE_PCI(dev, format, args...) device_printf(dev, format , 
##args)
+#else
+#      define TRACE_PCI(dev, format, args...) do { } while (0)
+#endif
+
+
+#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
+
+
+struct internal_intr {
+       device_t                dev;
+       driver_filter_t filter;
+       driver_intr_t   *handler;
+       void                    *arg;
+       int                             irq;
+       uint32                  flags;
+
+       thread_id               thread;
+       sem_id                  sem;
+       int32                   handling;
+};
+
+static int32 intr_wrapper(void *data);
+
+
+static int
+fls(int mask)
+{
+       int bit;
+       if (mask == 0)
+               return (0);
+       for (bit = 1; mask != 1; bit++)
+               mask = (unsigned int)mask >> 1;
+       return (bit);
+}
+
+
+static area_id
+map_mem(void **virtualAddr, phys_addr_t _phy, size_t size, uint32 protection,
+       const char *name)
+{
+       uint32 offset = _phy & (B_PAGE_SIZE - 1);
+       phys_addr_t physicalAddr = _phy - offset;
+       area_id area;
+
+       size = ROUNDUP(size + offset, B_PAGE_SIZE);
+       area = map_physical_memory(name, physicalAddr, size, 
B_ANY_KERNEL_ADDRESS,
+               protection, virtualAddr);
+       if (area < B_OK)
+               return area;
+
+       *virtualAddr = (uint8 *)(*virtualAddr) + offset;
+
+       return area;
+}
+
+
+static int
+bus_alloc_irq_resource(device_t dev, struct resource *res)
+{
+       uint8 irq = pci_read_config(dev, PCI_interrupt_line, 1);
+       if (irq == 0 || irq == 0xff)
+               return -1;
+
+       /* TODO: IRQ resources! */
+       res->r_bustag = 0;
+       res->r_bushandle = irq;
+
+       return 0;
+}
+
+
+static int
+bus_alloc_mem_resource(device_t dev, struct resource *res, int regid)
+{
+       uint32 addr = pci_read_config(dev, regid, 4) & 
PCI_address_memory_32_mask;
+       uint32 size = 128 * 1024; /* XXX */
+       void *virtualAddr;
+
+       res->r_mapped_area = map_mem(&virtualAddr, addr, size, 0,
+               "bus_alloc_resource(MEMORY)");
+       if (res->r_mapped_area < B_OK)
+               return -1;
+
+       res->r_bustag = I386_BUS_SPACE_MEM;
+       res->r_bushandle = (bus_space_handle_t)virtualAddr;
+       return 0;
+}
+
+
+static int
+bus_alloc_ioport_resource(device_t dev, struct resource *res, int regid)
+{
+       res->r_bustag = I386_BUS_SPACE_IO;
+       res->r_bushandle = pci_read_config(dev, regid, 4) & PCI_address_io_mask;
+       return 0;
+}
+
+
+struct resource *
+bus_alloc_resource(device_t dev, int type, int *rid, unsigned long start,
+       unsigned long end, unsigned long count, uint32 flags)
+{
+       struct resource *res;
+       int result = -1;
+
+       if (type != SYS_RES_IRQ && type != SYS_RES_MEMORY
+               && type != SYS_RES_IOPORT)
+               return NULL;
+
+       device_printf(dev, "bus_alloc_resource(%i, [%i], 0x%lx, 0x%lx, 0x%lx,"
+               "0x%" B_PRIx32 ")\n", type, *rid, start, end, count, flags);
+
+       // maybe a local array of resources is enough
+       res = (struct resource *)malloc(sizeof(struct resource));
+       if (res == NULL)
+               return NULL;
+
+       if (type == SYS_RES_IRQ) {
+               if (*rid == 0) {
+                       // pinned interrupt
+                       result = bus_alloc_irq_resource(dev, res);
+               } else {
+                       // msi or msi-x interrupt at index *rid - 1
+                       pci_info *info;
+                       info = &((struct root_device_softc 
*)dev->root->softc)->pci_info;
+                       res->r_bustag = 1;
+                       res->r_bushandle = info->u.h0.interrupt_line + *rid - 1;
+                       result = 0;
+               }
+       } else if (type == SYS_RES_MEMORY)
+               result = bus_alloc_mem_resource(dev, res, *rid);
+       else if (type == SYS_RES_IOPORT)
+               result = bus_alloc_ioport_resource(dev, res, *rid);
+
+       if (result < 0) {
+               free(res);
+               return NULL;
+       }
+
+       res->r_type = type;
+       return res;
+}
+
+
+int
+bus_release_resource(device_t dev, int type, int rid, struct resource *res)
+{
+       if (res->r_type != type)
+               panic("bus_release_resource: mismatch");
+
+       if (type == SYS_RES_MEMORY)
+               delete_area(res->r_mapped_area);
+
+       free(res);
+       return 0;
+}
+
+
+int
+bus_alloc_resources(device_t dev, struct resource_spec *resourceSpec,
+       struct resource **resources)
+{
+       int i;
+
+       for (i = 0; resourceSpec[i].type != -1; i++) {
+               resources[i] = bus_alloc_resource_any(dev,
+                       resourceSpec[i].type, &resourceSpec[i].rid, 
resourceSpec[i].flags);
+               if (resources[i] == NULL
+                       && (resourceSpec[i].flags & RF_OPTIONAL) == 0) {
+                       for (++i; resourceSpec[i].type != -1; i++) {
+                               resources[i] = NULL;
+                       }
+
+                       bus_release_resources(dev, resourceSpec, resources);
+                       return ENXIO;
+               }
+       }
+       return 0;
+}
+
+
+void
+bus_release_resources(device_t dev, const struct resource_spec *resourceSpec,
+       struct resource **resources)
+{
+       int i;
+
+       for (i = 0; resourceSpec[i].type != -1; i++) {
+               if (resources[i] == NULL)
+                       continue;
+
+               bus_release_resource(dev, resourceSpec[i].type, 
resourceSpec[i].rid,
+                       resources[i]);
+               resources[i] = NULL;
+       }
+}
+
+
+bus_space_handle_t
+rman_get_bushandle(struct resource *res)
+{
+       return res->r_bushandle;
+}
+
+
+bus_space_tag_t
+rman_get_bustag(struct resource *res)
+{
+       return res->r_bustag;
+}
+
+
+int
+rman_get_rid(struct resource *res)
+{
+       return 0;
+}
+
+
+//     #pragma mark - Interrupt handling
+
+
+static int32
+intr_wrapper(void *data)
+{
+       struct internal_intr *intr = (struct internal_intr *)data;
+
+       //device_printf(intr->dev, "in interrupt handler.\n");
+
+       if (!HAIKU_CHECK_DISABLE_INTERRUPTS(intr->dev))
+               return B_UNHANDLED_INTERRUPT;
+
+       release_sem_etc(intr->sem, 1, B_DO_NOT_RESCHEDULE);
+       return intr->handling ? B_HANDLED_INTERRUPT : B_INVOKE_SCHEDULER;
+}
+
+
+static int32
+intr_fast_wrapper(void *data)
+{
+       struct internal_intr *intr = (struct internal_intr *)data;
+
+       intr->handler(intr->arg);
+
+       // We don't know if the interrupt has been handled.
+       return B_UNHANDLED_INTERRUPT;
+}
+
+
+static int32
+intr_handler(void *data)
+{
+       struct internal_intr *intr = (struct internal_intr *)data;
+       status_t status;
+
+       while (1) {
+               status = acquire_sem(intr->sem);
+               if (status < B_OK)
+                       break;
+
+               //device_printf(intr->dev, "in soft interrupt handler.\n");
+
+               atomic_or(&intr->handling, 1);
+               intr->handler(intr->arg);
+               atomic_and(&intr->handling, 0);
+               HAIKU_REENABLE_INTERRUPTS(intr->dev);
+       }
+
+       return 0;
+}
+
+
+static void
+free_internal_intr(struct internal_intr *intr)
+{
+       if (intr->sem >= B_OK) {
+               status_t status;
+               delete_sem(intr->sem);
+               wait_for_thread(intr->thread, &status);
+       }
+
+       free(intr);
+}
+
+
+int
+bus_setup_intr(device_t dev, struct resource *res, int flags,
+       driver_filter_t filter, driver_intr_t handler, void *arg, void 
**_cookie)
+{
+       /* TODO check MPSAFE etc */
+
+       struct internal_intr *intr = (struct internal_intr *)malloc(
+               sizeof(struct internal_intr));
+       char semName[64];
+       status_t status;
+
+       if (intr == NULL)
+               return B_NO_MEMORY;
+
+       intr->dev = dev;
+       intr->filter = filter;
+       intr->handler = handler;
+       intr->arg = arg;
+       intr->irq = res->r_bushandle;
+       intr->flags = flags;
+       intr->sem = -1;
+       intr->thread = -1;
+
+       if (filter != NULL) {
+               status = install_io_interrupt_handler(intr->irq,
+                       (interrupt_handler)intr->filter, intr->arg, 0);
+       } else if ((flags & INTR_FAST) != 0) {
+               status = install_io_interrupt_handler(intr->irq,
+                       intr_fast_wrapper, intr, B_NO_HANDLED_INFO);
+       } else {
+               snprintf(semName, sizeof(semName), "%s intr", dev->device_name);
+
+               intr->sem = create_sem(0, semName);
+               if (intr->sem < B_OK) {
+                       free(intr);
+                       return B_NO_MEMORY;
+               }
+
+               snprintf(semName, sizeof(semName), "%s intr handler", 
dev->device_name);
+
+               intr->thread = spawn_kernel_thread(intr_handler, semName,
+                       B_REAL_TIME_DISPLAY_PRIORITY, intr);
+               if (intr->thread < B_OK) {
+                       delete_sem(intr->sem);
+                       free(intr);
+                       return B_NO_MEMORY;
+               }
+
+               status = install_io_interrupt_handler(intr->irq,
+                       intr_wrapper, intr, B_NO_HANDLED_INFO);
+       }
+
+       if (status == B_OK && res->r_bustag == 1 && gPCIx86 != NULL) {
+               // this is an msi, enable it
+               pci_info *info
+                       = &((struct root_device_softc 
*)dev->root->softc)->pci_info;
+               if (((struct root_device_softc *)dev->root->softc)->is_msi) {
+                       if (gPCIx86->enable_msi(info->bus, info->device,
+                                       info->function) != B_OK) {
+                               device_printf(dev, "enabling msi failed\n");
+                               bus_teardown_intr(dev, res, intr);
+                               return ENODEV;
+                       }
+               } else if (((struct root_device_softc 
*)dev->root->softc)->is_msix) {
+                       if (gPCIx86->enable_msix(info->bus, info->device,
+                                       info->function) != B_OK) {
+                               device_printf(dev, "enabling msix failed\n");
+                               bus_teardown_intr(dev, res, intr);
+                               return ENODEV;
+                       }
+               }
+       }
+
+       if (status < B_OK) {
+               free_internal_intr(intr);
+               return status;
+       }
+
+       resume_thread(intr->thread);
+
+       *_cookie = intr;
+       return 0;
+}
+
+
+int
+bus_teardown_intr(device_t dev, struct resource *res, void *arg)
+{
+       struct internal_intr *intr = (struct internal_intr *)arg;
+       struct root_device_softc *root = (struct root_device_softc 
*)dev->root->softc;
+
+       if ((root->is_msi || root->is_msix) && gPCIx86 != NULL) {
+               // disable msi generation
+               pci_info *info = &root->pci_info;
+               gPCIx86->disable_msi(info->bus, info->device, info->function);
+       }
+
+       if (intr->filter != NULL) {
+               remove_io_interrupt_handler(intr->irq, 
(interrupt_handler)intr->filter,
+                       intr->arg);
+       } else if (intr->flags & INTR_FAST) {
+               remove_io_interrupt_handler(intr->irq, intr_fast_wrapper, intr);
+       } else {
+               remove_io_interrupt_handler(intr->irq, intr_wrapper, intr);
+       }
+
+       free_internal_intr(intr);
+       return 0;
+}
+
+
+//     #pragma mark - bus functions
+
+
+bus_dma_tag_t
+bus_get_dma_tag(device_t dev)
+{
+       return NULL;
+}
+
+
+int
+bus_generic_suspend(device_t dev)
+{
+       UNIMPLEMENTED();
+       return B_ERROR;
+}
+
+
+int
+bus_generic_resume(device_t dev)
+{
+       UNIMPLEMENTED();
+       return B_ERROR;
+}
+
+
+void
+bus_generic_shutdown(device_t dev)
+{
+       UNIMPLEMENTED();
+}
+
+
+int
+bus_print_child_header(device_t dev, device_t child)
+{
+       UNIMPLEMENTED();
+       return B_ERROR;
+}
+
+
+int
+bus_print_child_footer(device_t dev, device_t child)
+{
+       UNIMPLEMENTED();
+       return B_ERROR;
+}
+
+
+int
+bus_generic_print_child(device_t dev, device_t child)
+{
+       UNIMPLEMENTED();
+       return B_ERROR;
+}
+
+
+void
+bus_generic_driver_added(device_t dev, driver_t *driver)
+{
+       UNIMPLEMENTED();
+}
+
+
+int
+bus_child_present(device_t child)
+{
+       device_t parent = device_get_parent(child);
+       if (parent == NULL)
+               return 0;
+
+       return bus_child_present(parent);
+}
+
+
+//     #pragma mark - PCI functions
+
+
+uint32_t
+pci_read_config(device_t dev, int offset, int size)
+{
+       pci_info *info = &((struct root_device_softc 
*)dev->root->softc)->pci_info;
+
+       uint32_t value = gPci->read_pci_config(info->bus, info->device,
+               info->function, offset, size);
+       TRACE_PCI(dev, "pci_read_config(%i, %i) = 0x%x\n", offset, size, value);
+       return value;
+}
+
+
+void
+pci_write_config(device_t dev, int offset, uint32_t value, int size)
+{
+       pci_info *info = &((struct root_device_softc 
*)dev->root->softc)->pci_info;
+
+       TRACE_PCI(dev, "pci_write_config(%i, 0x%x, %i)\n", offset, value, size);
+
+       gPci->write_pci_config(info->bus, info->device, info->function, offset,
+               size, value);
+}
+
+
+uint16_t
+pci_get_vendor(device_t dev)
+{
+       return pci_read_config(dev, PCI_vendor_id, 2);
+}
+
+
+uint16_t
+pci_get_device(device_t dev)
+{
+       return pci_read_config(dev, PCI_device_id, 2);
+}
+
+
+uint16_t
+pci_get_subvendor(device_t dev)
+{
+       return pci_read_config(dev, PCI_subsystem_vendor_id, 2);
+}
+
+
+uint16_t
+pci_get_subdevice(device_t dev)
+{
+       return pci_read_config(dev, PCI_subsystem_id, 2);
+}
+
+
+uint8_t
+pci_get_revid(device_t dev)
+{
+       return pci_read_config(dev, PCI_revision, 1);
+}
+
+
+uint32_t
+pci_get_domain(device_t dev)
+{
+       return 0;
+}
+
+uint32_t
+pci_get_devid(device_t dev)
+{
+       return pci_read_config(dev, PCI_device_id, 2) << 16 |
+               pci_read_config(dev, PCI_vendor_id, 2);
+}
+
+uint8_t
+pci_get_cachelnsz(device_t dev)
+{
+       return pci_read_config(dev, PCI_line_size, 1);
+}
+
+uint8_t *
+pci_get_ether(device_t dev)
+{
+       /* used in if_dc to get the MAC from CardBus CIS for Xircom card */
+       return NULL; /* NULL is handled in the caller correctly */
+}
+
+uint8_t
+pci_get_bus(device_t dev)
+{
+       pci_info *info
+               = &((struct root_device_softc *)dev->root->softc)->pci_info;
+       return info->bus;
+}
+
+
+uint8_t
+pci_get_slot(device_t dev)
+{
+       pci_info *info
+               = &((struct root_device_softc *)dev->root->softc)->pci_info;
+       return info->device;
+}
+
+
+uint8_t
+pci_get_function(device_t dev)
+{
+       pci_info *info
+               = &((struct root_device_softc *)dev->root->softc)->pci_info;
+       return info->function;
+}
+
+
+device_t
+pci_find_dbsf(uint32_t domain, uint8_t bus, uint8_t slot, uint8_t func)
+{
+       // We don't support that yet - if we want to support the multi port
+       // feature of the Broadcom BCM 570x driver, we would have to change
+       // that.
+       return NULL;
+}
+
+
+static void
+pci_set_command_bit(device_t dev, uint16_t bit)
+{
+       uint16_t command = pci_read_config(dev, PCI_command, 2);
+       pci_write_config(dev, PCI_command, command | bit, 2);
+}
+
+
+int
+pci_enable_busmaster(device_t dev)
+{
+       pci_set_command_bit(dev, PCI_command_master);
+       return 0;
+}
+
+
+int
+pci_enable_io(device_t dev, int space)
+{
+       /* adapted from FreeBSD's pci_enable_io_method */
+       int bit = 0;
+
+       switch (space) {
+               case SYS_RES_IOPORT:
+                       bit = PCI_command_io;
+                       break;
+               case SYS_RES_MEMORY:
+                       bit = PCI_command_memory;
+                       break;
+               default:
+                       return EINVAL;
+       }
+
+       pci_set_command_bit(dev, bit);
+       if (pci_read_config(dev, PCI_command, 2) & bit)
+               return 0;
+
+       device_printf(dev, "pci_enable_io(%d) failed.\n", space);
+
+       return ENXIO;
+}
+
+
+int
+pci_find_cap(device_t dev, int capability, int *capreg)
+{
+       return pci_find_extcap(dev, capability, capreg);
+}
+
+
+int
+pci_find_extcap(device_t child, int capability, int *_capabilityRegister)
+{
+       uint8 capabilityPointer;
+       uint8 headerType;
+       uint16 status;
+
+       status = pci_read_config(child, PCIR_STATUS, 2);
+       if ((status & PCIM_STATUS_CAPPRESENT) == 0)
+               return ENXIO;
+
+       headerType = pci_read_config(child, PCI_header_type, 1);
+       switch (headerType & PCIM_HDRTYPE) {
+               case 0:
+               case 1:
+                       capabilityPointer = PCIR_CAP_PTR;
+                       break;
+               case 2:
+                       capabilityPointer = PCIR_CAP_PTR_2;
+                       break;
+               default:
+                       return ENXIO;
+       }
+       capabilityPointer = pci_read_config(child, capabilityPointer, 1);
+
+       while (capabilityPointer != 0) {
+               if (pci_read_config(child, capabilityPointer + PCICAP_ID, 1)
+                               == capability) {
+                       if (_capabilityRegister != NULL)
+                               *_capabilityRegister = capabilityPointer;
+                       return 0;
+               }
+               capabilityPointer = pci_read_config(child,
+                       capabilityPointer + PCICAP_NEXTPTR, 1);
+       }
+
+       return ENOENT;
+}
+
+
+int
+pci_msi_count(device_t dev)
+{
+       pci_info *info;
+       if (gPCIx86 == NULL)
+               return 0;
+
+       info = &((struct root_device_softc *)dev->root->softc)->pci_info;
+       return gPCIx86->get_msi_count(info->bus, info->device, info->function);
+}
+
+
+int
+pci_alloc_msi(device_t dev, int *count)
+{
+       pci_info *info;
+       uint8 startVector = 0;
+       if (gPCIx86 == NULL)
+               return ENODEV;
+
+       info = &((struct root_device_softc *)dev->root->softc)->pci_info;
+
+       if (gPCIx86->configure_msi(info->bus, info->device, info->function, 
*count,
+                       &startVector) != B_OK) {
+               return ENODEV;
+       }
+
+       ((struct root_device_softc *)dev->root->softc)->is_msi = true;
+       info->u.h0.interrupt_line = startVector;
+       return EOK;
+}
+
+
+int
+pci_release_msi(device_t dev)
+{
+       pci_info *info;
+       if (gPCIx86 == NULL)
+               return ENODEV;
+
+       info = &((struct root_device_softc *)dev->root->softc)->pci_info;
+       gPCIx86->unconfigure_msi(info->bus, info->device, info->function);
+       ((struct root_device_softc *)dev->root->softc)->is_msi = false;
+       ((struct root_device_softc *)dev->root->softc)->is_msix = false;
+       return EOK;
+}
+
+
+int
+pci_msix_count(device_t dev)
+{
+       pci_info *info;
+       if (gPCIx86 == NULL)
+               return 0;
+
+       info = &((struct root_device_softc *)dev->root->softc)->pci_info;
+       return gPCIx86->get_msix_count(info->bus, info->device, info->function);
+}
+
+
+int
+pci_alloc_msix(device_t dev, int *count)
+{
+       pci_info *info;
+       uint8 startVector = 0;
+       if (gPCIx86 == NULL)
+               return ENODEV;
+
+       info = &((struct root_device_softc *)dev->root->softc)->pci_info;
+
+       if (gPCIx86->configure_msix(info->bus, info->device, info->function, 
*count,
+                       &startVector) != B_OK) {
+               return ENODEV;
+       }
+
+       ((struct root_device_softc *)dev->root->softc)->is_msix = true;
+       info->u.h0.interrupt_line = startVector;
+       return EOK;
+}
+
+
+int
+pci_get_max_read_req(device_t dev)
+{
+       int cap;
+       uint16_t val;
+
+       if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) != 0)
+               return (0);
+       val = pci_read_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, 2);
+       val &= PCIM_EXP_CTL_MAX_READ_REQUEST;
+       val >>= 12;
+       return (1 << (val + 7));
+}
+
+
+int
+pci_set_max_read_req(device_t dev, int size)
+{
+       int cap;
+       uint16_t val;
+
+       if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) != 0)
+               return (0);
+       if (size < 128)
+               size = 128;
+       if (size > 4096)
+               size = 4096;
+       size = (1 << (fls(size) - 1));
+       val = pci_read_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, 2);
+       val &= ~PCIM_EXP_CTL_MAX_READ_REQUEST;
+       val |= (fls(size) - 8) << 12;
+       pci_write_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, val, 2);
+       return (size);
+}
+
+
+int
+pci_get_powerstate(device_t dev)
+{
+       int capabilityRegister;
+       uint16 status;
+       int powerState = PCI_POWERSTATE_D0;
+
+       if (pci_find_extcap(dev, PCIY_PMG, &capabilityRegister) != EOK)
+               return powerState;
+
+       status = pci_read_config(dev, capabilityRegister + PCIR_POWER_STATUS, 
2);
+       switch (status & PCI_pm_mask) {
+               case PCI_pm_state_d0:
+                       break;
+               case PCI_pm_state_d1:
+                       powerState = PCI_POWERSTATE_D1;
+                       break;
+               case PCI_pm_state_d2:
+                       powerState = PCI_POWERSTATE_D2;
+                       break;
+               case PCI_pm_state_d3:
+                       powerState = PCI_POWERSTATE_D3;
+                       break;
+               default:
+                       powerState = PCI_POWERSTATE_UNKNOWN;
+                       break;
+       }
+
+       TRACE_PCI(dev, "%s: D%i\n", __func__, powerState);
+       return powerState;
+}
+
+
+int
+pci_set_powerstate(device_t dev, int newPowerState)
+{
+       int capabilityRegister;
+       int oldPowerState;
+       uint8 currentPowerManagementStatus;
+       uint8 newPowerManagementStatus;
+       uint16 powerManagementCapabilities;
+       bigtime_t stateTransitionDelayInUs = 0;
+
+       if (pci_find_extcap(dev, PCIY_PMG, &capabilityRegister) != EOK)
+               return EOPNOTSUPP;
+
+       oldPowerState = pci_get_powerstate(dev);
+       if (oldPowerState == newPowerState)
+               return EOK;
+
+       switch (std::max(oldPowerState, newPowerState)) {
+               case PCI_POWERSTATE_D2:
+                       stateTransitionDelayInUs = 200;
+                       break;
+               case PCI_POWERSTATE_D3:
+                       stateTransitionDelayInUs = 10000;
+                       break;
+       }
+
+       currentPowerManagementStatus = pci_read_config(dev, capabilityRegister
+               + PCIR_POWER_STATUS, 2);
+       newPowerManagementStatus = currentPowerManagementStatus & ~PCI_pm_mask;
+       powerManagementCapabilities = pci_read_config(dev, capabilityRegister
+               + PCIR_POWER_CAP, 2);
+
+       switch (newPowerState) {
+               case PCI_POWERSTATE_D0:
+                       newPowerManagementStatus |= PCIM_PSTAT_D0;
+                       break;
+               case PCI_POWERSTATE_D1:
+                       if ((powerManagementCapabilities & PCI_pm_d1supp) == 0)
+                               return EOPNOTSUPP;
+                       newPowerManagementStatus |= PCIM_PSTAT_D1;
+                       break;
+               case PCI_POWERSTATE_D2:
+                       if ((powerManagementCapabilities & PCI_pm_d2supp) == 0)
+                               return EOPNOTSUPP;
+                       newPowerManagementStatus |= PCIM_PSTAT_D2;
+                       break;
+               case PCI_POWERSTATE_D3:
+                       newPowerManagementStatus |= PCIM_PSTAT_D3;
+                       break;
+               default:
+                       return EINVAL;
+       }
+
+       TRACE_PCI(dev, "%s: D%i -> D%i\n", __func__, oldPowerState, 
newPowerState);
+       pci_write_config(dev, capabilityRegister + PCIR_POWER_STATUS, 
newPowerState,
+               2);
+       if (stateTransitionDelayInUs != 0)
+               snooze(stateTransitionDelayInUs);
+
+       return EOK;
+}
diff --git a/src/libs/compat/freebsd11_network/callout.cpp 
b/src/libs/compat/freebsd11_network/callout.cpp
new file mode 100644
index 0000000..c80938b
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/callout.cpp
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "device.h"
+
+#include <lock.h>
+#include <thread.h>
+
+extern "C" {
+#      include <sys/callout.h>
+#      include <sys/mutex.h>
+}
+
+#include <util/AutoLock.h>
+
+
+//#define TRACE_CALLOUT
+#ifdef TRACE_CALLOUT
+#      define TRACE(x...) dprintf(x)
+#else
+#      define TRACE(x...) ;
+#endif
+
+
+static struct list sTimers;
+static mutex sLock;
+static sem_id sWaitSem;
+static callout* sCurrentCallout;
+static thread_id sThread;
+static bigtime_t sTimeout;
+
+
+static status_t
+callout_thread(void* /*data*/)
+{
+       status_t status = B_OK;
+
+       do {
+               bigtime_t timeout = B_INFINITE_TIMEOUT;
+
+               if (status == B_TIMED_OUT || status == B_OK) {
+                       // scan timers for new timeout and/or execute a timer
+                       mutex_lock(&sLock);
+
+                       struct callout* c = NULL;
+                       while (true) {
+                               c = (callout*)list_get_next_item(&sTimers, c);
+                               if (c == NULL)
+                                       break;
+
+                               if (c->due < system_time()) {
+                                       struct mtx *mutex = c->c_mtx;
+
+                                       // execute timer
+                                       list_remove_item(&sTimers, c);
+                                       c->due = -1;
+                                       sCurrentCallout = c;
+
+                                       mutex_unlock(&sLock);
+
+                                       if (mutex != NULL)
+                                               mtx_lock(mutex);
+
+                                       c->c_func(c->c_arg);
+
+                                       if (mutex != NULL)
+                                               mtx_unlock(mutex);
+
+                                       mutex_lock(&sLock);
+
+                                       sCurrentCallout = NULL;
+                                       c = NULL;
+                                               // restart scanning as we 
unlocked the list
+                               } else {
+                                       // calculate new timeout
+                                       if (c->due < timeout)
+                                               timeout = c->due;
+                               }
+                       }
+
+                       sTimeout = timeout;
+                       mutex_unlock(&sLock);
+               }
+
+               status = acquire_sem_etc(sWaitSem, 1, B_ABSOLUTE_TIMEOUT, 
timeout);
+                       // the wait sem normally can't be acquired, so we
+                       // have to look at the status value the call returns:
+                       //
+                       // B_OK - a new timer has been added or canceled
+                       // B_TIMED_OUT - look for timers to be executed
+                       // B_BAD_SEM_ID - we are asked to quit
+       } while (status != B_BAD_SEM_ID);
+
+       return B_OK;
+}
+
+
+// #pragma mark - private API
+
+
+status_t
+init_callout(void)
+{
+       list_init(&sTimers);
+       sTimeout = B_INFINITE_TIMEOUT;
+
+       status_t status = B_OK;
+       mutex_init(&sLock, "fbsd callout");
+
+       sWaitSem = create_sem(0, "fbsd callout wait");
+       if (sWaitSem < 0) {
+               status = sWaitSem;
+               goto err1;
+       }
+
+       sThread = spawn_kernel_thread(callout_thread, "fbsd callout",
+               B_DISPLAY_PRIORITY, NULL);
+       if (sThread < 0) {
+               status = sThread;
+               goto err2;
+       }
+
+       return resume_thread(sThread);
+
+err1:
+       mutex_destroy(&sLock);
+err2:
+       delete_sem(sWaitSem);
+       return status;
+}
+
+
+void
+uninit_callout(void)
+{
+       delete_sem(sWaitSem);
+       mutex_lock(&sLock);
+
+       mutex_destroy(&sLock);
+
+       status_t status;
+       wait_for_thread(sThread, &status);
+}
+
+
+// #pragma mark - public API
+
+
+void
+callout_init(struct callout *callout, int mpsafe)
+{
+       if (mpsafe)
+               callout_init_mtx(callout, NULL, 0);
+       else
+               callout_init_mtx(callout, &Giant, 0);
+}
+
+
+void
+callout_init_mtx(struct callout *c, struct mtx *mtx, int flags)
+{
+       c->due = 0;
+       c->flags = 0;
+
+       c->c_arg = NULL;
+       c->c_func = NULL;
+       c->c_mtx = mtx;
+       c->c_flags = flags;
+}
+
+
+int
+callout_reset(struct callout *c, int ticks, void (*func)(void *), void *arg)
+{
+       int canceled = callout_stop(c);
+
+       MutexLocker locker(sLock);
+
+       c->c_func = func;
+       c->c_arg = arg;
+
+       TRACE("callout_reset %p, func %p, arg %p\n", c, c->c_func, c->c_arg);
+
+       if (ticks >= 0) {
+               // reschedule or add this timer
+               if (c->due <= 0)
+                       list_add_item(&sTimers, c);
+
+               c->due = system_time() + ticks_to_usecs(ticks);
+
+               // notify timer about the change if necessary
+               if (sTimeout > c->due)
+                       release_sem(sWaitSem);
+       }
+
+       return canceled;
+}
+
+
+int
+callout_schedule(struct callout *callout, int ticks)
+{
+       return callout_reset(callout, ticks, callout->c_func, callout->c_arg);
+}
+
+
+int
+_callout_stop_safe(struct callout *c, int safe)
+{
+       MutexLocker locker(sLock);
+
+       TRACE("_callout_stop_safe %p, func %p, arg %p\n", c, c->c_func, 
c->c_arg);
+
+       if (c->due <= 0)
+               return 0;
+
+       // this timer is scheduled, cancel it
+       list_remove_item(&sTimers, c);
+       c->due = 0;
+       return 1;
+}
+
+
+int
+callout_pending(struct callout *c)
+{
+       return c->due > 0;
+}
+
+
+int
+callout_active(struct callout *c)
+{
+       return c == sCurrentCallout;
+}
diff --git a/src/libs/compat/freebsd11_network/clock.c 
b/src/libs/compat/freebsd11_network/clock.c
new file mode 100644
index 0000000..fce43cc
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/clock.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009, Colin Günther, coling@xxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include "device.h"
+
+#include <compat/sys/kernel.h>
+
+
+int ticks;
+static timer sHardClockTimer;
+
+
+/*!
+ * Implementation of FreeBSD's hardclock timer.
+ */
+static status_t
+hardClock(timer* hardClockTimer)
+{
+       atomic_add((vint32*)&ticks, 1);
+       return B_OK;
+}
+
+
+/*!
+ * Initialization of the hardclock timer which ticks according to hz defined in
+ * compat/sys/kernel.h.
+ */
+status_t
+init_hard_clock()
+{
+       ticks = 0;
+       return add_timer(&sHardClockTimer, hardClock, ticks_to_usecs(1),
+               B_PERIODIC_TIMER);
+}
+
+
+void
+uninit_hard_clock()
+{
+       cancel_timer(&sHardClockTimer);
+}
diff --git a/src/libs/compat/freebsd11_network/compat.c 
b/src/libs/compat/freebsd11_network/compat.c
new file mode 100644
index 0000000..3b40c9f
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/compat.c
@@ -0,0 +1,659 @@
+/*
+ * Copyright 2007, Hugo Santos, hugosantos@xxxxxxxxx. All Rights Reserved.
+ * Copyright 2007, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx. All Rights Reserved.
+ * Copyright 2004, Marcus Overhagen. All Rights Reserved.
+ *
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "device.h"
+
+#include <stdio.h>
+
+#include <KernelExport.h>
+#include <image.h>
+
+#include <util/BitUtils.h>
+
+#include <compat/machine/resource.h>
+#include <compat/dev/mii/mii.h>
+#include <compat/sys/bus.h>
+#include <compat/sys/malloc.h>
+#include <compat/net/if_media.h>
+
+#include <compat/dev/mii/miivar.h>
+
+#include "compat_cpp.h"
+
+
+spinlock __haiku_intr_spinlock;
+
+struct net_stack_module_info *gStack;
+pci_module_info *gPci;
+struct pci_x86_module_info *gPCIx86;
+
+static struct list sRootDevices;
+static int sNextUnit;
+
+//     #pragma mark - private functions
+
+
+static device_t
+init_device(device_t device, driver_t *driver)
+{
+       list_init_etc(&device->children, offsetof(struct device, link));
+       device->unit = sNextUnit++;
+
+       if (driver != NULL && device_set_driver(device, driver) < 0)
+               return NULL;
+
+       return device;
+}
+
+
+static device_t
+new_device(driver_t *driver)
+{
+       device_t dev = malloc(sizeof(struct device));
+       if (dev == NULL)
+               return NULL;
+
+       memset(dev, 0, sizeof(struct device));
+
+       if (init_device(dev, driver) == NULL) {
+               free(dev);
+               return NULL;
+       }
+
+       return dev;
+}
+
+
+static image_id
+find_own_image()
+{
+       int32 cookie = 0;
+       image_info info;
+       while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &info) == B_OK) {
+               if (((addr_t)info.text <= (addr_t)find_own_image
+                       && (addr_t)info.text + (addr_t)info.text_size
+                               > (addr_t)find_own_image)) {
+                       // found our own image
+                       return info.id;
+               }
+       }
+
+       return B_ENTRY_NOT_FOUND;
+}
+
+
+static device_method_signature_t
+resolve_method(driver_t *driver, const char *name)
+{
+       device_method_signature_t method = NULL;
+       int i;
+
+       for (i = 0; method == NULL && driver->methods[i].name != NULL; i++) {
+               if (strcmp(driver->methods[i].name, name) == 0)
+                       method = driver->methods[i].method;
+       }
+
+       return method;
+}
+
+
+//     #pragma mark - Device
+
+
+void
+driver_printf(const char *format, ...)
+{
+       va_list vl;
+       va_start(vl, format);
+       driver_vprintf(format, vl);
+       va_end(vl);
+}
+
+
+static void
+driver_vprintf_etc(const char *extra, const char *format, va_list vl)
+{
+       char buf[256];
+       vsnprintf(buf, sizeof(buf), format, vl);
+
+       if (extra)
+               dprintf("[%s] (%s) %s", gDriverName, extra, buf);
+       else
+               dprintf("[%s] %s", gDriverName, buf);
+}
+
+
+void
+driver_vprintf(const char *format, va_list vl)
+{
+       driver_vprintf_etc(NULL, format, vl);
+}
+
+
+int
+device_printf(device_t dev, const char *format, ...)
+{
+       va_list vl;
+
+       va_start(vl, format);
+       driver_vprintf_etc(dev->device_name, format, vl);
+       va_end(vl);
+       return 0;
+}
+
+
+void
+device_set_desc(device_t dev, const char *desc)
+{
+       dev->description = desc;
+}
+
+
+void
+device_set_desc_copy(device_t dev, const char *desc)
+{
+       dev->description = strdup(desc);
+       dev->flags |= DEVICE_DESC_ALLOCED;
+}
+
+
+const char *
+device_get_desc(device_t dev)
+{
+       return dev->description;
+}
+
+
+device_t
+device_get_parent(device_t dev)
+{
+       return dev->parent;
+}
+
+
+devclass_t
+device_get_devclass(device_t dev)
+{
+       // TODO find out what to do
+       return 0;
+}
+
+
+int
+device_get_children(device_t dev, device_t **devlistp, int *devcountp)
+{
+       int count;
+       device_t child = NULL;
+       device_t *list;
+
+       count = 0;
+       while ((child = list_get_next_item(&dev->children, child)) != NULL) {
+               count++;
+       }
+       
+       list = malloc(count * sizeof(device_t));
+       if (!list)
+               return (ENOMEM);
+
+       count = 0;
+       while ((child = list_get_next_item(&dev->children, child)) != NULL) {
+               list[count] = child;
+               count++;
+       }
+
+       *devlistp = list;
+       *devcountp = count;
+
+       return (0);
+}
+
+
+void
+device_set_ivars(device_t dev, void *ivars)
+{
+       dev->ivars = ivars;
+}
+
+
+void *
+device_get_ivars(device_t dev)
+{
+       return dev->ivars;
+}
+
+
+const char *
+device_get_name(device_t dev)
+{
+       if (dev == NULL)
+               return NULL;
+
+       return dev->device_name;
+}
+
+
+int
+device_get_unit(device_t dev)
+{
+       return dev->unit;
+}
+
+
+const char *
+device_get_nameunit(device_t dev)
+{
+       return dev->nameunit;
+}
+
+
+void *
+device_get_softc(device_t dev)
+{
+       return dev->softc;
+}
+
+
+u_int32_t
+device_get_flags(device_t dev)
+{
+       return dev->flags;
+}
+
+
+int
+device_set_driver(device_t dev, driver_t *driver)
+{
+       device_method_signature_t method = NULL;
+       int i;
+
+       dev->softc = malloc(driver->softc_size);
+       if (dev->softc == NULL)
+               return -1;
+
+       memset(dev->softc, 0, driver->softc_size);
+       dev->driver = driver;
+
+       for (i = 0; method == NULL && driver->methods[i].name != NULL; i++) {
+               device_method_t *mth = &driver->methods[i];
+
+               if (strcmp(mth->name, "device_probe") == 0)
+                       dev->methods.probe = (void *)mth->method;
+               else if (strcmp(mth->name, "device_attach") == 0)
+                       dev->methods.attach = (void *)mth->method;
+               else if (strcmp(mth->name, "device_detach") == 0)
+                       dev->methods.detach = (void *)mth->method;
+               else if (strcmp(mth->name, "device_suspend") == 0)
+                       dev->methods.suspend = (void *)mth->method;
+               else if (strcmp(mth->name, "device_resume") == 0)
+                       dev->methods.resume = (void *)mth->method;
+               else if (strcmp(mth->name, "device_shutdown") == 0)
+                       dev->methods.shutdown = (void *)mth->method;
+               else if (strcmp(mth->name, "miibus_readreg") == 0)
+                       dev->methods.miibus_readreg = (void *)mth->method;
+               else if (strcmp(mth->name, "miibus_writereg") == 0)
+                       dev->methods.miibus_writereg = (void *)mth->method;
+               else if (strcmp(mth->name, "miibus_statchg") == 0)
+                       dev->methods.miibus_statchg = (void *)mth->method;
+               else if (!strcmp(mth->name, "miibus_linkchg"))
+                       dev->methods.miibus_linkchg = (void *)mth->method;
+               else if (!strcmp(mth->name, "miibus_mediainit"))
+                       dev->methods.miibus_mediainit = (void *)mth->method;
+       }
+
+       return 0;
+}
+
+
+int
+device_is_alive(device_t device)
+{
+       return (device->flags & DEVICE_ATTACHED) != 0;
+}
+
+
+device_t
+device_add_child(device_t parent, const char *name, int unit)
+{
+       device_t child = NULL;
+
+       if (name != NULL) {
+               if (strcmp(name, "miibus") == 0)
+                       child = new_device(&miibus_driver);
+               else {
+                       // find matching driver structure
+                       driver_t **driver;
+                       char symbol[128];
+
+                       snprintf(symbol, sizeof(symbol), "__fbsd_%s_%s", name,
+                               parent->driver->name);
+                       if (get_image_symbol(find_own_image(), symbol, 
B_SYMBOL_TYPE_DATA,
+                                       (void **)&driver) == B_OK) {
+                               child = new_device(*driver);
+                       } else
+                               device_printf(parent, "couldn't find symbol 
%s\n", symbol);
+               }
+       } else
+               child = new_device(NULL);
+
+       if (child == NULL)
+               return NULL;
+
+       if (name != NULL)
+               strlcpy(child->device_name, name, sizeof(child->device_name));
+
+       child->parent = parent;
+
+       if (parent != NULL) {
+               list_add_item(&parent->children, child);
+               child->root = parent->root;
+       } else {
+               if (sRootDevices.link.next == NULL)
+                       list_init_etc(&sRootDevices, offsetof(struct device, 
link));
+               list_add_item(&sRootDevices, child);
+       }
+
+       return child;
+}
+
+
+/*!    Delete the child and all of its children. Detach as necessary.
+*/
+int
+device_delete_child(device_t parent, device_t child)
+{
+       int status;
+
+       if (child == NULL)
+               return 0;
+
+       if (parent != NULL)
+               list_remove_item(&parent->children, child);
+       else
+               list_remove_item(&sRootDevices, child);
+
+       // We differentiate from the FreeBSD logic here - it will first delete
+       // the children, and will then detach the device.
+       // This has the problem that you cannot safely call 
device_delete_child()
+       // as you don't know if one of the children deletes its own children 
this
+       // way when it is detached.
+       // Therefore, we'll detach first, and then delete whatever is left.
+
+       parent = child;
+       child = NULL;
+
+       // detach children
+       while ((child = list_get_next_item(&parent->children, child)) != NULL) {
+               device_detach(child);
+       }
+
+       // detach device
+       status = device_detach(parent);
+       if (status != 0)
+               return status;
+
+       // delete children
+       while ((child = list_get_first_item(&parent->children)) != NULL) {
+               device_delete_child(parent, child);
+       }
+
+       // delete device
+       if (parent->flags & DEVICE_DESC_ALLOCED)
+               free((char *)parent->description);
+
+       free(parent->softc);
+       free(parent);
+       return 0;
+}
+
+
+int
+device_is_attached(device_t device)
+{
+       return (device->flags & DEVICE_ATTACHED) != 0;
+}
+
+
+int
+device_attach(device_t device)
+{
+       int result;
+
+       if (device->driver == NULL
+               || device->methods.attach == NULL)
+               return B_ERROR;
+
+       result = device->methods.attach(device);
+
+       if (result == 0)
+               atomic_or(&device->flags, DEVICE_ATTACHED);
+
+       if (result == 0)
+               result = start_wlan(device);
+
+       return result;
+}
+
+
+int
+device_detach(device_t device)
+{
+       if (device->driver == NULL)
+               return B_ERROR;
+
+       if ((atomic_and(&device->flags, ~DEVICE_ATTACHED) & DEVICE_ATTACHED) != 0
+               && device->methods.detach != NULL) {
+               int result = B_OK;
+
+               result = stop_wlan(device);
+               if (result != 0) {
+                       atomic_or(&device->flags, DEVICE_ATTACHED);
+                       return result;
+               }
+
+               result = device->methods.detach(device);
+               if (result != 0) {
+                       atomic_or(&device->flags, DEVICE_ATTACHED);
+                       return result;
+               }
+       }
+
+       return 0;
+}
+
+
+int
+bus_generic_attach(device_t dev)
+{
+       device_t child = NULL;
+
+       while ((child = list_get_next_item(&dev->children, child)) != NULL) {
+               if (child->driver == NULL) {
+                       driver_t *driver = __haiku_select_miibus_driver(child);
+                       if (driver == NULL) {
+                               struct mii_attach_args *ma = 
device_get_ivars(child);
+
+                               device_printf(dev, "No PHY module found 
(%x/%x)!\n",
+                                       MII_OUI(ma->mii_id1, ma->mii_id2), 
MII_MODEL(ma->mii_id2));
+                       } else
+                               device_set_driver(child, driver);
+               } else
+                       child->methods.probe(child);
+
+               if (child->driver != NULL) {
+                       int result = device_attach(child);
+                       if (result != 0)
+                               return result;
+               }
+       }
+
+       return 0;
+}
+
+
+int
+bus_generic_detach(device_t device)
+{
+       device_t child = NULL;
+
+       if ((device->flags & DEVICE_ATTACHED) == 0)
+               return B_ERROR;
+
+       while (true) {
+               child = list_get_next_item(&device->children, child);
+               if (child == NULL)
+                       break;
+
+               device_detach(child);
+       }
+
+       return 0;
+}
+
+
+//     #pragma mark - Misc, Malloc
+
+
+device_t
+find_root_device(int unit)
+{
+       device_t device = NULL;
+
+       while ((device = list_get_next_item(&sRootDevices, device)) != NULL) {
+               if (device->unit <= unit)
+                       return device;
+       }
+
+       return NULL;
+}
+
+
+driver_t *
+__haiku_probe_miibus(device_t dev, driver_t *drivers[])
+{
+       driver_t *selected = NULL;
+       int i, selectedResult = 0;
+
+       if (drivers == NULL)
+               return NULL;
+
+       for (i = 0; drivers[i]; i++) {
+               device_probe_t *probe = (device_probe_t *)
+                       resolve_method(drivers[i], "device_probe");
+               if (probe) {
+                       int result = probe(dev);
+                       if (result >= 0) {
+                               if (selected == NULL || result < 
selectedResult) {
+                                       selected = drivers[i];
+                                       selectedResult = result;
+                                       device_printf(dev, "Found MII: %s\n", 
selected->name);
+                               }
+                       }
+               }
+       }
+
+       return selected;
+}
+
+
+int
+printf(const char *format, ...)
+{
+       char buf[256];
+       va_list vl;
+       va_start(vl, format);
+       vsnprintf(buf, sizeof(buf), format, vl);
+       va_end(vl);
+       dprintf(buf);
+
+       return 0;
+}
+
+
+int
+ffs(int value)
+{
+       int i = 1;
+
+       if (value == 0)
+               return 0;
+
+       for (; !(value & 1); i++)
+               value >>= 1;
+
+       return i;
+}
+
+
+int
+resource_int_value(const char *name, int unit, const char *resname,
+       int *result)
+{
+       /* no support for hints */
+       return -1;
+}
+
+
+void *
+_kernel_malloc(size_t size, int flags)
+{
+       // our kernel malloc() is insufficient, must handle M_WAIT
+
+       // According to the FreeBSD kernel malloc man page the allocator is 
expected
+       // to return power of two aligned addresses for allocations up to one 
page
+       // size. While it also states that this shouldn't be relied upon, at 
least
+       // bus_dmamem_alloc expects it and drivers may depend on it as well.
+       void *ptr
+               = memalign(size >= PAGESIZE ? PAGESIZE : next_power_of_2(size), 
size);
+       if (ptr == NULL)
+               return NULL;
+
+       if (flags & M_ZERO)
+               memset(ptr, 0, size);
+
+       return ptr;
+}
+
+
+void
+_kernel_free(void *ptr)
+{
+       free(ptr);
+}
+
+
+void *
+_kernel_contigmalloc(const char *file, int line, size_t size, int flags,
+       vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
+       unsigned long boundary)
+{
+       return _kernel_contigmalloc_cpp(file, line, size, low, high,
+               alignment, boundary, (flags & M_ZERO) != 0, (flags & M_NOWAIT) 
!= 0);
+}
+
+
+void
+_kernel_contigfree(void *addr, size_t size)
+{
+       delete_area(area_for(addr));
+}
+
+
+vm_paddr_t
+pmap_kextract(vm_offset_t virtualAddress)
+{
+       physical_entry entry;
+       status_t status = get_memory_map((void *)virtualAddress, 1, &entry, 1);
+       if (status < B_OK) {
+               panic("fbsd compat: get_memory_map failed for %p, error %08" 
B_PRIx32
+                       "\n", (void *)virtualAddress, status);
+       }
+
+       return (vm_paddr_t)entry.address;
+}
+
diff --git a/src/libs/compat/freebsd11_network/compat/altq/if_altq.h 
b/src/libs/compat/freebsd11_network/compat/altq/if_altq.h
new file mode 100644
index 0000000..5b0a815
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/compat/altq/if_altq.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007 Haiku Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _FBSD_COMPAT_ALTQ_IF_ALTQ_H_
+#define _FBSD_COMPAT_ALTQ_IF_ALTQ_H_
+
+
+#include <sys/mbuf.h>
+#include <sys/mutex.h>
+
+
+struct ifaltq {
+       struct mbuf*    ifq_head;
+       struct mbuf*    ifq_tail;
+
+       int                             ifq_len;
+       int                             ifq_maxlen;
+       int                             ifq_drops;
+       struct mtx              ifq_mtx;
+
+       struct mbuf*    ifq_drv_head;
+       struct mbuf*    ifq_drv_tail;
+       int                             ifq_drv_len;
+       int                             ifq_drv_maxlen;
+
+       int                             altq_flags;
+};
+
+
+#define ALTQF_READY    0x1
+
+#define ALTDQ_REMOVE 1
+
+#define ALTQ_IS_ENABLED(ifq)   0
+#define ALTQ_ENQUEUE(ifr, m, foo, error) \
+       do { m_freem(m); error = -1; } while (0)
+#define ALTQ_DEQUEUE(ifr, m)   (m) = NULL
+
+#define TBR_IS_ENABLED(ifq)            0
+#define tbr_dequeue_ptr(ifq, v)        NULL
+
+#endif
diff --git a/src/libs/compat/freebsd11_network/compat/dev/mii/mii.h 
b/src/libs/compat/freebsd11_network/compat/dev/mii/mii.h
new file mode 100644
index 0000000..668fb8f
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/compat/dev/mii/mii.h
@@ -0,0 +1,202 @@
+/*     $NetBSD: mii.h,v 1.9 2001/05/31 03:07:14 thorpej Exp $  */
+
+/*-
+ * Copyright (c) 1997 Manuel Bouyer.  All rights reserved.
+ *
+ * Modification to match BSD/OS 3.0 MII interface by Jason R. Thorpe,
+ * Numerical Aerospace Simulation Facility, NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _DEV_MII_MII_H_
+#define        _DEV_MII_MII_H_
+
+/*
+ * Registers common to all PHYs.
+ */
+
+#define        MII_NPHY        32      /* max # of PHYs per MII */
+
+/*
+ * MII commands, used if a device must drive the MII lines
+ * manually.
+ */
+#define        MII_COMMAND_START       0x01
+#define        MII_COMMAND_READ        0x02
+#define        MII_COMMAND_WRITE       0x01
+#define        MII_COMMAND_ACK         0x02
+
+#define        MII_BMCR        0x00    /* Basic mode control register (rw) */
+#define        BMCR_RESET      0x8000  /* reset */
+#define        BMCR_LOOP       0x4000  /* loopback */
+#define        BMCR_SPEED0     0x2000  /* speed selection (LSB) */
+#define        BMCR_AUTOEN     0x1000  /* autonegotiation enable */
+#define        BMCR_PDOWN      0x0800  /* power down */
+#define        BMCR_ISO        0x0400  /* isolate */
+#define        BMCR_STARTNEG   0x0200  /* restart autonegotiation */
+#define        BMCR_FDX        0x0100  /* Set duplex mode */
+#define        BMCR_CTEST      0x0080  /* collision test */
+#define        BMCR_SPEED1     0x0040  /* speed selection (MSB) */
+
+#define        BMCR_S10        0x0000          /* 10 Mb/s */
+#define        BMCR_S100       BMCR_SPEED0     /* 100 Mb/s */
+#define        BMCR_S1000      BMCR_SPEED1     /* 1000 Mb/s */
+
+#define        BMCR_SPEED(x)   ((x) & (BMCR_SPEED0|BMCR_SPEED1))
+
+#define        MII_BMSR        0x01    /* Basic mode status register (ro) */
+#define        BMSR_100T4      0x8000  /* 100 base T4 capable */
+#define        BMSR_100TXFDX   0x4000  /* 100 base Tx full duplex capable */
+#define        BMSR_100TXHDX   0x2000  /* 100 base Tx half duplex capable */
+#define        BMSR_10TFDX     0x1000  /* 10 base T full duplex capable */
+#define        BMSR_10THDX     0x0800  /* 10 base T half duplex capable */
+#define        BMSR_100T2FDX   0x0400  /* 100 base T2 full duplex capable */
+#define        BMSR_100T2HDX   0x0200  /* 100 base T2 half duplex capable */
+#define        BMSR_EXTSTAT    0x0100  /* Extended status in register 15 */
+#define        BMSR_MFPS       0x0040  /* MII Frame Preamble Suppression */
+#define        BMSR_ACOMP      0x0020  /* Autonegotiation complete */
+#define        BMSR_RFAULT     0x0010  /* Link partner fault */
+#define        BMSR_ANEG       0x0008  /* Autonegotiation capable */
+#define        BMSR_LINK       0x0004  /* Link status */
+#define        BMSR_JABBER     0x0002  /* Jabber detected */
+#define        BMSR_EXTCAP     0x0001  /* Extended capability */
+
+#define        BMSR_DEFCAPMASK 0xffffffff
+
+/*
+ * Note that the EXTSTAT bit indicates that there is extended status
+ * info available in register 15, but 802.3 section 22.2.4.3 also
+ * states that that all 1000 Mb/s capable PHYs will set this bit to 1.
+ */
+
+#define        BMSR_MEDIAMASK  (BMSR_100T4|BMSR_100TXFDX|BMSR_100TXHDX| \
+                        BMSR_10TFDX|BMSR_10THDX|BMSR_100T2FDX|BMSR_100T2HDX)
+
+/*
+ * Convert BMSR media capabilities to ANAR bits for autonegotiation.
+ * Note the shift chopps off the BMSR_ANEG bit.
+ */
+#define        BMSR_MEDIA_TO_ANAR(x)   (((x) & BMSR_MEDIAMASK) >> 6)
+
+#define        MII_PHYIDR1     0x02    /* ID register 1 (ro) */
+
+#define        MII_PHYIDR2     0x03    /* ID register 2 (ro) */
+#define        IDR2_OUILSB     0xfc00  /* OUI LSB */
+#define        IDR2_MODEL      0x03f0  /* vendor model */
+#define        IDR2_REV        0x000f  /* vendor revision */
+
+#define        MII_ANAR        0x04    /* Autonegotiation advertisement (rw) */
+               /* section 28.2.4.1 and 37.2.6.1 */
+#define ANAR_NP                0x8000  /* Next page (ro) */
+#define        ANAR_ACK        0x4000  /* link partner abilities acknowledged 
(ro) */
+#define ANAR_RF                0x2000  /* remote fault (ro) */
+#define        ANAR_FC         0x0400  /* local device supports PAUSE */
+#define ANAR_T4                0x0200  /* local device supports 100bT4 */
+#define ANAR_TX_FD     0x0100  /* local device supports 100bTx FD */
+#define ANAR_TX                0x0080  /* local device supports 100bTx */
+#define ANAR_10_FD     0x0040  /* local device supports 10bT FD */
+#define ANAR_10                0x0020  /* local device supports 10bT */
+#define        ANAR_CSMA       0x0001  /* protocol selector CSMA/CD */
+#define        ANAR_PAUSE_NONE         (0 << 10)
+#define        ANAR_PAUSE_SYM          (1 << 10)
+#define        ANAR_PAUSE_ASYM         (2 << 10)
+#define        ANAR_PAUSE_TOWARDS      (3 << 10)
+
+#define        ANAR_X_FD       0x0020  /* local device supports 1000BASE-X FD 
*/
+#define        ANAR_X_HD       0x0040  /* local device supports 1000BASE-X HD 
*/
+#define        ANAR_X_PAUSE_NONE       (0 << 7)
+#define        ANAR_X_PAUSE_SYM        (1 << 7)
+#define        ANAR_X_PAUSE_ASYM       (2 << 7)
+#define        ANAR_X_PAUSE_TOWARDS    (3 << 7)
+
+#define        MII_ANLPAR      0x05    /* Autonegotiation lnk partner 
abilities (rw) */
+               /* section 28.2.4.1 and 37.2.6.1 */
+#define ANLPAR_NP      0x8000  /* Next page (ro) */
+#define        ANLPAR_ACK      0x4000  /* link partner accepted ACK (ro) */
+#define ANLPAR_RF      0x2000  /* remote fault (ro) */
+#define        ANLPAR_FC       0x0400  /* link partner supports PAUSE */
+#define ANLPAR_T4      0x0200  /* link partner supports 100bT4 */
+#define ANLPAR_TX_FD   0x0100  /* link partner supports 100bTx FD */
+#define ANLPAR_TX      0x0080  /* link partner supports 100bTx */
+#define ANLPAR_10_FD   0x0040  /* link partner supports 10bT FD */
+#define ANLPAR_10      0x0020  /* link partner supports 10bT */
+#define        ANLPAR_CSMA     0x0001  /* protocol selector CSMA/CD */
+#define        ANLPAR_PAUSE_MASK       (3 << 10)
+#define        ANLPAR_PAUSE_NONE       (0 << 10)
+#define        ANLPAR_PAUSE_SYM        (1 << 10)
+#define        ANLPAR_PAUSE_ASYM       (2 << 10)
+#define        ANLPAR_PAUSE_TOWARDS    (3 << 10)
+
+#define        ANLPAR_X_FD     0x0020  /* local device supports 1000BASE-X FD 
*/
+#define        ANLPAR_X_HD     0x0040  /* local device supports 1000BASE-X HD 
*/
+#define        ANLPAR_X_PAUSE_MASK     (3 << 7)
+#define        ANLPAR_X_PAUSE_NONE     (0 << 7)
+#define        ANLPAR_X_PAUSE_SYM      (1 << 7)
+#define        ANLPAR_X_PAUSE_ASYM     (2 << 7)
+#define        ANLPAR_X_PAUSE_TOWARDS  (3 << 7)
+
+#define        MII_ANER        0x06    /* Autonegotiation expansion (ro) */
+               /* section 28.2.4.1 and 37.2.6.1 */
+#define ANER_MLF       0x0010  /* multiple link detection fault */
+#define ANER_LPNP      0x0008  /* link parter next page-able */
+#define ANER_NP                0x0004  /* next page-able */
+#define ANER_PAGE_RX   0x0002  /* Page received */
+#define ANER_LPAN      0x0001  /* link parter autoneg-able */
+
+#define        MII_ANNP        0x07    /* Autonegotiation next page */
+               /* section 28.2.4.1 and 37.2.6.1 */
+
+#define        MII_ANLPRNP     0x08    /* Autonegotiation link partner rx next 
page */
+               /* section 32.5.1 and 37.2.6.1 */
+
+                       /* This is also the 1000baseT control register */
+#define        MII_100T2CR     0x09    /* 100base-T2 control register */
+#define        GTCR_TEST_MASK  0xe000  /* see 802.3ab ss. 40.6.1.1.2 */
+#define        GTCR_MAN_MS     0x1000  /* enable manual master/slave control */
+#define        GTCR_ADV_MS     0x0800  /* 1 = adv. master, 0 = adv. slave */
+#define        GTCR_PORT_TYPE  0x0400  /* 1 = DCE, 0 = DTE (NIC) */
+#define        GTCR_ADV_1000TFDX 0x0200 /* adv. 1000baseT FDX */
+#define        GTCR_ADV_1000THDX 0x0100 /* adv. 1000baseT HDX */
+
+                       /* This is also the 1000baseT status register */
+#define        MII_100T2SR     0x0a    /* 100base-T2 status register */
+#define        GTSR_MAN_MS_FLT 0x8000  /* master/slave config fault */
+#define        GTSR_MS_RES     0x4000  /* result: 1 = master, 0 = slave */
+#define        GTSR_LRS        0x2000  /* local rx status, 1 = ok */
+#define        GTSR_RRS        0x1000  /* remove rx status, 1 = ok */
+#define        GTSR_LP_1000TFDX 0x0800 /* link partner 1000baseT FDX capable */
+#define        GTSR_LP_1000THDX 0x0400 /* link partner 1000baseT HDX capable */
+#define        GTSR_LP_ASM_DIR 0x0200  /* link partner asym. pause dir. 
capable */
+#define        GTSR_IDLE_ERR   0x00ff  /* IDLE error count */
+
+#define        MII_EXTSR       0x0f    /* Extended status register */
+#define        EXTSR_1000XFDX  0x8000  /* 1000X full-duplex capable */
+#define        EXTSR_1000XHDX  0x4000  /* 1000X half-duplex capable */
+#define        EXTSR_1000TFDX  0x2000  /* 1000T full-duplex capable */
+#define        EXTSR_1000THDX  0x1000  /* 1000T half-duplex capable */
+
+#define        EXTSR_MEDIAMASK (EXTSR_1000XFDX|EXTSR_1000XHDX| \
+                        EXTSR_1000TFDX|EXTSR_1000THDX)
+
+#endif /* _DEV_MII_MII_H_ */
diff --git a/src/libs/compat/freebsd11_network/compat/dev/mii/mii_bitbang.h 
b/src/libs/compat/freebsd11_network/compat/dev/mii/mii_bitbang.h
new file mode 100644
index 0000000..2bc7427
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/compat/dev/mii/mii_bitbang.h
@@ -0,0 +1,54 @@
+/*     $NetBSD: mii_bitbang.h,v 1.6 2009/05/12 14:31:27 cegger Exp $   */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#define        MII_BIT_MDO             0       /* data out (host->PHY) */
+#define        MII_BIT_MDI             1       /* data in (PHY->host) */
+#define        MII_BIT_MDC             2       /* clock */
+#define        MII_BIT_DIR_HOST_PHY    3       /* set direction: host->PHY */
+#define        MII_BIT_DIR_PHY_HOST    4       /* set direction: PHY->host */
+#define        MII_NBITS               5
+
+struct mii_bitbang_ops {
+       uint32_t        (*mbo_read)(device_t);
+       void            (*mbo_write)(device_t, uint32_t);
+       uint32_t        mbo_bits[MII_NBITS];
+};
+
+typedef        const struct mii_bitbang_ops *mii_bitbang_ops_t;
+
+int    mii_bitbang_readreg(device_t dev, mii_bitbang_ops_t ops,
+           int phy, int reg);
+void   mii_bitbang_sync(device_t dev, mii_bitbang_ops_t ops);
+void   mii_bitbang_writereg(device_t dev, mii_bitbang_ops_t ops,
+           int phy, int reg, int val);
diff --git a/src/libs/compat/freebsd11_network/compat/dev/mii/miidevs 
b/src/libs/compat/freebsd11_network/compat/dev/mii/miidevs
new file mode 100644
index 0000000..5d69fa1
--- /dev/null
+++ b/src/libs/compat/freebsd11_network/compat/dev/mii/miidevs
@@ -0,0 +1,325 @@
+$FreeBSD$
+/*$NetBSD: miidevs,v 1.105 2011/11/25 23:28:14 jakllsch Exp $*/
+
+/*-
+ * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright

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


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

Commit:      078cb1083454d16008411522ff06fc72136cc36f
URL:         http://cgit.haiku-os.org/haiku/commit/?id=078cb1083454
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Tue Nov 14 20:22:30 2017 UTC

freebsd11_network: adapt code based on needs of the e1000 R11.1 driver.

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

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

Revision:    hrev51546
Commit:      b3fb200fe3116bc6f94feaf95a2149372b3e1dc0
URL:         http://cgit.haiku-os.org/haiku/commit/?id=b3fb200fe311
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Tue Nov 14 20:28:52 2017 UTC

ipro1000: Update with the 11.1 release of the e1000 driver.

* switch compat layer.
* tested on Qemu and Intel I217-LM.

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


Other related posts:

  • » [haiku-commits] haiku: hrev51546 - in src: add-ons/kernel/drivers/network/ipro1000/dev/e1000 libs/compat/freebsd11_network libs/compat/freebsd11_network/compat/sys libs/compat/freebsd11_network/compat/net libs/compat/freebsd11_network/compat/dev/pci - jerome . duval