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

📄 ieee80211_proto.c

📁 madwifi上的atheros无线网卡驱动源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	/*	 * Select mode; we can be called early in which case we	 * always use auto mode.  We know we'll be called when	 * entering the RUN state with bsschan setup properly	 * so state will eventually get set correctly	 */	if (ic->ic_bsschan != IEEE80211_CHAN_ANYC)		mode = ieee80211_chan2mode(ic->ic_bsschan);	else		mode = IEEE80211_MODE_AUTO;        if ((vap->iv_opmode == IEEE80211_M_HOSTAP &&	     (wme->wme_flags & WME_F_AGGRMODE) != 0) ||	    (vap->iv_opmode != IEEE80211_M_HOSTAP &&	     (vap->iv_bss->ni_flags & IEEE80211_NODE_QOS) == 0) ||	    (vap->iv_flags & IEEE80211_F_WME) == 0) {		struct ieee80211vap *tmpvap;		u_int8_t burstEnabled = 0;		/* check if bursting  enabled on at least one vap */		TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {			if (tmpvap->iv_ath_cap & IEEE80211_ATHC_BURST) {				burstEnabled = 1;				break;			}		}		wme->wme_chanParams.cap_wmeParams[WME_AC_BE].wmep_aifsn =			phyParam[mode].aifsn;		wme->wme_chanParams.cap_wmeParams[WME_AC_BE].wmep_logcwmin =			phyParam[mode].logcwmin;		wme->wme_chanParams.cap_wmeParams[WME_AC_BE].wmep_logcwmax =			phyParam[mode].logcwmax;				wme->wme_chanParams.cap_wmeParams[WME_AC_BE].wmep_txopLimit =			burstEnabled ? phyParam[mode].txopLimit : 0;		wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE].wmep_aifsn =			phyParam[mode].aifsn;		wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE].wmep_logcwmin =			phyParam[mode].logcwmin;		wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE].wmep_logcwmax =			phyParam[mode].logcwmax;		wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE].wmep_txopLimit =			burstEnabled ? phyParam[mode].txopLimit : 0;			}		if (ic->ic_opmode == IEEE80211_M_HOSTAP &&	    ic->ic_sta_assoc < 2 && (wme->wme_flags & WME_F_AGGRMODE) != 0) {		static const u_int8_t logCwMin[IEEE80211_MODE_MAX] = {			/* IEEE80211_MODE_AUTO  */   3,					/* IEEE80211_MODE_11A   */   3,			/* IEEE80211_MODE_11B   */   4,			/* IEEE80211_MODE_11G   */   3,			/* IEEE80211_MODE_FH    */   4,				/* IEEE80211_MODE_TURBO_A */ 3,			/* IEEE80211_MODE_TURBO_G */ 3		};		wme->wme_chanParams.cap_wmeParams[WME_AC_BE].wmep_logcwmin =			wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE].wmep_logcwmin =			logCwMin[mode];	}	if (vap->iv_opmode == IEEE80211_M_HOSTAP) {	/* XXX ibss? */		/*		 * Arrange for a beacon update and bump the parameter		 * set number so associated stations load the new values.		 */		wme->wme_bssChanParams.cap_info_count =			(wme->wme_bssChanParams.cap_info_count + 1) & WME_QOSINFO_COUNT;		vap->iv_flags |= IEEE80211_F_WMEUPDATE;	}	wme->wme_update(ic);	IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME,		"%s: WME params updated, cap_info 0x%x\n", __func__,		vap->iv_opmode == IEEE80211_M_STA ?			wme->wme_wmeChanParams.cap_info_count :			wme->wme_bssChanParams.cap_info_count);}voidieee80211_wme_updateparams(struct ieee80211vap *vap){	struct ieee80211com *ic = vap->iv_ic;	if (ic->ic_caps & IEEE80211_C_WME) {		IEEE80211_LOCK(ic);		ieee80211_wme_updateparams_locked(vap);		IEEE80211_UNLOCK(ic);	}}/* * Start a vap.  If this is the first vap running on the * underlying device then we first bring it up. */intieee80211_init(struct net_device *dev, int forcescan){#define	IS_RUNNING(_dev) \	((_dev->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))	struct ieee80211vap *vap = dev->priv;	struct ieee80211com *ic = vap->iv_ic;	struct net_device *parent = ic->ic_dev;	IEEE80211_DPRINTF(vap,		IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,		"start running (state=%d)\n", vap->iv_state);	if ((dev->flags & IFF_RUNNING) == 0) {		if (ic->ic_nopened++ == 0 &&		    (parent->flags & IFF_RUNNING) == 0)			dev_open(parent);		/*		 * Mark us running.  Note that we do this after		 * opening the parent device to avoid recursion.		 */		dev->flags |= IFF_RUNNING;		/* mark us running */	}	/*	 * If the parent is up and running, then kick the	 * 802.11 state machine as appropriate.	 * XXX parent should always be up+running	 */	if (IS_RUNNING(ic->ic_dev) &&	    ic->ic_roaming != IEEE80211_ROAMING_MANUAL) {		if (vap->iv_opmode == IEEE80211_M_STA) {			/*			 * Try to be intelligent about clocking the state			 * machine.  If we're currently in RUN state then			 * we should be able to apply any new state/parameters			 * simply by re-associating.  Otherwise we need to			 * re-scan to select an appropriate ap.			 */ 			if (vap->iv_state != IEEE80211_S_RUN || forcescan)				ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);			else				ieee80211_new_state(vap, IEEE80211_S_ASSOC, 1);		} else {			/*			 * When the old state is running the vap must 			 * be brought to init.			 */			if (vap->iv_state == IEEE80211_S_RUN)				ieee80211_new_state(vap, IEEE80211_S_INIT, -1); 					/*			 * For monitor+wds modes there's nothing to do but			 * start running.  Otherwise, if this is the first			 * vap to be brought up, start a scan which may be			 * preempted if the station is locked to a particular			 * channel.			 */			if (vap->iv_opmode == IEEE80211_M_MONITOR ||			    vap->iv_opmode == IEEE80211_M_WDS) {				ieee80211_new_state(vap, IEEE80211_S_RUN, -1);			} else				ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);		}	}	return 0;#undef IS_RUNNING}intieee80211_open(struct net_device *dev){	return ieee80211_init(dev, 0);}/* * Start all runnable vap's on a device. */voidieee80211_start_running(struct ieee80211com *ic){	struct ieee80211vap *vap;	struct net_device *dev;	/* XXX locking */	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {		dev = vap->iv_dev;		if ((dev->flags & IFF_UP) && !(dev->flags & IFF_RUNNING))	/* NB: avoid recursion */			ieee80211_open(dev);	}}EXPORT_SYMBOL(ieee80211_start_running);/* * Stop a vap.  We force it down using the state machine * then mark it's device not running.  If this is the last * vap running on the underlying device then we close it * too to ensure it will be properly initialized when the * next vap is brought up. */intieee80211_stop(struct net_device *dev){	struct ieee80211vap *vap = dev->priv;	struct ieee80211com *ic = vap->iv_ic;	struct net_device *parent = ic->ic_dev;	IEEE80211_DPRINTF(vap,		IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,		"%s\n", "stop running");	ieee80211_new_state(vap, IEEE80211_S_INIT, -1);	if (dev->flags & IFF_RUNNING) {		dev->flags &= ~IFF_RUNNING;		/* mark us stopped */		del_timer(&vap->iv_mgtsend);		if (--ic->ic_nopened == 0 && (parent->flags & IFF_RUNNING))			dev_close(parent);	}#ifdef ATH_SUPERG_XR	/*	 * also stop the XR vap. 	 */	if (vap->iv_xrvap && !(vap->iv_flags & IEEE80211_F_XR)) {		ieee80211_stop(vap->iv_xrvap->iv_dev);		del_timer(&vap->iv_xrvapstart);		vap->iv_xrvap->iv_dev->flags = dev->flags;	}#endif	return 0;}EXPORT_SYMBOL(ieee80211_stop);/* * Stop all vap's running on a device. */voidieee80211_stop_running(struct ieee80211com *ic){	struct ieee80211vap *vap;	struct net_device *dev;	/* XXX locking */	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {		dev = vap->iv_dev;		if (dev->flags & IFF_RUNNING)	/* NB: avoid recursion */			ieee80211_stop(dev);	}}EXPORT_SYMBOL(ieee80211_stop_running);#ifdef ATH_SUPERG_DYNTURBO/* * Switch between turbo and non-turbo operating modes. * Use the specified channel flags to locate the new * channel, update 802.11 state, and then call back into * the driver to effect the change. */voidieee80211_dturbo_switch(struct ieee80211com *ic, int newflags){	/* XXX use first vap for debug flags */	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);	struct ieee80211_channel *chan;	chan = ieee80211_find_channel(ic, ic->ic_bsschan->ic_freq, newflags);	if (chan == NULL) {		/* XXX should not happen */		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPG,			"%s: no channel with freq %u flags 0x%x\n",			__func__, ic->ic_bsschan->ic_freq, newflags);		return;	}	IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPG,		"%s: %s -> %s (freq %u flags 0x%x)\n", __func__,		ieee80211_phymode_name[ieee80211_chan2mode(ic->ic_bsschan)],		ieee80211_phymode_name[ieee80211_chan2mode(chan)],		chan->ic_freq, chan->ic_flags);	ic->ic_bsschan = chan;	ic->ic_prevchan = ic->ic_curchan;	ic->ic_curchan = chan;	ic->ic_set_channel(ic);	/* NB: do not need to reset ERP state because in sta mode */}EXPORT_SYMBOL(ieee80211_dturbo_switch);#endif /* ATH_SUPERG_DYNTURBO */voidieee80211_beacon_miss(struct ieee80211com *ic){	struct ieee80211vap *vap;	if (ic->ic_flags & IEEE80211_F_SCAN) {		/* XXX check ic_curchan != ic_bsschan? */		return;	}	/* XXX locking */	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {		IEEE80211_DPRINTF(vap,			IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,			"%s\n", "beacon miss");		/*		 * Our handling is only meaningful for stations that are		 * associated; any other conditions else will be handled		 * through different means (e.g. the tx timeout on mgt frames).		 */		if (vap->iv_opmode != IEEE80211_M_STA ||		    vap->iv_state != IEEE80211_S_RUN)			continue;		if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {#ifdef ATH_SUPERG_DYNTURBO			/* 			 * If we receive a beacon miss interrupt when using			 * dynamic turbo, attempt to switch modes before			 * reassociating.			 */			if (IEEE80211_ATH_CAP(vap, vap->iv_bss, IEEE80211_ATHC_TURBOP))				ieee80211_dturbo_switch(ic,					ic->ic_bsschan->ic_flags ^ IEEE80211_CHAN_TURBO);#endif /* ATH_SUPERG_DYNTURBO */			/*			 * Try to reassociate before scanning for a new ap.			 */			ieee80211_new_state(vap, IEEE80211_S_ASSOC, 1);		} else {			/*			 * Somebody else is controlling state changes (e.g.			 * a user-mode app) don't do anything that would			 * confuse them; just drop into scan mode so they'll			 * notified of the state change and given control.			 */			ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);		}	}}EXPORT_SYMBOL(ieee80211_beacon_miss);/* * STA software beacon timer callback. This is called * only when we have a series beacon misses. */static voidieee80211_sta_swbmiss(unsigned long arg){	struct ieee80211vap *vap = (struct ieee80211vap *) arg;	ieee80211_beacon_miss(vap->iv_ic);}/* * Per-ieee80211vap watchdog timer callback.  This * is used only to timeout the xmit of management frames. */static voidieee80211_tx_timeout(unsigned long arg){	struct ieee80211vap *vap = (struct ieee80211vap *) arg;	IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,		"%s: state %s%s\n", __func__,		ieee80211_state_name[vap->iv_state],		vap->iv_ic->ic_flags & IEEE80211_F_SCAN ? ", scan active" : "");	if (vap->iv_state != IEEE80211_S_INIT &&	    (vap->iv_ic->ic_flags & IEEE80211_F_SCAN) == 0) {		/*		 * NB: it's safe to specify a timeout as the reason here;		 *     it'll only be used in the right state.		 */		ieee80211_new_state(vap, IEEE80211_S_SCAN,			IEEE80211_SCAN_FAIL_TIMEOUT);	}}static voidsta_disassoc(void *arg, struct ieee80211_node *ni){	struct ieee80211vap *vap = arg;	if (ni->ni_vap == vap && ni->ni_associd != 0) {		IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DISASSOC,			IEEE80211_REASON_ASSOC_LEAVE);		ieee80211_node_leave(ni);	}}static voidsta_deauth(void *arg, struct ieee80211_node *ni){	struct ieee80211vap *vap = arg;	if (ni->ni_vap == vap)		IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DEAUTH,			IEEE80211_REASON_ASSOC_LEAVE);}/* * Context: softIRQ (tasklet) and process */intieee80211_new_state(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg){	struct ieee80211com *ic = vap->iv_ic;	int rc;	/* grab the lock so that only one vap can go through transition at any time */	IEEE80211_VAPS_LOCK_BH(ic);	rc = vap->iv_newstate(vap, nstate, arg);	IEEE80211_VAPS_UNLOCK_BH(ic);	return rc;}static int__ieee80211_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg){	struct ieee80211com *ic = vap->iv_ic;	struct ieee80211_node *ni;	enum ieee80211_state ostate;	ostate = vap->iv_state;	IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s\n", __func__,		ieee80211_state_name[ostate], ieee80211_state_name[nstate]);	vap->iv_state = nstate;			/* state transition */	del_timer(&vap->iv_mgtsend);	if (vap->iv_opmode != IEEE80211_M_HOSTAP && ostate != IEEE80211_S_SCAN)		ieee80211_cancel_scan(vap);	/* background scan */	ni = vap->iv_bss;			/* NB: no reference held */	switch (nstate) {	case IEEE80211_S_INIT:		switch (ostate) {		case IEEE80211_S_INIT:			break;		case IEEE80211_S_RUN:

⌨️ 快捷键说明

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