Module Name: src Committed By: jmcneill Date: Thu Aug 7 22:10:05 UTC 2014
Modified Files: src/sys/dev/pci: if_wpi.c Log Message: Scan one channel at a time instead of trying to do them all at once and trying to outsmart the ieee80211 state machine. To generate a diff of this commit: cvs rdiff -u -r1.66 -r1.67 src/sys/dev/pci/if_wpi.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/if_wpi.c diff -u src/sys/dev/pci/if_wpi.c:1.66 src/sys/dev/pci/if_wpi.c:1.67 --- src/sys/dev/pci/if_wpi.c:1.66 Thu Aug 7 19:54:23 2014 +++ src/sys/dev/pci/if_wpi.c Thu Aug 7 22:10:05 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wpi.c,v 1.66 2014/08/07 19:54:23 jmcneill Exp $ */ +/* $NetBSD: if_wpi.c,v 1.67 2014/08/07 22:10:05 jmcneill Exp $ */ /*- * Copyright (c) 2006, 2007 @@ -18,7 +18,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.66 2014/08/07 19:54:23 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.67 2014/08/07 22:10:05 jmcneill Exp $"); /* * Driver for Intel PRO/Wireless 3945ABG 802.11 network adapters. @@ -143,7 +143,7 @@ static int wpi_get_power_index(struct wp struct wpi_power_group *, struct ieee80211_channel *, int); static int wpi_setup_beacon(struct wpi_softc *, struct ieee80211_node *); static int wpi_auth(struct wpi_softc *); -static int wpi_scan(struct wpi_softc *, uint16_t); +static int wpi_scan(struct wpi_softc *); static int wpi_config(struct wpi_softc *); static void wpi_stop_master(struct wpi_softc *); static int wpi_power_up(struct wpi_softc *); @@ -877,6 +877,7 @@ wpi_newstate(struct ieee80211com *ic, en struct ifnet *ifp = ic->ic_ifp; struct wpi_softc *sc = ifp->if_softc; struct ieee80211_node *ni; + enum ieee80211_state ostate = ic->ic_state; int error; callout_stop(&sc->calib_to); @@ -888,20 +889,18 @@ wpi_newstate(struct ieee80211com *ic, en break; sc->is_scanning = true; - ieee80211_node_table_reset(&ic->ic_scan); - ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN; - /* make the link LED blink while we're scanning */ - wpi_set_led(sc, WPI_LED_LINK, 20, 2); + if (ostate != IEEE80211_S_SCAN) { + /* make the link LED blink while we're scanning */ + wpi_set_led(sc, WPI_LED_LINK, 20, 2); + } - if ((error = wpi_scan(sc, IEEE80211_CHAN_G)) != 0) { + if ((error = wpi_scan(sc)) != 0) { aprint_error_dev(sc->sc_dev, "could not initiate scan\n"); - ic->ic_flags &= ~(IEEE80211_F_SCAN | IEEE80211_F_ASCAN); return error; } - ic->ic_state = nstate; - return 0; + break; case IEEE80211_S_ASSOC: if (ic->ic_state != IEEE80211_S_RUN) @@ -1750,28 +1749,24 @@ wpi_notif_intr(struct wpi_softc *sc) scan->chan, le32toh(scan->status))); /* fix current channel */ - ic->ic_bss->ni_chan = &ic->ic_channels[scan->chan]; + ic->ic_curchan = &ic->ic_channels[scan->chan]; #endif break; } case WPI_STOP_SCAN: { +#ifdef WPI_DEBUG struct wpi_stop_scan *scan = (struct wpi_stop_scan *)(desc + 1); +#endif DPRINTF(("scan finished nchan=%d status=%d chan=%d\n", scan->nchan, scan->status, scan->chan)); - if (scan->status == 1 && scan->chan <= 14) { - /* - * We just finished scanning 802.11g channels, - * start scanning 802.11a ones. - */ - if (wpi_scan(sc, IEEE80211_CHAN_A) == 0) - break; - } sc->is_scanning = false; - ieee80211_end_scan(ic); + if (ic->ic_state == IEEE80211_S_SCAN) + ieee80211_next_scan(ic); + break; } } @@ -2764,7 +2759,7 @@ wpi_auth(struct wpi_softc *sc) * into a mbuf instead of using the pre-allocated set of commands. */ static int -wpi_scan(struct wpi_softc *sc, uint16_t flags) +wpi_scan(struct wpi_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; struct wpi_tx_ring *ring = &sc->cmdq; @@ -2779,6 +2774,9 @@ wpi_scan(struct wpi_softc *sc, uint16_t uint8_t *frm; int pktlen, error, nrates; + if (ic->ic_curchan == NULL) + return EIO; + desc = &ring->desc[ring->cur]; data = &ring->data[ring->cur]; @@ -2809,14 +2807,14 @@ wpi_scan(struct wpi_softc *sc, uint16_t hdr->cmd.id = WPI_ID_BROADCAST; hdr->cmd.lifetime = htole32(WPI_LIFETIME_INFINITE); /* - * Move to the next channel if no packets are received within 10 msecs + * Move to the next channel if no packets are received within 5 msecs * after sending the probe request (this helps to reduce the duration * of active scans). */ - hdr->quiet = htole16(10); /* timeout in milliseconds */ + hdr->quiet = htole16(5); /* timeout in milliseconds */ hdr->plcp_threshold = htole16(1); /* min # of packets */ - if (flags & IEEE80211_CHAN_A) { + if (ic->ic_curchan->ic_flags & IEEE80211_CHAN_5GHZ) { hdr->crc_threshold = htole16(1); /* send probe requests at 6Mbps */ hdr->cmd.rate = wpi_plcp_signal(12); @@ -2877,32 +2875,29 @@ wpi_scan(struct wpi_softc *sc, uint16_t hdr->cmd.len = htole16(frm - (uint8_t *)wh); chan = (struct wpi_scan_chan *)frm; - for (c = &ic->ic_channels[1]; - c <= &ic->ic_channels[IEEE80211_CHAN_MAX]; c++) { - if ((c->ic_flags & flags) != flags) - continue; + c = ic->ic_curchan; - chan->chan = ieee80211_chan2ieee(ic, c); - chan->flags = 0; - if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE)) - chan->flags |= WPI_CHAN_ACTIVE; + chan->chan = ieee80211_chan2ieee(ic, c); + chan->flags = 0; + if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE)) { + chan->flags |= WPI_CHAN_ACTIVE; if (ic->ic_des_esslen != 0) chan->flags |= WPI_CHAN_DIRECT; - chan->dsp_gain = 0x6e; - if (IEEE80211_IS_CHAN_5GHZ(c)) { - chan->rf_gain = 0x3b; - chan->active = htole16(24); - chan->passive = htole16(110); - } else { - chan->rf_gain = 0x28; - chan->active = htole16(36); - chan->passive = htole16(120); - } - hdr->nchan++; - chan++; - - frm += sizeof (struct wpi_scan_chan); } + chan->dsp_gain = 0x6e; + if (IEEE80211_IS_CHAN_5GHZ(c)) { + chan->rf_gain = 0x3b; + chan->active = htole16(10); + chan->passive = htole16(110); + } else { + chan->rf_gain = 0x28; + chan->active = htole16(20); + chan->passive = htole16(120); + } + hdr->nchan++; + chan++; + + frm += sizeof (struct wpi_scan_chan); hdr->len = htole16(frm - (uint8_t *)hdr); pktlen = frm - (uint8_t *)cmd;