summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2006-02-19 08:44:18 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2006-02-19 08:44:18 +0000
commitc42082fe656a7deeb573d8120c2cf28dcc4313e0 (patch)
treefd0ae7d30fc84cb9e878c77b61435aae3f20642f
parent145770fa9bc425bb5ca9cbf0fad51f7c2a42a256 (diff)
sync w/ rt2560.c:
don't try to release references to nodes that have been freed by net80211. in HostAP mode, when switching to the INIT state, net80211 sends a DISASSOC and a DEAUTH frame to all associated stations and immediately free all the nodes while we may still hold references to them in our Tx queues.
-rw-r--r--sys/dev/usb/if_ral.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/sys/dev/usb/if_ral.c b/sys/dev/usb/if_ral.c
index 587fb56cdb9..9eabe32b4e5 100644
--- a/sys/dev/usb/if_ral.c
+++ b/sys/dev/usb/if_ral.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ral.c,v 1.64 2006/02/11 09:31:42 damien Exp $ */
+/* $OpenBSD: if_ral.c,v 1.65 2006/02/19 08:44:17 damien Exp $ */
/*-
* Copyright (c) 2005, 2006
@@ -527,6 +527,9 @@ USB_DETACH(ural)
s = splusb();
+ ieee80211_ifdetach(ifp); /* free all nodes */
+ if_detach(ifp);
+
usb_rem_task(sc->sc_udev, &sc->sc_task);
timeout_del(&sc->scan_ch);
timeout_del(&sc->amrr_ch);
@@ -549,9 +552,6 @@ USB_DETACH(ural)
ural_free_rx_list(sc);
ural_free_tx_list(sc);
- ieee80211_ifdetach(ifp);
- if_detach(ifp);
-
splx(s);
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
@@ -600,7 +600,6 @@ fail: ural_free_tx_list(sc);
Static void
ural_free_tx_list(struct ural_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
struct ural_tx_data *data;
int i;
@@ -612,10 +611,11 @@ ural_free_tx_list(struct ural_softc *sc)
data->xfer = NULL;
}
- if (data->ni != NULL) {
- ieee80211_release_node(ic, data->ni);
- data->ni = NULL;
- }
+ /*
+ * The node has already been freed at that point so don't call
+ * ieee80211_release_node() here.
+ */
+ data->ni = NULL;
}
}
@@ -1400,6 +1400,13 @@ ural_start(struct ifnet *ifp)
struct ieee80211_node *ni;
struct mbuf *m0;
+ /*
+ * net80211 may still try to send management frames even if the
+ * IFF_RUNNING flag is not set...
+ */
+ if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
+ return;
+
for (;;) {
IF_POLL(&ic->ic_mgtq, m0);
if (m0 != NULL) {
@@ -2249,7 +2256,11 @@ ural_stop(struct ifnet *ifp, int disable)
struct ural_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
- ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
+ sc->sc_tx_timer = 0;
+ ifp->if_timer = 0;
+ ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+
+ ieee80211_new_state(ic, IEEE80211_S_INIT, -1); /* free all nodes */
/* disable Rx */
ural_write(sc, RAL_TXRX_CSR2, RAL_DISABLE_RX);
@@ -2258,10 +2269,6 @@ ural_stop(struct ifnet *ifp, int disable)
ural_write(sc, RAL_MAC_CSR1, RAL_RESET_ASIC | RAL_RESET_BBP);
ural_write(sc, RAL_MAC_CSR1, 0);
- sc->sc_tx_timer = 0;
- ifp->if_timer = 0;
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-
if (sc->amrr_xfer != NULL) {
usbd_free_xfer(sc->amrr_xfer);
sc->amrr_xfer = NULL;