Fix hardware vlan tagging support by setting vlan information on all TX
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 18 Oct 2008 04:44:41 +0000 (04:44 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 18 Oct 2008 04:44:41 +0000 (04:44 +0000)
descriptors for multi-segment packets.

# Even with this fix in place, 8169 still does not work reliably with vlan.
# Certain packets are never seen on the wire; maybe caused by the trailing
# ether frame CRC generated by the hardware?

sys/dev/netif/re/if_re.c

index 386d0fe..0ecea3e 100644 (file)
@@ -33,7 +33,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/re/if_re.c,v 1.25 2004/06/09 14:34:01 naddy Exp $
- * $DragonFly: src/sys/dev/netif/re/if_re.c,v 1.87 2008/10/18 03:00:29 sephe Exp $
+ * $DragonFly: src/sys/dev/netif/re/if_re.c,v 1.88 2008/10/18 04:44:41 sephe Exp $
  */
 
 /*
@@ -2296,7 +2296,7 @@ re_encap(struct re_softc *sc, struct mbuf **m_head, int *idx0)
        bus_dmamap_t map;
        int error, maxsegs, idx, i;
        struct re_desc *d, *tx_ring;
-       uint32_t cmd_csum, ctl_csum;
+       uint32_t cmd_csum, ctl_csum, vlantag;
 
        KASSERT(sc->re_ldata.re_tx_free > RE_TXDESC_SPARE,
                ("not enough free TX desc\n"));
@@ -2409,6 +2409,12 @@ re_encap(struct re_softc *sc, struct mbuf **m_head, int *idx0)
                }
        }
 
+       vlantag = 0;
+       if (m->m_flags & M_VLANTAG) {
+               vlantag = htobe16(m->m_pkthdr.ether_vlantag) |
+                         RE_TDESC_CTL_INSTAG;
+       }
+
        maxsegs = sc->re_ldata.re_tx_free;
        if (maxsegs > RE_MAXSEGS)
                maxsegs = RE_MAXSEGS;
@@ -2481,7 +2487,7 @@ re_encap(struct re_softc *sc, struct mbuf **m_head, int *idx0)
                if (idx == (sc->re_tx_desc_cnt - 1))
                        cmdstat |= RE_TDESC_CMD_EOR;
                d->re_cmdstat = htole32(cmdstat | cmd_csum);
-               d->re_control = htole32(ctl_csum);
+               d->re_control = htole32(ctl_csum | vlantag);
 
                i++;
                if (i == arg.re_nsegs)
@@ -2490,17 +2496,6 @@ re_encap(struct re_softc *sc, struct mbuf **m_head, int *idx0)
        }
        d->re_cmdstat |= htole32(RE_TDESC_CMD_EOF);
 
-       /*
-        * Set up hardware VLAN tagging. Note: vlan tag info must
-        * appear in the first descriptor of a multi-descriptor
-        * transmission attempt.
-        */
-       if (m->m_flags & M_VLANTAG) {
-               tx_ring[*idx0].re_control |=
-                   htole32(htobe16(m->m_pkthdr.ether_vlantag) |
-                           RE_TDESC_CTL_INSTAG);
-       }
-
        /* Transfer ownership of packet to the chip. */
        d->re_cmdstat |= htole32(RE_TDESC_CMD_OWN);
        if (*idx0 != idx)