Ticket #907: madwifi-refcnt.diff

File madwifi-refcnt.diff, 35.7 kB (added by mentor, 6 years ago)
  • net80211/ieee80211_crypto.c

    old new  
    609609 
    610610/* 
    611611 * Validate and strip privacy headers (and trailer) for a 
    612  * received frame that has the WEP/Privacy bit set. 
     612 * received frame that has the Protected Frame bit set. 
    613613 */ 
    614614struct ieee80211_key * 
    615615ieee80211_crypto_decap(struct ieee80211_node *ni, struct sk_buff *skb, int hdrlen) 
  • net80211/ieee80211_node.c

    old new  
    7272static u_int8_t node_getrssi(const struct ieee80211_node *); 
    7373 
    7474static void _ieee80211_free_node(struct ieee80211_node *); 
    75 static void node_reclaim(struct ieee80211_node_table *, struct ieee80211_node*); 
    7675 
     76static void _node_table_leave(struct ieee80211_node_table *, struct ieee80211_node *); 
     77static void _node_table_join(struct ieee80211_node_table *, struct ieee80211_node *); 
     78 
    7779static void ieee80211_node_timeout(unsigned long); 
    7880 
    7981static void ieee80211_node_table_init(struct ieee80211com *, 
     
    192194 
    193195        ieee80211_node_table_reset(&ic->ic_sta, vap); 
    194196        if (vap->iv_bss != NULL) { 
    195                 ieee80211_free_node(vap->iv_bss); 
    196                 vap->iv_bss = NULL; 
     197                ieee80211_unref_node(&vap->iv_bss); 
    197198        } 
    198199        if (vap->iv_aid_bitmap != NULL) { 
    199200                FREE(vap->iv_aid_bitmap, M_DEVBUF); 
     
    261262                "%s: creating ibss on channel %u\n", __func__, 
    262263                ieee80211_chan2ieee(ic, chan)); 
    263264 
    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         */ 
    265268        ni = ieee80211_find_node(&ic->ic_sta, vap->iv_myaddr); 
    266269        if (ni == NULL) { 
    267270                ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr); 
     
    270273                        return; 
    271274                } 
    272275        } 
    273         else 
    274                 ieee80211_free_node(ni); 
    275276 
    276277        IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "%s: %p<%s> refcnt %d\n", 
    277278                __func__, vap->iv_bss, ether_sprintf(vap->iv_bss->ni_macaddr), 
     
    343344        else if (IEEE80211_IS_CHAN_QUARTER(chan)) 
    344345                ni->ni_rates = ic->ic_sup_quarter_rates; 
    345346 
    346         (void) ieee80211_sta_join1(ieee80211_ref_node(ni)); 
     347        // Pass node reference to this function 
     348        (void) ieee80211_sta_join1(ni); 
    347349} 
    348350EXPORT_SYMBOL(ieee80211_create_ibss); 
    349351 
     
    370372        ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr); 
    371373        KASSERT(ni != NULL, ("unable to setup inital BSS node")); 
    372374        obss = vap->iv_bss; 
     375        // Caller's reference 
    373376        vap->iv_bss = ieee80211_ref_node(ni); 
    374377 
    375378        IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "%s: new bss %p<%s> refcnt %d\n", 
     
    379382        if (obss != NULL) { 
    380383                copy_bss(ni, obss); 
    381384                ni->ni_intval = ic->ic_lintval; 
    382                 ieee80211_free_node(obss); 
     385                // Caller's reference 
     386                ieee80211_unref_node(&obss); 
    383387        } 
    384388} 
    385389 
     
    419423                if ((ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0) 
    420424                        return 0; 
    421425        } 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                 */ 
    423429                if (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) 
    424430                        return 0; 
    425431        } 
     
    578584                vap->iv_state == IEEE80211_S_RUN && ssid_equal(obss, selbs)); 
    579585        vap->iv_bss = selbs; 
    580586        if (obss != NULL) 
    581                 ieee80211_free_node(obss); 
     587                ieee80211_unref_node(&obss); 
    582588        ic->ic_bsschan = selbs->ni_chan; 
    583589        ic->ic_curchan = ic->ic_bsschan; 
    584590        ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan); 
     
    641647                        return 0; 
    642648                } 
    643649        } else 
    644                 ieee80211_free_node(ni); 
     650                ieee80211_unref_node(&ni); 
    645651 
    646652        /* 
    647653         * Expand scan state into node's format. 
     
    681687 
    682688        IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,  
    683689        "%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); 
    685691 
    686692        return ieee80211_sta_join1(ieee80211_ref_node(ni)); 
    687693} 
     
    695701ieee80211_sta_leave(struct ieee80211_node *ni) 
    696702{ 
    697703        struct ieee80211vap *vap = ni->ni_vap; 
    698         struct ieee80211com *ic = vap->iv_ic; 
    699704 
    700705        /* WDS/Repeater: Stop software beacon timer for STA */ 
    701706        if (vap->iv_opmode == IEEE80211_M_STA && 
    702707            vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) { 
    703708                del_timer(&vap->iv_swbmiss); 
    704709        } 
    705  
    706         ic->ic_node_cleanup(ni); 
     710         
    707711        ieee80211_notify_node_leave(ni); 
    708712} 
    709713 
     
    716720        struct ieee80211_node_table *nt,        const char *name, int inact) 
    717721{ 
    718722        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); 
    720724        IEEE80211_SCAN_LOCK_INIT(nt, ic->ic_dev->name); 
    721725        TAILQ_INIT(&nt->nt_node); 
    722726        nt->nt_name = name; 
     
    728732        mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL); 
    729733} 
    730734 
     735static __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 
     744static __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 
    731754static struct ieee80211_node * 
    732755node_alloc(struct ieee80211_node_table *nt, struct ieee80211vap *vap) 
    733756{ 
     
    770793                        IEEE80211_UNLOCK_IRQ(ni->ni_ic); 
    771794                } 
    772795        } 
    773         /* 
    774          * Clear AREF flag that marks the authorization refcnt bump 
    775          * has happened.  This is probably not needed as the node 
    776          * should always be removed from the table so not found but 
    777          * do it just in case. 
    778          */ 
    779         ni->ni_flags &= ~IEEE80211_NODE_AREF; 
    780796 
    781797        /* 
    782798         * Drain power save queue and, if needed, clear TIM. 
     
    814830static void 
    815831node_free(struct ieee80211_node *ni) 
    816832{ 
     833#if 0 
     834        // We should 'cleanup' and then free'ing should be done automatically on decref 
    817835        struct ieee80211com *ic = ni->ni_ic; 
    818836 
    819837        ic->ic_node_cleanup(ni); 
     838#endif  
     839 
    820840        if (ni->ni_wpa_ie != NULL) 
    821841                FREE(ni->ni_wpa_ie, M_DEVBUF); 
    822842        if (ni->ni_rsn_ie != NULL) 
     
    864884                ether_sprintf(macaddr), nt->nt_name, 
    865885                ieee80211_node_refcnt(ni)+1); 
    866886 
     887        IEEE80211_NODE_LOCK_INIT(ni, ic->ic_dev->name); 
     888        ieee80211_node_initref(ni);             /* referenced once */ 
     889         
    867890        IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr); 
    868891        hash = IEEE80211_NODE_HASH(macaddr); 
    869         ieee80211_node_initref(ni);             /* mark referenced */ 
     892 
    870893        ni->ni_chan = IEEE80211_CHAN_ANYC; 
    871894        ni->ni_authmode = IEEE80211_AUTH_OPEN; 
    872895        ni->ni_txpower = ic->ic_txpowlimit;     /* max power */ 
    873         ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE); 
     896         
    874897        ni->ni_inact_reload = nt->nt_inact_init; 
    875898        ni->ni_inact = ni->ni_inact_reload; 
     899         
     900        ni->ni_challenge = NULL; 
     901        ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE); 
    876902        ni->ni_ath_defkeyindex = IEEE80211_INVAL_DEFKEY; 
    877903        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         
    886905#define N(a)    (sizeof(a)/sizeof(a[0])) 
    887906        for (i = 0; i < N(ni->ni_rxfrag); i++) 
    888907                ni->ni_rxfrag[i] = NULL; 
    889908#undef N 
    890         ni->ni_challenge = NULL; 
    891         IEEE80211_NODE_UNLOCK_IRQ(nt); 
     909        IEEE80211_NODE_SAVEQ_INIT(ni, "unknown"); 
    892910 
     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 
    893920        WME_UAPSD_NODE_TRIGSEQINIT(ni); 
    894921 
    895922        return ni; 
     
    916943                wds->wds_agingcount = WDS_AGING_COUNT; 
    917944        hash = IEEE80211_NODE_HASH(macaddr); 
    918945        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); 
    922949        LIST_INSERT_HEAD(&nt->nt_wds_hash[hash], wds, wds_hash); 
    923         IEEE80211_NODE_UNLOCK_IRQ(nt); 
     950        IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 
    924951        return 0; 
    925952} 
    926953EXPORT_SYMBOL(ieee80211_add_wds_addr); 
     
    933960        struct ieee80211_wds_addr *wds; 
    934961 
    935962        hash = IEEE80211_NODE_HASH(macaddr); 
    936         IEEE80211_NODE_LOCK_IRQ(nt); 
     963        IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 
    937964        LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 
    938965                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; 
    945970                } 
    946971        } 
    947         IEEE80211_NODE_UNLOCK_IRQ(nt); 
     972        IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 
    948973} 
    949974EXPORT_SYMBOL(ieee80211_remove_wds_addr); 
    950975 
     
    956981        int hash; 
    957982        struct ieee80211_wds_addr *wds; 
    958983 
    959         IEEE80211_NODE_LOCK_IRQ(nt); 
     984        IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 
    960985        for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) { 
    961986                LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 
    962987                        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); 
    968991                        } 
    969992                } 
    970993        } 
    971         IEEE80211_NODE_UNLOCK_IRQ(nt); 
     994        IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 
    972995} 
    973996EXPORT_SYMBOL(ieee80211_del_wds_node); 
    974997 
     
    9791002        int hash; 
    9801003        struct ieee80211_wds_addr *wds; 
    9811004 
    982         IEEE80211_NODE_LOCK_IRQ(nt); 
     1005        IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 
    9831006        for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) { 
    9841007                LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 
    9851008                        if (wds->wds_agingcount != WDS_AGING_STATIC) { 
    9861009                                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);   
    9921013                                } else 
    9931014                                        wds->wds_agingcount--; 
    9941015                        } 
    9951016                } 
    9961017        } 
    997         IEEE80211_NODE_UNLOCK_IRQ(nt); 
     1018        IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 
    9981019        mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL); 
    9991020} 
    10001021 
     
    10301051                /* XXX optimize away */ 
    10311052                IEEE80211_NODE_SAVEQ_INIT(ni, "unknown"); 
    10321053 
    1033                 ni->ni_table = NULL;           /* NB: pedantic */ 
     1054                ni->ni_table = NULL; 
    10341055                ni->ni_ic = ic; 
    10351056#define N(a)    (sizeof(a)/sizeof(a[0])) 
    10361057                for (i = 0; i < N(ni->ni_rxfrag); i++) 
     
    10561077 
    10571078        ni = ieee80211_alloc_node(&ic->ic_sta, vap, macaddr); 
    10581079        if (ni != NULL) { 
    1059                 /* 
    1060                  * Inherit from iv_bss. 
    1061                  */ 
     1080                /* Copy from iv_bss. */ 
    10621081                ni->ni_authmode = vap->iv_bss->ni_authmode; 
    10631082                ni->ni_txpower = vap->iv_bss->ni_txpower; 
    10641083                ni->ni_vlan = vap->iv_bss->ni_vlan;     /* XXX?? */ 
     
    10791098        struct ieee80211_node *ni; 
    10801099        struct ieee80211_wds_addr *wds; 
    10811100        int hash; 
    1082         IEEE80211_NODE_LOCK_ASSERT(nt); 
     1101        IEEE80211_NODE_TABLE_LOCK_ASSERT(nt); 
    10831102 
    10841103        hash = IEEE80211_NODE_HASH(macaddr); 
    10851104        LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { 
     
    11061125        int hash; 
    11071126        struct ieee80211_wds_addr *wds; 
    11081127 
    1109         IEEE80211_NODE_LOCK_ASSERT(nt); 
     1128        IEEE80211_NODE_TABLE_LOCK_ASSERT(nt); 
    11101129 
    11111130        hash = IEEE80211_NODE_HASH(macaddr); 
    11121131        LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) { 
     
    11441163{ 
    11451164        struct ieee80211_node *ni; 
    11461165 
    1147         IEEE80211_NODE_LOCK_IRQ(nt); 
     1166        IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 
    11481167        ni = _ieee80211_find_wds_node(nt, macaddr); 
    1149         IEEE80211_NODE_UNLOCK_IRQ(nt); 
     1168        IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 
    11501169        return ni; 
    11511170} 
    11521171EXPORT_SYMBOL(ieee80211_find_wds_node); 
     
    11611180{ 
    11621181        struct ieee80211_node *ni; 
    11631182 
    1164         IEEE80211_NODE_LOCK_IRQ(nt); 
     1183        IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 
    11651184        ni = _ieee80211_find_node(nt, macaddr); 
    1166         IEEE80211_NODE_UNLOCK_IRQ(nt); 
     1185        IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 
    11671186        return ni; 
    11681187} 
    11691188#ifdef IEEE80211_DEBUG_REFCNT 
     
    12911310        /* XXX check ic_bss first in station mode */ 
    12921311        /* XXX 4-address frames? */ 
    12931312        nt = &ic->ic_sta; 
    1294         IEEE80211_NODE_LOCK_IRQ(nt); 
     1313        IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 
    12951314        if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/) 
    12961315                ni = _ieee80211_find_node(nt, wh->i_addr1); 
    12971316        else 
    12981317                ni = _ieee80211_find_node(nt, wh->i_addr2); 
    1299         IEEE80211_NODE_UNLOCK_IRQ(nt); 
     1318        IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 
    13001319 
    13011320        return ni; 
    13021321#undef IS_PSPOLL 
     
    13331352 
    13341353        /* XXX can't hold lock across dup_bss due to recursive locking */ 
    13351354        nt = &vap->iv_ic->ic_sta; 
    1336         IEEE80211_NODE_LOCK_IRQ(nt); 
     1355        IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 
    13371356        ni = _ieee80211_find_node(nt, mac); 
    1338         IEEE80211_NODE_UNLOCK_IRQ(nt); 
     1357        IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 
    13391358 
    13401359        if (ni == NULL) { 
    13411360                if (vap->iv_opmode == IEEE80211_M_IBSS || 
     
    13801399 
    13811400        if (vap->iv_aid_bitmap != NULL) 
    13821401                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 
    13871403        vap->iv_ic->ic_node_free(ni); 
    13881404} 
    13891405 
     1406 
    13901407void 
    13911408#ifdef IEEE80211_DEBUG_REFCNT 
    13921409ieee80211_free_node_debug(struct ieee80211_node *ni, const char *func, int line) 
     
    13941411ieee80211_free_node(struct ieee80211_node *ni) 
    13951412#endif 
    13961413{ 
    1397         struct ieee80211_node_table *nt = ni->ni_table; 
    1398         struct ieee80211com *ic = ni->ni_ic; 
    1399  
    14001414#ifdef IEEE80211_DEBUG_REFCNT 
    14011415        IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE, 
    14021416                "%s (%s:%u) %p<%s> refcnt %d\n", __func__, func, line, ni, 
    14031417                 ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni) - 1); 
    14041418#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); 
    14341420} 
    14351421#ifdef IEEE80211_DEBUG_REFCNT 
    14361422EXPORT_SYMBOL(ieee80211_free_node_debug); 
     
    14381424EXPORT_SYMBOL(ieee80211_free_node); 
    14391425#endif 
    14401426 
    1441 /* 
    1442  * Reclaim a node.  If this is the last reference count then 
    1443  * do the normal free work.  Otherwise remove it from the node 
    1444  * table and mark it gone by clearing the back-reference. 
    1445  */ 
    14461427static 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 the 
    1457                  * node from the table so it cannot be found.  When 
    1458                  * the references are dropped storage will be 
    1459                  * 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         } else 
    1465                 _ieee80211_free_node(ni); 
    1466 } 
    1467  
    1468 static void 
    14691428ieee80211_node_table_reset(struct ieee80211_node_table *nt, 
    14701429        struct ieee80211vap *match) 
    14711430{ 
    14721431        struct ieee80211_node *ni, *next; 
    14731432 
    1474         IEEE80211_NODE_LOCK_IRQ(nt); 
     1433        IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 
    14751434        TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, next) { 
    14761435                if (match != NULL && ni->ni_vap != match) 
    14771436                        continue; 
     
    14831442                        if (vap->iv_aid_bitmap != NULL) 
    14841443                                IEEE80211_AID_CLR(vap, ni->ni_associd); 
    14851444                } 
    1486                 node_reclaim(nt, ni); 
     1445                ieee80211_node_leave(ni); 
    14871446        } 
    1488         IEEE80211_NODE_UNLOCK_IRQ(nt); 
     1447        IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 
    14891448} 
    14901449 
    14911450static void 
    14921451ieee80211_node_table_cleanup(struct ieee80211_node_table *nt) 
    14931452{ 
     1453        struct ieee80211com *ic = nt->nt_ic; 
    14941454        struct ieee80211_node *ni, *next; 
    14951455 
    14961456        TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, next) { 
     
    15021462                        if (vap->iv_aid_bitmap != NULL) 
    15031463                                IEEE80211_AID_CLR(vap, ni->ni_associd); 
    15041464                } 
    1505                 node_reclaim(nt, ni); 
     1465                ic->ic_node_cleanup(ni); 
    15061466        } 
    15071467        del_timer(&nt->nt_wds_aging_timer); 
    15081468        IEEE80211_SCAN_LOCK_DESTROY(nt); 
    1509         IEEE80211_NODE_LOCK_DESTROY(nt); 
     1469        IEEE80211_NODE_TABLE_LOCK_DESTROY(nt); 
    15101470} 
    15111471 
    15121472/* 
     
    15341494        IEEE80211_SCAN_LOCK_IRQ(nt);  
    15351495        gen = ++nt->nt_scangen; 
    15361496restart: 
    1537         IEEE80211_NODE_LOCK_IRQ(nt); 
     1497        IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 
    15381498        TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 
    15391499                if (ni->ni_scangen == gen)      /* previously handled */ 
    15401500                        continue; 
     
    15981558                                 * ref for us as needed. 
    15991559                                 */ 
    16001560                                ieee80211_ref_node(ni); 
    1601                                 IEEE80211_NODE_UNLOCK_IRQ_EARLY(nt); 
     1561                                IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt); 
    16021562                                ieee80211_send_nulldata(ni); 
    16031563                                /* XXX stat? */ 
    16041564                                goto restart; 
     
    16211581                         */ 
    16221582                        ni->ni_vap->iv_stats.is_node_timeout++; 
    16231583                        ieee80211_ref_node(ni); 
    1624                         IEEE80211_NODE_UNLOCK_IRQ_EARLY(nt); 
     1584                        IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt); 
    16251585                        if (ni->ni_associd != 0) { 
    16261586                                IEEE80211_SEND_MGMT(ni, 
    16271587                                        IEEE80211_FC0_SUBTYPE_DEAUTH, 
    16281588                                        IEEE80211_REASON_AUTH_EXPIRE); 
    16291589                        } 
    16301590                        ieee80211_node_leave(ni); 
    1631                         ieee80211_free_node(ni); 
     1591                        ieee80211_unref_node(&ni); 
    16321592                        goto restart; 
    16331593                } 
    16341594        } 
    1635         IEEE80211_NODE_UNLOCK_IRQ(nt); 
     1595        IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 
    16361596 
    16371597        IEEE80211_SCAN_UNLOCK_IRQ(nt); 
    16381598} 
     
    16451605{ 
    16461606        struct ieee80211com *ic = (struct ieee80211com *) arg; 
    16471607 
    1648         ieee80211_scan_timeout(ic); 
     1608        eee80211_scan_timeout(ic); 
    16491609        ieee80211_timeout_stations(&ic->ic_sta); 
    16501610 
    16511611        ic->ic_inact.expires = jiffies + IEEE80211_INACT_WAIT * HZ; 
     
    16611621        IEEE80211_SCAN_LOCK_IRQ(nt); 
    16621622        gen = ++nt->nt_scangen; 
    16631623restart: 
    1664         IEEE80211_NODE_LOCK(nt); 
     1624        IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 
    16651625        TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 
    16661626                if (ni->ni_scangen != gen) { 
    16671627                        ni->ni_scangen = gen; 
    16681628                        (void) ieee80211_ref_node(ni); 
    1669                         IEEE80211_NODE_UNLOCK(nt); 
    1670                         (*f)(arg, ni); 
    1671                         ieee80211_free_node(ni); 
    1672                         goto restart; 
     1629                        break; 
    16731630                } 
    16741631        } 
    1675         IEEE80211_NODE_UNLOCK(nt); 
     1632        IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 
     1633        (*f)(arg, ni); 
     1634        ieee80211_unref_node(&ni); 
     1635        goto restart; 
    16761636 
    16771637        IEEE80211_SCAN_UNLOCK_IRQ(nt); 
    16781638} 
     
    19641924        IEEE80211_LOCK_IRQ(ic); 
    19651925        if (vap->iv_aid_bitmap != NULL) 
    19661926                IEEE80211_AID_CLR(vap, ni->ni_associd); 
     1927 
    19671928        ni->ni_associd = 0; 
    19681929        vap->iv_sta_assoc--; 
    19691930        ic->ic_sta_assoc--; 
     1931 
    19701932#ifdef ATH_SUPERG_XR 
    19711933        if (ni->ni_vap->iv_flags & IEEE80211_F_XR) 
    19721934                ic->ic_xr_sta_assoc--; 
     
    19771939        if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) 
    19781940                ieee80211_node_leave_11g(ni); 
    19791941        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 
    19801954        /* 
    19811955         * Cleanup station state.  In particular clear various 
    19821956         * state that might otherwise be reused if the node 
     
    19861960        ieee80211_sta_leave(ni); 
    19871961done: 
    19881962        /* 
    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 
    19931964         */ 
    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); 
    20021967} 
    20031968EXPORT_SYMBOL(ieee80211_node_leave); 
    20041969 
     
    20582023void 
    20592024ieee80211_node_reset(struct ieee80211_node *ni, struct ieee80211vap *vap) 
    20602025{ 
    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; 
    20822030} 
  • net80211/ieee80211_node.h

    old new  
    9494        struct ieee80211_node_table *ni_table; 
    9595        TAILQ_ENTRY(ieee80211_node) ni_list; 
    9696        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; 
    9899        u_int ni_scangen;                       /* gen# for timeout scan */ 
    99100        u_int8_t ni_authmode;                   /* authentication algorithm */ 
    100101        u_int16_t ni_flags;                     /* special-purpose state */ 
     
    186187#define WME_UAPSD_NODE_INVALIDSEQ       0xffff 
    187188#define WME_UAPSD_NODE_TRIGSEQINIT(_ni) (memset(&(_ni)->ni_uapsd_trigseq[0], 0xff, sizeof((_ni)->ni_uapsd_trigseq))) 
    188189 
    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 void 
    197 ieee80211_unref_node(struct ieee80211_node **ni) 
    198 { 
    199         ieee80211_node_decref(*ni); 
    200         *ni = NULL;                     /* guard against use */ 
    201 } 
    202  
    203190void ieee80211_node_attach(struct ieee80211com *); 
    204191void ieee80211_node_detach(struct ieee80211com *); 
    205192void ieee80211_node_vattach(struct ieee80211vap *); 
     
    243230 */ 
    244231struct ieee80211_node_table { 
    245232        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 */ 
    247234        TAILQ_HEAD(, ieee80211_node) nt_node;   /* information of all nodes */ 
    248235        ATH_LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE]; 
    249236        ATH_LIST_HEAD(, ieee80211_wds_addr) nt_wds_hash[IEEE80211_NODE_HASHSIZE]; 
     
    280267#else 
    281268void ieee80211_free_node(struct ieee80211_node *); 
    282269 
     270static __inline struct ieee80211_node * 
     271ieee80211_ref_node(struct ieee80211_node *ni) 
     272{ 
     273        ieee80211_node_incref(ni); 
     274        return ni; 
     275} 
     276 
     277static __inline void 
     278ieee80211_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 
     287static __inline void 
     288_ieee80211_unref_node(struct ieee80211_node *ni) { 
     289        if (ieee80211_node_dectestref(ni)) { 
     290                _ieee80211_free_node(ni); 
     291        } 
     292} 
     293 
    283294struct ieee80211_node *ieee80211_find_node(struct ieee80211_node_table *, 
    284295        const u_int8_t *); 
    285296struct ieee80211_node * ieee80211_find_rxnode(struct ieee80211com *, 
  • net80211/ieee80211_wireless.c

    old new  
    515515ieee80211_ioctl_siwap(struct net_device *dev, struct iw_request_info *info, 
    516516        struct sockaddr *ap_addr, char *extra) 
    517517{ 
    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"; 
    521518        struct ieee80211vap *vap = dev->priv; 
    522519 
    523520        /* NB: should not be set when in AP mode */ 
     
    534531         * 
    535532         * anything else specifies a particular AP. 
    536533         */ 
    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")) 
    544537                        vap->iv_flags |= IEEE80211_F_DESBSSID; 
     538                 
     539                IEEE80211_ADDR_COPY(vap->iv_des_bssid, &ap_addr->sa_data); 
    545540                if (IS_UP_AUTO(vap)) 
    546541                        ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 
    547542        } 
     
    557552        if (vap->iv_flags & IEEE80211_F_DESBSSID) 
    558553                IEEE80211_ADDR_COPY(&ap_addr->sa_data, vap->iv_des_bssid); 
    559554        else { 
    560                 static const u_int8_t zero_bssid[IEEE80211_ADDR_LEN]; 
    561555                if (vap->iv_state == IEEE80211_S_RUN) 
    562556                        if (vap->iv_opmode != IEEE80211_M_WDS)  
    563557                                IEEE80211_ADDR_COPY(&ap_addr->sa_data, vap->iv_bss->ni_bssid); 
    564558                        else 
    565559                                IEEE80211_ADDR_COPY(&ap_addr->sa_data, vap->wds_mac); 
    566560                else 
    567                         IEEE80211_ADDR_COPY(&ap_addr->sa_data, zero_bssid); 
     561                        memset(&ap_addr->sa_data, 0, IEEE80211_ADDR_LEN); 
    568562        } 
    569563        ap_addr->sa_family = ARPHRD_ETHER; 
    570564        return 0; 
  • net80211/ieee80211_input.c

    old new  
    985985         * not freed by the timer process while we use it. 
    986986         * XXX bogus 
    987987         */ 
    988         IEEE80211_NODE_LOCK_IRQ(ni->ni_table); 
     988        IEEE80211_NODE_TABLE_LOCK_IRQ(ni->ni_table); 
    989989 
    990990        /* 
    991991         * Update the time stamp.  As a side effect, it 
     
    995995         */ 
    996996        ni->ni_rxfragstamp = jiffies; 
    997997 
    998         IEEE80211_NODE_UNLOCK_IRQ(ni->ni_table); 
     998        IEEE80211_NODE_TABLE_UNLOCK_IRQ(ni->ni_table); 
    999999 
    10001000        /* 
    10011001         * Validate that fragment is in order and 
     
    13071307                        "%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(ni->ni_macaddr),  
    13081308                        ieee80211_node_refcnt(ni)); 
    13091309 
    1310                 } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) 
    1311                        (void) ieee80211_ref_node(ni); 
     1310                } 
     1311                 
    13121312                /* 
    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 
    13161314                 */ 
    13171315                ni->ni_flags |= IEEE80211_NODE_AREF; 
    13181316 
     
    13991397{ 
    14001398        struct ieee80211vap *vap = ni->ni_vap; 
    14011399        u_int8_t *challenge; 
    1402         int allocbs, estatus
     1400        int allocbs = 0, estatus = 0
    14031401 
    14041402        /* 
    14051403         * NB: this can happen as we allow pre-shared key 
     
    14091407         * ordering in which case this check would just be 
    14101408         * for sanity/consistency. 
    14111409         */ 
    1412         estatus = 0;                    /* NB: silence compiler */ 
    14131410        if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { 
    14141411                IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 
    14151412                        ni->ni_macaddr, "shared key auth", 
     
    15001497                                ieee80211_node_refcnt(ni)); 
    15011498 
    15021499                                allocbs = 1; 
    1503                         } else { 
    1504                                 if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) 
    1505                                         (void) ieee80211_ref_node(ni); 
    1506                                 allocbs = 0; 
    15071500                        } 
    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 
    15141502                        ni->ni_rssi = rssi; 
    15151503                        ni->ni_rstamp = rstamp; 
    15161504                        ni->ni_last_rx = jiffies; 
     
    26472635                } 
    26482636                if (scan.capinfo & IEEE80211_CAPINFO_IBSS) { 
    26492637                        if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { 
    2650                                 /* 
    2651                                  * Create a new entry in the neighbor table. 
    2652                                  */ 
    26532638                                ni = ieee80211_add_neighbor(vap, wh, &scan); 
    26542639                        } else { 
    26552640                                /* 
     
    28222807                                        ni = vap->iv_xrvap->iv_bss; 
    28232808                                else { 
    28242809                                        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                                         */ 
    28252813                                        ieee80211_node_reset(ni, vap->iv_xrvap); 
    28262814                                } 
    28272815                                vap = vap->iv_xrvap; 
     
    28342822#endif 
    28352823                IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_AUTH, wh->i_addr2, 
    28362824                        "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. */ 
    28402826                if (vap->iv_acl != NULL && 
    28412827                    !vap->iv_acl->iac_check(vap, wh->i_addr2)) { 
    28422828                        IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL, 
     
    28692855                                /* XXX not right */ 
    28702856                                ieee80211_send_error(ni, wh->i_addr2, 
    28712857                                        IEEE80211_FC0_SUBTYPE_AUTH, 
    2872                                         (seq+1) | (IEEE80211_STATUS_ALG << 16)); 
     2858                                        (seq + 1) | (IEEE80211_STATUS_ALG << 16)); 
    28732859                        } 
    28742860                        return; 
    28752861                }  
  • net80211/ieee80211_linux.h

    old new  
    6565 
    6666#define IEEE80211_RESCHEDULE    schedule 
    6767 
     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 
    6874/* 
    6975 * Beacon handler locking definitions. 
    7076 * Beacon locking  
     
    8793#define IEEE80211_LOCK(_ic)     spin_lock(&(_ic)->ic_comlock) 
    8894#define IEEE80211_UNLOCK(_ic)   spin_unlock(&(_ic)->ic_comlock) 
    8995 
    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) 
    9297#define IEEE80211_LOCK_ASSERT(_ic) \ 
    9398        KASSERT(spin_is_locked(&(_ic)->ic_comlock),("ieee80211com not locked!")) 
    9499#else 
    95100#define IEEE80211_LOCK_ASSERT(_ic) 
    96101#endif 
    97102 
     103 
    98104#define IEEE80211_VAPS_LOCK_INIT(_ic, _name)            \ 
    99105        spin_lock_init(&(_ic)->ic_vapslock) 
    100106#define IEEE80211_VAPS_LOCK_DESTROY(_ic) 
     
    110116} while (0) 
    111117#define IEEE80211_VAPS_UNLOCK_IRQ_EARLY(_ic)    spin_unlock_irqrestore(&(_ic)->ic_vapslock, _vaps_lockflags) 
    112118 
    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) 
    116120#define IEEE80211_VAPS_LOCK_ASSERT(_ic) \ 
    117121        KASSERT(spin_is_locked(&(_ic)->ic_vapslock),("ieee80211com_vaps not locked!")) 
    118122#else 
     
    124128 * Node locking definitions. 
    125129 */ 
    126130typedef 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 {    \ 
    134140        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 */ 
     159typedef 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;         \ 
    135170        spin_lock_irqsave(&(_nt)->nt_nodelock, __node_lockflags); 
    136 #define IEEE80211_NODE_UNLOCK_IRQ(_nt)                \ 
     171#define IEEE80211_NODE_TABLE_UNLOCK_IRQ(_nt)          \ 
    137172        spin_unlock_irqrestore(&(_nt)->nt_nodelock, __node_lockflags); \ 
    138173} while(0) 
    139 #define IEEE80211_NODE_UNLOCK_IRQ_EARLY(_nt)          \ 
     174#define IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(_nt)            \ 
    140175        spin_unlock_irqrestore(&(_nt)->nt_nodelock, __node_lockflags); 
    141176 
    142 /* NB: beware, *_is_locked() are bogusly defined for UP+!PREEMPT */ 
    143177#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) \ 
    145179        KASSERT(spinlock_is_locked(&(_nt)->nt_nodelock), \ 
    146180                ("802.11 node table not locked!")) 
    147181#else 
    148 #define IEEE80211_NODE_LOCK_ASSERT(_nt) 
     182#define IEEE80211_NODE_TABLE_LOCK_ASSERT(_nt) 
    149183#endif 
    150184 
    151185/* 
     
    165199#define IEEE80211_SCAN_UNLOCK_IRQ_EARLY(_nt)            \ 
    166200        spin_unlock_irqrestore(&(_nt)->nt_scanlock, __scan_lockflags); 
    167201 
    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) 
    170203#define IEEE80211_SCAN_LOCK_ASSERT(_nt) \ 
    171204        KASSERT(spin_is_locked(&(_nt)->nt_scanlock), ("scangen not locked!")) 
    172205#else 
     
    184217#define ACL_LOCK_BH(_as)                spin_lock_bh(&(_as)->as_lock) 
    185218#define ACL_UNLOCK_BH(_as)              spin_unlock_bh(&(_as)->as_lock) 
    186219 
    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) 
    189221#define ACL_LOCK_ASSERT(_as) \ 
    190222        KASSERT(spin_is_locked(&(_as)->as_lock), ("ACL not locked!")) 
    191223#else 
     
    295327 *                              is the last reference, otherwise 0 
    296328 * ieee80211_node_refcnt        reference count for printing (only) 
    297329 */ 
     330typedef atomic_t ieee80211_node_ref_count_t;  
    298331#define ieee80211_node_initref(_ni)     atomic_set(&(_ni)->ni_refcnt, 1) 
    299332#define ieee80211_node_incref(_ni)      atomic_inc(&(_ni)->ni_refcnt) 
    300333#define ieee80211_node_decref(_ni)      atomic_dec(&(_ni)->ni_refcnt) 
     
    375408/* msecs_to_jiffies appeared in 2.6.7 and 2.4.29 */ 
    376409#include <linux/delay.h> 
    377410#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) 
    380413 
    381414/* The following definitions and inline functions are 
    382415 * copied from the kernel src, include/linux/jiffies.h */ 
  • ath/if_ath.c

    old new  
    29712971 
    29722972/* 
    29732973 * Allocate tx/rx key slots for TKIP.  We allocate two slots for 
    2974  * each key, one for decrypt/encrypt and the other for the MIC. 
     2974 * each key, one for decypt/encrypt and the other for the MIC. 
    29752975 */ 
    29762976static u_int16_t 
    29772977key_alloc_2pair(struct ath_softc *sc) 
     
    47134713                an->an_uapsd_overflowqdepth--; 
    47144714        } 
    47154715 
     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 
    47164719        ATH_NODE_UAPSD_LOCK_IRQ(an); 
    47174720        sc->sc_node_cleanup(ni); 
    47184721        ATH_NODE_UAPSD_UNLOCK_IRQ(an); 
     
    47234726{ 
    47244727        struct ath_softc *sc = ni->ni_ic->ic_dev->priv; 
    47254728 
    4726         ath_rate_node_cleanup(sc, ATH_NODE(ni)); 
    47274729        sc->sc_node_free(ni); 
    47284730#ifdef ATH_SUPERG_XR 
    47294731        ath_grppoll_period_update(sc);