From c32261430ca08f1c2e4d126512480156481142bc Mon Sep 17 00:00:00 2001 From: sam Date: Tue, 18 Jan 2005 20:21:29 +0000 Subject: [PATCH] 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. --- sys/net80211/ieee80211_node.c | 37 ++++++++++++++++------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index e865c67572c7..bfae047182e2 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -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; } }