summaryrefslogtreecommitdiffstats
path: root/bsd_eth_drivers/libbsdport
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2009-10-20 05:02:50 +0000
committerChris Johns <chrisj@rtems.org>2009-10-20 05:02:50 +0000
commitab325ab9061e577388514e428a7d5ed8331f2da7 (patch)
treef5aee1cfc1a2eddc4a9725f3891441f6ab3163fe /bsd_eth_drivers/libbsdport
parent2009-09-12 Chris Johns <chrisj@rtems.org> (diff)
downloadlibbsdport-ab325ab9061e577388514e428a7d5ed8331f2da7.tar.bz2
2009-10-20 Chris Johns <chrisj@rtems.org>
* bsd_eth_drivers/libbsdport/sysbus.cL Fixed the print message for no IRQ handler. * bsd_eth_drivers/libbsdport/misc.c: Add m_defrag and what else it needed. The RL driver needs it. * bsd_eth_drivers/libbsdport/libbsdport_post.h: Remove the define for m_defrag. * bsd_eth_drivers/libbsdport/libbsdport.h: Add if_maddr_rlock and if_maddr_runlock. * bsd_eth_drivers/libbsdport/bus.h: Add the bus_space_write_stream_4 call. * bsd_eth_drivers/libbsdport/libbsdport_post.h, bsd_eth_drivers/libbsdport/alldrv.c, bsd_eth_drivers/if_re/Makefile.am: Add RL driver support. * bsd_eth_drivers/if_re/if_re.c, bsd_eth_drivers/if_re/if_rlreg.h: Updated to the lastest version. * bsd_eth_drivers/if_re/if_rl.c: New. This is for the Realtek 8129/8139 PCI NIC while the RE driver does only the 8139C+ version.
Diffstat (limited to 'bsd_eth_drivers/libbsdport')
-rw-r--r--bsd_eth_drivers/libbsdport/alldrv.c3
-rw-r--r--bsd_eth_drivers/libbsdport/bus.h3
-rw-r--r--bsd_eth_drivers/libbsdport/libbsdport.h3
-rw-r--r--bsd_eth_drivers/libbsdport/libbsdport_api.h5
-rw-r--r--bsd_eth_drivers/libbsdport/libbsdport_post.h3
-rw-r--r--bsd_eth_drivers/libbsdport/misc.c178
-rw-r--r--bsd_eth_drivers/libbsdport/sysbus.c2
7 files changed, 191 insertions, 6 deletions
diff --git a/bsd_eth_drivers/libbsdport/alldrv.c b/bsd_eth_drivers/libbsdport/alldrv.c
index cd199fd..c68d6d1 100644
--- a/bsd_eth_drivers/libbsdport/alldrv.c
+++ b/bsd_eth_drivers/libbsdport/alldrv.c
@@ -9,6 +9,7 @@ driver_t *libbsdport_netdriver_table_all[] = {
&libbsdport_fxp_driver,
&libbsdport_bge_driver,
&libbsdport_re_driver,
+ &libbsdport_rl_driver,
0
};
@@ -26,6 +27,8 @@ 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
diff --git a/bsd_eth_drivers/libbsdport/bus.h b/bsd_eth_drivers/libbsdport/bus.h
index 0593d9c..e4a9d29 100644
--- a/bsd_eth_drivers/libbsdport/bus.h
+++ b/bsd_eth_drivers/libbsdport/bus.h
@@ -65,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)
@@ -121,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
diff --git a/bsd_eth_drivers/libbsdport/libbsdport.h b/bsd_eth_drivers/libbsdport/libbsdport.h
index 4f0bbf8..de6eb9b 100644
--- a/bsd_eth_drivers/libbsdport/libbsdport.h
+++ b/bsd_eth_drivers/libbsdport/libbsdport.h
@@ -359,6 +359,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)
diff --git a/bsd_eth_drivers/libbsdport/libbsdport_api.h b/bsd_eth_drivers/libbsdport/libbsdport_api.h
index fddfe15..18e20ee 100644
--- a/bsd_eth_drivers/libbsdport/libbsdport_api.h
+++ b/bsd_eth_drivers/libbsdport/libbsdport_api.h
@@ -31,9 +31,12 @@ extern driver_t libbsdport_em_driver;
/* AMD 79C971..976 pcnet PCI */
extern driver_t libbsdport_pcn_driver;
-/* RealTek RTL8139, 8168, 8169, 8169S, 8110, 8101E, and 8111 PCI */
+/* 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
diff --git a/bsd_eth_drivers/libbsdport/libbsdport_post.h b/bsd_eth_drivers/libbsdport/libbsdport_post.h
index ce893c1..a760a34 100644
--- a/bsd_eth_drivers/libbsdport/libbsdport_post.h
+++ b/bsd_eth_drivers/libbsdport/libbsdport_post.h
@@ -24,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)
{
diff --git a/bsd_eth_drivers/libbsdport/misc.c b/bsd_eth_drivers/libbsdport/misc.c
index 78f1fca..68e3c03 100644
--- a/bsd_eth_drivers/libbsdport/misc.c
+++ b/bsd_eth_drivers/libbsdport/misc.c
@@ -1 +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/sysbus.c b/bsd_eth_drivers/libbsdport/sysbus.c
index cbbc2cf..a88d7ad 100644
--- a/bsd_eth_drivers/libbsdport/sysbus.c
+++ b/bsd_eth_drivers/libbsdport/sysbus.c
@@ -187,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;
}
}