PERFORCE change 157544 for review

Hans Petter Selasky hselasky at FreeBSD.org
Wed Feb 11 07:09:46 PST 2009


http://perforce.freebsd.org/chv.cgi?CH=157544

Change 157544 by hselasky at hselasky_laptop001 on 2009/02/11 15:09:25

	
	USB WLAN: More fixes.
	 - (tx_nfree == 0) is not good enough check
	   to see if there are no TX slots left. Use
	   STAILQ_FIRST() == NULL as indication
	   when there are no TX slots.
	
	- remove tx_nfree variable from ZYD/RUM/RAL softc
	
	- make sure one slot is reserved for
	  management frames. Should have reserved
	  more frames (TODO).
	
	Reported by: Thomas Sparrevohn

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#36 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_rumvar.h#8 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#35 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_uralvar.h#8 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#37 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zydreg.h#9 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#36 (text+ko) ====

@@ -690,7 +690,6 @@
 		data->ni = NULL;
 	}
 	STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
-	sc->tx_nfree++;
 }
 
 static void
@@ -699,7 +698,6 @@
 	struct rum_tx_data *data;
 	int i;
 
-	sc->tx_nfree = 0;
 	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
 
@@ -708,7 +706,6 @@
 
 		data->sc = sc;
 		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
-		sc->tx_nfree++;
 	}
 }
 
@@ -719,7 +716,6 @@
 	int i;
 
 	/* make sure any subsequent use of the queues will fail */
-	sc->tx_nfree = 0;
 	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
 
@@ -857,7 +853,6 @@
 		xfer->priv_fifo = NULL;
 
 		ifp->if_opackets++;
-		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
 		/* FALLTHROUGH */
 	case USB_ST_SETUP:
@@ -1135,11 +1130,14 @@
 	}
 	if (mprot == NULL) {
 		/* XXX stat + msg */
-		return ENOBUFS;
+		return (ENOBUFS);
 	}
 	data = STAILQ_FIRST(&sc->tx_free);
+	if (data == NULL) {
+		m_freem(mprot);
+		return (ENOBUFS);
+	}
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
-	sc->tx_nfree--;
 
 	data->m = mprot;
 	data->ni = ieee80211_ref_node(ni);
@@ -1168,8 +1166,11 @@
 	RUM_LOCK_ASSERT(sc, MA_OWNED);
 
 	data = STAILQ_FIRST(&sc->tx_free);
+	if (data == NULL) {
+		m_freem(m0);
+		return (ENOBUFS);
+	}
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
-	sc->tx_nfree--;
 
 	wh = mtod(m0, struct ieee80211_frame *);
 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
@@ -1209,7 +1210,7 @@
 	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
 	usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
 
-	return 0;
+	return (0);
 }
 
 static int
@@ -1224,8 +1225,11 @@
 	KASSERT(params != NULL, ("no raw xmit params"));
 
 	data = STAILQ_FIRST(&sc->tx_free);
+	if (data == NULL) {
+		m_freem(m0);
+		return (ENOBUFS);
+	}
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
-	sc->tx_nfree--;
 
 	rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
 	/* XXX validate */
@@ -1319,8 +1323,11 @@
 	}
 
 	data = STAILQ_FIRST(&sc->tx_free);
+	if (data == NULL) {
+		m_freem(m0);
+		return (ENOBUFS);
+	}
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
-	sc->tx_nfree--;
 
 	data->m = m0;
 	data->ni = ni;
@@ -1351,6 +1358,7 @@
 {
 	struct rum_softc *sc = ifp->if_softc;
 	struct ieee80211_node *ni;
+	struct rum_tx_data *data;
 	struct mbuf *m;
 
 	RUM_LOCK(sc);
@@ -1362,15 +1370,19 @@
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
 		if (m == NULL)
 			break;
-		if (sc->tx_nfree == 0) {
-			IFQ_DRV_PREPEND(&ifp->if_snd, m);
-			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-			break;
+		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
+		data = STAILQ_FIRST(&sc->tx_free);
+		if ((data == NULL) || (STAILQ_NEXT(data, next) == NULL)) {
+			/* last slot is reserved for mgt frame */
+			m_freem(m);
+			ieee80211_free_node(ni);
+			ifp->if_oerrors++;
+			continue;
 		}
-		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
 		m = ieee80211_encap(ni, m);
 		if (m == NULL) {
 			ieee80211_free_node(ni);
+			ifp->if_oerrors++;
 			continue;
 		}
 		if (rum_tx_data(sc, m, ni) != 0) {
@@ -2084,7 +2096,6 @@
 	}
 	rum_write(sc, RT2573_TXRX_CSR0, tmp);
 
-	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	usb2_transfer_start(sc->sc_xfer[RUM_BULK_RD]);
 	return;
@@ -2120,7 +2131,7 @@
 
 	RUM_LOCK_ASSERT(sc, MA_OWNED);
 
-	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 
 	RUM_UNLOCK(sc);
 
@@ -2212,13 +2223,6 @@
 		ieee80211_free_node(ni);
 		return ENETDOWN;
 	}
-	if (sc->tx_nfree == 0) {
-		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-		RUM_UNLOCK(sc);
-		m_freem(m);
-		ieee80211_free_node(ni);
-		return EIO;
-	}
 
 	ifp->if_opackets++;
 

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_rumvar.h#8 (text+ko) ====

@@ -119,7 +119,6 @@
 	struct rum_tx_data		tx_data[RUM_TX_LIST_COUNT];
 	rum_txdhead			tx_q;
 	rum_txdhead			tx_free;
-	int				tx_nfree;
 	struct rum_rx_desc		sc_rx_desc;
 
 	struct mtx			sc_mtx;

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#35 (text+ko) ====

@@ -670,7 +670,6 @@
 		data->ni = NULL;
 	}
 	STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
