From owner-svn-src-all@FreeBSD.ORG Sun Mar 27 22:32:14 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7621F106566C; Sun, 27 Mar 2011 22:32:14 +0000 (UTC) (envelope-from yongari@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 63A478FC08; Sun, 27 Mar 2011 22:32:14 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p2RMWEBX071171; Sun, 27 Mar 2011 22:32:14 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p2RMWEhP071168; Sun, 27 Mar 2011 22:32:14 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <201103272232.p2RMWEhP071168@svn.freebsd.org> From: Pyun YongHyeon Date: Sun, 27 Mar 2011 22:32:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r220069 - stable/7/sys/dev/dc X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 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: Sun, 27 Mar 2011 22:32:14 -0000 Author: yongari Date: Sun Mar 27 22:32:14 2011 New Revision: 220069 URL: http://svn.freebsd.org/changeset/base/220069 Log: MFC r218789,218820,218826-218828: r218789: Remove use case of DC_TX_ONE. It was used to limit queue just 1 TX frame in DM910x controllers. In r67595(more than 10 years ago) it was replaced to use "Store and Forward" mode and made controller generate TX completion interrupt for every frame. r218820: For controllers that have TX interrupt moderation capability, request TX completion interrupt for every 8-th frames. Previously dc(4) requested TX completion interrupt if number of queued TX descriptors is greater than 64. This caused a lot of TX completion interrupt under high TX load once driver queued more than 64 TX descriptors. It's quite normal to see more than 64 queued TX descriptors under high TX load. This change reduces the number of TX completion interrupts to be less than 17k under high TX load. Because this change does not generate TX completion interrupt for each frame, add reclaiming transmitted buffers in dc_tick not to generate false watchdog timeouts. While I'm here add check for queued descriptors in dc_txeof() since there is no more work to do when there is no pending descriptors. r218826: Make sure to clear status word of TX descriptor in dc_list_tx_init(). Do not update if_opackets if the transmission had failed. r218827: There is no need to execute filter configuration when driver is not running. Remove wrong driver state change in dc_setfilt_xircom(). While I'm here nuke unnecessary assignments. r218828: Fix a long standing bug where driver handed over RX descriptor ownership to controller before completion of access to the descriptor. Driver is faking up status word so it should not give ownership to controller until it completes RX processing. Modified: stable/7/sys/dev/dc/if_dc.c stable/7/sys/dev/dc/if_dcreg.h Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/dev/dc/if_dc.c ============================================================================== --- stable/7/sys/dev/dc/if_dc.c Sun Mar 27 22:31:17 2011 (r220068) +++ stable/7/sys/dev/dc/if_dc.c Sun Mar 27 22:32:14 2011 (r220069) @@ -1335,7 +1335,6 @@ dc_setfilt_xircom(struct dc_softc *sc) DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON); DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ON); - ifp->if_drv_flags |= IFF_DRV_RUNNING; sframe->dc_status = htole32(DC_TXSTAT_OWN); CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF); @@ -2467,13 +2466,15 @@ dc_list_tx_init(struct dc_softc *sc) nexti = 0; else nexti = i + 1; + ld->dc_tx_list[i].dc_status = 0; + ld->dc_tx_list[i].dc_ctl = 0; + ld->dc_tx_list[i].dc_data = 0; ld->dc_tx_list[i].dc_next = htole32(DC_TXDESC(sc, nexti)); cd->dc_tx_chain[i] = NULL; - ld->dc_tx_list[i].dc_data = 0; - ld->dc_tx_list[i].dc_ctl = 0; } cd->dc_tx_prod = cd->dc_tx_cons = cd->dc_tx_cnt = 0; + cd->dc_tx_pkts = 0; bus_dmamap_sync(sc->dc_ltag, sc->dc_lmap, BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); return (0); @@ -2671,7 +2672,6 @@ dc_pnic_rx_bug_war(struct dc_softc *sc, * the status word to make it look like a successful * frame reception. */ - dc_newbuf(sc, i, 0); bcopy(ptr, mtod(m, char *), total_len); cur_rx->dc_status = htole32(rxstat | DC_RXSTAT_FIRSTFRAG); } @@ -2838,6 +2838,9 @@ dc_txeof(struct dc_softc *sc) int idx; u_int32_t ctl, txstat; + if (sc->dc_cdata.dc_tx_cnt == 0) + return; + ifp = sc->dc_ifp; /* @@ -2909,11 +2912,10 @@ dc_txeof(struct dc_softc *sc) dc_init_locked(sc); return; } - } - + } else + ifp->if_opackets++; ifp->if_collisions += (txstat & DC_TXSTAT_COLLCNT) >> 3; - ifp->if_opackets++; if (sc->dc_cdata.dc_tx_chain[idx] != NULL) { bus_dmamap_sync(sc->dc_mtag, sc->dc_cdata.dc_tx_map[idx], @@ -2949,6 +2951,13 @@ dc_tick(void *xsc) ifp = sc->dc_ifp; mii = device_get_softc(sc->dc_miibus); + /* + * Reclaim transmitted frames for controllers that do + * not generate TX completion interrupt for every frame. + */ + if (sc->dc_flags & DC_TX_USE_TX_INTR) + dc_txeof(sc); + if (sc->dc_flags & DC_REDUCED_MII_POLL) { if (sc->dc_flags & DC_21143_NWAY) { r = CSR_READ_4(sc, DC_10BTSTAT); @@ -3317,8 +3326,11 @@ dc_encap(struct dc_softc *sc, struct mbu htole32(DC_TXCTL_FINT); if (sc->dc_flags & DC_TX_INTR_ALWAYS) sc->dc_ldata->dc_tx_list[cur].dc_ctl |= htole32(DC_TXCTL_FINT); - if (sc->dc_flags & DC_TX_USE_TX_INTR && sc->dc_cdata.dc_tx_cnt > 64) + if (sc->dc_flags & DC_TX_USE_TX_INTR && + ++sc->dc_cdata.dc_tx_pkts >= 8) { + sc->dc_cdata.dc_tx_pkts = 0; sc->dc_ldata->dc_tx_list[cur].dc_ctl |= htole32(DC_TXCTL_FINT); + } sc->dc_ldata->dc_tx_list[first].dc_status = htole32(DC_TXSTAT_OWN); bus_dmamap_sync(sc->dc_mtag, sc->dc_cdata.dc_tx_map[idx], @@ -3386,11 +3398,6 @@ dc_start_locked(struct ifnet *ifp) * to him. */ BPF_MTAP(ifp, m_head); - - if (sc->dc_flags & DC_TX_ONE) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } } if (queued > 0) { @@ -3682,14 +3689,13 @@ dc_ioctl(struct ifnet *ifp, u_long comma } sc->dc_if_flags = ifp->if_flags; DC_UNLOCK(sc); - error = 0; break; case SIOCADDMULTI: case SIOCDELMULTI: DC_LOCK(sc); - dc_setfilt(sc); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + dc_setfilt(sc); DC_UNLOCK(sc); - error = 0; break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: Modified: stable/7/sys/dev/dc/if_dcreg.h ============================================================================== --- stable/7/sys/dev/dc/if_dcreg.h Sun Mar 27 22:31:17 2011 (r220068) +++ stable/7/sys/dev/dc/if_dcreg.h Sun Mar 27 22:32:14 2011 (r220069) @@ -495,6 +495,7 @@ struct dc_chain_data { bus_dmamap_t dc_tx_map[DC_TX_LIST_CNT]; u_int32_t *dc_sbuf; u_int8_t dc_pad[DC_MIN_FRAMELEN]; + int dc_tx_pkts; int dc_tx_first; int dc_tx_prod; int dc_tx_cons; @@ -780,7 +781,6 @@ struct dc_softc { #define DC_128BIT_HASH 0x00001000 #define DC_64BIT_HASH 0x00002000 #define DC_TULIP_LEDS 0x00004000 -#define DC_TX_ONE 0x00008000 #define DC_TX_ALIGN 0x00010000 /* align mbuf on tx */ /*