svn commit: r193352 - head/sys/dev/ath

Sam Leffler sam at FreeBSD.org
Tue Jun 2 21:17:57 UTC 2009


Author: sam
Date: Tue Jun  2 21:17:56 2009
New Revision: 193352
URL: http://svn.freebsd.org/changeset/base/193352

Log:
  improve raw xmit failure handling

Modified:
  head/sys/dev/ath/if_ath.c

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Tue Jun  2 21:13:57 2009	(r193351)
+++ head/sys/dev/ath/if_ath.c	Tue Jun  2 21:17:56 2009	(r193352)
@@ -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 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;
 }
 
 /*


More information about the svn-src-head mailing list