It looks vlan tag info must appear not only in the first descriptor
but in all descriptors of a multi-descriptor transmission attempt on re(4). Problem was reported and fix was confirmed by Chris Brookes on tech-net. Should also close PR kern/37959.
This commit is contained in:
parent
d5bb355fe9
commit
0e8643dfc7
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rtl8169.c,v 1.97 2008/03/14 13:42:01 tsutsui Exp $ */
|
||||
/* $NetBSD: rtl8169.c,v 1.98 2008/03/18 14:06:56 tsutsui Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1998-2003
|
||||
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.97 2008/03/14 13:42:01 tsutsui Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.98 2008/03/18 14:06:56 tsutsui Exp $");
|
||||
/* $FreeBSD: /repoman/r/ncvs/src/sys/dev/re/if_re.c,v 1.20 2004/04/11 20:34:08 ru Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -1458,7 +1458,7 @@ re_start(struct ifnet *ifp)
|
|||
struct re_txq *txq;
|
||||
struct re_desc *d;
|
||||
struct m_tag *mtag;
|
||||
uint32_t cmdstat, re_flags;
|
||||
uint32_t cmdstat, re_flags, vlanctl;
|
||||
int ofree, idx, error, nsegs, seg;
|
||||
int startdesc, curdesc, lastdesc;
|
||||
bool pad;
|
||||
|
@ -1553,6 +1553,16 @@ re_start(struct ifnet *ifp)
|
|||
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 ((mtag = VLAN_OUTPUT_TAG(&sc->ethercom, m)) != NULL)
|
||||
vlanctl = bswap16(VLAN_TAG_VALUE(mtag)) |
|
||||
RE_TDESC_VLANCTL_TAG;
|
||||
|
||||
/*
|
||||
* Map the segment array into descriptors.
|
||||
* Note that we set the start-of-frame and
|
||||
|
@ -1583,7 +1593,7 @@ re_start(struct ifnet *ifp)
|
|||
}
|
||||
#endif
|
||||
|
||||
d->re_vlanctl = 0;
|
||||
d->re_vlanctl = htole32(vlanctl);
|
||||
re_set_bufaddr(d, map->dm_segs[seg].ds_addr);
|
||||
cmdstat = re_flags | map->dm_segs[seg].ds_len;
|
||||
if (seg == 0)
|
||||
|
@ -1604,7 +1614,7 @@ re_start(struct ifnet *ifp)
|
|||
bus_addr_t paddaddr;
|
||||
|
||||
d = &sc->re_ldata.re_tx_list[curdesc];
|
||||
d->re_vlanctl = 0;
|
||||
d->re_vlanctl = htole32(vlanctl);
|
||||
paddaddr = RE_TXPADDADDR(sc);
|
||||
re_set_bufaddr(d, paddaddr);
|
||||
cmdstat = re_flags |
|
||||
|
@ -1620,17 +1630,6 @@ re_start(struct ifnet *ifp)
|
|||
}
|
||||
KASSERT(lastdesc != -1);
|
||||
|
||||
/*
|
||||
* Set up hardware VLAN tagging. Note: vlan tag info must
|
||||
* appear in the first descriptor of a multi-descriptor
|
||||
* transmission attempt.
|
||||
*/
|
||||
if ((mtag = VLAN_OUTPUT_TAG(&sc->ethercom, m)) != NULL) {
|
||||
sc->re_ldata.re_tx_list[startdesc].re_vlanctl =
|
||||
htole32(bswap16(VLAN_TAG_VALUE(mtag)) |
|
||||
RE_TDESC_VLANCTL_TAG);
|
||||
}
|
||||
|
||||
/* Transfer ownership of packet to the chip. */
|
||||
|
||||
sc->re_ldata.re_tx_list[startdesc].re_cmdstat |=
|
||||
|
|
Loading…
Reference in New Issue