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

📄 ieee80211_proto.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
		i++;	}	if (okrate == 0 || error != 0 ||	    ((flags & IEEE80211_F_DOFRATE) && fixedrate != vap->iv_fixed_rate))		return badrate | IEEE80211_RATE_BASIC;	else		return RV(okrate);#undef RV}/* * Reset 11g-related state. */voidieee80211_reset_erp(struct ieee80211com *ic, enum ieee80211_phymode mode){#define	IS_11G(m) \	((m) == IEEE80211_MODE_11G || (m) == IEEE80211_MODE_TURBO_G)	ic->ic_flags &= ~IEEE80211_F_USEPROT;	/*	 * Preserve the long slot and nonerp station count if	 * switching between 11g and turboG. Otherwise, inactivity	 * will cause the turbo station to disassociate and possibly	 * try to leave the network.	 * XXX not right if really trying to reset state	 */	if (IS_11G(mode) ^ IS_11G(ic->ic_curmode)) {		ic->ic_nonerpsta = 0;		ic->ic_longslotsta = 0;	}	/*	 * Short slot time is enabled only when operating in 11g	 * and not in an IBSS.  We must also honor whether or not	 * the driver is capable of doing it.	 */	ieee80211_set_shortslottime(ic,		IEEE80211_IS_CHAN_A(ic->ic_curchan) ||		(IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) &&		ic->ic_opmode == IEEE80211_M_HOSTAP &&		(ic->ic_caps & IEEE80211_C_SHSLOT)));	/*	 * Set short preamble and ERP barker-preamble flags.	 */	if (IEEE80211_IS_CHAN_A(ic->ic_curchan) ||	    (ic->ic_caps & IEEE80211_C_SHPREAMBLE)) {		ic->ic_flags |= IEEE80211_F_SHPREAMBLE;		ic->ic_flags &= ~IEEE80211_F_USEBARKER;	} else {		ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;		ic->ic_flags |= IEEE80211_F_USEBARKER;	}#undef IS_11G}/* * Set the short slot time state and notify the driver. */voidieee80211_set_shortslottime(struct ieee80211com *ic, int onoff){	if (onoff)		ic->ic_flags |= IEEE80211_F_SHSLOT;	else		ic->ic_flags &= ~IEEE80211_F_SHSLOT;	/* notify driver */	if (ic->ic_updateslot != NULL)		ic->ic_updateslot(ic->ic_dev);}/* * Check if the specified rate set supports ERP. * NB: the rate set is assumed to be sorted. */intieee80211_iserp_rateset(struct ieee80211com *ic, struct ieee80211_rateset *rs){	static const int rates[] = { 2, 4, 11, 22, 12, 24, 48 };	int i, j;	if (rs->rs_nrates < ARRAY_SIZE(rates))		return 0;	for (i = 0; i < ARRAY_SIZE(rates); i++) {		for (j = 0; j < rs->rs_nrates; j++) {			int r = rs->rs_rates[j] & IEEE80211_RATE_VAL;			if (rates[i] == r)				goto next;			if (r > rates[i])				return 0;		}		return 0;	next:		;	}	return 1;}static const struct ieee80211_rateset basic11g[IEEE80211_MODE_MAX] = {	{ 0 },			/* IEEE80211_MODE_AUTO */	{ 3, { 12, 24, 48 } },	/* IEEE80211_MODE_11A */	{ 2, { 2, 4 } },		/* IEEE80211_MODE_11B */	{ 4, { 2, 4, 11, 22 } },	/* IEEE80211_MODE_11G (mixed b/g) */	{ 0 },			/* IEEE80211_MODE_FH */	{ 3, { 12, 24, 48 } },	/* IEEE80211_MODE_TURBO_A */	{ 4, { 2, 4, 11, 22 } },	/* IEEE80211_MODE_TURBO_G (mixed b/g) */};/* * Mark the basic rates for the 11g rate table based on the * specified mode.  For 11b compatibility we mark only 11b * rates.  There's also a pseudo 11a-mode used to mark only * the basic OFDM rates; this is used to exclude 11b stations * from an 11g bss. */voidieee80211_set11gbasicrates(struct ieee80211_rateset *rs, enum ieee80211_phymode mode){	int i, j;	KASSERT(mode < IEEE80211_MODE_MAX, ("invalid mode %u", mode));	for (i = 0; i < rs->rs_nrates; i++) {		rs->rs_rates[i] &= IEEE80211_RATE_VAL;		for (j = 0; j < basic11g[mode].rs_nrates; j++)			if (basic11g[mode].rs_rates[j] == rs->rs_rates[i]) {				rs->rs_rates[i] |= IEEE80211_RATE_BASIC;				break;			}	}}/* * Deduce the 11g setup by examining the rates * that are marked basic. */enum ieee80211_phymodeieee80211_get11gbasicrates(struct ieee80211_rateset *rs){	struct ieee80211_rateset basic;	int i;	memset(&basic, 0, sizeof(basic));	for (i = 0; i < rs->rs_nrates; i++)		if (rs->rs_rates[i] & IEEE80211_RATE_BASIC)			basic.rs_rates[basic.rs_nrates++] =				rs->rs_rates[i] & IEEE80211_RATE_VAL;	for (i = 0; i < IEEE80211_MODE_MAX; i++)		if (memcmp(&basic, &basic11g[i], sizeof(basic)) == 0)			return i;	return IEEE80211_MODE_AUTO;}voidieee80211_wme_initparams(struct ieee80211vap *vap){	struct ieee80211com *ic = vap->iv_ic;	IEEE80211_LOCK_IRQ(ic);	ieee80211_wme_initparams_locked(vap);	IEEE80211_UNLOCK_IRQ(ic);}voidieee80211_wme_initparams_locked(struct ieee80211vap *vap){	struct ieee80211com *ic = vap->iv_ic;	struct ieee80211_wme_state *wme = &ic->ic_wme;	struct phyParamType {		u_int8_t aifsn;		u_int8_t logcwmin;		u_int8_t logcwmax;		u_int16_t txopLimit;		u_int8_t acm;	};	enum ieee80211_phymode mode;	struct phyParamType *pPhyParam, *pBssPhyParam;	static struct phyParamType phyParamForAC_BE[IEEE80211_MODE_MAX] = {		/* IEEE80211_MODE_AUTO  */ { 3, 4,  6,   0, 0 },		/* IEEE80211_MODE_11A   */ { 3, 4,  6,   0, 0 },		/* IEEE80211_MODE_11B   */ { 3, 5,  7,   0, 0 },		/* IEEE80211_MODE_11G   */ { 3, 4,  6,   0, 0 },		/* IEEE80211_MODE_FH    */ { 3, 5,  7,   0, 0 },		/* IEEE80211_MODE_TURBO */ { 2, 3,  5,   0, 0 },		/* IEEE80211_MODE_TURBO */ { 2, 3,  5,   0, 0 }};	static struct phyParamType phyParamForAC_BK[IEEE80211_MODE_MAX] = {		/* IEEE80211_MODE_AUTO  */ { 7, 4, 10,   0, 0 },		/* IEEE80211_MODE_11A   */ { 7, 4, 10,   0, 0 },		/* IEEE80211_MODE_11B   */ { 7, 5, 10,   0, 0 },		/* IEEE80211_MODE_11G   */ { 7, 4, 10,   0, 0 },		/* IEEE80211_MODE_FH    */ { 7, 5, 10,   0, 0 },		/* IEEE80211_MODE_TURBO */ { 7, 3, 10,   0, 0 },		/* IEEE80211_MODE_TURBO */ { 7, 3, 10,   0, 0 }};	static struct phyParamType phyParamForAC_VI[IEEE80211_MODE_MAX] = {		/* IEEE80211_MODE_AUTO  */ { 1, 3,  4,  94, 0 },		/* IEEE80211_MODE_11A   */ { 1, 3,  4,  94, 0 },		/* IEEE80211_MODE_11B   */ { 1, 4,  5, 188, 0 },		/* IEEE80211_MODE_11G   */ { 1, 3,  4,  94, 0 },		/* IEEE80211_MODE_FH    */ { 1, 4,  5, 188, 0 },		/* IEEE80211_MODE_TURBO */ { 1, 2,  3,  94, 0 },		/* IEEE80211_MODE_TURBO */ { 1, 2,  3,  94, 0 }};	static struct phyParamType phyParamForAC_VO[IEEE80211_MODE_MAX] = {		/* IEEE80211_MODE_AUTO  */ { 1, 2,  3,  47, 0 },		/* IEEE80211_MODE_11A   */ { 1, 2,  3,  47, 0 },		/* IEEE80211_MODE_11B   */ { 1, 3,  4, 102, 0 },		/* IEEE80211_MODE_11G   */ { 1, 2,  3,  47, 0 },		/* IEEE80211_MODE_FH    */ { 1, 3,  4, 102, 0 },		/* IEEE80211_MODE_TURBO */ { 1, 2,  2,  47, 0 },		/* IEEE80211_MODE_TURBO */ { 1, 2,  2,  47, 0 }};	static struct phyParamType bssPhyParamForAC_BE[IEEE80211_MODE_MAX] = {		/* IEEE80211_MODE_AUTO  */ { 3, 4, 10,   0, 0 },		/* IEEE80211_MODE_11A   */ { 3, 4, 10,   0, 0 },		/* IEEE80211_MODE_11B   */ { 3, 5, 10,   0, 0 },		/* IEEE80211_MODE_11G   */ { 3, 4, 10,   0, 0 },		/* IEEE80211_MODE_FH    */ { 3, 5, 10,   0, 0 },		/* IEEE80211_MODE_TURBO */ { 2, 3, 10,   0, 0 },		/* IEEE80211_MODE_TURBO */ { 2, 3, 10,   0, 0 }};	static struct phyParamType bssPhyParamForAC_VI[IEEE80211_MODE_MAX] = {		/* IEEE80211_MODE_AUTO  */ { 2, 3,  4,  94, 0 },		/* IEEE80211_MODE_11A   */ { 2, 3,  4,  94, 0 },		/* IEEE80211_MODE_11B   */ { 2, 4,  5, 188, 0 },		/* IEEE80211_MODE_11G   */ { 2, 3,  4,  94, 0 },		/* IEEE80211_MODE_FH    */ { 2, 4,  5, 188, 0 },		/* IEEE80211_MODE_TURBO */ { 2, 2,  3,  94, 0 },		/* IEEE80211_MODE_TURBO */ { 2, 2,  3,  94, 0 }};	static struct phyParamType bssPhyParamForAC_VO[IEEE80211_MODE_MAX] = {		/* IEEE80211_MODE_AUTO  */ { 2, 2,  3,  47, 0 },		/* IEEE80211_MODE_11A   */ { 2, 2,  3,  47, 0 },		/* IEEE80211_MODE_11B   */ { 2, 3,  4, 102, 0 },		/* IEEE80211_MODE_11G   */ { 2, 2,  3,  47, 0 },		/* IEEE80211_MODE_FH    */ { 2, 3,  4, 102, 0 },		/* IEEE80211_MODE_TURBO */ { 1, 2,  2,  47, 0 },		/* IEEE80211_MODE_TURBO */ { 1, 2,  2,  47, 0 }};	int i;	IEEE80211_LOCK_ASSERT(ic);	if ((ic->ic_caps & IEEE80211_C_WME) == 0)		return;	/*	 * 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;	for (i = 0; i < WME_NUM_AC; i++) {		switch (i) {		case WME_AC_BK:			pPhyParam = &phyParamForAC_BK[mode];			pBssPhyParam = &phyParamForAC_BK[mode];			break;		case WME_AC_VI:			pPhyParam = &phyParamForAC_VI[mode];			pBssPhyParam = &bssPhyParamForAC_VI[mode];			break;		case WME_AC_VO:			pPhyParam = &phyParamForAC_VO[mode];			pBssPhyParam = &bssPhyParamForAC_VO[mode];			break;		case WME_AC_BE:		default:			pPhyParam = &phyParamForAC_BE[mode];			pBssPhyParam = &bssPhyParamForAC_BE[mode];			break;		}		if (ic->ic_opmode == IEEE80211_M_HOSTAP) {			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_acm =				pPhyParam->acm;			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_aifsn =				pPhyParam->aifsn;			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_logcwmin =				pPhyParam->logcwmin;			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_logcwmax =				pPhyParam->logcwmax;			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_txopLimit =				pPhyParam->txopLimit;		} else {			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_acm =				pBssPhyParam->acm;			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_aifsn =				pBssPhyParam->aifsn;			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_logcwmin =				pBssPhyParam->logcwmin;			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_logcwmax =				pBssPhyParam->logcwmax;			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_txopLimit =				pBssPhyParam->txopLimit;		}		wme->wme_wmeBssChanParams.cap_wmeParams[i].wmep_acm =			pBssPhyParam->acm;		wme->wme_wmeBssChanParams.cap_wmeParams[i].wmep_aifsn =			pBssPhyParam->aifsn;		wme->wme_wmeBssChanParams.cap_wmeParams[i].wmep_logcwmin =			pBssPhyParam->logcwmin;		wme->wme_wmeBssChanParams.cap_wmeParams[i].wmep_logcwmax =			pBssPhyParam->logcwmax;		wme->wme_wmeBssChanParams.cap_wmeParams[i].wmep_txopLimit =			pBssPhyParam->txopLimit;	}	/* NB: check ic_bss to avoid NULL deref on initial attach */	if (vap->iv_bss != NULL) {		/*		 * Calculate aggressive mode switching threshold based		 * on beacon interval.		 */		wme->wme_hipri_switch_thresh =			(HIGH_PRI_SWITCH_THRESH * vap->iv_bss->ni_intval) / 100;		ieee80211_wme_updateparams_locked(vap);	}}/* * Update WME parameters for ourself and the BSS. */voidieee80211_wme_updateparams_locked(struct ieee80211vap *vap){	static const struct { u_int8_t aifsn; u_int8_t logcwmin; u_int8_t logcwmax; u_int16_t txopLimit;}	phyParam[IEEE80211_MODE_MAX] = {	      /* IEEE80211_MODE_AUTO  */ { 2, 4, 10, 64 },	      /* IEEE80211_MODE_11A   */ { 2, 4, 10, 64 },	      /* IEEE80211_MODE_11B   */ { 2, 5, 10, 64 },	      /* IEEE80211_MODE_11G   */ { 2, 4, 10, 64 },	      /* IEEE80211_MODE_FH    */ { 2, 5, 10, 64 },	      /* IEEE80211_MODE_TURBO */ { 1, 3, 10, 64 }};	struct ieee80211com *ic = vap->iv_ic;	struct ieee80211_wme_state *wme = &ic->ic_wme;	enum ieee80211_phymode mode;	int i;	IEEE80211_LOCK_ASSERT(vap->iv_ic);	/* set up the channel access parameters for the physical device */	for (i = 0; i < WME_NUM_AC; i++) {		wme->wme_chanParams.cap_wmeParams[i].wmep_aifsn =			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_aifsn;		wme->wme_chanParams.cap_wmeParams[i].wmep_logcwmin =			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_logcwmin;		wme->wme_chanParams.cap_wmeParams[i].wmep_logcwmax =			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_logcwmax;		wme->wme_chanParams.cap_wmeParams[i].wmep_txopLimit =			wme->wme_wmeChanParams.cap_wmeParams[i].wmep_txopLimit;		wme->wme_bssChanParams.cap_wmeParams[i].wmep_aifsn =			wme->wme_wmeBssChanParams.cap_wmeParams[i].wmep_aifsn;		wme->wme_bssChanParams.cap_wmeParams[i].wmep_logcwmin =			wme->wme_wmeBssChanParams.cap_wmeParams[i].wmep_logcwmin;		wme->wme_bssChanParams.cap_wmeParams[i].wmep_logcwmax =			wme->wme_wmeBssChanParams.cap_wmeParams[i].wmep_logcwmax;		wme->wme_bssChanParams.cap_wmeParams[i].wmep_txopLimit =			wme->wme_wmeBssChanParams.cap_wmeParams[i].wmep_txopLimit;	}	/*	 * 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);}EXPORT_SYMBOL(ieee80211_wme_updateparams);voidieee80211_wme_updateparams(struct ieee80211vap *vap){	struct ieee80211com *ic = vap->iv_ic;	if (ic->ic_caps & IEEE80211_C_WME) {		IEEE80211_LOCK_IRQ(ic);		ieee80211_wme_updateparams_locked(vap);		IEEE80211_UNLOCK_IRQ(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 = netdev_priv(dev);	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)) {		if (vap->iv_opmode == IEEE80211_M_STA) {			if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) {				/* 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 

⌨️ 快捷键说明

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