From owner-svn-src-projects@FreeBSD.ORG Thu May 21 22:12:45 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 14B2F106566B; Thu, 21 May 2009 22:12:45 +0000 (UTC) (envelope-from dwhite@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 877878FC0A; Thu, 21 May 2009 22:12:42 +0000 (UTC) (envelope-from dwhite@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n4LMCg55085995; Thu, 21 May 2009 22:12:42 GMT (envelope-from dwhite@svn.freebsd.org) Received: (from dwhite@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n4LMCgQ9085994; Thu, 21 May 2009 22:12:42 GMT (envelope-from dwhite@svn.freebsd.org) Message-Id: <200905212212.n4LMCgQ9085994@svn.freebsd.org> From: Doug White Date: Thu, 21 May 2009 22:12:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r192569 - projects/mips/sys/mips/atheros X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 May 2009 22:12:45 -0000 Author: dwhite Date: Thu May 21 22:12:42 2009 New Revision: 192569 URL: http://svn.freebsd.org/changeset/base/192569 Log: Add some missing bits to arge: * In arge_attach(), hard reset the MAC blocks before configuring the MAC. * In arge_reset_dma(), clear pending packet interrupts based off the hardware counter instead of acking every packet in the ring, as the hardware counter can exceed the ring size. If the reset was successful the counters will be zero anyway. * In arge_encap(), remove an unused variable. * In arge_tx_locked(), remove redundant setting of the EMPTY flag as the TX DMA engine sets it for us. * In arge_intr(), remember to clear the interrupt status bits relayed from arge_intr_filter(). * Handle RX overflow and TX underflow. * In arge_tx_intr(), remember to unmask the TX interrupt bits after processing them. Modified: projects/mips/sys/mips/atheros/if_arge.c Modified: projects/mips/sys/mips/atheros/if_arge.c ============================================================================== --- projects/mips/sys/mips/atheros/if_arge.c Thu May 21 21:21:22 2009 (r192568) +++ projects/mips/sys/mips/atheros/if_arge.c Thu May 21 22:12:42 2009 (r192569) @@ -306,6 +306,28 @@ arge_attach(device_t dev) goto fail; } + /* Initialize the MAC block */ + + /* Step 1. Soft-reset MAC */ + ARGE_SET_BITS(sc, AR71XX_MAC_CFG1, MAC_CFG1_SOFT_RESET); + DELAY(20); + + /* Step 2. Punt the MAC core from the central reset register */ + reg = ATH_READ_REG(AR71XX_RST_RESET); + if (sc->arge_mac_unit == 0) + reg |= RST_RESET_GE0_MAC; + else if (sc->arge_mac_unit == 1) + reg |= RST_RESET_GE1_MAC; + ATH_WRITE_REG(AR71XX_RST_RESET, reg); + DELAY(100); + reg = ATH_READ_REG(AR71XX_RST_RESET); + if (sc->arge_mac_unit == 0) + reg &= ~RST_RESET_GE0_MAC; + else if (sc->arge_mac_unit == 1) + reg &= ~RST_RESET_GE1_MAC; + ATH_WRITE_REG(AR71XX_RST_RESET, reg); + + /* Step 3. Reconfigure MAC block */ ARGE_WRITE(sc, AR71XX_MAC_CFG1, MAC_CFG1_SYNC_RX | MAC_CFG1_RX_ENABLE | MAC_CFG1_SYNC_TX | MAC_CFG1_TX_ENABLE); @@ -612,13 +634,13 @@ arge_reset_dma(struct arge_softc *sc) ARGE_WRITE(sc, AR71XX_DMA_TX_DESC, 0); /* Clear all possible RX interrupts */ - for (i = 0; i < ARGE_RX_RING_COUNT; i++) + while(ARGE_READ(sc, AR71XX_DMA_RX_STATUS) & DMA_RX_STATUS_PKT_RECVD) ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_PKT_RECVD); /* * Clear all possible TX interrupts */ - for (i = 0; i < ARGE_TX_RING_COUNT; i++) + while(ARGE_READ(sc, AR71XX_DMA_TX_STATUS) & DMA_TX_STATUS_PKT_SENT) ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_PKT_SENT); /* @@ -694,7 +716,7 @@ arge_encap(struct arge_softc *sc, struct struct arge_txdesc *txd; struct arge_desc *desc, *prev_desc; bus_dma_segment_t txsegs[ARGE_MAXFRAGS]; - int error, i, nsegs, prod, si, prev_prod; + int error, i, nsegs, prod, prev_prod; ARGE_LOCK_ASSERT(sc); @@ -724,8 +746,6 @@ arge_encap(struct arge_softc *sc, struct bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap, BUS_DMASYNC_PREWRITE); - si = prod; - /* * Make a list of descriptors for this packet. DMA controller will * walk through it while arge_link is not zero. @@ -1361,8 +1381,6 @@ arge_tx_locked(struct arge_softc *sc) txd = &sc->arge_cdata.arge_txdesc[cons]; - cur_tx->packet_ctrl = ARGE_DESC_EMPTY; - ifp->if_opackets++; bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap, @@ -1375,7 +1393,6 @@ arge_tx_locked(struct arge_softc *sc) txd->tx_m = NULL; /* reset descriptor */ - cur_tx->packet_ctrl = ARGE_DESC_EMPTY; cur_tx->packet_addr = 0; } @@ -1463,6 +1480,13 @@ arge_rx_intr(struct arge_softc *sc, uint /* interrupts are masked by filter */ arge_rx_locked(sc); + /* RX overrun disables the receiver. Clear indication and + re-enable rx. */ + if ( status | DMA_INTR_RX_OVERFLOW) { + ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_OVERFLOW); + ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, DMA_RX_CONTROL_EN); + } + /* unmask interrupts */ ARGE_SET_BITS(sc, AR71XX_DMA_INTR, DMA_INTR_RX_OVERFLOW | DMA_INTR_RX_PKT_RCVD); @@ -1511,6 +1535,7 @@ arge_intr(void *arg) uint32_t status; status = sc->arge_intr_status; + sc->arge_intr_status = 0; #if 0 dprintf("int status(intr) = %b\n", status, @@ -1551,6 +1576,19 @@ arge_tx_intr(struct arge_softc *sc, uint /* Interrupts are masked by filter */ arge_tx_locked(sc); + /* Underrun turns off TX. Clear underrun indication. + If there's anything left in the ring, reactivate the tx. */ + if (status & DMA_INTR_TX_UNDERRUN) { + ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_UNDERRUN); + if (sc->arge_cdata.arge_tx_pkts > 0 ) { + ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, DMA_TX_CONTROL_EN); + } + } + + /* unmask interrupts */ + ARGE_SET_BITS(sc, + AR71XX_DMA_INTR, DMA_INTR_TX_UNDERRUN | DMA_INTR_TX_PKT_SENT); + ARGE_UNLOCK(sc); }