Subject: Re: kern/32643: re(4) has problems with HW VLAN tagging
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 11/19/2006 03:50:03
The following reply was made to PR kern/32643; it has been noted by GNATS.

From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
To: gnats-bugs@netbsd.org
Cc: martin@netbsd.org, kern-bug-people@netbsd.org,
	gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
	tsutsui@ceres.dti.ne.jp
Subject: Re: kern/32643: re(4) has problems with HW VLAN tagging
Date: Sun, 19 Nov 2006 12:46:04 +0900

 > 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) ?