-	sc->tx_nfree++;
 }
 
 static void
@@ -679,7 +678,6 @@
 	struct ural_tx_data *data;
 	int i;
 
-	sc->tx_nfree = 0;
 	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
 
@@ -688,7 +686,6 @@
 
 		data->sc = sc;
 		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
-		sc->tx_nfree++;
 	}
 }
 
@@ -699,7 +696,6 @@
 	int i;
 
 	/* make sure any subsequent use of the queues will fail */
-	sc->tx_nfree = 0;
 	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
 
@@ -886,7 +882,6 @@
 		xfer->priv_fifo = NULL;
 
 		ifp->if_opackets++;
-		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
 		/* FALLTHROUGH */
 	case USB_ST_SETUP:
@@ -1138,19 +1133,16 @@
 {
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211com *ic = ni->ni_ic;
-	struct ifnet *ifp = sc->sc_ifp;
 	const struct ieee80211_txparam *tp;
 	struct ural_tx_data *data;
 
-	if (sc->tx_nfree == 0) {
-		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+	data = STAILQ_FIRST(&sc->tx_free);
+	if (data == NULL) {
 		m_freem(m0);
 		ieee80211_free_node(ni);
-		return EIO;
+		return (EIO);
 	}
-	data = STAILQ_FIRST(&sc->tx_free);
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
-	sc->tx_nfree--;
 	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
 
 	data->m = m0;
@@ -1185,8 +1177,11 @@
 	RAL_LOCK_ASSERT(sc, MA_OWNED);
 
 	data = STAILQ_FIRST(&sc->tx_free);
+	if (data == NULL) {
+		m_freem(m0);
+		return (ENOBUFS);
+	}
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
-	sc->tx_nfree--;
 
 	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
 
@@ -1268,8 +1263,11 @@
 		return ENOBUFS;
 	}
 	data = STAILQ_FIRST(&sc->tx_free);
+	if (data == NULL) {
+		m_freem(mprot);
+		return (ENOBUFS);
+	}
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
-	sc->tx_nfree--;
 
 	data->m = mprot;
 	data->ni = ieee80211_ref_node(ni);
@@ -1295,8 +1293,11 @@
 	KASSERT(params != NULL, ("no raw xmit params"));
 
 	data = STAILQ_FIRST(&sc->tx_free);
+	if (data == NULL) {
+		m_freem(m0);
+		return (ENOBUFS);
+	}
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
-	sc->tx_nfree--;
 
 	rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
 	/* XXX validate */
@@ -1388,8 +1389,11 @@
 	}
 
 	data = STAILQ_FIRST(&sc->tx_free);
+	if (data == NULL) {
+		m_freem(m0);
+		return (ENOBUFS);
+	}
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
-	sc->tx_nfree--;
 
 	data->m = m0;
 	data->ni = ni;
