From owner-svn-src-all@freebsd.org Sat Nov 18 20:46:32 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BFA51DDBEB8; Sat, 18 Nov 2017 20:46:32 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 99E2F7CA4F; Sat, 18 Nov 2017 20:46:32 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id vAIKkVmb021812; Sat, 18 Nov 2017 20:46:31 GMT (envelope-from manu@FreeBSD.org) Received: (from manu@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id vAIKkVDK021811; Sat, 18 Nov 2017 20:46:31 GMT (envelope-from manu@FreeBSD.org) Message-Id: <201711182046.vAIKkVDK021811@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: manu set sender to manu@FreeBSD.org using -f From: Emmanuel Vadot Date: Sat, 18 Nov 2017 20:46:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r325979 - head/sys/arm/allwinner X-SVN-Group: head X-SVN-Commit-Author: manu X-SVN-Commit-Paths: head/sys/arm/allwinner X-SVN-Commit-Revision: 325979 X-SVN-Commit-Repository: base 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.25 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: Sat, 18 Nov 2017 20:46:32 -0000 Author: manu Date: Sat Nov 18 20:46:31 2017 New Revision: 325979 URL: https://svnweb.freebsd.org/changeset/base/325979 Log: if_awg: store mbuf and dma mapping in the last segment of a tx frame instead of the first According to the datasheet, TX_DESC_CTL is cleared when whole frame is transmitted or all data in the current descriptor's buffer are transmitted. When the mbuf and mapping are stored in the first segment and in a scenario where a tx completion interrupt arrives for a frame and only the start of the next frame was transmitted, at the time of interrupt processing the mbuf and mapping will be freed when processing the first segment of the next frame but the other untrasmitted segments still need to use them. Submitted by: Guy Yur Differential Revision: https://reviews.freebsd.org/D13031 Modified: head/sys/arm/allwinner/if_awg.c Modified: head/sys/arm/allwinner/if_awg.c ============================================================================== --- head/sys/arm/allwinner/if_awg.c Sat Nov 18 20:42:48 2017 (r325978) +++ head/sys/arm/allwinner/if_awg.c Sat Nov 18 20:46:31 2017 (r325979) @@ -390,17 +390,19 @@ awg_media_change(if_t ifp) static int awg_setup_txbuf(struct awg_softc *sc, int index, struct mbuf **mp) { + bus_dmamap_t map; bus_dma_segment_t segs[TX_MAX_SEGS]; - int error, nsegs, cur, first, i; + int error, nsegs, cur, first, last, i; u_int csum_flags; uint32_t flags, status; struct mbuf *m; cur = first = index; + map = sc->tx.buf_map[first].map; m = *mp; - error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag, - sc->tx.buf_map[index].map, m, segs, &nsegs, BUS_DMA_NOWAIT); + error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag, map, m, segs, + &nsegs, BUS_DMA_NOWAIT); if (error == EFBIG) { m = m_collapse(m, M_NOWAIT, TX_MAX_SEGS); if (m == NULL) { @@ -408,16 +410,15 @@ awg_setup_txbuf(struct awg_softc *sc, int index, struc return (0); } *mp = m; - error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag, - sc->tx.buf_map[index].map, m, segs, &nsegs, BUS_DMA_NOWAIT); + error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag, map, m, + segs, &nsegs, BUS_DMA_NOWAIT); } if (error != 0) { device_printf(sc->dev, "awg_setup_txbuf: bus_dmamap_load_mbuf_sg failed\n"); return (0); } - bus_dmamap_sync(sc->tx.buf_tag, sc->tx.buf_map[index].map, - BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(sc->tx.buf_tag, map, BUS_DMASYNC_PREWRITE); flags = TX_FIR_DESC; status = 0; @@ -458,7 +459,11 @@ awg_setup_txbuf(struct awg_softc *sc, int index, struc cur = TX_NEXT(cur); } - sc->tx.buf_map[first].mbuf = m; + /* Store mapping and mbuf in the last segment */ + last = TX_SKIP(cur, TX_DESC_COUNT - 1); + sc->tx.buf_map[first].map = sc->tx.buf_map[last].map; + sc->tx.buf_map[last].map = map; + sc->tx.buf_map[last].mbuf = m; /* * The whole mbuf chain has been DMA mapped,