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

📄 minstrel.c

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 C
📖 第 1 页 / 共 3 页
字号:
{		ath_rate_ctl_reset(netdev_priv(ni->ni_ic->ic_dev), ni);}/* Reset the rate control state for each 802.11 state transition. */static voidath_rate_newstate(struct ieee80211vap *vap, enum ieee80211_state newstate){		struct ieee80211com *ic = vap->iv_ic;		if (newstate == IEEE80211_S_RUN) {			if (ic->ic_opmode != IEEE80211_M_STA) {				/* Sync rates for associated stations and				 * neighbors. */				ieee80211_iterate_nodes(&ic->ic_sta,						ath_rate_cb, NULL);			}			ath_rate_newassoc(netdev_priv(ic->ic_dev),					ATH_NODE(vap->iv_bss), 1);		}}static voidath_timer_function(unsigned long data){	struct minstrel_softc *ssc = (struct minstrel_softc *)data;	struct ath_softc *sc = ssc->sc;	struct ieee80211com *ic;	struct net_device *dev = ssc->sc_dev;	struct timer_list *timer;	unsigned int interval = ath_timer_interval;	if (dev == NULL)		DPRINTF(sc, "%s: 'dev' is null in this timer \n", __func__);	if (sc == NULL)		DPRINTF(sc, "%s: 'sc' is null in this timer\n", __func__);	ic = &sc->sc_ic;	if (ssc->close_timer_now)		return;	if (dev->flags & IFF_RUNNING) {		sc->sc_stats.ast_rate_calls++;		if (ic->ic_opmode == IEEE80211_M_STA) {			struct ieee80211vap *tmpvap;			TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {				/* NB: no reference */				ath_rate_statistics(sc, tmpvap->iv_bss);			}		} else			ieee80211_iterate_nodes(&ic->ic_sta,					ath_rate_statistics, sc);	}	if (ic->ic_opmode == IEEE80211_M_STA)		interval = ath_timer_interval >> 1;	timer  = &(ssc->timer);	if (timer == NULL)		DPRINTF(sc, "%s: timer is null - leave it\n", __func__);	mod_timer(timer, jiffies + ((HZ * interval) / 1000));}static voidath_rate_statistics(void *arg, struct ieee80211_node *ni){	struct ath_node *an = (struct ath_node *)ni;	struct ieee80211_rateset *rs = &ni->ni_rates;	struct minstrel_node *rn = ATH_NODE_MINSTREL(an);	unsigned int i;	u_int32_t p;	u_int32_t micro_secs;	u_int32_t max_prob,    index_max_prob;	u_int32_t max_tp,      index_max_tp,      index_max_tp2;	/* Calculate statistics for each date rate in the table */	/* 'micro_secs' is the time to transmit 1200 bytes, or 9600 bits. */	for (i = 0; i < rs->rs_nrates; i++) {		micro_secs = rn->perfect_tx_time[i];		if (micro_secs == 0)			micro_secs = ONE_SECOND;		if (rn->rs_rateattempts[i] != 0) {			p = (rn->rs_ratesuccess[i] * 18000) /				rn->rs_rateattempts[i];			rn->rs_succ_hist[i] += rn->rs_ratesuccess[i];			rn->rs_att_hist[i]  += rn->rs_rateattempts[i];			rn->rs_thisprob[i] = p;			p = ((p * (100 - ath_ewma_level)) +				(rn->rs_probability[i] * ath_ewma_level)) / 100;			rn->rs_probability[i] = p;			rn->rs_this_tp[i] = p * (ONE_SECOND / micro_secs);			rn->rs_lastratesuccess[i] = rn->rs_ratesuccess[i];			rn->rs_lastrateattempts[i] = rn->rs_rateattempts[i];			rn->rs_ratesuccess[i] = 0;			rn->rs_rateattempts[i] = 0;		} else {			rn->rs_lastratesuccess[i] = 0;			rn->rs_lastrateattempts[i] = 0;		}		/* Sample less often below the 10% chance of success.		 * Sample less often above the 95% chance of success.		 * 'rn->rs_probability' has a scale of 0 (0%) to 18000 (100%),		 * which avoids rounding issues.*/		if ((rn->rs_probability[i] > 17100) ||				(rn->rs_probability[i] < 1800)) {			rn->retry_adjusted_count[i] = rn->retry_count[i] >> 1;			if (rn->retry_adjusted_count[i] > 2)				rn->retry_adjusted_count[i] = 2;		} else			rn->retry_adjusted_count[i] = rn->retry_count[i];		if (rn->retry_adjusted_count[i] == 0)			rn->retry_adjusted_count[i] = 1;	}	/* The High speed rates (e.g 54Mbps) is checked last. If	 * throughput is the same for two rates, we prefer the	 * lower rate, as this has a better chance of success. */	max_prob = 0;	index_max_prob = 0;	max_tp = 0;	index_max_tp  = 0;	index_max_tp2 = 0;	/* This code could have been moved up into the previous	 * loop. More readable to have it here */	for (i = 0; i < rs->rs_nrates; i++) {		if (max_tp < rn->rs_this_tp[i]) {			index_max_tp = i;			max_tp = rn->rs_this_tp[i];		}		if (max_prob <  rn->rs_probability[i]) {			index_max_prob = i;			max_prob = rn->rs_probability[i];		}	}	max_tp = 0;	for (i = 0; i < rs->rs_nrates; i++) {		if ((i != index_max_tp) && (max_tp < rn->rs_this_tp[i])) {			index_max_tp2 = i;			max_tp = rn->rs_this_tp[i];		}	}	rn->max_tp_rate   = index_max_tp;	rn->max_tp_rate2  = index_max_tp2;	rn->max_prob_rate = index_max_prob;	rn->current_rate  = index_max_tp;}static struct ath_ratectrl *ath_rate_attach(struct ath_softc *sc){	struct minstrel_softc *osc;	DPRINTF(sc, "%s: %s\n", dev_info, __func__);	_MOD_INC_USE(THIS_MODULE, return NULL);	osc = kmalloc(sizeof(struct minstrel_softc), GFP_ATOMIC);	if (osc == NULL) {		_MOD_DEC_USE(THIS_MODULE);		return NULL;	}	osc->arc.arc_space = sizeof(struct minstrel_node);	osc->arc.arc_vap_space = 0;	osc->close_timer_now = 0;	init_timer(&osc->timer); 	osc->sc          = sc;	osc->sc_dev      = sc->sc_dev;	osc->timer.function = ath_timer_function;	osc->timer.data = (unsigned long)osc;	mod_timer(&osc->timer, jiffies + HZ);	return &osc->arc;}static voidath_rate_detach(struct ath_ratectrl *arc){ 	struct minstrel_softc *osc = (struct minstrel_softc *)arc;		osc->close_timer_now = 1;		del_timer(&osc->timer);		kfree(osc);		_MOD_DEC_USE(THIS_MODULE);}#ifdef CONFIG_SYSCTLstatic intath_proc_read_nodes(struct ieee80211vap *vap, char *buf, int space){	char *p = buf;	struct ieee80211_node *ni;	struct minstrel_node *odst;	struct ieee80211_node_table *nt =		(struct ieee80211_node_table *)&vap->iv_ic->ic_sta;	unsigned int x = 0;	unsigned int this_tp, this_prob, this_eprob;	struct ath_softc *sc = netdev_priv(vap->iv_ic->ic_dev);	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);	TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {		/* Assume each node needs 1500 bytes */		if ((buf + space) < (p + 1500)) {			if ((buf + space) > (p + 100)) {				p += sprintf(p, "out of room for node "						MAC_FMT "\n\n",						MAC_ADDR(ni->ni_macaddr));				break;			}			DPRINTF(sc, "%s: out of memeory to write "					"all of the nodes\n", __func__);			break;		}		odst = ATH_NODE_MINSTREL(ATH_NODE(ni));		/* Skip ourself */		if (IEEE80211_ADDR_EQ(vap->iv_myaddr, ni->ni_macaddr))			continue;		p += sprintf(p, "rate data for node: " MAC_FMT "\n",				MAC_ADDR(ni->ni_macaddr));		p += sprintf(p, "  rate   throughput EWMA prob this prob this "				"succ/attempt  success attempts\n");		for (x = 0; x < odst->num_rates; x++) {			p += sprintf(p, "%c",				     (x == odst->current_rate) ? 'T' : ' ');			p += sprintf(p, "%c",				     (x == odst->max_tp_rate2) ? 't' : ' ');			p += sprintf(p, "%c",				     (x == odst->max_prob_rate) ? 'P' : ' ');			p += sprintf(p, " %2u%s",				     odst->rates[x].rate / 2,				     (odst->rates[x].rate & 0x1) != 0 ?				      ".5" : "  ");			this_tp = ((odst->rs_this_tp[x] / 18000) * 96) >> 10;			this_prob = odst->rs_thisprob[x] / 18;			this_eprob = odst->rs_probability[x] / 18;			p += sprintf(p, "       %2u.%1u      %2u.%1u  %6u.%1u"					"        %3u(%3u)   %8llu %8llu\n",				     this_tp / 10, this_tp % 10,				     this_eprob / 10, this_eprob % 10,				     this_prob / 10, this_prob % 10,				     odst->rs_lastratesuccess[x],				     odst->rs_lastrateattempts[x],				     (unsigned long long)odst->rs_succ_hist[x],				     (unsigned long long)odst->rs_att_hist[x]);		}		p += sprintf(p, "\n");		p += sprintf(p, "Total packet count::    ideal %d      "				"lookaround %d\n\n",				odst->packet_count, odst->sample_count);	}	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);	return (p - buf);}static intath_proc_ratesample_open(struct inode *inode, struct file *file){	struct proc_ieee80211_priv *pv = NULL;	struct proc_dir_entry *dp = PDE(inode);	struct ieee80211vap *vap = dp->data;	if (!(file->private_data = kzalloc(sizeof(struct proc_ieee80211_priv),			   GFP_KERNEL)))		return -ENOMEM;	/* Initially allocate both read and write buffers */	pv = (struct proc_ieee80211_priv *)file->private_data;	pv->rbuf = vmalloc(MAX_PROC_IEEE80211_SIZE);	if (!pv->rbuf) {		kfree(pv);		return -ENOMEM;	}	pv->wbuf = vmalloc(MAX_PROC_IEEE80211_SIZE);	if (!pv->wbuf) {		vfree(pv->rbuf);		kfree(pv);		return -ENOMEM;	}	memset(pv->wbuf, 0, MAX_PROC_IEEE80211_SIZE);	memset(pv->rbuf, 0, MAX_PROC_IEEE80211_SIZE);	pv->max_wlen = MAX_PROC_IEEE80211_SIZE;	pv->max_rlen = MAX_PROC_IEEE80211_SIZE;	/* Now read the data into the buffer */	pv->rlen = ath_proc_read_nodes(vap, pv->rbuf, MAX_PROC_IEEE80211_SIZE);	return 0;}static struct file_operations ath_proc_ratesample_ops = {	.read = NULL,	.write = NULL,	.open = ath_proc_ratesample_open,	.release = NULL,};static voidath_rate_dynamic_proc_register(struct ieee80211vap *vap){	/* Create proc entries for the rate control algorithm */	ieee80211_proc_vcreate(vap, &ath_proc_ratesample_ops, "rate_info");}#endif /* CONFIG_SYSCTL */static struct ieee80211_rate_ops ath_rate_ops = {	.ratectl_id = IEEE80211_RATE_MINSTREL,	.node_init = ath_rate_node_init,	.node_cleanup = ath_rate_node_cleanup,	.findrate = ath_rate_findrate,	.get_mrr = ath_rate_get_mrr,	.tx_complete = ath_rate_tx_complete,	.newassoc = ath_rate_newassoc,	.newstate = ath_rate_newstate,	.attach = ath_rate_attach,	.detach = ath_rate_detach,	.dynamic_proc_register = ath_rate_dynamic_proc_register,};MODULE_AUTHOR("John Bicket/Derek Smithies");MODULE_DESCRIPTION("Minstrel Rate bit-rate selection algorithm for Atheros devices");#ifdef MODULE_VERSIONMODULE_VERSION(RELEASE_VERSION);#endif#ifdef MODULE_LICENSEMODULE_LICENSE("Dual BSD/GPL");#endifstatic int __init ath_rate_minstrel_init(void){/* Debugging output - disabled as noisy. */#if 0	printk(KERN_INFO "%s: look around rate set to %d%%\n",	       dev_info, ath_lookaround_rate);	printk(KERN_INFO "%s: EWMA rolloff level set to %d%%\n",	       dev_info, ath_ewma_level);	printk(KERN_INFO "%s: max segment size in the MRR set "	       "to %d us\n", dev_info, ath_segment_size);#endif	return ieee80211_rate_register(&ath_rate_ops);}module_init(ath_rate_minstrel_init);static void __exit ath_rate_minstrel_exit(void){	ieee80211_rate_unregister(&ath_rate_ops);}module_exit(ath_rate_minstrel_exit);/* The comment below is magic for those who use emacs to edit this file. *//* With the comment below, the tab key does auto indent to 8 spaces.     *//* * Local Variables: * mode:c * c-file-style:linux * c-basic-offset:8 * End: */

⌨️ 快捷键说明

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