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
This commit is contained in:
Sam Leffler 2006-12-13 19:34:35 +00:00
parent 8b33360649
commit 65f9edeee1
7 changed files with 289 additions and 289 deletions

View File

@ -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++;

View File

@ -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

View File

@ -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;

View File

@ -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;
/*
* 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_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 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_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 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
/*
* 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;
#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;

View File

@ -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 @@ ath_rx_proc(void *arg, int npending)
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 @@ ath_rx_proc(void *arg, int npending)
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 @@ ath_rx_proc(void *arg, int npending)
*/
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 @@ ath_rx_proc(void *arg, int npending)
* 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 @@ ath_rx_proc(void *arg, int npending)
* 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 @@ ath_rx_proc(void *arg, int npending)
* 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]);
}

View File

@ -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_ */

View File

@ -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)))