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

📄 minstrel.c

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 C
📖 第 1 页 / 共 3 页
字号:
					ndx = sn->max_tp_rate;							} else				ndx = sn->max_tp_rate;		 }		if ((sn->static_rate_ndx != -1) || !mrr)			    *try0 = ATH_TXMAXTRY;		else			    *try0 = sn->retry_adjusted_count[ndx];		KASSERT((ndx < sn->num_rates),			    ("%s: bad ndx (%d/%d) for " MAC_FMT "?",			     dev_info, ndx, sn->num_rates,			     MAC_ADDR(an->an_node.ni_macaddr)));		*rix = sn->rates[ndx].rix;		if (shortPreamble)			    *txrate = sn->rates[ndx].shortPreambleRateCode;		else			    *txrate = sn->rates[ndx].rateCode;}static voidath_rate_get_mrr(struct ath_softc *sc, struct ath_node *an, int shortPreamble,		 size_t frame_size, u_int8_t rix, struct ieee80211_mrr *mrr){		struct minstrel_node *sn = ATH_NODE_MINSTREL(an);		/* Index into the rate table, so for example, it is  0..11. */		int rc1, rc2, rc3;		if (sn->num_rates <= 0) {			DPRINTF(sc, "%s: no rates for " MAC_FMT "\n",					dev_info,					MAC_ADDR(an->an_node.ni_macaddr));			memset(mrr, 0, sizeof(struct ieee80211_mrr));			return;		}		if (sn->is_sampling) {			sn->is_sampling = 0;			if (sn->rs_sample_rate_slower)				rc1 = sn->rs_sample_rate;			else				rc1 = sn->max_tp_rate;		} else {			rc1 = sn->max_tp_rate2;		}		rc2 = sn->max_prob_rate;		rc3 = 0;		KASSERT((rc1 >= 0) && (rc1 < sn->num_rates),			    ("%s: bad rc1 (%d/%d) for " MAC_FMT "?",			     dev_info, rc1, sn->num_rates,			     MAC_ADDR(an->an_node.ni_macaddr)));		KASSERT((rc2 >= 0) && (rc2 < sn->num_rates),			    ("%s: bad rc2 (%d/%d) for " MAC_FMT "?",			     dev_info, rc2, sn->num_rates,			     MAC_ADDR(an->an_node.ni_macaddr)));		KASSERT((rc3 >= 0) && (rc3 < sn->num_rates),			    ("%s: bad rc3 (%d/%d) for " MAC_FMT "?",			     dev_info, rc3, sn->num_rates,			     MAC_ADDR(an->an_node.ni_macaddr)));		if (shortPreamble) {			mrr->rate1 = sn->rates[rc1].shortPreambleRateCode;			mrr->rate2 = sn->rates[rc2].shortPreambleRateCode;			mrr->rate3 = sn->rates[rc3].shortPreambleRateCode;		} else {			mrr->rate1 = sn->rates[rc1].rateCode;			mrr->rate2 = sn->rates[rc2].rateCode;			mrr->rate3 = sn->rates[rc3].rateCode;		}		mrr->retries1 = sn->retry_adjusted_count[rc1];		mrr->retries2 = sn->retry_adjusted_count[rc2];		mrr->retries3 = sn->retry_adjusted_count[rc3];}static voidath_rate_tx_complete(struct ath_softc *sc,		struct ath_node *an, const struct ath_buf *bf){		struct minstrel_node *sn = ATH_NODE_MINSTREL(an);		struct ieee80211com *ic = &sc->sc_ic;		const struct ath_tx_status *ts = &bf->bf_dsstatus.ds_txstat;		const struct ath_desc *ds = &bf->bf_desc[0];		int final_rate = 0;		int tries = 0;		int mrr;		int final_ndx;		int rate0, tries0, ndx0;		int rate1, tries1, ndx1;		int rate2, tries2, ndx2;		int rate3, tries3, ndx3;		/* This is the index in the retry chain we finish at.		 * With no retransmits, it is always 0.		 * int finalTSIdx = ads->final_ts_index; */		final_rate = sc->sc_hwmap[ts->ts_rate & ~HAL_TXSTAT_ALTRATE].ieeerate;		final_ndx = rate_to_ndx(sn, final_rate);		if (final_ndx >= sn->num_rates) {			DPRINTF(sc, "%s: final ndx too high\n", __func__);			final_ndx = 0;		}		if (final_ndx < 0) {			DPRINTF(sc, "%s: final ndx too low\n", __func__);			final_ndx = 0;		}		/* 'tries' is the total number of times we have endeavoured to		 * send this packet, and is a sum of the #attempts at each		 * level in the multi-rate retry chain. */		tries = ts->ts_longretry + 1;		if (sn->num_rates <= 0) {			DPRINTF(sc, "%s: " MAC_FMT " %s no rates yet\n", dev_info,				MAC_ADDR(an->an_node.ni_macaddr), __func__);			return;		}		if (!ts->ts_status)  /* Success when sending a packet*/			sn->rs_ratesuccess[final_ndx]++;		mrr = sc->sc_mrretry &&			!(ic->ic_flags & IEEE80211_F_USEPROT) &&			ENABLE_MRR;		if (!mrr) {			if ((0 <= final_ndx) && (final_ndx < sn->num_rates)) {				/* only one rate was used */				sn->rs_rateattempts[final_ndx] += tries;			}			return;		}		/* Now, query the HAL/hardware to find out the contents of the		 * multirate retry chain. If we have it set to 6, 3, 2, 2, this		 * call will always return 6,3,2,2. For some packets, we can		 * get a mrr of 0, -1, -1, -1, which indicates there is no		 * chain installed for that packet */		rate0 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate0)].ieeerate;		tries0 = MS(ds->ds_ctl2, AR_XmitDataTries0);		ndx0 = rate_to_ndx(sn, rate0);		rate1 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate1)].ieeerate;		tries1 = MS(ds->ds_ctl2, AR_XmitDataTries1);		ndx1 = rate_to_ndx(sn, rate1);		rate2 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate2)].ieeerate;		tries2 = MS(ds->ds_ctl2, AR_XmitDataTries2);		ndx2 = rate_to_ndx(sn, rate2);		rate3 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate3)].ieeerate;		tries3 = MS(ds->ds_ctl2, AR_XmitDataTries3);		ndx3 = rate_to_ndx(sn, rate3);		sn->rs_rateattempts[ndx0] += MIN(tries, tries0);		if (tries <= tries0)			return;		if (tries1 < 0)			return;		tries = tries - tries0;		sn->rs_rateattempts[ndx1] += MIN(tries, tries1);		if (tries <= tries1)			return;		if  (tries2 < 0)			return;		tries = tries - tries1;		sn->rs_rateattempts[ndx2] += MIN(tries, tries2);		if (tries <= tries2)			return;		if  (tries3 < 0)			return;		tries = tries - tries2;		sn->rs_rateattempts[ndx3] += MIN(tries, tries3);}static voidath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew){		DPRINTF(sc, "%s: " MAC_FMT " %s\n", dev_info,			MAC_ADDR(an->an_node.ni_macaddr), __func__);		if (isnew)			ath_rate_ctl_reset(sc, &an->an_node);}static voidath_fill_sample_table(struct ath_softc *sc, struct minstrel_node *sn){	unsigned int num_sample_rates = (sn->num_rates - 1);	/* newIndex varies as 0 .. (num_rates - 2) 	 * The highest index rate is the slowest and is ignored */	unsigned int i, column_index, newIndex;	u_int8_t random_bytes[8];	/* This should be unnecessary if we are assuming storage is provided	 * as zeroed */	memset(sn->rs_sampleTable, 0, sizeof(sn->rs_sampleTable));	sn->rs_sampleColumn = 0;	sn->rs_sampleIndex = 0;	/* Seed value to random number generator, which determines when we	 * send a sample packet at some non-optimal rate	 * FIXME: randomise? */	sn->random_n = 1;	sn->a = 1664525;	sn->b = 1013904223;	if (sn->num_rates > 1) {		for (column_index = 0; column_index < MINSTREL_COLUMNS; column_index++) {			for (i = 0; i < num_sample_rates; i++) {				get_random_bytes(random_bytes, 8);				newIndex = (i + random_bytes[i & 7]) % num_sample_rates;				while (sn->rs_sampleTable[newIndex][column_index] != 0)					newIndex = (newIndex + 1) % num_sample_rates;				sn->rs_sampleTable[newIndex][column_index] = i + 1;			}		}	}		for (column_index = 0; column_index < MINSTREL_COLUMNS; column_index++) {		for (i = 0; i < num_sample_rates && i < IEEE80211_RATE_MAXSIZE; i++) {			DPRINTF(sc, "rs_sampleTable[%2u][%2u] = %2u\n",				i, column_index, sn->rs_sampleTable[i][column_index]);		}	}}/* Initialize the tables for a node. */static voidath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni){	struct minstrel_node *sn = ATH_NODE_MINSTREL(ATH_NODE(ni));	struct ieee80211vap *vap = ni->ni_vap;	const HAL_RATE_TABLE *rt = sc->sc_currates;	unsigned int x;	int retry_index, tx_time;	int srate;	int ndx = 0;	sn->num_rates = 0;	sn->max_tp_rate = 0;	sn->max_tp_rate2 = 0;	sn->max_prob_rate = 0;	sn->packet_count = 0;	sn->sample_count = 0;	sn->is_sampling = 0;	if (rt == NULL) {		DPRINTF(sc, "no rates yet! mode %u\n", sc->sc_curmode);		return;	}	sn->static_rate_ndx = -1;	sn->num_rates = ni->ni_rates.rs_nrates;	for (x = 0; x < ni->ni_rates.rs_nrates; x++) {		sn->rs_rateattempts 	[x] = 0;		sn->rs_thisprob 	[x] = 0;		sn->rs_ratesuccess 	[x] = 0;		sn->rs_lastrateattempts [x] = 0;		sn->rs_lastratesuccess	[x] = 0;		sn->rs_probability	[x] = 0;		sn->rs_succ_hist	[x] = 0;		sn->rs_att_hist 	[x] = 0;		sn->rs_this_tp 		[x] = 0;		sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL;		sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];		if (sn->rates[x].rix == 0xff) {			DPRINTF(sc, "%s: %s ignore bogus rix at %d\n",				dev_info, __func__, x);			continue;		}		sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode;		sn->rates[x].shortPreambleRateCode =			rt->info[sn->rates[x].rix].rateCode |			rt->info[sn->rates[x].rix].shortPreamble;	}		ath_fill_sample_table(sc, sn);		ni->ni_txrate = 0;	if (sn->num_rates <= 0) {		DPRINTF(sc, "%s: %s " MAC_FMT " no rates (fixed %d) \n",			dev_info, __func__, MAC_ADDR(ni->ni_macaddr),			vap->iv_fixed_rate);		/* There are no rates yet; we're done */		return;	}	if (vap->iv_fixed_rate != IEEE80211_FIXED_RATE_NONE) {		srate = sn->num_rates - 1;		/* A fixed rate is to be used; ic_fixed_rate is an		 * index into the supported rate set.  Convert this		 * to the index into the negotiated rate set for		 * the node.  We know the rate is there because the		 * rate set is checked when the station associates. */		/* NB: the rate set is assumed to be sorted. */		for (;				(srate >= 0) &&				(ni->ni_rates.rs_rates[srate] &				 IEEE80211_RATE_VAL) != vap->iv_fixed_rate;				srate--);		KASSERT(srate >= 0,			("fixed rate %d not in rate set", vap->iv_fixed_rate));		sn->static_rate_ndx = srate;		ni->ni_txrate = srate;		DPRINTF(sc, "%s: %s " MAC_FMT " fixed rate %d%sMbps\n",			dev_info, __func__, MAC_ADDR(ni->ni_macaddr),			sn->rates[srate].rate / 2,			(sn->rates[srate].rate % 2) ? ".5 " : " ");		return;	}	for (x = 0; x < ni->ni_rates.rs_nrates; x++) {		if (sn->rates[x].rix == 0xff) {			DPRINTF(sc, "%s: %s ignore bogus rix at %d\n",				dev_info, __func__, x);			continue;		}		sn->rs_rateattempts	[x] = 0;		sn->rs_thisprob		[x] = 0;		sn->rs_ratesuccess 	[x] = 0;		sn->rs_probability 	[x] = 0;		sn->rs_lastrateattempts [x] = 0;		sn->rs_lastratesuccess 	[x] = 0;		sn->rs_succ_hist 	[x] = 0;		sn->rs_att_hist 	[x] = 0;		sn->perfect_tx_time 	[x] =			calc_usecs_unicast_packet(sc, 1200,						  sn->rates[x].rix,						  0, 0);		sn->retry_count 	[x] = 1;		sn->retry_adjusted_count[x] = 1;		for (retry_index = 2; retry_index < ATH_TXMAXTRY; retry_index++) {			tx_time = calc_usecs_unicast_packet(sc, 1200,					sn->rates[x].rix, 0, retry_index);			if (tx_time > ath_segment_size)				break;			sn->retry_count[x] = retry_index;			sn->retry_adjusted_count[x] = retry_index;		}	}#if 0	DPRINTF(sc, "%s: Retry table for this node\n", __func__);	for (x = 0; x < ni->ni_rates.rs_nrates; x++)		DPRINTF(sc, "%2d  %2d %6d  \n", x, sn->retry_count[x],				sn->perfect_tx_time[x]);#endif	/* Set the initial rate */	for (ndx = sn->num_rates - 1; ndx > 0; ndx--)		if (sn->rates[ndx].rate <= 72)			break;	sn->current_rate = ndx;	ni->ni_txrate = sn->current_rate;}static voidath_rate_cb(void *arg, struct ieee80211_node *ni)

⌨️ 快捷键说明

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