From owner-svn-src-all@FreeBSD.ORG Thu Oct 25 04:37:48 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 1398DD46; Thu, 25 Oct 2012 04:37:48 +0000 (UTC) (envelope-from kientzle@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D29F38FC14; Thu, 25 Oct 2012 04:37:47 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q9P4blXo074469; Thu, 25 Oct 2012 04:37:47 GMT (envelope-from kientzle@svn.freebsd.org) Received: (from kientzle@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q9P4blcV074467; Thu, 25 Oct 2012 04:37:47 GMT (envelope-from kientzle@svn.freebsd.org) Message-Id: <201210250437.q9P4blcV074467@svn.freebsd.org> From: Tim Kientzle Date: Thu, 25 Oct 2012 04:37:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r242068 - head/sys/arm/ti/cpsw X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Oct 2012 04:37:48 -0000 Author: kientzle Date: Thu Oct 25 04:37:47 2012 New Revision: 242068 URL: http://svn.freebsd.org/changeset/base/242068 Log: Do proper padding of runt packets using code copied from bge(4). Reviewed by: gnn Modified: head/sys/arm/ti/cpsw/if_cpsw.c Modified: head/sys/arm/ti/cpsw/if_cpsw.c ============================================================================== --- head/sys/arm/ti/cpsw/if_cpsw.c Thu Oct 25 04:33:47 2012 (r242067) +++ head/sys/arm/ti/cpsw/if_cpsw.c Thu Oct 25 04:37:47 2012 (r242068) @@ -581,8 +581,8 @@ cpsw_encap(struct cpsw_softc *sc, struct bd.next = 0; bd.bufptr = seg->ds_addr; bd.bufoff = 0; - bd.buflen = (seg->ds_len < 64 ? 64 : seg->ds_len); - bd.pktlen = (seg->ds_len < 64 ? 64 : seg->ds_len); + bd.buflen = seg->ds_len; + bd.pktlen = seg->ds_len; /* Set OWNERSHIP, SOP, EOP */ bd.flags = (7<<13); @@ -599,6 +599,49 @@ cpsw_encap(struct cpsw_softc *sc, struct return (0); } +/* + * Pad the packet to the minimum length for Ethernet. + * (CPSW hardware doesn't do this for us.) + */ +static int +cpsw_pad(struct mbuf *m) +{ + int padlen = ETHER_MIN_LEN - m->m_pkthdr.len; + struct mbuf *last, *n; + + if (padlen <= 0) + return (0); + + /* If there's only the packet-header and we can pad there, use it. */ + if (m->m_pkthdr.len == m->m_len && M_WRITABLE(m) && + M_TRAILINGSPACE(m) >= padlen) { + last = m; + } else { + /* + * Walk packet chain to find last mbuf. We will either + * pad there, or append a new mbuf and pad it. + */ + for (last = m; last->m_next != NULL; last = last->m_next) + ; + if (!(M_WRITABLE(last) && M_TRAILINGSPACE(last) >= padlen)) { + /* Allocate new empty mbuf, pad it. Compact later. */ + MGET(n, M_DONTWAIT, MT_DATA); + if (n == NULL) + return (ENOBUFS); + n->m_len = 0; + last->m_next = n; + last = n; + } + } + + /* Now zero the pad area. */ + memset(mtod(last, caddr_t) + last->m_len, 0, padlen); + last->m_len += padlen; + m->m_pkthdr.len += padlen; + + return (0); +} + static void cpsw_start(struct ifnet *ifp) { @@ -615,6 +658,7 @@ cpsw_start_locked(struct ifnet *ifp) struct cpsw_softc *sc = ifp->if_softc; struct mbuf *m0, *mtmp; uint32_t queued = 0; + int error; CPSW_TX_LOCK_ASSERT(sc); @@ -628,6 +672,11 @@ cpsw_start_locked(struct ifnet *ifp) if (m0 == NULL) break; + if ((error = cpsw_pad(m0))) { + m_freem(m0); + continue; + } + mtmp = m_defrag(m0, M_NOWAIT); if (mtmp) m0 = mtmp;