📄 minstrel.c.svn-base
字号:
ndx = sn->max_tp_rate; } else ndx = sn->max_tp_rate; } if ((sn->static_rate_ndx != -1) || !mrr) *try0 = ATH_TXMAXTRY; else *try0 = sn->retry_adjusted_count[ndx]; KASSERT((ndx < sn->num_rates), ("%s: bad ndx (%d/%d) for " MAC_FMT "?", dev_info, ndx, sn->num_rates, MAC_ADDR(an->an_node.ni_macaddr))); *rix = sn->rates[ndx].rix; if (shortPreamble) *txrate = sn->rates[ndx].shortPreambleRateCode; else *txrate = sn->rates[ndx].rateCode;}static voidath_rate_get_mrr(struct ath_softc *sc, struct ath_node *an, int shortPreamble, size_t frame_size, u_int8_t rix, struct ieee80211_mrr *mrr){ struct minstrel_node *sn = ATH_NODE_MINSTREL(an); /* Index into the rate table, so for example, it is 0..11. */ int rc1, rc2, rc3; if (sn->num_rates <= 0) { DPRINTF(sc, "%s: no rates for " MAC_FMT "\n", dev_info, MAC_ADDR(an->an_node.ni_macaddr)); memset(mrr, 0, sizeof(struct ieee80211_mrr)); return; } if (sn->is_sampling) { sn->is_sampling = 0; if (sn->rs_sample_rate_slower) rc1 = sn->rs_sample_rate; else rc1 = sn->max_tp_rate; } else { rc1 = sn->max_tp_rate2; } rc2 = sn->max_prob_rate; rc3 = 0; KASSERT((rc1 >= 0) && (rc1 < sn->num_rates), ("%s: bad rc1 (%d/%d) for " MAC_FMT "?", dev_info, rc1, sn->num_rates, MAC_ADDR(an->an_node.ni_macaddr))); KASSERT((rc2 >= 0) && (rc2 < sn->num_rates), ("%s: bad rc2 (%d/%d) for " MAC_FMT "?", dev_info, rc2, sn->num_rates, MAC_ADDR(an->an_node.ni_macaddr))); KASSERT((rc3 >= 0) && (rc3 < sn->num_rates), ("%s: bad rc3 (%d/%d) for " MAC_FMT "?", dev_info, rc3, sn->num_rates, MAC_ADDR(an->an_node.ni_macaddr))); if (shortPreamble) { mrr->rate1 = sn->rates[rc1].shortPreambleRateCode; mrr->rate2 = sn->rates[rc2].shortPreambleRateCode; mrr->rate3 = sn->rates[rc3].shortPreambleRateCode; } else { mrr->rate1 = sn->rates[rc1].rateCode; mrr->rate2 = sn->rates[rc2].rateCode; mrr->rate3 = sn->rates[rc3].rateCode; } mrr->retries1 = sn->retry_adjusted_count[rc1]; mrr->retries2 = sn->retry_adjusted_count[rc2]; mrr->retries3 = sn->retry_adjusted_count[rc3];}static voidath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, const struct ath_buf *bf){ struct minstrel_node *sn = ATH_NODE_MINSTREL(an); struct ieee80211com *ic = &sc->sc_ic; const struct ath_tx_status *ts = &bf->bf_dsstatus.ds_txstat; const struct ath_desc *ds = &bf->bf_desc[0]; int final_rate = 0; int tries = 0; int mrr; int final_ndx; int rate0, tries0, ndx0; int rate1, tries1, ndx1; int rate2, tries2, ndx2; int rate3, tries3, ndx3; /* This is the index in the retry chain we finish at. * With no retransmits, it is always 0. * int finalTSIdx = ads->final_ts_index; */ final_rate = sc->sc_hwmap[ts->ts_rate & ~HAL_TXSTAT_ALTRATE].ieeerate; final_ndx = rate_to_ndx(sn, final_rate); if (final_ndx >= sn->num_rates) { DPRINTF(sc, "%s: final ndx too high\n", __func__); final_ndx = 0; } if (final_ndx < 0) { DPRINTF(sc, "%s: final ndx too low\n", __func__); final_ndx = 0; } /* 'tries' is the total number of times we have endeavoured to * send this packet, and is a sum of the #attempts at each * level in the multi-rate retry chain. */ tries = ts->ts_longretry + 1; if (sn->num_rates <= 0) { DPRINTF(sc, "%s: " MAC_FMT " %s no rates yet\n", dev_info, MAC_ADDR(an->an_node.ni_macaddr), __func__); return; } if (!ts->ts_status) /* Success when sending a packet*/ sn->rs_ratesuccess[final_ndx]++; mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT) && ENABLE_MRR; if (!mrr) { if ((0 <= final_ndx) && (final_ndx < sn->num_rates)) { /* only one rate was used */ sn->rs_rateattempts[final_ndx] += tries; } return; } /* Now, query the HAL/hardware to find out the contents of the * multirate retry chain. If we have it set to 6, 3, 2, 2, this * call will always return 6,3,2,2. For some packets, we can * get a mrr of 0, -1, -1, -1, which indicates there is no * chain installed for that packet */ rate0 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate0)].ieeerate; tries0 = MS(ds->ds_ctl2, AR_XmitDataTries0); ndx0 = rate_to_ndx(sn, rate0); rate1 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate1)].ieeerate; tries1 = MS(ds->ds_ctl2, AR_XmitDataTries1); ndx1 = rate_to_ndx(sn, rate1); rate2 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate2)].ieeerate; tries2 = MS(ds->ds_ctl2, AR_XmitDataTries2); ndx2 = rate_to_ndx(sn, rate2); rate3 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate3)].ieeerate; tries3 = MS(ds->ds_ctl2, AR_XmitDataTries3); ndx3 = rate_to_ndx(sn, rate3); sn->rs_rateattempts[ndx0] += MIN(tries, tries0); if (tries <= tries0) return; if (tries1 < 0) return; tries = tries - tries0; sn->rs_rateattempts[ndx1] += MIN(tries, tries1); if (tries <= tries1) return; if (tries2 < 0) return; tries = tries - tries1; sn->rs_rateattempts[ndx2] += MIN(tries, tries2); if (tries <= tries2) return; if (tries3 < 0) return; tries = tries - tries2; sn->rs_rateattempts[ndx3] += MIN(tries, tries3);}static voidath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew){ DPRINTF(sc, "%s: " MAC_FMT " %s\n", dev_info, MAC_ADDR(an->an_node.ni_macaddr), __func__); if (isnew) ath_rate_ctl_reset(sc, &an->an_node);}static voidath_fill_sample_table(struct ath_softc *sc, struct minstrel_node *sn){ unsigned int num_sample_rates = (sn->num_rates - 1); /* newIndex varies as 0 .. (num_rates - 2) * The highest index rate is the slowest and is ignored */ unsigned int i, column_index, newIndex; u_int8_t random_bytes[8]; /* This should be unnecessary if we are assuming storage is provided * as zeroed */ memset(sn->rs_sampleTable, 0, sizeof(sn->rs_sampleTable)); sn->rs_sampleColumn = 0; sn->rs_sampleIndex = 0; /* Seed value to random number generator, which determines when we * send a sample packet at some non-optimal rate * FIXME: randomise? */ sn->random_n = 1; sn->a = 1664525; sn->b = 1013904223; if (sn->num_rates > 1) { for (column_index = 0; column_index < MINSTREL_COLUMNS; column_index++) { for (i = 0; i < num_sample_rates; i++) { get_random_bytes(random_bytes, 8); newIndex = (i + random_bytes[i & 7]) % num_sample_rates; while (sn->rs_sampleTable[newIndex][column_index] != 0) newIndex = (newIndex + 1) % num_sample_rates; sn->rs_sampleTable[newIndex][column_index] = i + 1; } } } for (column_index = 0; column_index < MINSTREL_COLUMNS; column_index++) { for (i = 0; i < num_sample_rates && i < IEEE80211_RATE_MAXSIZE; i++) { DPRINTF(sc, "rs_sampleTable[%2u][%2u] = %2u\n", i, column_index, sn->rs_sampleTable[i][column_index]); } }}/* Initialize the tables for a node. */static voidath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni){ struct minstrel_node *sn = ATH_NODE_MINSTREL(ATH_NODE(ni)); struct ieee80211vap *vap = ni->ni_vap; const HAL_RATE_TABLE *rt = sc->sc_currates; unsigned int x; int retry_index, tx_time; int srate; int ndx = 0; sn->num_rates = 0; sn->max_tp_rate = 0; sn->max_tp_rate2 = 0; sn->max_prob_rate = 0; sn->packet_count = 0; sn->sample_count = 0; sn->is_sampling = 0; if (rt == NULL) { DPRINTF(sc, "no rates yet! mode %u\n", sc->sc_curmode); return; } sn->static_rate_ndx = -1; sn->num_rates = ni->ni_rates.rs_nrates; for (x = 0; x < ni->ni_rates.rs_nrates; x++) { sn->rs_rateattempts [x] = 0; sn->rs_thisprob [x] = 0; sn->rs_ratesuccess [x] = 0; sn->rs_lastrateattempts [x] = 0; sn->rs_lastratesuccess [x] = 0; sn->rs_probability [x] = 0; sn->rs_succ_hist [x] = 0; sn->rs_att_hist [x] = 0; sn->rs_this_tp [x] = 0; sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; if (sn->rates[x].rix == 0xff) { DPRINTF(sc, "%s: %s ignore bogus rix at %d\n", dev_info, __func__, x); continue; } sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode; sn->rates[x].shortPreambleRateCode = rt->info[sn->rates[x].rix].rateCode | rt->info[sn->rates[x].rix].shortPreamble; } ath_fill_sample_table(sc, sn); ni->ni_txrate = 0; if (sn->num_rates <= 0) { DPRINTF(sc, "%s: %s " MAC_FMT " no rates (fixed %d) \n", dev_info, __func__, MAC_ADDR(ni->ni_macaddr), vap->iv_fixed_rate); /* There are no rates yet; we're done */ return; } if (vap->iv_fixed_rate != IEEE80211_FIXED_RATE_NONE) { srate = sn->num_rates - 1; /* A fixed rate is to be used; ic_fixed_rate is an * index into the supported rate set. Convert this * to the index into the negotiated rate set for * the node. We know the rate is there because the * rate set is checked when the station associates. */ /* NB: the rate set is assumed to be sorted. */ for (; (srate >= 0) && (ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) != vap->iv_fixed_rate; srate--); KASSERT(srate >= 0, ("fixed rate %d not in rate set", vap->iv_fixed_rate)); sn->static_rate_ndx = srate; ni->ni_txrate = srate; DPRINTF(sc, "%s: %s " MAC_FMT " fixed rate %d%sMbps\n", dev_info, __func__, MAC_ADDR(ni->ni_macaddr), sn->rates[srate].rate / 2, (sn->rates[srate].rate % 2) ? ".5 " : " "); return; } for (x = 0; x < ni->ni_rates.rs_nrates; x++) { if (sn->rates[x].rix == 0xff) { DPRINTF(sc, "%s: %s ignore bogus rix at %d\n", dev_info, __func__, x); continue; } sn->rs_rateattempts [x] = 0; sn->rs_thisprob [x] = 0; sn->rs_ratesuccess [x] = 0; sn->rs_probability [x] = 0; sn->rs_lastrateattempts [x] = 0; sn->rs_lastratesuccess [x] = 0; sn->rs_succ_hist [x] = 0; sn->rs_att_hist [x] = 0; sn->perfect_tx_time [x] = calc_usecs_unicast_packet(sc, 1200, sn->rates[x].rix, 0, 0); sn->retry_count [x] = 1; sn->retry_adjusted_count[x] = 1; for (retry_index = 2; retry_index < ATH_TXMAXTRY; retry_index++) { tx_time = calc_usecs_unicast_packet(sc, 1200, sn->rates[x].rix, 0, retry_index); if (tx_time > ath_segment_size) break; sn->retry_count[x] = retry_index; sn->retry_adjusted_count[x] = retry_index; } }#if 0 DPRINTF(sc, "%s: Retry table for this node\n", __func__); for (x = 0; x < ni->ni_rates.rs_nrates; x++) DPRINTF(sc, "%2d %2d %6d \n", x, sn->retry_count[x], sn->perfect_tx_time[x]);#endif /* Set the initial rate */ for (ndx = sn->num_rates - 1; ndx > 0; ndx--) if (sn->rates[ndx].rate <= 72) break; sn->current_rate = ndx; ni->ni_txrate = sn->current_rate;}static voidath_rate_cb(void *arg, struct ieee80211_node *ni)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -