Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 2 May 2011 22:49:43 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r221351 - stable/8/sys/dev/bge
Message-ID:  <201105022249.p42MnhaZ057961@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Mon May  2 22:49:43 2011
New Revision: 221351
URL: http://svn.freebsd.org/changeset/base/221351

Log:
  MFC r220368:
    Add initial jumbo frame support for BCM5714/BCM5715 and BCM5780.
    Unlike other controllers which have more advanced jumbo support,
    these controllers have one send ring, one standard receive producer
    ring and one receive return ring. In order to receive jumbo frames
    on the controllers, driver now will increase Rx buffer size to 9k.
    Two Rx modes are supported on these controllers and I chose
    standard Rx BDs over extended Rx BDs. The extended Rx BD mode
    allows up to 4 segmentations for each Rx BDs such that kernel does
    not have to allocate large buffer of contiguous memory for
    receiving. The extended Rx BD mode is already used on controllers
    that have separate jumbo receive ring. However, using extended Rx
    BDs on BCM5714/BCM5715/BCM5780 reduces the number of Rx BDs to 256
    entries which in turn may reduce the performance.  Also UMA backed
    page allocator for jumbo frame returns contiguous memory so using
    extended Rx BD has no advantage on FreeBSD unless highly customized
    local allocator implemented in driver is used.
    To use jumbo buffers in standard receive ring, Rx buffer allocation
    handler was changed to allocate MJUM9BYTES sized mbuf.
  
    PR:		kern/155192
    Tested by:	Vijay Singh <vijju.singh <> gmail dot com>
    Submitted by:	mjacob (initial version)

Modified:
  stable/8/sys/dev/bge/if_bge.c
  stable/8/sys/dev/bge/if_bgereg.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)

Modified: stable/8/sys/dev/bge/if_bge.c
==============================================================================
--- stable/8/sys/dev/bge/if_bge.c	Mon May  2 22:03:30 2011	(r221350)
+++ stable/8/sys/dev/bge/if_bge.c	Mon May  2 22:49:43 2011	(r221351)
@@ -943,10 +943,19 @@ bge_newbuf_std(struct bge_softc *sc, int
 	bus_dmamap_t map;
 	int error, nsegs;
 
-	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
-	if (m == NULL)
-		return (ENOBUFS);
-	m->m_len = m->m_pkthdr.len = MCLBYTES;
+	if (sc->bge_flags & BGE_FLAG_JUMBO_STD &&
+	    (sc->bge_ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN +
+	    ETHER_VLAN_ENCAP_LEN > (MCLBYTES - ETHER_ALIGN))) {
+		m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
+		if (m == NULL)
+			return (ENOBUFS);
+		m->m_len = m->m_pkthdr.len = MJUM9BYTES;
+	} else {
+		m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+		if (m == NULL)
+			return (ENOBUFS);
+		m->m_len = m->m_pkthdr.len = MCLBYTES;
+	}
 	if ((sc->bge_flags & BGE_FLAG_RX_ALIGNBUG) == 0)
 		m_adj(m, ETHER_ALIGN);
 
@@ -2385,7 +2394,7 @@ static int
 bge_dma_alloc(struct bge_softc *sc)
 {
 	bus_addr_t lowaddr;
-	bus_size_t boundary, sbsz, txsegsz, txmaxsegsz;
+	bus_size_t boundary, sbsz, rxmaxsegsz, txsegsz, txmaxsegsz;
 	int i, error;
 
 	lowaddr = BUS_SPACE_MAXADDR;
@@ -2513,9 +2522,13 @@ bge_dma_alloc(struct bge_softc *sc)
 	}
 
 	/* Create tag for Rx mbufs. */
+	if (sc->bge_flags & BGE_FLAG_JUMBO_STD)
+		rxmaxsegsz = MJUM9BYTES;
+	else
+		rxmaxsegsz = MCLBYTES;
 	error = bus_dma_tag_create(sc->bge_cdata.bge_buffer_tag, 1, 0,
-	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1,
-	    MCLBYTES, 0, NULL, NULL, &sc->bge_cdata.bge_rx_mtag);
+	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, rxmaxsegsz, 1,
+	    rxmaxsegsz, 0, NULL, NULL, &sc->bge_cdata.bge_rx_mtag);
 
 	if (error) {
 		device_printf(sc->bge_dev, "could not allocate RX dma tag\n");
@@ -2759,7 +2772,7 @@ bge_attach(device_t dev)
 	case BGE_ASICREV_BCM5714_A0:
 	case BGE_ASICREV_BCM5780:
 	case BGE_ASICREV_BCM5714:
-		sc->bge_flags |= BGE_FLAG_5714_FAMILY /* | BGE_FLAG_JUMBO */;
+		sc->bge_flags |= BGE_FLAG_5714_FAMILY | BGE_FLAG_JUMBO_STD;
 		/* FALLTHROUGH */
 	case BGE_ASICREV_BCM5750:
 	case BGE_ASICREV_BCM5752:
@@ -3560,7 +3573,8 @@ bge_rxeof(struct bge_softc *sc, uint16_t
 	    sc->bge_cdata.bge_rx_return_ring_map, BUS_DMASYNC_POSTREAD);
 	bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
 	    sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_POSTWRITE);
