Subject: Re: problem with HW VLAN tagging and re(4)
To: None <tech-net@netbsd.org>
From: Pavel Cahyna <pcah8322@artax.karlin.mff.cuni.cz>
List: tech-net
Date: 01/26/2006 17:58:51
On Thu, Jan 26, 2006 at 03:46:54PM +0100, Pavel Cahyna wrote:
> I'm using the re(4) driver with a VLAN and it does not work very well. The
> tagged VLAN works reliably, but the frames which should be sent untagged
> are often tagged with the tag of the tagged VLAN. The untagged VLAN then
> does not work, of course. It improves for several minutes when I do
> ifconfig re0 down up, then it gets worse again.
> 
> Then I discovered thet the OpenBSD driver had the equivalent code always
> #ifdef-ed out.

Doing the same (and correcting one bug which breaks it on OpenBSD: they
forgot to switch VLAN stripping off) "fixes" the problem.

dmesg:
re0 at pci1 dev 3 function 0: RealTek 8169S Single-chip Gigabit Ethernet
re0: interrupting at irq 5
re0: Ethernet address 00:01:6c:34:87:14
re0: using 256 tx descriptors
ukphy0 at re0 phy 7: Generic IEEE 802.3u media interface
ukphy0: RTL8169S/8110S 1000BASE-T media interface (OUI 0x00e04c, model 0x0011), rev. 0
ukphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseT, 1000baseT-FDX, auto

diff:

Index: rtl8169.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl8169.c,v
retrieving revision 1.14.2.4
diff -u -r1.14.2.4 rtl8169.c
--- rtl8169.c   18 Aug 2005 20:40:38 -0000      1.14.2.4
+++ rtl8169.c   26 Jan 2006 15:26:25 -0000
@@ -745,8 +745,10 @@
        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 | ETHERCAP_VLAN_HWTAGGING;
+       sc->ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
+#ifdef RE_VLAN
+       sc->ethercom.ec_capabilities |= ETHERCAP_VLAN_HWTAGGING;
+#endif
        ifp->if_start = re_start;
        ifp->if_stop = re_stop;
        ifp->if_capabilities |=
@@ -1269,11 +1271,13 @@
                                m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
                }
 
+#ifdef RE_VLAN
                if (rxvlan & RTK_RDESC_VLANCTL_TAG) {
                        VLAN_INPUT_TAG(ifp, m,
                             be16toh(rxvlan & RTK_RDESC_VLANCTL_DATA),
                             continue);
                }
+#endif
 #if NBPFILTER > 0
                if (ifp->if_bpf)
                        bpf_mtap(ifp->if_bpf, m);
@@ -1511,7 +1515,9 @@
 {
        bus_dmamap_t            map;
        int                     error, i, startidx, curidx;
+#ifdef RE_VLAN
        struct m_tag            *mtag;
+#endif
        struct rtk_desc         *d;
        u_int32_t               cmdstat, rtk_flags;
        struct rtk_txq          *txq;
@@ -1625,11 +1631,13 @@
         * transmission attempt.
         */
 
+#ifdef RE_VLAN
        if ((mtag = VLAN_OUTPUT_TAG(&sc->ethercom, m)) != NULL) {
                sc->rtk_ldata.rtk_tx_list[startidx].rtk_vlanctl =
                    htole32(htons(VLAN_TAG_VALUE(mtag)) |
                    RTK_TDESC_VLANCTL_TAG);
        }
+#endif
 
        /* Transfer ownership of packet to the chip. */
 
@@ -1781,7 +1789,10 @@
                reg |= (0x1 << 14) | RTK_CPLUSCMD_PCI_MRW;;
 
        if (1)  {/* not for 8169S ? */
-               reg |= RTK_CPLUSCMD_VLANSTRIP |
+               reg |= 
+#ifdef RE_VLAN
+                   RTK_CPLUSCMD_VLANSTRIP |
+#endif
                    (ifp->if_capenable &
                    (IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4) ?
                    RTK_CPLUSCMD_RXCSUM_ENB : 0);