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

📄 ieee80211_node.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
		ni->ni_flags |= IEEE80211_NODE_ERP;}static voidcount_suppchans(struct ieee80211com *ic, struct ieee80211_node *ni, int inc){	int i, tmp1, tmp2 = 0;	if (ni->ni_suppchans == NULL)		return;	CHANNEL_FOREACH(i, ic, tmp1, tmp2)		if (isset(ni->ni_suppchans, i))			ic->ic_chan_nodes[i] += inc;	ic->ic_cn_total += inc;}static voidremove_worse_nodes(void *arg, struct ieee80211_node *ni){	struct ieee80211_node *better = (struct ieee80211_node *)arg;	int i;	if (ni->ni_suppchans == NULL)		return;	if (ni == better)		return;	for (i = 0; i < better->ni_n_needed_chans; i++)		if (isclr(ni->ni_suppchans, better->ni_needed_chans[i])) {			/* this is the one of the nodes to be killed, do it now */			IEEE80211_NOTE_MAC(ni->ni_vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, better->ni_macaddr,					"forcing [" MAC_FMT "] (aid %d) to leave", MAC_ADDR(ni->ni_macaddr),					IEEE80211_NODE_AID(ni));			IEEE80211_SEND_MGMT(ni,					IEEE80211_FC0_SUBTYPE_DISASSOC,					IEEE80211_REASON_SUPPCHAN_UNACCEPTABLE);			ni->ni_vap->iv_stats.is_node_fdisassoc++;			ieee80211_node_leave(ni);			return;		}}voidieee80211_node_join(struct ieee80211_node *ni, int resp){	struct ieee80211com *ic = ni->ni_ic;	struct ieee80211vap *vap = ni->ni_vap;	int newassoc;	if (ni->ni_associd == 0) {		u_int16_t aid;		KASSERT(vap->iv_aid_bitmap != NULL, ("no aid bitmap"));		/*		 * It would be good to search the bitmap		 * more efficiently, but this will do for now.		 */		for (aid = 1; aid < vap->iv_max_aid; aid++)			if (!IEEE80211_AID_ISSET(vap, aid))				break;		if (aid >= vap->iv_max_aid) {			IEEE80211_SEND_MGMT(ni, resp,				IEEE80211_REASON_ASSOC_TOOMANY);			ieee80211_node_leave(ni);			return;		}		ni->ni_associd = aid | 0xc000;		IEEE80211_LOCK_IRQ(ic);		IEEE80211_AID_SET(vap, ni->ni_associd);		vap->iv_sta_assoc++;		ic->ic_sta_assoc++;#ifdef ATH_SUPERG_XR		if (ni->ni_vap->iv_flags & IEEE80211_F_XR)			ic->ic_xr_sta_assoc++;#endif		if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_ATHC_TURBOP))			ic->ic_dt_sta_assoc++;		if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))			ieee80211_node_join_11g(ni);		KASSERT(ni->ni_suppchans == NULL, ("not a reassociation, but suppchans bitmap not NULL"));		/* Use node's new suppchans as the current */		ni->ni_suppchans = ni->ni_suppchans_new;		ni->ni_suppchans_new = NULL;		/* Add node's suppchans to ic->ic_chan_nodes */		count_suppchans(ic, ni, 1);		IEEE80211_UNLOCK_IRQ(ic);		newassoc = 1;	} else {		IEEE80211_LOCK_IRQ(ic);		/* Remove node's previous suppchans from ic->ic_chan_nodes */		count_suppchans(ic, ni, -1);		if (ni->ni_suppchans != NULL) {			FREE(ni->ni_suppchans, M_DEVBUF);			ni->ni_suppchans = NULL;		}		/* Use node's new suppchans as the current */		ni->ni_suppchans = ni->ni_suppchans_new;		ni->ni_suppchans_new = NULL;		/* Add node's new suppchans to ic->ic_chan_nodes */		count_suppchans(ic, ni, 1);		IEEE80211_UNLOCK_IRQ(ic);		newassoc = 0;	}	IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, ni,		"station %sassociated at aid %d: %s preamble, %s slot time"		"%s%s%s%s%s%s%s",		newassoc ? "" : "re",		IEEE80211_NODE_AID(ni),		(ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&		(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) ? "short" : "long",		ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long",		ic->ic_flags & IEEE80211_F_USEPROT ? ", protection" : "",		ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "",		IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_TURBOP) ?			", turbo" : "",		IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_COMP) ?			", compression" : "",		IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF) ?			", fast-frames" : "",		IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_XR) ? ", XR" : "",		IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_AR) ? ", AR" : ""	);	/* give driver a chance to setup state like ni_txrate */	if (ic->ic_newassoc != NULL)		ic->ic_newassoc(ni, newassoc);	ni->ni_inact_reload = vap->iv_inact_auth;	ni->ni_inact = ni->ni_inact_reload;	IEEE80211_SEND_MGMT(ni, resp, IEEE80211_STATUS_SUCCESS);	if (ni->ni_needed_chans != NULL) {		/* remove nodes which don't support one of ni->ni_needed_chans */		ieee80211_iterate_nodes(&ic->ic_sta, &remove_worse_nodes, (void *)ni);		FREE(ni->ni_needed_chans, M_DEVBUF);		ni->ni_needed_chans = NULL;	}	/* tell the authenticator about new station */	if (vap->iv_auth->ia_node_join != NULL)		vap->iv_auth->ia_node_join(ni);	ieee80211_notify_node_join(ni, newassoc);}/* * Handle a station leaving an 11g network. */static voidieee80211_node_leave_11g(struct ieee80211_node *ni){	struct ieee80211com *ic = ni->ni_ic;	struct ieee80211vap *vap = ni->ni_vap;	IEEE80211_LOCK_ASSERT(ic);	KASSERT(IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan),		("not in 11g, bss %u:0x%x, curmode %u",		ic->ic_bsschan->ic_freq, ic->ic_bsschan->ic_flags,		ic->ic_curmode));	/*	 * If a long slot station do the slot time bookkeeping.	 */	if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) {		/* this can be 0 on mode changes from B -> G */		if (ic->ic_longslotsta > 0)			ic->ic_longslotsta--;		IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,			"long slot time station leaves, count now %d",			ic->ic_longslotsta);		if (ic->ic_longslotsta == 0) {			/*			 * Re-enable use of short slot time if supported			 * and not operating in IBSS mode (per spec).			 */			if ((ic->ic_caps & IEEE80211_C_SHSLOT) &&			    vap->iv_opmode != IEEE80211_M_IBSS) {				IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,					"%s: re-enable use of short slot time\n",					__func__);				ieee80211_set_shortslottime(ic, 1);			}		}	}	/*	 * If a non-ERP station do the protection-related bookkeeping.	 */	if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0) {		/* this can be 0 on mode changes from B -> G */		if (ic->ic_nonerpsta > 0)			ic->ic_nonerpsta--;		IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,			"non-ERP station leaves, count now %d", ic->ic_nonerpsta);		if (ic->ic_nonerpsta == 0) {			IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,				"%s: disable use of protection\n", __func__);			ic->ic_flags &= ~IEEE80211_F_USEPROT;			/* XXX verify mode? */			if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) {				IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,					"%s: re-enable use of short preamble\n",					__func__);				ic->ic_flags |= IEEE80211_F_SHPREAMBLE;				ic->ic_flags &= ~IEEE80211_F_USEBARKER;			}			ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;		}	}}/* * Handle bookkeeping for a station/neighbor leaving * the bss when operating in ap or adhoc modes. */voidieee80211_node_leave(struct ieee80211_node *ni){	struct ieee80211com *ic = ni->ni_ic;	struct ieee80211vap *vap = ni->ni_vap;	struct ieee80211_node_table *nt = ni->ni_table;	if (IEEE80211_NODE_AID(ni) != 0)		IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG,			ni, "station with aid %d leaves (refcnt %u)",			IEEE80211_NODE_AID(ni), atomic_read(&ni->ni_refcnt));	/* From this point onwards we can no longer find the node,	 * so no more references are generated	 */	ieee80211_remove_wds_addr(nt, ni->ni_macaddr);	ieee80211_del_wds_node(nt, ni);	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);	node_table_leave_locked(nt, ni);	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);	/*	 * If node wasn't previously associated all	 * we need to do is reclaim the reference.	 * This also goes for nodes that are auth'ed but	 * not associated.	 */	/* XXX ibss mode bypasses 11g and notification */	if (ni->ni_associd == 0)		goto done;	/*	 * Tell the authenticator the station is leaving.	 * Note that we must do this before yanking the	 * association id as the authenticator uses the	 * associd to locate its state block.	 */	if (vap->iv_auth->ia_node_leave != NULL)		vap->iv_auth->ia_node_leave(ni);	ieee80211_notify_sta_stats(ni);	IEEE80211_LOCK_IRQ(ic);	if (vap->iv_aid_bitmap != NULL)		IEEE80211_AID_CLR(vap, ni->ni_associd);	ni->ni_associd = 0;	vap->iv_sta_assoc--;	ic->ic_sta_assoc--;#ifdef ATH_SUPERG_XR	if (ni->ni_vap->iv_flags & IEEE80211_F_XR)		ic->ic_xr_sta_assoc--;#endif	if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_ATHC_TURBOP))		ic->ic_dt_sta_assoc--;	if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))		ieee80211_node_leave_11g(ni);	/* Remove node's suppchans from ic->ic_chan_nodes */	if (ni->ni_suppchans != NULL)		count_suppchans(ic, ni, -1);	IEEE80211_UNLOCK_IRQ(ic);	/*	 * Cleanup station state.  In particular clear various	 * state that might otherwise be reused if the node	 * is reused before the reference count goes to zero	 * (and memory is reclaimed).	 */	ieee80211_sta_leave(ni);done:	/* Run a cleanup */	ic->ic_node_cleanup(ni);}EXPORT_SYMBOL(ieee80211_node_leave);u_int8_tieee80211_getrssi(struct ieee80211com *ic){#define	NZ(x)	((x) == 0 ? 1 : (x))	struct ieee80211_node_table *nt = &ic->ic_sta;	struct ieee80211vap *vap;	u_int32_t rssi_samples, rssi_total;	struct ieee80211_node *ni;	rssi_total = 0;	rssi_samples = 0;	switch (ic->ic_opmode) {	case IEEE80211_M_IBSS:		/* average of all ibss neighbors */		/* XXX locking */		TAILQ_FOREACH(ni, &nt->nt_node, ni_list)			if (ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) {				rssi_samples++;				rssi_total += ic->ic_node_getrssi(ni);			}		break;	case IEEE80211_M_AHDEMO:	/* average of all neighbors */		/* XXX locking */		TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {			if (memcmp(ni->ni_vap->iv_myaddr, ni->ni_macaddr,						IEEE80211_ADDR_LEN)!=0) {				rssi_samples++;				rssi_total += ic->ic_node_getrssi(ni);			}		}		break;	case IEEE80211_M_HOSTAP:	/* average of all associated stations */		/* XXX locking */		TAILQ_FOREACH(ni, &nt->nt_node, ni_list)			if (IEEE80211_AID(ni->ni_associd) != 0) {				rssi_samples++;				rssi_total += ic->ic_node_getrssi(ni);			}		break;	case IEEE80211_M_MONITOR:	/* XXX */	case IEEE80211_M_STA:		/* use stats from associated ap */	default:		TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)			if (vap->iv_bss != NULL) {				rssi_samples++;				rssi_total += ic->ic_node_getrssi(vap->iv_bss);			}		break;	}	return rssi_total / NZ(rssi_samples);#undef NZ}EXPORT_SYMBOL(ieee80211_getrssi);voidieee80211_node_reset(struct ieee80211_node *ni, struct ieee80211vap *vap){	/* XXX: Untested use of iv_bssid. */	IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bssid);	ni->ni_prev_vap = ni->ni_vap;	ni->ni_vap = vap;	ni->ni_ic = vap->iv_ic;}EXPORT_SYMBOL(ieee80211_node_reset);struct ieee80211_node *ieee80211_ref_node(struct ieee80211_node *ni){	if (ni == NULL) {		printk(KERN_ERR "%s: NULL node.\n", __func__);		dump_stack();	}else if (atomic_read(&ni->ni_refcnt) < 1) {		node_print_message(IEEE80211_MSG_ANY,				   0 /* show counter */, 				   0 /* adjust refcount */, 				   ni, 				   "attempt to access node with invalid "				   "refcount of %d.  No changes made.",				   atomic_read(&ni->ni_refcnt));	} else {		atomic_inc(&ni->ni_refcnt);		node_print_message(IEEE80211_MSG_NODE_REF,				0 /* show counter */, 				0 /* adjust refcount */, 				ni, "ref");	}	return ni;}EXPORT_SYMBOL(ieee80211_ref_node);voidieee80211_unref_node(struct ieee80211_node **pni){	struct ieee80211_node *ni = NULL;	if (pni == NULL) {		printk(KERN_ERR "%s: NULL ieee80211_node **\n", __func__);		dump_stack();		return;	}	ni = *pni;	if (ni == NULL) {		printk(KERN_ERR "%s: NULL ieee80211_node *\n", __func__);		dump_stack();		return;	}	if (atomic_read(&ni->ni_refcnt) < 1) {		node_print_message(IEEE80211_MSG_ANY,				   0 /* show counter */, 				   0 /* adjust refcount */, 				   ni, 				   "attempt to access node with invalid "				   "refcount of %d.  No changes made.",				   atomic_read(&ni->ni_refcnt));		dump_stack();		return;	}	node_print_message(IEEE80211_MSG_NODE_REF, 			   0 /* show counter */, 			   -1 /* adjust refcount */, 			   ni, 			   "unref" /* message */);	if (atomic_dec_and_test(&ni->ni_refcnt))		ieee80211_free_node(ni);	*pni = NULL;}EXPORT_SYMBOL(ieee80211_unref_node);int32_t ieee80211_get_node_count(struct ieee80211com *ic){	return node_count(ic);}EXPORT_SYMBOL(ieee80211_get_node_count);

⌨️ 快捷键说明

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