From owner-svn-src-stable-9@FreeBSD.ORG Thu Dec 5 07:31:02 2013 Return-Path: <owner-svn-src-stable-9@FreeBSD.ORG> Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 9AF2B581; Thu, 5 Dec 2013 07:31:02 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 6D28E13D0; Thu, 5 Dec 2013 07:31:02 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rB57V2d7007809; Thu, 5 Dec 2013 07:31:02 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.7/8.14.7/Submit) id rB57V2i6007808; Thu, 5 Dec 2013 07:31:02 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <201312050731.rB57V2i6007808@svn.freebsd.org> From: Pyun YongHyeon <yongari@FreeBSD.org> Date: Thu, 5 Dec 2013 07:31:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r258966 - stable/9/sys/dev/bge X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree <svn-src-stable-9.freebsd.org> List-Unsubscribe: <http://lists.freebsd.org/mailman/options/svn-src-stable-9>, <mailto:svn-src-stable-9-request@freebsd.org?subject=unsubscribe> List-Archive: <http://lists.freebsd.org/pipermail/svn-src-stable-9/> List-Post: <mailto:svn-src-stable-9@freebsd.org> List-Help: <mailto:svn-src-stable-9-request@freebsd.org?subject=help> List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9>, <mailto:svn-src-stable-9-request@freebsd.org?subject=subscribe> X-List-Received-Date: Thu, 05 Dec 2013 07:31:02 -0000 Author: yongari Date: Thu Dec 5 07:31:01 2013 New Revision: 258966 URL: http://svnweb.freebsd.org/changeset/base/258966 Log: MFC r253540: 5725 family of devices corrupts TSO packets when TSO DMA buffers cross into regions which are within MSS bytes of a 4GB boundary. If we encounter the condition, drop the packet. Modified: stable/9/sys/dev/bge/if_bge.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/dev/ (props changed) Modified: stable/9/sys/dev/bge/if_bge.c ============================================================================== --- stable/9/sys/dev/bge/if_bge.c Thu Dec 5 07:29:25 2013 (r258965) +++ stable/9/sys/dev/bge/if_bge.c Thu Dec 5 07:31:01 2013 (r258966) @@ -5282,17 +5282,51 @@ bge_encap(struct bge_softc *sc, struct m csum_flags |= BGE_TXBDFLAG_VLAN_TAG; vlan_tag = m->m_pkthdr.ether_vtag; } - for (i = 0; ; i++) { - d = &sc->bge_ldata.bge_tx_ring[idx]; - d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr); - d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr); - d->bge_len = segs[i].ds_len; - d->bge_flags = csum_flags; - d->bge_vlan_tag = vlan_tag; - d->bge_mss = mss; - if (i == nsegs - 1) - break; - BGE_INC(idx, BGE_TX_RING_CNT); + + if (sc->bge_asicrev == BGE_ASICREV_BCM5762 && + (m->m_pkthdr.csum_flags & CSUM_TSO) != 0) { + /* + * 5725 family of devices corrupts TSO packets when TSO DMA + * buffers cross into regions which are within MSS bytes of + * a 4GB boundary. If we encounter the condition, drop the + * packet. + */ + for (i = 0; ; i++) { + d = &sc->bge_ldata.bge_tx_ring[idx]; + d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr); + d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr); + d->bge_len = segs[i].ds_len; + if (d->bge_addr.bge_addr_lo + segs[i].ds_len + mss < + d->bge_addr.bge_addr_lo) + break; + d->bge_flags = csum_flags; + d->bge_vlan_tag = vlan_tag; + d->bge_mss = mss; + if (i == nsegs - 1) + break; + BGE_INC(idx, BGE_TX_RING_CNT); + } + if (i != nsegs - 1) { + bus_dmamap_sync(sc->bge_cdata.bge_tx_mtag, map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag, map); + m_freem(*m_head); + *m_head = NULL; + return (EIO); + } + } else { + for (i = 0; ; i++) { + d = &sc->bge_ldata.bge_tx_ring[idx]; + d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr); + d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr); + d->bge_len = segs[i].ds_len; + d->bge_flags = csum_flags; + d->bge_vlan_tag = vlan_tag; + d->bge_mss = mss; + if (i == nsegs - 1) + break; + BGE_INC(idx, BGE_TX_RING_CNT); + } } /* Mark the last segment as end of packet... */