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

📄 sample.c

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*- * Copyright (c) 2005 John Bicket * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer, *    without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any *    redistribution must be conditioned upon including a substantially *    similar Disclaimer requirement for further binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names *    of any contributors may be used to endorse or promote products derived *    from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $Id: sample.c 3906 2009-01-14 02:54:40Z proski $ *//* * John Bicket's SampleRate control algorithm. */#ifndef AUTOCONF_INCLUDED#include <linux/config.h>#endif#include <linux/version.h>#include <linux/module.h>#include <linux/init.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <linux/random.h>#include <linux/delay.h>#include <linux/cache.h>#include <linux/proc_fs.h>#include <linux/if_arp.h>#include <linux/vmalloc.h>#include <asm/uaccess.h>#include <net80211/if_media.h>#include <net80211/ieee80211_var.h>#include <net80211/ieee80211_rate.h>#include "if_athvar.h"#include "if_ath_hal.h"#include "ah_desc.h"#include "sample.h"#define	SAMPLE_DEBUG#ifdef SAMPLE_DEBUGenum {	ATH_DEBUG_RATE		= 0x00000010,	/* rate control */	ATH_DEBUG_ANY		= 0xffffffff};#define	DPRINTF(sc, m, fmt, ...) do {				\	if (sc->sc_debug & (m))					\		printk(fmt, __VA_ARGS__);			\} while (0)#else#define	DPRINTF(sc, m, fmt, ...) do {				\	(void) sc;						\} while (0)#endif/* * This file is an implementation of the SampleRate algorithm * in "Bit-rate Selection in Wireless Networks" * (http://www.pdos.lcs.mit.edu/papers/jbicket-ms.ps) * * SampleRate chooses the bit-rate it predicts will provide the most * throughput based on estimates of the expected per-packet * transmission time for each bit-rate.  SampleRate periodically sends * packets at bit-rates other than the current one to estimate when * another bit-rate will provide better performance. SampleRate * switches to another bit-rate when its estimated per-packet * transmission time becomes smaller than the current bit-rate's. * SampleRate reduces the number of bit-rates it must sample by * eliminating those that could not perform better than the one * currently being used.  SampleRate also stops probing at a bit-rate * if it experiences several successive losses. * * The difference between the algorithm in the thesis and the one in this * file is that the one in this file uses a ewma instead of a window. * * Also, this implementation tracks the average transmission time for * a few different packet sizes independently for each link. * */#include "release.h"#if 0static char *version = "1.2 (" RELEASE_VERSION ")";#endifstatic char *dev_info = "ath_rate_sample";#define STALE_FAILURE_TIMEOUT_MS 10000#define MIN_SWITCH_MS 1000#define ENABLE_MRR 1static int ath_smoothing_rate = 95;	/* ewma percentage (out of 100) */static int ath_sample_rate = 10;		/* use x% of transmission time 					 * sending at a different bit-rate */static void ath_rate_ctl_reset(struct ath_softc *, struct ieee80211_node *);static __inline intsize_to_bin(int size){	unsigned int x;	for (x = 0; x < NUM_PACKET_SIZE_BINS; x++)		if (size <= packet_size_bins[x])			return x;	return NUM_PACKET_SIZE_BINS - 1;}static __inline intbin_to_size(int index) {	return packet_size_bins[index];}static __inline intrate_to_ndx(struct sample_node *sn, int rate){	unsigned int x;	for (x = 0; x < sn->num_rates; x++)		if (sn->rates[x].rate == rate)			return x;	return -1;}/* * Calculate the transmit duration of a frame. */static unsignedcalc_usecs_unicast_packet(struct ath_softc *sc, int length,	int rix, int short_retries, int long_retries){	const HAL_RATE_TABLE *rt = sc->sc_currates;	int rts, cts;	unsigned t_slot;	unsigned t_difs;	unsigned t_sifs;	struct ieee80211com *ic = &sc->sc_ic;	unsigned int tt = 0;	unsigned int x;	unsigned int cw = ATH_DEFAULT_CWMIN;	unsigned int cix = rt->info[rix].controlRate;	KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));	if (!rt->info[rix].rateKbps) {		printk(KERN_WARNING "rix %u (%u) bad ratekbps %u mode %u\n",		       rix, rt->info[rix].dot11Rate,		       rt->info[rix].rateKbps,		       sc->sc_curmode);		return 0;	}	cix = rt->info[rix].controlRate;	/* 	 * XXX getting mac/phy level timings should be fixed for turbo	 * rates, and there is probably a way to get this from the	 * hal...	 */	switch (rt->info[rix].phy) {	case IEEE80211_T_OFDM:		t_slot = 9;		t_sifs = 16;		t_difs = 28;		/* fall through */	case IEEE80211_T_TURBO:		t_slot = 9;		t_sifs = 8;		t_difs = 28;		break;	case IEEE80211_T_DS:		/* fall through to default */	default:		/* pg 205 ieee.802.11.pdf */		t_slot = 20;		t_difs = 50;		t_sifs = 10;	}	rts = cts = 0;	if ((ic->ic_flags & IEEE80211_F_USEPROT) &&	    rt->info[rix].phy == IEEE80211_T_OFDM) {		if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)			rts = 1;		else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)			cts = 1;		cix = rt->info[sc->sc_protrix].controlRate;	}	if (0 /*length > ic->ic_rtsthreshold */)		rts = 1;	if (rts || cts) {		int ctsrate;		int ctsduration = 0;		if (!rt->info[cix].rateKbps) {			printk(KERN_WARNING "cix %u (%u) bad ratekbps %u mode %u\n",			       cix, rt->info[cix].dot11Rate,			       rt->info[cix].rateKbps,			       sc->sc_curmode);			return 0;		}		ctsrate = rt->info[cix].rateCode | rt->info[cix].shortPreamble;		if (rts)		/* SIFS + CTS */			ctsduration += rt->info[cix].spAckDuration;		ctsduration += ath_hal_computetxtime(sc->sc_ah,						     rt, length, rix, AH_TRUE);		if (cts)	/* SIFS + ACK */			ctsduration += rt->info[cix].spAckDuration;		tt += (short_retries + 1) * ctsduration;	}	tt += t_difs;	tt += (long_retries+1)*(t_sifs + rt->info[rix].spAckDuration);	tt += (long_retries+1)*ath_hal_computetxtime(sc->sc_ah, rt, length,						rix, AH_TRUE);	for (x = 0; x <= short_retries + long_retries; x++) {		cw = MIN(ATH_DEFAULT_CWMAX, (cw + 1) * 2);		tt += (t_slot * cw / 2);	}	return tt;}static voidath_rate_node_init(struct ath_softc *sc, struct ath_node *an){	/* NB: assumed to be zero'd by caller */	ath_rate_ctl_reset(sc, &an->an_node);}static voidath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an){}#if 0static voidath_rate_node_copy(struct ath_softc *sc,	struct ath_node *dst, const struct ath_node *src){	struct sample_node *odst = ATH_NODE_SAMPLE(dst);	const struct sample_node *osrc = (const struct sample_node *)&src[1];	memcpy(odst, osrc, sizeof(struct sample_node));}#endif/* * returns the ndx with the lowest average_tx_time, * or -1 if all the average_tx_times are 0. */static __inline int best_rate_ndx(struct sample_node *sn, int size_bin,	int require_acked_before){	unsigned int x;	unsigned int best_rate_tt = 0;	unsigned int best_rate_ndx = -1;	for (x = 0; x < sn->num_rates; x++) {		unsigned int tt = sn->stats[size_bin][x].average_tx_time;		if (tt <= 0 || (require_acked_before &&		    !sn->stats[size_bin][x].packets_acked))			continue;		/* 9 megabits never works better than 12 */		if (sn->rates[x].rate == 18)			continue;		/* don't use a bit-rate that has been failing */		if (sn->stats[size_bin][x].successive_failures > 3)			continue;		if (!best_rate_tt || best_rate_tt > tt) {			best_rate_tt = tt;			best_rate_ndx = x;		}	}	return best_rate_ndx;}/* * pick a good "random" bit-rate to sample other than the current one */static __inline intpick_sample_ndx(struct sample_node *sn, int size_bin){	unsigned int x;	unsigned current_tt;	int current_ndx;	current_ndx = sn->current_rate[size_bin];	if (current_ndx < 0) {		/* no successes yet, send at the lowest bit-rate */		return 0;	}	current_tt = sn->stats[size_bin][current_ndx].average_tx_time;	for (x = 0; x < sn->num_rates; x++) {		unsigned int ndx = (sn->last_sample_ndx[size_bin] + 1 + x) % sn->num_rates;		/* don't sample the current bit-rate */		if (ndx == current_ndx)			continue;		/* this bit-rate is always worse than the current one */		if (sn->stats[size_bin][ndx].perfect_tx_time > current_tt)			continue;		/* rarely sample bit-rates that fail a lot */		if (time_before(jiffies, sn->stats[size_bin][ndx].last_tx +				((HZ * STALE_FAILURE_TIMEOUT_MS) / 1000)) &&		    sn->stats[size_bin][ndx].successive_failures > 3)			continue;		/* don't sample more than 2 indexes higher 		 * for rates higher than 11 megabits		 */		if (sn->rates[ndx].rate > 22 && ndx > current_ndx + 2)			continue;		/* 9 megabits never works better than 12 */		if (sn->rates[ndx].rate == 18)			continue;		/* if we're using 11 megabits, only sample up to 12 megabits		 */		if (sn->rates[current_ndx].rate == 22 && ndx > current_ndx + 1)			continue;		sn->last_sample_ndx[size_bin] = ndx;		return ndx;	}	return current_ndx;}static voidath_rate_findrate(struct ath_softc *sc, struct ath_node *an,	int shortPreamble, size_t frameLen,	u_int8_t *rix, unsigned int *try0, u_int8_t *txrate){	struct sample_node *sn = ATH_NODE_SAMPLE(an);	struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);	struct ieee80211com *ic = &sc->sc_ic;	unsigned int size_bin, mrr, change_rates;	int ndx, best_ndx;	unsigned average_tx_time;

⌨️ 快捷键说明

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