summaryrefslogtreecommitdiffstats
path: root/bsd_eth_drivers/libbsdport
diff options
context:
space:
mode:
authorcvs2git <rtems-devel@rtems.org>2010-03-07 17:11:24 +0000
committercvs2git <rtems-devel@rtems.org>2010-03-07 17:11:24 +0000
commita9f34b79757de68cdd3f951077be0dd65da6354c (patch)
treef60c55f42307a08ebee35449d53e450e7f4a3321 /bsd_eth_drivers/libbsdport
parenta8bf95d0249565f4210ccab5c13232d501ce0c2d (diff)
downloadlibbsdport-a9f34b79757de68cdd3f951077be0dd65da6354c.tar.bz2
This commit was manufactured by cvs2svn to create tag 'R_20100307_p0'.R_20100307_p0
Sprout from base 2009-04-22 22:06:58 UTC Till Straumann <strauman@slac.stanford.edu> ' - importing updated version from SLAC as of 20090422' Cherrypick from master 2010-03-07 17:11:23 UTC Till Straumann <strauman@slac.stanford.edu> '2010-03-07 Till Straumann <Till.Straumann@TU-Berlin.de>': bsd_eth_drivers/.cvsignore bsd_eth_drivers/ChangeLog bsd_eth_drivers/Makefile.am bsd_eth_drivers/if_bge/.cvsignore bsd_eth_drivers/if_bge/Makefile.am bsd_eth_drivers/if_bge/if_bge.c bsd_eth_drivers/if_bge/if_bgereg.h bsd_eth_drivers/if_em/.cvsignore bsd_eth_drivers/if_em/Makefile.am bsd_eth_drivers/if_em/e1000_manage.c bsd_eth_drivers/if_em/e1000_manage.h bsd_eth_drivers/if_em/e1000_osdep.h bsd_eth_drivers/if_em/if_em.c bsd_eth_drivers/if_fxp/.cvsignore bsd_eth_drivers/if_fxp/Makefile.am bsd_eth_drivers/if_fxp/if_fxp.c bsd_eth_drivers/if_fxp/if_fxpvar.h bsd_eth_drivers/if_le/.cvsignore bsd_eth_drivers/if_pcn/.cvsignore bsd_eth_drivers/if_pcn/if_pcn.c bsd_eth_drivers/if_re/.cvsignore bsd_eth_drivers/if_re/Makefile.am bsd_eth_drivers/if_re/if_re.c bsd_eth_drivers/if_re/if_rl.c bsd_eth_drivers/if_re/if_rlreg.h bsd_eth_drivers/libbsdport/.cvsignore bsd_eth_drivers/libbsdport/Makefile.am bsd_eth_drivers/libbsdport/alldrv.c bsd_eth_drivers/libbsdport/bus.h bsd_eth_drivers/libbsdport/callout.h bsd_eth_drivers/libbsdport/devicet.c bsd_eth_drivers/libbsdport/ifmedia.c bsd_eth_drivers/libbsdport/libbsdport.h bsd_eth_drivers/libbsdport/libbsdport_api.h bsd_eth_drivers/libbsdport/libbsdport_post.h bsd_eth_drivers/libbsdport/miistuff.c bsd_eth_drivers/libbsdport/misc.c bsd_eth_drivers/libbsdport/mutex.h bsd_eth_drivers/libbsdport/rtems_callout.c bsd_eth_drivers/libbsdport/sysbus.c bsd_eth_drivers/libbsdport/taskqueue.h bsd_eth_drivers/links.am Cherrypick from freebsd_orig 2009-04-23 04:52:05 UTC Till Straumann <strauman@slac.stanford.edu> ' - importing original 'releng_7_1' version of FXP driver from FreeBSD.': bsd_eth_drivers/if_fxp/if_fxpreg.h bsd_eth_drivers/if_fxp/rcvbundl.h Delete: INSTALL Makefile.am bootstrap config.h.in configure.ac m4/acinclude.m4 m4/config-if-present.m4 m4/cvstag.m4 m4/multilib-fix.m4 m4/multilib-installdir.m4 m4/rtems-bsp-postlink.m4 m4/rtems-bsplist.m4 m4/rtems-check-libargs.m4 m4/rtems-checkprog.m4 m4/rtems-checktool.m4 m4/rtems-checktop.m4 m4/rtems-fixup-prefix.m4 m4/rtems-isml.m4 m4/rtems-ismultibsp.m4 m4/rtems-isrtems.m4 m4/rtems-makevars.m4 m4/rtems-multilib.m4 m4/rtems-options.m4 m4/rtems-setup-recurse.m4 m4/rtems-tools.m4 m4/rtems-trim-builddir.m4 m4/rtems-verscheck.m4 makefile.top.am makefile.top.in rtems-pre.am rtems.am ssrlApps.components.in
Diffstat (limited to 'bsd_eth_drivers/libbsdport')
-rw-r--r--bsd_eth_drivers/libbsdport/.cvsignore1
-rw-r--r--bsd_eth_drivers/libbsdport/Makefile.am27
-rw-r--r--bsd_eth_drivers/libbsdport/alldrv.c30
-rw-r--r--bsd_eth_drivers/libbsdport/bus.h121
-rw-r--r--bsd_eth_drivers/libbsdport/callout.h44
-rw-r--r--bsd_eth_drivers/libbsdport/devicet.c73
-rw-r--r--bsd_eth_drivers/libbsdport/ifmedia.c10
-rw-r--r--bsd_eth_drivers/libbsdport/libbsdport.h50
-rw-r--r--bsd_eth_drivers/libbsdport/libbsdport_api.h16
-rw-r--r--bsd_eth_drivers/libbsdport/libbsdport_post.h35
-rw-r--r--bsd_eth_drivers/libbsdport/miistuff.c58
-rw-r--r--bsd_eth_drivers/libbsdport/misc.c179
-rw-r--r--bsd_eth_drivers/libbsdport/mutex.h3
-rw-r--r--bsd_eth_drivers/libbsdport/rtems_callout.c31
-rw-r--r--bsd_eth_drivers/libbsdport/sysbus.c60
-rw-r--r--bsd_eth_drivers/libbsdport/taskqueue.h2
16 files changed, 664 insertions, 76 deletions
diff --git a/bsd_eth_drivers/libbsdport/.cvsignore b/bsd_eth_drivers/libbsdport/.cvsignore
new file mode 100644
index 0000000..70845e0
--- /dev/null
+++ b/bsd_eth_drivers/libbsdport/.cvsignore
@@ -0,0 +1 @@
+Makefile.in
diff --git a/bsd_eth_drivers/libbsdport/Makefile.am b/bsd_eth_drivers/libbsdport/Makefile.am
index e6e31cd..06c70c8 100644
--- a/bsd_eth_drivers/libbsdport/Makefile.am
+++ b/bsd_eth_drivers/libbsdport/Makefile.am
@@ -5,7 +5,7 @@ include $(top_srcdir)/rtems-pre.am
libbsdport_a_SOURCES = rtems_callout.c rtems_taskqueue.c rtems_udelay.c
libbsdport_a_SOURCES += ifstuff.c devicet.c alldrv.c contigmalloc.c
-libbsdport_a_SOURCES += sysbus.c malloc.c ifmedia.c
+libbsdport_a_SOURCES += sysbus.c malloc.c ifmedia.c misc.c miistuff.c
libbsdport_a_SOURCES += rtems_verscheck.h bus.h callout.h devicet.h
libbsdport_a_SOURCES += libbsdport.h libbsdport_post.h mutex.h
@@ -38,6 +38,9 @@ DUMMYHEADERS+=dummyheaders/netinet/ip6.h
DUMMYHEADERS+=dummyheaders/vm/pmap.h
DUMMYHEADERS+=dummyheaders/miibus_if.h
+DUMMYHEADERS+=dummyheaders/miidevs.h
+DUMMYHEADERS+=dummyheaders/dev/mii/brgphyreg.h
+
BUILT_SOURCES=
include ../links.am
@@ -48,25 +51,3 @@ include ../links.am
# after OBJECTS are made :-(
$(libbsdport_a_OBJECTS): $(DUMMYHEADERS) $(LINKS)
-if FALSE
-CLOBBER_ADDITIONS =
-CLOBBER_ADDITIONS += $(srcdir)/dummyheaders
-CLOBBER_ADDITIONS += $(addprefix $(srcdir)/,$(sort $(foreach n,$(LINKS),$(firstword $(subst /, ,$(n))))))
-
-dummyheaders/%:
- @if [ ! -d $(srcdir)/`dirname $@` ] ; then mkdir -p $(srcdir)/`dirname $@`; fi
- @touch $(srcdir)/$@
-
-# for each name listed in LINKS, create parent directories (if needed)
-# and a symlink to file in .
-# E.g., LINKS=a/b/c.h
-# creates a/b/c.h -> ../../c.h
-$(LINKS):
- @if [ ! -d $(srcdir)/$(dir $@) ] ; then mkdir -p $(srcdir)/$(dir $@); fi
- @ln -s `echo $@ | sed -e 's%[^/]\+[/]\+%../%g'` $(srcdir)/$@
-
-
-distclean-local:
- $(RM) -r $(CLOBBER_ADDITIONS)
-endif
-
diff --git a/bsd_eth_drivers/libbsdport/alldrv.c b/bsd_eth_drivers/libbsdport/alldrv.c
index f81b95a..c68d6d1 100644
--- a/bsd_eth_drivers/libbsdport/alldrv.c
+++ b/bsd_eth_drivers/libbsdport/alldrv.c
@@ -1,14 +1,42 @@
#include <stdio.h>
#include "libbsdport_api.h"
+#include "devicet.h"
driver_t *libbsdport_netdriver_table_all[] = {
&libbsdport_em_driver,
&libbsdport_pcn_driver,
&libbsdport_le_pci_driver,
+ &libbsdport_fxp_driver,
+ &libbsdport_bge_driver,
+ &libbsdport_re_driver,
+ &libbsdport_rl_driver,
0
};
-/* weak alias defaults to a table that includes all currently supported drivers */
+driver_t libbsdport_null_driver = {0};
+
+extern driver_t libbsdport_em_driver
+ __attribute__((weak,alias("libbsdport_null_driver")));
+extern driver_t libbsdport_pcn_driver
+ __attribute__((weak,alias("libbsdport_null_driver")));
+extern driver_t libbsdport_le_pci_driver
+ __attribute__((weak,alias("libbsdport_null_driver")));
+extern driver_t libbsdport_fxp_driver
+ __attribute__((weak,alias("libbsdport_null_driver")));
+extern driver_t libbsdport_bge_driver
+ __attribute__((weak,alias("libbsdport_null_driver")));
+extern driver_t libbsdport_re_driver
+ __attribute__((weak,alias("libbsdport_null_driver")));
+extern driver_t libbsdport_rl_driver
+ __attribute__((weak,alias("libbsdport_null_driver")));
+
+
+/* weak alias defaults to a table that includes
+ * all currently supported drivers.
+ *
+ * However, the individual entires are weak aliases
+ * themselves so that you don't have to link all drivers...
+ */
extern driver_t *libbsdport_netdriver_table
[
sizeof(libbsdport_netdriver_table_all)/sizeof(libbsdport_netdriver_table_all[0])
diff --git a/bsd_eth_drivers/libbsdport/bus.h b/bsd_eth_drivers/libbsdport/bus.h
index 19cb24f..e4a9d29 100644
--- a/bsd_eth_drivers/libbsdport/bus.h
+++ b/bsd_eth_drivers/libbsdport/bus.h
@@ -17,6 +17,12 @@ typedef enum {
struct resource;
+struct resource_spec {
+ int type;
+ int rid;
+ int flags;
+};
+
typedef bus_addr_t bus_space_handle_t;
/* The 'bus_space_xxx()' inlines can be helped if the
@@ -59,7 +65,6 @@ bus_space_write_##nwidth(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
*(volatile type __attribute__((may_alias)) *)(h+o) = v; \
}\
}
-
BUS_SPACE_DECL(u_int32_t, long, 4)
BUS_SPACE_DECL(u_int16_t, word, 2)
BUS_SPACE_DECL(u_int8_t, byte, 1)
@@ -115,6 +120,8 @@ BUS_SPACE_DECL(u_int8_t, byte, 1, 8)
#error "Missing definitions of bus_space_XXX() for this CPU architecture"
#endif
+#define bus_space_write_stream_4(_t, _h, _o, _v) \
+ bus_space_write_4(_t, _h, _o, htole32(_v))
#undef BUS_SPACE_DECL
@@ -140,10 +147,17 @@ BUS_SPACE_DECL(u_int8_t, byte, 1, 8)
/* flags (1<<31) means unsupported */
#define RF_ACTIVE (1<<1)
#define RF_SHAREABLE (1<<2)
+#define RF_OPTIONAL (1<<3)
struct resource *
bus_alloc_resource_any(device_t dev, int type, int *prid, unsigned flags);
+int
+bus_alloc_resources(device_t dev, struct resource_spec *rs, struct resource **res);
+
+void
+bus_release_resources(device_t dev, const struct resource_spec *rs, struct resource **res);
+
#define FILTER_STRAY 1
#define FILTER_HANDLED 0
@@ -157,6 +171,29 @@ bus_setup_intr(device_t dev, struct resource *r, int flags, driver_filter_t filt
#define INTR_MPSAFE 0
#define INTR_TYPE_NET 0
+/*
+ * INTR_FAST handlers are already more like 'filters',
+ * i.e., they disable interrupts and schedule work
+ * on a task queue.
+ *
+ * During porting the fast handler has to be slightly
+ * rewritten (must return an int value, FILTER_HANDLED
+ * if a valid IRQ was detected and work has been scheduled
+ * and FILTER_STRAY if this device didn't interrupt).
+ *
+ * You need to then remove INTR_FAST from the flags,
+ * pass the converted handler as the 'filter' argument
+ * and a NULL handler argument to bus_setup_intr().
+ *
+ */
+extern int __INTR_FAST() __attribute__((
+ error("\n\n==> you need to convert bus_setup_intr(INTR_FAST) to new API;\n"
+ " consult <sys/bus.h>\n\n")
+));
+
+/* Barf at compile time if they try to use INTR_FAST */
+#define INTR_FAST (__INTR_FAST())
+
int
bus_teardown_intr(device_t dev, struct resource *r, void *cookiep);
@@ -177,6 +214,37 @@ rman_get_bushandle(struct resource *r);
bus_space_tag_t
rman_get_bustag(struct resource *r);
+/* Newer API (releng 7_1) */
+static inline u_int8_t bus_read_1(struct resource *r, bus_size_t o)
+{
+ return bus_space_read_1(rman_get_bustag(r), rman_get_bushandle(r), o);
+}
+
+static inline u_int16_t bus_read_2(struct resource *r, bus_size_t o)
+{
+ return bus_space_read_2(rman_get_bustag(r), rman_get_bushandle(r), o);
+}
+
+static inline u_int32_t bus_read_4(struct resource *r, bus_size_t o)
+{
+ return bus_space_read_4(rman_get_bustag(r), rman_get_bushandle(r), o);
+}
+
+static inline void bus_write_1(struct resource *r, bus_size_t o, u_int8_t v)
+{
+ bus_space_write_1(rman_get_bustag(r), rman_get_bushandle(r), o, v);
+}
+
+static inline void bus_write_2(struct resource *r, bus_size_t o, u_int16_t v)
+{
+ bus_space_write_2(rman_get_bustag(r), rman_get_bushandle(r), o, v);
+}
+
+static inline void bus_write_4(struct resource *r, bus_size_t o, u_int32_t v)
+{
+ bus_space_write_4(rman_get_bustag(r), rman_get_bushandle(r), o, v);
+}
+
#ifndef BUS_DMA_NOWAIT
/* ignored anyways */
#define BUS_DMA_NOWAIT 0
@@ -192,6 +260,20 @@ rman_get_bustag(struct resource *r);
#define BUS_DMA_COHERENT 0
#endif
+#ifndef BUS_DMA_ZERO
+/* ignored anyways */
+#define BUS_DMA_ZERO 0
+#endif
+
+#ifndef BUS_DMA_ALLOCNOW
+/* ignored anyways */
+#define BUS_DMA_ALLOCNOW 0
+#endif
+
+#ifndef BUS_DMA_ZERO
+#define BUS_DMA_ZERO 1
+#endif
+
/* unused */
#ifndef BUS_SPACE_MAXADDR
#define BUS_SPACE_MAXADDR 0xdeadbeef
@@ -223,6 +305,12 @@ typedef void *bus_dmamap_t;
int
bus_dma_tag_create(void *parent, unsigned alignment, unsigned bounds, uint32_t lowadd, uint32_t hiaddr, void (*filter)(void*), void *filterarg, unsigned maxsize, int nsegs, unsigned maxsegsize, unsigned flags, void (*lockfunc)(void*), void *lockarg, bus_dma_tag_t *ptag);
+/* Dummy NULL fcn pointer */
+#define busdma_lock_mutex 0
+
+extern uint32_t __busdma_dummy_Giant;
+#define Giant __busdma_dummy_Giant
+
void
bus_dma_tag_destroy(bus_dma_tag_t tag);
@@ -265,10 +353,10 @@ bus_get_dma_tag(device_t dev)
return 0;
}
-typedef void bus_dmamap_callback_t (void *, bus_dma_segment_t *, int, int);
+typedef void bus_dmamap_callback_t (void *arg, bus_dma_segment_t *segs, int nseg, int error);
static inline int
-bus_dmamap_load(bus_dma_tag_t tag, bus_dmamap_t map, caddr_t vaddr, bus_size_t size, void (*cb)(void *arg, bus_dma_segment_t *segs, int nseg, int error), void *arg, unsigned flags)
+bus_dmamap_load(bus_dma_tag_t tag, bus_dmamap_t map, void *vaddr, bus_size_t size, bus_dmamap_callback_t cb, void *arg, unsigned flags)
{
bus_dma_segment_t segs[1];
segs[0].ds_addr = CPU2BUSADDR(vaddr);
@@ -277,6 +365,28 @@ bus_dma_segment_t segs[1];
return 0;
}
+typedef void bus_dmamap_callback2_t (void *arg, bus_dma_segment_t *segs, int nsegs, bus_size_t mapsize, int error);
+
+static inline int
+bus_dmamap_load_mbuf(bus_dma_tag_t tag, bus_dmamap_t map, struct mbuf *m_head, bus_dmamap_callback2_t cb, void *arg, unsigned flags)
+{
+/* hopefully there's enough stack ... */
+bus_dma_segment_t segs[tag->maxsegs];
+struct mbuf *m;
+int n;
+bus_size_t sz;
+ for ( m=m_head, sz=0, n=0; m; m=m->m_next, n++ ) {
+ if ( n >= tag->maxsegs ) {
+ cb(arg, segs, n, sz, EFBIG);
+ return EFBIG;
+ }
+ segs[n].ds_addr = CPU2BUSADDR(mtod(m, unsigned));
+ sz += (segs[n].ds_len = m->m_len);
+ }
+ cb(arg, segs, n, sz, 0);
+ return 0;
+}
+
#define bus_dmamap_unload(tag, map) do {} while (0)
/* should we do something if we have no HW snooping ? */
@@ -285,4 +395,9 @@ bus_dma_segment_t segs[1];
#define bus_dmamap_create(tag, flags, pmap) ( *(pmap) = 0, 0 )
#define bus_dmamap_destroy(tag, map) do {} while (0)
+int
+resource_int_value(const char *name, int unit, const char *resname, int *result);
+int
+resource_long_value(const char *name, int unit, const char *resname, long *result);
+
#endif
diff --git a/bsd_eth_drivers/libbsdport/callout.h b/bsd_eth_drivers/libbsdport/callout.h
index 3f586bf..acc9de0 100644
--- a/bsd_eth_drivers/libbsdport/callout.h
+++ b/bsd_eth_drivers/libbsdport/callout.h
@@ -18,16 +18,56 @@ struct callout {
void *c_arg;
struct mtx *c_mtx;
callout_time_t c_time;
+ unsigned c_flags;
};
+#define CALLOUT_PENDING (1<<0)
+#define CALLOUT_ACTIVE (1<<1)
+
+/*
+ * Strictly, we don't need any protection
+ * because the global network semaphore
+ * takes care; however we want to
+ */
+static inline int
+callout_active(struct callout *p_c)
+{
+int rval;
+rtems_interrupt_level l;
+ rtems_interrupt_disable(l);
+ rval = p_c->c_flags & CALLOUT_ACTIVE;
+ rtems_interrupt_enable(l);
+ return rval;
+}
+
+static inline int
+callout_pending(struct callout *p_c)
+{
+int rval;
+rtems_interrupt_level l;
+ rtems_interrupt_disable(l);
+ rval = p_c->c_flags & CALLOUT_PENDING;
+ rtems_interrupt_enable(l);
+ return rval;
+}
+
+static inline void
+callout_decativate(struct callout *p_c)
+{
+rtems_interrupt_level l;
+ rtems_interrupt_disable(l);
+ p_c->c_flags &= ~CALLOUT_ACTIVE;
+ rtems_interrupt_enable(l);
+}
+
/* We cannot stop a callout that's in progress */
-void
+int
callout_stop(struct callout *c);
#define callout_drain callout_stop
-void
+int
callout_reset(struct callout *c, int ticks, void (*fn)(void*), void *arg);
void
diff --git a/bsd_eth_drivers/libbsdport/devicet.c b/bsd_eth_drivers/libbsdport/devicet.c
index f197da4..fde3975 100644
--- a/bsd_eth_drivers/libbsdport/devicet.c
+++ b/bsd_eth_drivers/libbsdport/devicet.c
@@ -12,7 +12,8 @@
#include <sys/bus.h>
#include "libbsdport_api.h"
-#undef DEBUG
+#define DEBUG 0
+int libbsdportAttachVerbose = DEBUG;
extern void real_libc_free(void*);
@@ -65,11 +66,11 @@ devattach(device_t dev, int unit, struct rtems_bsdnet_ifconfig *cfg)
{
int error;
-#ifdef DEBUG
- printf("Now attaching %s%d: (0x%x:%x.%x)\n",
- dev->name, unit,
- dev->bushdr.pci.bus, dev->bushdr.pci.dev, dev->bushdr.pci.fun);
-#endif
+ if ( libbsdportAttachVerbose ) {
+ printf("Now attaching %s%d: (0x%x:%x.%x)\n",
+ dev->name, unit,
+ dev->bushdr.pci.bus, dev->bushdr.pci.dev, dev->bushdr.pci.fun);
+ }
dev->unit = unit;
dev->ifconfig = cfg;
@@ -247,6 +248,8 @@ device_t tmpdev;
int error = 0;
int bdfunit;
+int n_bus;
+
if ( !attaching )
return ENOTSUP;
@@ -256,20 +259,33 @@ int bdfunit;
wantedunit |= 1<<31;
nm[0]=0;
}
-#ifdef DEBUG
- printf("Wanted unit is 0x%x, pattern '%s'\n", wantedunit, nm);
+ if ( libbsdportAttachVerbose )
+ printf("Wanted unit is 0x%x, pattern '%s'\n", wantedunit, nm);
+
+ n_bus = pci_bus_count();
+#ifdef __i386__
+ /* ugliest of all hacks -- RTEMS routine is currently (4.9)
+ * still broken; it reports the (0-based) highest bus number
+ * instead of the count.
+ */
+ n_bus++;
#endif
unit = 0;
for ( i=0; (dr=libbsdport_netdriver_table[i]); i++ ) {
+
+ /* unused slot ? */
+ if ( 0 == dr->name && 0 == dr->methods )
+ continue;
+
/* Find matching driver */
-#ifdef DEBUG
- printf("Trying driver '%s' ...", dr->name);
-#endif
+ if ( libbsdportAttachVerbose )
+ printf("Trying driver '%s' ...", dr->name);
+
if ( matches(dr, nm) ) {
-#ifdef DEBUG
- printf("MATCH\n");
-#endif
+
+ if ( libbsdportAttachVerbose )
+ printf("MATCH\n");
assert( dr->methods );
@@ -281,7 +297,7 @@ int bdfunit;
}
dev = devalloc(dr);
- for ( b=0; b<pci_bus_count(); b++)
+ for ( b=0; b<n_bus; b++ )
for ( d=0; d<PCI_MAX_DEVICES; d++ ) {
for ( f=0; f<pci_num_functions(b,d); f++ ) {
if ( ! pci_is_ether(b,d,f) )
@@ -293,10 +309,10 @@ int bdfunit;
bdfunit = (b<<8) | PCI_DEVFN(d,f);
-#ifdef DEBUG
- printf("Probing PCI 0x%x:%x.%x\n",
- bdfunit>>8, PCI_SLOT(bdfunit), PCI_FUNC(bdfunit));
-#endif
+ if ( libbsdportAttachVerbose ) {
+ printf("Probing PCI 0x%x:%x.%x\n",
+ bdfunit>>8, PCI_SLOT(bdfunit), PCI_FUNC(bdfunit));
+ }
/* has this device been attached already ? */
if ( (tmpdev = devattached(dev)) ) {
@@ -319,9 +335,9 @@ int bdfunit;
/* wanted unit == 0 means next avail.
* unit is acceptable.
*/
-#ifdef DEBUG
- printf("->SUCCESS\n");
-#endif
+ if ( libbsdportAttachVerbose )
+ printf("->SUCCESS\n");
+
if ( 0 == wantedunit || UNITMATCH(wantedunit, unit, bdfunit) ) {
error = devattach(dev, thisunit, cfg);
if ( !error )
@@ -331,9 +347,8 @@ int bdfunit;
break;
default:
-#ifdef DEBUG
- printf("->FAILED\n");
-#endif
+ if ( libbsdportAttachVerbose )
+ printf("->FAILED\n");
/* probe failed */
break;
}
@@ -343,9 +358,11 @@ int bdfunit;
} /* for all busses + slots */
devfree(dev); dev = 0;
} /* matching driver */
-#ifdef DEBUG
- else printf("NO MATCH\n");
-#endif
+ else
+ {
+ if ( libbsdportAttachVerbose )
+ printf("NO MATCH\n");
+ }
} /* for all drivers */
/* Nothing found */
diff --git a/bsd_eth_drivers/libbsdport/ifmedia.c b/bsd_eth_drivers/libbsdport/ifmedia.c
index 77c3bd3..dc85dfd 100644
--- a/bsd_eth_drivers/libbsdport/ifmedia.c
+++ b/bsd_eth_drivers/libbsdport/ifmedia.c
@@ -50,6 +50,16 @@ struct ifmedia_entry *ifmen, *ifmep, *ifme;
}
}
+void
+ifmedia_removeall(struct ifmedia *ifm)
+{
+struct ifmedia_entry *ifmen, *ifmep;
+ for ( ifmep = LIST_FIRST(&ifm->ifm_list); ifmep; ifmep = ifmen ) {
+ ifmen = LIST_NEXT(ifmep, ifm_list);
+ free(ifmep, M_DEVBUF);
+ }
+}
+
int
ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm, u_long cmd)
{
diff --git a/bsd_eth_drivers/libbsdport/libbsdport.h b/bsd_eth_drivers/libbsdport/libbsdport.h
index 0fdd4a4..24d8da7 100644
--- a/bsd_eth_drivers/libbsdport/libbsdport.h
+++ b/bsd_eth_drivers/libbsdport/libbsdport.h
@@ -2,12 +2,19 @@
#define RTEMS_COMPAT_DEFS_H
#include <rtems.h>
-#include <sys/param.h>
+#ifndef _KERNEL
#define _KERNEL
+#endif
+#ifndef __INSIDE_RTEMS_BSD_TCPIP_STACK__
+#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
+#endif
+
#include <rtems/rtems_bsdnet.h>
#include <rtems/rtems_bsdnet_internal.h>
+#include <sys/param.h>
+
#include <inttypes.h>
#include <string.h>
@@ -31,6 +38,10 @@
#include <rtems_udelay.h>
+#ifndef bswap32
+#define bswap32(_x) CPU_swap_u32(_x)
+#endif
+
#if defined(__LITTLE_ENDIAN__) || defined(__i386__)
static inline uint16_t htole16(uint16_t v) { return v; }
static inline uint32_t htole32(uint32_t v) { return v; }
@@ -128,6 +139,17 @@ static inline void membarrier_w() { asm volatile("eieio":::"memory"); }
#error "Unknown CPU endianness"
#endif
+static __inline void
+le32enc(void *pp, uint32_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ p[0] = u & 0xff;
+ p[1] = (u >> 8) & 0xff;
+ p[2] = (u >> 16) & 0xff;
+ p[3] = (u >> 24) & 0xff;
+}
+
#include <mutex.h>
#include <callout.h>
@@ -175,6 +197,10 @@ static inline void membarrier_w() { asm volatile("eieio":::"memory"); }
#define PCIR_POWER_STATUS 0x4
#endif
+#ifndef PCIR_CACHELNSZ
+#define PCIR_CACHELNSZ PCI_CACHE_LINE_SIZE
+#endif
+
#ifndef PCIM_PSTAT_PME
#define PCIM_PSTAT_PME 0x8000
#endif
@@ -183,10 +209,17 @@ static inline void membarrier_w() { asm volatile("eieio":::"memory"); }
#define PCIM_PSTAT_PMEENABLE 0x0100
#endif
+#ifndef PCIM_CMD_MWRICEN
+#define PCIM_CMD_MWRICEN PCI_COMMAND_INVALIDATE
+#endif
+
#ifndef PCIY_PMG
#define PCIY_PMG 0x01
#endif
+#ifndef PCI_RF_DENSE
+#define PCI_RF_DENSE 0
+#endif
static inline uint32_t
pci_read_config(device_t dev, unsigned reg, int width)
@@ -259,6 +292,12 @@ pci_get_subdevice(device_t dev)
return pci_read_config(dev, PCIR_SUBDEV_0, 2);
}
+static inline uint8_t
+pci_get_revid(device_t dev)
+{
+ return pci_read_config(dev, PCIR_REVID, 1);
+}
+
static inline void
pci_enable_busmaster(device_t dev)
{
@@ -325,6 +364,9 @@ pci_release_msi(device_t dev) { }
#define if_link_state_change(ifp, state) do {} while (0)
+#define if_maddr_rlock(ifp) do {} while (0)
+#define if_maddr_runlock(ifp) do {} while (0)
+
/* if_name should probably be const char * but isn't */
#define if_initname(ifp, name, unit) \
do { (ifp)->if_name = (char*)(name); (ifp)->if_unit = (unit); } while (0)
@@ -362,12 +404,14 @@ contigfree(void *ptr, size_t size, int type);
#define __FBSDID(x)
#define MODULE_DEPEND(x1,x2,x3,x4,x5)
-#define mii_mediachg(mii) do {} while (0)
-
void *
real_libc_malloc(size_t);
void
real_libc_free(void*);
+extern int libbsdport_bootverbose;
+/* Try not to pollute global namespace */
+#define bootverbose libbsdport_bootverbose
+
#endif
diff --git a/bsd_eth_drivers/libbsdport/libbsdport_api.h b/bsd_eth_drivers/libbsdport/libbsdport_api.h
index 73b54b0..18e20ee 100644
--- a/bsd_eth_drivers/libbsdport/libbsdport_api.h
+++ b/bsd_eth_drivers/libbsdport/libbsdport_api.h
@@ -3,6 +3,7 @@
#include <rtems.h>
#include <rtems/rtems_bsdnet.h>
+#include <stdio.h>
/* $Id$ */
@@ -20,17 +21,30 @@ typedef struct driver driver_t;
extern driver_t *libbsdport_netdriver_table[];
/* Drivers ported so far: */
+
+/* Broadcom BCM57xx PCI */
+extern driver_t libbsdport_bge_driver;
+
/* Intel E1000 chips */
extern driver_t libbsdport_em_driver;
+
/* AMD 79C971..976 pcnet PCI */
extern driver_t libbsdport_pcn_driver;
+
+/* RealTek RTL8139C+, 8168, 8169, 8169S, 8110, 8101E, and 8111 PCI */
+extern driver_t libbsdport_re_driver;
+
+/* RealTek RTL8139 PCI */
+extern driver_t libbsdport_rl_driver;
+
/* AMD/Lance older (and later) chips; this driver also supports what 'pcn'
* does but might not be as efficient.
* NOTE: The 'le_pci' driver works with the pcnet32 (79C970A) emulation
* of qemu.
*/
extern driver_t libbsdport_le_pci_driver;
-
+/* Intel E100 chips */
+extern driver_t libbsdport_fxp_driver;
/* Generic driver attach function (can be used in rtems_bsdnet_ifconfig).
* This routine selects a driver/device combination based on
diff --git a/bsd_eth_drivers/libbsdport/libbsdport_post.h b/bsd_eth_drivers/libbsdport/libbsdport_post.h
index fcf7e2d..ca3fe04 100644
--- a/bsd_eth_drivers/libbsdport/libbsdport_post.h
+++ b/bsd_eth_drivers/libbsdport/libbsdport_post.h
@@ -10,6 +10,8 @@
#undef SYSCTL_ADD_INT
#define SYSCTL_ADD_INT(unused...) do { } while (0)
+
+#define RTEMS_SYSCTL_NOTYETSUP
#endif
#include <netinet/in.h>
@@ -22,9 +24,6 @@
#define IFF_DRV_RUNNING IFF_RUNNING
#define IFF_DRV_OACTIVE IFF_OACTIVE
-/* FIXME: should implement m_defrag() */
-#define m_defrag(m_headp, opt) NULL
-
static inline struct mbuf *
m_getcl(int how, int type, unsigned flags)
{
@@ -87,9 +86,35 @@ ether_setaddr(struct ifnet *ifp, u_int8_t *eaddr);
} while (0)
#define ETHER_SIOCMULTIFRAG(e, c, ifr, ifp) \
- ( ENETRESET != (e = (SIOCADDMULTI == (c) ? \
+ ( ((e) = (SIOCADDMULTI == (c) ? \
ether_addmulti((ifr), (struct arpcom*)(ifp)) : \
- ether_delmulti((ifr), (struct arpcom*)(ifp)) ))) \
+ ether_delmulti((ifr), (struct arpcom*)(ifp)) )), \
+ ((e) = ENETRESET == (e) ? 0 : (e)) )
#define arp_ifinit(ifp, ifa) arp_ifinit((struct arpcom *)ifp, ifa)
+
+#define mii_mediachg(mii) do {} while (0)
+
+/* find the currently active PHY; assume bootloader or firmware
+ * has set it up already.
+ *
+ * RETURNS: phy idx 0..31 or -1 on error
+ */
+int
+rtems_mii_phy_probe(struct rtems_mdio_info *mdio, void *if_softc);
+
+/*
+ * Defragment a mbuf chain, returning the shortest possible
+ * chain of mbufs and clusters. If allocation fails and
+ * this cannot be completed, NULL will be returned, but
+ * the passed in chain will be unchanged. Upon success,
+ * the original chain will be freed, and the new chain
+ * will be returned.
+ *
+ * If a non-packet header is passed in, the original
+ * mbuf (chain?) will be returned unharmed.
+ */
+struct mbuf *
+m_defrag(struct mbuf *m0, int how);
+
diff --git a/bsd_eth_drivers/libbsdport/miistuff.c b/bsd_eth_drivers/libbsdport/miistuff.c
new file mode 100644
index 0000000..b15545f
--- /dev/null
+++ b/bsd_eth_drivers/libbsdport/miistuff.c
@@ -0,0 +1,58 @@
+#include <rtems.h>
+#define _KERNEL
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/rtems_bsdnet_internal.h>
+
+#include <bsp/rtems_verscheck.h>
+
+#include <sys/malloc.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#include <net/if_media.h>
+#include <rtems/rtems_mii_ioctl.h>
+
+#define PHY_MAX 32
+
+#undef DEBUG
+
+/* A helper to find the active PHY. We really should port
+ * the entire BSD miibus/phy support but that's a bigger
+ * project...
+ */
+int
+rtems_mii_phy_probe(struct rtems_mdio_info *mdio, void *softc)
+{
+int phy;
+uint32_t bmsr, bmcr;
+ for ( phy = 0; phy<PHY_MAX; phy++ ) {
+ if ( mdio->mdio_r(phy, softc, MII_BMSR, &bmsr) )
+ continue;
+
+ bmsr &= 0xffff;
+
+ if ( 0 == bmsr || 0xffff == bmsr )
+ continue; /* nothing here */
+
+ /* no media supported ? */
+ if ( 0 == ((BMSR_EXTSTAT | 0xfe00) & bmsr ) )
+ continue; /* probably nothing there */
+
+ if ( mdio->mdio_r(phy, softc, MII_BMCR, &bmcr) )
+ continue;
+
+ /* skip isolated or powered-down phys */
+ if ( (BMCR_PDOWN | BMCR_ISO) & bmcr )
+ continue;
+
+#ifdef DEBUG
+ printk("PHY #%u seems active; link status is %s\n", phy, BMSR_LINK & bmsr ? "UP" : "DOWN");
+#endif
+
+ /* seems we found one */
+ return phy;
+ }
+
+ return -1;
+}
diff --git a/bsd_eth_drivers/libbsdport/misc.c b/bsd_eth_drivers/libbsdport/misc.c
new file mode 100644
index 0000000..68e3c03
--- /dev/null
+++ b/bsd_eth_drivers/libbsdport/misc.c
@@ -0,0 +1,179 @@
+
+#include <libbsdport.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
+#include <sys/mbuf.h>
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+
+#include <libbsdport_post.h>
+
+int libbsdport_bootverbose = 0;
+
+#ifdef WITNESS
+#define MBUF_CHECKSLEEP(how) do {\
+ if (how == M_WAITOK)\
+ WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,\
+ "Sleeping in \"%s\"", __func__);\
+ } while (0)
+#else
+#define MBUF_CHECKSLEEP(how)
+#endif
+
+#define MBTOM(how)(how)
+
+u_int
+m_length(struct mbuf *m0, struct mbuf **last)
+{
+ struct mbuf *m;
+ u_int len;
+
+ len = 0;
+ for (m = m0; m != NULL; m = m->m_next) {
+ len += m->m_len;
+ if (m->m_next == NULL)
+ break;
+ }
+ if (last != NULL)
+ *last = m;
+ return (len);
+}
+
+/*
+ * Duplicate "from"'s mbuf pkthdr in "to".
+ * "from" must have M_PKTHDR set, and "to" must be empty.
+ * In particular, this does a deep copy of the packet tags.
+ */
+int
+m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how)
+{
+
+ #if 0
+ /*
+ * The mbuf allocator only initializes the pkthdr
+ * when the mbuf is allocated with MGETHDR. Many users
+ * (e.g. m_copy*, m_prepend) use MGET and then
+ * smash the pkthdr as needed causing these
+ * assertions to trip. For now just disable them.
+ */
+ M_ASSERTPKTHDR(to);
+ /* Note: with MAC, this may not be a good assertion. */
+ KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags), ("m_dup_pkthdr: to has tags"));
+ #endif
+ MBUF_CHECKSLEEP(how);
+ #ifdef MAC
+ if (to->m_flags & M_PKTHDR)
+ m_tag_delete_chain(to, NULL);
+ #endif
+ to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT);
+ if ((to->m_flags & M_EXT) == 0)
+ to->m_data = to->m_pktdat;
+ to->m_pkthdr = from->m_pkthdr;
+ return 1;
+}
+
+u_int
+m_fixhdr(struct mbuf *m0)
+{
+ u_int len;
+
+ len = m_length(m0, NULL);
+ m0->m_pkthdr.len = len;
+ return (len);
+}
+
+/*
+ * Defragment a mbuf chain, returning the shortest possible
+ * chain of mbufs and clusters. If allocation fails and
+ * this cannot be completed, NULL will be returned, but
+ * the passed in chain will be unchanged. Upon success,
+ * the original chain will be freed, and the new chain
+ * will be returned.
+ *
+ * If a non-packet header is passed in, the original
+ * mbuf (chain?) will be returned unharmed.
+ */
+struct mbuf *
+m_defrag(struct mbuf *m0, int how)
+{
+ struct mbuf *m_new = NULL, *m_final = NULL;
+ int progress = 0, length;
+
+ MBUF_CHECKSLEEP(how);
+ if (!(m0->m_flags & M_PKTHDR))
+ return (m0);
+
+ m_fixhdr(m0); /* Needed sanity check */
+
+ #ifdef MBUF_STRESS_TEST
+ if (m_defragrandomfailures) {
+ int temp = arc4random() & 0xff;
+ if (temp == 0xba)
+ goto nospace;
+ }
+ #endif
+
+ if (m0->m_pkthdr.len > MHLEN)
+ m_final = m_getcl(how, MT_DATA, M_PKTHDR);
+ else
+ m_final = m_gethdr(how, MT_DATA);
+
+ if (m_final == NULL)
+ goto nospace;
+
+ if (m_dup_pkthdr(m_final, m0, how) == 0)
+ goto nospace;
+
+ m_new = m_final;
+
+ while (progress < m0->m_pkthdr.len) {
+ length = m0->m_pkthdr.len - progress;
+ if (length > MCLBYTES)
+ length = MCLBYTES;
+
+ if (m_new == NULL) {
+ if (length > MLEN)
+ m_new = m_getcl(how, MT_DATA, 0);
+ else
+ m_new = m_get(how, MT_DATA);
+ if (m_new == NULL)
+ goto nospace;
+ }
+
+ m_copydata(m0, progress, length, mtod(m_new, caddr_t));
+ progress += length;
+ m_new->m_len = length;
+ if (m_new != m_final)
+ m_cat(m_final, m_new);
+ m_new = NULL;
+ }
+ #ifdef MBUF_STRESS_TEST
+ if (m0->m_next == NULL)
+ m_defraguseless++;
+ #endif
+ m_freem(m0);
+ m0 = m_final;
+ #ifdef MBUF_STRESS_TEST
+ m_defragpackets++;
+ m_defragbytes += m0->m_pkthdr.len;
+ #endif
+ return (m0);
+ nospace:
+ #ifdef MBUF_STRESS_TEST
+ m_defragfailure++;
+ #endif
+ if (m_final)
+ m_freem(m_final);
+ return (NULL);
+}
+
diff --git a/bsd_eth_drivers/libbsdport/mutex.h b/bsd_eth_drivers/libbsdport/mutex.h
index 5476e37..8f0b5e6 100644
--- a/bsd_eth_drivers/libbsdport/mutex.h
+++ b/bsd_eth_drivers/libbsdport/mutex.h
@@ -46,7 +46,8 @@ mtx_destroy(struct mtx *m)
}
/* what ? */
-#define MA_OWNED 1
+#define MA_OWNED 1
+#define MA_NOTOWNED 0
static inline void
mtx_assert(struct mtx *m, int what)
{
diff --git a/bsd_eth_drivers/libbsdport/rtems_callout.c b/bsd_eth_drivers/libbsdport/rtems_callout.c
index ce9a477..c041c5b 100644
--- a/bsd_eth_drivers/libbsdport/rtems_callout.c
+++ b/bsd_eth_drivers/libbsdport/rtems_callout.c
@@ -100,6 +100,9 @@ LIST_KEY_DECL(k);
n = c->c_next;
if ( c->c_time <= 0 ) {
/* this one expired */
+ rtems_interrupt_disable(k1);
+ c->c_flags &= ~ CALLOUT_PENDING;
+ rtems_interrupt_enable(k1);
c_deq(c);
if ( c->c_func )
c->c_func(c->c_arg);
@@ -173,31 +176,43 @@ bail:
/* We cannot stop a callout that's in progress */
-void
+int
callout_stop(struct callout *c)
{
+rtems_interrupt_level l;
LIST_KEY_DECL(k);
if ( !c->c_pprev )
- return; /* not currently on a list */
+ return 0; /* not currently on a list */
LIST_LOCK(k);
+ /* have to check again */
+ if ( ! c->c_pprev ) {
+ LIST_UNLOCK(k);
+ return 0;
+ }
/* remove from list */
c_deq(c);
+ rtems_interrupt_disable(l);
+ c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING);
+ rtems_interrupt_enable(l);
LIST_UNLOCK(k);
+
+ return 1;
}
-void
+int
callout_reset(struct callout *c, int ticks, timeout_t fn, void *arg)
{
+rtems_interrupt_level l;
LIST_KEY_DECL(k);
-int i;
+int i, rval;
if ( ticks <= 0 )
ticks = 1;
- callout_stop(c);
+ rval = callout_stop(c);
c->c_func = fn;
c->c_arg = arg;
@@ -209,7 +224,13 @@ int i;
/* enqueue */
c_enq(&c_wheel[i], c);
+ rtems_interrupt_disable(l);
+ c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING);
+ rtems_interrupt_enable(l);
+
LIST_UNLOCK(k);
+
+ return rval;
}
static rtems_id callout_tid = 0;
diff --git a/bsd_eth_drivers/libbsdport/sysbus.c b/bsd_eth_drivers/libbsdport/sysbus.c
index fcd3aac..a88d7ad 100644
--- a/bsd_eth_drivers/libbsdport/sysbus.c
+++ b/bsd_eth_drivers/libbsdport/sysbus.c
@@ -96,6 +96,41 @@ int isio;
return (struct resource*)0;
}
+int
+bus_alloc_resources(device_t dev, struct resource_spec *rs,
+ struct resource **res)
+{
+ int i;
+
+ for (i = 0; rs[i].type != -1; i++)
+ res[i] = NULL;
+ for (i = 0; rs[i].type != -1; i++) {
+ res[i] = bus_alloc_resource_any(dev,
+ rs[i].type, &rs[i].rid, rs[i].flags);
+ if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) {
+ bus_release_resources(dev, rs, res);
+ return (ENXIO);
+ }
+ }
+ return (0);
+}
+
+void
+bus_release_resources(device_t dev, const struct resource_spec *rs,
+ struct resource **res)
+{
+ int i;
+
+ for (i = 0; rs[i].type != -1; i++)
+ if (res[i] != NULL) {
+ bus_release_resource(
+ dev, rs[i].type, rs[i].rid, res[i]);
+ res[i] = NULL;
+ }
+}
+
+
+
struct irq_cookie {
device_t dev;
driver_filter_t handler;
@@ -143,8 +178,6 @@ bus_setup_intr(device_t dev, struct resource *r, int flags, driver_filter_t filt
int rval;
struct irq_cookie *info = 0;
-
-
if ( filter && handler ) {
rtems_panic("bus_setup_intr for both: filter & handler not implemented\n");
}
@@ -154,7 +187,7 @@ struct irq_cookie *info = 0;
device_printf(dev, "bus_setup_intr: device has no driver attached\n");
return EINVAL;
} else if ( !dev->drv->methods->irq_check_dis ) {
- device_printf(dev, "bus_setup_intr: driver has no 'irq_dis' method\n");
+ device_printf(dev, "bus_setup_intr: driver has no 'irq_check_dis' method\n");
return EINVAL;
}
}
@@ -247,10 +280,13 @@ int
bus_dmamem_alloc(bus_dma_tag_t tag, void **p_vaddr, unsigned flags, bus_dmamap_t *p_map)
{
uintptr_t a;
- if ( ! (*p_map = malloc(tag->maxsize + tag->alignment, M_DEVBUF, M_NOWAIT)) )
+unsigned sz = tag->maxsize + tag->alignment;
+ if ( ! (*p_map = malloc(sz, M_DEVBUF, M_NOWAIT)) )
return ENOMEM;
a = ((uintptr_t)*p_map + tag->alignment - 1 ) & ~(tag->alignment - 1);
*p_vaddr = (void*)a;
+ if ( (BUS_DMA_ZERO & flags) )
+ memset(*p_map, 0, sz);
return 0;
}
@@ -259,3 +295,19 @@ bus_dmamem_free(bus_dma_tag_t tag, void *vaddr, bus_dmamap_t map)
{
free(map, M_DEVBUF);
}
+
+/* Dummy handle for Giant mutex */
+uint32_t __busdma_dummy_Giant = 0;
+
+int
+resource_int_value(const char *name, int unit, const char *resname, int *result)
+{
+ /* not implemented */
+ return ENOENT;
+}
+int
+resource_long_value(const char *name, int unit, const char *resname, long *result)
+{
+ /* not implemented */
+ return ENOENT;
+}
diff --git a/bsd_eth_drivers/libbsdport/taskqueue.h b/bsd_eth_drivers/libbsdport/taskqueue.h
index a341ec1..d700edf 100644
--- a/bsd_eth_drivers/libbsdport/taskqueue.h
+++ b/bsd_eth_drivers/libbsdport/taskqueue.h
@@ -31,6 +31,8 @@ taskqueue_create_fast(const char *name, int mflags, tq_enq_fn, void *ctxt);
int
taskqueue_enqueue(struct taskqueue *tq, struct task *ta);
+#define taskqueue_enqueue_fast(_q,_t) taskqueue_enqueue(_q,_t)
+
void
taskqueue_thread_enqueue(void *ctxt);