⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wlan_node.c

📁 Linux下SDIO设备的驱动程序
💻 C
字号:
/* * Copyright (c) 2001 Atsushi Onoe * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting * Copyright (c) 2004-2006 Atheros Communications * *  Wireless Network driver for Atheros AR6001 * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License version 2 as *  published by the Free Software Foundation; * *  Software distributed under the License is distributed on an "AS *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or *  implied. See the License for the specific language governing *  rights and limitations under the License. * * *//* * IEEE 802.11 node handling support. */#include "../include/athdefs.h"#include "../include/athtypes.h"#include "../include/osapi.h"#include "../include/ieee80211.h"#include "../include/wlan_api.h"#include "../include/ieee80211_node.h"#include "../include/htc.h"#include "../include/wmi.h"#include "../include/wmi_api.h"#ifdef DEBUGstatic int wlan_node_debug= 1;#define ND_PRINTF      if (wlan_node_debug) A_PRINTF#else#define ND_PRINTF(args...)#endifstatic void wlan_node_timeout(unsigned long arg);static bss_t * _ieee80211_find_node(struct ieee80211_node_table *nt,                                    const A_UINT8 *macaddr);bss_t *wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size){    bss_t *ni;    ni = A_MALLOC_NOWAIT(sizeof(bss_t));    if (ni != NULL) {        ni->ni_buf = A_MALLOC_NOWAIT(wh_size);        if (ni->ni_buf == NULL) {            A_FREE(ni);            ni = NULL;        }    }    /* Make sure our lists are clean */    ni->ni_list_next = NULL;    ni->ni_list_prev = NULL;    ni->ni_hash_next = NULL;    ni->ni_hash_prev = NULL;    return ni;}voidwlan_node_free(bss_t *ni){    if (ni->ni_buf != NULL) {        A_FREE(ni->ni_buf);    }    A_FREE(ni);}voidwlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,                const A_UINT8 *macaddr){    int hash;    A_MEMCPY(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN);    hash = IEEE80211_NODE_HASH(macaddr);    ieee80211_node_initref(ni);     /* mark referenced */    ni->ni_tstamp = jiffies + (WLAN_NODE_INACT_TIMEOUT_MSEC / 1000) * HZ;    IEEE80211_NODE_LOCK_BH(nt);    /* Insert at the end of the node list */    ni->ni_list_next = NULL;    ni->ni_list_prev = nt->nt_node_last;    if(nt->nt_node_last != NULL)    {        nt->nt_node_last->ni_list_next = ni;    }    nt->nt_node_last = ni;    if(nt->nt_node_first == NULL)    {        nt->nt_node_first = ni;    }    /* Insert into the hash list i.e. the bucket */    if((ni->ni_hash_next = nt->nt_hash[hash]) != NULL)    {        nt->nt_hash[hash]->ni_hash_prev = ni;    }    ni->ni_hash_prev = NULL;    nt->nt_hash[hash] = ni;    IEEE80211_NODE_UNLOCK_BH(nt);}static bss_t *_ieee80211_find_node(struct ieee80211_node_table *nt,    const A_UINT8 *macaddr){    bss_t *ni;    int hash;    IEEE80211_NODE_LOCK_ASSERT(nt);    hash = IEEE80211_NODE_HASH(macaddr);    for(ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {        if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {            ieee80211_node_incref(ni);  /* mark referenced */            return ni;        }    }    return NULL;}bss_t *wlan_find_node(struct ieee80211_node_table *nt, const A_UINT8 *macaddr){    bss_t *ni;    IEEE80211_NODE_LOCK(nt);    ni = _ieee80211_find_node(nt, macaddr);    IEEE80211_NODE_UNLOCK(nt);    return ni;}/* * Reclaim a node.  If this is the last reference count then * do the normal free work.  Otherwise remove it from the node * table and mark it gone by clearing the back-reference. */voidwlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni){    IEEE80211_NODE_LOCK(nt);    if(ni->ni_list_prev == NULL)    {        /* First in list so fix the list head */        nt->nt_node_first = ni->ni_list_next;    }    else    {        ni->ni_list_prev->ni_list_next = ni->ni_list_next;    }    if(ni->ni_list_next == NULL)    {        /* Last in list so fix list tail */        nt->nt_node_last = ni->ni_list_prev;    }    else    {        ni->ni_list_next->ni_list_prev = ni->ni_list_prev;    }    if(ni->ni_hash_prev == NULL)    {        /* First in list so fix the list head */        int hash;        hash = IEEE80211_NODE_HASH(ni->ni_macaddr);        nt->nt_hash[hash] = ni->ni_hash_next;    }    else    {        ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;    }    if(ni->ni_hash_next != NULL)    {        ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;    }    wlan_node_free(ni);    IEEE80211_NODE_UNLOCK(nt);}static voidwlan_node_dec_free(bss_t *ni){    if (ieee80211_node_dectestref(ni)) {        wlan_node_free(ni);    }}voidwlan_free_allnodes(struct ieee80211_node_table *nt){    bss_t *ni;    while ((ni = nt->nt_node_first) != NULL) {        wlan_node_reclaim(nt, ni);    }}voidwlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,                   void *arg){    bss_t *ni;    A_UINT32 gen;    gen = nt->nt_scangen++;    IEEE80211_NODE_LOCK(nt);    for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {        if (ni->ni_scangen != gen) {            ni->ni_scangen = gen;            (void) ieee80211_node_incref(ni);            (*f)(arg, ni);            wlan_node_dec_free(ni);        }    }    IEEE80211_NODE_UNLOCK(nt);}/* * Node table support. */voidwlan_node_table_init(void *wmip, struct ieee80211_node_table *nt){    int i;    ND_PRINTF("node table = 0x%x\n", (A_UINT32)nt);    IEEE80211_NODE_LOCK_INIT(nt);    nt->nt_node_first = nt->nt_node_last = NULL;    for(i = 0; i < IEEE80211_NODE_HASHSIZE; i++)    {        nt->nt_hash[i] = NULL;    }    A_INIT_TIMER(&nt->nt_inact_timer, wlan_node_timeout, nt);    A_TIMEOUT_MS(&nt->nt_inact_timer, WLAN_NODE_INACT_TIMEOUT_MSEC, 0);    nt->nt_wmip = wmip;}static voidwlan_node_timeout(unsigned long arg){    struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg;    bss_t *bss, *nextBss;    A_UINT8 myBssid[IEEE80211_ADDR_LEN];    wmi_get_current_bssid(nt->nt_wmip, myBssid);    bss = nt->nt_node_first;    while (bss != NULL) {        nextBss = bss->ni_list_next;        if ((A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) &&            (bss->ni_tstamp <= jiffies))        {            /*             * free up all but the current bss - if set             */            wlan_node_reclaim(nt, bss);        }        bss = nextBss;    }    A_TIMEOUT_MS(&nt->nt_inact_timer, WLAN_NODE_INACT_TIMEOUT_MSEC, 0);}voidwlan_node_table_cleanup(struct ieee80211_node_table *nt){    A_UNTIMEOUT(&nt->nt_inact_timer);    wlan_free_allnodes(nt);    IEEE80211_NODE_LOCK_DESTROY(nt);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -