Ticket #907: madwifi-refcnt.diff
| File madwifi-refcnt.diff, 35.7 kB (added by mentor, 6 years ago) |
|---|
-
net80211/ieee80211_crypto.c
old new 609 609 610 610 /* 611 611 * Validate and strip privacy headers (and trailer) for a 612 * received frame that has the WEP/Privacybit set.612 * received frame that has the Protected Frame bit set. 613 613 */ 614 614 struct ieee80211_key * 615 615 ieee80211_crypto_decap(struct ieee80211_node *ni, struct sk_buff *skb, int hdrlen) -
net80211/ieee80211_node.c
old new 72 72 static u_int8_t node_getrssi(const struct ieee80211_node *); 73 73 74 74 static void _ieee80211_free_node(struct ieee80211_node *); 75 static void node_reclaim(struct ieee80211_node_table *, struct ieee80211_node*);76 75 76 static void _node_table_leave(struct ieee80211_node_table *, struct ieee80211_node *); 77 static void _node_table_join(struct ieee80211_node_table *, struct ieee80211_node *); 78 77 79 static void ieee80211_node_timeout(unsigned long); 78 80 79 81 static void ieee80211_node_table_init(struct ieee80211com *, … … 192 194 193 195 ieee80211_node_table_reset(&ic->ic_sta, vap); 194 196 if (vap->iv_bss != NULL) { 195 ieee80211_free_node(vap->iv_bss); 196 vap->iv_bss = NULL; 197 ieee80211_unref_node(&vap->iv_bss); 197 198 } 198 199 if (vap->iv_aid_bitmap != NULL) { 199 200 FREE(vap->iv_aid_bitmap, M_DEVBUF); … … 261 262 "%s: creating ibss on channel %u\n", __func__, 262 263 ieee80211_chan2ieee(ic, chan)); 263 264 264 /* Check to see if we already have a node for this mac */ 265 /* Check to see if we already have a node for this mac 266 * NB: we gain a node reference here 267 */ 265 268 ni = ieee80211_find_node(&ic->ic_sta, vap->iv_myaddr); 266 269 if (ni == NULL) { 267 270 ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr); … … 270 273 return; 271 274 } 272 275 } 273 else274 ieee80211_free_node(ni);275 276 276 277 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "%s: %p<%s> refcnt %d\n", 277 278 __func__, vap->iv_bss, ether_sprintf(vap->iv_bss->ni_macaddr), … … 343 344 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 344 345 ni->ni_rates = ic->ic_sup_quarter_rates; 345 346 346 (void) ieee80211_sta_join1(ieee80211_ref_node(ni)); 347 // Pass node reference to this function 348 (void) ieee80211_sta_join1(ni); 347 349 } 348 350 EXPORT_SYMBOL(ieee80211_create_ibss); 349 351 … … 370 372 ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr); 371 373 KASSERT(ni != NULL, ("unable to setup inital BSS node")); 372 374 obss = vap->iv_bss; 375 // Caller's reference 373 376 vap->iv_bss = ieee80211_ref_node(ni); 374 377 375 378 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "%s: new bss %p<%s> refcnt %d\n", … … 379 382 if (obss != NULL) { 380 383 copy_bss(ni, obss); 381 384 ni->ni_intval = ic->ic_lintval; 382 ieee80211_free_node(obss); 385 // Caller's reference 386 ieee80211_unref_node(&obss); 383 387 } 384 388 } 385 389 … … 419 423 if ((ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0) 420 424 return 0; 421 425 } else { 422 /* XXX does this mean privacy is supported or required? */ 426 /* This means that the data confidentiality service is required 427 * for all frames exchanged within this BSS. (IEEE802.11 7.3.1.4) 428 */ 423 429 if (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) 424 430 return 0; 425 431 } … … 578 584 vap->iv_state == IEEE80211_S_RUN && ssid_equal(obss, selbs)); 579 585 vap->iv_bss = selbs; 580 586 if (obss != NULL) 581 ieee80211_ free_node(obss);587 ieee80211_unref_node(&obss); 582 588 ic->ic_bsschan = selbs->ni_chan; 583 589 ic->ic_curchan = ic->ic_bsschan; 584 590 ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan); … … 641 647 return 0; 642 648 } 643 649 } else 644 ieee80211_ free_node(ni);650 ieee80211_unref_node(&ni); 645 651 646 652 /* 647 653 * Expand scan state into node's format. … … 681 687 682 688 IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, 683 689 "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(ni->ni_macaddr), 684 ieee80211_node_refcnt(ni) +1);690 ieee80211_node_refcnt(ni) + 1); 685 691 686 692 return ieee80211_sta_join1(ieee80211_ref_node(ni)); 687 693 } … … 695 701 ieee80211_sta_leave(struct ieee80211_node *ni) 696 702 { 697 703 struct ieee80211vap *vap = ni->ni_vap; 698 struct ieee80211com *ic = vap->iv_ic;699 704 700 705 /* WDS/Repeater: Stop software beacon timer for STA */ 701 706 if (vap->iv_opmode == IEEE80211_M_STA && 702 707 vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) { 703 708 del_timer(&vap->iv_swbmiss); 704 709 } 705 706 ic->ic_node_cleanup(ni); 710 707 711 ieee80211_notify_node_leave(ni); 708 712 } 709 713 … … 716 720 struct ieee80211_node_table *nt, const char *name, int inact) 717 721 { 718 722 nt->nt_ic = ic; 719 IEEE80211_NODE_ LOCK_INIT(nt, ic->ic_dev->name);723 IEEE80211_NODE_TABLE_LOCK_INIT(nt, ic->ic_dev->name); 720 724 IEEE80211_SCAN_LOCK_INIT(nt, ic->ic_dev->name); 721 725 TAILQ_INIT(&nt->nt_node); 722 726 nt->nt_name = name; … … 728 732 mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL); 729 733 } 730 734 735 static __inline void _node_table_join(struct ieee80211_node_table *nt, struct ieee80211_node *ni) { 736 IEEE80211_NODE_TABLE_LOCK_ASSERT(ni); 737 IEEE80211_NODE_LOCK_ASSERT(ni); 738 739 ni->ni_table = nt; 740 TAILQ_INSERT_TAIL(&nt->nt_node, ieee80211_ref_node(ni), ni_list); 741 LIST_INSERT_HEAD(&nt->nt_hash[IEEE80211_NODE_HASH(ni->ni_macaddr)], ni, ni_hash); 742 } 743 744 static __inline void _node_table_leave(struct ieee80211_node_table *nt, struct ieee80211_node *ni) { 745 IEEE80211_NODE_TABLE_LOCK_ASSERT(ni); 746 IEEE80211_NODE_LOCK_ASSERT(ni); 747 748 TAILQ_REMOVE(&nt->nt_node, ni, ni_list); 749 LIST_REMOVE(ni, ni_hash); 750 ni->ni_table = NULL; 751 _ieee80211_unref_node(ni); 752 } 753 731 754 static struct ieee80211_node * 732 755 node_alloc(struct ieee80211_node_table *nt, struct ieee80211vap *vap) 733 756 { … … 770 793 IEEE80211_UNLOCK_IRQ(ni->ni_ic); 771 794 } 772 795 } 773 /*774 * Clear AREF flag that marks the authorization refcnt bump775 * has happened. This is probably not needed as the node776 * should always be removed from the table so not found but777 * do it just in case.778 */779 ni->ni_flags &= ~IEEE80211_NODE_AREF;780 796 781 797 /* 782 798 * Drain power save queue and, if needed, clear TIM. … … 814 830 static void 815 831 node_free(struct ieee80211_node *ni) 816 832 { 833 #if 0 834 // We should 'cleanup' and then free'ing should be done automatically on decref 817 835 struct ieee80211com *ic = ni->ni_ic; 818 836 819 837 ic->ic_node_cleanup(ni); 838 #endif 839 820 840 if (ni->ni_wpa_ie != NULL) 821 841 FREE(ni->ni_wpa_ie, M_DEVBUF); 822 842 if (ni->ni_rsn_ie != NULL) … … 864 884 ether_sprintf(macaddr), nt->nt_name, 865 885 ieee80211_node_refcnt(ni)+1); 866 886 887 IEEE80211_NODE_LOCK_INIT(ni, ic->ic_dev->name); 888 ieee80211_node_initref(ni); /* referenced once */ 889 867 890 IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr); 868 891 hash = IEEE80211_NODE_HASH(macaddr); 869 ieee80211_node_initref(ni); /* mark referenced */ 892 870 893 ni->ni_chan = IEEE80211_CHAN_ANYC; 871 894 ni->ni_authmode = IEEE80211_AUTH_OPEN; 872 895 ni->ni_txpower = ic->ic_txpowlimit; /* max power */ 873 ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE);896 874 897 ni->ni_inact_reload = nt->nt_inact_init; 875 898 ni->ni_inact = ni->ni_inact_reload; 899 900 ni->ni_challenge = NULL; 901 ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE); 876 902 ni->ni_ath_defkeyindex = IEEE80211_INVAL_DEFKEY; 877 903 ni->ni_rxkeyoff = 0; 878 IEEE80211_NODE_SAVEQ_INIT(ni, "unknown"); 879 880 IEEE80211_NODE_LOCK_IRQ(nt); 881 ni->ni_vap = vap; 882 ni->ni_ic = ic; 883 ni->ni_table = nt; 884 TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list); 885 LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash); 904 886 905 #define N(a) (sizeof(a)/sizeof(a[0])) 887 906 for (i = 0; i < N(ni->ni_rxfrag); i++) 888 907 ni->ni_rxfrag[i] = NULL; 889 908 #undef N 890 ni->ni_challenge = NULL; 891 IEEE80211_NODE_UNLOCK_IRQ(nt); 909 IEEE80211_NODE_SAVEQ_INIT(ni, "unknown"); 892 910 911 ni->ni_vap = vap; 912 ni->ni_ic = ic; 913 914 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 915 IEEE80211_NODE_LOCK_IRQ(ni); 916 _node_table_join(nt, ni); 917 IEEE80211_NODE_UNLOCK_IRQ(ni); 918 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 919 893 920 WME_UAPSD_NODE_TRIGSEQINIT(ni); 894 921 895 922 return ni; … … 916 943 wds->wds_agingcount = WDS_AGING_COUNT; 917 944 hash = IEEE80211_NODE_HASH(macaddr); 918 945 IEEE80211_ADDR_COPY(wds->wds_macaddr, macaddr); 919 ieee80211_ref_node(ni); /* Reference node */920 wds->wds_ni = ni;921 IEEE80211_NODE_LOCK_IRQ(nt);946 947 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 948 wds->wds_ni = ieee80211_ref_node(ni); 922 949 LIST_INSERT_HEAD(&nt->nt_wds_hash[hash], wds, wds_hash); 923 IEEE80211_NODE_ UNLOCK_IRQ(nt);950 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 924 951 return 0; 925 952 } 926 953 EXPORT_SYMBOL(ieee80211_add_wds_addr); … … 933 960 struct ieee80211_wds_addr *wds; 934 961 935 962 hash = IEEE80211_NODE_HASH(macaddr); 936 IEEE80211_NODE_ LOCK_IRQ(nt);963 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 937 964 LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 938 965 if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) { 939 if (ieee80211_node_dectestref(wds->wds_ni)) { 940 _ieee80211_free_node(wds->wds_ni); 941 LIST_REMOVE(wds, wds_hash); 942 FREE(wds, M_80211_WDS); 943 break; 944 } 966 LIST_REMOVE(wds, wds_hash); 967 FREE(wds, M_80211_WDS); 968 ieee80211_unref_node(&wds->wds_ni); 969 break; 945 970 } 946 971 } 947 IEEE80211_NODE_ UNLOCK_IRQ(nt);972 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 948 973 } 949 974 EXPORT_SYMBOL(ieee80211_remove_wds_addr); 950 975 … … 956 981 int hash; 957 982 struct ieee80211_wds_addr *wds; 958 983 959 IEEE80211_NODE_ LOCK_IRQ(nt);984 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 960 985 for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) { 961 986 LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 962 987 if (wds->wds_ni == ni) { 963 if (ieee80211_node_dectestref(ni)) { 964 _ieee80211_free_node(ni); 965 LIST_REMOVE(wds, wds_hash); 966 FREE(wds, M_80211_WDS); 967 } 988 LIST_REMOVE(wds, wds_hash); 989 FREE(wds, M_80211_WDS); 990 ieee80211_unref_node(&ni); 968 991 } 969 992 } 970 993 } 971 IEEE80211_NODE_ UNLOCK_IRQ(nt);994 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 972 995 } 973 996 EXPORT_SYMBOL(ieee80211_del_wds_node); 974 997 … … 979 1002 int hash; 980 1003 struct ieee80211_wds_addr *wds; 981 1004 982 IEEE80211_NODE_ LOCK_IRQ(nt);1005 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 983 1006 for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) { 984 1007 LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 985 1008 if (wds->wds_agingcount != WDS_AGING_STATIC) { 986 1009 if (!wds->wds_agingcount) { 987 if (ieee80211_node_dectestref(wds->wds_ni)) { 988 _ieee80211_free_node(wds->wds_ni); 989 LIST_REMOVE(wds, wds_hash); 990 FREE(wds, M_80211_WDS); 991 } 1010 LIST_REMOVE(wds, wds_hash); 1011 FREE(wds, M_80211_WDS); 1012 ieee80211_unref_node(&wds->wds_ni); 992 1013 } else 993 1014 wds->wds_agingcount--; 994 1015 } 995 1016 } 996 1017 } 997 IEEE80211_NODE_ UNLOCK_IRQ(nt);1018 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 998 1019 mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL); 999 1020 } 1000 1021 … … 1030 1051 /* XXX optimize away */ 1031 1052 IEEE80211_NODE_SAVEQ_INIT(ni, "unknown"); 1032 1053 1033 ni->ni_table = NULL; /* NB: pedantic */1054 ni->ni_table = NULL; 1034 1055 ni->ni_ic = ic; 1035 1056 #define N(a) (sizeof(a)/sizeof(a[0])) 1036 1057 for (i = 0; i < N(ni->ni_rxfrag); i++) … … 1056 1077 1057 1078 ni = ieee80211_alloc_node(&ic->ic_sta, vap, macaddr); 1058 1079 if (ni != NULL) { 1059 /* 1060 * Inherit from iv_bss. 1061 */ 1080 /* Copy from iv_bss. */ 1062 1081 ni->ni_authmode = vap->iv_bss->ni_authmode; 1063 1082 ni->ni_txpower = vap->iv_bss->ni_txpower; 1064 1083 ni->ni_vlan = vap->iv_bss->ni_vlan; /* XXX?? */ … … 1079 1098 struct ieee80211_node *ni; 1080 1099 struct ieee80211_wds_addr *wds; 1081 1100 int hash; 1082 IEEE80211_NODE_ LOCK_ASSERT(nt);1101 IEEE80211_NODE_TABLE_LOCK_ASSERT(nt); 1083 1102 1084 1103 hash = IEEE80211_NODE_HASH(macaddr); 1085 1104 LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { … … 1106 1125 int hash; 1107 1126 struct ieee80211_wds_addr *wds; 1108 1127 1109 IEEE80211_NODE_ LOCK_ASSERT(nt);1128 IEEE80211_NODE_TABLE_LOCK_ASSERT(nt); 1110 1129 1111 1130 hash = IEEE80211_NODE_HASH(macaddr); 1112 1131 LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) { … … 1144 1163 { 1145 1164 struct ieee80211_node *ni; 1146 1165 1147 IEEE80211_NODE_ LOCK_IRQ(nt);1166 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1148 1167 ni = _ieee80211_find_wds_node(nt, macaddr); 1149 IEEE80211_NODE_ UNLOCK_IRQ(nt);1168 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1150 1169 return ni; 1151 1170 } 1152 1171 EXPORT_SYMBOL(ieee80211_find_wds_node); … … 1161 1180 { 1162 1181 struct ieee80211_node *ni; 1163 1182 1164 IEEE80211_NODE_ LOCK_IRQ(nt);1183 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1165 1184 ni = _ieee80211_find_node(nt, macaddr); 1166 IEEE80211_NODE_ UNLOCK_IRQ(nt);1185 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1167 1186 return ni; 1168 1187 } 1169 1188 #ifdef IEEE80211_DEBUG_REFCNT … … 1291 1310 /* XXX check ic_bss first in station mode */ 1292 1311 /* XXX 4-address frames? */ 1293 1312 nt = &ic->ic_sta; 1294 IEEE80211_NODE_ LOCK_IRQ(nt);1313 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1295 1314 if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/) 1296 1315 ni = _ieee80211_find_node(nt, wh->i_addr1); 1297 1316 else 1298 1317 ni = _ieee80211_find_node(nt, wh->i_addr2); 1299 IEEE80211_NODE_ UNLOCK_IRQ(nt);1318 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1300 1319 1301 1320 return ni; 1302 1321 #undef IS_PSPOLL … … 1333 1352 1334 1353 /* XXX can't hold lock across dup_bss due to recursive locking */ 1335 1354 nt = &vap->iv_ic->ic_sta; 1336 IEEE80211_NODE_ LOCK_IRQ(nt);1355 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1337 1356 ni = _ieee80211_find_node(nt, mac); 1338 IEEE80211_NODE_ UNLOCK_IRQ(nt);1357 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1339 1358 1340 1359 if (ni == NULL) { 1341 1360 if (vap->iv_opmode == IEEE80211_M_IBSS || … … 1380 1399 1381 1400 if (vap->iv_aid_bitmap != NULL) 1382 1401 IEEE80211_AID_CLR(vap, ni->ni_associd); 1383 if (nt != NULL) { 1384 TAILQ_REMOVE(&nt->nt_node, ni, ni_list); 1385 LIST_REMOVE(ni, ni_hash); 1386 } 1402 1387 1403 vap->iv_ic->ic_node_free(ni); 1388 1404 } 1389 1405 1406 1390 1407 void 1391 1408 #ifdef IEEE80211_DEBUG_REFCNT 1392 1409 ieee80211_free_node_debug(struct ieee80211_node *ni, const char *func, int line) … … 1394 1411 ieee80211_free_node(struct ieee80211_node *ni) 1395 1412 #endif 1396 1413 { 1397 struct ieee80211_node_table *nt = ni->ni_table;1398 struct ieee80211com *ic = ni->ni_ic;1399 1400 1414 #ifdef IEEE80211_DEBUG_REFCNT 1401 1415 IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE, 1402 1416 "%s (%s:%u) %p<%s> refcnt %d\n", __func__, func, line, ni, 1403 1417 ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni) - 1); 1404 1418 #endif 1405 /* 1406 * XXX: may need to lock out the following race. we dectestref 1407 * and determine it's time to free the node. between the if() 1408 * and lock, we take an rx intr to receive a frame from this 1409 * node. the rx path (tasklet or intr) bumps this node's 1410 * refcnt and xmits a response frame. eventually that response 1411 * will get reaped, and the reaping code will attempt to use 1412 * the node. the code below will delete the node prior 1413 * to the reap and we could get a crash. 1414 * 1415 * as a stopgap before delving deeper, lock intrs to 1416 * prevent this case. 1417 */ 1418 IEEE80211_LOCK_IRQ(ic); 1419 if (ieee80211_node_dectestref(ni)) { 1420 /* 1421 * Beware; if the node is marked gone then it's already 1422 * been removed from the table and we cannot assume the 1423 * table still exists. Regardless, there's no need to lock 1424 * the table. 1425 */ 1426 if (ni->ni_table != NULL) { 1427 IEEE80211_NODE_LOCK(nt); 1428 _ieee80211_free_node(ni); 1429 IEEE80211_NODE_UNLOCK(nt); 1430 } else 1431 _ieee80211_free_node(ni); 1432 } 1433 IEEE80211_UNLOCK_IRQ(ic); 1419 _ieee80211_free_node(ni); 1434 1420 } 1435 1421 #ifdef IEEE80211_DEBUG_REFCNT 1436 1422 EXPORT_SYMBOL(ieee80211_free_node_debug); … … 1438 1424 EXPORT_SYMBOL(ieee80211_free_node); 1439 1425 #endif 1440 1426 1441 /*1442 * Reclaim a node. If this is the last reference count then1443 * do the normal free work. Otherwise remove it from the node1444 * table and mark it gone by clearing the back-reference.1445 */1446 1427 static void 1447 node_reclaim(struct ieee80211_node_table *nt, struct ieee80211_node *ni)1448 {1449 1450 IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,1451 "%s: remove %p<%s> from %s table, refcnt %d\n",1452 __func__, ni, ether_sprintf(ni->ni_macaddr),1453 nt->nt_name, ieee80211_node_refcnt(ni)-1);1454 if (!ieee80211_node_dectestref(ni)) {1455 /*1456 * Other references are present, just remove the1457 * node from the table so it cannot be found. When1458 * the references are dropped storage will be1459 * reclaimed. This normally only happens for ic_bss.1460 */1461 TAILQ_REMOVE(&nt->nt_node, ni, ni_list);1462 LIST_REMOVE(ni, ni_hash);1463 ni->ni_table = NULL; /* clear reference */1464 } else1465 _ieee80211_free_node(ni);1466 }1467 1468 static void1469 1428 ieee80211_node_table_reset(struct ieee80211_node_table *nt, 1470 1429 struct ieee80211vap *match) 1471 1430 { 1472 1431 struct ieee80211_node *ni, *next; 1473 1432 1474 IEEE80211_NODE_ LOCK_IRQ(nt);1433 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1475 1434 TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, next) { 1476 1435 if (match != NULL && ni->ni_vap != match) 1477 1436 continue; … … 1483 1442 if (vap->iv_aid_bitmap != NULL) 1484 1443 IEEE80211_AID_CLR(vap, ni->ni_associd); 1485 1444 } 1486 node_reclaim(nt,ni);1445 ieee80211_node_leave(ni); 1487 1446 } 1488 IEEE80211_NODE_ UNLOCK_IRQ(nt);1447 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1489 1448 } 1490 1449 1491 1450 static void 1492 1451 ieee80211_node_table_cleanup(struct ieee80211_node_table *nt) 1493 1452 { 1453 struct ieee80211com *ic = nt->nt_ic; 1494 1454 struct ieee80211_node *ni, *next; 1495 1455 1496 1456 TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, next) { … … 1502 1462 if (vap->iv_aid_bitmap != NULL) 1503 1463 IEEE80211_AID_CLR(vap, ni->ni_associd); 1504 1464 } 1505 node_reclaim(nt,ni);1465 ic->ic_node_cleanup(ni); 1506 1466 } 1507 1467 del_timer(&nt->nt_wds_aging_timer); 1508 1468 IEEE80211_SCAN_LOCK_DESTROY(nt); 1509 IEEE80211_NODE_ LOCK_DESTROY(nt);1469 IEEE80211_NODE_TABLE_LOCK_DESTROY(nt); 1510 1470 } 1511 1471 1512 1472 /* … … 1534 1494 IEEE80211_SCAN_LOCK_IRQ(nt); 1535 1495 gen = ++nt->nt_scangen; 1536 1496 restart: 1537 IEEE80211_NODE_ LOCK_IRQ(nt);1497 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1538 1498 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 1539 1499 if (ni->ni_scangen == gen) /* previously handled */ 1540 1500 continue; … … 1598 1558 * ref for us as needed. 1599 1559 */ 1600 1560 ieee80211_ref_node(ni); 1601 IEEE80211_NODE_ UNLOCK_IRQ_EARLY(nt);1561 IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt); 1602 1562 ieee80211_send_nulldata(ni); 1603 1563 /* XXX stat? */ 1604 1564 goto restart; … … 1621 1581 */ 1622 1582 ni->ni_vap->iv_stats.is_node_timeout++; 1623 1583 ieee80211_ref_node(ni); 1624 IEEE80211_NODE_ UNLOCK_IRQ_EARLY(nt);1584 IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt); 1625 1585 if (ni->ni_associd != 0) { 1626 1586 IEEE80211_SEND_MGMT(ni, 1627 1587 IEEE80211_FC0_SUBTYPE_DEAUTH, 1628 1588 IEEE80211_REASON_AUTH_EXPIRE); 1629 1589 } 1630 1590 ieee80211_node_leave(ni); 1631 ieee80211_ free_node(ni);1591 ieee80211_unref_node(&ni); 1632 1592 goto restart; 1633 1593 } 1634 1594 } 1635 IEEE80211_NODE_ UNLOCK_IRQ(nt);1595 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1636 1596 1637 1597 IEEE80211_SCAN_UNLOCK_IRQ(nt); 1638 1598 } … … 1645 1605 { 1646 1606 struct ieee80211com *ic = (struct ieee80211com *) arg; 1647 1607 1648 ieee80211_scan_timeout(ic);1608 eee80211_scan_timeout(ic); 1649 1609 ieee80211_timeout_stations(&ic->ic_sta); 1650 1610 1651 1611 ic->ic_inact.expires = jiffies + IEEE80211_INACT_WAIT * HZ; … … 1661 1621 IEEE80211_SCAN_LOCK_IRQ(nt); 1662 1622 gen = ++nt->nt_scangen; 1663 1623 restart: 1664 IEEE80211_NODE_ LOCK(nt);1624 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1665 1625 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 1666 1626 if (ni->ni_scangen != gen) { 1667 1627 ni->ni_scangen = gen; 1668 1628 (void) ieee80211_ref_node(ni); 1669 IEEE80211_NODE_UNLOCK(nt); 1670 (*f)(arg, ni); 1671 ieee80211_free_node(ni); 1672 goto restart; 1629 break; 1673 1630 } 1674 1631 } 1675 IEEE80211_NODE_UNLOCK(nt); 1632 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1633 (*f)(arg, ni); 1634 ieee80211_unref_node(&ni); 1635 goto restart; 1676 1636 1677 1637 IEEE80211_SCAN_UNLOCK_IRQ(nt); 1678 1638 } … … 1964 1924 IEEE80211_LOCK_IRQ(ic); 1965 1925 if (vap->iv_aid_bitmap != NULL) 1966 1926 IEEE80211_AID_CLR(vap, ni->ni_associd); 1927 1967 1928 ni->ni_associd = 0; 1968 1929 vap->iv_sta_assoc--; 1969 1930 ic->ic_sta_assoc--; 1931 1970 1932 #ifdef ATH_SUPERG_XR 1971 1933 if (ni->ni_vap->iv_flags & IEEE80211_F_XR) 1972 1934 ic->ic_xr_sta_assoc--; … … 1977 1939 if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) 1978 1940 ieee80211_node_leave_11g(ni); 1979 1941 IEEE80211_UNLOCK_IRQ(ic); 1942 1943 /* From this point onwards we can no longer find the node, 1944 * so no more references are generated 1945 */ 1946 ieee80211_remove_wds_addr(nt, ni->ni_macaddr); 1947 ieee80211_del_wds_node(nt, ni); 1948 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 1949 IEEE80211_NODE_LOCK_IRQ(ni); 1950 _node_table_leave(nt, ni); 1951 IEEE80211_NODE_UNLOCK_IRQ(ni); 1952 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1953 1980 1954 /* 1981 1955 * Cleanup station state. In particular clear various 1982 1956 * state that might otherwise be reused if the node … … 1986 1960 ieee80211_sta_leave(ni); 1987 1961 done: 1988 1962 /* 1989 * Remove the node from any table it's recorded in and 1990 * drop the caller's reference. Removal from the table 1991 * is important to ensure the node is not reprocessed 1992 * for inactivity. 1963 * Run a cleanup and then drop the caller's reference 1993 1964 */ 1994 if (nt != NULL) { 1995 IEEE80211_NODE_LOCK_IRQ(nt); 1996 node_reclaim(nt, ni); 1997 IEEE80211_NODE_UNLOCK_IRQ(nt); 1998 ieee80211_remove_wds_addr(nt,ni->ni_macaddr); 1999 ieee80211_del_wds_node(nt,ni); 2000 } else 2001 ieee80211_free_node(ni); 1965 ic->ic_node_cleanup(ni); 1966 ieee80211_unref_node(&ni); 2002 1967 } 2003 1968 EXPORT_SYMBOL(ieee80211_node_leave); 2004 1969 … … 2058 2023 void 2059 2024 ieee80211_node_reset(struct ieee80211_node *ni, struct ieee80211vap *vap) 2060 2025 { 2061 if (ni != NULL) { 2062 struct ieee80211_node_table *nt = ni->ni_table; 2063 if (!nt) 2064 nt = &vap->iv_ic->ic_sta; 2065 IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid); 2066 ni->ni_prev_vap = ni->ni_vap; 2067 ni->ni_vap = vap; 2068 ni->ni_ic = vap->iv_ic; 2069 /* 2070 * if node not found in the node table 2071 * add it to the node table . 2072 */ 2073 if(nt && ieee80211_find_node(nt, ni->ni_macaddr) != ni) { 2074 int hash = IEEE80211_NODE_HASH(ni->ni_macaddr); 2075 IEEE80211_NODE_LOCK_IRQ(nt); 2076 TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list); 2077 LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash); 2078 ni->ni_table = nt; 2079 IEEE80211_NODE_UNLOCK_IRQ(nt); 2080 } 2081 } 2026 IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid); 2027 ni->ni_prev_vap = ni->ni_vap; 2028 ni->ni_vap = vap; 2029 ni->ni_ic = vap->iv_ic; 2082 2030 } -
net80211/ieee80211_node.h
old new 94 94 struct ieee80211_node_table *ni_table; 95 95 TAILQ_ENTRY(ieee80211_node) ni_list; 96 96 LIST_ENTRY(ieee80211_node) ni_hash; 97 atomic_t ni_refcnt; 97 ieee80211_node_lock_t ni_nodelock; /* on node - notably for ref counting */ 98 ieee80211_node_ref_count_t ni_refcnt; 98 99 u_int ni_scangen; /* gen# for timeout scan */ 99 100 u_int8_t ni_authmode; /* authentication algorithm */ 100 101 u_int16_t ni_flags; /* special-purpose state */ … … 186 187 #define WME_UAPSD_NODE_INVALIDSEQ 0xffff 187 188 #define WME_UAPSD_NODE_TRIGSEQINIT(_ni) (memset(&(_ni)->ni_uapsd_trigseq[0], 0xff, sizeof((_ni)->ni_uapsd_trigseq))) 188 189 189 static __inline struct ieee80211_node *190 ieee80211_ref_node(struct ieee80211_node *ni)191 {192 ieee80211_node_incref(ni);193 return ni;194 }195 196 static __inline void197 ieee80211_unref_node(struct ieee80211_node **ni)198 {199 ieee80211_node_decref(*ni);200 *ni = NULL; /* guard against use */201 }202 203 190 void ieee80211_node_attach(struct ieee80211com *); 204 191 void ieee80211_node_detach(struct ieee80211com *); 205 192 void ieee80211_node_vattach(struct ieee80211vap *); … … 243 230 */ 244 231 struct ieee80211_node_table { 245 232 struct ieee80211com *nt_ic; /* back reference */ 246 ieee80211_node_ lock_t nt_nodelock; /* on node table */233 ieee80211_node_table_lock_t nt_nodelock; /* on node table */ 247 234 TAILQ_HEAD(, ieee80211_node) nt_node; /* information of all nodes */ 248 235 ATH_LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE]; 249 236 ATH_LIST_HEAD(, ieee80211_wds_addr) nt_wds_hash[IEEE80211_NODE_HASHSIZE]; … … 280 267 #else 281 268 void ieee80211_free_node(struct ieee80211_node *); 282 269 270 static __inline struct ieee80211_node * 271 ieee80211_ref_node(struct ieee80211_node *ni) 272 { 273 ieee80211_node_incref(ni); 274 return ni; 275 } 276 277 static __inline void 278 ieee80211_unref_node(struct ieee80211_node **pni) 279 { 280 struct ieee80211_node *ni = *pni; 281 IEEE80211_NODE_LOCK_IRQ(ni); 282 _ieee80211_unref_node(ni); 283 IEEE80211_NODE_UNLOCK_IRQ(ni); 284 pni = NULL; /* guard against use */ 285 } 286 287 static __inline void 288 _ieee80211_unref_node(struct ieee80211_node *ni) { 289 if (ieee80211_node_dectestref(ni)) { 290 _ieee80211_free_node(ni); 291 } 292 } 293 283 294 struct ieee80211_node *ieee80211_find_node(struct ieee80211_node_table *, 284 295 const u_int8_t *); 285 296 struct ieee80211_node * ieee80211_find_rxnode(struct ieee80211com *, -
net80211/ieee80211_wireless.c
old new 515 515 ieee80211_ioctl_siwap(struct net_device *dev, struct iw_request_info *info, 516 516 struct sockaddr *ap_addr, char *extra) 517 517 { 518 static const u_int8_t zero_bssid[IEEE80211_ADDR_LEN];519 static const u_int8_t broadcast_bssid[IEEE80211_ADDR_LEN] =520 "\xff\xff\xff\xff\xff\xff";521 518 struct ieee80211vap *vap = dev->priv; 522 519 523 520 /* NB: should not be set when in AP mode */ … … 534 531 * 535 532 * anything else specifies a particular AP. 536 533 */ 537 if (IEEE80211_ADDR_EQ(&ap_addr->sa_data, zero_bssid)) 538 vap->iv_flags &= ~IEEE80211_F_DESBSSID; 539 else { 540 IEEE80211_ADDR_COPY(vap->iv_des_bssid, &ap_addr->sa_data); 541 if (IEEE80211_ADDR_EQ(vap->iv_des_bssid, broadcast_bssid)) 542 vap->iv_flags &= ~IEEE80211_F_DESBSSID; 543 else 534 vap->iv_flags &= ~IEEE80211_F_DESBSSID; 535 if (!IEEE80211_ADDR_NULL(&ap_addr->sa_data)) 536 if (!IEEE80211_ADDR_EQ(vap->iv_des_bssid, (u_int8_t*) "\xff\xff\xff\xff\xff\xff")) 544 537 vap->iv_flags |= IEEE80211_F_DESBSSID; 538 539 IEEE80211_ADDR_COPY(vap->iv_des_bssid, &ap_addr->sa_data); 545 540 if (IS_UP_AUTO(vap)) 546 541 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 547 542 } … … 557 552 if (vap->iv_flags & IEEE80211_F_DESBSSID) 558 553 IEEE80211_ADDR_COPY(&ap_addr->sa_data, vap->iv_des_bssid); 559 554 else { 560 static const u_int8_t zero_bssid[IEEE80211_ADDR_LEN];561 555 if (vap->iv_state == IEEE80211_S_RUN) 562 556 if (vap->iv_opmode != IEEE80211_M_WDS) 563 557 IEEE80211_ADDR_COPY(&ap_addr->sa_data, vap->iv_bss->ni_bssid); 564 558 else 565 559 IEEE80211_ADDR_COPY(&ap_addr->sa_data, vap->wds_mac); 566 560 else 567 IEEE80211_ADDR_COPY(&ap_addr->sa_data, zero_bssid);561 memset(&ap_addr->sa_data, 0, IEEE80211_ADDR_LEN); 568 562 } 569 563 ap_addr->sa_family = ARPHRD_ETHER; 570 564 return 0; -
net80211/ieee80211_input.c
old new 985 985 * not freed by the timer process while we use it. 986 986 * XXX bogus 987 987 */ 988 IEEE80211_NODE_ LOCK_IRQ(ni->ni_table);988 IEEE80211_NODE_TABLE_LOCK_IRQ(ni->ni_table); 989 989 990 990 /* 991 991 * Update the time stamp. As a side effect, it … … 995 995 */ 996 996 ni->ni_rxfragstamp = jiffies; 997 997 998 IEEE80211_NODE_ UNLOCK_IRQ(ni->ni_table);998 IEEE80211_NODE_TABLE_UNLOCK_IRQ(ni->ni_table); 999 999 1000 1000 /* 1001 1001 * Validate that fragment is in order and … … 1307 1307 "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(ni->ni_macaddr), 1308 1308 ieee80211_node_refcnt(ni)); 1309 1309 1310 } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0)1311 (void) ieee80211_ref_node(ni);1310 } 1311 1312 1312 /* 1313 * Mark the node as referenced to reflect that it's 1314 * reference count has been bumped to ensure it remains 1315 * after the transaction completes. 1313 * Mark the node as authenticated 1316 1314 */ 1317 1315 ni->ni_flags |= IEEE80211_NODE_AREF; 1318 1316 … … 1399 1397 { 1400 1398 struct ieee80211vap *vap = ni->ni_vap; 1401 1399 u_int8_t *challenge; 1402 int allocbs , estatus;1400 int allocbs = 0, estatus = 0; 1403 1401 1404 1402 /* 1405 1403 * NB: this can happen as we allow pre-shared key … … 1409 1407 * ordering in which case this check would just be 1410 1408 * for sanity/consistency. 1411 1409 */ 1412 estatus = 0; /* NB: silence compiler */1413 1410 if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { 1414 1411 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 1415 1412 ni->ni_macaddr, "shared key auth", … … 1500 1497 ieee80211_node_refcnt(ni)); 1501 1498 1502 1499 allocbs = 1; 1503 } else {1504 if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0)1505 (void) ieee80211_ref_node(ni);1506 allocbs = 0;1507 1500 } 1508 /* 1509 * Mark the node as referenced to reflect that it's 1510 * reference count has been bumped to ensure it remains 1511 * after the transaction completes. 1512 */ 1513 ni->ni_flags |= IEEE80211_NODE_AREF; 1501 1514 1502 ni->ni_rssi = rssi; 1515 1503 ni->ni_rstamp = rstamp; 1516 1504 ni->ni_last_rx = jiffies; … … 2647 2635 } 2648 2636 if (scan.capinfo & IEEE80211_CAPINFO_IBSS) { 2649 2637 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { 2650 /*2651 * Create a new entry in the neighbor table.2652 */2653 2638 ni = ieee80211_add_neighbor(vap, wh, &scan); 2654 2639 } else { 2655 2640 /* … … 2822 2807 ni = vap->iv_xrvap->iv_bss; 2823 2808 else { 2824 2809 ieee80211_node_leave(ni); 2810 /* This would be a stupid place to add a node to the table 2811 * XR stuff needs work anyway 2812 */ 2825 2813 ieee80211_node_reset(ni, vap->iv_xrvap); 2826 2814 } 2827 2815 vap = vap->iv_xrvap; … … 2834 2822 #endif 2835 2823 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_AUTH, wh->i_addr2, 2836 2824 "recv auth frame with algorithm %d seq %d", algo, seq); 2837 /* 2838 * Consult the ACL policy module if setup. 2839 */ 2825 /* Consult the ACL policy module if setup. */ 2840 2826 if (vap->iv_acl != NULL && 2841 2827 !vap->iv_acl->iac_check(vap, wh->i_addr2)) { 2842 2828 IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL, … … 2869 2855 /* XXX not right */ 2870 2856 ieee80211_send_error(ni, wh->i_addr2, 2871 2857 IEEE80211_FC0_SUBTYPE_AUTH, 2872 (seq +1) | (IEEE80211_STATUS_ALG << 16));2858 (seq + 1) | (IEEE80211_STATUS_ALG << 16)); 2873 2859 } 2874 2860 return; 2875 2861 } -
net80211/ieee80211_linux.h
old new 65 65 66 66 #define IEEE80211_RESCHEDULE schedule 67 67 68 /* Locking */ 69 /* NB: beware, spin_is_locked() is not usefully defined for UP+!PREEMPT 70 * because spinlocks do not exist in this configuration. Instead IRQs 71 * are simply disabled, as this is all that is needed 72 */ 73 68 74 /* 69 75 * Beacon handler locking definitions. 70 76 * Beacon locking … … 87 93 #define IEEE80211_LOCK(_ic) spin_lock(&(_ic)->ic_comlock) 88 94 #define IEEE80211_UNLOCK(_ic) spin_unlock(&(_ic)->ic_comlock) 89 95 90 /* NB: beware, spin_is_locked() is unusable for !SMP */ 91 #if defined(CONFIG_SMP) 96 #if (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)) && defined(spinlock_is_locked) 92 97 #define IEEE80211_LOCK_ASSERT(_ic) \ 93 98 KASSERT(spin_is_locked(&(_ic)->ic_comlock),("ieee80211com not locked!")) 94 99 #else 95 100 #define IEEE80211_LOCK_ASSERT(_ic) 96 101 #endif 97 102 103 98 104 #define IEEE80211_VAPS_LOCK_INIT(_ic, _name) \ 99 105 spin_lock_init(&(_ic)->ic_vapslock) 100 106 #define IEEE80211_VAPS_LOCK_DESTROY(_ic) … … 110 116 } while (0) 111 117 #define IEEE80211_VAPS_UNLOCK_IRQ_EARLY(_ic) spin_unlock_irqrestore(&(_ic)->ic_vapslock, _vaps_lockflags) 112 118 113 114 /* NB: beware, spin_is_locked() is unusable for !SMP */ 115 #if defined(CONFIG_SMP) 119 #if (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)) && defined(spinlock_is_locked) 116 120 #define IEEE80211_VAPS_LOCK_ASSERT(_ic) \ 117 121 KASSERT(spin_is_locked(&(_ic)->ic_vapslock),("ieee80211com_vaps not locked!")) 118 122 #else … … 124 128 * Node locking definitions. 125 129 */ 126 130 typedef spinlock_t ieee80211_node_lock_t; 127 #define IEEE80211_NODE_LOCK_INIT(_nt, _name) spin_lock_init(&(_nt)->nt_nodelock) 128 #define IEEE80211_NODE_LOCK_DESTROY(_nt) 129 #define IEEE80211_NODE_LOCK(_nt) spin_lock(&(_nt)->nt_nodelock) 130 #define IEEE80211_NODE_UNLOCK(_nt) spin_unlock(&(_nt)->nt_nodelock) 131 #define IEEE80211_NODE_LOCK_BH(_nt) spin_lock_bh(&(_nt)->nt_nodelock) 132 #define IEEE80211_NODE_UNLOCK_BH(_nt) spin_unlock_bh(&(_nt)->nt_nodelock) 133 #define IEEE80211_NODE_LOCK_IRQ(_nt) do { \ 131 #define IEEE80211_NODE_LOCK_INIT(_ni, _name) spin_lock_init(&(_ni)->ni_nodelock) 132 #define IEEE80211_NODE_LOCK_DESTROY(_ni) 133 #if 0 /* We should always be contesting in the same contexts */ 134 #define IEEE80211_NODE_LOCK(_ni) spin_lock(&(_ni)->ni_nodelock) 135 #define IEEE80211_NODE_UNLOCK(_ni) spin_unlock(&(_ni)->ni_nodelock) 136 #define IEEE80211_NODE_LOCK_BH(_ni) spin_lock_bh(&(_ni)->ni_nodelock) 137 #define IEEE80211_NODE_UNLOCK_BH(_ni) spin_unlock_bh(&(_ni)->ni_nodelock) 138 #endif 139 #define IEEE80211_NODE_LOCK_IRQ(_ni) do { \ 134 140 unsigned long __node_lockflags; \ 141 spin_lock_irqsave(&(_ni)->ni_nodelock, __node_lockflags); 142 #define IEEE80211_NODE_UNLOCK_IRQ(_ni) \ 143 spin_unlock_irqrestore(&(_ni)->ni_nodelock, __node_lockflags); \ 144 } while(0) 145 #define IEEE80211_NODE_UNLOCK_IRQ_EARLY(_ni) \ 146 spin_unlock_irqrestore(&(_ni)->ni_nodelock, __node_lockflags); 147 148 #if (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)) && defined(spinlock_is_locked) 149 #define IEEE80211_NODE_LOCK_ASSERT(_nt) \ 150 KASSERT(spinlock_is_locked(&(_ni)->ni_nodelock), \ 151 ("802.11 node not locked!")) 152 #else 153 #define IEEE80211_NODE_LOCK_ASSERT(_ni) 154 #endif 155 156 /* 157 * Node table locking definitions. 158 */ 159 typedef spinlock_t ieee80211_node_table_lock_t; 160 #define IEEE80211_NODE_TABLE_LOCK_INIT(_nt, _name) spin_lock_init(&(_nt)->nt_nodelock) 161 #define IEEE80211_NODE_TABLE_LOCK_DESTROY(_nt) 162 #if 0 /* We should always be contesting in the same contexts */ 163 #define IEEE80211_NODE_TABLE_LOCK(_nt) spin_lock(&(_nt)->nt_nodelock) 164 #define IEEE80211_NODE_TABLE_UNLOCK(_nt) spin_unlock(&(_nt)->nt_nodelock) 165 #define IEEE80211_NODE_TABLE_LOCK_BH(_nt) spin_lock_bh(&(_nt)->nt_nodelock) 166 #define IEEE80211_NODE_TABLE_UNLOCK_BH(_nt) spin_unlock_bh(&(_nt)->nt_nodelock) 167 #endif 168 #define IEEE80211_NODE_TABLE_LOCK_IRQ(_nt) do { \ 169 unsigned long __node_lockflags; \ 135 170 spin_lock_irqsave(&(_nt)->nt_nodelock, __node_lockflags); 136 #define IEEE80211_NODE_ UNLOCK_IRQ(_nt) \171 #define IEEE80211_NODE_TABLE_UNLOCK_IRQ(_nt) \ 137 172 spin_unlock_irqrestore(&(_nt)->nt_nodelock, __node_lockflags); \ 138 173 } while(0) 139 #define IEEE80211_NODE_ UNLOCK_IRQ_EARLY(_nt) \174 #define IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(_nt) \ 140 175 spin_unlock_irqrestore(&(_nt)->nt_nodelock, __node_lockflags); 141 176 142 /* NB: beware, *_is_locked() are bogusly defined for UP+!PREEMPT */143 177 #if (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)) && defined(spinlock_is_locked) 144 #define IEEE80211_NODE_ LOCK_ASSERT(_nt) \178 #define IEEE80211_NODE_TABLE_LOCK_ASSERT(_nt) \ 145 179 KASSERT(spinlock_is_locked(&(_nt)->nt_nodelock), \ 146 180 ("802.11 node table not locked!")) 147 181 #else 148 #define IEEE80211_NODE_ LOCK_ASSERT(_nt)182 #define IEEE80211_NODE_TABLE_LOCK_ASSERT(_nt) 149 183 #endif 150 184 151 185 /* … … 165 199 #define IEEE80211_SCAN_UNLOCK_IRQ_EARLY(_nt) \ 166 200 spin_unlock_irqrestore(&(_nt)->nt_scanlock, __scan_lockflags); 167 201 168 /* NB: beware, spin_is_locked() is unusable for !SMP */ 169 #if defined(CONFIG_SMP) 202 #if (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)) && defined(spinlock_is_locked) 170 203 #define IEEE80211_SCAN_LOCK_ASSERT(_nt) \ 171 204 KASSERT(spin_is_locked(&(_nt)->nt_scanlock), ("scangen not locked!")) 172 205 #else … … 184 217 #define ACL_LOCK_BH(_as) spin_lock_bh(&(_as)->as_lock) 185 218 #define ACL_UNLOCK_BH(_as) spin_unlock_bh(&(_as)->as_lock) 186 219 187 /* NB: beware, spin_is_locked() is unusable for !SMP */ 188 #if defined(CONFIG_SMP) 220 #if (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)) && defined(spinlock_is_locked) 189 221 #define ACL_LOCK_ASSERT(_as) \ 190 222 KASSERT(spin_is_locked(&(_as)->as_lock), ("ACL not locked!")) 191 223 #else … … 295 327 * is the last reference, otherwise 0 296 328 * ieee80211_node_refcnt reference count for printing (only) 297 329 */ 330 typedef atomic_t ieee80211_node_ref_count_t; 298 331 #define ieee80211_node_initref(_ni) atomic_set(&(_ni)->ni_refcnt, 1) 299 332 #define ieee80211_node_incref(_ni) atomic_inc(&(_ni)->ni_refcnt) 300 333 #define ieee80211_node_decref(_ni) atomic_dec(&(_ni)->ni_refcnt) … … 375 408 /* msecs_to_jiffies appeared in 2.6.7 and 2.4.29 */ 376 409 #include <linux/delay.h> 377 410 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \ 378 LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) || \379 LINUX_VERSION_CODE < KERNEL_VERSION(2,4,29)411 LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) || \ 412 LINUX_VERSION_CODE < KERNEL_VERSION(2,4,29) 380 413 381 414 /* The following definitions and inline functions are 382 415 * copied from the kernel src, include/linux/jiffies.h */ -
ath/if_ath.c
old new 2971 2971 2972 2972 /* 2973 2973 * Allocate tx/rx key slots for TKIP. We allocate two slots for 2974 * each key, one for dec rypt/encrypt and the other for the MIC.2974 * each key, one for decypt/encrypt and the other for the MIC. 2975 2975 */ 2976 2976 static u_int16_t 2977 2977 key_alloc_2pair(struct ath_softc *sc) … … 4713 4713 an->an_uapsd_overflowqdepth--; 4714 4714 } 4715 4715 4716 // Clean up node-specific rate things - this currently appears to always be a no-op 4717 ath_rate_node_cleanup(sc, ATH_NODE(ni)); 4718 4716 4719 ATH_NODE_UAPSD_LOCK_IRQ(an); 4717 4720 sc->sc_node_cleanup(ni); 4718 4721 ATH_NODE_UAPSD_UNLOCK_IRQ(an); … … 4723 4726 { 4724 4727 struct ath_softc *sc = ni->ni_ic->ic_dev->priv; 4725 4728 4726 ath_rate_node_cleanup(sc, ATH_NODE(ni));4727 4729 sc->sc_node_free(ni); 4728 4730 #ifdef ATH_SUPERG_XR 4729 4731 ath_grppoll_period_update(sc);
