From ab325ab9061e577388514e428a7d5ed8331f2da7 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Tue, 20 Oct 2009 05:02:50 +0000 Subject: 2009-10-20 Chris Johns * 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. --- bsd_eth_drivers/libbsdport/alldrv.c | 3 + bsd_eth_drivers/libbsdport/bus.h | 3 +- bsd_eth_drivers/libbsdport/libbsdport.h | 3 + bsd_eth_drivers/libbsdport/libbsdport_api.h | 5 +- bsd_eth_drivers/libbsdport/libbsdport_post.h | 3 - bsd_eth_drivers/libbsdport/misc.c | 178 +++++++++++++++++++++++++++ bsd_eth_drivers/libbsdport/sysbus.c | 2 +- 7 files changed, 191 insertions(+), 6 deletions(-) (limited to 'bsd_eth_drivers/libbsdport') 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 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + 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; } } -- cgit v1.2.3