Date: Mon, 1 Aug 2005 21:56:54 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 81315 for review Message-ID: <200508012156.j71LusCV029648@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=81315 Change 81315 by sam@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508012156.j71LusCV029648>