PERFORCE change 81315 for review
Sam Leffler
sam at FreeBSD.org
Mon Aug 1 21:56:57 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=81315
Change 81315 by sam at sam_ebb on 2005/08/01 21:56:24
Use a private callout to timeout mgt frames instead of using
the watchdog timer; this eliminates another incestuous tie
between the driver and net80211.
Also bring in proper handling of tx timeout on auth frames:
notify the scan module so the entry is ignored; this fixes
problems with ap's moving channel.
Affected files ...
.. //depot/projects/wifi/sys/dev/ath/if_ath.c#94 edit
.. //depot/projects/wifi/sys/net80211/ieee80211.c#26 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_output.c#51 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.c#33 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_var.h#32 edit
Differences ...
==== //depot/projects/wifi/sys/dev/ath/if_ath.c#94 (text+ko) ====
@@ -4370,8 +4370,6 @@
ath_hal_txprocdesc(ah, bf->bf_desc) == HAL_OK);
#endif /* AR_DEBUG */
bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
- m_freem(bf->bf_m);
- bf->bf_m = NULL;
ni = bf->bf_node;
bf->bf_node = NULL;
if (ni != NULL) {
@@ -4380,6 +4378,8 @@
*/
ieee80211_free_node(ni);
}
+ m_freem(bf->bf_m);
+ bf->bf_m = NULL;
ATH_TXBUF_LOCK(sc);
STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
ATH_TXBUF_UNLOCK(sc);
@@ -5198,7 +5198,6 @@
ath_watchdog(struct ifnet *ifp)
{
struct ath_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = &sc->sc_ic;
ifp->if_timer = 0;
if ((ifp->if_flags & IFF_RUNNING) == 0 || sc->sc_invalid)
@@ -5212,7 +5211,6 @@
} else
ifp->if_timer = 1;
}
- ieee80211_watchdog(ic);
}
/*
==== //depot/projects/wifi/sys/net80211/ieee80211.c#26 (text+ko) ====
@@ -795,18 +795,6 @@
imr->ifm_active |= IFM_AUTO;
}
-void
-ieee80211_watchdog(struct ieee80211com *ic)
-{
-
- if (ic->ic_state != IEEE80211_S_INIT) {
- if (ic->ic_mgt_timer && --ic->ic_mgt_timer == 0)
- ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
- }
- if (ic->ic_mgt_timer != 0)
- ic->ic_ifp->if_timer = 1;
-}
-
/*
* Set the current phy mode and recalculate the active channel
* set based on the available channels for this mode. Also
==== //depot/projects/wifi/sys/net80211/ieee80211_output.c#51 (text+ko) ====
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_output.c,v 1.32 2005/07/31 06:12:32 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_output.c,v 1.31 2005/07/22 21:11:26 sam Exp $");
#include "opt_inet.h"
@@ -64,6 +64,7 @@
struct mbuf *m2, const struct ether_header *eh2);
static int ieee80211_fragment(struct ieee80211com *, struct mbuf *,
u_int hdrsize, u_int ciphdrsize, u_int mtu);
+static void ieee80211_tx_timeout(void *);
#ifdef IEEE80211_DEBUG
/*
@@ -213,10 +214,6 @@
/*
* Send a null data frame to the specified node.
- *
- * NB: the caller is assumed to have setup a node reference
- * for use; this is necessary to deal with a race condition
- * when probing for inactive stations.
*/
int
ieee80211_send_nulldata(struct ieee80211_node *ni)
@@ -230,10 +227,9 @@
if (m == NULL) {
/* XXX debug msg */
ic->ic_stats.is_tx_nobuf++;
- ieee80211_unref_node(&ni);
return ENOMEM;
}
- m->m_pkthdr.rcvif = (void *) ni;
+ m->m_pkthdr.rcvif = (void *) ieee80211_ref_node(ni);
wh = mtod(m, struct ieee80211_frame *);
ieee80211_send_setup(ic, ni, wh,
@@ -1703,17 +1699,34 @@
}
ret = ieee80211_mgmt_output(ic, ni, m, type);
- if (ret == 0) {
- if (timer)
- ic->ic_mgt_timer = timer;
- } else {
+ if (ret != 0)
+ goto bad;
+ if (timer)
+ callout_reset(&ic->ic_mgtsend, timer*hz,
+ ieee80211_tx_timeout, ic);
+ return 0;
bad:
- ieee80211_free_node(ni);
- }
+ ieee80211_free_node(ni);
return ret;
#undef senderr
}
+static void
+ieee80211_tx_timeout(void *arg)
+{
+ struct ieee80211com *ic = arg;
+
+ if (ic->ic_state != IEEE80211_S_INIT &&
+ (ic->ic_flags & IEEE80211_F_SCAN) == 0) {
+ /*
+ * NB: it's safe to specify a timeout as the reason here;
+ * it'll only be used in the right state.
+ */
+ ieee80211_new_state(ic, IEEE80211_S_SCAN,
+ IEEE80211_SCAN_FAIL_TIMEOUT);
+ }
+}
+
/*
* Allocate a beacon frame and fillin the appropriate bits.
*/
==== //depot/projects/wifi/sys/net80211/ieee80211_proto.c#33 (text+ko) ====
@@ -97,6 +97,7 @@
ic->ic_rtsthreshold = IEEE80211_RTS_DEFAULT;
ic->ic_fragthreshold = IEEE80211_FRAG_DEFAULT;
ic->ic_fixed_rate = IEEE80211_FIXED_RATE_NONE;
+ callout_init(&ic->ic_mgtsend, CALLOUT_MPSAFE);
ic->ic_mcast_rate = IEEE80211_MCAST_RATE_DEFAULT;
ic->ic_protmode = IEEE80211_PROT_CTSONLY;
ic->ic_roaming = IEEE80211_ROAMING_AUTO;
@@ -919,6 +920,7 @@
IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE, "%s: %s -> %s\n", __func__,
ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
ic->ic_state = nstate; /* state transition */
+ callout_drain(&ic->ic_mgtsend);
if (ostate != IEEE80211_S_SCAN)
ieee80211_cancel_scan(ic); /* background scan */
ni = ic->ic_bss; /* NB: no reference held */
@@ -963,7 +965,6 @@
goto reset;
case IEEE80211_S_AUTH:
reset:
- ic->ic_mgt_timer = 0;
IF_DRAIN(&ic->ic_mgtq);
ieee80211_reset_bss(ic);
break;
@@ -1144,7 +1145,6 @@
IEEE80211_RATE2MBS(ni->ni_rates.rs_rates[ni->ni_txrate]));
}
#endif
- ic->ic_mgt_timer = 0;
if (ic->ic_opmode == IEEE80211_M_STA)
ieee80211_scan_assoc_success(ic,
ni->ni_macaddr);
==== //depot/projects/wifi/sys/net80211/ieee80211_var.h#32 (text+ko) ====
@@ -175,6 +175,7 @@
struct ifqueue ic_mgtq;
enum ieee80211_state ic_state; /* 802.11 state */
+ struct callout ic_mgtsend; /* mgmt frame response timer */
u_int32_t *ic_aid_bitmap; /* association id map */
u_int16_t ic_max_aid;
u_int16_t ic_ps_sta; /* stations in power save */
@@ -193,7 +194,6 @@
u_int16_t ic_txmin; /* min tx retry count */
u_int16_t ic_txmax; /* max tx retry count */
u_int16_t ic_txlifetime; /* tx lifetime */
- int ic_mgt_timer; /* mgmt timeout */
struct callout ic_inact; /* inactivity timer wait */
void *ic_opt_ie; /* user-specified IE's */
u_int16_t ic_opt_ie_len; /* length of ni_opt_ie */
@@ -327,7 +327,6 @@
int ieee80211_ioctl(struct ieee80211com *, u_long, caddr_t);
int ieee80211_cfgget(struct ieee80211com *, u_long, caddr_t);
int ieee80211_cfgset(struct ieee80211com *, u_long, caddr_t);
-void ieee80211_watchdog(struct ieee80211com *);
int ieee80211_rate2media(struct ieee80211com *, int,
enum ieee80211_phymode);
int ieee80211_media2rate(int);
More information about the p4-projects
mailing list