[Madwifi-cvs] madwifi/ath_rate/sample sample.c,1.1,1.2 sample.h,1.1,1.2
Status: Beta
Brought to you by:
otaku
From: Bruno R. <br...@us...> - 2005-03-09 16:42:07
|
Update of /cvsroot/madwifi/madwifi/ath_rate/sample In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2855/ath_rate/sample Modified Files: sample.c sample.h Log Message: sample rate update by John Bicket: 1. use ath_hal_computetxtime so that it will estimate throughput for turbo modes correctly. 2. calculate the txtime independently for a few different packet sizes since delivery probability is affected by packet size. 3. fix setting the bit-rate for management frames. 4. fix ewma to average the first few packets instead of just setting the average to the first packet. Index: sample.h =================================================================== RCS file: /cvsroot/madwifi/madwifi/ath_rate/sample/sample.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** sample.h 7 Mar 2005 15:29:45 -0000 1.1 --- sample.h 9 Mar 2005 16:41:57 -0000 1.2 *************** *** 46,167 **** struct ath_ratectrl arc; /* base state */ }; struct rate_info { ! int rate; ! int rix; ! int rateCode; ! int shortPreambleRateCode; ! ! int average_tx_time; ! int successive_failures; ! int tries; ! int packets_acked; ! int perfect_tx_time; /* transmit time for 0 retries */ }; ! /* per-node state */ ! struct sample_node { ! int packets_sent; ! ! int static_rate_ndx; ! int num_rates; ! ! struct rate_info rates[IEEE80211_RATE_MAXSIZE]; ! int sample_num; }; ! #define WIFI_SLOT_B 20 ! #define WIFI_DIFS_B 50 ! #define WIFI_SIFS_B 10 ! #define WIFI_ACK_B 304 ! #define WIFI_PLCP_HEADER_LONG_B 192 ! #define WIFI_PLCP_HEADER_SHORT_B 192 ! ! #define WIFI_SLOT_A 9 ! #define WIFI_DIFS_A 28 ! #define WIFI_SIFS_A 9 ! #define WIFI_ACK_A 30 ! #define WIFI_PLCP_HEADER_A 20 ! #define is_b_rate(b) ((b == 2) || (b == 4) || (b == 11) || (b == 22)) ! #define WIFI_CW_MIN 31 ! #define WIFI_CW_MAX 1023 #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) ! /* ! * transmit time for data payload + plcp_header ! */ ! unsigned calc_transmit_time(int rate, int length) { ! unsigned t_plcp_header = 96; ! if (rate == 1) { ! t_plcp_header = 192; ! } else if (!is_b_rate(rate)) { ! t_plcp_header = 20; ! } ! return (2 * (t_plcp_header + ((length * 8))))/ rate; ! } /* ! * expected backoff for t tries. */ ! unsigned calc_backoff(int rate, int t) ! { ! int t_slot = is_b_rate(rate) ? WIFI_SLOT_B : WIFI_SLOT_A; ! int cw = WIFI_CW_MIN; ! int x = 0; ! ! /* there is backoff, even for the first packet */ ! for (x = 0; x < t; x++) { ! cw = MIN(WIFI_CW_MAX, (cw + 1) * 2); ! } ! return t_slot * cw / 2; ! } ! ! ! ! unsigned calc_usecs_wifi_packet_tries(int length, ! int rate, ! int try0, int tryN) { ! if (!rate || !length || try0 > tryN) { ! return 99999; ! } ! ! /* pg 205 ieee.802.11.pdf */ ! unsigned t_slot = 20; ! unsigned t_ack = 304; // 192 + 14*8/1 ! unsigned t_difs = 50; ! unsigned t_sifs = 10; ! ! ! if (!is_b_rate(rate)) { ! /* with 802.11g, things are at 6 mbit/s */ ! t_slot = 9; ! t_sifs = 9; ! t_difs = 28; ! t_ack = 30; ! } ! ! int tt = 0; ! int x = 0; ! for (x = try0; x <= tryN; x++) { ! tt += calc_backoff(rate, x) + ! calc_transmit_time(rate, length) + ! t_sifs + t_ack; ! } ! return tt; ! } ! unsigned calc_usecs_wifi_packet(int length, ! int rate, int retries) { ! return calc_usecs_wifi_packet_tries(length, rate, ! 0, retries); } - #define ATH_NODE_SAMPLE(an) ((struct sample_node *)&an[1]) #endif /* _DEV_ATH_RATE_SAMPLE_H */ --- 46,130 ---- struct ath_ratectrl arc; /* base state */ }; + #define ATH_NODE_SAMPLE(an) ((struct sample_node *)&an[1]) struct rate_info { ! int rate; ! int rix; ! int rateCode; ! int shortPreambleRateCode; }; ! struct rate_stats { ! int average_tx_time; ! int successive_failures; ! int tries; ! int total_packets; ! int packets_acked; ! int perfect_tx_time; /* transmit time for 0 retries */ ! int last_tx; }; ! /* ! * for now, we track performance for three different packet ! * size buckets ! */ ! #define NUM_PACKET_SIZE_BINS 3 ! static int packet_size_bins[] = {250, 1600, 3000}; + /* per-node state */ + struct sample_node { + int static_rate_ndx; + int num_rates; ! struct rate_info rates[IEEE80211_RATE_MAXSIZE]; ! ! struct rate_stats stats[NUM_PACKET_SIZE_BINS][IEEE80211_RATE_MAXSIZE]; ! int sample_num[NUM_PACKET_SIZE_BINS]; ! int packets_sent[NUM_PACKET_SIZE_BINS]; ! }; #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) ! #define WIFI_CW_MIN 31 ! #define WIFI_CW_MAX 1023 /* ! * Calculate the transmit duration of a frame. */ ! unsigned calc_usecs_unicast_packet(struct ath_softc *sc, ! int length, ! int rix, int retries) { ! const HAL_RATE_TABLE *rt = sc->sc_currates; ! ! /* pg 205 ieee.802.11.pdf */ ! unsigned t_slot = 20; ! unsigned t_difs = 50; ! unsigned t_sifs = 10; ! int tt = 0; ! int x = 0; ! int cw = WIFI_CW_MIN; ! int cix = rt->info[rix].controlRate; ! KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); ! ! if (rt->info[rix].phy == IEEE80211_T_OFDM) { ! t_slot = 9; ! t_sifs = 9; ! t_difs = 28; ! } ! tt += t_difs; ! tt += (retries+1)*(t_sifs + rt->info[cix].spAckDuration); ! tt += (retries+1)*ath_hal_computetxtime(sc->sc_ah, rt, length, ! rix, AH_TRUE); ! for (x = 0; x <= retries; x++) { ! cw = MIN(WIFI_CW_MAX, (cw + 1) * 2); ! tt += (t_slot * cw/2); ! } ! return tt; } #endif /* _DEV_ATH_RATE_SAMPLE_H */ Index: sample.c =================================================================== RCS file: /cvsroot/madwifi/madwifi/ath_rate/sample/sample.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** sample.c 7 Mar 2005 15:29:45 -0000 1.1 --- sample.c 9 Mar 2005 16:41:57 -0000 1.2 *************** *** 61,67 **** #define SAMPLE_DEBUG #ifdef SAMPLE_DEBUG ! #define DPRINTF(sc, _fmt, ...) do { \ ! if (sc->sc_debug & 0x10) \ ! printk(_fmt, __VA_ARGS__); \ } while (0) #else --- 61,70 ---- #define SAMPLE_DEBUG #ifdef SAMPLE_DEBUG ! enum { ! 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 *************** *** 89,98 **** * file is that the one in this file uses a ewma instead of a window. * */ ! static int ath_smoothing_rate = 90; /* ewma percentage (out of 100) */ static int ath_sample_rate = 10; /* send a different bit-rate 1/X packets */ static void ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *); void --- 92,139 ---- * 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. + * */ ! static int ath_smoothing_rate = 95; /* ewma percentage (out of 100) */ static int ath_sample_rate = 10; /* send a different bit-rate 1/X packets */ static void ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *); + static void ath_rate_ctl_reset(struct ath_softc *, struct ieee80211_node *); + + + + + static __inline int size_to_bin(int size) + { + int x = 0; + 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]; + } + /* + * Setup rate codes for management/control frames. We force + * all such frames to the lowest rate. + */ + static void + ath_rate_setmgtrates(struct ath_softc *sc, struct ath_node *an) + { + const HAL_RATE_TABLE *rt = sc->sc_currates; + KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); + + /* setup rates for management frames */ + /* XXX management/control frames always go at lowest speed */ + an->an_tx_mgtrate = rt->info[0].rateCode; + an->an_tx_mgtratesp = an->an_tx_mgtrate + | rt->info[0].shortPreamble; + } + void *************** *** 100,103 **** --- 141,145 ---- DPRINTF(sc, "%s:\n", __func__); /* NB: assumed to be zero'd by caller */ + ath_rate_setmgtrates(sc, an); } EXPORT_SYMBOL(ath_rate_node_init); *************** *** 114,121 **** struct ath_node *dst, const struct ath_node *src) { - DPRINTF(sc, "%s:\n", __func__); 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)); } --- 156,163 ---- 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]; + DPRINTF(sc, "%s:\n", __func__); memcpy(odst, osrc, sizeof(struct sample_node)); } *************** *** 127,131 **** * or -1 if all the average_tx_times are 0. */ ! inline int best_rate_ndx(struct sample_node *sn) { int x = 0; --- 169,173 ---- * or -1 if all the average_tx_times are 0. */ ! static __inline int best_rate_ndx(struct sample_node *sn, int size_bin) { int x = 0; *************** *** 133,137 **** int best_rate_tt = 0; for (x = 0; x < sn->num_rates; x++) { ! int tt = sn->rates[x].average_tx_time; if (tt > 0) { if (!best_rate_tt || best_rate_tt > tt) { --- 175,179 ---- int best_rate_tt = 0; for (x = 0; x < sn->num_rates; x++) { ! int tt = sn->stats[size_bin][x].average_tx_time; if (tt > 0) { if (!best_rate_tt || best_rate_tt > tt) { *************** *** 141,145 **** } } - return (best_rate_tt) ? best_rate_ndx : -1; } --- 183,186 ---- *************** *** 150,157 **** * and the ndx has not had four successive failures. */ ! inline int pick_sample_ndx(struct sample_node *sn) { int x = 0; ! int best_ndx = best_rate_ndx(sn); int best_tt = 0; int num_eligible = 0; --- 191,198 ---- * and the ndx has not had four successive failures. */ ! static __inline int pick_sample_ndx(struct sample_node *sn, int size_bin) { int x = 0; ! int best_ndx = best_rate_ndx(sn, size_bin); int best_tt = 0; int num_eligible = 0; *************** *** 162,167 **** } ! best_tt = sn->rates[best_ndx].average_tx_time; ! sn->sample_num++; /* --- 203,208 ---- } ! best_tt = sn->stats[size_bin][best_ndx].average_tx_time; ! sn->sample_num[size_bin]++; /* *************** *** 172,177 **** for (x = 0; x < sn->num_rates; x++) { if (x != best_ndx && ! sn->rates[x].perfect_tx_time < best_tt && ! sn->rates[x].successive_failures < 4) { num_eligible++; } --- 213,218 ---- for (x = 0; x < sn->num_rates; x++) { if (x != best_ndx && ! sn->stats[size_bin][x].perfect_tx_time < best_tt && ! sn->stats[size_bin][x].successive_failures < 4) { num_eligible++; } *************** *** 179,187 **** if (num_eligible > 0) { ! int pick = sn->sample_num % num_eligible; for (x = 0; x < sn->num_rates; x++) { if (x != best_ndx && ! sn->rates[x].perfect_tx_time < best_tt && ! sn->rates[x].successive_failures < 4) { if (pick == 0) { return x; --- 220,228 ---- if (num_eligible > 0) { ! int pick = sn->sample_num[size_bin] % num_eligible; for (x = 0; x < sn->num_rates; x++) { if (x != best_ndx && ! sn->stats[size_bin][x].perfect_tx_time < best_tt && ! sn->stats[size_bin][x].successive_failures < 4) { if (pick == 0) { return x; *************** *** 201,205 **** { struct sample_node *sn = ATH_NODE_SAMPLE(an); ! if (sn->static_rate_ndx != -1) { *try0 = 4; --- 242,249 ---- { struct sample_node *sn = ATH_NODE_SAMPLE(an); ! int x; ! int ndx = 0; ! int size_bin = size_to_bin(frameLen); ! int best_ndx = best_rate_ndx(sn, size_bin); if (sn->static_rate_ndx != -1) { *try0 = 4; *************** *** 208,215 **** return; } ! int ndx = 0; ! *try0 = 4; ! int best_ndx = best_rate_ndx(sn); ! if (!sn->packets_sent || sn->packets_sent % ath_sample_rate > 0) { /* * for most packets, send the packet at the bit-rate with --- 252,261 ---- return; } ! ! *try0 = 2; ! ! best_ndx = best_rate_ndx(sn, size_bin); ! if (!sn->packets_sent[size_bin] || ! sn->packets_sent[size_bin] % ath_sample_rate > 0) { /* * for most packets, send the packet at the bit-rate with *************** *** 223,239 **** * that hasn't failed. */ - *try0 = 2; for (ndx = sn->num_rates-1; ndx >= 0; ndx--) { ! if (sn->rates[ndx].successive_failures == 0) { break; } } } } else { ! /* send the packet at a different bit-rate */ ! ndx = pick_sample_ndx(sn); ! if (best_ndx != ndx) { ! *try0 = 2; } } --- 269,299 ---- * that hasn't failed. */ for (ndx = sn->num_rates-1; ndx >= 0; ndx--) { ! if (sn->stats[size_bin][ndx].successive_failures == 0) { break; } } } + if (size_bin == 0) { + /* update the visible txrate for this node */ + an->an_node.ni_txrate = ndx; + } } else { ! /* ! * before we pick a bit-rate to "sample", clear any ! * stale stuff out. ! */ ! for (x = 0; x < sn->num_rates; x++) { ! if (jiffies - sn->stats[size_bin][x].last_tx > ((HZ * 10000)/1000)) { ! sn->stats[size_bin][x].average_tx_time = sn->stats[size_bin][x].perfect_tx_time; ! sn->stats[size_bin][x].successive_failures = 0; ! sn->stats[size_bin][x].tries = 0; ! sn->stats[size_bin][x].total_packets = 0; ! sn->stats[size_bin][x].packets_acked = 0; ! } } + + /* send the packet at a different bit-rate */ + ndx = pick_sample_ndx(sn, size_bin); } *************** *** 247,257 **** } ! ! sn->packets_sent++; ! DPRINTF(sc, "packets %d rate %d ndx %d rateCode %d try0 %d average %d\n", ! sn->packets_sent, ! sn->rates[ndx].rate, ndx, sn->rates[ndx].rateCode, ! *try0, sn->rates[*rix].average_tx_time); ! } EXPORT_SYMBOL(ath_rate_findrate); --- 307,311 ---- } ! sn->packets_sent[size_bin]++; } EXPORT_SYMBOL(ath_rate_findrate); *************** *** 262,272 **** { struct sample_node *sn = ATH_NODE_SAMPLE(an); ! int best_ndx = best_rate_ndx(sn); ! int rateCode = 0; ! if (best_ndx == -1) { /* * no packet has succeeded, so also try twice at the lowest bitate. */ ! rateCode = sn->rates[0].shortPreambleRateCode; } else if (sn->rates[best_ndx].rix != rix) { /* --- 316,333 ---- { struct sample_node *sn = ATH_NODE_SAMPLE(an); ! int rateCode = -1; ! int frame_size = ds->ds_ctl0 & 0x0fff; /* low-order 12 bits of ds_ctl0 */ ! int size_bin = size_to_bin(frame_size); ! int best_ndx = best_rate_ndx(sn, size_bin); ! ! if (best_ndx == -1 || !sn->stats[size_bin][best_ndx].packets_acked) { /* * no packet has succeeded, so also try twice at the lowest bitate. */ ! if (shortPreamble) { ! rateCode = sn->rates[0].shortPreambleRateCode; ! } else { ! rateCode = sn->rates[0].rateCode; ! } } else if (sn->rates[best_ndx].rix != rix) { /* *************** *** 274,284 **** * so if it fails try at the best bit-rate. */ ! rateCode = sn->rates[best_ndx].shortPreambleRateCode; } - ath_hal_setupxtxdesc(sc->sc_ah, ds - , rateCode, 2 /* series 1 */ - , 0, 0 /* series 2 */ - , 0, 0 /* series 3 */ - ); } --- 335,351 ---- * so if it fails try at the best bit-rate. */ ! if (shortPreamble) { ! rateCode = sn->rates[MAX(0,best_ndx-1)].shortPreambleRateCode; ! } else { ! rateCode = sn->rates[MAX(0,best_ndx-1)].rateCode; ! } ! } ! if (rateCode != -1) { ! ath_hal_setupxtxdesc(sc->sc_ah, ds ! , rateCode, 1 /* series 1 */ ! , rateCode, 1 /* series 2 */ ! , rateCode, 1 /* series 3 */ ! ); } } *************** *** 290,300 **** { struct sample_node *sn = ATH_NODE_SAMPLE(an); ! int rate = sc->sc_hwmap[ds->ds_txstat.ts_rate & IEEE80211_RATE_VAL]; ! int used_alt_rate = ds->ds_txstat.ts_rate & HAL_TXSTAT_ALTRATE; int retries = ds->ds_txstat.ts_longretry; ! int tt = calc_usecs_wifi_packet(1500, rate, MIN(retries, 4)); int rix = -1; int x = 0; ! if (!sn->num_rates) { DPRINTF(sc, "%s: no rates yet\n", __func__); --- 357,371 ---- { struct sample_node *sn = ATH_NODE_SAMPLE(an); ! int rate = sc->sc_hwmap[ds->ds_txstat.ts_rate &~ HAL_TXSTAT_ALTRATE]; int retries = ds->ds_txstat.ts_longretry; ! int initial_rate_failed = ((ds->ds_txstat.ts_rate & HAL_TXSTAT_ALTRATE) ! || ds->ds_txstat.ts_status != 0 || ! retries > 3); ! int tt = 0; int rix = -1; int x = 0; ! int frame_size = ds->ds_ctl0 & 0x0fff; /* low-order 12 bits of ds_ctl0 */ ! int size_bin = size_to_bin(frame_size); ! int size = bin_to_size(size_bin); if (!sn->num_rates) { DPRINTF(sc, "%s: no rates yet\n", __func__); *************** *** 312,335 **** return; } ! DPRINTF(sc, "%s: rate %d rix %d retries %d tt %d success %d ts_rate %d\n", ! __func__, rate, rix, retries, tt, used_alt_rate, ds->ds_txstat.ts_rate); ! ! if (!sn->rates[rix].average_tx_time) { ! sn->rates[rix].average_tx_time = tt; } else { ! sn->rates[rix].average_tx_time = ! ((sn->rates[rix].average_tx_time * ath_smoothing_rate) + (tt * (100 - ath_smoothing_rate))) / 100; } ! if (!used_alt_rate) { ! sn->rates[rix].packets_acked++; ! sn->rates[rix].successive_failures = 0; } else { ! sn->rates[rix].successive_failures++; } ! sn->rates[rix].tries += (1+retries); ! } EXPORT_SYMBOL(ath_rate_tx_complete); --- 383,427 ---- return; } + + tt = calc_usecs_unicast_packet(sc, size, sn->rates[rix].rix, + retries); + + DPRINTF(sc, "%s: rate %d rix %d frame_size %d (%d) retries %d status %d tt %d avg_tt %d perfect_tt %d ts-rate %d\n", + __func__, rate, rix, frame_size, size, retries, initial_rate_failed, tt, + sn->stats[size_bin][rix].average_tx_time, + sn->stats[size_bin][rix].perfect_tx_time, + ds->ds_txstat.ts_rate); ! if (sn->stats[size_bin][rix].total_packets < 7) { ! /* just average the first few packets */ ! int avg_tx = sn->stats[size_bin][rix].average_tx_time; ! int packets = sn->stats[size_bin][rix].total_packets; ! sn->stats[size_bin][rix].average_tx_time = (tt+(avg_tx*packets))/(packets+1); } else { ! /* use a ewma */ ! sn->stats[size_bin][rix].average_tx_time = ! ((sn->stats[size_bin][rix].average_tx_time * ath_smoothing_rate) + (tt * (100 - ath_smoothing_rate))) / 100; } ! if (initial_rate_failed) { ! /* ! * this packet failed - count this as a failure ! * for larger packets also, since we assume ! * if a small packet fails at a lower bit-rate ! * then a larger one will also. ! */ ! int y; ! for (y = size_bin; y < NUM_PACKET_SIZE_BINS; y++) { ! sn->stats[y][rix].successive_failures++; ! sn->stats[y][rix].last_tx = jiffies; ! } } else { ! sn->stats[size_bin][rix].packets_acked++; ! sn->stats[size_bin][rix].successive_failures = 0; } ! sn->stats[size_bin][rix].tries += (1+retries); ! sn->stats[size_bin][rix].last_tx = jiffies; ! sn->stats[size_bin][rix].total_packets++; } EXPORT_SYMBOL(ath_rate_tx_complete); *************** *** 346,349 **** --- 438,481 ---- + static void + ath_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); + int x = 0; + int y = 0; + + for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) { + int size = bin_to_size(y); + sn->packets_sent[y] = 0; + sn->sample_num[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); + sn->stats[y][x].average_tx_time = sn->stats[y][x].perfect_tx_time; + + + if (1) { + DPRINTF(sc, "%s: %d rate %d rix %d rateCode %d perfect_tx_time %d \n", __func__, + x, sn->rates[x].rate, + sn->rates[x].rix, sn->rates[x].rateCode, + sn->stats[0][x].perfect_tx_time); + } + } + + } + + /* set the visible bit-rate to the lowest one available */ + ni->ni_txrate = 0; + + } + /* * Initialize the tables for a node. *************** *** 357,363 **** struct sample_node *sn = ATH_NODE_SAMPLE(an); const HAL_RATE_TABLE *rt = sc->sc_currates; int srate; ! int x = 0; ! DPRINTF(sc, "%s:\n", __func__); KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); --- 489,496 ---- struct sample_node *sn = ATH_NODE_SAMPLE(an); const HAL_RATE_TABLE *rt = sc->sc_currates; + + int x; int srate; ! DPRINTF(sc, "%s:\n", __func__); KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); *************** *** 385,389 **** } 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; --- 518,521 ---- *************** *** 393,411 **** rt->info[sn->rates[x].rix].rateCode | rt->info[sn->rates[x].rix].shortPreamble; ! sn->rates[x].perfect_tx_time = calc_usecs_wifi_packet(1500, ! sn->rates[x].rate, ! 0); ! ! DPRINTF(sc, "%s: %d rate %d rix %d rateCode %d perfect_tx_time %d \n", __func__, ! x, sn->rates[x].rate, ! sn->rates[x].rix, sn->rates[x].rateCode, ! sn->rates[x].perfect_tx_time); - } #undef RATE - - /* XXX management/control frames always go at the lowest speed */ - an->an_tx_mgtrate = rt->info[0].rateCode; - an->an_tx_mgtratesp = an->an_tx_mgtrate | rt->info[0].shortPreamble; } /* --- 525,532 ---- rt->info[sn->rates[x].rix].rateCode | rt->info[sn->rates[x].rix].shortPreamble; ! } ! ath_rate_ctl_reset(sc, ni); #undef RATE } /* *************** *** 423,430 **** */ ni = ic->ic_bss; ! if (state == IEEE80211_S_RUN) { ath_rate_ctl_start(sc, ni); ! } ! } } EXPORT_SYMBOL(ath_rate_newstate); --- 544,558 ---- */ ni = ic->ic_bss; ! ath_rate_ctl_start(sc, ni); ! } else { ! /* ! * When operating as a station the node table holds ! * the AP's that were discovered during scanning. ! * For any other operating mode we want to reset the ! * tx rate state of each node. ! */ ! TAILQ_FOREACH(ni, &ic->ic_node, ni_list) ath_rate_ctl_start(sc, ni); ! } } EXPORT_SYMBOL(ath_rate_newstate); *************** *** 433,438 **** ath_rate_attach(struct ath_softc *sc) { - DPRINTF(sc, "%s:\n", __func__); struct sample_softc *osc; osc = kmalloc(sizeof(struct sample_softc), GFP_ATOMIC); --- 561,566 ---- ath_rate_attach(struct ath_softc *sc) { struct sample_softc *osc; + DPRINTF(sc, "%s:\n", __func__); osc = kmalloc(sizeof(struct sample_softc), GFP_ATOMIC); *************** *** 468,471 **** --- 596,600 ---- }; + static ctl_table ath_rate_static_sysctls[] = { { .ctl_name = CTL_AUTO, |