Subject: Re: kern/32643: re(4) has problems with HW VLAN tagging
To: None <gnats-bugs@netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 11/19/2006 12:46:04
> Maybe it is a hardware bug?
This looks a software bug.
(re_vlanctl in the DMA descriptors are not cleared)
Could you try the attached patch?
VLAN seems working on both i386 and macppc with this patch.
---
Izumi Tsutsui
Index: rtl8169.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl8169.c,v
retrieving revision 1.68
diff -u -r1.68 rtl8169.c
--- rtl8169.c 18 Nov 2006 17:39:44 -0000 1.68
+++ rtl8169.c 19 Nov 2006 03:33:11 -0000
@@ -759,16 +759,8 @@
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = re_ioctl;
- sc->ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
-
- /*
- * This is a way to disable hw VLAN tagging by default
- * (RE_VLAN is undefined), as it is problematic. PR 32643
- */
-
-#ifdef RE_VLAN
- sc->ethercom.ec_capabilities |= ETHERCAP_VLAN_HWTAGGING;
-#endif
+ sc->ethercom.ec_capabilities |=
+ ETHERCAP_VLAN_MTU | ETHERCAP_VLAN_HWTAGGING;
ifp->if_start = re_start;
ifp->if_stop = re_stop;
@@ -1083,6 +1075,7 @@
rxs->rxs_mbuf = m;
+ d->re_vlanctl = 0;
cmdstat = map->dm_segs[0].ds_len;
if (idx == (RE_RX_DESC_CNT - 1))
cmdstat |= RE_RDESC_CMD_EOR;
@@ -1287,13 +1280,11 @@
m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
}
-#ifdef RE_VLAN
if (rxvlan & RE_RDESC_VLANCTL_TAG) {
VLAN_INPUT_TAG(ifp, m,
- be16toh(rxvlan & RE_RDESC_VLANCTL_DATA),
+ bswap16(rxvlan & RE_RDESC_VLANCTL_DATA),
continue);
}
-#endif
#if NBPFILTER > 0
if (ifp->if_bpf)
bpf_mtap(ifp->if_bpf, m);
@@ -1517,9 +1508,7 @@
bus_dmamap_t map;
struct re_txq *txq;
struct re_desc *d;
-#ifdef RE_VLAN
struct m_tag *mtag;
-#endif
uint32_t cmdstat, re_flags;
int ofree, idx, error, nsegs, seg;
int startdesc, curdesc, lastdesc;
@@ -1645,6 +1634,7 @@
}
#endif
+ d->re_vlanctl = 0;
re_set_bufaddr(d, map->dm_segs[seg].ds_addr);
cmdstat = re_flags | map->dm_segs[seg].ds_len;
if (seg == 0)
@@ -1665,6 +1655,7 @@
bus_addr_t paddaddr;
d = &sc->re_ldata.re_tx_list[curdesc];
+ d->re_vlanctl = 0;
paddaddr = RE_TXPADDADDR(sc);
re_set_bufaddr(d, paddaddr);
cmdstat = re_flags |
@@ -1685,14 +1676,11 @@
* appear in the first descriptor of a multi-descriptor
* transmission attempt.
*/
-
-#ifdef RE_VLAN
if ((mtag = VLAN_OUTPUT_TAG(&sc->ethercom, m)) != NULL) {
sc->re_ldata.re_tx_list[startdesc].re_vlanctl =
- htole32(htons(VLAN_TAG_VALUE(mtag)) |
+ htole32(bswap16(VLAN_TAG_VALUE(mtag)) |
RE_TDESC_VLANCTL_TAG);
}
-#endif
/* Transfer ownership of packet to the chip. */
@@ -1795,9 +1783,7 @@
if (1) {/* not for 8169S ? */
reg |=
-#ifdef RE_VLAN
RTK_CPLUSCMD_VLANSTRIP |
-#endif
(ifp->if_capenable &
(IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_TCPv4_Rx |
IFCAP_CSUM_UDPv4_Rx) ?