Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Jan 2005 23:11:40 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 68864 for review
Message-ID:  <200501122311.j0CNBe5L016142@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=68864

Change 68864 by sam@sam_ebb on 2005/01/12 23:11:01

	Embed the station table in the ieee80211com structure instead
	of dynamically allocating it.  We can't do the latter safely
	without locking the enclosing structure or revamping locking
	strategy.  Since a node table is <250 bytes just eat the space
	for now.  The positive in this is that we can eliminate all
	the checks for whether the table is allocated.

Affected files ...

.. //depot/projects/wifi/sys/dev/ath/ath_rate/amrr/amrr.c#7 edit
.. //depot/projects/wifi/sys/dev/ath/ath_rate/onoe/onoe.c#7 edit
.. //depot/projects/wifi/sys/net80211/ieee80211.c#19 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_input.c#39 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#34 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.c#39 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.h#20 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.c#22 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_var.h#23 edit

Differences ...

==== //depot/projects/wifi/sys/dev/ath/ath_rate/amrr/amrr.c#7 (text+ko) ====

@@ -361,8 +361,7 @@
 		 * For any other operating mode we want to reset the
 		 * tx rate state of each node.
 		 */
-		if (ic->ic_sta != NULL)
-			ieee80211_iterate_nodes(ic->ic_sta, ath_rate_cb, 0);
+		ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, 0);
 		ath_rate_update(sc, ic->ic_bss, 0);
 	}
 	if (ic->ic_fixed_rate == -1 && state == IEEE80211_S_RUN) {
@@ -467,8 +466,8 @@
 
 		if (ic->ic_opmode == IEEE80211_M_STA)
 			ath_rate_ctl(sc, ic->ic_bss);	/* NB: no reference */
-		else if (ic->ic_sta != NULL)
-			ieee80211_iterate_nodes(ic->ic_sta, ath_rate_ctl, sc);
+		else
+			ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc);
 	}
 	interval = ath_rateinterval;
 	if (ic->ic_opmode == IEEE80211_M_STA)

==== //depot/projects/wifi/sys/dev/ath/ath_rate/onoe/onoe.c#7 (text+ko) ====

@@ -345,8 +345,7 @@
 		 * For any other operating mode we want to reset the
 		 * tx rate state of each node.
 		 */
-		if (ic->ic_sta != NULL)
-			ieee80211_iterate_nodes(ic->ic_sta, ath_rate_cb, 0);
+		ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, 0);
 		ath_rate_update(sc, ic->ic_bss, 0);
 	}
 	if (ic->ic_fixed_rate == -1 && state == IEEE80211_S_RUN) {
@@ -448,8 +447,8 @@
 
 		if (ic->ic_opmode == IEEE80211_M_STA)
 			ath_rate_ctl(sc, ic->ic_bss);	/* NB: no reference */
-		else if (ic->ic_sta != NULL)
-			ieee80211_iterate_nodes(ic->ic_sta, ath_rate_ctl, sc);
+		else
+			ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc);
 	}
 	interval = ath_rateinterval;
 	if (ic->ic_opmode == IEEE80211_M_STA)

==== //depot/projects/wifi/sys/net80211/ieee80211.c#19 (text+ko) ====

@@ -714,8 +714,8 @@
 				nt->nt_timeout(nt);
 			need_inact_timer += nt->nt_inact_timer;
 		}