@@ -1420,6 +1424,7 @@
 {
 	struct ural_softc *sc = ifp->if_softc;
 	struct ieee80211_node *ni;
+	struct ural_tx_data *data;
 	struct mbuf *m;
 
 	RAL_LOCK(sc);
@@ -1431,15 +1436,20 @@
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
 		if (m == NULL)
 			break;
-		if (sc->tx_nfree == 0) {
-			IFQ_DRV_PREPEND(&ifp->if_snd, m);
-			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-			break;
+
+		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
+		data = STAILQ_FIRST(&sc->tx_free);
+		if ((data == NULL) || (STAILQ_NEXT(data, next) == NULL)) {
+			/* last slot is reserved for mgt frame */
+			m_freem(m);
+			ieee80211_free_node(ni);
+			ifp->if_oerrors++;
+			continue;
 		}
-		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
 		m = ieee80211_encap(ni, m);
 		if (m == NULL) {
 			ieee80211_free_node(ni);
+			ifp->if_oerrors++;
 			continue;
 		}
 		if (ural_tx_data(sc, m, ni) != 0) {
@@ -2208,7 +2218,6 @@
 	}
 	ural_write(sc, RAL_TXRX_CSR2, tmp);
 
-	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	usb2_transfer_start(sc->sc_xfer[URAL_BULK_RD]);
 	return;
@@ -2243,7 +2252,7 @@
 
 	RAL_LOCK_ASSERT(sc, MA_OWNED);
 
-	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 
 	/*
 	 * Drain all the transfers, if not already drained:
@@ -2282,14 +2291,6 @@
 		ieee80211_free_node(ni);
 		return ENETDOWN;
 	}
-	if (sc->tx_nfree == 0) {
-		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-		RAL_UNLOCK(sc);
-		m_freem(m);
-		ieee80211_free_node(ni);
-		return EIO;
-	}
-
 	ifp->if_opackets++;
 
 	if (params == NULL) {

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_uralvar.h#8 (text+ko) ====

@@ -122,7 +122,6 @@
 	struct ural_tx_data		tx_data[RAL_TX_LIST_COUNT];
 	ural_txdhead			tx_q;
 	ural_txdhead			tx_free;
-	int				tx_nfree;
 	struct ural_rx_desc		sc_rx_desc;
 
 	struct mtx			sc_mtx;

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#37 (text+ko) ====

@@ -548,7 +548,6 @@
 		data->ni = NULL;
 	}
 	STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
-	sc->tx_nfree++;
 }
 
 static void
@@ -557,7 +556,6 @@
 	struct zyd_tx_data *data;
 	int i;
 
-	sc->tx_nfree = 0;
 	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
 
@@ -566,7 +564,6 @@
 
 		data->sc = sc;
 		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
-		sc->tx_nfree++;
 	}
 }
 
@@ -577,7 +574,6 @@
 	int i;
 
 	/* make sure any subsequent use of the queues will fail */
-	sc->tx_nfree = 0;
 	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
 
@@ -2400,8 +2396,11 @@
 	uint16_t pktlen;
 
 	data = STAILQ_FIRST(&sc->tx_free);
+	if (data == NULL) {
+		m_freem(m0);
+		return (ENOBUFS);
+	}
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
-	sc->tx_nfree--;
 	desc = &data->desc;
 
 	rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
@@ -2510,7 +2509,6 @@
 		xfer->priv_fifo = NULL;
 
 		ifp->if_opackets++;
-		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
 		/* FALLTHROUGH */
 	case USB_ST_SETUP:
@@ -2583,8 +2581,11 @@
 
 	wh = mtod(m0, struct ieee80211_frame *);
 	data = STAILQ_FIRST(&sc->tx_free);
+	if (data == NULL) {
+		m_freem(m0);
+		return (ENOBUFS);
+	}
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
-	sc->tx_nfree--;
 	desc = &data->desc;
 
 	desc->flags = ZYD_TX_FLAG_BACKOFF;
@@ -2673,6 +2674,7 @@
 {
 	struct zyd_softc *sc = ifp->if_softc;
 	struct ieee80211_node *ni;
+	struct zyd_tx_data *data;
 	struct mbuf *m;
 
 	ZYD_LOCK(sc);
@@ -2680,12 +2682,16 @@
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
 		if (m == NULL)
 			break;
-		if (sc->tx_nfree == 0) {
-			IFQ_DRV_PREPEND(&ifp->if_snd, m);
-			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-			break;
+
+		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+		data = STAILQ_FIRST(&sc->tx_free);
+		if ((data == NULL) || (STAILQ_NEXT(data, next) == NULL)) {
+			/* last slot is reserved for mgt frame */
+			m_freem(m);
+			ieee80211_free_node(ni);
+			ifp->if_oerrors++;
+			continue;
 		}
-		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
 		m = ieee80211_encap(ni, m);
 		if (m == NULL) {
 			ieee80211_free_node(ni);
@@ -2717,14 +2723,6 @@
 		ieee80211_free_node(ni);
 		return (ENETDOWN);
 	}
-	if (sc->tx_nfree == 0) {
-		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-		ZYD_UNLOCK(sc);
-		m_freem(m);
-		ieee80211_free_node(ni);
-		return (ENOBUFS);		/* XXX */
-	}
-
 	/*
 	 * Legacy path; interpret frame contents to decide
 	 * precisely how to send the frame.
@@ -2886,7 +2884,6 @@
 	/* enable interrupts */
 	zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
 
-	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	usb2_transfer_start(sc->sc_xfer[ZYD_BULK_RD]);
 	usb2_transfer_start(sc->sc_xfer[ZYD_INTR_RD]);
@@ -2924,7 +2921,7 @@
 
 	ZYD_LOCK_ASSERT(sc, MA_OWNED);
 
-	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 
 	/*
 	 * Drain all the transfers, if not already drained:

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_zydreg.h#9 (text+ko) ====

@@ -1319,7 +1319,6 @@
 	struct zyd_tx_data	tx_data[ZYD_TX_LIST_CNT];
 	zyd_txdhead		tx_q;
 	zyd_txdhead		tx_free;
-	int			tx_nfree;
 	struct zyd_rx_desc	sc_rx_desc;
 	struct zyd_rx_data	sc_rx_data[ZYD_MAX_RXFRAMECNT];
 	int			sc_rx_count;


More information about the p4-projects mailing list