Resurrecting this, I've now fixed the problem I introduced when I merged
in your changes and have tested it.
The performance on my ALIX routing from a VLAN to another non-VLAN
interface, iperf TCP went up a little (the CPU is saturated at this
point):
baseline: RX 80.0 Mbits/sec TX 65.2 Mbits/sec
hwtagging: RX 80.4 Mbits/sec TX 73.2 Mbits/sec
ok?
Index: dev/pci/if_vr.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_vr.c,v
retrieving revision 1.121
diff -u -p -r1.121 if_vr.c
--- dev/pci/if_vr.c 1 Dec 2012 09:55:03 -0000 1.121
+++ dev/pci/if_vr.c 14 Jan 2013 03:30:55 -0000
@@ -62,6 +62,7 @@
*/
#include "bpfilter.h"
+#include "vlan.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -83,6 +84,11 @@
#include <net/if_dl.h>
#include <net/if_media.h>
+#if NVLAN > 0
+#include <net/if_types.h>
+#include <net/if_vlan_var.h>
+#endif
+
#if NBPFILTER > 0
#include <net/bpf.h>
#endif
@@ -632,6 +638,12 @@ vr_attach(struct device *parent, struct
ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 |
IFCAP_CSUM_UDPv4;
+#if NVLAN > 0
+ /* if the hardware can do VLAN tagging, say so. */
+ if (sc->vr_quirks & VR_Q_HWTAG)
+ ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
+#endif
+
#ifndef SMALL_KERNEL
if (sc->vr_revid >= REV_ID_VT3065_A) {
ifp->if_capabilities |= IFCAP_WOL;
@@ -874,6 +886,21 @@ vr_rxeof(struct vr_softc *sc)
cur_rx->vr_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->sc_dmat, cur_rx->vr_map);
+#if NVLAN > 0
+ /*
+ * If there's a tagged packet, the 802.1q header will be at the
+ * 4-byte boundary following the CRC. There will be 2 bytes
+ * TPID (0x8100) and 2 bytes TCI (including VLAN ID).
+ * This isn't in the data sheet.
+ */
+ if (rxctl & VR_RXCTL_TAG) {
+ int offset = ((total_len + 3) & ~3) + 2;
+ m->m_pkthdr.ether_vtag = htons(*(u_int16_t *)
+ ((u_int8_t *)m->m_data + offset));
+ m->m_flags |= M_VLANTAG;
+ }
+#endif
+
/*
* The VIA Rhine chip includes the CRC with every
* received frame, and there's no way to turn this
@@ -1223,12 +1250,20 @@ vr_encap(struct vr_softc *sc, struct vr_
if (m_new != NULL) {
m_freem(m_head);
-
c->vr_mbuf = m_new;
} else
c->vr_mbuf = m_head;
txmap = c->vr_map;
for (i = 0; i < txmap->dm_nsegs; i++) {
+#if NVLAN > 0
+ /* Tell chip to insert VLAN tag if needed. */
+ if (m_head->m_flags & M_VLANTAG) {
+ u_int32_t vtag = m_head->m_pkthdr.ether_vtag;
+ vtag = (vtag << VR_TXSTAT_PQSHIFT) & VR_TXSTAT_PQMASK;
+ vr_status |= vtag;
+ vr_ctl |= htole32(VR_TXCTL_INSERTTAG);
+ }
+#endif
if (i != 0)
*cp = c = c->vr_nextdesc;
f = c->vr_ptr;
@@ -1254,7 +1289,7 @@ vr_encap(struct vr_softc *sc, struct vr_
sc->vr_cdata.vr_tx_cnt++;
}
- /* Set EOP on the last desciptor */
+ /* Set EOP on the last descriptor */
f->vr_ctl |= htole32(VR_TXCTL_LASTFRAG | VR_TXCTL_FINT);
return (0);
@@ -1395,6 +1430,11 @@ vr_init(void *xsc)
VR_CLRBIT(sc, VR_TXCFG, VR_TXCFG_TX_THRESH);
VR_SETBIT(sc, VR_TXCFG, VR_TXTHRESH_STORENFWD);
+
+#if NVLAN > 0
+ if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
+ VR_SETBIT(sc, VR_TXCFG, VR_TXCFG_TXTAGEN);
+#endif
/* Init circular RX list. */
if (vr_list_rx_init(sc) == ENOBUFS) {
Index: dev/pci/if_vrreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_vrreg.h,v
retrieving revision 1.32
diff -u -p -r1.32 if_vrreg.h
--- dev/pci/if_vrreg.h 20 Oct 2012 16:12:22 -0000 1.32
+++ dev/pci/if_vrreg.h 14 Jan 2013 03:30:55 -0000
@@ -83,6 +83,9 @@
#define VR_MPA_CNT 0x7C
#define VR_CRC_CNT 0x7E
#define VR_STICKHW 0x83
+#define VR_CAMMASK 0x88 /* length 4 bytes */
+#define VR_CAMCTRL 0x92
+#define VR_CAMADDR 0x93
/* Misc Registers */
#define VR_MISC_CR1 0x81
@@ -342,6 +345,14 @@
#define VR_BCR1_VLANFILT_ENB 0x80 /* 6105M */
/*
+ * CAM Control registers (VT6105M)
+ */
+#define VR_CAMCTRL_WREN 0x01
+#define VR_CAMCTRL_VCAMSEL 0x02
+#define VR_CAMCTRL_WRITE 0x04
+#define VR_CAMCTRL_READ 0x08
+
+/*
* Rhine TX/RX list structure.
*/
@@ -404,6 +415,7 @@ struct vr_desc {
#define VR_TXSTAT_ERRSUM 0x00008000
#define VR_TXSTAT_PQMASK 0x7FFF0000
#define VR_TXSTAT_OWN 0x80000000
+#define VR_TXSTAT_PQSHIFT 16
#define VR_TXCTL_BUFLEN 0x000007FF
#define VR_TXCTL_BUFLEN_EXT 0x00007800
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.