diff options
author | Yaroslav Tykhiy <ytykhiy@gmail.com> | 2007-06-01 02:02:39 +0000 |
---|---|---|
committer | Yaroslav Tykhiy <ytykhiy@gmail.com> | 2007-06-01 02:02:39 +0000 |
commit | cb2eacc7ddcd501e3fa776d0a51cf4908e1f2400 (patch) | |
tree | 13229afe2ba946488716ab55d1e1fb6d419878d4 /sys/dev/bge/if_bge.c | |
parent | bb7de6da03eb18700be9c85bffe86444080876d2 (diff) | |
download | src-cb2eacc7ddcd501e3fa776d0a51cf4908e1f2400.tar.gz src-cb2eacc7ddcd501e3fa776d0a51cf4908e1f2400.zip |
Add on/off controls for VLAN_MTU and VLAN_HWTAGGING to bge(4).
Notes
Notes:
svn path=/head/; revision=170176
Diffstat (limited to 'sys/dev/bge/if_bge.c')
-rw-r--r-- | sys/dev/bge/if_bge.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 3e1a37caee65..e6483b92f9ae 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); |