madwifi: switch to latest madwifi-hal-0.9.30.13 snapshot as reference
[openwrt/svn-archive/archive.git] / package / madwifi / patches / 010-refcount_merge.patch
1 diff -ur madwifi.old/ath/if_ath.c madwifi.dev/ath/if_ath.c
2 --- madwifi.old/ath/if_ath.c 2007-05-18 13:19:16.000000000 +0200
3 +++ madwifi.dev/ath/if_ath.c 2007-05-21 08:10:46.864754176 +0200
4 @@ -158,8 +158,7 @@
5 static int ath_desc_alloc(struct ath_softc *);
6 static void ath_desc_free(struct ath_softc *);
7 static void ath_desc_swap(struct ath_desc *);
8 -static struct ieee80211_node *ath_node_alloc(struct ieee80211_node_table *,
9 - struct ieee80211vap *);
10 +static struct ieee80211_node *ath_node_alloc(struct ieee80211vap *);
11 static void ath_node_cleanup(struct ieee80211_node *);
12 static void ath_node_free(struct ieee80211_node *);
13 static u_int8_t ath_node_getrssi(const struct ieee80211_node *);
14 @@ -2385,7 +2384,7 @@
15 if (ath_tx_start(sc->sc_dev, ni, bf_ff, bf_ff->bf_skb, 0) == 0)
16 continue;
17 bad:
18 - ieee80211_free_node(ni);
19 + ieee80211_unref_node(&ni);
20 if (bf_ff->bf_skb != NULL) {
21 dev_kfree_skb(bf_ff->bf_skb);
22 bf_ff->bf_skb = NULL;
23 @@ -2525,8 +2524,10 @@
24 skb = bf->bf_skb;
25 ATH_FF_MAGIC_PUT(skb);
26
27 +#if 0
28 /* decrement extra node reference made when an_tx_ffbuf[] was set */
29 - //ieee80211_free_node(ni); /* XXX where was it set ? */
30 + ieee80211_unref_node(&ni); /* XXX where was it set ? */
31 +#endif
32
33 DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_FF,
34 "%s: aggregating fast-frame\n", __func__);
35 @@ -2585,7 +2586,7 @@
36 ff_flushbad:
37 DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_FF,
38 "%s: ff stageq flush failure\n", __func__);
39 - ieee80211_free_node(ni);
40 + ieee80211_unref_node(&ni);
41 if (bf_ff->bf_skb) {
42 dev_kfree_skb(bf_ff->bf_skb);
43 bf_ff->bf_skb = NULL;
44 @@ -2707,7 +2708,7 @@
45 tbf->bf_node = NULL;
46
47 if (ni != NULL)
48 - ieee80211_free_node(ni);
49 + ieee80211_unref_node(&ni);
50
51 STAILQ_INSERT_TAIL(&sc->sc_txbuf, tbf, bf_list);
52 }
53 @@ -2789,7 +2790,7 @@
54 /* fall thru... */
55 bad:
56 if (ni != NULL)
57 - ieee80211_free_node(ni);
58 + ieee80211_unref_node(&ni);
59 if (bf != NULL) {
60 bf->bf_skb = NULL;
61 bf->bf_node = NULL;
62 @@ -3178,7 +3179,7 @@
63 */
64 ni = sc->sc_keyixmap[keyix];
65 if (ni != NULL) {
66 - ieee80211_free_node(ni);
67 + ieee80211_unref_node(&ni);
68 sc->sc_keyixmap[keyix] = NULL;
69 }
70 /*
71 @@ -3189,7 +3190,7 @@
72 ath_hal_keyreset(ah, keyix + 32); /* RX key */
73 ni = sc->sc_keyixmap[keyix + 32];
74 if (ni != NULL) { /* as above... */
75 - ieee80211_free_node(ni);
76 + ieee80211_unref_node(&ni);
77 sc->sc_keyixmap[keyix + 32] = NULL;
78 }
79 }
80 @@ -3202,7 +3203,7 @@
81 ath_hal_keyreset(ah, keyix + rxkeyoff);
82 ni = sc->sc_keyixmap[keyix + rxkeyoff];
83 if (ni != NULL) { /* as above... */
84 - ieee80211_free_node(ni);
85 + ieee80211_unref_node(&ni);
86 sc->sc_keyixmap[keyix + rxkeyoff] = NULL;
87 }
88 }
89 @@ -3764,10 +3765,8 @@
90 dev_kfree_skb(bf->bf_skb);
91 bf->bf_skb = NULL;
92 }
93 - if (bf->bf_node != NULL) {
94 - ieee80211_free_node(bf->bf_node);
95 - bf->bf_node = NULL;
96 - }
97 + if (bf->bf_node != NULL)
98 + ieee80211_unref_node(&bf->bf_node);
99
100 /*
101 * NB: the beacon data buffer must be 32-bit aligned;
102 @@ -3808,7 +3807,7 @@
103 DPRINTF(sc, ATH_DEBUG_BEACON,
104 "%s: %s beacons, bslot %d intval %u tsfadjust(Kus) %llu\n",
105 __func__, sc->sc_stagbeacons ? "stagger" : "burst",
106 - avp->av_bslot, ni->ni_intval, (unsigned long long) tuadjust);
107 + avp->av_bslot, ni->ni_intval, (long long) tuadjust);
108
109 wh = (struct ieee80211_frame *) skb->data;
110 memcpy(&wh[1], &tsfadjust, sizeof(tsfadjust));
111 @@ -4128,7 +4127,7 @@
112 vap = sc->sc_bslot[(slot + 1) % ATH_BCBUF];
113 DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
114 "%s: slot %d [tsf %llu tsftu %u intval %u] vap %p\n",
115 - __func__, slot, (unsigned long long) tsf, tsftu, ic->ic_lintval, vap);
116 + __func__, slot, (long long) tsf, tsftu, ic->ic_lintval, vap);
117 bfaddr = 0;
118 if (vap != NULL) {
119 bf = ath_beacon_generate(sc, vap, needmark);
120 @@ -4309,10 +4308,8 @@
121 dev_kfree_skb(bf->bf_skb);
122 bf->bf_skb = NULL;
123 }
124 - if (bf->bf_node != NULL) {
125 - ieee80211_free_node(bf->bf_node);
126 - bf->bf_node = NULL;
127 - }
128 + if (bf->bf_node != NULL)
129 + ieee80211_unref_node(&bf->bf_node);
130 STAILQ_INSERT_TAIL(&sc->sc_bbuf, bf, bf_list);
131 }
132
133 @@ -4331,10 +4328,8 @@
134 dev_kfree_skb(bf->bf_skb);
135 bf->bf_skb = NULL;
136 }
137 - if (bf->bf_node != NULL) {
138 - ieee80211_free_node(bf->bf_node);
139 - bf->bf_node = NULL;
140 - }
141 + if (bf->bf_node != NULL)
142 + ieee80211_unref_node(&bf->bf_node);
143 }
144 }
145
146 @@ -4620,7 +4615,7 @@
147 /*
148 * Reclaim node reference.
149 */
150 - ieee80211_free_node(ni);
151 + ieee80211_unref_node(&ni);
152 }
153 }
154
155 @@ -4679,37 +4674,39 @@
156 }
157
158 static struct ieee80211_node *
159 -ath_node_alloc(struct ieee80211_node_table *nt,struct ieee80211vap *vap)
160 +ath_node_alloc(struct ieee80211vap *vap)
161 {
162 - struct ath_softc *sc = nt->nt_ic->ic_dev->priv;
163 + struct ath_softc *sc = vap->iv_ic->ic_dev->priv;
164 const size_t space = sizeof(struct ath_node) + sc->sc_rc->arc_space;
165 struct ath_node *an;
166
167 an = kmalloc(space, GFP_ATOMIC);
168 - if (an == NULL)
169 - return NULL;
170 - memset(an, 0, space);
171 - an->an_decomp_index = INVALID_DECOMP_INDEX;
172 - an->an_avgrssi = ATH_RSSI_DUMMY_MARKER;
173 - an->an_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
174 - an->an_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
175 - an->an_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
176 - /*
177 - * ath_rate_node_init needs a VAP pointer in node
178 - * to decide which mgt rate to use
179 - */
180 - an->an_node.ni_vap = vap;
181 - sc->sc_rc->ops->node_init(sc, an);
182 -
183 - /* U-APSD init */
184 - STAILQ_INIT(&an->an_uapsd_q);
185 - an->an_uapsd_qdepth = 0;
186 - STAILQ_INIT(&an->an_uapsd_overflowq);
187 - an->an_uapsd_overflowqdepth = 0;
188 - ATH_NODE_UAPSD_LOCK_INIT(an);
189 + if (an != NULL) {
190 + memset(an, 0, space);
191 + an->an_decomp_index = INVALID_DECOMP_INDEX;
192 + an->an_avgrssi = ATH_RSSI_DUMMY_MARKER;
193 + an->an_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
194 + an->an_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
195 + an->an_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
196 + /*
197 + * ath_rate_node_init needs a vap pointer in node
198 + * to decide which mgt rate to use
199 + */
200 + an->an_node.ni_vap = vap;
201 + sc->sc_rc->ops->node_init(sc, an);
202
203 - DPRINTF(sc, ATH_DEBUG_NODE, "%s: an %p\n", __func__, an);
204 - return &an->an_node;
205 + /* U-APSD init */
206 + STAILQ_INIT(&an->an_uapsd_q);
207 + an->an_uapsd_qdepth = 0;
208 + STAILQ_INIT(&an->an_uapsd_overflowq);
209 + an->an_uapsd_overflowqdepth = 0;
210 + ATH_NODE_UAPSD_LOCK_INIT(an);
211 +
212 + DPRINTF(sc, ATH_DEBUG_NODE, "%s: an %p\n", __func__, an);
213 + return &an->an_node;
214 + } else {
215 + return NULL;
216 + }
217 }
218
219 static void
220 @@ -4719,6 +4716,7 @@
221 struct ath_softc *sc = ni->ni_ic->ic_dev->priv;
222 struct ath_node *an = ATH_NODE(ni);
223 struct ath_buf *bf;
224 + struct ieee80211_cb *cb = NULL;
225
226 /*
227 * U-APSD cleanup
228 @@ -4733,15 +4731,18 @@
229 while (an->an_uapsd_qdepth) {
230 bf = STAILQ_FIRST(&an->an_uapsd_q);
231 STAILQ_REMOVE_HEAD(&an->an_uapsd_q, bf_list);
232 - bf->bf_desc->ds_link = 0;
233
234 + cb = (struct ieee80211_cb *) bf->bf_skb->cb;
235 + ieee80211_unref_node(&cb->ni);
236 dev_kfree_skb_any(bf->bf_skb);
237 +
238 + bf->bf_desc->ds_link = 0;
239 bf->bf_skb = NULL;
240 bf->bf_node = NULL;
241 +
242 ATH_TXBUF_LOCK_IRQ(sc);
243 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
244 ATH_TXBUF_UNLOCK_IRQ(sc);
245 - ieee80211_free_node(ni);
246
247 an->an_uapsd_qdepth--;
248 }
249 @@ -4749,19 +4750,25 @@
250 while (an->an_uapsd_overflowqdepth) {
251 bf = STAILQ_FIRST(&an->an_uapsd_overflowq);
252 STAILQ_REMOVE_HEAD(&an->an_uapsd_overflowq, bf_list);
253 - bf->bf_desc->ds_link = 0;
254
255 + cb = (struct ieee80211_cb *) bf->bf_skb->cb;
256 + ieee80211_unref_node(&cb->ni);
257 dev_kfree_skb_any(bf->bf_skb);
258 +
259 bf->bf_skb = NULL;
260 bf->bf_node = NULL;
261 + bf->bf_desc->ds_link = 0;
262 +
263 ATH_TXBUF_LOCK_IRQ(sc);
264 STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
265 ATH_TXBUF_UNLOCK_IRQ(sc);
266 - ieee80211_free_node(ni);
267
268 an->an_uapsd_overflowqdepth--;
269 }
270
271 + /* Clean up node-specific rate things - this currently appears to always be a no-op */
272 + sc->sc_rc->ops->node_cleanup(sc, ATH_NODE(ni));
273 +
274 ATH_NODE_UAPSD_LOCK_IRQ(an);
275 sc->sc_node_cleanup(ni);
276 ATH_NODE_UAPSD_UNLOCK_IRQ(an);
277 @@ -4772,7 +4779,6 @@
278 {
279 struct ath_softc *sc = ni->ni_ic->ic_dev->priv;
280
281 - sc->sc_rc->ops->node_cleanup(sc, ATH_NODE(ni));
282 sc->sc_node_free(ni);
283 #ifdef ATH_SUPERG_XR
284 ath_grppoll_period_update(sc);
285 @@ -5660,7 +5666,7 @@
286 an = ATH_NODE(ieee80211_ref_node(ni));
287 ATH_RSSI_LPF(an->an_avgrssi, rs->rs_rssi);
288 type = ieee80211_input(ni, skb, rs->rs_rssi, rs->rs_tstamp);
289 - ieee80211_free_node(ni);
290 + ieee80211_unref_node(&ni);
291 } else {
292 /*
293 * No key index or no entry, do a lookup and
294 @@ -5682,7 +5688,7 @@
295 if (keyix != IEEE80211_KEYIX_NONE &&
296 sc->sc_keyixmap[keyix] == NULL)
297 sc->sc_keyixmap[keyix] = ieee80211_ref_node(ni);
298 - ieee80211_free_node(ni);
299 + ieee80211_unref_node(&ni);
300 } else
301 type = ieee80211_input_all(ic, skb,
302 rs->rs_rssi, rs->rs_tstamp);
303 @@ -6478,8 +6484,7 @@
304 STAILQ_REMOVE_HEAD(&an->an_uapsd_q, bf_list);
305 dev_kfree_skb(lastbuf->bf_skb);
306 lastbuf->bf_skb = NULL;
307 - ieee80211_free_node(lastbuf->bf_node);
308 - lastbuf->bf_node = NULL;
309 + ieee80211_unref_node(&lastbuf->bf_node);
310 ATH_TXBUF_LOCK_IRQ(sc);
311 STAILQ_INSERT_TAIL(&sc->sc_txbuf, lastbuf, bf_list);
312 ATH_TXBUF_UNLOCK_IRQ(sc);
313 @@ -7229,7 +7234,7 @@
314 * this is a DEAUTH message that was sent and the
315 * node was timed out due to inactivity.
316 */
317 - ieee80211_free_node(ni);
318 + ieee80211_unref_node(&ni);
319 }
320
321 bus_unmap_single(sc->sc_bdev, bf->bf_skbaddr,
322 @@ -7474,7 +7479,7 @@
323 }
324 #endif /* ATH_SUPERG_FF */
325 if (bf->bf_node)
326 - ieee80211_free_node(bf->bf_node);
327 + ieee80211_unref_node(&bf->bf_node);
328
329 bf->bf_skb = NULL;
330 bf->bf_node = NULL;
331 diff -ur madwifi.old/net80211/ieee80211_input.c madwifi.dev/net80211/ieee80211_input.c
332 --- madwifi.old/net80211/ieee80211_input.c 2007-05-18 13:19:16.000000000 +0200
333 +++ madwifi.dev/net80211/ieee80211_input.c 2007-05-21 08:10:46.865754024 +0200
334 @@ -489,7 +489,7 @@
335 nt = &ic->ic_sta;
336 ni_wds = ieee80211_find_wds_node(nt, wh->i_addr3);
337 if (ni_wds) {
338 - ieee80211_free_node(ni_wds); /* Decr ref count */
339 + ieee80211_unref_node(&ni_wds); /* Decr ref count */
340 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
341 wh, NULL, "%s",
342 "multicast echo originated from node behind me");
343 @@ -543,10 +543,12 @@
344 * the node table for the packet source address (addr4).
345 * If not, add one.
346 */
347 + /* XXX: Useless node mgmt API; make better */
348 if (dir == IEEE80211_FC1_DIR_DSTODS) {
349 struct ieee80211_node_table *nt;
350 struct ieee80211_frame_addr4 *wh4;
351 struct ieee80211_node *ni_wds;
352 +
353 if (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS)) {
354 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
355 wh, "data", "%s", "4 addr not allowed");
356 @@ -569,7 +571,7 @@
357 if (ni_wds == NULL)
358 ieee80211_add_wds_addr(nt, ni, wh4->i_addr4, 0);
359 else
360 - ieee80211_free_node(ni_wds); /* Decr ref count */
361 + ieee80211_unref_node(&ni_wds); /* Decr. ref count */
362 }
363
364 /*
365 @@ -936,7 +938,7 @@
366 }
367 ni = ieee80211_ref_node(vap->iv_bss);
368 type = ieee80211_input(ni, skb1, rssi, rstamp);
369 - ieee80211_free_node(ni);
370 + ieee80211_unref_node(&ni);
371 }
372 if (skb != NULL) /* no vaps, reclaim skb */
373 dev_kfree_skb(skb);
374 @@ -986,22 +988,14 @@
375 }
376
377 /*
378 - * Use this lock to make sure ni->ni_rxfrag is
379 - * not freed by the timer process while we use it.
380 - * XXX bogus
381 - */
382 - IEEE80211_NODE_LOCK_IRQ(ni->ni_table);
383 -
384 - /*
385 * Update the time stamp. As a side effect, it
386 * also makes sure that the timer will not change
387 * ni->ni_rxfrag for at least 1 second, or in
388 * other words, for the remaining of this function.
389 + * XXX HUGE HORRIFIC HACK
390 */
391 ni->ni_rxfragstamp = jiffies;
392
393 - IEEE80211_NODE_UNLOCK_IRQ(ni->ni_table);
394 -
395 /*
396 * Validate that fragment is in order and
397 * related to the previous ones.
398 @@ -1130,7 +1124,7 @@
399 skb = NULL;
400 }
401 /* XXX statistic? */
402 - ieee80211_free_node(ni1);
403 + ieee80211_unref_node(&ni1);
404 }
405 }
406 if (skb1 != NULL) {
407 @@ -1265,6 +1259,7 @@
408 int rssi, u_int32_t rstamp, u_int16_t seq, u_int16_t status)
409 {
410 struct ieee80211vap *vap = ni->ni_vap;
411 + unsigned int tmpnode = 0;
412
413 if (ni->ni_authmode == IEEE80211_AUTH_SHARED) {
414 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH,
415 @@ -1272,22 +1267,21 @@
416 "bad sta auth mode %u", ni->ni_authmode);
417 vap->iv_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */
418 if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
419 - /* XXX hack to workaround calling convention */
420 -
421 - /* XXX To send the frame to the requesting STA, we have to
422 - * create a node for the station that we're going to reject.
423 - * The node will be freed automatically */
424 if (ni == vap->iv_bss) {
425 - ni = ieee80211_dup_bss(vap, wh->i_addr2);
426 + ni = ieee80211_dup_bss(vap, wh->i_addr2, 0);
427 if (ni == NULL)
428 return;
429
430 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
431 "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(ni->ni_macaddr),
432 ieee80211_node_refcnt(ni));
433 + tmpnode = 1;
434 }
435 IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_AUTH,
436 (seq + 1) | (IEEE80211_STATUS_ALG << 16));
437 +
438 + if (tmpnode)
439 + ieee80211_unref_node(&ni);
440 return;
441 }
442 }
443 @@ -1315,23 +1309,16 @@
444 }
445 /* always accept open authentication requests */
446 if (ni == vap->iv_bss) {
447 - ni = ieee80211_dup_bss(vap, wh->i_addr2);
448 + ni = ieee80211_dup_bss(vap, wh->i_addr2, 0);
449 if (ni == NULL)
450 return;
451
452 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
453 "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(ni->ni_macaddr),
454 ieee80211_node_refcnt(ni));
455 -
456 - } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0)
457 - (void) ieee80211_ref_node(ni);
458 - /*
459 - * Mark the node as referenced to reflect that it's
460 - * reference count has been bumped to ensure it remains
461 - * after the transaction completes.
462 - */
463 - ni->ni_flags |= IEEE80211_NODE_AREF;
464 -
465 + tmpnode = 1;
466 + }
467 +
468 IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
469 IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
470 ni, "station authenticated (%s)", "open");
471 @@ -1341,6 +1328,8 @@
472 */
473 if (ni->ni_authmode != IEEE80211_AUTH_8021X)
474 ieee80211_node_authorize(ni);
475 + if (tmpnode)
476 + ieee80211_unref_node(&ni);
477 break;
478
479 case IEEE80211_M_STA:
480 @@ -1379,7 +1368,7 @@
481 int istmp;
482
483 if (ni == vap->iv_bss) {
484 - ni = ieee80211_tmp_node(vap, mac);
485 + ni = ieee80211_dup_bss(vap, mac, 1);
486 if (ni == NULL) {
487 /* XXX msg */
488 return;
489 @@ -1389,7 +1378,7 @@
490 istmp = 0;
491 IEEE80211_SEND_MGMT(ni, subtype, arg);
492 if (istmp)
493 - ieee80211_free_node(ni);
494 + ieee80211_unref_node(&ni);
495 }
496
497 static int
498 @@ -1505,7 +1494,7 @@
499 switch (seq) {
500 case IEEE80211_AUTH_SHARED_REQUEST:
501 if (ni == vap->iv_bss) {
502 - ni = ieee80211_dup_bss(vap, wh->i_addr2);
503 + ni = ieee80211_dup_bss(vap, wh->i_addr2, 0);
504 if (ni == NULL) {
505 /* NB: no way to return an error */
506 return;
507 @@ -1516,17 +1505,8 @@
508 ieee80211_node_refcnt(ni));
509
510 allocbs = 1;
511 - } else {
512 - if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0)
513 - (void) ieee80211_ref_node(ni);
514 - allocbs = 0;
515 }
516 - /*
517 - * Mark the node as referenced to reflect that it's
518 - * reference count has been bumped to ensure it remains
519 - * after the transaction completes.
520 - */
521 - ni->ni_flags |= IEEE80211_NODE_AREF;
522 +
523 ni->ni_rssi = rssi;
524 ni->ni_rstamp = rstamp;
525 ni->ni_last_rx = jiffies;
526 @@ -1620,14 +1600,13 @@
527 }
528 return;
529 bad:
530 - /*
531 - * Send an error response; but only when operating as an AP.
532 - */
533 + /* Send an error response; but only when operating as an AP. */
534 if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
535 /* XXX hack to workaround calling convention */
536 ieee80211_send_error(ni, wh->i_addr2,
537 IEEE80211_FC0_SUBTYPE_AUTH,
538 (seq + 1) | (estatus<<16));
539 + ieee80211_node_leave(ni);
540 } else if (vap->iv_opmode == IEEE80211_M_STA) {
541 /*
542 * Kick the state machine. This short-circuits
543 @@ -2600,7 +2579,7 @@
544 u_int8_t *frm, *efrm;
545 u_int8_t *ssid, *rates, *xrates, *wpa, *rsn, *wme, *ath;
546 u_int8_t rate;
547 - int reassoc, resp, allocbs;
548 + int reassoc, resp, allocbs = 0;
549 u_int8_t qosinfo;
550
551 wh = (struct ieee80211_frame *) skb->data;
552 @@ -3008,13 +2987,13 @@
553 ni = ieee80211_fakeup_adhoc_node(vap,
554 wh->i_addr2);
555 } else {
556 - ni = ieee80211_tmp_node(vap, wh->i_addr2);
557 + ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);
558 }
559 if (ni == NULL)
560 return;
561 allocbs = 1;
562 - } else
563 - allocbs = 0;
564 + }
565 +
566 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2,
567 "%s", "recv probe req");
568 ni->ni_rssi = rssi;
569 @@ -3037,7 +3016,7 @@
570 * Temporary node created just to send a
571 * response, reclaim immediately
572 */
573 - ieee80211_free_node(ni);
574 + ieee80211_unref_node(&ni);
575 } else if (ath != NULL)
576 ieee80211_saveath(ni, ath);
577 break;
578 @@ -3067,6 +3046,9 @@
579 ni = vap->iv_xrvap->iv_bss;
580 else {
581 ieee80211_node_leave(ni);
582 + /* This would be a stupid place to add a node to the table
583 + * XR stuff needs work anyway
584 + */
585 ieee80211_node_reset(ni, vap->iv_xrvap);
586 }
587 vap = vap->iv_xrvap;
588 diff -ur madwifi.old/net80211/ieee80211_linux.c madwifi.dev/net80211/ieee80211_linux.c
589 --- madwifi.old/net80211/ieee80211_linux.c 2007-05-18 13:19:16.000000000 +0200
590 +++ madwifi.dev/net80211/ieee80211_linux.c 2007-05-21 08:10:46.866753872 +0200
591 @@ -358,7 +358,7 @@
592 struct ieee80211_node *ni;
593 struct ieee80211_node_table *nt = (struct ieee80211_node_table *) &vap->iv_ic->ic_sta;
594
595 - //IEEE80211_NODE_LOCK(nt);
596 + /* IEEE80211_NODE_LOCK(nt); */
597 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
598 /* Assume each node needs 500 bytes */
599 if (buf + space < p + 500)
600 @@ -376,7 +376,7 @@
601
602 }
603 }
604 - //IEEE80211_NODE_UNLOCK(nt);
605 + /* IEEE80211_NODE_UNLOCK(nt); */
606 return (p - buf);
607 }
608
609 diff -ur madwifi.old/net80211/ieee80211_linux.h madwifi.dev/net80211/ieee80211_linux.h
610 --- madwifi.old/net80211/ieee80211_linux.h 2007-05-04 15:45:58.000000000 +0200
611 +++ madwifi.dev/net80211/ieee80211_linux.h 2007-05-21 08:10:46.867753720 +0200
612 @@ -63,6 +63,12 @@
613
614 #define IEEE80211_RESCHEDULE schedule
615
616 +/* Locking */
617 +/* NB: beware, spin_is_locked() is not usefully defined for !(DEBUG || SMP)
618 + * because spinlocks do not exist in this configuration. Instead IRQs
619 + * or pre-emption are simply disabled, as this is all that is needed.
620 + */
621 +
622 /*
623 * Beacon handler locking definitions.
624 * Beacon locking
625 @@ -85,14 +91,14 @@
626 #define IEEE80211_LOCK(_ic) spin_lock(&(_ic)->ic_comlock)
627 #define IEEE80211_UNLOCK(_ic) spin_unlock(&(_ic)->ic_comlock)
628
629 -/* NB: beware, spin_is_locked() is unusable for !SMP */
630 -#if defined(CONFIG_SMP)
631 +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked)
632 #define IEEE80211_LOCK_ASSERT(_ic) \
633 KASSERT(spin_is_locked(&(_ic)->ic_comlock),("ieee80211com not locked!"))
634 #else
635 #define IEEE80211_LOCK_ASSERT(_ic)
636 #endif
637
638 +
639 #define IEEE80211_VAPS_LOCK_INIT(_ic, _name) \
640 spin_lock_init(&(_ic)->ic_vapslock)
641 #define IEEE80211_VAPS_LOCK_DESTROY(_ic)
642 @@ -108,11 +114,10 @@
643 } while (0)
644 #define IEEE80211_VAPS_UNLOCK_IRQ_EARLY(_ic) spin_unlock_irqrestore(&(_ic)->ic_vapslock, _vaps_lockflags)
645
646 -
647 -/* NB: beware, spin_is_locked() is unusable for !SMP */
648 -#if defined(CONFIG_SMP)
649 +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked)
650 #define IEEE80211_VAPS_LOCK_ASSERT(_ic) \
651 - KASSERT(spin_is_locked(&(_ic)->ic_vapslock),("ieee80211com_vaps not locked!"))
652 + KASSERT(spin_is_locked(&(_ic)->ic_vapslock), \
653 + ("ieee80211com_vaps not locked!"))
654 #else
655 #define IEEE80211_VAPS_LOCK_ASSERT(_ic)
656 #endif
657 @@ -121,29 +126,63 @@
658 /*
659 * Node locking definitions.
660 */
661 +#if 0
662 +
663 typedef spinlock_t ieee80211_node_lock_t;
664 -#define IEEE80211_NODE_LOCK_INIT(_nt, _name) spin_lock_init(&(_nt)->nt_nodelock)
665 -#define IEEE80211_NODE_LOCK_DESTROY(_nt)
666 -#define IEEE80211_NODE_LOCK(_nt) spin_lock(&(_nt)->nt_nodelock)
667 -#define IEEE80211_NODE_UNLOCK(_nt) spin_unlock(&(_nt)->nt_nodelock)
668 -#define IEEE80211_NODE_LOCK_BH(_nt) spin_lock_bh(&(_nt)->nt_nodelock)
669 -#define IEEE80211_NODE_UNLOCK_BH(_nt) spin_unlock_bh(&(_nt)->nt_nodelock)
670 -#define IEEE80211_NODE_LOCK_IRQ(_nt) do { \
671 +#define IEEE80211_NODE_LOCK_INIT(_ni, _name) spin_lock_init(&(_ni)->ni_nodelock)
672 +#define IEEE80211_NODE_LOCK_DESTROY(_ni)
673 +#if 0 /* We should always be contesting in the same contexts */
674 +#define IEEE80211_NODE_LOCK(_ni) spin_lock(&(_ni)->ni_nodelock)
675 +#define IEEE80211_NODE_UNLOCK(_ni) spin_unlock(&(_ni)->ni_nodelock)
676 +#define IEEE80211_NODE_LOCK_BH(_ni) spin_lock_bh(&(_ni)->ni_nodelock)
677 +#define IEEE80211_NODE_UNLOCK_BH(_ni) spin_unlock_bh(&(_ni)->ni_nodelock)
678 +#endif
679 +#define IEEE80211_NODE_LOCK_IRQ(_ni) do { \
680 + unsigned long __node_lockflags; \
681 + spin_lock_irqsave(&(_ni)->ni_nodelock, __node_lockflags);
682 +#define IEEE80211_NODE_UNLOCK_IRQ(_ni) \
683 + spin_unlock_irqrestore(&(_ni)->ni_nodelock, __node_lockflags); \
684 +} while(0)
685 +#define IEEE80211_NODE_UNLOCK_IRQ_EARLY(_ni) \
686 + spin_unlock_irqrestore(&(_ni)->ni_nodelock, __node_lockflags);
687 +
688 +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked)
689 +#define IEEE80211_NODE_LOCK_ASSERT(_nt) \
690 + KASSERT(spin_is_locked(&(_ni)->ni_nodelock), \
691 + ("802.11 node not locked!"))
692 +#else
693 +#define IEEE80211_NODE_LOCK_ASSERT(_ni)
694 +#endif
695 +
696 +#endif /* node lock */
697 +
698 +/*
699 + * Node table locking definitions.
700 + */
701 +typedef spinlock_t ieee80211_node_table_lock_t;
702 +#define IEEE80211_NODE_TABLE_LOCK_INIT(_nt, _name) spin_lock_init(&(_nt)->nt_nodelock)
703 +#define IEEE80211_NODE_TABLE_LOCK_DESTROY(_nt)
704 +#if 0 /* We should always be contesting in the same contexts */
705 +#define IEEE80211_NODE_TABLE_LOCK(_nt) spin_lock(&(_nt)->nt_nodelock)
706 +#define IEEE80211_NODE_TABLE_UNLOCK(_nt) spin_unlock(&(_nt)->nt_nodelock)
707 +#define IEEE80211_NODE_TABLE_LOCK_BH(_nt) spin_lock_bh(&(_nt)->nt_nodelock)
708 +#define IEEE80211_NODE_TABLE_UNLOCK_BH(_nt) spin_unlock_bh(&(_nt)->nt_nodelock)
709 +#endif
710 +#define IEEE80211_NODE_TABLE_LOCK_IRQ(_nt) do { \
711 unsigned long __node_lockflags; \
712 spin_lock_irqsave(&(_nt)->nt_nodelock, __node_lockflags);
713 -#define IEEE80211_NODE_UNLOCK_IRQ(_nt) \
714 +#define IEEE80211_NODE_TABLE_UNLOCK_IRQ(_nt) \
715 spin_unlock_irqrestore(&(_nt)->nt_nodelock, __node_lockflags); \
716 } while(0)
717 -#define IEEE80211_NODE_UNLOCK_IRQ_EARLY(_nt) \
718 +#define IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(_nt) \
719 spin_unlock_irqrestore(&(_nt)->nt_nodelock, __node_lockflags);
720
721 -/* NB: beware, *_is_locked() are bogusly defined for UP+!PREEMPT */
722 -#if (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)) && defined(spinlock_is_locked)
723 -#define IEEE80211_NODE_LOCK_ASSERT(_nt) \
724 - KASSERT(spinlock_is_locked(&(_nt)->nt_nodelock), \
725 +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked)
726 +#define IEEE80211_NODE_TABLE_LOCK_ASSERT(_nt) \
727 + KASSERT(spin_is_locked(&(_nt)->nt_nodelock), \
728 ("802.11 node table not locked!"))
729 #else
730 -#define IEEE80211_NODE_LOCK_ASSERT(_nt)
731 +#define IEEE80211_NODE_TABLE_LOCK_ASSERT(_nt)
732 #endif
733
734 /*
735 @@ -163,8 +202,7 @@
736 #define IEEE80211_SCAN_UNLOCK_IRQ_EARLY(_nt) \
737 spin_unlock_irqrestore(&(_nt)->nt_scanlock, __scan_lockflags);
738
739 -/* NB: beware, spin_is_locked() is unusable for !SMP */
740 -#if defined(CONFIG_SMP)
741 +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked)
742 #define IEEE80211_SCAN_LOCK_ASSERT(_nt) \
743 KASSERT(spin_is_locked(&(_nt)->nt_scanlock), ("scangen not locked!"))
744 #else
745 @@ -182,8 +220,7 @@
746 #define ACL_LOCK_BH(_as) spin_lock_bh(&(_as)->as_lock)
747 #define ACL_UNLOCK_BH(_as) spin_unlock_bh(&(_as)->as_lock)
748
749 -/* NB: beware, spin_is_locked() is unusable for !SMP */
750 -#if defined(CONFIG_SMP)
751 +#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked)
752 #define ACL_LOCK_ASSERT(_as) \
753 KASSERT(spin_is_locked(&(_as)->as_lock), ("ACL not locked!"))
754 #else
755 @@ -299,6 +336,7 @@
756 * is the last reference, otherwise 0
757 * ieee80211_node_refcnt reference count for printing (only)
758 */
759 +typedef atomic_t ieee80211_node_ref_count_t;
760 #define ieee80211_node_initref(_ni) atomic_set(&(_ni)->ni_refcnt, 1)
761 #define ieee80211_node_incref(_ni) atomic_inc(&(_ni)->ni_refcnt)
762 #define ieee80211_node_decref(_ni) atomic_dec(&(_ni)->ni_refcnt)
763 @@ -379,8 +417,8 @@
764 /* msecs_to_jiffies appeared in 2.6.7 and 2.4.29 */
765 #include <linux/delay.h>
766 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \
767 - LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) || \
768 - LINUX_VERSION_CODE < KERNEL_VERSION(2,4,29)
769 + LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) || \
770 + LINUX_VERSION_CODE < KERNEL_VERSION(2,4,29)
771
772 /* The following definitions and inline functions are
773 * copied from the kernel src, include/linux/jiffies.h */
774 diff -ur madwifi.old/net80211/ieee80211_node.c madwifi.dev/net80211/ieee80211_node.c
775 --- madwifi.old/net80211/ieee80211_node.c 2007-05-18 13:19:16.000000000 +0200
776 +++ madwifi.dev/net80211/ieee80211_node.c 2007-05-21 08:10:46.868753568 +0200
777 @@ -65,16 +65,17 @@
778 #define IEEE80211_AID_ISSET(_vap, _b) \
779 ((_vap)->iv_aid_bitmap[IEEE80211_AID(_b) / 32] & (1 << (IEEE80211_AID(_b) % 32)))
780
781 +static struct ieee80211_node *ieee80211_alloc_node(struct ieee80211vap *, const u_int8_t *);
782 +
783 static int ieee80211_sta_join1(struct ieee80211_node *);
784
785 -static struct ieee80211_node *node_alloc(struct ieee80211_node_table *,
786 - struct ieee80211vap *);
787 +static struct ieee80211_node *node_alloc(struct ieee80211vap *);
788 static void node_cleanup(struct ieee80211_node *);
789 static void node_free(struct ieee80211_node *);
790 static u_int8_t node_getrssi(const struct ieee80211_node *);
791
792 -static void _ieee80211_free_node(struct ieee80211_node *);
793 -static void node_reclaim(struct ieee80211_node_table *, struct ieee80211_node*);
794 +static void _node_table_leave(struct ieee80211_node_table *, struct ieee80211_node *);
795 +static void _node_table_join(struct ieee80211_node_table *, struct ieee80211_node *);
796
797 static void ieee80211_node_timeout(unsigned long);
798
799 @@ -194,8 +195,7 @@
800
801 ieee80211_node_table_reset(&ic->ic_sta, vap);
802 if (vap->iv_bss != NULL) {
803 - ieee80211_free_node(vap->iv_bss);
804 - vap->iv_bss = NULL;
805 + ieee80211_unref_node(&vap->iv_bss);
806 }
807 if (vap->iv_aid_bitmap != NULL) {
808 FREE(vap->iv_aid_bitmap, M_DEVBUF);
809 @@ -250,6 +250,7 @@
810 nbss->ni_txpower = obss->ni_txpower;
811 nbss->ni_vlan = obss->ni_vlan;
812 nbss->ni_rsn = obss->ni_rsn;
813 + nbss->ni_rates = obss->ni_rates;
814 /* XXX statistics? */
815 }
816
817 @@ -263,17 +264,17 @@
818 "%s: creating ibss on channel %u\n", __func__,
819 ieee80211_chan2ieee(ic, chan));
820
821 - /* Check to see if we already have a node for this mac */
822 + /* Check to see if we already have a node for this mac
823 + * NB: we gain a node reference here
824 + */
825 ni = ieee80211_find_node(&ic->ic_sta, vap->iv_myaddr);
826 if (ni == NULL) {
827 - ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr);
828 + ni = ieee80211_alloc_node_table(vap, vap->iv_myaddr);
829 if (ni == NULL) {
830 /* XXX recovery? */
831 return;
832 }
833 }
834 - else
835 - ieee80211_free_node(ni);
836
837 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "%s: %p<%s> refcnt %d\n",
838 __func__, vap->iv_bss, ether_sprintf(vap->iv_bss->ni_macaddr),
839 @@ -339,7 +340,7 @@
840 else if (IEEE80211_IS_CHAN_QUARTER(chan))
841 ni->ni_rates = ic->ic_sup_quarter_rates;
842
843 - (void) ieee80211_sta_join1(ieee80211_ref_node(ni));
844 + (void) ieee80211_sta_join1(PASS_NODE(ni));
845 }
846 EXPORT_SYMBOL(ieee80211_create_ibss);
847
848 @@ -363,9 +364,10 @@
849 /* XXX multi-bss wrong */
850 ieee80211_reset_erp(ic, ic->ic_curmode);
851
852 - ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr);
853 + ni = ieee80211_alloc_node_table(vap, vap->iv_myaddr);
854 KASSERT(ni != NULL, ("unable to setup inital BSS node"));
855 obss = vap->iv_bss;
856 + /* New reference for caller */
857 vap->iv_bss = ieee80211_ref_node(ni);
858
859 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "%s: new bss %p<%s> refcnt %d\n",
860 @@ -375,7 +377,8 @@
861 if (obss != NULL) {
862 copy_bss(ni, obss);
863 ni->ni_intval = ic->ic_lintval;
864 - ieee80211_free_node(obss);
865 + /* Caller's reference */
866 + ieee80211_unref_node(&obss);
867 }
868 }
869
870 @@ -581,7 +584,7 @@
871 vap->iv_state == IEEE80211_S_RUN && ssid_equal(obss, selbs));
872 vap->iv_bss = selbs;
873 if (obss != NULL)
874 - ieee80211_free_node(obss);
875 + ieee80211_unref_node(&obss);
876 ic->ic_bsschan = selbs->ni_chan;
877 ic->ic_curchan = ic->ic_bsschan;
878 ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan);
879 @@ -638,21 +641,20 @@
880
881 ni = ieee80211_find_node(&ic->ic_sta, se->se_macaddr);
882 if (ni == NULL) {
883 - ni = ieee80211_alloc_node(&ic->ic_sta, vap, se->se_macaddr);
884 + ni = ieee80211_alloc_node_table(vap, se->se_macaddr);
885 if (ni == NULL) {
886 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
887 "%s: Unable to allocate node for BSS: %s\n", __func__,
888 ether_sprintf(ni->ni_macaddr));
889 return 0;
890 }
891 - } else
892 - ieee80211_free_node(ni);
893 + }
894
895 /*
896 * Expand scan state into node's format.
897 * XXX may not need all this stuff
898 */
899 - ni->ni_authmode = vap->iv_bss->ni_authmode; /* inherit authmode from iv_bss */
900 + ni->ni_authmode = vap->iv_bss->ni_authmode; /* inherit authmode from iv_bss */
901 /* inherit the WPA setup as well (structure copy!) */
902 ni->ni_rsn = vap->iv_bss->ni_rsn;
903 IEEE80211_ADDR_COPY(ni->ni_bssid, se->se_bssid);
904 @@ -686,9 +688,9 @@
905
906 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
907 "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(ni->ni_macaddr),
908 - ieee80211_node_refcnt(ni)+1);
909 + ieee80211_node_refcnt(ni));
910
911 - return ieee80211_sta_join1(ieee80211_ref_node(ni));
912 + return ieee80211_sta_join1(PASS_NODE(ni));
913 }
914 EXPORT_SYMBOL(ieee80211_sta_join);
915
916 @@ -700,15 +702,13 @@
917 ieee80211_sta_leave(struct ieee80211_node *ni)
918 {
919 struct ieee80211vap *vap = ni->ni_vap;
920 - struct ieee80211com *ic = vap->iv_ic;
921
922 /* WDS/Repeater: Stop software beacon timer for STA */
923 if (vap->iv_opmode == IEEE80211_M_STA &&
924 vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) {
925 del_timer(&vap->iv_swbmiss);
926 }
927 -
928 - ic->ic_node_cleanup(ni);
929 +
930 ieee80211_notify_node_leave(ni);
931 }
932
933 @@ -717,11 +717,11 @@
934 */
935
936 static void
937 -ieee80211_node_table_init(struct ieee80211com *ic,
938 - struct ieee80211_node_table *nt, const char *name, int inact)
939 +ieee80211_node_table_init(struct ieee80211com *ic, struct ieee80211_node_table *nt,
940 + const char *name, int inact)
941 {
942 nt->nt_ic = ic;
943 - IEEE80211_NODE_LOCK_INIT(nt, ic->ic_dev->name);
944 + IEEE80211_NODE_TABLE_LOCK_INIT(nt, ic->ic_dev->name);
945 IEEE80211_SCAN_LOCK_INIT(nt, ic->ic_dev->name);
946 TAILQ_INIT(&nt->nt_node);
947 nt->nt_name = name;
948 @@ -733,11 +733,31 @@
949 mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL);
950 }
951
952 +static __inline void _node_table_join(struct ieee80211_node_table *nt, struct ieee80211_node *ni) {
953 + IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);
954 +
955 + ni->ni_table = nt;
956 + TAILQ_INSERT_TAIL(&nt->nt_node, ieee80211_ref_node(ni), ni_list);
957 + LIST_INSERT_HEAD(&nt->nt_hash[IEEE80211_NODE_HASH(ni->ni_macaddr)], ni, ni_hash);
958 +}
959 +
960 +static __inline void _node_table_leave(struct ieee80211_node_table *nt, struct ieee80211_node *ni) {
961 + struct ieee80211_node *hni;
962 + IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);
963 +
964 + TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
965 + LIST_FOREACH(hni, &nt->nt_hash[IEEE80211_NODE_HASH(ni->ni_macaddr)], ni_hash) {
966 + LIST_REMOVE(ni, ni_hash);
967 + }
968 + ni->ni_table = NULL;
969 + _ieee80211_unref_node(ni);
970 +}
971 +
972 /* This is overridden by ath_node_alloc in ath/if_ath.c, and so
973 - * should never get called
974 + * should never get called.
975 */
976 static struct ieee80211_node *
977 -node_alloc(struct ieee80211_node_table *nt, struct ieee80211vap *vap)
978 +node_alloc(struct ieee80211vap *vap)
979 {
980 struct ieee80211_node *ni;
981
982 @@ -776,13 +796,6 @@
983 IEEE80211_UNLOCK_IRQ(ni->ni_ic);
984 }
985 }
986 - /*
987 - * Clear AREF flag that marks the authorization refcnt bump
988 - * has happened. This is probably not needed as the node
989 - * should always be removed from the table so not found but
990 - * do it just in case.
991 - */
992 - ni->ni_flags &= ~IEEE80211_NODE_AREF;
993
994 /*
995 * Drain power save queue and, if needed, clear TIM.
996 @@ -791,10 +804,7 @@
997 vap->iv_set_tim(ni, 0);
998
999 ni->ni_associd = 0;
1000 - if (ni->ni_challenge != NULL) {
1001 - FREE(ni->ni_challenge, M_DEVBUF);
1002 - ni->ni_challenge = NULL;
1003 - }
1004 +
1005 /*
1006 * Preserve SSID, WPA, and WME ie's so the bss node is
1007 * reusable during a re-auth/re-assoc state transition.
1008 @@ -819,9 +829,16 @@
1009 static void
1010 node_free(struct ieee80211_node *ni)
1011 {
1012 +#if 0
1013 + /* We should 'cleanup' and then free'ing should be done automatically on decref */
1014 struct ieee80211com *ic = ni->ni_ic;
1015
1016 ic->ic_node_cleanup(ni);
1017 +#endif
1018 + KASSERT(ieee80211_node_refcnt(ni) == 0, ("node being free whilst still referenced"));
1019 +
1020 + if (ni->ni_challenge != NULL)
1021 + FREE(ni->ni_challenge, M_DEVBUF);
1022 if (ni->ni_wpa_ie != NULL)
1023 FREE(ni->ni_wpa_ie, M_DEVBUF);
1024 if (ni->ni_rsn_ie != NULL)
1025 @@ -831,6 +848,7 @@
1026 if (ni->ni_ath_ie != NULL)
1027 FREE(ni->ni_ath_ie, M_DEVBUF);
1028 IEEE80211_NODE_SAVEQ_DESTROY(ni);
1029 +
1030 FREE(ni, M_80211_NODE);
1031 }
1032
1033 @@ -847,55 +865,70 @@
1034 * This interface is not intended for general use, it is
1035 * used by the routines below to create entries with a
1036 * specific purpose.
1037 + * Dont assume a BSS?
1038 */
1039 struct ieee80211_node *
1040 -ieee80211_alloc_node(struct ieee80211_node_table *nt,
1041 - struct ieee80211vap *vap, const u_int8_t *macaddr)
1042 +ieee80211_alloc_node_table(struct ieee80211vap *vap,
1043 + const u_int8_t *macaddr)
1044 {
1045 - struct ieee80211com *ic = nt->nt_ic;
1046 + struct ieee80211com *ic = vap->iv_ic;
1047 + struct ieee80211_node_table *nt = &ic->ic_sta;
1048 struct ieee80211_node *ni;
1049 - int hash;
1050
1051 - ni = ic->ic_node_alloc(nt, vap);
1052 - if (ni == NULL) {
1053 - /* XXX msg */
1054 - vap->iv_stats.is_rx_nodealloc++;
1055 - return NULL;
1056 - }
1057 + ni = ieee80211_alloc_node(vap, macaddr);
1058 + if (ni != NULL) {
1059 + ni->ni_inact = ni->ni_inact_reload = nt->nt_inact_init;
1060
1061 - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
1062 - "%s: %p<%s> in %s table, refcnt %d\n", __func__, ni,
1063 - ether_sprintf(macaddr), nt->nt_name,
1064 - ieee80211_node_refcnt(ni)+1);
1065 + WME_UAPSD_NODE_TRIGSEQINIT(ni);
1066 + IEEE80211_NODE_SAVEQ_INIT(ni, "unknown");
1067
1068 - IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);
1069 - hash = IEEE80211_NODE_HASH(macaddr);
1070 - ieee80211_node_initref(ni); /* mark referenced */
1071 - ni->ni_chan = IEEE80211_CHAN_ANYC;
1072 - ni->ni_authmode = IEEE80211_AUTH_OPEN;
1073 - ni->ni_txpower = ic->ic_txpowlimit; /* max power */
1074 - ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE);
1075 - ni->ni_inact_reload = nt->nt_inact_init;
1076 - ni->ni_inact = ni->ni_inact_reload;
1077 - ni->ni_ath_defkeyindex = IEEE80211_INVAL_DEFKEY;
1078 - ni->ni_rxkeyoff = 0;
1079 - IEEE80211_NODE_SAVEQ_INIT(ni, "unknown");
1080 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1081 + _node_table_join(nt, ni);
1082 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1083 + }
1084
1085 - IEEE80211_NODE_LOCK_IRQ(nt);
1086 - ni->ni_vap = vap;
1087 - ni->ni_ic = ic;
1088 - ni->ni_table = nt;
1089 - TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list);
1090 - LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash);
1091 - ni->ni_rxfrag = NULL;
1092 - ni->ni_challenge = NULL;
1093 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1094 + return ni;
1095 +}
1096 +EXPORT_SYMBOL(ieee80211_alloc_node_table);
1097 +
1098 +/* Allocate a node structure and initialise specialised structures
1099 + * This function does not add the node to the node table, thus this
1100 + * node will not be found using ieee80211_find_*node.
1101 + * This is useful when sending one off errors or request denials.
1102 + */
1103 +static struct ieee80211_node *
1104 +ieee80211_alloc_node(struct ieee80211vap *vap, const u_int8_t *macaddr)
1105 +{
1106 + struct ieee80211com *ic = vap->iv_ic;
1107 + struct ieee80211_node *ni;
1108 +
1109 + /* This always allocates zeroed memoery */
1110 + ni = ic->ic_node_alloc(vap);
1111 + if (ni != NULL) {
1112 + IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
1113 + "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(macaddr),
1114 + ieee80211_node_refcnt(ni)+1);
1115
1116 - WME_UAPSD_NODE_TRIGSEQINIT(ni);
1117 + ieee80211_node_initref(ni); /* mark referenced */
1118 +
1119 + IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);
1120 +
1121 + ni->ni_chan = IEEE80211_CHAN_ANYC;
1122 + ni->ni_authmode = IEEE80211_AUTH_OPEN;
1123 + ni->ni_txpower = ic->ic_txpowlimit;
1124 +
1125 + ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey,
1126 + IEEE80211_KEYIX_NONE);
1127 + ni->ni_ath_defkeyindex = IEEE80211_INVAL_DEFKEY;
1128
1129 + ni->ni_vap = vap;
1130 + ni->ni_ic = ic;
1131 + } else {
1132 + /* XXX msg */
1133 + vap->iv_stats.is_rx_nodealloc++;
1134 + }
1135 return ni;
1136 }
1137 -EXPORT_SYMBOL(ieee80211_alloc_node);
1138
1139 /* Add wds address to the node table */
1140 int
1141 @@ -917,11 +950,11 @@
1142 wds->wds_agingcount = WDS_AGING_COUNT;
1143 hash = IEEE80211_NODE_HASH(macaddr);
1144 IEEE80211_ADDR_COPY(wds->wds_macaddr, macaddr);
1145 - ieee80211_ref_node(ni); /* Reference node */
1146 - wds->wds_ni = ni;
1147 - IEEE80211_NODE_LOCK_IRQ(nt);
1148 +
1149 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1150 + wds->wds_ni = ieee80211_ref_node(ni);
1151 LIST_INSERT_HEAD(&nt->nt_wds_hash[hash], wds, wds_hash);
1152 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1153 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1154 return 0;
1155 }
1156 EXPORT_SYMBOL(ieee80211_add_wds_addr);
1157 @@ -934,22 +967,19 @@
1158 struct ieee80211_wds_addr *wds, *twds;
1159
1160 hash = IEEE80211_NODE_HASH(macaddr);
1161 - IEEE80211_NODE_LOCK_IRQ(nt);
1162 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1163 LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {
1164 if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {
1165 - if (ieee80211_node_dectestref(wds->wds_ni)) {
1166 - _ieee80211_free_node(wds->wds_ni);
1167 - LIST_REMOVE(wds, wds_hash);
1168 - FREE(wds, M_80211_WDS);
1169 - break;
1170 - }
1171 + LIST_REMOVE(wds, wds_hash);
1172 + ieee80211_unref_node(&wds->wds_ni);
1173 + FREE(wds, M_80211_WDS);
1174 + break;
1175 }
1176 }
1177 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1178 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1179 }
1180 EXPORT_SYMBOL(ieee80211_remove_wds_addr);
1181
1182 -
1183 /* Remove node references from wds table */
1184 void
1185 ieee80211_del_wds_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni)
1186 @@ -957,19 +987,17 @@
1187 int hash;
1188 struct ieee80211_wds_addr *wds, *twds;
1189
1190 - IEEE80211_NODE_LOCK_IRQ(nt);
1191 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1192 for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) {
1193 LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {
1194 if (wds->wds_ni == ni) {
1195 - if (ieee80211_node_dectestref(ni)) {
1196 - _ieee80211_free_node(ni);
1197 - LIST_REMOVE(wds, wds_hash);
1198 - FREE(wds, M_80211_WDS);
1199 - }
1200 + LIST_REMOVE(wds, wds_hash);
1201 + ieee80211_unref_node(&wds->wds_ni);
1202 + FREE(wds, M_80211_WDS);
1203 }
1204 }
1205 }
1206 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1207 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1208 }
1209 EXPORT_SYMBOL(ieee80211_del_wds_node);
1210
1211 @@ -980,88 +1008,46 @@
1212 int hash;
1213 struct ieee80211_wds_addr *wds, *twds;
1214
1215 - IEEE80211_NODE_LOCK_IRQ(nt);
1216 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1217 for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) {
1218 LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {
1219 if (wds->wds_agingcount != WDS_AGING_STATIC) {
1220 if (!wds->wds_agingcount) {
1221 - if (ieee80211_node_dectestref(wds->wds_ni)) {
1222 - _ieee80211_free_node(wds->wds_ni);
1223 - LIST_REMOVE(wds, wds_hash);
1224 - FREE(wds, M_80211_WDS);
1225 - }
1226 + LIST_REMOVE(wds, wds_hash);
1227 + ieee80211_unref_node(&wds->wds_ni);
1228 + FREE(wds, M_80211_WDS);
1229 } else
1230 wds->wds_agingcount--;
1231 }
1232 }
1233 }
1234 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1235 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1236 mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL);
1237 }
1238
1239
1240 /*
1241 - * Craft a temporary node suitable for sending a management frame
1242 - * to the specified station. We craft only as much state as we
1243 - * need to do the work since the node will be immediately reclaimed
1244 - * once the send completes.
1245 - */
1246 -struct ieee80211_node *
1247 -ieee80211_tmp_node(struct ieee80211vap *vap, const u_int8_t *macaddr)
1248 -{
1249 - struct ieee80211com *ic = vap->iv_ic;
1250 - struct ieee80211_node *ni;
1251 -
1252 - ni = ic->ic_node_alloc(&ic->ic_sta,vap);
1253 - if (ni != NULL) {
1254 - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
1255 - "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(macaddr),
1256 - ieee80211_node_refcnt(ni)+1);
1257 -
1258 - IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);
1259 - IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid);
1260 - ieee80211_node_initref(ni); /* mark referenced */
1261 - ni->ni_txpower = vap->iv_bss->ni_txpower;
1262 - ni->ni_vap = vap;
1263 - /* NB: required by ieee80211_fix_rate */
1264 - ieee80211_node_set_chan(ic, ni);
1265 - ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey,
1266 - IEEE80211_KEYIX_NONE);
1267 - /* XXX optimize away */
1268 - IEEE80211_NODE_SAVEQ_INIT(ni, "unknown");
1269 -
1270 - ni->ni_table = NULL; /* NB: pedantic */
1271 - ni->ni_ic = ic;
1272 - ni->ni_rxfrag = NULL;
1273 - ni->ni_challenge = NULL;
1274 - } else {
1275 - /* XXX msg */
1276 - vap->iv_stats.is_rx_nodealloc++;
1277 - }
1278 - return ni;
1279 -}
1280 -
1281 -/*
1282 * Add the specified station to the station table.
1283 */
1284 struct ieee80211_node *
1285 -ieee80211_dup_bss(struct ieee80211vap *vap, const u_int8_t *macaddr)
1286 +ieee80211_dup_bss(struct ieee80211vap *vap, const u_int8_t *macaddr,
1287 + unsigned char tmp)
1288 {
1289 - struct ieee80211com *ic = vap->iv_ic;
1290 struct ieee80211_node *ni;
1291 +
1292 + /* FIXME: Hack */
1293 + if (tmp)
1294 + ni = ieee80211_alloc_node(vap, macaddr);
1295 + else
1296 + ni = ieee80211_alloc_node_table(vap, macaddr);
1297
1298 - ni = ieee80211_alloc_node(&ic->ic_sta, vap, macaddr);
1299 if (ni != NULL) {
1300 - /*
1301 - * Inherit from iv_bss.
1302 - */
1303 - ni->ni_authmode = vap->iv_bss->ni_authmode;
1304 - ni->ni_txpower = vap->iv_bss->ni_txpower;
1305 - ni->ni_vlan = vap->iv_bss->ni_vlan; /* XXX?? */
1306 + copy_bss(ni, vap->iv_bss);
1307 IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid);
1308 - ieee80211_node_set_chan(ic, ni);
1309 - ni->ni_rsn = vap->iv_bss->ni_rsn;
1310 - ni->ni_rxfrag = NULL;
1311 + /* Do this only for nodes that already have a BSS. Otherwise
1312 + * ic_bsschan is not set and we get a KASSERT failure.
1313 + * Required by ieee80211_fix_rate */
1314 + ieee80211_node_set_chan(vap->iv_ic, ni);
1315 }
1316 return ni;
1317 }
1318 @@ -1069,19 +1055,16 @@
1319 static struct ieee80211_node *
1320 _ieee80211_find_wds_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr)
1321 {
1322 - struct ieee80211_node *ni;
1323 struct ieee80211_wds_addr *wds;
1324 int hash;
1325 - IEEE80211_NODE_LOCK_ASSERT(nt);
1326 + IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);
1327
1328 hash = IEEE80211_NODE_HASH(macaddr);
1329 LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {
1330 if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {
1331 - ni = wds->wds_ni;
1332 if (wds->wds_agingcount != WDS_AGING_STATIC)
1333 wds->wds_agingcount = WDS_AGING_COUNT; /* reset the aging count */
1334 - ieee80211_ref_node(ni);
1335 - return ni;
1336 + return ieee80211_ref_node(wds->wds_ni);
1337 }
1338 }
1339 return NULL;
1340 @@ -1099,7 +1082,7 @@
1341 int hash;
1342 struct ieee80211_wds_addr *wds;
1343
1344 - IEEE80211_NODE_LOCK_ASSERT(nt);
1345 + IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);
1346
1347 hash = IEEE80211_NODE_HASH(macaddr);
1348 LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
1349 @@ -1120,9 +1103,7 @@
1350 nodes. */
1351 LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {
1352 if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {
1353 - ni = wds->wds_ni;
1354 - ieee80211_ref_node(ni);
1355 - return ni;
1356 + return ieee80211_ref_node(wds->wds_ni);
1357 }
1358 }
1359 return NULL;
1360 @@ -1137,9 +1118,9 @@
1361 {
1362 struct ieee80211_node *ni;
1363
1364 - IEEE80211_NODE_LOCK_IRQ(nt);
1365 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1366 ni = _ieee80211_find_wds_node(nt, macaddr);
1367 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1368 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1369 return ni;
1370 }
1371 EXPORT_SYMBOL(ieee80211_find_wds_node);
1372 @@ -1154,9 +1135,9 @@
1373 {
1374 struct ieee80211_node *ni;
1375
1376 - IEEE80211_NODE_LOCK_IRQ(nt);
1377 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1378 ni = _ieee80211_find_node(nt, macaddr);
1379 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1380 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1381 return ni;
1382 }
1383 #ifdef IEEE80211_DEBUG_REFCNT
1384 @@ -1179,7 +1160,7 @@
1385 {
1386 struct ieee80211_node *ni;
1387
1388 - ni = ieee80211_dup_bss(vap, macaddr);
1389 + ni = ieee80211_dup_bss(vap, macaddr, 0);
1390 if (ni != NULL) {
1391 /* XXX no rate negotiation; just dup */
1392 ni->ni_rates = vap->iv_bss->ni_rates;
1393 @@ -1202,14 +1183,13 @@
1394 * driver has an opportunity to setup it's private state.
1395 */
1396 struct ieee80211_node *
1397 -ieee80211_add_neighbor(struct ieee80211vap *vap, const struct ieee80211_frame *wh,
1398 +ieee80211_add_neighbor(struct ieee80211vap *vap, const struct ieee80211_frame *wh,
1399 const struct ieee80211_scanparams *sp)
1400 {
1401 struct ieee80211com *ic = vap->iv_ic;
1402 struct ieee80211_node *ni;
1403
1404 - ni = ieee80211_dup_bss(vap, wh->i_addr2); /* XXX alloc_node? */
1405 - /* TODO: not really putting itself in a table */
1406 + ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);
1407 if (ni != NULL) {
1408 ni->ni_esslen = sp->ssid[1];
1409 memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]);
1410 @@ -1284,12 +1264,12 @@
1411 /* XXX check ic_bss first in station mode */
1412 /* XXX 4-address frames? */
1413 nt = &ic->ic_sta;
1414 - IEEE80211_NODE_LOCK_IRQ(nt);
1415 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1416 if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/)
1417 ni = _ieee80211_find_node(nt, wh->i_addr1);
1418 else
1419 ni = _ieee80211_find_node(nt, wh->i_addr2);
1420 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1421 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1422
1423 return ni;
1424 #undef IS_PSPOLL
1425 @@ -1326,9 +1306,9 @@
1426
1427 /* XXX can't hold lock across dup_bss due to recursive locking */
1428 nt = &vap->iv_ic->ic_sta;
1429 - IEEE80211_NODE_LOCK_IRQ(nt);
1430 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1431 ni = _ieee80211_find_node(nt, mac);
1432 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1433 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1434
1435 if (ni == NULL) {
1436 if (vap->iv_opmode == IEEE80211_M_IBSS ||
1437 @@ -1355,11 +1335,9 @@
1438 EXPORT_SYMBOL(ieee80211_find_txnode);
1439 #endif
1440
1441 -/* Caller must lock the IEEE80211_NODE_LOCK
1442 - *
1443 - * Context: hwIRQ, softIRQ and process context
1444 +/* Context: hwIRQ, softIRQ and process context
1445 */
1446 -static void
1447 +void
1448 _ieee80211_free_node(struct ieee80211_node *ni)
1449 {
1450 struct ieee80211vap *vap = ni->ni_vap;
1451 @@ -1373,117 +1351,36 @@
1452
1453 if (vap->iv_aid_bitmap != NULL)
1454 IEEE80211_AID_CLR(vap, ni->ni_associd);
1455 - if (nt != NULL) {
1456 - TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
1457 - LIST_REMOVE(ni, ni_hash);
1458 - }
1459 +
1460 vap->iv_ic->ic_node_free(ni);
1461 }
1462 +EXPORT_SYMBOL(_ieee80211_free_node);
1463
1464 -void
1465 -#ifdef IEEE80211_DEBUG_REFCNT
1466 -ieee80211_free_node_debug(struct ieee80211_node *ni, const char *func, int line)
1467 -#else
1468 -ieee80211_free_node(struct ieee80211_node *ni)
1469 -#endif
1470 +static void _reset_node(void *arg, struct ieee80211_node *ni)
1471 {
1472 - struct ieee80211_node_table *nt = ni->ni_table;
1473 - struct ieee80211com *ic = ni->ni_ic;
1474 + if (ni->ni_associd != 0) {
1475 + struct ieee80211vap *vap = ni->ni_vap;
1476
1477 -#ifdef IEEE80211_DEBUG_REFCNT
1478 - IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,
1479 - "%s (%s:%u) %p<%s> refcnt %d\n", __func__, func, line, ni,
1480 - ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni) - 1);
1481 -#endif
1482 - /*
1483 - * XXX: may need to lock out the following race. we dectestref
1484 - * and determine it's time to free the node. between the if()
1485 - * and lock, we take an rx intr to receive a frame from this
1486 - * node. the rx path (tasklet or intr) bumps this node's
1487 - * refcnt and xmits a response frame. eventually that response
1488 - * will get reaped, and the reaping code will attempt to use
1489 - * the node. the code below will delete the node prior
1490 - * to the reap and we could get a crash.
1491 - *
1492 - * as a stopgap before delving deeper, lock intrs to
1493 - * prevent this case.
1494 - */
1495 - IEEE80211_LOCK_IRQ(ic);
1496 - if (ieee80211_node_dectestref(ni)) {
1497 - /*
1498 - * Beware; if the node is marked gone then it's already
1499 - * been removed from the table and we cannot assume the
1500 - * table still exists. Regardless, there's no need to lock
1501 - * the table.
1502 - */
1503 - if (ni->ni_table != NULL) {
1504 - IEEE80211_NODE_LOCK(nt);
1505 - _ieee80211_free_node(ni);
1506 - IEEE80211_NODE_UNLOCK(nt);
1507 - } else
1508 - _ieee80211_free_node(ni);
1509 + if (vap->iv_auth->ia_node_leave != NULL)
1510 + vap->iv_auth->ia_node_leave(ni);
1511 + if (vap->iv_aid_bitmap != NULL)
1512 + IEEE80211_AID_CLR(vap, ni->ni_associd);
1513 }
1514 - IEEE80211_UNLOCK_IRQ(ic);
1515 -}
1516 -#ifdef IEEE80211_DEBUG_REFCNT
1517 -EXPORT_SYMBOL(ieee80211_free_node_debug);
1518 -#else
1519 -EXPORT_SYMBOL(ieee80211_free_node);
1520 -#endif
1521 -
1522 -/*
1523 - * Reclaim a node. If this is the last reference count then
1524 - * do the normal free work. Otherwise remove it from the node
1525 - * table and mark it gone by clearing the back-reference.
1526 - */
1527 -static void
1528 -node_reclaim(struct ieee80211_node_table *nt, struct ieee80211_node *ni)
1529 -{
1530
1531 - IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,
1532 - "%s: remove %p<%s> from %s table, refcnt %d\n",
1533 - __func__, ni, ether_sprintf(ni->ni_macaddr),
1534 - nt->nt_name, ieee80211_node_refcnt(ni)-1);
1535 - if (!ieee80211_node_dectestref(ni)) {
1536 - /*
1537 - * Other references are present, just remove the
1538 - * node from the table so it cannot be found. When
1539 - * the references are dropped storage will be
1540 - * reclaimed. This normally only happens for ic_bss.
1541 - */
1542 - TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
1543 - LIST_REMOVE(ni, ni_hash);
1544 - ni->ni_table = NULL; /* clear reference */
1545 - } else
1546 - _ieee80211_free_node(ni);
1547 + ieee80211_node_leave(ni);
1548 }
1549
1550 static void
1551 ieee80211_node_table_reset(struct ieee80211_node_table *nt,
1552 - struct ieee80211vap *match)
1553 + struct ieee80211vap *vap)
1554 {
1555 - struct ieee80211_node *ni, *next;
1556 -
1557 - IEEE80211_NODE_LOCK_IRQ(nt);
1558 - TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, next) {
1559 - if (match != NULL && ni->ni_vap != match)
1560 - continue;
1561 - if (ni->ni_associd != 0) {
1562 - struct ieee80211vap *vap = ni->ni_vap;
1563 -
1564 - if (vap->iv_auth->ia_node_leave != NULL)
1565 - vap->iv_auth->ia_node_leave(ni);
1566 - if (vap->iv_aid_bitmap != NULL)
1567 - IEEE80211_AID_CLR(vap, ni->ni_associd);
1568 - }
1569 - node_reclaim(nt, ni);
1570 - }
1571 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1572 + ieee80211_iterate_dev_nodes(vap->iv_dev, nt, _reset_node, NULL);
1573 }
1574
1575 static void
1576 ieee80211_node_table_cleanup(struct ieee80211_node_table *nt)
1577 {
1578 + struct ieee80211com *ic = nt->nt_ic;
1579 struct ieee80211_node *ni, *next;
1580
1581 TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, next) {
1582 @@ -1495,11 +1392,11 @@
1583 if (vap->iv_aid_bitmap != NULL)
1584 IEEE80211_AID_CLR(vap, ni->ni_associd);
1585 }
1586 - node_reclaim(nt, ni);
1587 + ic->ic_node_cleanup(ni);
1588 }
1589 del_timer(&nt->nt_wds_aging_timer);
1590 IEEE80211_SCAN_LOCK_DESTROY(nt);
1591 - IEEE80211_NODE_LOCK_DESTROY(nt);
1592 + IEEE80211_NODE_TABLE_LOCK_DESTROY(nt);
1593 }
1594
1595 /*
1596 @@ -1527,19 +1424,22 @@
1597 IEEE80211_SCAN_LOCK_IRQ(nt);
1598 gen = ++nt->nt_scangen;
1599 restart:
1600 - IEEE80211_NODE_LOCK_IRQ(nt);
1601 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1602 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
1603 if (ni->ni_scangen == gen) /* previously handled */
1604 continue;
1605 + /* Temporary entries should no longer be in the node table */
1606 /*
1607 * Ignore entries for which have yet to receive an
1608 * authentication frame. These are transient and
1609 * will be reclaimed when the last reference to them
1610 * goes away (when frame xmits complete).
1611 */
1612 - if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
1613 - (ni->ni_flags & IEEE80211_NODE_AREF) == 0)
1614 - continue;
1615 + /*
1616 + *if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
1617 + * (ni->ni_flags & IEEE80211_NODE_AREF) == 0)
1618 + * continue;
1619 + */
1620 ni->ni_scangen = gen;
1621 /*
1622 * Free fragment if not needed anymore
1623 @@ -1591,7 +1491,7 @@
1624 * ref for us as needed.
1625 */
1626 ieee80211_ref_node(ni);
1627 - IEEE80211_NODE_UNLOCK_IRQ_EARLY(nt);
1628 + IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt);
1629 ieee80211_send_nulldata(ni);
1630 /* XXX stat? */
1631 goto restart;
1632 @@ -1614,18 +1514,18 @@
1633 */
1634 ni->ni_vap->iv_stats.is_node_timeout++;
1635 ieee80211_ref_node(ni);
1636 - IEEE80211_NODE_UNLOCK_IRQ_EARLY(nt);
1637 + IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt);
1638 if (ni->ni_associd != 0) {
1639 IEEE80211_SEND_MGMT(ni,
1640 IEEE80211_FC0_SUBTYPE_DEAUTH,
1641 IEEE80211_REASON_AUTH_EXPIRE);
1642 }
1643 ieee80211_node_leave(ni);
1644 - ieee80211_free_node(ni);
1645 + ieee80211_unref_node(&ni);
1646 goto restart;
1647 }
1648 }
1649 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1650 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1651
1652 IEEE80211_SCAN_UNLOCK_IRQ(nt);
1653 }
1654 @@ -1660,21 +1560,23 @@
1655
1656 IEEE80211_SCAN_LOCK_IRQ(nt);
1657 gen = ++nt->nt_scangen;
1658 +
1659 restart:
1660 - IEEE80211_NODE_LOCK(nt);
1661 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1662 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
1663 if (dev != NULL && ni->ni_vap->iv_dev != dev)
1664 continue; /* skip node not for this vap */
1665 if (ni->ni_scangen != gen) {
1666 ni->ni_scangen = gen;
1667 (void) ieee80211_ref_node(ni);
1668 - IEEE80211_NODE_UNLOCK(nt);
1669 + IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt);
1670 (*f)(arg, ni);
1671 - ieee80211_free_node(ni);
1672 +
1673 + ieee80211_unref_node(&ni);
1674 goto restart;
1675 }
1676 }
1677 - IEEE80211_NODE_UNLOCK(nt);
1678 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1679
1680 IEEE80211_SCAN_UNLOCK_IRQ(nt);
1681 }
1682 @@ -1948,9 +1850,20 @@
1683 "station with aid %d leaves (refcnt %u)",
1684 IEEE80211_NODE_AID(ni), ieee80211_node_refcnt(ni));
1685
1686 + /* From this point onwards we can no longer find the node,
1687 + * so no more references are generated
1688 + */
1689 + ieee80211_remove_wds_addr(nt, ni->ni_macaddr);
1690 + ieee80211_del_wds_node(nt, ni);
1691 + IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
1692 + _node_table_leave(nt, ni);
1693 + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
1694 +
1695 /*
1696 * If node wasn't previously associated all
1697 * we need to do is reclaim the reference.
1698 + * This also goes for nodes that are auth'ed but
1699 + * not associated.
1700 */
1701 /* XXX ibss mode bypasses 11g and notification */
1702 if (ni->ni_associd == 0)
1703 @@ -1968,9 +1881,11 @@
1704 IEEE80211_LOCK_IRQ(ic);
1705 if (vap->iv_aid_bitmap != NULL)
1706 IEEE80211_AID_CLR(vap, ni->ni_associd);
1707 +
1708 ni->ni_associd = 0;
1709 vap->iv_sta_assoc--;
1710 ic->ic_sta_assoc--;
1711 +
1712 #ifdef ATH_SUPERG_XR
1713 if (ni->ni_vap->iv_flags & IEEE80211_F_XR)
1714 ic->ic_xr_sta_assoc--;
1715 @@ -1981,6 +1896,7 @@
1716 if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
1717 ieee80211_node_leave_11g(ni);
1718 IEEE80211_UNLOCK_IRQ(ic);
1719 +
1720 /*
1721 * Cleanup station state. In particular clear various
1722 * state that might otherwise be reused if the node
1723 @@ -1990,19 +1906,10 @@
1724 ieee80211_sta_leave(ni);
1725 done:
1726 /*
1727 - * Remove the node from any table it's recorded in and
1728 - * drop the caller's reference. Removal from the table
1729 - * is important to ensure the node is not reprocessed
1730 - * for inactivity.
1731 - */
1732 - if (nt != NULL) {
1733 - IEEE80211_NODE_LOCK_IRQ(nt);
1734 - node_reclaim(nt, ni);
1735 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1736 - ieee80211_remove_wds_addr(nt,ni->ni_macaddr);
1737 - ieee80211_del_wds_node(nt,ni);
1738 - } else
1739 - ieee80211_free_node(ni);
1740 + * Run a cleanup and then drop the caller's reference
1741 + */
1742 + ic->ic_node_cleanup(ni);
1743 + ieee80211_unref_node(&ni);
1744 }
1745 EXPORT_SYMBOL(ieee80211_node_leave);
1746
1747 @@ -2062,25 +1969,8 @@
1748 void
1749 ieee80211_node_reset(struct ieee80211_node *ni, struct ieee80211vap *vap)
1750 {
1751 - if (ni != NULL) {
1752 - struct ieee80211_node_table *nt = ni->ni_table;
1753 - if (!nt)
1754 - nt = &vap->iv_ic->ic_sta;
1755 - IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid);
1756 - ni->ni_prev_vap = ni->ni_vap;
1757 - ni->ni_vap = vap;
1758 - ni->ni_ic = vap->iv_ic;
1759 - /*
1760 - * if node not found in the node table
1761 - * add it to the node table .
1762 - */
1763 - if(nt && ieee80211_find_node(nt, ni->ni_macaddr) != ni) {
1764 - int hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
1765 - IEEE80211_NODE_LOCK_IRQ(nt);
1766 - TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list);
1767 - LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash);
1768 - ni->ni_table = nt;
1769 - IEEE80211_NODE_UNLOCK_IRQ(nt);
1770 - }
1771 - }
1772 + IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid);
1773 + ni->ni_prev_vap = ni->ni_vap;
1774 + ni->ni_vap = vap;
1775 + ni->ni_ic = vap->iv_ic;
1776 }
1777 diff -ur madwifi.old/net80211/ieee80211_node.h madwifi.dev/net80211/ieee80211_node.h
1778 --- madwifi.old/net80211/ieee80211_node.h 2007-03-06 11:59:28.000000000 +0100
1779 +++ madwifi.dev/net80211/ieee80211_node.h 2007-05-21 08:10:46.869753416 +0200
1780 @@ -52,14 +52,14 @@
1781 * authorized. The latter timeout is shorter to more aggressively
1782 * reclaim nodes that leave part way through the 802.1x exchange.
1783 */
1784 -#define IEEE80211_INACT_WAIT 15 /* inactivity interval (secs) */
1785 +#define IEEE80211_INACT_WAIT 15 /* inactivity interval (secs) */
1786 #define IEEE80211_INACT_INIT (30/IEEE80211_INACT_WAIT) /* initial */
1787 #define IEEE80211_INACT_AUTH (180/IEEE80211_INACT_WAIT) /* associated but not authorized */
1788 #define IEEE80211_INACT_RUN (300/IEEE80211_INACT_WAIT) /* authorized */
1789 #define IEEE80211_INACT_PROBE (30/IEEE80211_INACT_WAIT) /* probe */
1790 #define IEEE80211_INACT_SCAN (300/IEEE80211_INACT_WAIT) /* scanned */
1791
1792 -#define IEEE80211_TRANS_WAIT 5 /* mgt frame tx timer (secs) */
1793 +#define IEEE80211_TRANS_WAIT 5 /* mgt frame tx timer (secs) */
1794
1795 #define IEEE80211_NODE_HASHSIZE 32
1796 /* simple hash is enough for variation of macaddr */
1797 @@ -94,7 +94,8 @@
1798 struct ieee80211_node_table *ni_table;
1799 TAILQ_ENTRY(ieee80211_node) ni_list;
1800 LIST_ENTRY(ieee80211_node) ni_hash;
1801 - atomic_t ni_refcnt;
1802 + // ieee80211_node_lock_t ni_nodelock; /* on node - notably for ref counting */
1803 + ieee80211_node_ref_count_t ni_refcnt;
1804 u_int ni_scangen; /* gen# for timeout scan */
1805 u_int8_t ni_authmode; /* authentication algorithm */
1806 u_int16_t ni_flags; /* special-purpose state */
1807 @@ -121,13 +122,13 @@
1808 u_int16_t ni_associd; /* assoc response */
1809 u_int16_t ni_txpower; /* current transmit power (in 0.5 dBm) */
1810 u_int16_t ni_vlan; /* vlan tag */
1811 - u_int32_t *ni_challenge; /* shared-key challenge */
1812 + u_int32_t *ni_challenge; /* shared-key challenge */
1813 u_int8_t *ni_wpa_ie; /* captured WPA ie */
1814 u_int8_t *ni_rsn_ie; /* captured RSN ie */
1815 u_int8_t *ni_wme_ie; /* captured WME ie */
1816 u_int8_t *ni_ath_ie; /* captured Atheros ie */
1817 - u_int16_t ni_txseqs[17]; /* tx seq per-tid */
1818 - u_int16_t ni_rxseqs[17]; /* rx seq previous per-tid*/
1819 + u_int16_t ni_txseqs[17]; /* tx seq per-tid */
1820 + u_int16_t ni_rxseqs[17]; /* rx seq previous per-tid*/
1821 u_int32_t ni_rxfragstamp; /* time stamp of last rx frag */
1822 struct sk_buff *ni_rxfrag; /* rx frag reassembly */
1823 struct ieee80211_rsnparms ni_rsn; /* RSN/WPA parameters */
1824 @@ -156,7 +157,7 @@
1825 struct ieee80211_channel *ni_chan;
1826 u_int16_t ni_fhdwell; /* FH only */
1827 u_int8_t ni_fhindex; /* FH only */
1828 - u_int8_t ni_erp; /* ERP from beacon/probe resp */
1829 + u_int8_t ni_erp; /* ERP from beacon/probe resp */
1830 u_int16_t ni_timoff; /* byte offset to TIM ie */
1831
1832 /* others */
1833 @@ -168,7 +169,7 @@
1834 struct ieee80211vap *ni_prev_vap; /* previously associated vap */
1835 u_int8_t ni_uapsd; /* U-APSD per-node flags matching WMM STA Qos Info field */
1836 u_int8_t ni_uapsd_maxsp; /* maxsp from flags above */
1837 - u_int16_t ni_uapsd_trigseq[WME_NUM_AC]; /* trigger suppression on retry */
1838 + u_int16_t ni_uapsd_trigseq[WME_NUM_AC]; /* trigger suppression on retry */
1839 __le16 ni_pschangeseq;
1840 };
1841 MALLOC_DECLARE(M_80211_NODE);
1842 @@ -186,20 +187,6 @@
1843 #define WME_UAPSD_NODE_INVALIDSEQ 0xffff
1844 #define WME_UAPSD_NODE_TRIGSEQINIT(_ni) (memset(&(_ni)->ni_uapsd_trigseq[0], 0xff, sizeof((_ni)->ni_uapsd_trigseq)))
1845
1846 -static __inline struct ieee80211_node *
1847 -ieee80211_ref_node(struct ieee80211_node *ni)
1848 -{
1849 - ieee80211_node_incref(ni);
1850 - return ni;
1851 -}
1852 -
1853 -static __inline void
1854 -ieee80211_unref_node(struct ieee80211_node **ni)
1855 -{
1856 - ieee80211_node_decref(*ni);
1857 - *ni = NULL; /* guard against use */
1858 -}
1859 -
1860 void ieee80211_node_attach(struct ieee80211com *);
1861 void ieee80211_node_detach(struct ieee80211com *);
1862 void ieee80211_node_vattach(struct ieee80211vap *);
1863 @@ -242,43 +229,39 @@
1864 * is a second table for associated stations or neighbors.
1865 */
1866 struct ieee80211_node_table {
1867 + const char *nt_name; /* for debugging */
1868 struct ieee80211com *nt_ic; /* back reference */
1869 - ieee80211_node_lock_t nt_nodelock; /* on node table */
1870 + ieee80211_node_table_lock_t nt_nodelock; /* on node table */
1871 TAILQ_HEAD(, ieee80211_node) nt_node; /* information of all nodes */
1872 ATH_LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE];
1873 ATH_LIST_HEAD(, ieee80211_wds_addr) nt_wds_hash[IEEE80211_NODE_HASHSIZE];
1874 - const char *nt_name; /* for debugging */
1875 ieee80211_scan_lock_t nt_scanlock; /* on nt_scangen */
1876 u_int nt_scangen; /* gen# for timeout scan */
1877 int nt_inact_init; /* initial node inact setting */
1878 struct timer_list nt_wds_aging_timer; /* timer to age out wds entries */
1879 };
1880
1881 -struct ieee80211_node *ieee80211_alloc_node(struct ieee80211_node_table *,
1882 - struct ieee80211vap *, const u_int8_t *);
1883 -struct ieee80211_node *ieee80211_tmp_node(struct ieee80211vap *,
1884 - const u_int8_t *);
1885 -struct ieee80211_node *ieee80211_dup_bss(struct ieee80211vap *,
1886 +struct ieee80211_node *ieee80211_alloc_node_table(struct ieee80211vap *,
1887 const u_int8_t *);
1888 +struct ieee80211_node *ieee80211_dup_bss(struct ieee80211vap *,
1889 + const u_int8_t *, unsigned char);
1890 void ieee80211_node_reset(struct ieee80211_node *, struct ieee80211vap *);
1891 #ifdef IEEE80211_DEBUG_REFCNT
1892 -void ieee80211_free_node_debug(struct ieee80211_node *, const char *, int);
1893 struct ieee80211_node *ieee80211_find_node_debug(struct ieee80211_node_table *,
1894 const u_int8_t *, const char *, int);
1895 struct ieee80211_node *ieee80211_find_rxnode_debug(struct ieee80211com *,
1896 const struct ieee80211_frame_min *, const char *, int);
1897 struct ieee80211_node *ieee80211_find_txnode_debug(struct ieee80211vap *,
1898 const u_int8_t *, const char *, int);
1899 -#define ieee80211_free_node(ni) \
1900 - ieee80211_free_node_debug(ni, __func__, __LINE__)
1901 -#define ieee80211_find_node(nt, mac) \
1902 - ieee80211_find_node_debug(nt, mac, __func__, __LINE__)
1903 -#define ieee80211_find_rxnode(nt, wh) \
1904 - ieee80211_find_rxnode_debug(nt, wh, __func__, __LINE__)
1905 -#define ieee80211_find_txnode(nt, mac) \
1906 - ieee80211_find_txnode_debug(nt, mac, __func__, __LINE__)
1907 +#define ieee80211_unref_node(_ni) \
1908 + ieee80211_unref_node_debug(_ni, __func__, __LINE__)
1909 +#define ieee80211_find_node(_nt, _mac) \
1910 + ieee80211_find_node_debug(_nt, _mac, __func__, __LINE__)
1911 +#define ieee80211_find_rxnode(_nt, _wh) \
1912 + ieee80211_find_rxnode_debug(_nt, _wh, __func__, __LINE__)
1913 +#define ieee80211_find_txnode(_nt, _mac) \
1914 + ieee80211_find_txnode_debug(_nt, _mac, __func__, __LINE__)
1915 #else
1916 -void ieee80211_free_node(struct ieee80211_node *);
1917
1918 struct ieee80211_node *ieee80211_find_node(struct ieee80211_node_table *,
1919 const u_int8_t *);
1920 @@ -287,6 +270,53 @@
1921 struct ieee80211_node *ieee80211_find_txnode(struct ieee80211vap *,
1922 const u_int8_t *);
1923 #endif
1924 +
1925 +void _ieee80211_free_node(struct ieee80211_node *);
1926 +
1927 +static __inline struct ieee80211_node *
1928 +ieee80211_ref_node(struct ieee80211_node *ni)
1929 +{
1930 + ieee80211_node_incref(ni);
1931 + return ni;
1932 +}
1933 +
1934 +static __inline struct ieee80211_node *
1935 +_ieee80211_pass_node(struct ieee80211_node **pni) {
1936 + struct ieee80211_node *tmp = *pni;
1937 + *pni = NULL;
1938 + return (tmp);
1939 +}
1940 +
1941 +#define PASS_NODE(_ni) \
1942 + _ieee80211_pass_node(&_ni)
1943 +
1944 +static __inline int
1945 +_ieee80211_unref_node(struct ieee80211_node *ni) {
1946 + if (ieee80211_node_dectestref(ni)) {
1947 + _ieee80211_free_node(ni);
1948 + return 1;
1949 + } else {
1950 + return 0;
1951 + }
1952 +}
1953 +
1954 +static __inline void
1955 +#ifdef IEEE80211_DEBUG_REFCNT
1956 +ieee80211_unref_node_debug(struct ieee80211_node **pni, const char *func, int line)
1957 +#else
1958 +ieee80211_unref_node(struct ieee80211_node **pni)
1959 +#endif
1960 +{
1961 + struct ieee80211_node *ni = *pni;
1962 +#ifdef IEEE80211_DEBUG_REFCNT
1963 + IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,
1964 + "%s (%s:%u) %p<%s> refcnt %d\n", __func__, func, line, ni,
1965 + ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni) - 1);
1966 +#endif
1967 + _ieee80211_unref_node(ni);
1968 + *pni = NULL; /* guard against use */
1969 +}
1970 +
1971 int ieee80211_add_wds_addr(struct ieee80211_node_table *, struct ieee80211_node *,
1972 const u_int8_t *, u_int8_t);
1973 void ieee80211_remove_wds_addr(struct ieee80211_node_table *, const u_int8_t *);
1974 diff -ur madwifi.old/net80211/ieee80211_output.c madwifi.dev/net80211/ieee80211_output.c
1975 --- madwifi.old/net80211/ieee80211_output.c 2007-05-18 13:19:16.000000000 +0200
1976 +++ madwifi.dev/net80211/ieee80211_output.c 2007-05-21 08:10:46.870753264 +0200
1977 @@ -254,7 +254,7 @@
1978 goto bad;
1979 }
1980
1981 - cb->ni = ni;
1982 + cb->ni = ieee80211_ref_node(ni);
1983
1984 /* power-save checks */
1985 if (WME_UAPSD_AC_CAN_TRIGGER(skb->priority, ni)) {
1986 @@ -293,13 +293,14 @@
1987 }
1988 #endif
1989 ieee80211_parent_queue_xmit(skb);
1990 + ieee80211_unref_node(&ni);
1991 return 0;
1992
1993 bad:
1994 if (skb != NULL)
1995 dev_kfree_skb(skb);
1996 if (ni != NULL)
1997 - ieee80211_free_node(ni);
1998 + ieee80211_unref_node(&ni);
1999 return 0;
2000 }
2001
2002 @@ -453,7 +454,7 @@
2003 if (skb == NULL) {
2004 /* XXX debug msg */
2005 vap->iv_stats.is_tx_nobuf++;
2006 - ieee80211_free_node(ni);
2007 + ieee80211_unref_node(&ni);
2008 return -ENOMEM;
2009 }
2010 cb = (struct ieee80211_cb *)skb->cb;
2011 @@ -507,16 +508,14 @@
2012 u_int8_t *frm;
2013 int tid;
2014
2015 - ieee80211_ref_node(ni);
2016 skb = ieee80211_getmgtframe(&frm, 2);
2017 if (skb == NULL) {
2018 /* XXX debug msg */
2019 vap->iv_stats.is_tx_nobuf++;
2020 - ieee80211_free_node(ni);
2021 return -ENOMEM;
2022 }
2023 cb = (struct ieee80211_cb *)skb->cb;
2024 - cb->ni = ni;
2025 + cb->ni = ieee80211_ref_node(ni);
2026
2027 skb->priority = ac;
2028 qwh = (struct ieee80211_qosframe *)skb_push(skb, sizeof(struct ieee80211_qosframe));
2029 @@ -865,7 +864,7 @@
2030 nt = &ic->ic_sta;
2031 ni_wds = ieee80211_find_wds_node(nt, eh.ether_shost);
2032 if (ni_wds)
2033 - ieee80211_free_node(ni_wds); /* Decr ref count */
2034 + ieee80211_unref_node(&ni_wds); /* Decr ref count */
2035 else
2036 ieee80211_add_wds_addr(nt, ni, eh.ether_shost, 0);
2037 }
2038 @@ -1719,7 +1718,6 @@
2039 __func__, __LINE__,
2040 ni, ether_sprintf(ni->ni_macaddr),
2041 ieee80211_node_refcnt(ni) + 1);
2042 - ieee80211_ref_node(ni);
2043
2044 /*
2045 * prreq frame format
2046 @@ -1735,7 +1733,6 @@
2047 vap->app_ie[IEEE80211_APPIE_FRAME_PROBE_REQ].length);
2048 if (skb == NULL) {
2049 vap->iv_stats.is_tx_nobuf++;
2050 - ieee80211_free_node(ni);
2051 return -ENOMEM;
2052 }
2053
2054 @@ -1758,7 +1755,7 @@
2055 skb_trim(skb, frm - skb->data);
2056
2057 cb = (struct ieee80211_cb *)skb->cb;
2058 - cb->ni = ni;
2059 + cb->ni = ieee80211_ref_node(ni);
2060
2061 wh = (struct ieee80211_frame *)
2062 skb_push(skb, sizeof(struct ieee80211_frame));
2063 @@ -2234,7 +2231,7 @@
2064 mod_timer(&vap->iv_mgtsend, jiffies + timer * HZ);
2065 return 0;
2066 bad:
2067 - ieee80211_free_node(ni);
2068 + ieee80211_unref_node(&ni);
2069 return ret;
2070 #undef senderr
2071 }
2072 diff -ur madwifi.old/net80211/ieee80211_power.c madwifi.dev/net80211/ieee80211_power.c
2073 --- madwifi.old/net80211/ieee80211_power.c 2007-05-18 13:19:16.000000000 +0200
2074 +++ madwifi.dev/net80211/ieee80211_power.c 2007-05-21 08:10:46.870753264 +0200
2075 @@ -109,13 +109,15 @@
2076 int
2077 ieee80211_node_saveq_drain(struct ieee80211_node *ni)
2078 {
2079 + struct ieee80211_cb *cb = NULL;
2080 struct sk_buff *skb;
2081 int qlen;
2082
2083 IEEE80211_NODE_SAVEQ_LOCK(ni);
2084 qlen = skb_queue_len(&ni->ni_savedq);
2085 while ((skb = __skb_dequeue(&ni->ni_savedq)) != NULL) {
2086 - ieee80211_free_node(ni);
2087 + cb = (struct ieee80211_cb *) skb->cb;
2088 + ieee80211_unref_node(&cb->ni);
2089 dev_kfree_skb_any(skb);
2090 }
2091 IEEE80211_NODE_SAVEQ_UNLOCK(ni);
2092 diff -ur madwifi.old/net80211/ieee80211_proto.c madwifi.dev/net80211/ieee80211_proto.c
2093 --- madwifi.old/net80211/ieee80211_proto.c 2006-12-08 18:20:08.000000000 +0100
2094 +++ madwifi.dev/net80211/ieee80211_proto.c 2007-05-21 08:10:46.871753112 +0200
2095 @@ -1456,7 +1456,7 @@
2096 */
2097 if (vap->iv_opmode == IEEE80211_M_WDS) {
2098 struct ieee80211_node *wds_ni;
2099 - wds_ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->wds_mac);
2100 + wds_ni = ieee80211_alloc_node_table(vap, vap->wds_mac);
2101 if (wds_ni != NULL) {
2102 if (ieee80211_add_wds_addr(&ic->ic_sta, wds_ni, vap->wds_mac, 1) == 0) {
2103 ieee80211_node_authorize(wds_ni);
2104 diff -ur madwifi.old/net80211/ieee80211_var.h madwifi.dev/net80211/ieee80211_var.h
2105 --- madwifi.old/net80211/ieee80211_var.h 2007-05-18 13:19:16.000000000 +0200
2106 +++ madwifi.dev/net80211/ieee80211_var.h 2007-05-21 08:12:01.499407984 +0200
2107 @@ -44,6 +44,8 @@
2108
2109 #include <sys/queue.h>
2110
2111 +struct ieee80211vap;
2112 +
2113 #include <net80211/_ieee80211.h>
2114 #include <net80211/ieee80211.h>
2115 #include <net80211/ieee80211_crypto.h>
2116 @@ -115,7 +117,6 @@
2117 * the underlying device and the net80211 layer is exposed here;
2118 * e.g. device-specific callbacks.
2119 */
2120 -struct ieee80211vap;
2121
2122 struct ieee80211com {
2123 struct net_device *ic_dev; /* associated device */
2124 @@ -236,8 +237,7 @@
2125 /* new station association callback/notification */
2126 void (*ic_newassoc)(struct ieee80211_node *, int);
2127 /* node state management */
2128 - struct ieee80211_node *(*ic_node_alloc)(struct ieee80211_node_table *,
2129 - struct ieee80211vap *);
2130 + struct ieee80211_node *(*ic_node_alloc)(struct ieee80211vap *);
2131 void (*ic_node_free)(struct ieee80211_node *);
2132 void (*ic_node_cleanup)(struct ieee80211_node *);
2133 u_int8_t (*ic_node_getrssi)(const struct ieee80211_node *);
2134 diff -ur madwifi.old/net80211/ieee80211_wireless.c madwifi.dev/net80211/ieee80211_wireless.c
2135 --- madwifi.old/net80211/ieee80211_wireless.c 2007-05-18 13:19:16.000000000 +0200
2136 +++ madwifi.dev/net80211/ieee80211_wireless.c 2007-05-21 08:10:46.874752656 +0200
2137 @@ -3186,7 +3186,7 @@
2138 error = -ENXIO;
2139 ieee80211_key_update_end(vap);
2140 if (ni != NULL)
2141 - ieee80211_free_node(ni);
2142 + ieee80211_unref_node(&ni);
2143 #ifdef ATH_SUPERG_XR
2144 /* set the same params on the xr vap device if exists */
2145 if (vap->iv_xrvap && !(vap->iv_flags & IEEE80211_F_XR))
2146 @@ -3246,7 +3246,7 @@
2147 memset(ik.ik_keydata, 0, sizeof(ik.ik_keydata));
2148 }
2149 if (ni != NULL)
2150 - ieee80211_free_node(ni);
2151 + ieee80211_unref_node(&ni);
2152 return (copy_to_user(iwr->u.data.pointer, &ik, sizeof(ik)) ? -EFAULT : 0);
2153 }
2154
2155 @@ -3271,7 +3271,7 @@
2156 return -ENOENT; /* No such entity is a more appropriate error */
2157 /* XXX error return */
2158 ieee80211_crypto_delkey(vap, &ni->ni_ucastkey, ni);
2159 - ieee80211_free_node(ni);
2160 + ieee80211_unref_node(&ni);
2161 } else {
2162 if (kix >= IEEE80211_WEP_NKID)
2163 return -EINVAL;
2164 @@ -3382,7 +3382,7 @@
2165 return -EINVAL;
2166 if (dev == ni->ni_vap->iv_dev)
2167 domlme(mlme, ni);
2168 - ieee80211_free_node(ni);
2169 + ieee80211_unref_node(&ni);
2170 } else
2171 ieee80211_iterate_dev_nodes(dev, &ic->ic_sta, domlme, mlme);
2172 break;
2173 @@ -3401,7 +3401,7 @@
2174 ieee80211_node_authorize(ni);
2175 else
2176 ieee80211_node_unauthorize(ni);
2177 - ieee80211_free_node(ni);
2178 + ieee80211_unref_node(&ni);
2179 break;
2180 case IEEE80211_MLME_CLEAR_STATS:
2181 if (vap->iv_opmode != IEEE80211_M_HOSTAP)
2182 @@ -3412,7 +3412,7 @@
2183
2184 /* clear statistics */
2185 memset(&ni->ni_stats, 0, sizeof(struct ieee80211_nodestats));
2186 - ieee80211_free_node(ni);
2187 + ieee80211_unref_node(&ni);
2188 break;
2189 default:
2190 return -EINVAL;
2191 @@ -3785,7 +3785,7 @@
2192 ielen = sizeof(wpaie.rsn_ie);
2193 memcpy(wpaie.rsn_ie, ni->ni_rsn_ie, ielen);
2194 }
2195 - ieee80211_free_node(ni);
2196 + ieee80211_unref_node(&ni);
2197 return (copy_to_user(iwr->u.data.pointer, &wpaie, sizeof(wpaie)) ?
2198 -EFAULT : 0);
2199 }
2200 @@ -3813,7 +3813,7 @@
2201 /* NB: copy out only the statistics */
2202 error = copy_to_user(iwr->u.data.pointer + off, &ni->ni_stats,
2203 iwr->u.data.length - off);
2204 - ieee80211_free_node(ni);
2205 + ieee80211_unref_node(&ni);
2206 return (error ? -EFAULT : 0);
2207 }
2208