summaryrefslogtreecommitdiffstats
path: root/sys/dev/ath
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2006-12-13 19:34:35 +0000
committersam <sam@FreeBSD.org>2006-12-13 19:34:35 +0000
commitac0fb656dff8bf7a99867fb9519e91ed32f5aa59 (patch)
tree36c0dfd59922a278ac1cbf77e7391d4dc14c4de1 /sys/dev/ath
parent9e61df7b2c3c1242c94b4c3220ba55584f9434b6 (diff)
downloadFreeBSD-src-ac0fb656dff8bf7a99867fb9519e91ed32f5aa59.zip
FreeBSD-src-ac0fb656dff8bf7a99867fb9519e91ed32f5aa59.tar.gz
Track v0.9.20.3 hal:
o no more ds_vdata in tx/rx descriptors o split h/w tx/rx descriptor from s/w status o as part of the descriptor split change the rate control module api so the ath_buf is passed in to the module so it can fetch both descriptor and status information as needed o add some const poisoning Also for sample rate control algorithm: o split debug msgs (node, rate, any) o uniformly bounds check rate indices (and in some cases correct checks) o move array index ops to after bounds checking o use final tsi from the status block instead of the h/w descriptor o replace h/w descriptor struct's with proper mask+shift defs (this doesn't belong here; everything is known by the driver and should just be sent down so there's no h/w-specific knowledge) MFC after: 1 month
Diffstat (limited to 'sys/dev/ath')
-rw-r--r--sys/dev/ath/ath_rate/amrr/amrr.c7
-rw-r--r--sys/dev/ath/ath_rate/onoe/onoe.c9
-rw-r--r--sys/dev/ath/ath_rate/sample/sample.c288
-rw-r--r--sys/dev/ath/ath_rate/sample/sample.h128
-rw-r--r--sys/dev/ath/if_ath.c139
-rw-r--r--sys/dev/ath/if_athrate.h3
-rw-r--r--sys/dev/ath/if_athvar.h10
7 files changed, 292 insertions, 292 deletions
diff --git a/sys/dev/ath/ath_rate/amrr/amrr.c b/sys/dev/ath/ath_rate/amrr/amrr.c
index abae549..fc72abf 100644
--- a/sys/dev/ath/ath_rate/amrr/amrr.c
+++ b/sys/dev/ath/ath_rate/amrr/amrr.c
@@ -142,11 +142,12 @@ ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
void
ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
- const struct ath_desc *ds, const struct ath_desc *ds0)
+ const struct ath_buf *bf)
{
struct amrr_node *amn = ATH_NODE_AMRR(an);
- int sr = ds->ds_txstat.ts_shortretry;
- int lr = ds->ds_txstat.ts_longretry;
+ const struct ath_tx_status *ts = &bf->bf_status.ds_txstat;
+ int sr = ts->ts_shortretry;
+ int lr = ts->ts_longretry;
int retry_count = sr + lr;
amn->amn_tx_try0_cnt++;
diff --git a/sys/dev/ath/ath_rate/onoe/onoe.c b/sys/dev/ath/ath_rate/onoe/onoe.c
index dc4fada..4cda9e1 100644
--- a/sys/dev/ath/ath_rate/onoe/onoe.c
+++ b/sys/dev/ath/ath_rate/onoe/onoe.c
@@ -159,16 +159,17 @@ ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
void
ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
- const struct ath_desc *ds, const struct ath_desc *ds0)
+ const struct ath_buf *bf)
{
struct onoe_node *on = ATH_NODE_ONOE(an);
+ const struct ath_tx_status *ts = &bf->bf_status.ds_txstat;
- if (ds->ds_txstat.ts_status == 0)
+ if (ts->ts_status == 0)
on->on_tx_ok++;
else
on->on_tx_err++;
- on->on_tx_retr += ds->ds_txstat.ts_shortretry
- + ds->ds_txstat.ts_longretry;
+ on->on_tx_retr += ts->ts_shortretry
+ + ts->ts_longretry;
}
void
diff --git a/sys/dev/ath/ath_rate/sample/sample.c b/sys/dev/ath/ath_rate/sample/sample.c
index 2bdf1ef..a873527 100644
--- a/sys/dev/ath/ath_rate/sample/sample.c
+++ b/sys/dev/ath/ath_rate/sample/sample.c
@@ -78,14 +78,18 @@ __FBSDID("$FreeBSD$");
#define SAMPLE_DEBUG
#ifdef SAMPLE_DEBUG
enum {
- ATH_DEBUG_RATE = 0x00000010 /* rate control */
+ ATH_DEBUG_NODE = 0x00080000, /* node management */
+ ATH_DEBUG_RATE = 0x00000010, /* rate control */
+ ATH_DEBUG_ANY = 0xffffffff
};
-#define DPRINTF(sc, _fmt, ...) do { \
- if (sc->sc_debug & ATH_DEBUG_RATE) \
- printf(_fmt, __VA_ARGS__); \
+#define DPRINTF(sc, m, fmt, ...) do { \
+ if (sc->sc_debug & (m)) \
+ printf(fmt, __VA_ARGS__); \
} while (0)
#else
-#define DPRINTF(sc, _fmt, ...)
+#define DPRINTF(sc, m, fmt, ...) do { \
+ (void) sc; \
+} while (0)
#endif
/*
@@ -147,14 +151,14 @@ rate_to_ndx(struct sample_node *sn, int rate) {
void
ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
{
- DPRINTF(sc, "%s:\n", __func__);
+ DPRINTF(sc, ATH_DEBUG_NODE, "%s:\n", __func__);
/* NB: assumed to be zero'd by caller */
}
void
ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an)
{
- DPRINTF(sc, "%s:\n", __func__);
+ DPRINTF(sc, ATH_DEBUG_NODE, "%s:\n", __func__);
}
@@ -318,18 +322,19 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
if (change_rates) {
if (best_ndx != sn->current_rate[size_bin]) {
- DPRINTF(sc, "%s: %s size %d switch rate %d (%d/%d) -> %d (%d/%d) after %d packets mrr %d\n",
- __func__,
- ether_sprintf(an->an_node.ni_macaddr),
- packet_size_bins[size_bin],
- sn->rates[sn->current_rate[size_bin]].rate,
- sn->stats[size_bin][sn->current_rate[size_bin]].average_tx_time,
- sn->stats[size_bin][sn->current_rate[size_bin]].perfect_tx_time,
- sn->rates[best_ndx].rate,
- sn->stats[size_bin][best_ndx].average_tx_time,
- sn->stats[size_bin][best_ndx].perfect_tx_time,
- sn->packets_since_switch[size_bin],
- mrr);
+ DPRINTF(sc, ATH_DEBUG_RATE,
+"%s: %s size %d switch rate %d (%d/%d) -> %d (%d/%d) after %d packets mrr %d\n",
+ __func__,
+ ether_sprintf(an->an_node.ni_macaddr),
+ packet_size_bins[size_bin],
+ sn->rates[sn->current_rate[size_bin]].rate,
+ sn->stats[size_bin][sn->current_rate[size_bin]].average_tx_time,
+ sn->stats[size_bin][sn->current_rate[size_bin]].perfect_tx_time,
+ sn->rates[best_ndx].rate,
+ sn->stats[size_bin][best_ndx].average_tx_time,
+ sn->stats[size_bin][best_ndx].perfect_tx_time,
+ sn->packets_since_switch[size_bin],
+ mrr);
}
sn->packets_since_switch[size_bin] = 0;
sn->current_rate[size_bin] = best_ndx;
@@ -406,30 +411,51 @@ update_stats(struct ath_softc *sc, struct ath_node *an,
size_bin = size_to_bin(frame_size);
size = bin_to_size(size_bin);
+
+ if (!(0 <= ndx0 && ndx0 < sn->num_rates)) {
+ printf("%s: bogus ndx0 %d, max %u, mode %u\n",
+ __func__, ndx0, sn->num_rates, sc->sc_curmode);
+ return;
+ }
rate = sn->rates[ndx0].rate;
tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx0].rix,
- short_tries-1,
+ short_tries,
MIN(tries0, tries) - 1);
tries_so_far += tries0;
if (tries1 && tries0 < tries) {
+ if (!(0 <= ndx1 && ndx1 < sn->num_rates)) {
+ printf("%s: bogus ndx1 %d, max %u, mode %u\n",
+ __func__, ndx1, sn->num_rates, sc->sc_curmode);
+ return;
+ }
tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx1].rix,
- short_tries-1,
+ short_tries,
MIN(tries1 + tries_so_far, tries) - tries_so_far - 1);
}
tries_so_far += tries1;
if (tries2 && tries0 + tries1 < tries) {
+ if (!(0 <= ndx2 && ndx2 < sn->num_rates)) {
+ printf("%s: bogus ndx2 %d, max %u, mode %u\n",
+ __func__, ndx2, sn->num_rates, sc->sc_curmode);
+ return;
+ }
tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx2].rix,
- short_tries-1,
+ short_tries,
MIN(tries2 + tries_so_far, tries) - tries_so_far - 1);
}
tries_so_far += tries2;
if (tries3 && tries0 + tries1 + tries2 < tries) {
+ if (!(0 <= ndx3 && ndx3 < sn->num_rates)) {
+ printf("%s: bogus ndx3 %d, max %u, mode %u\n",
+ __func__, ndx3, sn->num_rates, sc->sc_curmode);
+ return;
+ }
tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx3].rix,
- short_tries-1,
+ short_tries,
MIN(tries3 + tries_so_far, tries) - tries_so_far - 1);
}
if (sn->stats[size_bin][ndx0].total_packets < (100 / (100 - ssc->ath_smoothing_rate))) {
@@ -467,12 +493,14 @@ update_stats(struct ath_softc *sc, struct ath_node *an,
if (ndx0 == sn->current_sample_ndx[size_bin]) {
- DPRINTF(sc, "%s: %s size %d sample rate %d tries (%d/%d) tt %d avg_tt (%d/%d) status %d\n",
- __func__, ether_sprintf(an->an_node.ni_macaddr),
- size, rate, short_tries, tries, tt,
- sn->stats[size_bin][ndx0].average_tx_time,
- sn->stats[size_bin][ndx0].perfect_tx_time,
- status);
+ DPRINTF(sc, ATH_DEBUG_RATE,
+"%s: %s size %d %s sample rate %d tries (%d/%d) tt %d avg_tt (%d/%d)\n",
+ __func__, ether_sprintf(an->an_node.ni_macaddr),
+ size,
+ status ? "FAIL" : "OK",
+ rate, short_tries, tries, tt,
+ sn->stats[size_bin][ndx0].average_tx_time,
+ sn->stats[size_bin][ndx0].perfect_tx_time);
sn->sample_tt[size_bin] = tt;
sn->current_sample_ndx[size_bin] = -1;
}
@@ -480,117 +508,124 @@ update_stats(struct ath_softc *sc, struct ath_node *an,
void
ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
- const struct ath_desc *ds, const struct ath_desc *ds0)
+ const struct ath_buf *bf)
{
struct ieee80211com *ic = &sc->sc_ic;
struct sample_node *sn = ATH_NODE_SAMPLE(an);
- const struct ar5212_desc *ads = (const struct ar5212_desc *)&ds->ds_ctl0;
+ const struct ath_tx_status *ts = &bf->bf_status.ds_txstat;
+ const struct ath_desc *ds0 = &bf->bf_desc[0];
int final_rate, short_tries, long_tries, frame_size;
- int ndx = -1;
int mrr;
- final_rate = sc->sc_hwmap[ds->ds_txstat.ts_rate &~ HAL_TXSTAT_ALTRATE].ieeerate;
- short_tries = ds->ds_txstat.ts_shortretry + 1;
- long_tries = ds->ds_txstat.ts_longretry + 1;
+ final_rate = sc->sc_hwmap[ts->ts_rate &~ HAL_TXSTAT_ALTRATE].ieeerate;
+ short_tries = ts->ts_shortretry;
+ long_tries = ts->ts_longretry + 1;
frame_size = ds0->ds_ctl0 & 0x0fff; /* low-order 12 bits of ds_ctl0 */
if (frame_size == 0) /* NB: should not happen */
frame_size = 1500;
if (sn->num_rates <= 0) {
- DPRINTF(sc, "%s: %s size %d status %d rate/try %d/%d "
- "no rates yet\n",
- __func__, ether_sprintf(an->an_node.ni_macaddr),
- bin_to_size(size_to_bin(frame_size)),
- ds->ds_txstat.ts_status,
- short_tries, long_tries);
+ DPRINTF(sc, ATH_DEBUG_RATE,
+ "%s: %s size %d %s rate/try %d/%d no rates yet\n",
+ __func__, ether_sprintf(an->an_node.ni_macaddr),
+ bin_to_size(size_to_bin(frame_size)),
+ ts->ts_status ? "FAIL" : "OK",
+ short_tries, long_tries);
return;
}
- mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT);
-
- if (sc->sc_mrretry && ds->ds_txstat.ts_status) {
- /* this packet failed */
- DPRINTF(sc, "%s: %s size %d rate/try %d/%d %d/%d %d/%d %d/%d status %s retries (%d/%d)\n",
- __func__,
- ether_sprintf(an->an_node.ni_macaddr),
- bin_to_size(size_to_bin(frame_size)),
- sc->sc_hwmap[ads->xmit_rate0].ieeerate,
- ads->xmit_tries0,
- sc->sc_hwmap[ads->xmit_rate1].ieeerate,
- ads->xmit_tries1,
- sc->sc_hwmap[ads->xmit_rate2].ieeerate,
- ads->xmit_tries2,
- sc->sc_hwmap[ads->xmit_rate3].ieeerate,
- ads->xmit_tries3,
- ds->ds_txstat.ts_status ? "FAIL" : "OK",
- short_tries,
- long_tries);
+ if (ts->ts_status) { /* this packet failed */
+ DPRINTF(sc, ATH_DEBUG_RATE,
+"%s: %s size %d rate/try [%d/%d %d/%d %d/%d %d/%d] FAIL tries [%d/%d]\n",
+ __func__,
+ ether_sprintf(an->an_node.ni_macaddr),
+ bin_to_size(size_to_bin(frame_size)),
+ sc->sc_hwmap[MS(ds0->ds_ctl3, AR_XmitRate0)].ieeerate,
+ MS(ds0->ds_ctl2, AR_XmitDataTries0),
+ sc->sc_hwmap[MS(ds0->ds_ctl3, AR_XmitRate1)].ieeerate,
+ MS(ds0->ds_ctl2, AR_XmitDataTries1),
+ sc->sc_hwmap[MS(ds0->ds_ctl3, AR_XmitRate2)].ieeerate,
+ MS(ds0->ds_ctl2, AR_XmitDataTries2),
+ sc->sc_hwmap[MS(ds0->ds_ctl3, AR_XmitRate3)].ieeerate,
+ MS(ds0->ds_ctl2, AR_XmitDataTries3),
+ short_tries, long_tries);
}
- if (!mrr || !(ds->ds_txstat.ts_rate & HAL_TXSTAT_ALTRATE)) {
- /* only one rate was used */
- ndx = rate_to_ndx(sn, final_rate);
- DPRINTF(sc, "%s: %s size %d status %d rate/try %d/%d/%d\n",
- __func__, ether_sprintf(an->an_node.ni_macaddr),
- bin_to_size(size_to_bin(frame_size)),
- ds->ds_txstat.ts_status,
- ndx, short_tries, long_tries);
- if (ndx >= 0 && ndx < sn->num_rates) {
- update_stats(sc, an, frame_size,
- ndx, long_tries,
- 0, 0,
- 0, 0,
- 0, 0,
- short_tries, long_tries, ds->ds_txstat.ts_status);
- }
+ mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT);
+ if (!mrr || !(ts->ts_rate & HAL_TXSTAT_ALTRATE)) {
+ int ndx = rate_to_ndx(sn, final_rate);
+
+ /*
+ * Only one rate was used; optimize work.
+ */
+ DPRINTF(sc, ATH_DEBUG_RATE,
+ "%s: %s size %d %s rate/try %d/%d/%d\n",
+ __func__, ether_sprintf(an->an_node.ni_macaddr),
+ bin_to_size(size_to_bin(frame_size)),
+ ts->ts_status ? "FAIL" : "OK",
+ final_rate, short_tries, long_tries);
+ update_stats(sc, an, frame_size,
+ ndx, long_tries,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ short_tries, long_tries, ts->ts_status);
} else {
int rate0, tries0, ndx0;
int rate1, tries1, ndx1;
int rate2, tries2, ndx2;
int rate3, tries3, ndx3;
- int finalTSIdx = ads->final_ts_index;
+ int finalTSIdx = ts->ts_finaltsi;
/*
* Process intermediate rates that failed.
*/
-
- rate0 = sc->sc_hwmap[ads->xmit_rate0].ieeerate;
- tries0 = ads->xmit_tries0;
+ rate0 = sc->sc_hwmap[MS(ds0->ds_ctl3, AR_XmitRate0)].ieeerate;
+ tries0 = MS(ds0->ds_ctl2, AR_XmitDataTries0);
ndx0 = rate_to_ndx(sn, rate0);
-
- rate1 = sc->sc_hwmap[ads->xmit_rate1].ieeerate;
- tries1 = ads->xmit_tries1;
+
+ rate1 = sc->sc_hwmap[MS(ds0->ds_ctl3, AR_XmitRate1)].ieeerate;
+ tries1 = MS(ds0->ds_ctl2, AR_XmitDataTries1);
ndx1 = rate_to_ndx(sn, rate1);
-
- rate2 = sc->sc_hwmap[ads->xmit_rate2].ieeerate;
- tries2 = ads->xmit_tries2;
+
+ rate2 = sc->sc_hwmap[MS(ds0->ds_ctl3, AR_XmitRate2)].ieeerate;
+ tries2 = MS(ds0->ds_ctl2, AR_XmitDataTries2);
ndx2 = rate_to_ndx(sn, rate2);
-
- rate3 = sc->sc_hwmap[ads->xmit_rate3].ieeerate;
- tries3 = ads->xmit_tries3;
+
+ rate3 = sc->sc_hwmap[MS(ds0->ds_ctl3, AR_XmitRate3)].ieeerate;
+ tries3 = MS(ds0->ds_ctl2, AR_XmitDataTries3);
ndx3 = rate_to_ndx(sn, rate3);
-
+
#if 1
- DPRINTF(sc, "%s: %s size %d finaltsidx %d tries %d status %d rate/try %d/%d %d/%d %d/%d %d/%d\n",
- __func__, ether_sprintf(an->an_node.ni_macaddr),
- bin_to_size(size_to_bin(frame_size)),
- finalTSIdx,
- long_tries,
- ds->ds_txstat.ts_status,
- rate0, tries0,
- rate1, tries1,
- rate2, tries2,
- rate3, tries3);
+ DPRINTF(sc, ATH_DEBUG_RATE,
+"%s: %s size %d finaltsidx %d tries %d %s rate/try [%d/%d %d/%d %d/%d %d/%d]\n",
+ __func__, ether_sprintf(an->an_node.ni_macaddr),
+ bin_to_size(size_to_bin(frame_size)),
+ finalTSIdx,
+ long_tries,
+ ts->ts_status ? "FAIL" : "OK",
+ rate0, tries0,
+ rate1, tries1,
+ rate2, tries2,
+ rate3, tries3);
#endif
+ /*
+ * NB: series > 0 are not penalized for failure
+ * based on the try counts under the assumption
+ * that losses are often bursty and since we
+ * sample higher rates 1 try at a time doing so
+ * may unfairly penalize them.
+ */
if (tries0) {
update_stats(sc, an, frame_size,
ndx0, tries0,
ndx1, tries1,
ndx2, tries2,
ndx3, tries3,
- short_tries, ds->ds_txstat.ts_longretry + 1,
+ short_tries, long_tries,
long_tries > tries0);
+ long_tries -= tries0;
}
if (tries1 && finalTSIdx > 0) {
@@ -599,8 +634,9 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
ndx2, tries2,
ndx3, tries3,
0, 0,
- short_tries, ds->ds_txstat.ts_longretry + 1 - tries0,
- ds->ds_txstat.ts_status);
+ short_tries, long_tries,
+ ts->ts_status);
+ long_tries -= tries1;
}
if (tries2 && finalTSIdx > 1) {
@@ -609,8 +645,9 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
ndx3, tries3,
0, 0,
0, 0,
- short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1,
- ds->ds_txstat.ts_status);
+ short_tries, long_tries,
+ ts->ts_status);
+ long_tries -= tries2;
}
if (tries3 && finalTSIdx > 2) {
@@ -619,8 +656,8 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
0, 0,
0, 0,
0, 0,
- short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1 - tries2,
- ds->ds_txstat.ts_status);
+ short_tries, long_tries,
+ ts->ts_status);
}
}
}
@@ -628,8 +665,8 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
void
ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
{
- DPRINTF(sc, "%s: %s isnew %d\n", __func__,
- ether_sprintf(an->an_node.ni_macaddr), isnew);
+ DPRINTF(sc, ATH_DEBUG_NODE, "%s: %s isnew %d\n", __func__,
+ ether_sprintf(an->an_node.ni_macaddr), isnew);
if (isnew)
ath_rate_ctl_reset(sc, &an->an_node);
}
@@ -668,15 +705,16 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
sn->static_rate_ndx = srate;
}
- DPRINTF(sc, "%s: %s size 1600 rate/tt", __func__, ether_sprintf(ni->ni_macaddr));
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s size 1600 rate/tt",
+ __func__, ether_sprintf(ni->ni_macaddr));
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: ignore bogus rix at %d\n",
- __func__, x);
+ DPRINTF(sc, ATH_DEBUG_RATE,
+ "%s: ignore bogus rix at %d\n", __func__, x);
continue;
}
sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode;
@@ -684,11 +722,10 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
rt->info[sn->rates[x].rix].rateCode |
rt->info[sn->rates[x].rix].shortPreamble;
- DPRINTF(sc, " %d/%d", sn->rates[x].rate,
- calc_usecs_unicast_packet(sc, 1600, sn->rates[x].rix,
- 0,0));
+ DPRINTF(sc, ATH_DEBUG_RATE, " %d/%d", sn->rates[x].rate,
+ calc_usecs_unicast_packet(sc, 1600, sn->rates[x].rix, 0,0));
}
- DPRINTF(sc, "%s\n", "");
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s\n", "");
/* set the visible bit-rate to the lowest one available */
ni->ni_txrate = 0;
@@ -724,14 +761,15 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
sn->current_rate[y] = ndx;
}
- DPRINTF(sc, "%s: %s %d rates %d%sMbps (%dus)- %d%sMbps (%dus)\n",
- __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
+ DPRINTF(sc, ATH_DEBUG_RATE,
+ "%s: %s %d rates %d%sMbps (%dus)- %d%sMbps (%dus)\n",
+ __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
);
if (sn->static_rate_ndx != -1)
@@ -789,7 +827,7 @@ ath_rate_attach(struct ath_softc *sc)
{
struct sample_softc *osc;
- DPRINTF(sc, "%s:\n", __func__);
+ DPRINTF(sc, ATH_DEBUG_ANY, "%s:\n", __func__);
osc = malloc(sizeof(struct sample_softc), M_DEVBUF, M_NOWAIT|M_ZERO);
if (osc == NULL)
return NULL;
diff --git a/sys/dev/ath/ath_rate/sample/sample.h b/sys/dev/ath/ath_rate/sample/sample.h
index c5a4a23..90593aa 100644
--- a/sys/dev/ath/ath_rate/sample/sample.h
+++ b/sys/dev/ath/ath_rate/sample/sample.h
@@ -107,77 +107,36 @@ struct sample_node {
#define WIFI_CW_MIN 31
#define WIFI_CW_MAX 1023
-struct ar5212_desc {
- /*
- * tx_control_0
- */
- u_int32_t frame_len:12;
- u_int32_t reserved_12_15:4;
- u_int32_t xmit_power:6;
- u_int32_t rts_cts_enable:1;
- u_int32_t veol:1;
- u_int32_t clear_dest_mask:1;
- u_int32_t ant_mode_xmit:4;
- u_int32_t inter_req:1;
- u_int32_t encrypt_key_valid:1;
- u_int32_t cts_enable:1;
-
- /*
- * tx_control_1
- */
- u_int32_t buf_len:12;
- u_int32_t more:1;
- u_int32_t encrypt_key_index:7;
- u_int32_t frame_type:4;
- u_int32_t no_ack:1;
- u_int32_t comp_proc:2;
- u_int32_t comp_iv_len:2;
- u_int32_t comp_icv_len:2;
- u_int32_t reserved_31:1;
-
- /*
- * tx_control_2
- */
- u_int32_t rts_duration:15;
- u_int32_t duration_update_enable:1;
- u_int32_t xmit_tries0:4;
- u_int32_t xmit_tries1:4;
- u_int32_t xmit_tries2:4;
- u_int32_t xmit_tries3:4;
-
- /*
- * tx_control_3
- */
- u_int32_t xmit_rate0:5;
- u_int32_t xmit_rate1:5;
- u_int32_t xmit_rate2:5;
- u_int32_t xmit_rate3:5;
- u_int32_t rts_cts_rate:5;
- u_int32_t reserved_25_31:7;
-
- /*
- * tx_status_0
- */
- u_int32_t frame_xmit_ok:1;
- u_int32_t excessive_retries:1;
- u_int32_t fifo_underrun:1;
- u_int32_t filtered:1;
- u_int32_t rts_fail_count:4;
- u_int32_t data_fail_count:4;
- u_int32_t virt_coll_count:4;
- u_int32_t send_timestamp:16;
-
- /*
- * tx_status_1
- */
- u_int32_t done:1;
- u_int32_t seq_num:12;
- u_int32_t ack_sig_strength:8;
- u_int32_t final_ts_index:2;
- u_int32_t comp_success:1;
- u_int32_t xmit_antenna:1;
- u_int32_t reserved_25_31_x:7;
-} __packed;
+/*
+ * Definitions for pulling the rate and trie counts from
+ * a 5212 h/w descriptor. These Don't belong here; the
+ * driver should record this information so the rate control
+ * code doesn't go groveling around in the descriptor bits.
+ */
+#define ds_ctl2 ds_hw[0]
+#define ds_ctl3 ds_hw[1]
+
+/* TX ds_ctl2 */
+#define AR_XmitDataTries0 0x000f0000 /* series 0 max attempts */
+#define AR_XmitDataTries0_S 16
+#define AR_XmitDataTries1 0x00f00000 /* series 1 max attempts */
+#define AR_XmitDataTries1_S 20
+#define AR_XmitDataTries2 0x0f000000 /* series 2 max attempts */
+#define AR_XmitDataTries2_S 24
+#define AR_XmitDataTries3 0xf0000000 /* series 3 max attempts */
+#define AR_XmitDataTries3_S 28
+
+/* TX ds_ctl3 */
+#define AR_XmitRate0 0x0000001f /* series 0 tx rate */
+#define AR_XmitRate0_S 0
+#define AR_XmitRate1 0x000003e0 /* series 1 tx rate */
+#define AR_XmitRate1_S 5
+#define AR_XmitRate2 0x00007c00 /* series 2 tx rate */
+#define AR_XmitRate2_S 10
+#define AR_XmitRate3 0x000f8000 /* series 3 tx rate */
+#define AR_XmitRate3_S 15
+
+#define MS(_v, _f) (((_v) & (_f)) >> _f##_S)
/*
* Calculate the transmit duration of a frame.
@@ -195,18 +154,16 @@ static unsigned calc_usecs_unicast_packet(struct ath_softc *sc,
int tt = 0;
int x = 0;
int cw = WIFI_CW_MIN;
- int cix = rt->info[rix].controlRate;
+ int cix;
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
- if (!rt->info[rix].rateKbps) {
- printf("rix %d (%d) bad ratekbps %d mode %u\n",
- rix, rt->info[rix].dot11Rate,
- rt->info[rix].rateKbps,
- sc->sc_curmode);
-
+ if (rix >= rt->rateCount) {
+ printf("bogus rix %d, max %u, mode %u\n",
+ rix, rt->rateCount, 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
@@ -250,18 +207,15 @@ static unsigned calc_usecs_unicast_packet(struct ath_softc *sc,
}
if (rts || cts) {
- int ctsrate = rt->info[cix].rateCode;
+ int ctsrate;
int ctsduration = 0;
- if (!rt->info[cix].rateKbps) {
- printf("cix %d (%d) bad ratekbps %d mode %u\n",
- cix, rt->info[cix].dot11Rate,
- rt->info[cix].rateKbps,
- sc->sc_curmode);
- return 0;
- }
+ /* NB: this is intentionally not a runtime check */
+ KASSERT(cix < rt->rateCount,
+ ("bogus cix %d, max %u, mode %u\n", cix, rt->rateCount,
+ sc->sc_curmode));
- ctsrate |= rt->info[cix].shortPreamble;
+ ctsrate = rt->info[cix].rateCode | rt->info[cix].shortPreamble;
if (rts) /* SIFS + CTS */
ctsduration += rt->info[cix].spAckDuration;
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 12602d2..a0bcb9a 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -258,8 +258,8 @@ enum {
if (sc->sc_debug & ATH_DEBUG_KEYCACHE) \
ath_keyprint(sc, __func__, ix, hk, mac); \
} while (0)
-static void ath_printrxbuf(struct ath_buf *bf, u_int ix, int);
-static void ath_printtxbuf(struct ath_buf *bf, u_int qnum, u_int ix, int done);
+static void ath_printrxbuf(const struct ath_buf *bf, u_int ix, int);
+static void ath_printtxbuf(const struct ath_buf *bf, u_int qnum, u_int ix, int done);
#else
#define IFF_DUMPPKTS(sc, m) \
((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
@@ -2758,7 +2758,6 @@ ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
ds = bf->bf_desc;
ds->ds_link = bf->bf_daddr; /* link to self */
ds->ds_data = bf->bf_segs[0].ds_addr;
- ds->ds_vdata = mtod(m, void *); /* for radar */
ath_hal_setuprxdesc(ah, ds
, m->m_len /* buffer size */
, 0
@@ -2856,7 +2855,7 @@ ath_setdefantenna(struct ath_softc *sc, u_int antenna)
static int
ath_rx_tap(struct ath_softc *sc, struct mbuf *m,
- const struct ath_desc *ds, u_int64_t tsf, int16_t nf)
+ const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf)
{
u_int8_t rix;
@@ -2871,17 +2870,16 @@ ath_rx_tap(struct ath_softc *sc, struct mbuf *m,
sc->sc_stats.ast_rx_tooshort++;
return 0;
}
- sc->sc_rx_th.wr_tsf = htole64(
- ath_extend_tsf(ds->ds_rxstat.rs_tstamp, tsf));
- rix = ds->ds_rxstat.rs_rate;
+ sc->sc_rx_th.wr_tsf = htole64(ath_extend_tsf(rs->rs_tstamp, tsf));
+ rix = rs->rs_rate;
sc->sc_rx_th.wr_flags = sc->sc_hwmap[rix].rxflags;
- if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC)
+ if (rs->rs_status & HAL_RXERR_CRC)
sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
/* XXX propagate other error flags from descriptor */
sc->sc_rx_th.wr_rate = sc->sc_hwmap[rix].ieeerate;
- sc->sc_rx_th.wr_antsignal = ds->ds_rxstat.rs_rssi + nf;
+ sc->sc_rx_th.wr_antsignal = rs->rs_rssi + nf;
sc->sc_rx_th.wr_antnoise = nf;
- sc->sc_rx_th.wr_antenna = ds->ds_rxstat.rs_antenna;
+ sc->sc_rx_th.wr_antenna = rs->rs_antenna;
bpf_mtap2(sc->sc_drvbpf, &sc->sc_rx_th, sc->sc_rx_th_len, m);
@@ -2900,6 +2898,7 @@ ath_rx_proc(void *arg, int npending)
struct ifnet *ifp = sc->sc_ifp;
struct ath_hal *ah = sc->sc_ah;
struct ath_desc *ds;
+ struct ath_rx_status *rs;
struct mbuf *m;
struct ieee80211_node *ni;
struct ath_node *an;
@@ -2949,8 +2948,9 @@ ath_rx_proc(void *arg, int npending)
* on. All this is necessary because of our use of
* a self-linked list to avoid rx overruns.
*/
+ rs = &bf->bf_status.ds_rxstat;
status = ath_hal_rxprocdesc(ah, ds,
- bf->bf_daddr, PA2DESC(sc, ds->ds_link));
+ bf->bf_daddr, PA2DESC(sc, ds->ds_link), rs);
#ifdef ATH_DEBUG
if (sc->sc_debug & ATH_DEBUG_RECV_DESC)
ath_printrxbuf(bf, 0, status == HAL_OK);
@@ -2958,7 +2958,7 @@ ath_rx_proc(void *arg, int npending)
if (status == HAL_EINPROGRESS)
break;
STAILQ_REMOVE_HEAD(&sc->sc_rxbuf, bf_list);
- if (ds->ds_rxstat.rs_more) {
+ if (rs->rs_more) {
/*
* Frame spans multiple descriptors; this
* cannot happen yet as we don't support
@@ -2970,18 +2970,18 @@ ath_rx_proc(void *arg, int npending)
goto rx_next;
}
/* fall thru for monitor mode handling... */
- } else if (ds->ds_rxstat.rs_status != 0) {
- if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC)
+ } else if (rs->rs_status != 0) {
+ if (rs->rs_status & HAL_RXERR_CRC)
sc->sc_stats.ast_rx_crcerr++;
- if (ds->ds_rxstat.rs_status & HAL_RXERR_FIFO)
+ if (rs->rs_status & HAL_RXERR_FIFO)
sc->sc_stats.ast_rx_fifoerr++;
- if (ds->ds_rxstat.rs_status & HAL_RXERR_PHY) {
+ if (rs->rs_status & HAL_RXERR_PHY) {
sc->sc_stats.ast_rx_phyerr++;
- phyerr = ds->ds_rxstat.rs_phyerr & 0x1f;
+ phyerr = rs->rs_phyerr & 0x1f;
sc->sc_stats.ast_rx_phy[phyerr]++;
goto rx_next;
}
- if (ds->ds_rxstat.rs_status & HAL_RXERR_DECRYPT) {
+ if (rs->rs_status & HAL_RXERR_DECRYPT) {
/*
* Decrypt error. If the error occurred
* because there was no hardware key, then
@@ -2992,18 +2992,18 @@ ath_rx_proc(void *arg, int npending)
*
* XXX do key cache faulting
*/
- if (ds->ds_rxstat.rs_keyix == HAL_RXKEYIX_INVALID)
+ if (rs->rs_keyix == HAL_RXKEYIX_INVALID)
goto rx_accept;
sc->sc_stats.ast_rx_badcrypt++;
}
- if (ds->ds_rxstat.rs_status & HAL_RXERR_MIC) {
+ if (rs->rs_status & HAL_RXERR_MIC) {
sc->sc_stats.ast_rx_badmic++;
/*
* Do minimal work required to hand off
* the 802.11 header for notifcation.
*/
/* XXX frag's and qos frames */
- len = ds->ds_rxstat.rs_datalen;
+ len = rs->rs_datalen;
if (len >= sizeof (struct ieee80211_frame)) {
bus_dmamap_sync(sc->sc_dmat,
bf->bf_dmamap,
@@ -3011,8 +3011,7 @@ ath_rx_proc(void *arg, int npending)
ieee80211_notify_michael_failure(ic,
mtod(m, struct ieee80211_frame *),
sc->sc_splitmic ?
- ds->ds_rxstat.rs_keyix-32 :
- ds->ds_rxstat.rs_keyix
+ rs->rs_keyix-32 : rs->rs_keyix
);
}
}
@@ -3024,13 +3023,13 @@ ath_rx_proc(void *arg, int npending)
* interesting (e.g. crc).
*/
if (bpf_peers_present(sc->sc_drvbpf) &&
- (ds->ds_rxstat.rs_status & sc->sc_monpass)) {
+ (rs->rs_status & sc->sc_monpass)) {
bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
BUS_DMASYNC_POSTREAD);
/* NB: bpf needs the mbuf length setup */
- len = ds->ds_rxstat.rs_datalen;
+ len = rs->rs_datalen;
m->m_pkthdr.len = m->m_len = len;
- (void) ath_rx_tap(sc, m, ds, tsf, nf);
+ (void) ath_rx_tap(sc, m, rs, tsf, nf);
}
/* XXX pass MIC errors up for s/w reclaculation */
goto rx_next;
@@ -3049,13 +3048,13 @@ rx_accept:
bf->bf_m = NULL;
m->m_pkthdr.rcvif = ifp;
- len = ds->ds_rxstat.rs_datalen;
+ len = rs->rs_datalen;
m->m_pkthdr.len = m->m_len = len;
- sc->sc_stats.ast_ant_rx[ds->ds_rxstat.rs_antenna]++;
+ sc->sc_stats.ast_ant_rx[rs->rs_antenna]++;
if (bpf_peers_present(sc->sc_drvbpf) &&
- !ath_rx_tap(sc, m, ds, tsf, nf)) {
+ !ath_rx_tap(sc, m, rs, tsf, nf)) {
m_freem(m); /* XXX reclaim */
goto rx_next;
}
@@ -3074,8 +3073,8 @@ rx_accept:
if (IFF_DUMPPKTS(sc, ATH_DEBUG_RECV)) {
ieee80211_dump_pkt(mtod(m, caddr_t), len,
- sc->sc_hwmap[ds->ds_rxstat.rs_rate].ieeerate,
- ds->ds_rxstat.rs_rssi);
+ sc->sc_hwmap[rs->rs_rate].ieeerate,
+ rs->rs_rssi);
}
m_adj(m, -IEEE80211_CRC_LEN);
@@ -3087,19 +3086,18 @@ rx_accept:
*/
ni = ieee80211_find_rxnode_withkey(ic,
mtod(m, const struct ieee80211_frame_min *),
- ds->ds_rxstat.rs_keyix == HAL_RXKEYIX_INVALID ?
- IEEE80211_KEYIX_NONE : ds->ds_rxstat.rs_keyix);
+ rs->rs_keyix == HAL_RXKEYIX_INVALID ?
+ IEEE80211_KEYIX_NONE : rs->rs_keyix);
/*
* Track rx rssi and do any rx antenna management.
*/
an = ATH_NODE(ni);
- ATH_RSSI_LPF(an->an_avgrssi, ds->ds_rxstat.rs_rssi);
- ATH_RSSI_LPF(sc->sc_halstats.ns_avgrssi, ds->ds_rxstat.rs_rssi);
+ ATH_RSSI_LPF(an->an_avgrssi, rs->rs_rssi);
+ ATH_RSSI_LPF(sc->sc_halstats.ns_avgrssi, rs->rs_rssi);
/*
* Send frame up for processing.
*/
- type = ieee80211_input(ic, m, ni,
- ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp);
+ type = ieee80211_input(ic, m, ni, rs->rs_rssi, rs->rs_tstamp);
ieee80211_free_node(ni);
if (sc->sc_diversity) {
/*
@@ -3107,10 +3105,9 @@ rx_accept:
* antenna if diversity chooses the other antenna 3
* times in a row.
*/
- if (sc->sc_defant != ds->ds_rxstat.rs_antenna) {
+ if (sc->sc_defant != rs->rs_antenna) {
if (++sc->sc_rxotherant >= 3)
- ath_setdefantenna(sc,
- ds->ds_rxstat.rs_antenna);
+ ath_setdefantenna(sc, rs->rs_antenna);
} else
sc->sc_rxotherant = 0;
}
@@ -3122,7 +3119,7 @@ rx_accept:
* periodic beacon frames to trigger the poll event.
*/
if (type == IEEE80211_FC0_TYPE_DATA) {
- sc->sc_rxrate = ds->ds_rxstat.rs_rate;
+ sc->sc_rxrate = rs->rs_rate;
ath_led_event(sc, ATH_LED_RX);
} else if (ticks - sc->sc_ledevent >= sc->sc_ledidle)
ath_led_event(sc, ATH_LED_POLL);
@@ -3133,7 +3130,7 @@ rx_accept:
* This assumes the rx key is always setup when associated.
*/
if (ic->ic_opmode == IEEE80211_M_STA &&
- ds->ds_rxstat.rs_keyix != HAL_RXKEYIX_INVALID)
+ rs->rs_keyix != HAL_RXKEYIX_INVALID)
ngood++;
rx_next:
STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
@@ -3918,6 +3915,7 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
struct ieee80211com *ic = &sc->sc_ic;
struct ath_buf *bf;
struct ath_desc *ds, *ds0;
+ struct ath_tx_status *ts;
struct ieee80211_node *ni;
struct ath_node *an;
int sr, lr, pri, nacked;
@@ -3938,7 +3936,8 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
}
ds0 = &bf->bf_desc[0];
ds = &bf->bf_desc[bf->bf_nseg - 1];
- status = ath_hal_txprocdesc(ah, ds);
+ ts = &bf->bf_status.ds_txstat;
+ status = ath_hal_txprocdesc(ah, ds, ts);
#ifdef ATH_DEBUG
if (sc->sc_debug & ATH_DEBUG_XMIT_DESC)
ath_printtxbuf(bf, txq->axq_qnum, 0, status == HAL_OK);
@@ -3955,44 +3954,43 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
ni = bf->bf_node;
if (ni != NULL) {
an = ATH_NODE(ni);
- if (ds->ds_txstat.ts_status == 0) {
- u_int8_t txant = ds->ds_txstat.ts_antenna;
+ if (ts->ts_status == 0) {
+ u_int8_t txant = ts->ts_antenna;
sc->sc_stats.ast_ant_tx[txant]++;
sc->sc_ant_tx[txant]++;
- if (ds->ds_txstat.ts_rate & HAL_TXSTAT_ALTRATE)
+ if (ts->ts_rate & HAL_TXSTAT_ALTRATE)
sc->sc_stats.ast_tx_altrate++;
- sc->sc_stats.ast_tx_rssi =
- ds->ds_txstat.ts_rssi;
+ sc->sc_stats.ast_tx_rssi = ts->ts_rssi;
ATH_RSSI_LPF(sc->sc_halstats.ns_avgtxrssi,
- ds->ds_txstat.ts_rssi);
+ ts->ts_rssi);
pri = M_WME_GETAC(bf->bf_m);
if (pri >= WME_AC_VO)
ic->ic_wme.wme_hipri_traffic++;
ni->ni_inact = ni->ni_inact_reload;
} else {
- if (ds->ds_txstat.ts_status & HAL_TXERR_XRETRY)
+ if (ts->ts_status & HAL_TXERR_XRETRY)
sc->sc_stats.ast_tx_xretries++;
- if (ds->ds_txstat.ts_status & HAL_TXERR_FIFO)
+ if (ts->ts_status & HAL_TXERR_FIFO)
sc->sc_stats.ast_tx_fifoerr++;
- if (ds->ds_txstat.ts_status & HAL_TXERR_FILT)
+ if (ts->ts_status & HAL_TXERR_FILT)
sc->sc_stats.ast_tx_filtered++;
}
- sr = ds->ds_txstat.ts_shortretry;
- lr = ds->ds_txstat.ts_longretry;
+ sr = ts->ts_shortretry;
+ lr = ts->ts_longretry;
sc->sc_stats.ast_tx_shortretry += sr;
sc->sc_stats.ast_tx_longretry += lr;
/*
* Hand the descriptor to the rate control algorithm.
*/
- if ((ds->ds_txstat.ts_status & HAL_TXERR_FILT) == 0 &&
+ if ((ts->ts_status & HAL_TXERR_FILT) == 0 &&
(bf->bf_flags & HAL_TXDESC_NOACK) == 0) {
/*
* If frame was ack'd update the last rx time
* used to workaround phantom bmiss interrupts.
*/
- if (ds->ds_txstat.ts_status == 0)
+ if (ts->ts_status == 0)
nacked++;
- ath_rate_tx_complete(sc, an, ds, ds0);
+ ath_rate_tx_complete(sc, an, bf);
}
/*
* Reclaim reference to node.
@@ -4141,7 +4139,8 @@ ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
#ifdef ATH_DEBUG
if (sc->sc_debug & ATH_DEBUG_RESET) {
ath_printtxbuf(bf, txq->axq_qnum, ix,
- ath_hal_txprocdesc(ah, bf->bf_desc) == HAL_OK);
+ ath_hal_txprocdesc(ah, bf->bf_desc,
+ &bf->bf_status.ds_txstat) == HAL_OK);
ieee80211_dump_pkt(mtod(bf->bf_m, caddr_t),
bf->bf_m->m_len, 0, -1);
}
@@ -4206,7 +4205,8 @@ ath_draintxq(struct ath_softc *sc)
struct ath_buf *bf = STAILQ_FIRST(&sc->sc_bbuf);
if (bf != NULL && bf->bf_m != NULL) {
ath_printtxbuf(bf, sc->sc_bhalq, 0,
- ath_hal_txprocdesc(ah, bf->bf_desc) == HAL_OK);
+ ath_hal_txprocdesc(ah, bf->bf_desc,
+ &bf->bf_status.ds_txstat) == HAL_OK);
ieee80211_dump_pkt(mtod(bf->bf_m, caddr_t),
bf->bf_m->m_len, 0, -1);
}
@@ -4241,8 +4241,9 @@ ath_stoprecv(struct ath_softc *sc)
ix = 0;
STAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
struct ath_desc *ds = bf->bf_desc;
+ struct ath_rx_status *rs = &bf->bf_status.ds_rxstat;
HAL_STATUS status = ath_hal_rxprocdesc(ah, ds,
- bf->bf_daddr, PA2DESC(sc, ds->ds_link));
+ bf->bf_daddr, PA2DESC(sc, ds->ds_link), rs);
if (status == HAL_OK || (sc->sc_debug & ATH_DEBUG_FATAL))
ath_printrxbuf(bf, ix, status == HAL_OK);
ix++;
@@ -5040,35 +5041,37 @@ ath_setcurmode(struct ath_softc *sc, enum ieee80211_phymode mode)
#ifdef ATH_DEBUG
static void
-ath_printrxbuf(struct ath_buf *bf, u_int ix, int done)
+ath_printrxbuf(const struct ath_buf *bf, u_int ix, int done)
{
- struct ath_desc *ds;
+ const struct ath_rx_status *rs = &bf->bf_status.ds_rxstat;
+ const struct ath_desc *ds;
int i;
for (i = 0, ds = bf->bf_desc; i < bf->bf_nseg; i++, ds++) {
printf("R[%2u] (DS.V:%p DS.P:%p) L:%08x D:%08x%s\n"
" %08x %08x %08x %08x\n",
- ix, ds, (struct ath_desc *)bf->bf_daddr + i,
+ ix, ds, (const struct ath_desc *)bf->bf_daddr + i,
ds->ds_link, ds->ds_data,
- !done ? "" : (ds->ds_rxstat.rs_status == 0) ? " *" : " !",
+ !done ? "" : (rs->rs_status == 0) ? " *" : " !",
ds->ds_ctl0, ds->ds_ctl1,
ds->ds_hw[0], ds->ds_hw[1]);
}
}
static void
-ath_printtxbuf(struct ath_buf *bf, u_int qnum, u_int ix, int done)
+ath_printtxbuf(const struct ath_buf *bf, u_int qnum, u_int ix, int done)
{
- struct ath_desc *ds;
+ const struct ath_tx_status *ts = &bf->bf_status.ds_txstat;
+ const struct ath_desc *ds;
int i;
printf("Q%u[%3u]", qnum, ix);
for (i = 0, ds = bf->bf_desc; i < bf->bf_nseg; i++, ds++) {
printf(" (DS.V:%p DS.P:%p) L:%08x D:%08x F:04%x%s\n"
" %08x %08x %08x %08x %08x %08x\n",
- ds, (struct ath_desc *)bf->bf_daddr + i,
+ ds, (const struct ath_desc *)bf->bf_daddr + i,
ds->ds_link, ds->ds_data, bf->bf_flags,
- !done ? "" : (ds->ds_txstat.ts_status == 0) ? " *" : " !",
+ !done ? "" : (ts->ts_status == 0) ? " *" : " !",
ds->ds_ctl0, ds->ds_ctl1,
ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3]);
}
diff --git a/sys/dev/ath/if_athrate.h b/sys/dev/ath/if_athrate.h
index 90a4416..385bf2a 100644
--- a/sys/dev/ath/if_athrate.h
+++ b/sys/dev/ath/if_athrate.h
@@ -135,6 +135,7 @@ void ath_rate_setupxtxdesc(struct ath_softc *, struct ath_node *,
* for packets that were successfully sent and for those that
* failed (consult the descriptor for details).
*/
+struct ath_buf;
void ath_rate_tx_complete(struct ath_softc *, struct ath_node *,
- const struct ath_desc *last, const struct ath_desc *first);
+ const struct ath_buf *);
#endif /* _ATH_RATECTRL_H_ */
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index c6c8a39..40ccb48 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -45,6 +45,7 @@
#include <sys/taskqueue.h>
#include <contrib/dev/ath/ah.h>
+#include <contrib/dev/ath/ah_desc.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/ath/if_athioctl.h>
#include <dev/ath/if_athrate.h>
@@ -102,6 +103,7 @@ struct ath_buf {
int bf_nseg;
int bf_flags; /* tx descriptor flags */
struct ath_desc *bf_desc; /* virtual addr of desc */
+ struct ath_desc_status bf_status; /* tx/rx status */
bus_addr_t bf_daddr; /* physical addr of desc */
bus_dmamap_t bf_dmamap; /* DMA map for mbuf chain */
struct mbuf *bf_m; /* mbuf for buf */
@@ -550,8 +552,8 @@ void ath_intr(void *);
#define ath_hal_setuprxdesc(_ah, _ds, _size, _intreq) \
((*(_ah)->ah_setupRxDesc)((_ah), (_ds), (_size), (_intreq)))
-#define ath_hal_rxprocdesc(_ah, _ds, _dspa, _dsnext) \
- ((*(_ah)->ah_procRxDesc)((_ah), (_ds), (_dspa), (_dsnext), 0))
+#define ath_hal_rxprocdesc(_ah, _ds, _dspa, _dsnext, _rs) \
+ ((*(_ah)->ah_procRxDesc)((_ah), (_ds), (_dspa), (_dsnext), 0, (_rs)))
#define ath_hal_setuptxdesc(_ah, _ds, _plen, _hlen, _atype, _txpow, \
_txr0, _txtr0, _keyix, _ant, _flags, \
_rtsrate, _rtsdura) \
@@ -564,8 +566,8 @@ void ath_intr(void *);
(_txr1), (_txtr1), (_txr2), (_txtr2), (_txr3), (_txtr3)))
#define ath_hal_filltxdesc(_ah, _ds, _l, _first, _last, _ds0) \
((*(_ah)->ah_fillTxDesc)((_ah), (_ds), (_l), (_first), (_last), (_ds0)))
-#define ath_hal_txprocdesc(_ah, _ds) \
- ((*(_ah)->ah_procTxDesc)((_ah), (_ds)))
+#define ath_hal_txprocdesc(_ah, _ds, _ts) \
+ ((*(_ah)->ah_procTxDesc)((_ah), (_ds), (_ts)))
#define ath_hal_gettxintrtxqs(_ah, _txqs) \
((*(_ah)->ah_getTxIntrQueue)((_ah), (_txqs)))
OpenPOWER on IntegriCloud