PERFORCE change 157132 for review
Weongyo Jeong
weongyo at FreeBSD.org
Wed Feb 4 04:42:35 PST 2009
http://perforce.freebsd.org/chv.cgi?CH=157132
Change 157132 by weongyo at 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;
More information about the p4-projects
mailing list