From owner-p4-projects@FreeBSD.ORG Sat Mar 24 15:58:21 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 12CE616A408; Sat, 24 Mar 2007 15:58:21 +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 C882716A405 for ; Sat, 24 Mar 2007 15:58:20 +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 B6A3013C4DA for ; Sat, 24 Mar 2007 15:58:19 +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 l2OFwJWU034325 for ; Sat, 24 Mar 2007 15:58:19 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l2OFwJD2034322 for perforce@freebsd.org; Sat, 24 Mar 2007 15:58:19 GMT (envelope-from sam@freebsd.org) Date: Sat, 24 Mar 2007 15:58:19 GMT Message-Id: <200703241558.l2OFwJD2034322@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 116493 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: Sat, 24 Mar 2007 15:58:21 -0000 http://perforce.freebsd.org/chv.cgi?CH=116493 Change 116493 by sam@sam_ebb on 2007/03/24 15:57:27 checkpoint scanning changes for iwi Affected files ... .. //depot/projects/wifi/sys/dev/iwi/if_iwi.c#25 edit .. //depot/projects/wifi/sys/dev/iwi/if_iwivar.h#12 edit Differences ... ==== //depot/projects/wifi/sys/dev/iwi/if_iwi.c#25 (text+ko) ==== @@ -163,12 +163,12 @@ static int iwi_get_firmware(struct iwi_softc *); static void iwi_put_firmware(struct iwi_softc *); static void iwi_scanabort(void *, int); -static void iwi_scandone(void *, int); -static void iwi_scanstart(void *, int); -static void iwi_scanchan(void *, int); +static int iwi_scanchan(struct iwi_softc *, unsigned long); static void iwi_scan_start(struct ieee80211com *); static void iwi_scan_end(struct ieee80211com *); static void iwi_set_channel(struct ieee80211com *); +static void iwi_scan_curchan(struct ieee80211com *, unsigned long maxdwell); +static void iwi_scan_mindwell(struct ieee80211com *); static void iwi_assoc(struct ieee80211com *ic); static void iwi_ops(void *, int); static int iwi_auth_and_assoc(struct iwi_softc *); @@ -275,10 +275,7 @@ #endif TASK_INIT(&sc->sc_radiontask, 0, iwi_radio_on, sc); TASK_INIT(&sc->sc_radiofftask, 0, iwi_radio_off, sc); - TASK_INIT(&sc->sc_scanstarttask, 0, iwi_scanstart, sc); TASK_INIT(&sc->sc_scanaborttask, 0, iwi_scanabort, sc); - TASK_INIT(&sc->sc_scandonetask, 0, iwi_scandone, sc); - TASK_INIT(&sc->sc_scantask, 0, iwi_scanchan, sc); TASK_INIT(&sc->sc_setwmetask, 0, iwi_wme_setparams, sc); TASK_INIT(&sc->sc_downtask, 0, iwi_down, sc); TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc); @@ -369,12 +366,16 @@ /* set device capabilities */ ic->ic_caps = - IEEE80211_C_IBSS | /* IBSS mode supported */ - IEEE80211_C_MONITOR | /* monitor mode supported */ - IEEE80211_C_PMGT | /* power save supported */ - IEEE80211_C_SHPREAMBLE | /* short preamble supported */ - IEEE80211_C_WPA | /* 802.11i */ - IEEE80211_C_WME; /* 802.11e */ + IEEE80211_C_IBSS /* IBSS mode supported */ + | IEEE80211_C_MONITOR /* monitor mode supported */ + | IEEE80211_C_PMGT /* power save supported */ + | IEEE80211_C_SHPREAMBLE /* short preamble supported */ + | IEEE80211_C_WPA /* 802.11i */ + | IEEE80211_C_WME /* 802.11e */ +#if 0 + | IEEE80211_C_BGSCAN /* capable of bg scanning */ +#endif + ; /* read MAC address from EEPROM */ val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0); @@ -403,6 +404,8 @@ ic->ic_scan_start = iwi_scan_start; ic->ic_scan_end = iwi_scan_end; ic->ic_set_channel = iwi_set_channel; + ic->ic_scan_curchan = iwi_scan_curchan; + ic->ic_scan_mindwell = iwi_scan_mindwell; /* override state transition machine */ sc->sc_newstate = ic->ic_newstate; @@ -1371,7 +1374,6 @@ DPRINTFN(3, ("Scan of channel %u complete (%u)\n", ic->ic_channels[chan->nchan].ic_freq, chan->nchan)); - sc->flags &= ~IWI_FLAG_CHANNEL_SCAN; break; case IWI_NOTIF_TYPE_SCAN_COMPLETE: @@ -1381,6 +1383,8 @@ scan->status)); sc->sc_scan_timer = 0; + sc->flags &= ~IWI_FLAG_SCANNING; + ieee80211_scan_next(ic); break; @@ -1966,6 +1970,7 @@ if (--sc->sc_scan_timer == 0) { if (sc->flags & IWI_FLAG_SCANNING) { if_printf(ifp, "scan stuck\n"); + ieee80211_cancel_scan(&sc->sc_ic); taskqueue_enqueue(sc->sc_tq, &sc->sc_restarttask); } } @@ -2638,97 +2643,6 @@ *st = (*st & 0x0f) | ((scan_type & 0xf) << 4); } -static int -iwi_scan(struct iwi_softc *sc) -{ - struct ieee80211com *ic = &sc->sc_ic; - const struct ieee80211_channel *c; - struct iwi_scan_ext scan; - int i, ix, start, scan_type, error; - - IWI_LOCK_CHECK(sc); - - memset(&scan, 0, sizeof scan); - - /* XXX different dwell times for different scan types */ - scan.dwell_time[IWI_SCAN_TYPE_PASSIVE] = htole16(sc->dwelltime); - scan.dwell_time[IWI_SCAN_TYPE_BROADCAST] = htole16(sc->dwelltime); - scan.dwell_time[IWI_SCAN_TYPE_BDIRECTED] = htole16(sc->dwelltime); - - scan.full_scan_index = htole32(++sc->sc_scangen); - - if (ic->ic_des_nssid != 0) { - scan_type = IWI_SCAN_TYPE_BDIRECTED; -#ifdef IWI_DEBUG - if (iwi_debug > 0) { - printf("Setting desired ESSID to "); - ieee80211_print_essid(ic->ic_des_ssid[0].ssid, - ic->ic_des_ssid[0].len); - printf("\n"); - } -#endif - error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ic->ic_des_ssid[0].ssid, - ic->ic_des_ssid[0].len); - if (error != 0) - return error; - } else - scan_type = IWI_SCAN_TYPE_BROADCAST; - - ix = 0; - if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) { - start = ix; - for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { - c = &ic->ic_channels[i]; - /* - * NB: ieee80211_next_scan clears curchan from the - * channel list so we must explicitly check; this - * will be fixed when the new scanning support arrives. - */ - if (!IEEE80211_IS_CHAN_5GHZ(c) || - !(isset(ic->ic_chan_scan,i) || c == ic->ic_curchan)) - continue; - ix++; - scan.channels[ix] = c->ic_ieee; - if (c->ic_flags & IEEE80211_CHAN_PASSIVE) - set_scan_type(&scan, ix, IWI_SCAN_TYPE_PASSIVE); - else - set_scan_type(&scan, ix, scan_type); - } - if (start != ix) { - scan.channels[start] = IWI_CHAN_5GHZ | (ix - start); - ix++; - } - } - if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) { - start = ix; - for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { - c = &ic->ic_channels[i]; - /* NB: see above */ - if (!IEEE80211_IS_CHAN_2GHZ(c) || - !(isset(ic->ic_chan_scan,i) || c == ic->ic_curchan)) - continue; - ix++; - scan.channels[ix] = c->ic_ieee; - if (c->ic_flags & IEEE80211_CHAN_PASSIVE) - set_scan_type(&scan, ix, IWI_SCAN_TYPE_PASSIVE); - else - set_scan_type(&scan, ix, scan_type); - } - if (start != ix) - scan.channels[start] = IWI_CHAN_2GHZ | (ix - start); - } - - DPRINTF(("Start scanning\n")); - /* - * With 100ms/channel dwell time and a max of ~20 channels - * 5 seconds may be too tight; leave a bit more slack. - */ - sc->sc_scan_timer = 7; /* seconds to complete */ - sc->sc_ifp->if_timer = 1; - sc->flags |= IWI_FLAG_SCANNING; - return iwi_cmd(sc, IWI_CMD_SCAN_EXT, &scan, sizeof scan); -} - static void iwi_scanabort(void *arg, int npending) { @@ -2742,88 +2656,61 @@ IWI_UNLOCK(sc); } -static void -iwi_scanstart(void *arg, int npending) -{ - struct iwi_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - IWI_LOCK_DECL; - - IWI_LOCK(sc); - /* - * Tell the card to kick off a scan. We guard this - * by checking IWI_FLAG_SCANNING as otherwise we'll - * do this twice because ieee80211_begin_scan will - * immediately call us back to scan the first channel - * in the list. - */ - if (sc->flags & IWI_FLAG_SCANNING) { - if (iwi_scan(sc) != 0) { - /* XXX should not happen */ - sc->flags &= ~IWI_FLAG_SCANNING; - ieee80211_new_state(ic, IEEE80211_S_INIT, 0); - } - } - IWI_UNLOCK(sc); -} - -static void -iwi_scandone(void *arg, int npending) -{ - struct iwi_softc *sc = arg; - IWI_LOCK_DECL; - - IWI_LOCK(sc); - if (sc->flags & IWI_FLAG_ASSOCIATED) - iwi_disassociate(sc, 0); -#if 0 - ieee80211_end_scan(ic); -#endif - IWI_UNLOCK(sc); -} - /* - * Set the current channel by doing a passive scan. Note this - * is explicitly for monitor mode operation; do not use it for - * anything else (sigh). + * Scan on ic_curchan according to ic_scan (essid, active/passive, dwell ...) */ -static void -iwi_scanchan(void *arg, int npending) +static int +iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell) { - struct iwi_softc *sc = arg; struct ieee80211com *ic; struct ieee80211_channel *chan; + struct ieee80211_scan_state *ss; struct iwi_scan_ext scan; - IWI_LOCK_DECL; + int error = 0; + + IWI_LOCK_CHECK(sc); + if (sc->flags & IWI_FLAG_SCANNING) { + /* + * This should not happen as we only trigger scan_next after + * completion + */ + DPRINTF(("%s: called too early - still scanning\n", __func__)); + return (EBUSY); + } - IWI_LOCK(sc); ic = &sc->sc_ic; - KASSERT(ic->ic_opmode == IEEE80211_M_MONITOR, - ("opmode %u", ic->ic_opmode)); + ss = ic->ic_scan; chan = ic->ic_curchan; memset(&scan, 0, sizeof scan); - /* - * Set the dwell time to a fairly small value. The firmware - * is prone to crash when aborting a scan so it's better to - * let a scan complete before changing channels--such as when - * channel hopping in monitor mode. - */ - scan.dwell_time[IWI_SCAN_TYPE_PASSIVE] = htole16(20); - scan.dwell_time[IWI_SCAN_TYPE_BROADCAST] = htole16(20); - scan.dwell_time[IWI_SCAN_TYPE_BDIRECTED] = htole16(20); 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 (IEEE80211_IS_CHAN_5GHZ(chan)) scan.channels[0] = 1 | IWI_CHAN_5GHZ; else scan.channels[0] = 1 | IWI_CHAN_2GHZ; scan.channels[1] = ieee80211_chan2ieee(ic, chan); - set_scan_type(&scan, 1, IWI_SCAN_TYPE_PASSIVE); + /* We can only set one essid for a directed scan */ + if (ss->ss_nssid != 0) { + set_scan_type(&scan, 1, 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) { + set_scan_type(&scan, 1, IWI_SCAN_TYPE_BROADCAST); + } else + set_scan_type(&scan, 1, IWI_SCAN_TYPE_PASSIVE); - DPRINTF(("Setting channel to %u\n", ieee80211_chan2ieee(ic, chan))); + DPRINTF(("Scanning on channel %u\n", ieee80211_chan2ieee(ic, chan))); sc->flags |= IWI_FLAG_SCANNING; - (void) iwi_cmd(sc, IWI_CMD_SCAN_EXT, &scan, sizeof scan); - IWI_UNLOCK(sc); + sc->sc_scan_timer = 1; + + return (iwi_cmd(sc, IWI_CMD_SCAN_EXT, &scan, sizeof scan)); } static int @@ -3333,11 +3220,6 @@ CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, iwi_sysctl_stats, "S", "statistics"); - sc->dwelltime = 100; - SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "dwell", - CTLFLAG_RW, &sc->dwelltime, 0, - "channel dwell time (ms) for AP/station scanning"); - sc->bluetooth = 0; SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "bluetooth", CTLFLAG_RW, &sc->bluetooth, 0, "bluetooth coexistence"); @@ -3557,11 +3439,25 @@ iwi_auth_and_assoc(sc); break; case IWI_SCAN_START: - iwi_scan(sc); + sc->flags |= IWI_FLAG_CHANNEL_SCAN; break; case IWI_SCAN_END: + sc->flags &= ~IWI_FLAG_CHANNEL_SCAN; iwi_scanabort(sc, 0); break; + case IWI_SCAN_CURCHAN: + if (!(sc->flags & IWI_FLAG_CHANNEL_SCAN)) { + DPRINTF(("%s: ic_scan_curchan while not scanning\n", + __func__)); + return; + } + if (iwi_scanchan(sc, sc->sc_maxdwell)) { + iwi_scanabort(sc, 0); + IWI_UNLOCK(sc); + ieee80211_cancel_scan(ic); + return; + } + break; } done: IWI_UNLOCK(sc); @@ -3572,7 +3468,7 @@ { struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - printf("start scan\n"); + sc->sc_scanop = IWI_SCAN_START; taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask); @@ -3583,17 +3479,33 @@ { struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - if (!(sc->flags & IWI_FLAG_SCANNING)) + if (!(sc->flags & (IWI_FLAG_SCANNING | IWI_FLAG_CHANNEL_SCAN))) iwi_setcurchan(sc, ic->ic_curchan->ic_ieee); } static void +iwi_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell) +{ + struct ifnet *ifp = ic->ic_ifp; + struct iwi_softc *sc = ifp->if_softc; + + sc->sc_scanop = IWI_SCAN_CURCHAN; + sc->sc_maxdwell = maxdwell; + taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask); +} + +static void +iwi_scan_mindwell(struct ieee80211com *ic) +{ + /* NB: don't try to abort scan; wait for firmware to finish */ +} + +static void iwi_scan_end(struct ieee80211com *ic) { struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - printf("end scan\n"); sc->sc_scanop = IWI_SCAN_END; taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask); } ==== //depot/projects/wifi/sys/dev/iwi/if_iwivar.h#12 (text+ko) ==== @@ -176,7 +176,6 @@ int curchan; /* current h/w channel # */ int antenna; - int dwelltime; int bluetooth; struct iwi_associate assoc; struct iwi_wme_params wme[3]; @@ -187,7 +186,6 @@ struct task sc_scanstarttask;/* scan start processing */ struct task sc_scanaborttask;/* scan abort processing */ struct task sc_scandonetask;/* scan completed processing */ - struct task sc_scantask; /* scan channel processing */ struct task sc_setwmetask; /* set wme params processing */ struct task sc_downtask; /* disassociate processing */ struct task sc_restarttask; /* restart adapter processing */ @@ -215,7 +213,9 @@ #define IWI_SET_CHANNEL (1 << 1) #define IWI_SCAN_END (1 << 2) #define IWI_ASSOC (1 << 3) - int sc_scanop; /* operation for scan task to perform */ +#define IWI_SCAN_CURCHAN (1 << 4) + int sc_scanop; /* op for scan task to do */ + unsigned long sc_maxdwell; /* max dwell time for curchan */ struct bpf_if *sc_drvbpf; union {