Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-2]: src Pull up following revision(s) (requested by riz in ticket...
details: https://anonhg.NetBSD.org/src/rev/3383d2e4f32d
branches: netbsd-2
changeset: 564515:3383d2e4f32d
user: rpaulo <rpaulo%NetBSD.org@localhost>
date: Thu Sep 07 00:14:13 2006 +0000
description:
Pull up following revision(s) (requested by riz in ticket #10680):
sys/dev/pci/if_skvar.h: revision 1.10
share/man/man4/sk.4: revision 1.9
sys/dev/pci/if_sk.c: revision 1.22
Add jumbo frames support, from OpenBSD (mcbride). As seen on tech-net
for the last N months.
Jumbo frames now work under NetBSD, so note it.
diffstat:
share/man/man4/sk.4 | 9 +-
sys/dev/pci/if_sk.c | 234 ++++++++++++++++++++++++++++++++++++++++--------
sys/dev/pci/if_skvar.h | 10 +-
3 files changed, 198 insertions(+), 55 deletions(-)
diffs (truncated from 401 to 300 lines):
diff -r 4ca3b5dc5ef2 -r 3383d2e4f32d share/man/man4/sk.4
--- a/share/man/man4/sk.4 Wed Sep 06 07:00:12 2006 +0000
+++ b/share/man/man4/sk.4 Thu Sep 07 00:14:13 2006 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: sk.4,v 1.4.4.1 2005/04/17 13:35:46 tron Exp $
+.\" $NetBSD: sk.4,v 1.4.4.2 2006/09/07 00:14:14 rpaulo Exp $
.\"
.\" Copyright (c) 2003, The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -65,7 +65,7 @@
.\"
.\" $FreeBSD: src/share/man/man4/man4.i386/sk.4,v 1.3 1999/08/28 00:20:29 peter Exp $
.\"
-.Dd December 17, 2003
+.Dd March 28, 2006
.Dt SK 4
.Os
.Sh NAME
@@ -230,11 +230,6 @@
This driver is
.Em experimental .
.Pp
-Support for the jumbo-frame feature does not currently work with
-Marvell-based adapters under
-.Nx
-and is disabled.
-.Pp
Support for checksum offload is unimplemented.
.Pp
Performance with at least some Marvell-based adapters is poor,
diff -r 4ca3b5dc5ef2 -r 3383d2e4f32d sys/dev/pci/if_sk.c
--- a/sys/dev/pci/if_sk.c Wed Sep 06 07:00:12 2006 +0000
+++ b/sys/dev/pci/if_sk.c Thu Sep 07 00:14:13 2006 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_sk.c,v 1.7.2.3.2.9 2006/06/04 14:06:34 tron Exp $ */
+/* $NetBSD: if_sk.c,v 1.7.2.3.2.10 2006/09/07 00:14:13 rpaulo Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -195,6 +195,10 @@
void sk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
void sk_reset(struct sk_softc *);
int sk_newbuf(struct sk_if_softc *, int, struct mbuf *, bus_dmamap_t);
+int sk_alloc_jumbo_mem(struct sk_if_softc *);
+void sk_free_jumbo_mem(struct sk_if_softc *);
+void *sk_jalloc(struct sk_if_softc *);
+void sk_jfree(struct mbuf *, caddr_t, size_t, void *);
int sk_init_rx_ring(struct sk_if_softc *);
int sk_init_tx_ring(struct sk_if_softc *);
u_int8_t sk_vpd_readbyte(struct sk_softc *, int);
@@ -734,7 +738,8 @@
}
for (i = 0; i < SK_RX_RING_CNT; i++) {
- if (sk_newbuf(sc_if, i, NULL, NULL) == ENOBUFS) {
+ if (sk_newbuf(sc_if, i, NULL,
+ sc_if->sk_cdata.sk_rx_jumbo_map) == ENOBUFS) {
printf("%s: failed alloc of %dth mbuf\n",
sc_if->sk_dev.dv_xname, i);
return(ENOBUFS);
@@ -781,26 +786,13 @@
sk_newbuf(struct sk_if_softc *sc_if, int i, struct mbuf *m,
bus_dmamap_t dmamap)
{
- struct sk_softc *sc = sc_if->sk_softc;
struct mbuf *m_new = NULL;
struct sk_chain *c;
struct sk_rx_desc *r;
- if (dmamap == NULL) {
- /* if (m) panic() */
-
- if (bus_dmamap_create(sc->sc_dmatag, MCLBYTES, 1, MCLBYTES,
- 0, BUS_DMA_NOWAIT, &dmamap)) {
- printf("%s: can't create recv map\n",
- sc_if->sk_dev.dv_xname);
- return(ENOMEM);
- }
- } else if (m == NULL)
- bus_dmamap_unload(sc->sc_dmatag, dmamap);
-
- sc_if->sk_cdata.sk_rx_map[i] = dmamap;
-
if (m == NULL) {
+ caddr_t buf = NULL;
+
MGETHDR(m_new, M_DONTWAIT, MT_DATA);
if (m_new == NULL) {
printf("%s: no memory for rx list -- "
@@ -809,19 +801,18 @@
}
/* Allocate the jumbo buffer */
- MCLGET(m_new, M_DONTWAIT);
- if (!(m_new->m_flags & M_EXT)) {
+ buf = sk_jalloc(sc_if);
+ if (buf == NULL) {
m_freem(m_new);
- return (ENOBUFS);
+ DPRINTFN(1, ("%s jumbo allocation failed -- packet "
+ "dropped!\n", sc_if->sk_ethercom.ec_if.if_xname));
+ return(ENOBUFS);
}
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
-
- m_adj(m_new, ETHER_ALIGN);
-
- if (bus_dmamap_load_mbuf(sc->sc_dmatag, dmamap, m_new,
- BUS_DMA_NOWAIT))
- return(ENOBUFS);
+ /* Attach the buffer to the mbuf */
+ m_new->m_len = m_new->m_pkthdr.len = SK_JLEN;
+ MEXTADD(m_new, buf, SK_JLEN, 0, sk_jfree, sc_if);
+
} else {
/*
* We're re-using a previously allocated mbuf;
@@ -829,16 +820,18 @@
* default values.
*/
m_new = m;
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
- m_adj(m_new, ETHER_ALIGN);
+ m_new->m_len = m_new->m_pkthdr.len = SK_JLEN;
m_new->m_data = m_new->m_ext.ext_buf;
}
+ m_adj(m_new, ETHER_ALIGN);
c = &sc_if->sk_cdata.sk_rx_chain[i];
r = c->sk_desc;
c->sk_mbuf = m_new;
- r->sk_data_lo = dmamap->dm_segs[0].ds_addr;
- r->sk_ctl = dmamap->dm_segs[0].ds_len | SK_RXSTAT;
+ r->sk_data_lo = dmamap->dm_segs[0].ds_addr +
+ (((vaddr_t)m_new->m_data
+ - (vaddr_t)sc_if->sk_cdata.sk_jumbo_buf));
+ r->sk_ctl = SK_JLEN | SK_RXSTAT;
SK_CDRXSYNC(sc_if, i, BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
@@ -846,6 +839,161 @@
}
/*
+ * Memory management for jumbo frames.
+ */
+
+int
+sk_alloc_jumbo_mem(struct sk_if_softc *sc_if)
+{
+ struct sk_softc *sc = sc_if->sk_softc;
+ caddr_t ptr, kva;
+ bus_dma_segment_t seg;
+ int i, rseg, state, error;
+ struct sk_jpool_entry *entry;
+
+ state = error = 0;
+
+ /* Grab a big chunk o' storage. */
+ if (bus_dmamem_alloc(sc->sc_dmatag, SK_JMEM, PAGE_SIZE, 0,
+ &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
+ printf("%s: can't alloc rx buffers\n", sc->sk_dev.dv_xname);
+ return (ENOBUFS);
+ }
+
+ state = 1;
+ if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg, SK_JMEM, &kva,
+ BUS_DMA_NOWAIT)) {
+ printf("%s: can't map dma buffers (%d bytes)\n",
+ sc->sk_dev.dv_xname, SK_JMEM);
+ error = ENOBUFS;
+ goto out;
+ }
+
+ state = 2;
+ if (bus_dmamap_create(sc->sc_dmatag, SK_JMEM, 1, SK_JMEM, 0,
+ BUS_DMA_NOWAIT, &sc_if->sk_cdata.sk_rx_jumbo_map)) {
+ printf("%s: can't create dma map\n", sc->sk_dev.dv_xname);
+ error = ENOBUFS;
+ goto out;
+ }
+
+ state = 3;
+ if (bus_dmamap_load(sc->sc_dmatag, sc_if->sk_cdata.sk_rx_jumbo_map,
+ kva, SK_JMEM, NULL, BUS_DMA_NOWAIT)) {
+ printf("%s: can't load dma map\n", sc->sk_dev.dv_xname);
+ error = ENOBUFS;
+ goto out;
+ }
+
+ state = 4;
+ sc_if->sk_cdata.sk_jumbo_buf = (caddr_t)kva;
+ DPRINTFN(1,("sk_jumbo_buf = 0x%p\n", sc_if->sk_cdata.sk_jumbo_buf));
+
+ LIST_INIT(&sc_if->sk_jfree_listhead);
+ LIST_INIT(&sc_if->sk_jinuse_listhead);
+
+ /*
+ * Now divide it up into 9K pieces and save the addresses
+ * in an array.
+ */
+ ptr = sc_if->sk_cdata.sk_jumbo_buf;
+ for (i = 0; i < SK_JSLOTS; i++) {
+ sc_if->sk_cdata.sk_jslots[i] = ptr;
+ ptr += SK_JLEN;
+ entry = malloc(sizeof(struct sk_jpool_entry),
+ M_DEVBUF, M_NOWAIT);
+ if (entry == NULL) {
+ printf("%s: no memory for jumbo buffer queue!\n",
+ sc->sk_dev.dv_xname);
+ error = ENOBUFS;
+ goto out;
+ }
+ entry->slot = i;
+ if (i)
+ LIST_INSERT_HEAD(&sc_if->sk_jfree_listhead,
+ entry, jpool_entries);
+ else
+ LIST_INSERT_HEAD(&sc_if->sk_jinuse_listhead,
+ entry, jpool_entries);
+ }
+out:
+ if (error != 0) {
+ switch (state) {
+ case 4:
+ bus_dmamap_unload(sc->sc_dmatag,
+ sc_if->sk_cdata.sk_rx_jumbo_map);
+ case 3:
+ bus_dmamap_destroy(sc->sc_dmatag,
+ sc_if->sk_cdata.sk_rx_jumbo_map);
+ case 2:
+ bus_dmamem_unmap(sc->sc_dmatag, kva, SK_JMEM);
+ case 1:
+ bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return (error);
+}
+
+/*
+ * Allocate a jumbo buffer.
+ */
+void *
+sk_jalloc(struct sk_if_softc *sc_if)
+{
+ struct sk_jpool_entry *entry;
+
+ entry = LIST_FIRST(&sc_if->sk_jfree_listhead);
+
+ if (entry == NULL)
+ return (NULL);
+
+ LIST_REMOVE(entry, jpool_entries);
+ LIST_INSERT_HEAD(&sc_if->sk_jinuse_listhead, entry, jpool_entries);
+ return (sc_if->sk_cdata.sk_jslots[entry->slot]);
+}
+
+/*
+ * Release a jumbo buffer.
+ */
+void
+sk_jfree(struct mbuf *m, caddr_t buf, size_t size, void *arg)
+{
+ struct sk_jpool_entry *entry;
+ struct sk_if_softc *sc;
+ int i, s;
+
+ /* Extract the softc struct pointer. */
+ sc = (struct sk_if_softc *)arg;
+
+ if (sc == NULL)
+ panic("sk_jfree: can't find softc pointer!");
+
+ /* calculate the slot this buffer belongs to */
+
+ i = ((vaddr_t)buf
+ - (vaddr_t)sc->sk_cdata.sk_jumbo_buf) / SK_JLEN;
+
+ if ((i < 0) || (i >= SK_JSLOTS))
+ panic("sk_jfree: asked to free buffer that we don't manage!");
+
+ s = splvm();
+ entry = LIST_FIRST(&sc->sk_jinuse_listhead);
+ if (entry == NULL)
+ panic("sk_jfree: buffer not in use!");
+ entry->slot = i;
+ LIST_REMOVE(entry, jpool_entries);
+ LIST_INSERT_HEAD(&sc->sk_jfree_listhead, entry, jpool_entries);
+
+ if (__predict_true(m != NULL))
+ pool_cache_put(&mbpool_cache, m);
+ splx(s);
+}
+
+/*
Home |
Main Index |
Thread Index |
Old Index