From 20f3ba36d7a941e49123904e6ddee387e363346f Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Thu, 20 Mar 2008 23:54:58 +0000 Subject: VLAN tag info must be inserted into all descriptors of a multi-descriptor packet transmission. From NetBSD Fixes PR 5655. Tested by Panagiotis Efstratiou , brad@ and sthen@ --- sys/dev/ic/re.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'sys/dev/ic') 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; @@ -1599,6 +1599,17 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx) bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 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 @@ -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 |= -- cgit v1.2.3