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.
----------------------------------------------------------------------------