📄 sample.c
字号:
ndx0, tries0, ndx1, tries1, ndx2, tries2, ndx3, tries3, short_tries, ds->ds_txstat.ts_longretry + 1, long_tries > tries0); if (tries1 && finalTSIdx > 0) update_stats(sc, an, frame_size, ndx1, tries1, ndx2, tries2, ndx3, tries3, 0, 0, short_tries, ds->ds_txstat.ts_longretry + 1 - tries0, ds->ds_txstat.ts_status); if (tries2 && finalTSIdx > 1) update_stats(sc, an, frame_size, ndx2, tries2, ndx3, tries3, 0, 0, 0, 0, short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1, ds->ds_txstat.ts_status); if (tries3 && finalTSIdx > 2) update_stats(sc, an, frame_size, ndx3, tries3, 0, 0, 0, 0, 0, 0, short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1 - tries2, ds->ds_txstat.ts_status); }}EXPORT_SYMBOL(ath_rate_tx_complete);voidath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew){ DPRINTF(sc, "%s: %s %s\n", dev_info, ether_sprintf(an->an_node.ni_macaddr), __func__); if (isnew) ath_rate_ctl_reset(sc, &an->an_node);}EXPORT_SYMBOL(ath_rate_newassoc);/* * Initialize the tables for a node. */static voidath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni){ struct ath_node *an = ATH_NODE(ni); struct sample_node *sn = ATH_NODE_SAMPLE(an); struct ieee80211vap *vap = ni->ni_vap; const HAL_RATE_TABLE *rt = sc->sc_currates; int x, y; int srate; sn->num_rates = 0; if (rt == NULL) { printk(KERN_WARNING "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->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; } ni->ni_txrate = 0; sn->num_rates = ni->ni_rates.rs_nrates; if (sn->num_rates <= 0) { DPRINTF(sc, "%s: %s %s no rates (fixed %d) \n", dev_info, __func__, ether_sprintf(ni->ni_macaddr), vap->iv_fixed_rate); /* there are no rates yet we're done */ return; } if (vap->iv_fixed_rate != -1) { 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 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 %s fixed rate %d%sMbps\n", dev_info, __func__, ether_sprintf(ni->ni_macaddr), sn->rates[srate].rate / 2, (sn->rates[srate].rate % 0x1) ? ".5" : " "); return; } for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) { int size = bin_to_size(y); int ndx = 0; sn->packets_sent[y] = 0; sn->current_sample_ndx[y] = -1; sn->last_sample_ndx[y] = 0; for (x = 0; x < ni->ni_rates.rs_nrates; x++) { sn->stats[y][x].successive_failures = 0; sn->stats[y][x].tries = 0; sn->stats[y][x].total_packets = 0; sn->stats[y][x].packets_acked = 0; sn->stats[y][x].last_tx = 0; sn->stats[y][x].perfect_tx_time = calc_usecs_unicast_packet(sc, size, sn->rates[x].rix, 0, 0); sn->stats[y][x].average_tx_time = sn->stats[y][x].perfect_tx_time; } /* set the initial rate */ for (ndx = sn->num_rates-1; ndx > 0; ndx--) if (sn->rates[ndx].rate <= 72) break; sn->current_rate[y] = ndx; } DPRINTF(sc, "%s: %s %s %d rates %d%sMbps (%dus)- %d%sMbps (%dus)\n", dev_info, __func__, ether_sprintf(ni->ni_macaddr), sn->num_rates, sn->rates[0].rate / 2, sn->rates[0].rate % 0x1 ? ".5" : "", sn->stats[1][0].perfect_tx_time, sn->rates[sn->num_rates-1].rate / 2, sn->rates[sn->num_rates-1].rate % 0x1 ? ".5" : "", sn->stats[1][sn->num_rates-1].perfect_tx_time); ni->ni_txrate = sn->current_rate[0];}static voidath_rate_cb(void *arg, struct ieee80211_node *ni){ ath_rate_ctl_reset(ni->ni_ic->ic_dev->priv, ni);}/* * Reset the rate control state for each 802.11 state transition. */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(ic->ic_dev->priv, ATH_NODE(vap->iv_bss), 1); }}EXPORT_SYMBOL(ath_rate_newstate);struct ath_ratectrl *ath_rate_attach(struct ath_softc *sc){ struct sample_softc *osc; DPRINTF(sc, "%s: %s\n", dev_info, __func__); osc = kmalloc(sizeof(struct sample_softc), GFP_ATOMIC); if (osc == NULL) return NULL; osc->arc.arc_space = sizeof(struct sample_node); osc->arc.arc_vap_space = 0; osc->ath_smoothing_rate = ath_smoothing_rate; osc->ath_sample_rate = ath_sample_rate; return &osc->arc;}EXPORT_SYMBOL(ath_rate_attach);voidath_rate_detach(struct ath_ratectrl *arc){ struct sample_softc *osc = (struct sample_softc *) arc; kfree(osc);}EXPORT_SYMBOL(ath_rate_detach);#ifdef CONFIG_SYSCTLstatic intproc_read_nodes(struct ieee80211vap *vap, const int size, char *buf, int space){ char *p = buf; struct ieee80211_node *ni; struct ath_node *an; struct sample_node *sn; struct ieee80211_node_table *nt = (struct ieee80211_node_table *) &vap->iv_ic->ic_sta; int x = 0; int size_bin = 0; TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { /* Assume each node needs 500 bytes */ if (buf + space < p + 500) break; an = ATH_NODE(ni); sn = ATH_NODE_SAMPLE(an); /* Skip ourself */ if (memcmp(vap->iv_myaddr, ni->ni_macaddr, IEEE80211_ADDR_LEN)==0) { continue; } size_bin = size_to_bin(size); p += sprintf(p, "%s\n", ether_sprintf(ni->ni_macaddr)); p += sprintf(p, "rate\ttt\tperfect\tfailed\tpkts\tavg_tries\tlast_tx\n"); for (x = 0; x < sn->num_rates; x++) { int a = 1; int t = 1; p += sprintf(p, "%s", (x == sn->current_rate[size_bin]) ? "*" : " "); p += sprintf(p, "%3d%s", sn->rates[x].rate/2, (sn->rates[x].rate & 0x1) != 0 ? ".5" : " "); p += sprintf(p, "\t%4d\t%4d\t%2d\t%3d", sn->stats[size_bin][x].average_tx_time, sn->stats[size_bin][x].perfect_tx_time, sn->stats[size_bin][x].successive_failures, sn->stats[size_bin][x].total_packets); if (sn->stats[size_bin][x].total_packets) { a = sn->stats[size_bin][x].total_packets; t = sn->stats[size_bin][x].tries; } p += sprintf(p, "\t%d.%02d\t", t/a, (t*100/a) % 100); if (sn->stats[size_bin][x].last_tx) { unsigned d = jiffies - sn->stats[size_bin][x].last_tx; p += sprintf(p, "%d.%02d", d / HZ, d % HZ); } else { p += sprintf(p, "-"); } p += sprintf(p, "\n"); } printk("\n"); } return (p - buf);}intproc_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; int size = 0; if (!(file->private_data = kmalloc(sizeof(struct proc_ieee80211_priv), GFP_KERNEL))) return -ENOMEM; /* intially allocate both read and write buffers */ pv = (struct proc_ieee80211_priv *) file->private_data; memset(pv, 0, sizeof(struct proc_ieee80211_priv)); 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; /* Determine what size packets to get stats for based on proc filename */ size = (int)simple_strtol(dp->name + 10, NULL, 0); /* now read the data into the buffer */ pv->rlen = proc_read_nodes(vap, size, pv->rbuf, MAX_PROC_IEEE80211_SIZE); return 0;}static struct file_operations proc_ratesample_ops = { .read = NULL, .write = NULL, .open = proc_ratesample_open, .release = NULL,};voidath_rate_dynamic_proc_register(struct ieee80211vap *vap){ /* Create proc entries for the rate control algorithm */ ieee80211_proc_vcreate(vap, &proc_ratesample_ops, "ratestats_250"); ieee80211_proc_vcreate(vap, &proc_ratesample_ops, "ratestats_1600"); ieee80211_proc_vcreate(vap, &proc_ratesample_ops, "ratestats_3000"); }EXPORT_SYMBOL(ath_rate_dynamic_proc_register);#endif /* CONFIG_SYSCTL */MODULE_AUTHOR("John Bicket");MODULE_DESCRIPTION("SampleRate bit-rate selection algorithm for Atheros devices");#ifdef MODULE_VERSIONMODULE_VERSION(RELEASE_VERSION);#endif#ifdef MODULE_LICENSEMODULE_LICENSE("Dual BSD/GPL");#endifstatic int __initinit_ath_rate_sample(void){ printk(KERN_INFO "%s: %s\n", dev_info, version); return (0);}module_init(init_ath_rate_sample);static void __exitexit_ath_rate_sample(void){ printk(KERN_INFO "%s: unloaded\n", dev_info);}module_exit(exit_ath_rate_sample);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -