Simplify the logic for checking the scan candidates at the end of a scan.

Hold a lock on the table instead of futzing with reference counts which
was potentially dangerous except drivers were quiescent while we did this
so the table contents never changed.  Disable the hack logic for removing
scan candidates with multiple association failures; it's never done the
right thing and will be fixed correctly with background scanning goes in.
This commit is contained in:
sam 2005-01-18 20:21:29 +00:00
parent de6108a4c0
commit c32261430c

View File

@ -589,15 +589,12 @@ ieee80211_cancel_scan(struct ieee80211com *ic)
void
ieee80211_end_scan(struct ieee80211com *ic)
{
struct ieee80211_node *ni, *nextbs, *selbs;
struct ieee80211_node_table *nt;
struct ieee80211_node_table *nt = &ic->ic_scan;
struct ieee80211_node *ni, *selbs;
ieee80211_cancel_scan(ic);
ieee80211_notify_scan_done(ic);
nt = &ic->ic_scan;
ni = TAILQ_FIRST(&nt->nt_node);
if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
u_int8_t maxrssi[IEEE80211_CHAN_MAX]; /* XXX off stack? */
int i, bestchan;
@ -611,15 +608,14 @@ ieee80211_end_scan(struct ieee80211com *ic)
* looks to be quietest.
*/
memset(maxrssi, 0, sizeof(maxrssi));
for (; ni != NULL; ni = nextbs) {
ieee80211_ref_node(ni);
nextbs = TAILQ_NEXT(ni, ni_list);
IEEE80211_NODE_LOCK(nt);
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
rssi = ic->ic_node_getrssi(ni);
i = ieee80211_chan2ieee(ic, ni->ni_chan);
if (rssi > maxrssi[i])
maxrssi[i] = rssi;
ieee80211_unref_node(&ni);
}
IEEE80211_NODE_UNLOCK(nt);
/* XXX select channel more intelligently */
bestchan = -1;
for (i = 0; i < IEEE80211_CHAN_MAX; i++)
@ -656,7 +652,8 @@ ieee80211_end_scan(struct ieee80211com *ic)
* Automatic sequencing; look for a candidate and
* if found join the network.
*/
if (ni == NULL) {
/* NB: unlocked read should be ok */
if (TAILQ_FIRST(&nt->nt_node) == NULL) {
IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
"%s: no scan candidate\n", __func__);
notfound:
@ -677,9 +674,8 @@ ieee80211_end_scan(struct ieee80211com *ic)
selbs = NULL;
IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN, "\t%s\n",
"macaddr bssid chan rssi rate flag wep essid");
for (; ni != NULL; ni = nextbs) {
ieee80211_ref_node(ni);
nextbs = TAILQ_NEXT(ni, ni_list);
IEEE80211_NODE_LOCK(nt);
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
if (ni->ni_fails) {
/*
* The configuration of the access points may change
@ -690,26 +686,27 @@ ieee80211_end_scan(struct ieee80211com *ic)
"%s: skip scan candidate %s, fails %u\n",
__func__, ether_sprintf(ni->ni_macaddr),
ni->ni_fails);
ni->ni_fails++;
#if 0
if (ni->ni_fails++ > 2)
ieee80211_free_node(ni);
#endif
continue;
}
if (ieee80211_match_bss(ic, ni) == 0) {
if (selbs == NULL)
selbs = ni;
else if (ieee80211_node_compare(ic, ni, selbs) > 0) {
ieee80211_unref_node(&selbs);
else if (ieee80211_node_compare(ic, ni, selbs) > 0)
selbs = ni;
} else
ieee80211_unref_node(&ni);
} else {
ieee80211_unref_node(&ni);
}
}
if (selbs != NULL) /* NB: grab ref while dropping lock */
(void) ieee80211_ref_node(selbs);
IEEE80211_NODE_UNLOCK(nt);
if (selbs == NULL)
goto notfound;
if (!ieee80211_sta_join(ic, selbs)) {
ieee80211_unref_node(&selbs);
ieee80211_free_node(selbs);
goto notfound;
}
}