From owner-svn-src-stable-8@FreeBSD.ORG Thu May 6 18:34:16 2010 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 24A84106564A; Thu, 6 May 2010 18:34:16 +0000 (UTC) (envelope-from yongari@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [69.147.83.44]) by mx1.freebsd.org (Postfix) with ESMTP id 136638FC17; Thu, 6 May 2010 18:34:16 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o46IYFbA055810; Thu, 6 May 2010 18:34:15 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o46IYFD0055807; Thu, 6 May 2010 18:34:15 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <201005061834.o46IYFD0055807@svn.freebsd.org> From: Pyun YongHyeon Date: Thu, 6 May 2010 18:34:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r207714 - stable/8/sys/dev/sge X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 8-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 May 2010 18:34:16 -0000 Author: yongari Date: Thu May 6 18:34:15 2010 New Revision: 207714 URL: http://svn.freebsd.org/changeset/base/207714 Log: MFC r207380: Enable VLAN hardware tag insertion/stripping. Due to lack of SiS190 controller, I'm not sure whether this is also applicable to SiS190 so this feature is only activated on SiS191 controller. In theory, controller reinitialization is not needed when VLAN tag configuration is changed, but xclin said controller was not stable whenever toggling VLAN tag bit. To address that, sge(4) reinitialize controller for VLAN configuration which seems to work as expected. VLAN tag information for TX/RX descriptor and configure bit of RxMacControl register was found by xclin. Submitted by: xclin cs dot nctu dot edu dot tw > (initial version) Tested by: xclin cs dot nctu dot edu dot tw > Modified: stable/8/sys/dev/sge/if_sge.c stable/8/sys/dev/sge/if_sgereg.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) stable/8/sys/geom/sched/ (props changed) Modified: stable/8/sys/dev/sge/if_sge.c ============================================================================== --- stable/8/sys/dev/sge/if_sge.c Thu May 6 18:32:02 2010 (r207713) +++ stable/8/sys/dev/sge/if_sge.c Thu May 6 18:34:15 2010 (r207714) @@ -137,6 +137,7 @@ static int sge_get_mac_addr_eeprom(struc static uint16_t sge_read_eeprom(struct sge_softc *, int); static void sge_rxfilter(struct sge_softc *); +static void sge_setvlan(struct sge_softc *); static void sge_reset(struct sge_softc *); static int sge_list_rx_init(struct sge_softc *); static int sge_list_rx_free(struct sge_softc *); @@ -484,6 +485,25 @@ sge_rxfilter(struct sge_softc *sc) } static void +sge_setvlan(struct sge_softc *sc) +{ + struct ifnet *ifp; + uint16_t rxfilt; + + SGE_LOCK_ASSERT(sc); + + ifp = sc->sge_ifp; + if ((ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) == 0) + return; + rxfilt = CSR_READ_2(sc, RxMacControl); + if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) + rxfilt |= RXMAC_STRIP_VLAN; + else + rxfilt &= ~RXMAC_STRIP_VLAN; + CSR_WRITE_2(sc, RxMacControl, rxfilt); +} + +static void sge_reset(struct sge_softc *sc) { @@ -619,6 +639,9 @@ sge_attach(device_t dev) ether_ifattach(ifp, eaddr); /* VLAN setup. */ + if ((sc->sge_flags & SGE_FLAG_SIS190) == 0) + ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | + IFCAP_VLAN_HWCSUM; ifp->if_capabilities |= IFCAP_VLAN_MTU; ifp->if_capenable = ifp->if_capabilities; /* Tell the upper layer(s) we support long frames. */ @@ -1175,9 +1198,12 @@ sge_rxeof(struct sge_softc *sc) m->m_pkthdr.csum_data = 0xffff; } } - /* - * TODO : VLAN hardware tag stripping. - */ + /* Check for VLAN tagged frame. */ + if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 && + (rxstat & RDS_VLAN) != 0) { + m->m_pkthdr.ether_vtag = rxinfo & RDC_VLAN_MASK; + m->m_flags |= M_VLANTAG; + } if ((sc->sge_flags & SGE_FLAG_SIS190) == 0) { /* * Account for 10bytes auto padding which is used @@ -1422,6 +1448,11 @@ sge_encap(struct sge_softc *sc, struct m desc->sge_flags = htole32(txsegs[0].ds_len); if (prod == SGE_TX_RING_CNT - 1) desc->sge_flags |= htole32(RING_END); + /* Configure VLAN. */ + if(((*m_head)->m_flags & M_VLANTAG) != 0) { + cflags |= (*m_head)->m_pkthdr.ether_vtag; + desc->sge_sts_size |= htole32(TDS_INS_VLAN); + } desc->sge_cmdsts = htole32(TDC_DEF | TDC_CRC | TDC_PAD | cflags); #if 1 if ((sc->sge_flags & SGE_FLAG_SPEED_1000) != 0) @@ -1563,6 +1594,7 @@ sge_init_locked(struct sge_softc *sc) rxfilt |= RXMAC_STRIP_FCS | RXMAC_PAD_ENB; CSR_WRITE_2(sc, RxMacControl, rxfilt); sge_rxfilter(sc); + sge_setvlan(sc); /* Initialize default speed/duplex information. */ if ((sc->sge_flags & SGE_FLAG_FASTETHER) == 0) @@ -1653,7 +1685,7 @@ sge_ioctl(struct ifnet *ifp, u_long comm struct sge_softc *sc; struct ifreq *ifr; struct mii_data *mii; - int error = 0, mask; + int error = 0, mask, reinit; sc = ifp->if_softc; ifr = (struct ifreq *)data; @@ -1675,6 +1707,7 @@ sge_ioctl(struct ifnet *ifp, u_long comm break; case SIOCSIFCAP: SGE_LOCK(sc); + reinit = 0; mask = ifr->ifr_reqcap ^ ifp->if_capenable; if ((mask & IFCAP_TXCSUM) != 0 && (ifp->if_capabilities & IFCAP_TXCSUM) != 0) { @@ -1687,7 +1720,24 @@ sge_ioctl(struct ifnet *ifp, u_long comm if ((mask & IFCAP_RXCSUM) != 0 && (ifp->if_capabilities & IFCAP_RXCSUM) != 0) ifp->if_capenable ^= IFCAP_RXCSUM; + if ((mask & IFCAP_VLAN_HWCSUM) != 0 && + (ifp->if_capabilities & IFCAP_VLAN_HWCSUM) != 0) + ifp->if_capenable ^= IFCAP_VLAN_HWCSUM; + if ((mask & IFCAP_VLAN_HWTAGGING) != 0 && + (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) != 0) { + /* + * Due to unknown reason, toggling VLAN hardware + * tagging require interface reinitialization. + */ + ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; + reinit = 1; + } + if (reinit > 0 && (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sge_init_locked(sc); + } SGE_UNLOCK(sc); + VLAN_CAPABILITIES(ifp); break; case SIOCADDMULTI: case SIOCDELMULTI: Modified: stable/8/sys/dev/sge/if_sgereg.h ============================================================================== --- stable/8/sys/dev/sge/if_sgereg.h Thu May 6 18:32:02 2010 (r207713) +++ stable/8/sys/dev/sge/if_sgereg.h Thu May 6 18:34:15 2010 (r207714) @@ -137,6 +137,7 @@ #define AcceptAllPhys 0x0100 #define AcceptErr 0x0020 #define AcceptRunt 0x0010 +#define RXMAC_STRIP_VLAN 0x0020 #define RXMAC_STRIP_FCS 0x0010 #define RXMAC_PAD_ENB 0x0004 @@ -187,12 +188,14 @@ #define TDC_COL 0x00040000 #define TDC_CRC 0x00020000 #define TDC_PAD 0x00010000 +#define TDC_VLAN_MASK 0x0000FFFF #define SGE_TX_INTR_FRAMES 32 /* * TX descriptor status bits. */ +#define TDS_INS_VLAN 0x80000000 #define TDS_OWC 0x00080000 #define TDS_ABT 0x00040000 #define TDS_FIFO 0x00020000 @@ -219,11 +222,12 @@ #define RDC_UCAST 0x00040000 #define RDC_CRCOFF 0x00020000 #define RDC_PREADD 0x00010000 +#define RDC_VLAN_MASK 0x0000FFFF /* * RX descriptor status bits */ -#define RDS_TAGON 0x80000000 +#define RDS_VLAN 0x80000000 #define RDS_DESCS 0x3f000000 #define RDS_ABORT 0x00800000 #define RDS_SHORT 0x00400000 @@ -240,7 +244,7 @@ #define RX_ERR_BITS "\20" \ "\21CRCOK\22COLON\23NIBON\24OVRUN" \ "\25MIIER\26LIMIT\27SHORT\30ABORT" \ - "\40TAGON" + "\40VLAN" #define RING_END 0x80000000 #define SGE_RX_BYTES(x) ((x) & 0xFFFF)