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

📄 ieee80211_proto.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
		KASSERT(vap->iv_opmode == IEEE80211_M_STA,			("switch to %s state when operating in mode %u",			 ieee80211_state_name[nstate], vap->iv_opmode));		switch (ostate) {		case IEEE80211_S_INIT:		case IEEE80211_S_SCAN:			IEEE80211_DPRINTF(vap, IEEE80211_MSG_ANY,				"%s: invalid transition\n", __func__);			break;		case IEEE80211_S_AUTH:		case IEEE80211_S_ASSOC:			IEEE80211_SEND_MGMT(ni,				IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);			break;		case IEEE80211_S_RUN:			ieee80211_sta_leave(ni);			if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {				/* NB: caller specifies ASSOC/REASSOC by arg */				IEEE80211_SEND_MGMT(ni, arg ?					IEEE80211_FC0_SUBTYPE_REASSOC_REQ :					IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);			}			break;		}		break;	case IEEE80211_S_RUN:		if (vap->iv_flags & IEEE80211_F_WPA) {			/* XXX validate prerequisites */		}		switch (ostate) {		case IEEE80211_S_INIT:			if (vap->iv_opmode == IEEE80211_M_MONITOR ||			    vap->iv_opmode == IEEE80211_M_WDS ||			    vap->iv_opmode == IEEE80211_M_HOSTAP) {				/*				 * Already have a channel; bypass the				 * scan and startup immediately.				 */				ieee80211_create_ibss(vap, ic->ic_curchan);				/* In WDS mode, allocate and initialize peer node. */				if (vap->iv_opmode == IEEE80211_M_WDS) {					/* XXX: This is horribly non-atomic. */					struct ieee80211_node *wds_ni =						ieee80211_find_node(&ic->ic_sta,								vap->wds_mac);					if (wds_ni == NULL) {						wds_ni = ieee80211_alloc_node_table(								vap,								vap->wds_mac);						if (wds_ni != NULL) {							ieee80211_add_wds_addr(									&ic->ic_sta,									wds_ni,									vap->wds_mac,									1);							ieee80211_ref_node(wds_ni); /* pin in memory */						}						else							IEEE80211_DPRINTF(									vap,									IEEE80211_MSG_NODE,									"%s: Unable to "									"allocate node for "									"WDS: " MAC_FMT "\n",									__func__,									MAC_ADDR(										vap->wds_mac)									);					}					if (wds_ni != NULL) {						ieee80211_node_authorize(wds_ni);						wds_ni->ni_chan =							vap->iv_bss->ni_chan;						wds_ni->ni_capinfo =							ni->ni_capinfo;						wds_ni->ni_associd = 1;						wds_ni->ni_ath_flags =							vap->iv_ath_cap;					}				}				break;			}			/* fall thru... */		case IEEE80211_S_AUTH:			IEEE80211_DPRINTF(vap, IEEE80211_MSG_ANY,				"%s: invalid transition\n", __func__);			break;		case IEEE80211_S_RUN:			break;		case IEEE80211_S_SCAN:		/* adhoc/hostap mode */		case IEEE80211_S_ASSOC:		/* infra mode */			KASSERT(ni->ni_txrate < ni->ni_rates.rs_nrates,				("%s: bogus xmit rate %u setup", __func__,				ni->ni_txrate));#ifdef IEEE80211_DEBUG			if (ieee80211_msg_debug(vap)) {				ieee80211_note(vap, "%s with " MAC_FMT " ssid ",					(vap->iv_opmode == IEEE80211_M_STA ?					"associated" : "synchronized "),					MAC_ADDR(vap->iv_bssid));				ieee80211_print_essid(vap->iv_bss->ni_essid,					ni->ni_esslen);				printk(" channel %d start %uMb\n",					ieee80211_chan2ieee(ic, ic->ic_curchan),					IEEE80211_RATE2MBS(ni->ni_rates.rs_rates[ni->ni_txrate]));			}#endif			if (vap->iv_opmode == IEEE80211_M_STA) {				ieee80211_scan_assoc_success(ic,					ni->ni_macaddr);				ieee80211_notify_node_join(ni,					(arg == IEEE80211_FC0_SUBTYPE_ASSOC_RESP) | \					(arg == IEEE80211_FC0_SUBTYPE_REASSOC_RESP));			}			break;		}		/* WDS/Repeater: Start software beacon timer for STA */		if (ostate != IEEE80211_S_RUN &&		    (vap->iv_opmode == IEEE80211_M_STA &&		     vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) {			vap->iv_swbmiss.function = ieee80211_sta_swbmiss;			vap->iv_swbmiss.data = (unsigned long) vap;			vap->iv_swbmiss_period = IEEE80211_TU_TO_JIFFIES(				vap->iv_ic->ic_bmissthreshold * ni->ni_intval);			mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period);		}		/*		 * Start/stop the authenticator when operating as an		 * AP.  We delay until here to allow configuration to		 * happen out of order.		 */		/* XXX WDS? */		if (vap->iv_opmode == IEEE80211_M_HOSTAP && /* XXX IBSS/AHDEMO */		    vap->iv_auth->ia_attach != NULL) {			/* XXX check failure */			vap->iv_auth->ia_attach(vap);		} else if (vap->iv_auth->ia_detach != NULL)			vap->iv_auth->ia_detach(vap);		/*		 * When 802.1x is not in use mark the port authorized		 * at this point so traffic can flow.		 */		if (ni->ni_authmode != IEEE80211_AUTH_8021X)			ieee80211_node_authorize(ni);#ifdef ATH_SUPERG_XR		/*		 * fire a timer to bring up XR vap if configured.		 */		if (ostate != IEEE80211_S_RUN &&		    vap->iv_xrvap &&		    !(vap->iv_flags & IEEE80211_F_XR)) {			vap->iv_xrvapstart.function = ieee80211_start_xrvap;			vap->iv_xrvapstart.data = (unsigned long) vap->iv_xrvap;			mod_timer(&vap->iv_xrvapstart, jiffies + HZ); /* start xr vap on next second */			/* 			 * do not let the normal vap automatically bring up XR vap.			 * let the timer handler start the XR vap. if you let the			 * normal vap automatically start the XR vap  normal vap will not			 * have the bssid initialized and the XR vap will use the			 * invalid bssid in XRIE of its beacon.			 */			if (vap->iv_xrvap->iv_flags_ext & IEEE80211_FEXT_SCAN_PENDING)				vap->iv_xrvap->iv_flags_ext &= ~IEEE80211_FEXT_SCAN_PENDING;		}		/*		 * when an XR vap transitions to RUN state,		 * normal vap needs to update the XR IE		 * with the xr vaps MAC address.		 */		if (vap->iv_flags & IEEE80211_F_XR)			vap->iv_xrvap->iv_flags |= IEEE80211_F_XRUPDATE;#endif		break;	}	return 0;}/* Get the dominant state of the device (init, running, or scanning  * (and/or associating)) */static int get_dominant_state(struct ieee80211com *ic) {	int nscanning = 0;	int nrunning  = 0;	struct ieee80211vap *tmpvap;	TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {		if (tmpvap->iv_opmode == IEEE80211_M_MONITOR)			/* skip monitor vaps as their			 * S_RUN shouldn't have any			 * influence on modifying state			 * transition */			continue;		if (tmpvap->iv_state == IEEE80211_S_RUN)			nrunning++;		else if (tmpvap->iv_state == IEEE80211_S_SCAN ||			 tmpvap->iv_state == IEEE80211_S_AUTH ||			 tmpvap->iv_state == IEEE80211_S_ASSOC) {			KASSERT((nscanning <= 1), ("Two VAPs cannot scan at "						"the same time"));			nscanning++;		}	}	KASSERT(!(nscanning && nrunning), ("SCAN and RUN can't happen at the "				"same time"));	KASSERT((nscanning <= 1),         ("Two VAPs must not SCAN at the "				"same time"));	if (nrunning > 0) 		return IEEE80211_S_RUN;	else if (nscanning > 0)		return IEEE80211_S_SCAN;	else		return IEEE80211_S_INIT;}static void dump_vap_states(struct ieee80211com *ic, struct ieee80211vap *highlighed){	/* RE-count the number of VAPs in RUN, SCAN states */	int nrunning = 0;	int nscanning = 0;	struct ieee80211vap *tmpvap;	TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {		IEEE80211_DPRINTF(tmpvap, IEEE80211_MSG_STATE, 				"%s: VAP %s%p[%24s]%s = %s%s%s.\n", __func__, 				(highlighed == tmpvap ? "*" : " "), 				tmpvap, tmpvap->iv_nickname, 				(highlighed == tmpvap ? "*" : " "), 				ieee80211_state_name[tmpvap->iv_state],				(tmpvap->iv_state == IEEE80211_S_RUN) ? 					"[RUNNING]" : "",				(tmpvap->iv_state == IEEE80211_S_SCAN ||				 tmpvap->iv_state == IEEE80211_S_AUTH || 				 tmpvap->iv_state == IEEE80211_S_ASSOC) ? 					"[SCANNING]" : ""				);		/* Ignore monitors they are passive */		if (tmpvap->iv_opmode == IEEE80211_M_MONITOR) {			continue;		}		if (tmpvap->iv_state == IEEE80211_S_RUN) {			KASSERT((nscanning == 0), ("SCAN and RUN can't happen "						"at the same time"));			nrunning++;		}		if (tmpvap->iv_state == IEEE80211_S_SCAN ||				/* STA in WDS/Repeater */				tmpvap->iv_state == IEEE80211_S_AUTH || 				tmpvap->iv_state == IEEE80211_S_ASSOC) {			KASSERT((nscanning == 0), ("Two VAPs cannot scan at "						"the same time"));			KASSERT((nrunning == 0), ("SCAN and RUN can't happen "						"at the same time"));			nscanning++;		}	}}static intieee80211_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg){	struct ieee80211com *ic = vap->iv_ic;	enum ieee80211_state ostate;	enum ieee80211_state dstate;	int blocked = 0;	struct ieee80211vap *tmpvap;	ostate = vap->iv_state;	dstate = get_dominant_state(ic);	IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, 			  "%s: %p[%s] %s -> %s (dominant %s)\n", 			  __func__, vap, vap->iv_nickname,			  ieee80211_state_name[ostate], 			  ieee80211_state_name[nstate], 			  ieee80211_state_name[dstate]);	switch (nstate) {	case IEEE80211_S_AUTH:	case IEEE80211_S_ASSOC:	case IEEE80211_S_SCAN:		switch (dstate) {		case IEEE80211_S_RUN:			if (vap->iv_opmode == IEEE80211_M_MONITOR || 			    vap->iv_opmode == IEEE80211_M_WDS ||			    vap->iv_opmode == IEEE80211_M_HOSTAP) {				IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, 						"%s: Jumping directly to RUN "						"on VAP %p [%s].\n", 						__func__, vap, 						vap->iv_nickname);				/* One or more VAPs are running, so 				 * non-station VAPs can skip SCAN/AUTH/ASSOC 				 * states and just run. */				__ieee80211_newstate(vap, IEEE80211_S_RUN, arg);			} else {				/* We'll use this flag briefly to mark 				 * transition in progress */				ic->ic_flags_ext |= IEEE80211_FEXT_SCAN_PENDING;				/* IEEE80211_M_IBSS or IEEE80211_M_STA VAP				 * is forced to scan, we need to change 				 * all other VAPs state to S_INIT and pend for 				 * the scan completion */				TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {					if ((vap != tmpvap) && 							(tmpvap->iv_opmode != 							 IEEE80211_M_MONITOR)) {						IEEE80211_DPRINTF(vap, 								IEEE80211_MSG_STATE, 								  "%s: Setting "								  "SCAN_PENDING "								  "flag on "								  "VAP %p "								  "[%s].\n", 								  __func__, 								  tmpvap, 								  tmpvap->								  iv_nickname);						tmpvap->iv_flags_ext |= 							IEEE80211_FEXT_SCAN_PENDING;						if (tmpvap->iv_state != 								IEEE80211_S_INIT) {							IEEE80211_DPRINTF(vap, 									IEEE80211_MSG_STATE, 									"%s: "									"Forcing "									"INIT "									"state "									"on "									"VAP "									"%p "									"[%s].\n", 									__func__, 									tmpvap, 									tmpvap->									iv_nickname);							tmpvap->iv_newstate(tmpvap, 									IEEE80211_S_INIT, 									0);						} else {							IEEE80211_DPRINTF(vap, 									IEEE80211_MSG_STATE, 									"%s: "									"NOT "									"forcing "									"INIT "									"state "									"on "									"VAP "									"%p "									"[%s].\n", 									__func__, 									tmpvap, 									tmpvap->									iv_nickname);						}					}				}				/* We used this flag briefly to mark transition in progress */				ic->ic_flags_ext &= ~IEEE80211_FEXT_SCAN_PENDING;				/* Transition S_INIT -> S_SCAN */				__ieee80211_newstate(vap, nstate, arg);				break;			}			break;		case IEEE80211_S_SCAN:		case IEEE80211_S_AUTH:		case IEEE80211_S_ASSOC:			/* this VAP was scanning */			/* STA in WDS/Repeater needs to bring up other VAPs */			if (ostate == IEEE80211_S_SCAN || 			    ostate == IEEE80211_S_AUTH ||			    ostate == IEEE80211_S_ASSOC) {				/* Transition (S_SCAN|S_AUTH|S_ASSOC) -> 				 * S_SCAN */				__ieee80211_newstate(vap, nstate, arg);			} else {				/* Someone else is scanning, so block the 				 * transition */				vap->iv_flags_ext |= 					IEEE80211_FEXT_SCAN_PENDING;				__ieee80211_newstate(vap, IEEE80211_S_INIT, 						arg);				blocked = 1;			}			break;		case IEEE80211_S_INIT:			/* Transition S_INIT -> S_SCAN */			__ieee80211_newstate(vap, nstate, arg);			break;		}		break;	case IEEE80211_S_RUN:		/* this VAP was scanning */		/* STA in WDS/Repeater needs to bring up other VAPs  */		if (ostate == IEEE80211_S_SCAN || 		    ostate == IEEE80211_S_AUTH ||		    ostate == IEEE80211_S_ASSOC) {			/* Transition (S_SCAN|S_AUTH|S_ASSOC) -> S_RUN */			__ieee80211_newstate(vap, nstate, arg);			/* Then bring up all other vaps pending on the scan */			dstate = get_dominant_state(ic);			if (dstate == IEEE80211_S_RUN) {				TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {					if ((vap != tmpvap) && 					    (tmpvap->iv_opmode != 					     IEEE80211_M_MONITOR) && 					    (tmpvap->iv_flags_ext & 					     IEEE80211_FEXT_SCAN_PENDING)) {						IEEE80211_DPRINTF(vap, 								IEEE80211_MSG_STATE, 								"%s: Clearing "								"SCAN_PENDING "								"flag from VAP "								"%p [%s] and "								"transitioning "								"to RUN state.\n", 								__func__, tmpvap, 								tmpvap->iv_nickname);						tmpvap->iv_flags_ext &= 							~IEEE80211_FEXT_SCAN_PENDING;						if (tmpvap->iv_state != 								IEEE80211_S_RUN) {							tmpvap->iv_newstate(tmpvap, 									IEEE80211_S_RUN, 0);						} else if (tmpvap->iv_opmode == 								IEEE80211_M_HOSTAP) {							/* Force other AP through 							 * -> INIT -> RUN to make							 * sure beacons are 							 * reallocated */							tmpvap->iv_newstate(tmpvap, 									IEEE80211_S_INIT, 0);							tmpvap->iv_newstate(tmpvap, 									IEEE80211_S_RUN, 0);						}					}				}			}		} else if (dstate == IEEE80211_S_SCAN) {			/* Force to scan pending... someone is scanning */			vap->iv_flags_ext |= IEEE80211_FEXT_SCAN_PENDING;			__ieee80211_newstate(vap, IEEE80211_S_INIT, arg);			blocked = 1;		} else {			__ieee80211_newstate(vap, nstate, arg);		}		break;	default:		__ieee80211_newstate(vap, nstate, arg);	}	IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, 		"%s: %s requested transition %s -> %s on VAP %p [%s].  "		"Dominant state is %s.\n",		__func__,		(blocked ? "BLOCKED" : "ALLOWED"),		ieee80211_state_name[ostate],		ieee80211_state_name[nstate],		vap,		vap->iv_nickname,		ieee80211_state_name[dstate]);	dump_vap_states(ic, vap);	return 0;}#ifdef ATH_SUPERG_XR/* * start the XR vap . * called from a timer when normal vap enters RUN state . */static voidieee80211_start_xrvap(unsigned long data){	struct ieee80211vap *vap = (struct ieee80211vap *)data;	/* make sure that the normal vap is still in RUN state */	if (vap->iv_xrvap->iv_state == IEEE80211_S_RUN)		ieee80211_init(vap->iv_dev, 0);}#endif

⌨️ 快捷键说明

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