Date: Wed, 11 Feb 2009 15:09:44 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 157544 for review Message-ID: <200902111509.n1BF9iKn043096@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=157544 Change 157544 by hselasky@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902111509.n1BF9iKn043096>