summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2007-06-30 21:39:21 +0000
committerthompsa <thompsa@FreeBSD.org>2007-06-30 21:39:21 +0000
commit76b4b5f6b064569bcf43b44df19092d7dccf525b (patch)
tree306cc9408848851d98d30d3afd746ba9f8d4a1f4
parent03a3b230428af3dfad8a2660809025cc47b938c6 (diff)
downloadFreeBSD-src-76b4b5f6b064569bcf43b44df19092d7dccf525b.zip
FreeBSD-src-76b4b5f6b064569bcf43b44df19092d7dccf525b.tar.gz
Fix scanning issues since the new net80211 code went in
- provide dummy routines for ic_scan_curchan and ic_scan_mindwell, we do not support those operations. - add ieee80211_scan_done() to tell the scanning module that all channels have been scanned. - pass IEEE80211_S_SCAN state off to net80211 so it can initiate scanning - fix overflow in the rates array - scale the rate value passed back from the firmware scan to the units that net80211 uses. Submitted by: Token Reviewed by: sam, avatar Approved by: re (kensmith)
-rw-r--r--sys/dev/wi/if_wi.c37
-rw-r--r--sys/net80211/ieee80211_scan.c23
-rw-r--r--sys/net80211/ieee80211_scan.h1
3 files changed, 41 insertions, 20 deletions
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index 86f8b96..8c1ea93 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -165,6 +165,8 @@ static int wi_symbol_write_firm(struct wi_softc *, const void *, int,
static int wi_symbol_set_hcr(struct wi_softc *, int);
static void wi_scan_start(struct ieee80211com *);
+static void wi_scan_curchan(struct ieee80211com *, unsigned long);
+static void wi_scan_mindwell(struct ieee80211com *);
static void wi_scan_end(struct ieee80211com *);
static void wi_set_channel(struct ieee80211com *);
static void wi_update_slot(struct ifnet *);
@@ -369,8 +371,9 @@ wi_attach(device_t dev)
val = le16toh(val);
ic->ic_bsschan = ieee80211_find_channel(ic,
ieee80211_ieee2mhz(val, IEEE80211_CHAN_B),
- IEEE80211_MODE_AUTO);
- /* XXX check return value */
+ IEEE80211_CHAN_B);
+ if (ic->ic_bsschan == NULL)
+ ic->ic_bsschan = &ic->ic_channels[0];
} else {
device_printf(dev,
"WI_RID_OWN_CHNL failed, using first channel!\n");
@@ -467,7 +470,6 @@ wi_attach(device_t dev)
rs->rs_rates[rs->rs_nrates++] = ratebuf[2+i];
} else {
/* XXX fallback on error? */
- rs->rs_nrates = 0;
}
buflen = sizeof(val);
@@ -504,6 +506,8 @@ wi_attach(device_t dev)
ic->ic_raw_xmit = wi_raw_xmit;
ic->ic_scan_start = wi_scan_start;
+ ic->ic_scan_curchan = wi_scan_curchan;
+ ic->ic_scan_mindwell = wi_scan_mindwell;
ic->ic_scan_end = wi_scan_end;
ic->ic_set_channel = wi_set_channel;
ic->ic_node_alloc = wi_node_alloc;
@@ -1918,9 +1922,9 @@ wi_info_intr(struct wi_softc *sc)
case WI_INFO_SCAN_RESULTS:
case WI_INFO_HOST_SCAN_RESULTS:
wi_scan_result(sc, fid, le16toh(ltbuf[0]));
- ieee80211_notify_scan_done(ic);
+ ieee80211_scan_done(ic);
break;
-
+
default:
DPRINTF(("wi_info_intr: got fid %x type %x len %d\n", fid,
le16toh(ltbuf[1]), le16toh(ltbuf[0])));
@@ -2945,6 +2949,8 @@ wi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
return (*sc->sc_newstate)(ic, nstate, arg);
case IEEE80211_S_SCAN:
+ return (*sc->sc_newstate)(ic, nstate, arg);
+
case IEEE80211_S_AUTH:
case IEEE80211_S_ASSOC:
ic->ic_state = nstate; /* NB: skip normal ieee80211 handling */
@@ -2964,7 +2970,6 @@ wi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
IEEE80211_CHAN_B);
if (ni->ni_chan == NULL)
ni->ni_chan = &ic->ic_channels[0];
- /* XXX validate channel */
ic->ic_curchan = ic->ic_bsschan = ni->ni_chan;
#if NBPFILTER > 0
sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
@@ -3046,7 +3051,6 @@ wi_scan_result(struct wi_softc *sc, int fid, int cnt)
struct ieee80211com *ic;
uint8_t ssid[2+IEEE80211_NWID_LEN];
- printf("wi_scan_result\n");
ic = &sc->sc_ic;
rstamp++;
memset(&sp, 0, sizeof(sp));
@@ -3081,7 +3085,7 @@ wi_scan_result(struct wi_softc *sc, int fid, int cnt)
memset(&ws_dat, 0, sizeof(ws_dat));
for (i = 0; i < naps; i++, ap++) {
- uint8_t rates[2];
+ uint8_t rates[2 + IEEE80211_RATE_MAXSIZE];
uint16_t *bssid;
wi_read_bap(sc, fid, off, &ws_dat,
(sizeof(ws_dat) < szbuf ? sizeof(ws_dat) : szbuf));
@@ -3106,7 +3110,7 @@ wi_scan_result(struct wi_softc *sc, int fid, int cnt)
sp.bintval = ap->interval = le16toh(ws_dat.wi_interval);
ap->rate = le16toh(ws_dat.wi_rate);
rates[1] = 1;
- rates[2] = (uint8_t)ap->rate;
+ rates[2] = (uint8_t)ap->rate / 5;
ap->namelen = le16toh(ws_dat.wi_namelen);
if (ap->namelen > sizeof(ap->name))
ap->namelen = sizeof(ap->name);
@@ -3122,7 +3126,8 @@ wi_scan_result(struct wi_softc *sc, int fid, int cnt)
sp.curchan = &ic->ic_channels[0];
sp.rates = &rates[0];
sp.tstamp = (uint8_t *)&rstamp;
- printf("calling add_scan \n");
+ DPRINTF(("calling add_scan, bssid %s chan %d signal %d\n",
+ ether_sprintf(ws_dat.wi_bssid), ap->channel, ap->signal));
ieee80211_add_scan(ic, &sp, &wh, 0, ap->signal, ap->noise, rstamp);
}
done:
@@ -3537,6 +3542,18 @@ wi_scan_start(struct ieee80211com *ic)
}
static void
+wi_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell)
+{
+ /* The firmware is not capable of scanning a single channel */
+}
+
+static void
+wi_scan_mindwell(struct ieee80211com *ic)
+{
+ /* NB: don't try to abort scan; wait for firmware to finish */
+}
+
+static void
wi_scan_end(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c
index 8835654..35584e5 100644
--- a/sys/net80211/ieee80211_scan.c
+++ b/sys/net80211/ieee80211_scan.c
@@ -627,6 +627,19 @@ ieee80211_scan_next(struct ieee80211com *ic)
}
/*
+ * Public access to scan_next for drivers that are not able to scan single
+ * channels (e.g. for firmware-based devices).
+ */
+void
+ieee80211_scan_done(struct ieee80211com *ic)
+{
+ struct ieee80211_scan_state *ss = ic->ic_scan;
+
+ ss->ss_next = ss->ss_last; /* all channels are complete */
+ scan_next(ss);
+}
+
+/*
* Scan curchan. If this is an active scan and the channel
* is not marked passive then send probe request frame(s).
* Arrange for the channel change after maxdwell ticks.
@@ -897,17 +910,7 @@ ieee80211_add_scan(struct ieee80211com *ic,
ieee80211_chan2ieee(ic, ic->ic_curchan),
channel_type(ic->ic_curchan),
ticks, SCAN_PRIVATE(ss)->ss_chanmindwell);
- /*
- * XXX
- * We want to just kick the timer and still
- * process frames until it fires but linux
- * will livelock unless we discard frames.
- */
-#if 0
SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_MINDWELL;
-#else
- SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD;
-#endif
/*
* NB: trigger at next clock tick or wait for the
* hardware
diff --git a/sys/net80211/ieee80211_scan.h b/sys/net80211/ieee80211_scan.h
index d8953c4..fed5e0b 100644
--- a/sys/net80211/ieee80211_scan.h
+++ b/sys/net80211/ieee80211_scan.h
@@ -83,6 +83,7 @@ int ieee80211_check_scan(struct ieee80211com *, int flags, u_int duration,
int ieee80211_bg_scan(struct ieee80211com *);
void ieee80211_cancel_scan(struct ieee80211com *);
void ieee80211_scan_next(struct ieee80211com *);
+void ieee80211_scan_done(struct ieee80211com *);
struct ieee80211_scanparams;
void ieee80211_add_scan(struct ieee80211com *,
OpenPOWER on IntegriCloud