From owner-svn-src-all@FreeBSD.ORG Sat Jan 5 20:37:41 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 6F3E819C; Sat, 5 Jan 2013 20:37:41 +0000 (UTC) (envelope-from kientzle@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 52BC1177; Sat, 5 Jan 2013 20:37:41 +0000 (UTC) Received: from svn.freebsd.org (svn.FreeBSD.org [8.8.178.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r05Kbfq0053880; Sat, 5 Jan 2013 20:37:41 GMT (envelope-from kientzle@svn.freebsd.org) Received: (from kientzle@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r05KbfXW053879; Sat, 5 Jan 2013 20:37:41 GMT (envelope-from kientzle@svn.freebsd.org) Message-Id: <201301052037.r05KbfXW053879@svn.freebsd.org> From: Tim Kientzle Date: Sat, 5 Jan 2013 20:37:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r245070 - 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: Sat, 05 Jan 2013 20:37:41 -0000 Author: kientzle Date: Sat Jan 5 20:37:40 2013 New Revision: 245070 URL: http://svnweb.freebsd.org/changeset/base/245070 Log: Shuffle the TX underrun to work the same way as the RX underrun, as suggested by YongHyeon PYUN. 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 Sat Jan 5 20:37:14 2013 (r245069) +++ head/sys/arm/ti/cpsw/if_cpsw.c Sat Jan 5 20:37:40 2013 (r245070) @@ -716,26 +716,22 @@ cpsw_start_locked(struct ifnet *ifp) if (STAILQ_EMPTY(&newslots)) return; - /* Attach new segments to the hardware TX queue. */ + /* Attach the list of new buffers to the hardware TX queue. */ prev_slot = STAILQ_LAST(&sc->tx_active, cpsw_slot, next); first_new_slot = STAILQ_FIRST(&newslots); STAILQ_CONCAT(&sc->tx_active, &newslots); if (prev_slot == NULL) { /* Start the TX queue fresh. */ cpsw_write_4(CPSW_CPDMA_TX_HDP(0), - cpsw_cpdma_txbd_paddr(first_new_slot->index)); + cpsw_cpdma_txbd_paddr(first_new_slot->index)); } else { - /* Add packets to current queue. */ - /* Race: The hardware might have sent the last packet - * on the queue and stopped the transmitter just - * before we got here. In that case, this is a no-op, - * but it also means there's a TX interrupt waiting - * to be processed as soon as we release the lock here. - * That TX interrupt can detect and recover from this - * situation; see cpsw_intr_tx_locked. - */ + /* Add buffers to end of current queue. */ cpsw_cpdma_write_txbd_next(prev_slot->index, cpsw_cpdma_txbd_paddr(first_new_slot->index)); + /* If underrun, restart queue. */ + if (cpsw_cpdma_read_txbd_flags(prev_slot->index) & CPDMA_BD_EOQ) + cpsw_write_4(CPSW_CPDMA_TX_HDP(0), + cpsw_cpdma_txbd_paddr(first_new_slot->index)); } sc->tx_enqueues += enqueued; sc->tx_queued += enqueued; @@ -1091,14 +1087,10 @@ cpsw_fill_rx_queue_locked(struct cpsw_so cpsw_write_4(CPSW_CPDMA_RX_HDP(0), cpsw_cpdma_rxbd_paddr(next_slot->index)); } else { - /* Extend an existing RX queue. */ + /* Add buffers to end of current queue. */ cpsw_cpdma_write_rxbd_next(prev_slot->index, cpsw_cpdma_rxbd_paddr(next_slot->index)); - /* XXX Order matters: Previous write must complete - before next read begins in order to avoid an - end-of-queue race. I think bus_write and bus_read have - sufficient barriers built-in to ensure this. XXX */ - /* If old RX queue was stopped, restart it. */ + /* If underrun, restart queue. */ if (cpsw_cpdma_read_rxbd_flags(prev_slot->index) & CPDMA_BD_EOQ) { cpsw_write_4(CPSW_CPDMA_RX_HDP(0), cpsw_cpdma_rxbd_paddr(next_slot->index)); @@ -1170,12 +1162,6 @@ cpsw_intr_tx_locked(void *arg) /* Tell hardware the last item we dequeued. */ cpsw_write_4(CPSW_CPDMA_TX_CP(0), cpsw_cpdma_txbd_paddr(last_slot->index)); - /* If transmitter stopped and there's more, restart it. */ - /* This resolves the race described in tx_start above. */ - if ((last_flags & CPDMA_BD_EOQ) && (slot != NULL)) { - cpsw_write_4(CPSW_CPDMA_TX_HDP(0), - cpsw_cpdma_txbd_paddr(slot->index)); - } sc->tx_retires += retires; sc->tx_queued -= retires; }