From owner-p4-projects@FreeBSD.ORG Sun Jun 3 02:22:44 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DA51716A492; Sun, 3 Jun 2007 02:22:43 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id AAF7016A482 for ; Sun, 3 Jun 2007 02:22:43 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 8E98013C4B8 for ; Sun, 3 Jun 2007 02:22:43 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l532MhbA029131 for ; Sun, 3 Jun 2007 02:22:43 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l532MhN0029125 for perforce@freebsd.org; Sun, 3 Jun 2007 02:22:43 GMT (envelope-from sam@freebsd.org) Date: Sun, 3 Jun 2007 02:22:43 GMT Message-Id: <200706030222.l532MhN0029125@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 120812 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 Jun 2007 02:22:44 -0000 http://perforce.freebsd.org/chv.cgi?CH=120812 Change 120812 by sam@sam_laptop on 2007/06/03 02:21:42 o correct bg scan operation (on 2915 cards at least); use a short dwell time for scans that send a probe request frame; w/o this the f/w reliably gets stuck (30ms value taken from linux driver) o rewrite code to construct a multi-channel scan list; this list must be run-length encoded based on the band of the channels (untested and we may need to discard the channel order crafted by net80211 as the run-length encoding may overflow the max #channels allowed by the f/w) o #if 0 code to trigger a scan of all channels to suppress compiler complaints o add scan request dump msgs when debugging Affected files ... .. //depot/projects/wifi/sys/dev/iwi/if_iwi.c#39 edit Differences ... ==== //depot/projects/wifi/sys/dev/iwi/if_iwi.c#39 (text+ko) ==== @@ -167,7 +167,9 @@ static void iwi_scan_end(struct ieee80211com *); static void iwi_set_channel(struct ieee80211com *); static void iwi_scan_curchan(struct ieee80211com *, unsigned long maxdwell); +#if 0 static void iwi_scan_allchan(struct ieee80211com *, unsigned long maxdwell); +#endif static void iwi_scan_mindwell(struct ieee80211com *); static void iwi_assoc(struct ieee80211com *ic); static void iwi_ops(void *, int); @@ -1388,7 +1390,7 @@ chan = (struct iwi_notif_scan_channel *)(notif + 1); DPRINTFN(3, ("Scan of channel %u complete (%u)\n", - ic->ic_channels[chan->nchan].ic_freq, chan->nchan)); + ieee80211_ieee2mhz(chan->nchan, 0), chan->nchan)); /* Reset the timer, the scan is still going */ sc->sc_scan_timer = 3; @@ -2663,8 +2665,27 @@ *st = (*st & 0x0f) | ((scan_type & 0xf) << 4); } +static int +scan_type(const struct ieee80211_scan_state *ss, + const struct ieee80211_channel *chan) +{ + /* We can only set one essid for a directed scan */ + if (ss->ss_nssid != 0) + return IWI_SCAN_TYPE_BDIRECTED; + if ((ss->ss_flags & IEEE80211_SCAN_ACTIVE) && + (chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) + return IWI_SCAN_TYPE_BROADCAST; + return IWI_SCAN_TYPE_PASSIVE; +} + +static __inline int +scan_band(const struct ieee80211_channel *c) +{ + return IEEE80211_IS_CHAN_5GHZ(c) ? IWI_CHAN_5GHZ : IWI_CHAN_2GHZ; +} + /* - * Scan on ic_curchan according to ic_scan (essid, active/passive, dwell ...) + * Start a scan on the current channel or all channels. */ static int iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell, int mode) @@ -2674,7 +2695,6 @@ struct ieee80211_scan_state *ss; struct iwi_scan_ext scan; int error = 0; - int i, type; IWI_LOCK_CHECK(sc); if (sc->flags & IWI_FLAG_SCANNING) { @@ -2688,47 +2708,97 @@ ic = &sc->sc_ic; ss = ic->ic_scan; - chan = ic->ic_curchan; memset(&scan, 0, sizeof scan); scan.full_scan_index = htole32(++sc->sc_scangen); scan.dwell_time[IWI_SCAN_TYPE_PASSIVE] = htole16(maxdwell); - scan.dwell_time[IWI_SCAN_TYPE_BROADCAST] = htole16(maxdwell); - scan.dwell_time[IWI_SCAN_TYPE_BDIRECTED] = htole16(maxdwell); + if (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) { + /* + * Use very short dwell times for when we send probe request + * frames. Without this bg scans hang. Ideally this should + * be handled with early-termination as done by net80211 but + * that's not feasible (aborting a scan is problematic). + */ + scan.dwell_time[IWI_SCAN_TYPE_BROADCAST] = htole16(30); + scan.dwell_time[IWI_SCAN_TYPE_BDIRECTED] = htole16(30); + } else { + scan.dwell_time[IWI_SCAN_TYPE_BROADCAST] = htole16(maxdwell); + scan.dwell_time[IWI_SCAN_TYPE_BDIRECTED] = htole16(maxdwell); + } /* We can only set one essid for a directed scan */ if (ss->ss_nssid != 0) { - type = IWI_SCAN_TYPE_BDIRECTED; error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len); if (error) return (error); - } else if ((ss->ss_flags & IEEE80211_SCAN_ACTIVE) && - (chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) { - type = IWI_SCAN_TYPE_BROADCAST; - } else - type = IWI_SCAN_TYPE_PASSIVE; + } if (mode == IWI_SCAN_ALLCHAN) { - for (i = 0; i < ss->ss_last;) { + int i, next, band, b, bstart; + /* + * Convert scan list to run-length encoded channel list + * the firmware requires (preserving the order setup by + * net80211). The first entry in each run specifies the + * band and the count of items in the run. + */ + next = 0; /* next open slot */ + bstart = 0; /* NB: not needed, silence compiler */ + band = -1; /* NB: impossible value */ + KASSERT(ss->ss_last > 0, ("no channels")); + for (i = 0; i < ss->ss_last; i++) { chan = ss->ss_chans[i]; - scan.channels[++i] = ieee80211_chan2ieee(ic, chan); - set_scan_type(&scan, i, type); + b = scan_band(chan); + if (b != band) { + if (band != -1) + scan.channels[bstart] = + (next - bstart) | band; + /* NB: this allocates a slot for the run-len */ + band = b, bstart = next++; + } + if (next >= IWI_SCAN_CHANNELS) { + DPRINTF(("truncating scan list\n")); + break; + } + scan.channels[next] = ieee80211_chan2ieee(ic, chan); + set_scan_type(&scan, next, scan_type(ss, chan)); + next++; } - DPRINTF(("Scanning on %d channel(s)\n", i)); + scan.channels[bstart] = (next - bstart) | band; } else { /* Scan the current channel only */ - i = 1; - scan.channels[i] = ieee80211_chan2ieee(ic, chan); - set_scan_type(&scan, i, type); - DPRINTF(("Scanning on channel %u\n", - ieee80211_chan2ieee(ic, chan))); + chan = ic->ic_curchan; + scan.channels[0] = 1 | scan_band(chan); + scan.channels[1] = ieee80211_chan2ieee(ic, chan); + set_scan_type(&scan, 1, scan_type(ss, chan)); + } +#ifdef IWI_DEBUG + if (iwi_debug > 0) { + static const char *scantype[8] = + { "PSTOP", "PASV", "DIR", "BCAST", "BDIR", "5", "6", "7" }; + int i; + printf("Scan request: index %u dwell %d/%d/%d\n" + , le32toh(scan.full_scan_index) + , le16toh(scan.dwell_time[IWI_SCAN_TYPE_PASSIVE]) + , le16toh(scan.dwell_time[IWI_SCAN_TYPE_BROADCAST]) + , le16toh(scan.dwell_time[IWI_SCAN_TYPE_BDIRECTED]) + ); + i = 0; + do { + int run = scan.channels[i]; + if (run == 0) + break; + printf("Scan %d %s channels:", run & 0x3f, + run & IWI_CHAN_2GHZ ? "2.4GHz" : "5GHz"); + for (run &= 0x3f, i++; run > 0; run--, i++) { + uint8_t type = scan.scan_type[i/2]; + printf(" %u/%s", scan.channels[i], + scantype[(i & 1 ? type : type>>4) & 7]); + } + printf("\n"); + } while (i < IWI_SCAN_CHANNELS); } - if (IEEE80211_IS_CHAN_5GHZ(chan)) - scan.channels[0] = i | IWI_CHAN_5GHZ; - else - scan.channels[0] = i | IWI_CHAN_2GHZ; - +#endif sc->flags |= IWI_FLAG_SCANNING; sc->sc_scan_timer = 3; sc->sc_ifp->if_timer = 1; @@ -3547,6 +3617,7 @@ iwi_scan_cmd(sc, IWI_SCAN_CURCHAN); } +#if 0 static void iwi_scan_allchan(struct ieee80211com *ic, unsigned long maxdwell) { @@ -3556,6 +3627,7 @@ sc->sc_maxdwell = maxdwell; iwi_scan_cmd(sc, IWI_SCAN_ALLCHAN); } +#endif static void iwi_scan_mindwell(struct ieee80211com *ic)