diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2008-03-20 23:54:58 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2008-03-20 23:54:58 +0000 |
commit | 20f3ba36d7a941e49123904e6ddee387e363346f (patch) | |
tree | 6308fc5e7355d8c00d68d1b1578577bdfbc1ad28 /sys/dev | |
parent | e95ad2804c61202c397a7b666dbfa6f7b3a06f64 (diff) |
VLAN tag info must be inserted into all descriptors of a multi-descriptor
packet transmission.
From NetBSD
Fixes PR 5655.
Tested by Panagiotis Efstratiou <slasher at ee dot auth dot gr>, brad@ and sthen@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/re.c | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/sys/dev/ic/re.c b/sys/dev/ic/re.c index d82e057577c..4daa4406c61 100644 --- a/sys/dev/ic/re.c +++ b/sys/dev/ic/re.c @@ -1,4 +1,4 @@ -/* $OpenBSD: re.c,v 1.77 2008/03/12 16:26:45 brad Exp $ */ +/* $OpenBSD: re.c,v 1.78 2008/03/20 23:54:57 brad Exp $ */ /* $FreeBSD: if_re.c,v 1.31 2004/09/04 07:54:05 ru Exp $ */ /* * Copyright (c) 1997, 1998-2003 @@ -1533,7 +1533,7 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx) bus_dmamap_t map; int error, seg, nsegs, uidx, startidx, curidx, lastidx, pad; struct rl_desc *d; - u_int32_t cmdstat, rl_flags = 0; + u_int32_t cmdstat, vlanctl, rl_flags = 0; struct rl_txq *txq; #if NVLAN > 0 struct ifvlan *ifv = NULL; @@ -1600,6 +1600,17 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx) BUS_DMASYNC_PREWRITE); /* + * Set up hardware VLAN tagging. Note: vlan tag info must + * appear in all descriptors of a multi-descriptor + * transmission attempt. + */ + vlanctl = 0; +#if NVLAN > 0 + if (ifv != NULL) + vlanctl = swap16(ifv->ifv_tag) | RL_TDESC_VLANCTL_TAG; +#endif + + /* * Map the segment array into descriptors. Note that we set the * start-of-frame and end-of-frame markers for either TX or RX, but * they really only have meaning in the TX case. (In the RX case, @@ -1633,7 +1644,7 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx) goto fail_unload; } - d->rl_vlanctl = 0; + d->rl_vlanctl = htole32(vlanctl); re_set_bufaddr(d, map->dm_segs[seg].ds_addr); cmdstat = rl_flags | map->dm_segs[seg].ds_len; if (seg == 0) @@ -1654,7 +1665,7 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx) bus_addr_t paddaddr; d = &sc->rl_ldata.rl_tx_list[curidx]; - d->rl_vlanctl = 0; + d->rl_vlanctl = htole32(vlanctl); paddaddr = RL_TXPADDADDR(sc); re_set_bufaddr(d, paddaddr); cmdstat = rl_flags | @@ -1670,20 +1681,6 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx) } KASSERT(lastidx != -1); - /* - * Set up hardware VLAN tagging. Note: vlan tag info must - * appear in the first descriptor of a multi-descriptor - * transmission attempt. - */ - -#if NVLAN > 0 - if (ifv != NULL) { - sc->rl_ldata.rl_tx_list[startidx].rl_vlanctl = - htole32(swap16(ifv->ifv_tag) | - RL_TDESC_VLANCTL_TAG); - } -#endif - /* Transfer ownership of packet to the chip. */ sc->rl_ldata.rl_tx_list[startidx].rl_cmdstat |= |