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

📄 sample.c

📁 linux下的wifi源码,可以直接编译测试运行..希望大家能有作用
💻 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 2161 2007-02-27 17:45:56Z 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 "ah_desc.h"#include "sample.h"#define	SAMPLE_DEBUG#ifdef SAMPLE_DEBUGenum {	ATH_DEBUG_RATE		= 0x00000010	/* rate control */};#define	DPRINTF(sc, _fmt, ...) do {				\	if (sc->sc_debug & ATH_DEBUG_RATE)			\		printf(_fmt, __VA_ARGS__);			\} while (0)#else#define	DPRINTF(sc, _fmt, ...)#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"static char *version = "1.2 (" RELEASE_VERSION ")";static 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 int size_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 int bin_to_size(int index) {	return packet_size_bins[index];}static __inline int rate_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 = WIFI_CW_MIN;	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;	}	/* 	 * 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 = rt->info[cix].rateCode;		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].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(WIFI_CW_MAX, (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 int pick_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 (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;}

⌨️ 快捷键说明

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