-		nt = ic->ic_sta;
-		if (nt != NULL && nt->nt_inact_timer) {
+		nt = &ic->ic_sta;
+		if (nt->nt_inact_timer) {
 			if (--nt->nt_inact_timer == 0)
 				nt->nt_timeout(nt);
 			need_inact_timer += nt->nt_inact_timer;

==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#39 (text+ko) ====

@@ -239,7 +239,7 @@
 				 * Fake up a node for this newly
 				 * discovered member of the IBSS.
 				 */
-				ni = ieee80211_fakeup_adhoc_node(ic->ic_sta,
+				ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
 						type == IEEE80211_FC0_TYPE_CTL ?
 						    wh->i_addr1 : wh->i_addr2);
 				if (ni == NULL) {
@@ -353,7 +353,7 @@
 				IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
 				    wh, "data", "%s", "unknown src");
 				/* NB: caller deals with reference */
-				ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
+				ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
 				if (ni != NULL) {
 					IEEE80211_SEND_MGMT(ic, ni,
 					    IEEE80211_FC0_SUBTYPE_DEAUTH,
@@ -721,7 +721,7 @@
 			/* XXX this dups work done in ieee80211_encap */
 			/* check if destination is associated */
 			struct ieee80211_node *ni1 =
-			    ieee80211_find_node(ic->ic_sta,
+			    ieee80211_find_node(&ic->ic_sta,
 						eh->ether_dhost);
 			if (ni1 != NULL) {
 				/* XXX check if authorized */
@@ -1018,7 +1018,7 @@
 		}
 		/* always accept open authentication requests */
 		if (ni == ic->ic_bss) {
-			ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
+			ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
 			if (ni == NULL)
 				return;
 		} else
@@ -1165,7 +1165,7 @@
 		switch (seq) {
 		case IEEE80211_AUTH_SHARED_REQUEST:
 			if (ni == ic->ic_bss) {
-				ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
+				ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
 				if (ni == NULL) {
 					/* NB: no way to return an error */
 					return;
@@ -2072,7 +2072,7 @@
 			if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
 				if ((capinfo & IEEE80211_CAPINFO_IBSS) == 0)
 					return;
-				ni = ieee80211_fakeup_adhoc_node(ic->ic_sta,
+				ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
 						wh->i_addr2);
 			} else
 				ni = ieee80211_dup_bss(&ic->ic_scan, wh->i_addr2);
@@ -2186,10 +2186,10 @@
 				 * send the response so blindly add them to the
 				 * neighbor table.
 				 */
-				ni = ieee80211_fakeup_adhoc_node(ic->ic_sta,
+				ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
 					wh->i_addr2);
 			} else
-				ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
+				ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
 			if (ni == NULL)
 				return;
 			allocbs = 1;
@@ -2361,7 +2361,7 @@
 			    "[%s] deny %s request, sta not authenticated\n",
 			    ether_sprintf(wh->i_addr2),
 			    reassoc ? "reassoc" : "assoc");
-			ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
+			ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
 			if (ni != NULL) {
 				IEEE80211_SEND_MGMT(ic, ni,
 				    IEEE80211_FC0_SUBTYPE_DEAUTH,

==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#34 (text+ko) ====

@@ -868,9 +868,7 @@
 		return error;
 	kid = ik.ik_keyix;
 	if (kid == IEEE80211_KEYIX_NONE) {
-		if (ic->ic_sta == NULL)
-			return EINVAL;
-		ni = ieee80211_find_node(ic->ic_sta, ik.ik_macaddr);
+		ni = ieee80211_find_node(&ic->ic_sta, ik.ik_macaddr);
 		if (ni == NULL)
 			return EINVAL;		/* XXX */
 		wk = &ni->ni_ucastkey;
@@ -958,9 +956,7 @@
 	error = copyin(ireq->i_data, wpaie.wpa_macaddr, IEEE80211_ADDR_LEN);
 	if (error != 0)
 		return error;
-	if (ic->ic_sta == NULL)
-		return EINVAL;
-	ni = ieee80211_find_node(ic->ic_sta, wpaie.wpa_macaddr);
+	ni = ieee80211_find_node(&ic->ic_sta, wpaie.wpa_macaddr);
 	if (ni == NULL)
 		return EINVAL;		/* XXX */
 	memset(wpaie.wpa_ie, 0, sizeof(wpaie.wpa_ie));
@@ -989,9 +985,7 @@
 	error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN);
 	if (error != 0)
 		return error;
-	if (ic->ic_sta == NULL)
-		return EINVAL;
-	ni = ieee80211_find_node(ic->ic_sta, macaddr);
+	ni = ieee80211_find_node(&ic->ic_sta, macaddr);
 	if (ni == NULL)
 		return EINVAL;		/* XXX */
 	if (ireq->i_len > sizeof(struct ieee80211req_sta_stats))
@@ -1145,9 +1139,7 @@
 	int error, space;
 	u_int8_t *p, *cp;
 
-	nt = ic->ic_sta;
-	if (nt == NULL)
-		return EINVAL;
+	nt = &ic->ic_sta;
 	p = ireq->i_data;
 	space = ireq->i_len;
 	error = 0;
@@ -1193,9 +1185,7 @@
 	error = copyin(ireq->i_data, &txpow, sizeof(txpow));
 	if (error != 0)
 		return error;
-	if (ic->ic_sta == NULL)
-		return EINVAL;
-	ni = ieee80211_find_node(ic->ic_sta, txpow.it_macaddr);
+	ni = ieee80211_find_node(&ic->ic_sta, txpow.it_macaddr);
 	if (ni == NULL)
 		return EINVAL;		/* XXX */
 	txpow.it_txpow = ni->ni_txpower;
@@ -1524,9 +1514,7 @@
 			if (!IEEE80211_ADDR_EQ(ik.ik_macaddr, ni->ni_bssid))
 				return EADDRNOTAVAIL;
 		} else {
-			if (ic->ic_sta == NULL)
-				return EINVAL;
-			ni = ieee80211_find_node(ic->ic_sta, ik.ik_macaddr);
+			ni = ieee80211_find_node(&ic->ic_sta, ik.ik_macaddr);
 			if (ni == NULL)
 				return ENOENT;
 		}
@@ -1579,9 +1567,7 @@
 	if (dk.idk_keyix == (u_int8_t) IEEE80211_KEYIX_NONE) {
 		struct ieee80211_node *ni;
 
-		if (ic->ic_sta == NULL)
-			return EINVAL;
-		ni = ieee80211_find_node(ic->ic_sta, dk.idk_macaddr);
+		ni = ieee80211_find_node(&ic->ic_sta, dk.idk_macaddr);
 		if (ni == NULL)
 			return EINVAL;		/* XXX */
 		/* XXX error return */
@@ -1662,15 +1648,13 @@
 		case IEEE80211_M_HOSTAP:
 			/* NB: the broadcast address means do 'em all */
 			if (!IEEE80211_ADDR_EQ(mlme.im_macaddr, ic->ic_ifp->if_broadcastaddr)) {
-				if (ic->ic_sta == NULL ||
-				    (ni = ieee80211_find_node(ic->ic_sta,
+				if ((ni = ieee80211_find_node(&ic->ic_sta,
 						mlme.im_macaddr)) == NULL)
 					return EINVAL;
 				domlme(&mlme, ni);
 				ieee80211_free_node(ni);
 			} else {
-				if (ic->ic_sta != NULL)
-					ieee80211_iterate_nodes(ic->ic_sta,
+				ieee80211_iterate_nodes(&ic->ic_sta,
 						domlme, &mlme);
 			}
 			break;
@@ -1682,9 +1666,7 @@
 	case IEEE80211_MLME_UNAUTHORIZE:
 		if (ic->ic_opmode != IEEE80211_M_HOSTAP)
 			return EINVAL;
-		if (ic->ic_sta == NULL)
-			return EINVAL;
-		ni = ieee80211_find_node(ic->ic_sta, mlme.im_macaddr);
+		ni = ieee80211_find_node(&ic->ic_sta, mlme.im_macaddr);
 		if (ni == NULL)
 			return EINVAL;
 		if (mlme.im_op == IEEE80211_MLME_AUTHORIZE)
@@ -1817,9 +1799,7 @@
 	error = copyin(ireq->i_data, &txpow, sizeof(txpow));
 	if (error != 0)
 		return error;
-	if (ic->ic_sta == NULL)
-		return EINVAL;
-	ni = ieee80211_find_node(ic->ic_sta, txpow.it_macaddr);
+	ni = ieee80211_find_node(&ic->ic_sta, txpow.it_macaddr);
 	if (ni == NULL)
 		return EINVAL;		/* XXX */
 	ni->ni_txpower = txpow.it_txpow;

==== //depot/projects/wifi/sys/net80211/ieee80211_node.c#39 (text+ko) ====

@@ -68,9 +68,6 @@
 static void ieee80211_node_table_init(struct ieee80211com *ic,
 	struct ieee80211_node_table *nt, const char *name, int inact,
 	void (*timeout)(struct ieee80211_node_table *));
-static struct ieee80211_node_table *ieee80211_node_table_alloc(
-	struct ieee80211com *ic, const char *name, int inact,
-	void (*timeout)(struct ieee80211_node_table *));
 static void ieee80211_node_table_cleanup(struct ieee80211_node_table *nt);
 
 MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state");
@@ -79,7 +76,8 @@
 ieee80211_node_attach(struct ieee80211com *ic)
 {
 
-	ic->ic_sta = NULL;		/* defer to when we need it */
+	ieee80211_node_table_init(ic, &ic->ic_sta, "station",
+		IEEE80211_INACT_INIT, ieee80211_timeout_stations);
 	ieee80211_node_table_init(ic, &ic->ic_scan, "scan",
 		IEEE80211_INACT_SCAN, ieee80211_timeout_scan_candidates);
 
@@ -176,10 +174,7 @@
 		ic->ic_bss = NULL;
 	}
 	ieee80211_node_table_cleanup(&ic->ic_scan);
-	if (ic->ic_sta != NULL) {
-		ieee80211_node_table_free(ic->ic_sta);
-		ic->ic_sta = NULL;
-	}
+	ieee80211_node_table_cleanup(&ic->ic_sta);
 	if (ic->ic_aid_bitmap != NULL) {
 		FREE(ic->ic_aid_bitmap, M_DEVBUF);
 		ic->ic_aid_bitmap = NULL;
@@ -355,6 +350,7 @@
 void
 ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan)
 {
+	struct ieee80211_node_table *nt;
 	struct ieee80211_node *ni;
 
 	IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
@@ -366,33 +362,27 @@
 	 * we create nodes only through discovery and they typically
 	 * are long-lived associations.
 	 */
-	if (ic->ic_opmode == IEEE80211_M_HOSTAP)
-		ic->ic_sta = ieee80211_node_table_alloc(ic,
-					"station", ic->ic_inact_init,
-					ieee80211_timeout_stations);
-	else
-		ic->ic_sta = ieee80211_node_table_alloc(ic,
-					"neighbor", ic->ic_inact_run,
-					ieee80211_timeout_stations);
-	if (ic->ic_sta == NULL) {
-		/*
-		 * Should remain in SCAN state and retry.
-		 */
-		/* XXX stat+msg */
+	nt = &ic->ic_sta;
+	IEEE80211_NODE_LOCK(nt);
+	if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+		nt->nt_name = "station";
+		nt->nt_inact_init = ic->ic_inact_init;
+	} else {
+		nt->nt_name = "neighbor";
+		nt->nt_inact_init = ic->ic_inact_run;
+	}
+	IEEE80211_NODE_UNLOCK(nt);
+
+	ni = ieee80211_alloc_node(nt, ic->ic_myaddr);
+	if (ni == NULL) {
+		/* XXX recovery? */
+		IEEE80211_NODE_UNLOCK(nt);
 		return;
 	}
-
-	ni = ic->ic_bss;
-	IEEE80211_ADDR_COPY(ni->ni_macaddr, ic->ic_myaddr);
 	IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_myaddr);
 	ni->ni_esslen = ic->ic_des_esslen;
 	memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen);
-	ni->ni_rssi = 0;
-	ni->ni_rstamp = 0;
-	ni->ni_tstamp.tsf = 0;
 	ni->ni_intval = ic->ic_lintval;
-	ni->ni_capinfo = 0;
-	ni->ni_erp = 0;
 	if (ic->ic_flags & IEEE80211_F_PRIVACY)
 		ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
 	if (ic->ic_phytype == IEEE80211_T_FH) {
@@ -423,15 +413,8 @@
 		 */
 		ieee80211_set11gbasicrates(&ni->ni_rates, IEEE80211_MODE_11B);
 	}
-	/*
-	 * Set the erp state (mostly the slot time) to deal with
-	 * the auto-select case; this should be redundant if the
-	 * mode is locked.
-	 */ 
-	ieee80211_reset_erp(ic);
-	ieee80211_wme_initparams(ic);
 
-	ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+	(void) ieee80211_sta_join(ic, ieee80211_ref_node(ni));
 }
 
 void
@@ -440,16 +423,14 @@
 	struct ieee80211_node *ni, *obss;
 
 	ieee80211_node_table_reset(&ic->ic_scan);
+	ieee80211_node_table_reset(&ic->ic_sta);
+
 	ni = ieee80211_alloc_node(&ic->ic_scan, ic->ic_myaddr);
 	KASSERT(ni != NULL, ("unable to setup inital BSS node"));
 	obss = ic->ic_bss;
 	ic->ic_bss = ieee80211_ref_node(ni);
 	if (obss != NULL)
 		ieee80211_free_node(obss);
-	if (ic->ic_sta != NULL) {
-		ieee80211_node_table_free(ic->ic_sta);
-		ic->ic_sta = NULL;
-	}
 }
 
 static int
@@ -576,7 +557,8 @@
 ieee80211_cancel_scan(struct ieee80211com *ic)
 {
 
-	IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN, "end %s scan\n",
+	IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN, "%s: end %s scan\n",
+		__func__,
 		(ic->ic_flags & IEEE80211_F_ASCAN) ?  "active" : "passive");
 
 	ic->ic_flags &= ~(IEEE80211_F_SCAN | IEEE80211_F_ASCAN);
@@ -588,14 +570,10 @@
 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);
-
-	nt = &ic->ic_scan;
-	ni = TAILQ_FIRST(&nt->nt_node);
-
 	ieee80211_notify_scan_done(ic);
 
 	if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
@@ -611,15 +589,14 @@
 		 * 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 +633,8 @@
 	 * 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 +655,8 @@
 	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 +667,27 @@
 				"%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;
 	}
 }
@@ -730,7 +708,8 @@
 ieee80211_ibss_merge(struct ieee80211com *ic, struct ieee80211_node *ni)
 {
 
-	if (IEEE80211_ADDR_EQ(ni->ni_bssid, ic->ic_bss->ni_bssid)) {
+	if (ni == ic->ic_bss ||
+	    IEEE80211_ADDR_EQ(ni->ni_bssid, ic->ic_bss->ni_bssid)) {
 		/* unchanged, nothing to do */
 		return 0;
 	}
@@ -747,8 +726,7 @@
 		ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long",
 		ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : ""
 	);
-	/* XXX check ni is in sta table and not scan table */
-	return ieee80211_sta_join(ic, ni);
+	return ieee80211_sta_join(ic, ieee80211_ref_node(ni));
 }
 
 /*
@@ -761,34 +739,28 @@
 	struct ieee80211_node *obss;
 
 	if (ic->ic_opmode == IEEE80211_M_IBSS) {
+		struct ieee80211_node_table *nt;
 		/*
 		 * Delete unusable rates; we've already checked
 		 * that the negotiated rate set is acceptable.
 		 */
 		ieee80211_fix_rate(ic, selbs, IEEE80211_F_DODEL);
 		/*
-		 * Create the neighbor table; it will already
+		 * Fillin the neighbor table; it will already
 		 * exist if we are simply switching mastership.
 		 */
-		if (ic->ic_sta == NULL) {
-			ic->ic_sta = ieee80211_node_table_alloc(ic,
-					"neighbor", ic->ic_inact_run,
-					ieee80211_timeout_stations);
-			if (ic->ic_sta == NULL) {
-				/*
-				 * Should remain in SCAN state and retry.
-				 */
-				/* XXX stat+msg */
-				return 0;
-			}
-		}
+		nt = &ic->ic_sta;
+		IEEE80211_NODE_LOCK(nt);
+		nt->nt_name = "neighbor";
+		nt->nt_inact_init = ic->ic_inact_run;
+		IEEE80211_NODE_UNLOCK(nt);
 	}
 
 	/*
 	 * Committed to selbs, setup state.
 	 */
 	obss = ic->ic_bss;
-	ic->ic_bss = selbs;
+	ic->ic_bss = selbs;		/* NB: caller assumed to bump refcnt */
 	if (obss != NULL)
 		ieee80211_free_node(obss);
 	/*
@@ -799,10 +771,10 @@
 	ic->ic_curmode = ieee80211_chan2mode(ic, selbs->ni_chan);
 	ieee80211_reset_erp(ic);
 	ieee80211_wme_initparams(ic);
-	if (ic->ic_opmode == IEEE80211_M_IBSS)
+	if (ic->ic_opmode == IEEE80211_M_STA)
+		ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
+	else
 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
-	else
-		ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
 	return 1;
 }
 
@@ -1077,7 +1049,7 @@
 	    (ic->ic_flags & IEEE80211_F_SCAN))
 		nt = &ic->ic_scan;
 	else
-		nt = ic->ic_sta;
+		nt = &ic->ic_sta;
 	/* XXX check ic_bss first in station mode */
 	/* XXX 4-address frames? */
 	IEEE80211_NODE_LOCK(nt);
@@ -1104,7 +1076,7 @@
 ieee80211_find_txnode(struct ieee80211com *ic, const u_int8_t *macaddr)
 #endif
 {
-	struct ieee80211_node_table *nt = ic->ic_sta;
+	struct ieee80211_node_table *nt = &ic->ic_sta;
 	struct ieee80211_node *ni;
 
 	/*
@@ -1112,7 +1084,7 @@
 	 * unless we are operating in station mode or this is a
 	 * multicast/broadcast frame.
 	 */
-	if (nt == NULL || IEEE80211_IS_MULTICAST(macaddr))
+	if (ic->ic_opmode == IEEE80211_M_STA || IEEE80211_IS_MULTICAST(macaddr))
 		return ieee80211_ref_node(ic->ic_bss);
 
 	/* XXX can't hold lock across dup_bss 'cuz of recursive locking */
@@ -1272,7 +1244,7 @@
 		 * Other references are present, just remove the
 		 * node from the table so it cannot be found.  When
 		 * the references are dropped storage will be
-		 * reclaimed.  This normally only happens for ic_bss.
+		 * reclaimed.
 		 */
 		TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
 		LIST_REMOVE(ni, ni_hash);
@@ -1754,7 +1726,7 @@
 ieee80211_getrssi(struct ieee80211com *ic)
 {
 #define	NZ(x)	((x) == 0 ? 1 : (x))
-	struct ieee80211_node_table *nt = ic->ic_sta;
+	struct ieee80211_node_table *nt = &ic->ic_sta;
 	u_int32_t rssi_samples, rssi_total;
 	struct ieee80211_node *ni;
 
@@ -1762,32 +1734,23 @@
 	rssi_samples = 0;
 	switch (ic->ic_opmode) {
 	case IEEE80211_M_IBSS:		/* average of all ibss neighbors */
-		nt = ic->ic_sta;
-		if (nt == NULL)
-			break;
 		/* XXX locking */
-		TAILQ_FOREACH(ni, &ic->ic_sta->nt_node, ni_list)
+		TAILQ_FOREACH(ni, &nt->nt_node, ni_list)
 			if (ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) {
 				rssi_samples++;
 				rssi_total += ic->ic_node_getrssi(ni);
 			}
 		break;
 	case IEEE80211_M_AHDEMO:	/* average of all neighbors */
-		nt = ic->ic_sta;
-		if (nt == NULL)
-			break;
 		/* XXX locking */
-		TAILQ_FOREACH(ni, &ic->ic_sta->nt_node, ni_list) {
+		TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
 			rssi_samples++;
 			rssi_total += ic->ic_node_getrssi(ni);
 		}
 		break;
 	case IEEE80211_M_HOSTAP:	/* average of all associated stations */
-		nt = ic->ic_sta;
-		if (nt == NULL)
-			break;
 		/* XXX locking */
-		TAILQ_FOREACH(ni, &ic->ic_sta->nt_node, ni_list)
+		TAILQ_FOREACH(ni, &nt->nt_node, ni_list)
 			if (IEEE80211_AID(ni->ni_associd) != 0) {
 				rssi_samples++;
 				rssi_total += ic->ic_node_getrssi(ni);
@@ -1860,24 +1823,6 @@
 	nt->nt_timeout = timeout;
 }
 
-static struct ieee80211_node_table *
-ieee80211_node_table_alloc(struct ieee80211com *ic,
-	const char *name, int inact,
-	void (*timeout)(struct ieee80211_node_table *))
-{
-	struct ieee80211_node_table *nt;
-
-	MALLOC(nt, struct ieee80211_node_table *,
-		sizeof(struct ieee80211_node_table),
-		M_DEVBUF, M_NOWAIT | M_ZERO);
-	if (nt == NULL) {
-		printf("%s: no memory node table!\n", __func__);
-		return NULL;
-	}
-	ieee80211_node_table_init(ic, nt, name, inact, timeout);
-	return nt;
-}
-
 void
 ieee80211_node_table_reset(struct ieee80211_node_table *nt)
 {
@@ -1902,19 +1847,3 @@
 	IEEE80211_SCAN_LOCK_DESTROY(nt);
 	IEEE80211_NODE_LOCK_DESTROY(nt);
 }
-
-/*
- * NB: public for use in ieee80211_proto.c
- */
-void
-ieee80211_node_table_free(struct ieee80211_node_table *nt)
-{
-
-	IEEE80211_DPRINTF(nt->nt_ic, IEEE80211_MSG_NODE,
-		"%s %s table\n", __func__, nt->nt_name);
-
-	IEEE80211_NODE_LOCK(nt);
-	nt->nt_inact_timer = 0;
-	ieee80211_node_table_cleanup(nt);
-	FREE(nt, M_DEVBUF);
-}

==== //depot/projects/wifi/sys/net80211/ieee80211_node.h#20 (text+ko) ====

@@ -223,7 +223,6 @@
 	void			(*nt_timeout)(struct ieee80211_node_table *);
 };
 extern	void ieee80211_node_table_reset(struct ieee80211_node_table *);
-extern	void ieee80211_node_table_free(struct ieee80211_node_table *);
 
 extern	struct ieee80211_node *ieee80211_alloc_node(
 		struct ieee80211_node_table *, const u_int8_t *);

==== //depot/projects/wifi/sys/net80211/ieee80211_proto.c#22 (text+ko) ====

@@ -856,11 +856,7 @@
 				ieee80211_sta_leave(ic, ni);
 				break;
 			case IEEE80211_M_HOSTAP:
-				nt = ic->ic_sta;
-				if (nt == NULL) {	/* XXX cannot happen */
-					if_printf(ifp, "no sta table (run)\n");
-					break;
-				}
+				nt = &ic->ic_sta;
 				IEEE80211_NODE_LOCK(nt);
 				TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
 					if (ni->ni_associd == 0)
@@ -883,11 +879,7 @@
 				    IEEE80211_REASON_AUTH_LEAVE);
 				break;
 			case IEEE80211_M_HOSTAP:
-				nt = ic->ic_sta;
-				if (nt == NULL) {	/* XXX cannot happen */
-					if_printf(ifp, "no sta table (assoc)\n");
-					break;
-				}
+				nt = &ic->ic_sta;
 				IEEE80211_NODE_LOCK(nt);
 				TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
 					IEEE80211_SEND_MGMT(ic, ni,
@@ -1029,9 +1021,10 @@
 				break;
 			/* fall thru... */
 		case IEEE80211_S_AUTH:
-		case IEEE80211_S_RUN:
 			IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
 				"%s: invalid transition\n", __func__);
+			/* fall thru... */
+		case IEEE80211_S_RUN:
 			break;
 		case IEEE80211_S_SCAN:		/* adhoc/hostap mode */
 		case IEEE80211_S_ASSOC:		/* infra mode */
@@ -1083,8 +1076,7 @@
 		 * XXX
 		 */
 		ic->ic_scan.nt_inact_timer = IEEE80211_INACT_WAIT;
-		if (ic->ic_sta != NULL)
-			ic->ic_sta->nt_inact_timer = IEEE80211_INACT_WAIT;
+		ic->ic_sta.nt_inact_timer = IEEE80211_INACT_WAIT;
 		break;
 	}
 	return 0;

==== //depot/projects/wifi/sys/net80211/ieee80211_var.h#23 (text+ko) ====

@@ -114,7 +114,7 @@
 	enum ieee80211_state	ic_state;	/* 802.11 state */
 	enum ieee80211_protmode	ic_protmode;	/* 802.11g protection mode */
 	enum ieee80211_roamingmode ic_roaming;	/* roaming mode */
-	struct ieee80211_node_table *ic_sta;	/* stations/neighbors */
+	struct ieee80211_node_table ic_sta;	/* stations/neighbors */
 	u_int32_t		*ic_aid_bitmap;	/* association id map */
 	u_int16_t		ic_max_aid;
 	u_int16_t		ic_sta_assoc;	/* stations associated */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501122311.j0CNBe5L016142>