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