-	if (ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN >
+	if (BGE_IS_JUMBO_CAPABLE(sc) &&
+	    ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN >
 	    (MCLBYTES - ETHER_ALIGN))
 		bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
 		    sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_POSTWRITE);
@@ -4689,7 +4703,8 @@ bge_init_locked(struct bge_softc *sc)
 	}
 
 	/* Init jumbo RX ring. */
-	if (ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN >
+	if (BGE_IS_JUMBO_CAPABLE(sc) &&
+	    ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN >
 	    (MCLBYTES - ETHER_ALIGN)) {
 		if (bge_init_rx_ring_jumbo(sc) != 0) {
 			device_printf(sc->bge_dev,
@@ -4914,14 +4929,19 @@ bge_ioctl(struct ifnet *ifp, u_long comm
 
 	switch (command) {
 	case SIOCSIFMTU:
+		if (BGE_IS_JUMBO_CAPABLE(sc) ||
+		    (sc->bge_flags & BGE_FLAG_JUMBO_STD)) {
+			if (ifr->ifr_mtu < ETHERMIN ||
+			    ifr->ifr_mtu > BGE_JUMBO_MTU) {
+				error = EINVAL;
+				break;
+			}
+		} else if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU) {
+			error = EINVAL; 
+			break;
+		}
 		BGE_LOCK(sc);
-		if (ifr->ifr_mtu < ETHERMIN ||
-		    ((BGE_IS_JUMBO_CAPABLE(sc)) &&
-		    ifr->ifr_mtu > BGE_JUMBO_MTU) ||
-		    ((!BGE_IS_JUMBO_CAPABLE(sc)) &&
-		    ifr->ifr_mtu > ETHERMTU))
-			error = EINVAL;
-		else if (ifp->if_mtu != ifr->ifr_mtu) {
+		if (ifp->if_mtu != ifr->ifr_mtu) {
 			ifp->if_mtu = ifr->ifr_mtu;
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 				ifp->if_drv_flags &= ~IFF_DRV_RUNNING;

Modified: stable/8/sys/dev/bge/if_bgereg.h
==============================================================================
--- stable/8/sys/dev/bge/if_bgereg.h	Mon May  2 22:03:30 2011	(r221350)
+++ stable/8/sys/dev/bge/if_bgereg.h	Mon May  2 22:49:43 2011	(r221351)
@@ -2748,6 +2748,7 @@ struct bge_softc {
 	uint32_t		bge_flags;
 #define	BGE_FLAG_TBI		0x00000001
 #define	BGE_FLAG_JUMBO		0x00000002
+#define	BGE_FLAG_JUMBO_STD	0x00000004
 #define	BGE_FLAG_EADDR		0x00000008
 #define	BGE_FLAG_MII_SERDES	0x00000010
 #define	BGE_FLAG_CPMU_PRESENT	0x00000020



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105022249.p42MnhaZ057961>