PERFORCE change 64628 for review
Sam Leffler
sam at FreeBSD.org
Mon Nov 8 11:07:24 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=64628
Change 64628 by sam at sam_ebb on 2004/11/08 19:07:05
checkpoint node table rewrite; works for station mode
Affected files ...
.. //depot/projects/wifi/sys/dev/ath/if_ath.c#13 edit
.. //depot/projects/wifi/sys/dev/ath/if_athvar.h#5 edit
.. //depot/projects/wifi/sys/dev/awi/awi.c#3 edit
.. //depot/projects/wifi/sys/dev/wi/if_wi.c#4 edit
.. //depot/projects/wifi/sys/net80211/ieee80211.c#3 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#3 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_input.c#10 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#10 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.c#8 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.h#7 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_output.c#7 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.c#4 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_var.h#6 edit
Differences ...
==== //depot/projects/wifi/sys/dev/ath/if_ath.c#13 (text+ko) ====
@@ -124,12 +124,9 @@
static void ath_beacon_config(struct ath_softc *);
static int ath_desc_alloc(struct ath_softc *);
static void ath_desc_free(struct ath_softc *);
-static struct ieee80211_node *ath_node_alloc(struct ieee80211com *);
-static void ath_node_cleanup(struct ieee80211com *, struct ieee80211_node*);
-static void ath_node_copy(struct ieee80211com *,
- struct ieee80211_node *, const struct ieee80211_node *);
-static u_int8_t ath_node_getrssi(struct ieee80211com *,
- struct ieee80211_node *);
+static struct ieee80211_node *ath_node_alloc(struct ieee80211_node_table *);
+static void ath_node_free(struct ieee80211_node *);
+static u_int8_t ath_node_getrssi(const struct ieee80211_node *);
static int ath_rxbuf_init(struct ath_softc *, struct ath_buf *);
static void ath_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
struct ieee80211_node *ni,
@@ -509,10 +506,8 @@
ieee80211_ifattach(ic);
/* override default methods */
ic->ic_node_alloc = ath_node_alloc;
- sc->sc_node_cleanup = ic->ic_node_cleanup;
- ic->ic_node_cleanup = ath_node_cleanup;
- sc->sc_node_copy = ic->ic_node_copy;
- ic->ic_node_copy = ath_node_copy;
+ sc->sc_node_free = ic->ic_node_free;
+ ic->ic_node_free = ath_node_free;
ic->ic_node_getrssi = ath_node_getrssi;
sc->sc_recv_mgmt = ic->ic_recv_mgmt;
ic->ic_recv_mgmt = ath_recv_mgmt;
@@ -1087,8 +1082,8 @@
STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
ATH_TXBUF_UNLOCK(sc);
ifp->if_oerrors++;
- if (ni && ni != ic->ic_bss)
- ieee80211_free_node(ic, ni);
+ if (ni != NULL)
+ ieee80211_free_node(ni);
continue;
}
@@ -2038,8 +2033,9 @@
}
static struct ieee80211_node *
-ath_node_alloc(struct ieee80211com *ic)
+ath_node_alloc(struct ieee80211_node_table *nt)
{
+ struct ieee80211com *ic = nt->nt_ic;
struct ath_softc *sc = ic->ic_ifp->if_softc;
const size_t space = sizeof(struct ath_node) + sc->sc_rc->arc_space;
struct ath_node *an;
@@ -2072,57 +2068,39 @@
ATH_TXQ_LOCK(txq);
STAILQ_FOREACH(bf, &txq->axq_q, bf_list) {
if (bf->bf_node == ni) {
- bf->bf_node = NULL;
- if (ni != ic->ic_bss)
- /* NB: cannot use ieee80211_unref_node */
- ieee80211_node_decref(ni);
+ /* NB: this clears the pointer too */
+ ieee80211_unref_node(&bf->bf_node);
}
}
ATH_TXQ_UNLOCK(txq);
}
static void
-ath_node_cleanup(struct ieee80211com *ic, struct ieee80211_node *ni)
+ath_node_free(struct ieee80211_node *ni)
{
+ struct ieee80211com *ic = ni->ni_ic;
struct ath_softc *sc = ic->ic_ifp->if_softc;
int i;
DPRINTF(sc, ATH_DEBUG_NODE, "%s: ni %p\n", __func__, ni);
+ /* XXX can this happen since refcnt must be zero for us to be called? */
for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
if (ATH_TXQ_SETUP(sc, i))
ath_tx_cleanq(ic, &sc->sc_txq[i], ni);
ath_rate_node_cleanup(sc, ATH_NODE(ni));
- sc->sc_node_cleanup(ic, ni);
+ sc->sc_node_free(ni);
}
-static void
-ath_node_copy(struct ieee80211com *ic,
- struct ieee80211_node *dst, const struct ieee80211_node *src)
-{
- struct ath_softc *sc = ic->ic_ifp->if_softc;
- const struct ath_node *an = (const struct ath_node *)src;
-
- DPRINTF(sc, ATH_DEBUG_NODE, "%s: dst %p src %p\n", __func__, dst, src);
-
- /*
- * NB: Must copy first so the cleanup done by node_copy is
- * done before we copy bits around below.
- */
- sc->sc_node_copy(ic, dst, src);
- memcpy(&dst[1], &src[1],
- sizeof(struct ath_node) - sizeof(struct ieee80211_node));
- ath_rate_node_copy(sc, ATH_NODE(dst), an);
-}
-
static u_int8_t
-ath_node_getrssi(struct ieee80211com *ic, struct ieee80211_node *ni)
+ath_node_getrssi(const struct ieee80211_node *ni)
{
#define HAL_EP_RND(x, mul) \
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+ u_int32_t avgrssi = ATH_NODE_CONST(ni)->an_avgrssi;
int32_t rssi;
- rssi = HAL_EP_RND(ATH_NODE(ni)->an_avgrssi, HAL_RSSI_EP_MULTIPLIER);
+ rssi = HAL_EP_RND(avgrssi, HAL_RSSI_EP_MULTIPLIER);
/* NB: theoretically we shouldn't need this, but be paranoid */
return rssi < 0 ? 0 : rssi > 127 ? 127 : rssi;
#undef HAL_EP_RND
@@ -2245,8 +2223,6 @@
#define PA2DESC(_sc, _pa) \
((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \
((_pa) - (_sc)->sc_desc_paddr)))
-#define IS_CTL(wh) \
- ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
struct ath_softc *sc = arg;
struct ath_buf *bf;
struct ieee80211com *ic = &sc->sc_ic;
@@ -2432,24 +2408,10 @@
/*
* Locate the node for sender, track state, and then
* pass the (referenced) node up to the 802.11 layer
- * for its use. We are required to pass some node so
- * we fall back to ic_bss when this frame is from an
- * unknown sender. The 802.11 layer knows this means the
- * sender wasn't in the node table and acts accordingly.
- * Note also that by convention we do not reference
- * count ic_bss, only other nodes (ic_bss is never free'd).
+ * for its use.
*/
- if (ic->ic_opmode != IEEE80211_M_STA) {
- struct ieee80211_frame_min *wh =
- mtod(m, struct ieee80211_frame_min *);
- if (IS_CTL(wh))
- ni = ieee80211_find_node(ic, wh->i_addr1);
- else
- ni = ieee80211_find_node(ic, wh->i_addr2);
- if (ni == NULL)
- ni = ic->ic_bss;
- } else
- ni = ic->ic_bss;
+ ni = ieee80211_find_rxnode(ic,
+ mtod(m, const struct ieee80211_frame_min *));
/*
* Track rx rssi and do any rx antenna management.
@@ -2479,8 +2441,7 @@
/*
* Reclaim node reference.
*/
- if (ni != ic->ic_bss)
- ieee80211_free_node(ic, ni);
+ ieee80211_free_node(ni);
rx_next:
STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
} while (ath_rxbuf_init(sc, bf) == 0);
@@ -2489,7 +2450,6 @@
ath_hal_rxmonitor(ah, &ATH_NODE(ic->ic_bss)->an_halstats);
NET_UNLOCK_GIANT(); /* XXX */
-#undef IS_CTL
#undef PA2DESC
}
@@ -2980,7 +2940,6 @@
static void
ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
{
- struct ieee80211com *ic = &sc->sc_ic;
struct ath_hal *ah = sc->sc_ah;
struct ath_buf *bf;
struct ath_desc *ds;
@@ -3050,8 +3009,7 @@
* this is a DEAUTH message that was sent and the
* node was timed out due to inactivity.
*/
- if (ni != ic->ic_bss)
- ieee80211_free_node(ic, ni);
+ ieee80211_free_node(ni);
}
bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
BUS_DMASYNC_POSTWRITE);
@@ -3135,7 +3093,6 @@
ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
{
struct ath_hal *ah = sc->sc_ah;
- struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
struct ath_buf *bf;
@@ -3163,11 +3120,11 @@
bf->bf_m = NULL;
ni = bf->bf_node;
bf->bf_node = NULL;
- if (ni != NULL && ni != ic->ic_bss) {
+ if (ni != NULL) {
/*
* Reclaim node reference.
*/
- ieee80211_free_node(ic, ni);
+ ieee80211_free_node(ni);
}
ATH_TXBUF_LOCK(sc);
STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
==== //depot/projects/wifi/sys/dev/ath/if_athvar.h#5 (text+ko) ====
@@ -67,6 +67,7 @@
/* variable-length rate control state follows */
};
#define ATH_NODE(ni) ((struct ath_node *)(ni))
+#define ATH_NODE_CONST(ni) ((const struct ath_node *)(ni))
#define ATH_RSSI_LPF_LEN 10
#define ATH_RSSI_DUMMY_MARKER 0x127
@@ -140,11 +141,7 @@
int, int, u_int32_t);
int (*sc_newstate)(struct ieee80211com *,
enum ieee80211_state, int);
- void (*sc_node_cleanup)(struct ieee80211com *,
- struct ieee80211_node *);
- void (*sc_node_copy)(struct ieee80211com *,
- struct ieee80211_node *,
- const struct ieee80211_node *);
+ void (*sc_node_free)(struct ieee80211_node *);
device_t sc_dev;
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
==== //depot/projects/wifi/sys/dev/awi/awi.c#3 (text+ko) ====
@@ -663,7 +663,7 @@
ni->ni_intval = ic->ic_lintval;
ni->ni_rssi = 0;
ni->ni_rstamp = 0;
- memset(ni->ni_tstamp, 0, sizeof(ni->ni_tstamp));
+ memset(&ni->ni_tstamp, 0, sizeof(ni->ni_tstamp));
ni->ni_rates =
ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
IEEE80211_ADDR_COPY(ni->ni_macaddr, ic->ic_myaddr);
@@ -802,7 +802,7 @@
ifp->if_oerrors++;
continue;
}
- if (ni != NULL && ni != ic->ic_bss)
+ if (ni != NULL)
ieee80211_free_node(ic, ni);
wh = mtod(m0, struct ieee80211_frame *);
if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
@@ -826,7 +826,7 @@
k = ieee80211_crypto_encap(ic, ni, m0);
if (k == NULL) {
- if (ni && ni != ic->ic_bss)
+ if (ni != NULL)
ieee80211_free_node(ic, ni);
continue;
}
@@ -1175,7 +1175,6 @@
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &sc->sc_if;
- struct ieee80211_frame *wh;
struct ieee80211_node *ni;
u_int8_t state, rate, rssi;
u_int16_t len;
@@ -1220,33 +1219,16 @@
sc->sc_adhoc_ap)
m = awi_ether_modcap(sc, m);
else
- m = m_pullup(m, sizeof(*wh));
+ m = m_pullup(m,
+ sizeof(struct ieee80211_frame_min));
if (m == NULL) {
ifp->if_ierrors++;
goto rx_next;
}
- wh = mtod(m, struct ieee80211_frame *);
-#ifdef __NetBSD__
- ni = ieee80211_find_rxnode(ic, wh);
-#else
- if (ic->ic_opmode != IEEE80211_M_STA) {
- ni = ieee80211_find_node(ic,
- wh->i_addr2);
- if (ni == NULL)
- ni = ic->ic_bss;
- } else
- ni = ic->ic_bss;
-#endif
+ ni = ieee80211_find_rxnode(ic,
+ mtod(m, struct ieee80211_frame_min *));
ieee80211_input(ic, m, ni, rssi, rstamp);
- /*
- * The frame may have caused the
- * node to be marked for reclamation
- * (e.g. in response to a DEAUTH
- * message) so use free_node here
- * instead of unref_node.
- */
- if (ni != ic->ic_bss)
- ieee80211_free_node(ic, ni);
+ ieee80211_free_node(ic, ni);
} else
sc->sc_rxpend = m;
rx_next:
@@ -2048,14 +2030,14 @@
awi_write_2(sc, AWI_CA_SYNC_DWELL, 0);
}
if (ic->ic_flags & IEEE80211_F_SIBSS) {
- memset(ni->ni_tstamp, 0, sizeof(ni->ni_tstamp));
+ memset(&ni->ni_tstamp, 0, sizeof(ni->ni_tstamp));
ni->ni_rstamp = 0;
awi_write_1(sc, AWI_CA_SYNC_STARTBSS, 1);
} else
awi_write_1(sc, AWI_CA_SYNC_STARTBSS, 0);
awi_write_2(sc, AWI_CA_SYNC_MBZ, 0);
awi_write_bytes(sc, AWI_CA_SYNC_TIMESTAMP,
- ni->ni_tstamp, 8);
+ ni->ni_tstamp.data, 8);
awi_write_4(sc, AWI_CA_SYNC_REFTIME, ni->ni_rstamp);
sc->sc_cur_chan = ieee80211_chan2ieee(ic, ni->ni_chan);
if ((error = awi_cmd(sc, AWI_CMD_SYNC, AWI_NOWAIT))
==== //depot/projects/wifi/sys/dev/wi/if_wi.c#4 (text+ko) ====
@@ -941,8 +941,8 @@
k = ieee80211_crypto_encap(ic, ni, m0);
if (k == NULL) {
- if (ni && ni != ic->ic_bss)
- ieee80211_free_node(ic, ni);
+ if (ni != NULL)
+ ieee80211_free_node(ni);
continue;
}
if (k->wk_flags & IEEE80211_KEY_SWCRYPT)
@@ -967,8 +967,8 @@
error = wi_write_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0
|| wi_mwrite_bap(sc, fid, off, m0, m0->m_pkthdr.len) != 0;
m_freem(m0);
- if (ni && ni != ic->ic_bss)
- ieee80211_free_node(ic, ni);
+ if (ni != NULL)
+ ieee80211_free_node(ni);
if (error) {
ifp->if_oerrors++;
continue;
@@ -1513,16 +1513,9 @@
/*
* Locate the node for sender, track state, and
* then pass this node (referenced) up to the 802.11
- * layer for its use. We are required to pass
- * something so we fallback to ic_bss when this frame
- * is from an unknown sender.
+ * layer for its use.
*/
- if (ic->ic_opmode != IEEE80211_M_STA) {
- ni = ieee80211_find_node(ic, wh->i_addr2);
- if (ni == NULL)
- ni = ic->ic_bss;
- } else
- ni = ic->ic_bss;
+ ni = ieee80211_find_rxnode(ic, wh);
/*
* Send frame up for processing.
*/
@@ -1532,8 +1525,7 @@
* reclamation (e.g. in response to a DEAUTH message)
* so use free_node here instead of unref_node.
*/
- if (ni != ic->ic_bss)
- ieee80211_free_node(ic, ni);
+ ieee80211_free_node(ni);
}
static void
==== //depot/projects/wifi/sys/net80211/ieee80211.c#3 (text+ko) ====
@@ -653,15 +653,26 @@
void
ieee80211_watchdog(struct ieee80211com *ic)
{
+ struct ieee80211_node_table *nt;
+ int need_inact_timer = 0;
if (ic->ic_state != IEEE80211_S_INIT) {
if (ic->ic_mgt_timer && --ic->ic_mgt_timer == 0)
ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
- if (ic->ic_inact_timer && --ic->ic_inact_timer == 0)
- ieee80211_timeout_nodes(ic);
+ nt = &ic->ic_scan;
+ if (nt->nt_inact_timer) {
+ if (--nt->nt_inact_timer == 0)
+ nt->nt_timeout(nt);
+ need_inact_timer += nt->nt_inact_timer;
+ }
+ nt = ic->ic_sta;
+ if (nt != NULL && nt->nt_inact_timer) {
+ if (--nt->nt_inact_timer == 0)
+ nt->nt_timeout(nt);
+ need_inact_timer += nt->nt_inact_timer;
+ }
}
-
- if (ic->ic_mgt_timer != 0 || ic->ic_inact_timer != 0)
+ if (ic->ic_mgt_timer != 0 || need_inact_timer)
ic->ic_ifp->if_timer = 1;
}
==== //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#3 (text+ko) ====
@@ -33,13 +33,13 @@
* Node locking definitions.
*/
typedef struct mtx ieee80211_node_lock_t;
-#define IEEE80211_NODE_LOCK_INIT(_ic, _name) \
- mtx_init(&(_ic)->ic_nodelock, _name, "802.11 node table", MTX_DEF)
-#define IEEE80211_NODE_LOCK_DESTROY(_ic) mtx_destroy(&(_ic)->ic_nodelock)
-#define IEEE80211_NODE_LOCK(_ic) mtx_lock(&(_ic)->ic_nodelock)
-#define IEEE80211_NODE_UNLOCK(_ic) mtx_unlock(&(_ic)->ic_nodelock)
-#define IEEE80211_NODE_LOCK_ASSERT(_ic) \
- mtx_assert(&(_ic)->ic_nodelock, MA_OWNED)
+#define IEEE80211_NODE_LOCK_INIT(_nt, _name) \
+ mtx_init(&(_nt)->nt_nodelock, _name, "802.11 node table", MTX_DEF)
+#define IEEE80211_NODE_LOCK_DESTROY(_nt) mtx_destroy(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_LOCK(_nt) mtx_lock(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_UNLOCK(_nt) mtx_unlock(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_LOCK_ASSERT(_nt) \
+ mtx_assert(&(_nt)->nt_nodelock, MA_OWNED)
/*
* 802.1x MAC ACL database locking definitions.
==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#10 (text+ko) ====
@@ -246,7 +246,7 @@
if ((wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) == 0) {
/* turn off power save mode, dequeue stored packets */
ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT;
- (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
+ ic->ic_set_tim(ic, ni->ni_associd, 0);
while (!_IF_QLEN(&ni->ni_savedq) != 0) {
struct mbuf *m0;
_IF_DEQUEUE(&ni->ni_savedq, m0);
@@ -351,12 +351,12 @@
"[%s] discard data from unknown src\n",
ether_sprintf(wh->i_addr2));
/* NB: caller deals with reference */
- ni = ieee80211_dup_bss(ic, 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,
IEEE80211_REASON_NOT_AUTHED);
- ieee80211_free_node(ic, ni);
+ ieee80211_free_node(ni);
}
ic->ic_stats.is_rx_notassoc++;
goto err;
@@ -502,14 +502,16 @@
/* XXX this dups work done in ieee80211_encap */
/* check if destination is associated */
struct ieee80211_node *ni1 =
- ieee80211_find_node(ic, eh->ether_dhost);
+ ieee80211_find_node(ic->ic_sta,
+ eh->ether_dhost);
if (ni1 != NULL) {
+ /* XXX check if authorized */
if (ni1->ni_associd != 0) {
m1 = m;
m = NULL;
}
/* XXX statistic? */
- ieee80211_free_node(ic, ni1);
+ ieee80211_free_node(ni1);
}
}
if (m1 != NULL) {
@@ -648,10 +650,23 @@
/*
* Remove frag to insure it doesn't get reaped by timer.
*/
- IEEE80211_NODE_LOCK(ic);
+ if (ni->ni_table == NULL) {
+ /*
+ * Should never happen. If the node is orphaned (not in
+ * the table) then input packets should not reach here.
+ * Otherwise, a concurrent request that yanks the table
+ * should be blocked by other interlocking and/or by first
+ * shutting the driver down. Regardless, be defensive
+ * here and just bail
+ */
+ /* XXX need msg+stat */
+ m_freem(m);
+ return NULL;
+ }
+ IEEE80211_NODE_LOCK(ni->ni_table);
mfrag = ni->ni_rxfrag[0];
ni->ni_rxfrag[0] = NULL;
- IEEE80211_NODE_UNLOCK(ic);
+ IEEE80211_NODE_UNLOCK(ni->ni_table);
/*
* Validate new fragment is in order and
@@ -860,7 +875,7 @@
}
/* always accept open authentication requests */
if (ni == ic->ic_bss) {
- ni = ieee80211_dup_bss(ic, wh->i_addr2);
+ ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
if (ni == NULL)
return;
allocbs = 1;
@@ -1006,7 +1021,7 @@
switch (seq) {
case IEEE80211_AUTH_SHARED_REQUEST:
if (ni == ic->ic_bss) {
- ni = ieee80211_dup_bss(ic, wh->i_addr2);
+ ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
if (ni == NULL) {
/* NB: no way to return an error */
return;
@@ -1583,7 +1598,7 @@
#define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
struct ieee80211_frame *wh;
u_int8_t *frm, *efrm;
- u_int8_t *ssid, *rates, *xrates, *wpa;
+ u_int8_t *ssid, *rates, *xrates, *wpa, *wme;
int reassoc, resp, allocbs;
wh = mtod(m0, struct ieee80211_frame *);
@@ -1592,7 +1607,7 @@
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
case IEEE80211_FC0_SUBTYPE_BEACON: {
- u_int8_t *tstamp, *country, *wpa, *wme;
+ u_int8_t *tstamp, *country;
u_int8_t chan, bchan, fhindex, erp;
u_int16_t capinfo, bintval, timoff;
u_int16_t fhdwell;
@@ -1779,57 +1794,51 @@
ni->ni_capinfo = capinfo;
/* XXX statistic */
}
+ ni->ni_inact = ic->ic_inact_run;
return;
}
- /*
- * Use mac and channel for lookup so we collect all
- * potential AP's when scanning. Otherwise we may
- * see the same AP on multiple channels and will only
- * record the last one. We could filter APs here based
- * on rssi, etc. but leave that to the end of the scan
- * so we can keep the selection criteria in one spot.
- * This may result in a bloat of the scanned AP list but
- * it shouldn't be too much.
- */
- ni = ieee80211_find_node_with_channel(ic, wh->i_addr2,
- &ic->ic_channels[chan]);
- if (ni == NULL) {
+ if (ni == ic->ic_bss) {
#ifdef IEEE80211_DEBUG
if (ieee80211_msg_scan(ic))
dump_probe_beacon(subtype, 1,
wh->i_addr2, chan, bchan, capinfo,
bintval, erp, ssid, country);
#endif
- ni = ieee80211_dup_bss(ic, wh->i_addr2);
+ ni = ieee80211_dup_bss(&ic->ic_scan, wh->i_addr2);
if (ni == NULL)
return;
ni->ni_esslen = ssid[1];
memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
memcpy(ni->ni_essid, ssid + 2, ssid[1]);
- } else if (ssid[1] != 0 &&
- (ISPROBE(subtype) || ni->ni_esslen == 0)) {
- /*
- * Update ESSID at probe response to adopt hidden AP by
- * Lucent/Cisco, which announces null ESSID in beacon.
- */
- ni->ni_esslen = ssid[1];
- memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
- memcpy(ni->ni_essid, ssid + 2, ssid[1]);
+ } else {
+ ni->ni_inact = ic->ic_inact_run; /* XXX? */
+ if (ssid[1] != 0 &&
+ (ISPROBE(subtype) || ni->ni_esslen == 0)) {
+ /*
+ * Update ESSID at probe response to adopt
+ * hidden AP by Lucent/Cisco, which announces
+ * null ESSID in beacon.
+ */
#ifdef IEEE80211_DEBUG
- if (ieee80211_msg_scan(ic) || ieee80211_msg_debug(ic))
- dump_probe_beacon(subtype, 0,
- wh->i_addr2, chan, bchan, capinfo,
- bintval, erp, ssid, country);
+ if (ieee80211_msg_scan(ic) ||
+ ieee80211_msg_debug(ic))
+ dump_probe_beacon(subtype, 0,
+ wh->i_addr2, chan, bchan, capinfo,
+ bintval, erp, ssid, country);
#endif
+ ni->ni_esslen = ssid[1];
+ memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
+ memcpy(ni->ni_essid, ssid + 2, ssid[1]);
+ }
}
+ ni->ni_scangen = ic->ic_scan.nt_scangen;
IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
ni->ni_rssi = rssi;
ni->ni_rstamp = rstamp;
memcpy(ni->ni_tstamp.data, tstamp, sizeof(ni->ni_tstamp));
ni->ni_intval = bintval;
ni->ni_capinfo = capinfo;
- /* XXX validate channel # */
ni->ni_chan = &ic->ic_channels[chan];
ni->ni_fhdwell = fhdwell;
ni->ni_fhindex = fhindex;
@@ -1851,25 +1860,6 @@
ieee80211_saveie(&ni->ni_wpa_ie, wpa);
/* NB: must be after ni_chan is setup */
ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);
- ieee80211_unref_node(&ni); /* NB: do not free */
-#if 0
- if (ic->ic_state == IEEE80211_S_SCAN)
- ieee80211_unref_node(&ni); /* NB: do not free */
- else if (ic->ic_opmode == IEEE80211_M_IBSS &&
- allocbs && isprobe) {
- /*
- * Fake an association so the driver can setup it's
- * private state. The rate set has been setup above;
- * there is no handshake as in ap/station operation.
- */
- if (ic->ic_newassoc)
- (*ic->ic_newassoc)(ic, ni, 1);
- /* NB: hold reference */
- } else {
- /* XXX optimize to avoid work done above */
- ieee80211_free_node(ic, ni);
- }
-#endif
break;
}
@@ -1908,7 +1898,7 @@
IEEE80211_VERIFY_SSID(ic->ic_bss, ssid, "probe");
if (ni == ic->ic_bss) {
- ni = ieee80211_dup_bss(ic, wh->i_addr2);
+ ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
if (ni == NULL)
return;
IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
@@ -1926,21 +1916,12 @@
IEEE80211_DPRINTF(ic, IEEE80211_MSG_XRATE,
"%s: rate negotiation failed: %s\n",
__func__,ether_sprintf(wh->i_addr2));
+ if (allocbs) /* reclaim immediately */
+ ieee80211_free_node(ni);
} else {
IEEE80211_SEND_MGMT(ic, ni,
IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
}
- if (allocbs) {
- /*
- * When operating in ibss mode we hold the node but
- * with a zero reference count; this is the current
- * convention (XXX). For other cases we do nothing
- * as the node is created with a short inactivity
- * timer (may want to shorten it further here).
- */
- if (ic->ic_opmode == IEEE80211_M_IBSS)
- ieee80211_unref_node(&ni);
- }
break;
}
@@ -2050,7 +2031,7 @@
bintval = le16toh(*(u_int16_t *)frm); frm += 2;
if (reassoc)
frm += 6; /* ignore current AP info */
- ssid = rates = xrates = wpa = NULL;
+ ssid = rates = xrates = wpa = wme = NULL;
while (frm < efrm) {
switch (*frm) {
case IEEE80211_ELEMID_SSID:
@@ -2070,7 +2051,8 @@
if (iswpaoui(frm)) {
if (ic->ic_flags & IEEE80211_F_WPA1)
wpa = frm;
- }
+ } else if (iswmeoui(frm))
+ wme = frm;
/* XXX Atheros OUI support */
break;
}
@@ -2086,12 +2068,12 @@
"%s: deny %sassoc from %s, not authenticated\n",
__func__, reassoc ? "reassoc" : "assoc",
ether_sprintf(wh->i_addr2));
- ni = ieee80211_dup_bss(ic, 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,
IEEE80211_REASON_ASSOC_NOT_AUTHED);
- ieee80211_free_node(ic, ni);
+ ieee80211_free_node(ni);
}
ic->ic_stats.is_rx_assoc_notauth++;
return;
@@ -2180,6 +2162,28 @@
*/
ni->ni_rsn = rsn;
ieee80211_saveie(&ni->ni_wpa_ie, wpa);
+ } else if (ni->ni_wpa_ie != NULL) {
+ /*
+ * Flush any state from a previous association.
+ */
+ FREE(ni->ni_wpa_ie, M_DEVBUF);
+ ni->ni_wpa_ie = NULL;
+ }
+ if (wme != NULL) {
+ /*
+ * Record WME parameters for station, mark node
+ * as capable of QoS and record information
+ * element for applications that require it.
+ */
+ ieee80211_saveie(&ni->ni_wpa_ie, wpa);
+ ni->ni_flags |= IEEE80211_NODE_QOS;
+ } else if (ni->ni_wme_ie != NULL) {
+ /*
+ * Flush any state from a previous association.
+ */
+ FREE(ni->ni_wme_ie, M_DEVBUF);
+ ni->ni_wme_ie = NULL;
+ ni->ni_flags &= ~IEEE80211_NODE_QOS;
}
ieee80211_node_join(ic, ni, resp);
break;
@@ -2187,7 +2191,6 @@
case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: {
- u_int8_t *wme;
u_int16_t capinfo, associd;
u_int16_t status;
@@ -2225,7 +2228,7 @@
associd = le16toh(*(u_int16_t *)frm);
frm += 2;
- rates = xrates = wme = NULL;
+ rates = xrates = wpa = wme = NULL;
while (frm < efrm) {
switch (*frm) {
case IEEE80211_ELEMID_RATES:
@@ -2300,6 +2303,7 @@
ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "",
ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : ""
);
+ ni->ni_inact = ic->ic_inact_run;
ieee80211_new_state(ic, IEEE80211_S_RUN, subtype);
break;
}
@@ -2321,6 +2325,7 @@
IEEE80211_NODE_STAT(ni, rx_deauth);
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
+ ni->ni_inact = ic->ic_inact_run;
ieee80211_new_state(ic, IEEE80211_S_AUTH,
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
break;
@@ -2358,6 +2363,7 @@
IEEE80211_NODE_STAT(ni, rx_disassoc);
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
+ ni->ni_inact = ic->ic_inact_run;
ieee80211_new_state(ic, IEEE80211_S_ASSOC,
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
break;
@@ -2423,6 +2429,7 @@
/* XXX statistic */
return;
}
+ ni->ni_inact = ic->ic_inact_run;
/* Okay, take the first queued packet and put it out... */
_IF_DEQUEUE(&ni->ni_savedq, m);
@@ -2439,7 +2446,7 @@
*/
if (_IF_QLEN(&ni->ni_savedq) == 0) {
if (ic->ic_set_tim)
- (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
+ ic->ic_set_tim(ic, ni->ni_associd, 0);
} else {
wh = mtod(m, struct ieee80211_frame_min *);
wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#10 (text+ko) ====
@@ -87,6 +87,7 @@
struct wi_req wreq;
struct wi_ltv_keys *keys;
struct wi_apinfo *ap;
+ struct ieee80211_node_table *nt;
struct ieee80211_node *ni;
struct ieee80211_rateset *rs;
struct wi_sigcache wsc;
@@ -158,7 +159,7 @@
break;
case WI_RID_COMMS_QUALITY:
wreq.wi_val[0] = 0; /* quality */
- wreq.wi_val[1] = htole16(ic->ic_node_getrssi(ic, ic->ic_bss));
+ wreq.wi_val[1] = htole16(ic->ic_node_getrssi(ic->ic_bss));
wreq.wi_val[2] = 0; /* noise */
wreq.wi_len = 3;
break;
@@ -266,19 +267,18 @@
/* XXX: should be implemented in lower drivers */
break;
case WI_RID_READ_APS:
- if (ic->ic_opmode != IEEE80211_M_HOSTAP) {
- /*
- * Don't return results until active scan completes.
- */
- if (ic->ic_state == IEEE80211_S_SCAN &&
- (ic->ic_flags & IEEE80211_F_ASCAN)) {
- error = EINPROGRESS;
- break;
- }
+ /*
+ * Don't return results until active scan completes.
+ */
+ if (ic->ic_state == IEEE80211_S_SCAN &&
+ (ic->ic_flags & IEEE80211_F_ASCAN)) {
+ error = EINPROGRESS;
+ break;
}
i = 0;
ap = (void *)((char *)wreq.wi_val + sizeof(i));
- TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
+ nt = &ic->ic_scan;
+ TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
if ((caddr_t)(ap + 1) > (caddr_t)(&wreq + 1))
break;
memset(ap, 0, sizeof(*ap));
@@ -296,7 +296,7 @@
ni->ni_esslen);
}
ap->channel = ieee80211_chan2ieee(ic, ni->ni_chan);
- ap->signal = ic->ic_node_getrssi(ic, ni);
+ ap->signal = ic->ic_node_getrssi(ni);
ap->capinfo = ni->ni_capinfo;
ap->interval = ni->ni_intval;
rs = &ni->ni_rates;
@@ -317,8 +317,7 @@
wreq.wi_len = sizeof(u_int16_t) / 2;
break;
case WI_RID_SCAN_RES: /* compatibility interface */
- if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
- ic->ic_state == IEEE80211_S_SCAN &&
+ if (ic->ic_state == IEEE80211_S_SCAN &&
(ic->ic_flags & IEEE80211_F_ASCAN)) {
error = EINPROGRESS;
break;
@@ -327,12 +326,13 @@
p2 = (struct wi_scan_p2_hdr *)wreq.wi_val;
res = (void *)&p2[1];
i = 0;
- TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
+ nt = &ic->ic_scan;
+ TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
if ((caddr_t)(res + 1) > (caddr_t)(&wreq + 1))
break;
res->wi_chan = ieee80211_chan2ieee(ic, ni->ni_chan);
res->wi_noise = 0;
- res->wi_signal = ic->ic_node_getrssi(ic, ni);
+ res->wi_signal = ic->ic_node_getrssi(ni);
IEEE80211_ADDR_COPY(res->wi_bssid, ni->ni_bssid);
res->wi_interval = ni->ni_intval;
res->wi_capinfo = ni->ni_capinfo;
@@ -353,12 +353,13 @@
break;
case WI_RID_READ_CACHE:
i = 0;
- TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
+ nt = &ic->ic_scan;
+ TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
if (i == (WI_MAX_DATALEN/sizeof(struct wi_sigcache))-1)
break;
IEEE80211_ADDR_COPY(wsc.macsrc, ni->ni_macaddr);
memset(&wsc.ipsrc, 0, sizeof(wsc.ipsrc));
- wsc.signal = ic->ic_node_getrssi(ic, ni);
+ wsc.signal = ic->ic_node_getrssi(ni);
wsc.noise = 0;
wsc.quality = 0;
memcpy((caddr_t)wreq.wi_val + sizeof(wsc) * i,
@@ -827,7 +828,9 @@
return error;
kid = ik.ik_keyix;
if (kid == IEEE80211_KEYIX_NONE) {
- ni = ieee80211_find_node(ic, ik.ik_macaddr);
+ if (ic->ic_sta == NULL)
+ return EINVAL;
+ ni = ieee80211_find_node(ic->ic_sta, ik.ik_macaddr);
if (ni == NULL)
return EINVAL; /* XXX */
wk = &ni->ni_ucastkey;
@@ -861,7 +864,7 @@
memset(ik.ik_keydata, 0, sizeof(ik.ik_keydata));
}
if (ni != NULL)
- ieee80211_free_node(ic, ni);
+ ieee80211_free_node(ni);
return copyout(&ik, ireq->i_data, sizeof(ik));
}
@@ -900,7 +903,9 @@
error = copyin(ireq->i_data, wpaie.wpa_macaddr, IEEE80211_ADDR_LEN);
if (error != 0)
return error;
- ni = ieee80211_find_node(ic, wpaie.wpa_macaddr);
+ if (ic->ic_sta == NULL)
+ return EINVAL;
+ 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));
@@ -910,7 +915,7 @@
ielen = sizeof(wpaie.wpa_ie);
memcpy(wpaie.wpa_ie, ni->ni_wpa_ie, ielen);
}
- ieee80211_free_node(ic, ni);
+ ieee80211_free_node(ni);
if (ireq->i_len > sizeof(wpaie))
ireq->i_len = sizeof(wpaie);
return copyout(&wpaie, ireq->i_data, ireq->i_len);
@@ -929,7 +934,9 @@
error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN);
if (error != 0)
return error;
- ni = ieee80211_find_node(ic, macaddr);
+ if (ic->ic_sta == NULL)
+ return EINVAL;
+ ni = ieee80211_find_node(ic->ic_sta, macaddr);
if (ni == NULL)
return EINVAL; /* XXX */
if (ireq->i_len > sizeof(struct ieee80211req_sta_stats))
@@ -937,7 +944,7 @@
/* NB: copy out only the statistics */
error = copyout(&ni->ni_stats, (u_int8_t *) ireq->i_data + off,
ireq->i_len - off);
- ieee80211_free_node(ic, ni);
+ ieee80211_free_node(ni);
return error;
}
@@ -949,18 +956,17 @@
char data[512];
} u;
struct ieee80211req_scan_result *sr = &u.res;
+ struct ieee80211_node_table *nt;
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list