summaryrefslogtreecommitdiffstats
path: root/sys/net80211/ieee80211_node.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2005-01-18 20:21:29 +0000
committersam <sam@FreeBSD.org>2005-01-18 20:21:29 +0000
commitc32261430ca08f1c2e4d126512480156481142bc (patch)
treecc6d3eb88660de8939d686c476c1349403cda3ea /sys/net80211/ieee80211_node.c
parentde6108a4c0f3a4ec2be152a66535066f67c09018 (diff)
downloadFreeBSD-src-c32261430ca08f1c2e4d126512480156481142bc.zip
FreeBSD-src-c32261430ca08f1c2e4d126512480156481142bc.tar.gz
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.
Diffstat (limited to 'sys/net80211/ieee80211_node.c')
-rw-r--r--sys/net80211/ieee80211_node.c37
1 files changed, 17 insertions, 20 deletions
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index e865c67..bfae047 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;
}
}
OpenPOWER on IntegriCloud