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