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

📄 ieee80211_node.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
	if (show_counter) {		snprintf(node_count,			 sizeof(node_count),			 "[#NODES=%05d] ",			 atomic_read(&ni->ni_ic->ic_node_counter));	}	va_start(args, message);	vsnprintf(expanded_message, sizeof(expanded_message), message, args);	printk(KERN_DEBUG "%s/%s: %s %s [node %p<" MAC_FMT ">%s%s%s%s, refs=%02d]\n",			ni->ni_ic->ic_dev->name,			ni->ni_vap->iv_dev->name,			node_count,			expanded_message,			ni, MAC_ADDR(ni->ni_macaddr),			ni->ni_table != NULL ? " in " : "",			ni->ni_table != NULL ? ni->ni_table->nt_name : "",			ni->ni_table != NULL ? " table" : "",			ni->ni_table != NULL ? "" : " (not in any tables)",			adjusted_refcount);	dump_stack();	va_end(args);}#else# define	node_print_message(...)#endifstatic voidnode_free(struct ieee80211_node *ni){	KASSERT(atomic_read(&ni->ni_refcnt) == 0,			("node being free whilst still referenced"));	if (ni->ni_challenge != NULL)		FREE(ni->ni_challenge, M_DEVBUF);	if (ni->ni_wpa_ie != NULL)		FREE(ni->ni_wpa_ie, M_DEVBUF);	if (ni->ni_rsn_ie != NULL)		FREE(ni->ni_rsn_ie, M_DEVBUF);	if (ni->ni_wme_ie != NULL)		FREE(ni->ni_wme_ie, M_DEVBUF);	if (ni->ni_ath_ie != NULL)		FREE(ni->ni_ath_ie, M_DEVBUF);	if (ni->ni_suppchans != NULL)		FREE(ni->ni_suppchans, M_DEVBUF);	if (ni->ni_suppchans_new != NULL)		FREE(ni->ni_suppchans_new, M_DEVBUF);	if (ni->ni_needed_chans != NULL)		FREE(ni->ni_needed_chans, M_DEVBUF);	IEEE80211_NODE_SAVEQ_DESTROY(ni);	FREE(ni, M_80211_NODE);}static int32_tnode_count(struct ieee80211com *ic){	return atomic_read(&ic->ic_node_counter);}static u_int8_tnode_getrssi(const struct ieee80211_node *ni){	return ni->ni_rssi;}/* * Create an entry in the specified node table.  The node * is setup with the mac address, an initial reference count, * and some basic parameters obtained from global state. * This interface is not intended for general use, it is * used by the routines below to create entries with a * specific purpose. * Dont assume a BSS? * Allocates a new struct ieee80211_node that has a reference  * count of one, and adds it to the node table. */struct ieee80211_node *ieee80211_alloc_node_table(struct ieee80211vap *vap,	const u_int8_t *macaddr){	struct ieee80211com *ic = vap->iv_ic;	struct ieee80211_node_table *nt = &ic->ic_sta;	struct ieee80211_node *ni;	ni = ieee80211_alloc_node(vap, macaddr);	if (ni != NULL) {		ni->ni_inact = ni->ni_inact_reload = nt->nt_inact_init;		WME_UAPSD_NODE_TRIGSEQINIT(ni);		IEEE80211_NODE_SAVEQ_INIT(ni, "unknown");		IEEE80211_NODE_TABLE_LOCK_IRQ(nt);		node_table_join_locked(nt, ni);		IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);	}	else {		printk(KERN_ERR "Failed to allocate node for " MAC_FMT ".\n",				MAC_ADDR(macaddr));	}	return ni;}EXPORT_SYMBOL(ieee80211_alloc_node_table);/* Allocate a node structure and initialise specialised structures * This function does not add the node to the node table, thus this * node will not be found using ieee80211_find_*node. * This is useful when sending one off errors or request denials. */static struct ieee80211_node *ieee80211_alloc_node(struct ieee80211vap *vap, const u_int8_t *macaddr){	struct ieee80211com *ic = vap->iv_ic;	struct ieee80211_node *ni;	/* This always allocates zeroed memoery */	ni = ic->ic_node_alloc(vap);	if (ni != NULL) {		atomic_set(&ni->ni_refcnt, 1);		IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);		ni->ni_chan = IEEE80211_CHAN_ANYC;		ni->ni_authmode = IEEE80211_AUTH_OPEN;		ni->ni_txpower = ic->ic_txpowlimit;		ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey,			IEEE80211_KEYIX_NONE);		ni->ni_ath_defkeyindex = IEEE80211_INVAL_DEFKEY;		ni->ni_vap = vap;		ni->ni_ic = ic;		atomic_inc(&ni->ni_ic->ic_node_counter);		node_print_message(IEEE80211_MSG_NODE | IEEE80211_MSG_NODE_REF,				   1 /* show counter */, 				   0 /* adjust refcount */, 				   ni, 				   "alloc" /* message */);	} else {		/* XXX msg */		vap->iv_stats.is_rx_nodealloc++;	}	return ni;}/* Add wds address to the node table. */intieee80211_add_wds_addr(struct ieee80211_node_table *nt,	struct ieee80211_node *ni, const u_int8_t *macaddr, u_int8_t wds_static){	int hash;	struct ieee80211_wds_addr *wds;	MALLOC(wds, struct ieee80211_wds_addr *,			sizeof(struct ieee80211_wds_addr),			M_80211_WDS, M_NOWAIT | M_ZERO);	if (wds == NULL) {		/* XXX msg */		return 1;	}	if (wds_static)		wds->wds_agingcount = WDS_AGING_STATIC;	else		wds->wds_agingcount = WDS_AGING_COUNT;	hash = IEEE80211_NODE_HASH(macaddr);	IEEE80211_ADDR_COPY(wds->wds_macaddr, macaddr);	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);	wds->wds_ni = ieee80211_ref_node(ni);	LIST_INSERT_HEAD(&nt->nt_wds_hash[hash], wds, wds_hash);	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);	return 0;}EXPORT_SYMBOL(ieee80211_add_wds_addr);/* remove wds address from the wds hash table */voidieee80211_remove_wds_addr(struct ieee80211_node_table *nt,		const u_int8_t *macaddr){	int hash;	struct ieee80211_wds_addr *wds, *twds;	hash = IEEE80211_NODE_HASH(macaddr);	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);	LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {		if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {			LIST_REMOVE(wds, wds_hash);			ieee80211_unref_node(&wds->wds_ni);			FREE(wds, M_80211_WDS);			break;		}	}	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);}EXPORT_SYMBOL(ieee80211_remove_wds_addr);/* Remove node references from wds table */voidieee80211_del_wds_node(struct ieee80211_node_table *nt,		struct ieee80211_node *ni){	int hash;	struct ieee80211_wds_addr *wds, *twds;	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);	for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) {		LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {			if (wds->wds_ni == ni) {				LIST_REMOVE(wds, wds_hash);				ieee80211_unref_node(&wds->wds_ni);				FREE(wds, M_80211_WDS);			}		}	}	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);}EXPORT_SYMBOL(ieee80211_del_wds_node);static voidieee80211_node_wds_ageout(unsigned long data){	struct ieee80211_node_table *nt = (struct ieee80211_node_table *)data;	int hash;	struct ieee80211_wds_addr *wds, *twds;	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);	for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) {		LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {			if (wds->wds_agingcount != WDS_AGING_STATIC) {				if (!wds->wds_agingcount) {					LIST_REMOVE(wds, wds_hash);					ieee80211_unref_node(&wds->wds_ni);					FREE(wds, M_80211_WDS);				} else					wds->wds_agingcount--;			}		}	}	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);	mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL);}/* Add the specified station to the station table. * Allocates a new struct ieee80211_node that has a reference count of one * If tmp is 0, it is added to the node table and the reference is used. * If tmp is 1, then the caller gets to use the reference. */struct ieee80211_node *ieee80211_dup_bss(struct ieee80211vap *vap, const u_int8_t *macaddr,		unsigned char tmp){	struct ieee80211_node *ni;	/* FIXME: Hack */	if (tmp) {		ni = ieee80211_alloc_node(vap, macaddr);	}	else {		ni = ieee80211_alloc_node_table(vap, macaddr);		IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,				  "%s: ni:%p allocated for " MAC_FMT "\n",				  __func__, ni, MAC_ADDR(macaddr));	}	if (ni != NULL) {		copy_bss_state(ni, vap->iv_bss);		IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bssid);		/* Do this only for nodes that already have a BSS. Otherwise		 * ic_bsschan is not set and we get a KASSERT failure.		 * Required by ieee80211_fix_rate */		ieee80211_node_set_chan(vap->iv_ic, ni);	}	return ni;}static struct ieee80211_node *ieee80211_find_wds_node_locked(struct ieee80211_node_table *nt, 			 const u_int8_t *macaddr){	struct ieee80211_wds_addr *wds;	int hash;	IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);	hash = IEEE80211_NODE_HASH(macaddr);	LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {		if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {			/* Reset the aging count. */			if (wds->wds_agingcount != WDS_AGING_STATIC)				wds->wds_agingcount = WDS_AGING_COUNT;			return ieee80211_ref_node(wds->wds_ni);		}	}	return NULL;}/* NB: A node reference is acquired here; the caller MUST release it. */static struct ieee80211_node *ieee80211_find_node_locked(struct ieee80211_node_table *nt,	const u_int8_t *macaddr){	struct ieee80211_node *ni;	int hash;	struct ieee80211_wds_addr *wds;	IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);	hash = IEEE80211_NODE_HASH(macaddr);	LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {		if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {			ieee80211_ref_node(ni);			return ni;		}	}	/* Now, we look for the desired mac address in the 4 address	   nodes. */	LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {		if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr))			return ieee80211_ref_node(wds->wds_ni);	}	return NULL;}struct ieee80211_node *ieee80211_find_wds_node(struct ieee80211_node_table *nt,		const u_int8_t *macaddr){	struct ieee80211_node *ni;	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);	ni = ieee80211_find_wds_node_locked(nt, macaddr);	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);	return ni;}EXPORT_SYMBOL(ieee80211_find_wds_node);struct ieee80211_node *ieee80211_find_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr){	struct ieee80211_node *ni;	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);	ni = ieee80211_find_node_locked(nt, macaddr);	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);	return ni;}EXPORT_SYMBOL(ieee80211_find_node);/* * Fake up a node; this handles node discovery in adhoc mode. * Note that for the driver's benefit we we treat this like * an association so the driver has an opportunity to setup * its private state. * * Caller must ieee80211_ref_node() */struct ieee80211_node *ieee80211_fakeup_adhoc_node(struct ieee80211vap *vap,	const u_int8_t macaddr[IEEE80211_ADDR_LEN]){	struct ieee80211_node *ni;	ni = ieee80211_dup_bss(vap, macaddr, 0);	if (ni != NULL) {		/* XXX no rate negotiation; just dup */		ni->ni_rates = vap->iv_bss->ni_rates;		if (vap->iv_ic->ic_newassoc != NULL)			vap->iv_ic->ic_newassoc(ni, 1);		/* XXX not right for 802.1x/WPA */		ieee80211_node_authorize(ni);	}	return ni;}/* * Do node discovery in adhoc mode on receipt of a beacon * or probe response frame.  Note that for the driver's * benefit we treat this like an association so the * driver has an opportunity to setup its private state. */struct ieee80211_node *ieee80211_add_neighbor(struct ieee80211vap *vap, const struct ieee80211_frame *wh,	const struct ieee80211_scanparams *sp){	struct ieee80211com *ic = vap->iv_ic;	struct ieee80211_node *ni;	ni = ieee80211_dup_bss(vap, wh->i_addr2, 0);	if (ni != NULL) {		ni->ni_esslen = sp->ssid[1];		memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]);		IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);		memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp));		ni->ni_intval = IEEE80211_BINTVAL_SANITISE(sp->bintval);		ni->ni_capinfo = sp->capinfo;		ni->ni_chan = ic->ic_curchan;		ni->ni_fhdwell = sp->fhdwell;		ni->ni_fhindex = sp->fhindex;		ni->ni_erp = sp->erp;		ni->ni_timoff = sp->timoff;		if (sp->wme != NULL)			ieee80211_saveie(&ni->ni_wme_ie, sp->wme);		if (sp->wpa != NULL)			ieee80211_saveie(&ni->ni_wpa_ie, sp->wpa);		if (sp->rsn != NULL)			ieee80211_saveie(&ni->ni_rsn_ie, sp->rsn);		if (sp->ath != NULL)			ieee80211_saveath(ni, sp->ath);		/* NB: must be after ni_chan is setup */		ieee80211_setup_rates(ni, sp->rates, sp->xrates, IEEE80211_F_DOSORT);		if (ic->ic_newassoc != NULL)			ic->ic_newassoc(ni, 1);		/* XXX not right for 802.1x/WPA */		ieee80211_node_authorize(ni);		if (vap->iv_opmode == IEEE80211_M_AHDEMO) {			/*			 * Blindly propagate capabilities based on the			 * local configuration.  In particular this permits			 * us to use QoS to disable ACKs and to use short			 * preamble on 2.4G channels.			 */			if (vap->iv_flags & IEEE80211_F_WME)				ni->ni_flags |= IEEE80211_NODE_QOS;			if (vap->iv_flags & IEEE80211_F_SHPREAMBLE)				ni->ni_capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;		}	}	return ni;}

⌨️ 快捷键说明

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