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)
This commit is contained in:
Andrew Thompson 2007-06-30 21:39:21 +00:00
parent b54b1bab4b
commit d81b3a5588
3 changed files with 41 additions and 20 deletions

View File

@ -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:
@ -3536,6 +3541,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)
{

View File

@ -626,6 +626,19 @@ ieee80211_scan_next(struct ieee80211com *ic)
scan_next(ic->ic_scan);
}
/*
* 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).
@ -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

View File

@ -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 *,