summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2009-06-02 21:17:56 +0000
committersam <sam@FreeBSD.org>2009-06-02 21:17:56 +0000
commitb55d45b9c9f4259eb09b762956ea264a731bb796 (patch)
tree97cd3a9a162a7bef08f0a1d31a6c672df455d632 /sys/dev
parentfd8abec02af068a6ea941b67d4b4c7fcc11e3a68 (diff)
downloadFreeBSD-src-b55d45b9c9f4259eb09b762956ea264a731bb796.zip
FreeBSD-src-b55d45b9c9f4259eb09b762956ea264a731bb796.tar.gz
improve raw xmit failure handling
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ath/if_ath.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index e378770..6409365 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -1710,7 +1710,6 @@ _ath_getbuf_locked(struct ath_softc *sc)
DPRINTF(sc, ATH_DEBUG_XMIT, "%s: %s\n", __func__,
STAILQ_FIRST(&sc->sc_txbuf) == NULL ?
"out of xmit buffers" : "xmit buffer busy");
- sc->sc_stats.ast_tx_nobuf++;
}
return bf;
}
@@ -6832,55 +6831,60 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
struct ifnet *ifp = ic->ic_ifp;
struct ath_softc *sc = ifp->if_softc;
struct ath_buf *bf;
+ int error;
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) {
DPRINTF(sc, ATH_DEBUG_XMIT, "%s: discard frame, %s", __func__,
(ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ?
"!running" : "invalid");
- sc->sc_stats.ast_tx_raw_fail++;
- ieee80211_free_node(ni);
m_freem(m);
- return ENETDOWN;
+ error = ENETDOWN;
+ goto bad;
}
/*
* Grab a TX buffer and associated resources.
*/
bf = ath_getbuf(sc);
if (bf == NULL) {
- /* NB: ath_getbuf handles stat+msg */
- ieee80211_free_node(ni);
+ sc->sc_stats.ast_tx_nobuf++;
m_freem(m);
- return ENOBUFS;
+ error = ENOBUFS;
+ goto bad;
}
- ifp->if_opackets++;
- sc->sc_stats.ast_tx_raw++;
-
if (params == NULL) {
/*
* Legacy path; interpret frame contents to decide
* precisely how to send the frame.
*/
- if (ath_tx_start(sc, ni, bf, m))
- goto bad;
+ if (ath_tx_start(sc, ni, bf, m)) {
+ error = EIO; /* XXX */
+ goto bad2;
+ }
} else {
/*
* Caller supplied explicit parameters to use in
* sending the frame.
*/
- if (ath_tx_raw_start(sc, ni, bf, m, params))
- goto bad;
+ if (ath_tx_raw_start(sc, ni, bf, m, params)) {
+ error = EIO; /* XXX */
+ goto bad2;
+ }
}
sc->sc_wd_timer = 5;
+ ifp->if_opackets++;
+ sc->sc_stats.ast_tx_raw++;
return 0;
-bad:
- ifp->if_oerrors++;
+bad2:
ATH_TXBUF_LOCK(sc);
STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
ATH_TXBUF_UNLOCK(sc);
+bad:
+ ifp->if_oerrors++;
+ sc->sc_stats.ast_tx_raw_fail++;
ieee80211_free_node(ni);
- return EIO; /* XXX */
+ return error;
}
/*
OpenPOWER on IntegriCloud