summaryrefslogtreecommitdiffstats
path: root/sys/dev/bge
diff options
context:
space:
mode:
authoryar <yar@FreeBSD.org>2007-06-01 02:02:39 +0000
committeryar <yar@FreeBSD.org>2007-06-01 02:02:39 +0000
commitf754fa4c1d06992c3940965346d8f0aade216783 (patch)
tree13229afe2ba946488716ab55d1e1fb6d419878d4 /sys/dev/bge
parent4a1b08f1a6c7b2f17cb585bf509b6e26a9224744 (diff)
downloadFreeBSD-src-f754fa4c1d06992c3940965346d8f0aade216783.zip
FreeBSD-src-f754fa4c1d06992c3940965346d8f0aade216783.tar.gz
Add on/off controls for VLAN_MTU and VLAN_HWTAGGING to bge(4).
Diffstat (limited to 'sys/dev/bge')
-rw-r--r--sys/dev/bge/if_bge.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 3e1a37c..e6483b9 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -342,6 +342,7 @@ static int bge_read_eeprom(struct bge_softc *, caddr_t, int, int);
static void bge_setpromisc(struct bge_softc *);
static void bge_setmulti(struct bge_softc *);
+static void bge_setvlan(struct bge_softc *);
static int bge_newbuf_std(struct bge_softc *, int, struct mbuf *);
static int bge_newbuf_jumbo(struct bge_softc *, int, struct mbuf *);
@@ -1058,6 +1059,22 @@ bge_setmulti(struct bge_softc *sc)
}
static void
+bge_setvlan(struct bge_softc *sc)
+{
+ struct ifnet *ifp;
+
+ BGE_LOCK_ASSERT(sc);
+
+ ifp = sc->bge_ifp;
+
+ /* Enable or disable VLAN tag stripping as needed. */
+ if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
+ BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_KEEP_VLAN_DIAG);
+ else
+ BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_KEEP_VLAN_DIAG);
+}
+
+static void
bge_sig_pre_reset(sc, type)
struct bge_softc *sc;
int type;
@@ -2896,7 +2913,8 @@ bge_rxeof(struct bge_softc *sc)
rxidx = cur_rx->bge_idx;
BGE_INC(sc->bge_rx_saved_considx, sc->bge_return_ring_cnt);
- if (cur_rx->bge_flags & BGE_RXBDFLAG_VLAN_TAG) {
+ if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING &&
+ cur_rx->bge_flags & BGE_RXBDFLAG_VLAN_TAG) {
have_tag = 1;
vlan_tag = cur_rx->bge_vlan_tag;
}
@@ -3591,7 +3609,8 @@ bge_init_locked(struct bge_softc *sc)
/* Specify MTU. */
CSR_WRITE_4(sc, BGE_RX_MTU, ifp->if_mtu +
- ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN);
+ ETHER_HDR_LEN + ETHER_CRC_LEN +
+ (ifp->if_capenable & IFCAP_VLAN_MTU ? ETHER_VLAN_ENCAP_LEN : 0));
/* Load our MAC address. */
m = (uint16_t *)IF_LLADDR(sc->bge_ifp);
@@ -3604,6 +3623,9 @@ bge_init_locked(struct bge_softc *sc)
/* Program multicast filter. */
bge_setmulti(sc);
+ /* Program VLAN tag stripping. */
+ bge_setvlan(sc);
+
/* Init RX ring. */
bge_init_rx_ring_std(sc);
@@ -3909,6 +3931,23 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
VLAN_CAPABILITIES(ifp);
#endif
}
+
+ if (mask & IFCAP_VLAN_MTU) {
+ ifp->if_capenable ^= IFCAP_VLAN_MTU;
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ bge_init(sc);
+ }
+
+ if (mask & IFCAP_VLAN_HWTAGGING) {
+ ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
+ BGE_LOCK(sc);
+ bge_setvlan(sc);
+ BGE_UNLOCK(sc);
+#ifdef VLAN_CAPABILITIES
+ VLAN_CAPABILITIES(ifp);
+#endif
+ }
+
break;
default:
error = ether_ioctl(ifp, command, data);
OpenPOWER on IntegriCloud