From owner-p4-projects@FreeBSD.ORG Wed Feb 4 12:42:35 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3C7251065672; Wed, 4 Feb 2009 12:42:34 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EDF8A106564A for ; Wed, 4 Feb 2009 12:42:33 +0000 (UTC) (envelope-from weongyo@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id D0AB98FC19 for ; Wed, 4 Feb 2009 12:42:33 +0000 (UTC) (envelope-from weongyo@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n14CgXXC014960 for ; Wed, 4 Feb 2009 12:42:33 GMT (envelope-from weongyo@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n14CgXj2014958 for perforce@freebsd.org; Wed, 4 Feb 2009 12:42:33 GMT (envelope-from weongyo@FreeBSD.org) Date: Wed, 4 Feb 2009 12:42:33 GMT Message-Id: <200902041242.n14CgXj2014958@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to weongyo@FreeBSD.org using -f From: Weongyo Jeong To: Perforce Change Reviews Cc: Subject: PERFORCE change 157132 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Feb 2009 12:42:35 -0000 http://perforce.freebsd.org/chv.cgi?CH=157132 Change 157132 by weongyo@weongyo_ws on 2009/02/04 12:42:14 o remove UATH_RX_DATA_LIST_COUNT macro unused anymore. o change a strategy to allocate tx buffers based on STAILQ. It's more easy and useful to handle free lists. Affected files ... .. //depot/projects/vap/sys/dev/usb/if_uath.c#13 edit .. //depot/projects/vap/sys/dev/usb/if_uathvar.h#5 edit Differences ... ==== //depot/projects/vap/sys/dev/usb/if_uath.c#13 (text+ko) ==== @@ -670,10 +670,22 @@ static int uath_alloc_tx_data_list(struct uath_softc *sc) { + int error, i; + struct uath_data *tx; - return uath_alloc_data_list(sc, - sc->sc_data_tx, UATH_TX_DATA_LIST_COUNT, - UATH_MAX_TXBUFSZ, 0 /* no mbufs */); + error = uath_alloc_data_list(sc, + sc->sc_data_tx, UATH_TX_DATA_LIST_COUNT, UATH_MAX_TXBUFSZ, + 0 /* no mbufs */); + if (error != 0) + return (error); + + STAILQ_INIT(&sc->sc_data_txhead); + for (i = 0; i < UATH_TX_DATA_LIST_COUNT; i++) { + tx = &sc->sc_data_tx[i]; + STAILQ_INSERT_HEAD(&sc->sc_data_txhead, tx, next); + } + + return (0); } static void @@ -780,6 +792,39 @@ sc->sc_cmd_rx, UATH_RX_CMD_LIST_COUNT); } +static struct uath_data * +_uath_getbuf(struct uath_softc *sc) +{ + struct uath_data *bf; + + UATH_ASSERT_LOCKED(sc); + + bf = STAILQ_FIRST(&sc->sc_data_txhead); + if (bf != NULL) + STAILQ_REMOVE_HEAD(&sc->sc_data_txhead, next); + else + bf = NULL; + if (bf == NULL) + DPRINTF(sc, UATH_DEBUG_XMIT, "%s: %s\n", __func__, + "out of xmit buffers"); + return (bf); +} + +static struct uath_data * +uath_getbuf(struct uath_softc *sc) +{ + struct uath_data *bf; + + bf = _uath_getbuf(sc); + if (bf == NULL) { + struct ifnet *ifp = sc->sc_ifp; + + DPRINTF(sc, UATH_DEBUG_XMIT, "%s: stop queue\n", __func__); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + } + return (bf); +} + /* * This function is called periodically (every second) when associated to * query device statistics. @@ -1754,15 +1799,14 @@ struct uath_data *data; struct uath_chunk *chunk; struct uath_tx_desc *desc; - int data_idx, xferlen; + int error = 0, xferlen; usbd_status status; UATH_ASSERT_LOCKED(sc); - data_idx = sc->sc_data_idx; - sc->sc_data_idx = (data_idx + 1) % UATH_TX_DATA_LIST_COUNT; - - data = &sc->sc_data_tx[data_idx]; + data = uath_getbuf(sc); + if (data == NULL) + return (ENOBUFS); data->ni = NULL; chunk = (struct uath_chunk *)data->buf; desc = (struct uath_tx_desc *)(chunk + 1); @@ -1775,7 +1819,7 @@ bzero(desc, sizeof(struct uath_tx_desc)); desc->msglen = htobe32(sizeof(struct uath_tx_desc)); - desc->msgid = data_idx + 1; /* don't care about endianness */ + desc->msgid = (sc->sc_msgid++) + 1; /* don't care about endianness */ desc->type = htobe32(WDCMSG_FLUSH); desc->txqid = htobe32(0); desc->connid = htobe32(0); @@ -1783,7 +1827,7 @@ #ifdef UATH_DEBUG if (sc->sc_debug & UATH_DEBUG_CMDS) { - printf("send flush ix %u\n", data_idx); + printf("send flush ix %d\n", desc->msgid); if (sc->sc_debug & UATH_DEBUG_CMDS_DUMP) uath_dump_cmd(data->buf, xferlen, '+'); } @@ -1796,9 +1840,12 @@ if (status != USBD_IN_PROGRESS && status != USBD_NORMAL_COMPLETION) { device_printf(sc->sc_dev, "could not send flush: %s\n", usbd_errstr(status)); - return (EIO); + error = EIO; } - return (0); + /* NB: flushing the data pipe is synchronous so add the buffer again. */ + STAILQ_INSERT_HEAD(&sc->sc_data_txhead, data, next); + + return (error); } static void @@ -1842,7 +1889,7 @@ ifp->if_opackets++; UATH_LOCK(sc); - sc->sc_tx_queued--; + STAILQ_INSERT_HEAD(&sc->sc_data_txhead, data, next); ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; UATH_UNLOCK(sc); @@ -1850,24 +1897,20 @@ } static int -uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) +uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, + struct uath_data *data) { struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; - struct uath_data *data; struct uath_chunk *chunk; struct uath_tx_desc *desc; const struct ieee80211_frame *wh; struct ieee80211_key *k; - int data_idx, framelen, msglen, xferlen; + int framelen, msglen, xferlen; usbd_status status; UATH_ASSERT_LOCKED(sc); - data_idx = sc->sc_data_idx; - sc->sc_data_idx = (sc->sc_data_idx + 1) % UATH_TX_DATA_LIST_COUNT; - - data = &sc->sc_data_tx[data_idx]; data->ni = ni; data->m = m0; chunk = (struct uath_chunk *)data->buf; @@ -1908,7 +1951,7 @@ /* fill Tx descriptor */ desc->msglen = htobe32(msglen); /* NB: to get UATH_TX_NOTIFY reply, `msgid' must be larger than 0 */ - desc->msgid = data_idx + 1; /* don't care about endianness */ + desc->msgid = (sc->sc_msgid++) + 1; /* don't care about endianness */ desc->type = htobe32(WDCMSG_SEND); switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { case IEEE80211_FC0_TYPE_CTL: @@ -1941,7 +1984,7 @@ #ifdef UATH_DEBUG DPRINTF(sc, UATH_DEBUG_XMIT, "send frame ix %u framelen %d msglen %d connid 0x%x txqid 0x%x\n", - data_idx, framelen, msglen, be32toh(desc->connid), + desc->msgid, framelen, msglen, be32toh(desc->connid), be32toh(desc->txqid)); if (sc->sc_debug & UATH_DEBUG_XMIT_DUMP) uath_dump_cmd(data->buf, xferlen, '+'); @@ -1956,14 +1999,13 @@ m_freem(m0); return (EIO); } - - sc->sc_tx_queued++; return (0); } static void uath_start(struct ifnet *ifp) { + struct uath_data *bf; struct uath_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; @@ -1973,12 +2015,13 @@ UATH_LOCK(sc); for (;;) { + bf = uath_getbuf(sc); + if (bf == NULL) + break; + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - if (sc->sc_tx_queued >= UATH_TX_DATA_LIST_COUNT) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + if (m == NULL) { + STAILQ_INSERT_HEAD(&sc->sc_data_txhead, bf, next); break; } @@ -1986,15 +2029,17 @@ m->m_pkthdr.rcvif = NULL; m = ieee80211_encap(ni, m); if (m == NULL) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - continue; + DPRINTF(sc, UATH_DEBUG_XMIT, + "%s: encapsulation failure\n", __func__); + goto bad; } - if (uath_tx_start(sc, m, ni) != 0) { + if (uath_tx_start(sc, m, ni, bf) != 0) { + bad: + ifp->if_oerrors++; + STAILQ_INSERT_HEAD(&sc->sc_data_txhead, bf, next); ieee80211_free_node(ni); - ifp->if_oerrors++; - break; + continue; } sc->sc_tx_timer = 5; @@ -2425,8 +2470,8 @@ if (ifp->if_drv_flags & IFF_DRV_RUNNING) uath_stop_locked(ifp); - /* reset data and command rings */ - sc->sc_tx_queued = sc->sc_data_idx = sc->sc_cmd_idx = 0; + /* reset command rings */ + sc->sc_msgid = sc->sc_cmd_idx = 0; val = htobe32(0); uath_cmd_write(sc, WDCMSG_BIND, &val, sizeof val, 0); @@ -2648,6 +2693,7 @@ { struct ieee80211com *ic = ni->ni_ic; struct ifnet *ifp = ic->ic_ifp; + struct uath_data *bf; struct uath_softc *sc = ifp->if_softc; /* prevent management frames from being sent if we're not ready */ @@ -2658,17 +2704,19 @@ } UATH_LOCK(sc); - if (sc->sc_tx_queued >= UATH_TX_DATA_LIST_COUNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + /* grab a TX buffer */ + bf = uath_getbuf(sc); + if (bf == NULL) { + ieee80211_free_node(ni); m_freem(m); - ieee80211_free_node(ni); UATH_UNLOCK(sc); - return (ENOBUFS); /* XXX */ + return (ENOBUFS); } - if (uath_tx_start(sc, m, ni) != 0) { + if (uath_tx_start(sc, m, ni, bf) != 0) { ieee80211_free_node(ni); ifp->if_oerrors++; + STAILQ_INSERT_HEAD(&sc->sc_data_txhead, bf, next); UATH_UNLOCK(sc); return (EIO); } ==== //depot/projects/vap/sys/dev/usb/if_uathvar.h#5 (text+ko) ==== @@ -26,8 +26,6 @@ #define UATH_RX_DATA_LIST_COUNT 1 /* 128 */ #define UATH_RX_CMD_LIST_COUNT 1 /* 30 */ -#define UATH_RX_DATA_POOL_COUNT (UATH_RX_DATA_LIST_COUNT + 24) - #define UATH_DATA_TIMEOUT 10000 #define UATH_CMD_TIMEOUT 1000 @@ -66,7 +64,9 @@ uint8_t *buf; struct mbuf *m; struct ieee80211_node *ni; /* NB: tx only */ + STAILQ_ENTRY(uath_data) next; }; +typedef STAILQ_HEAD(, uath_data) uath_bufhead; struct uath_cmd { struct uath_softc *sc; @@ -176,10 +176,10 @@ int sc_cmd_idx; usbd_pipe_handle sc_data_rxpipe; usbd_pipe_handle sc_data_txpipe; - struct uath_data sc_data_rx[UATH_RX_DATA_POOL_COUNT]; + struct uath_data sc_data_rx[UATH_RX_DATA_LIST_COUNT]; struct uath_data sc_data_tx[UATH_TX_DATA_LIST_COUNT]; - int sc_data_idx; - int sc_tx_queued; + uath_bufhead sc_data_txhead; + uint32_t sc_msgid; int sc_tx_timer; struct callout watchdog_ch; struct callout stat_ch;