📄 minstrel.c
字号:
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 >= 0 && ndx < sn->num_rates, ("%s: bad ndx (%d/%d) for %s?\n", dev_info, ndx, sn->num_rates, ether_sprintf(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_setupxtxdesc(struct ath_softc *sc, struct ath_node *an, struct ath_desc *ds, int shortPreamble, size_t frame_size, u_int8_t rix){ struct minstrel_node *sn = ATH_NODE_MINSTREL(an); int rc1, rc2, rc3; /* Index into the rate table, so for example, it is 0..11 */ int rixc1, rixc2, rixc3; /* The actual bit rate used */ 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 %s?\n", dev_info, rc1, sn->num_rates, ether_sprintf(an->an_node.ni_macaddr))); KASSERT(rc2 >= 0 && rc2 < sn->num_rates, ("%s: bad rc2 (%d/%d) for %s?\n", dev_info, rc2, sn->num_rates, ether_sprintf(an->an_node.ni_macaddr))); KASSERT(rc3 >= 0 && rc3 < sn->num_rates, ("%s: bad rc3 (%d/%d) for %s?\n", dev_info, rc3, sn->num_rates, ether_sprintf(an->an_node.ni_macaddr))); if (shortPreamble) { rixc1 = sn->rates[rc1].shortPreambleRateCode; rixc2 = sn->rates[rc2].shortPreambleRateCode; rixc3 = sn->rates[rc3].shortPreambleRateCode; } else { rixc1 = sn->rates[rc1].rateCode; rixc2 = sn->rates[rc2].rateCode; rixc3 = sn->rates[rc3].rateCode; } ath_hal_setupxtxdesc(sc->sc_ah, ds, rixc1, sn->retry_adjusted_count[rc1], /* series 1 */ rixc2, sn->retry_adjusted_count[rc2], /* series 2 */ rixc3, sn->retry_adjusted_count[rc3] /* series 3 */ );}static voidath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, const struct ath_desc *ds){ struct minstrel_node *sn = ATH_NODE_MINSTREL(an); struct ieee80211com *ic = &sc->sc_ic; const struct ar5212_desc *ads = (const struct ar5212_desc *)&ds->ds_ctl0; int final_rate = 0; int tries = 0; int ndx = -1; 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[ds->ds_txstat.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 = ds->ds_txstat.ts_shortretry + ds->ds_txstat.ts_longretry + 1; if (sn->num_rates <= 0) { DPRINTF(sc, "%s: %s %s no rates yet\n", dev_info, ether_sprintf(an->an_node.ni_macaddr), __func__); return; } if (!ds->ds_txstat.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 (ndx >= 0 && ndx < sn->num_rates) { sn->rs_rateattempts[ndx]++; /* only one rate was used */ } 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[ads->xmit_rate0].ieeerate; tries0 = ads->xmit_tries0; ndx0 = rate_to_ndx(sn, rate0); rate1 = sc->sc_hwmap[ads->xmit_rate1].ieeerate; tries1 = ads->xmit_tries1; ndx1 = rate_to_ndx(sn, rate1); rate2 = sc->sc_hwmap[ads->xmit_rate2].ieeerate; tries2 = ads->xmit_tries2; ndx2 = rate_to_ndx(sn, rate2); rate3 = sc->sc_hwmap[ads->xmit_rate3].ieeerate; tries3 = ads->xmit_tries3; 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: %s %s\n", dev_info, ether_sprintf(an->an_node.ni_macaddr), __func__); if (isnew) ath_rate_ctl_reset(sc, &an->an_node);}static voidath_fill_sample_table(struct minstrel_node *sn){ unsigned int num_sample_rates = sn->num_rates; unsigned int i, column_index; int newIndex; u_int8_t random_bytes[12]; for(column_index = 0; column_index < MINSTREL_COLUMNS; column_index++) { for (i = 0; i <= IEEE80211_RATE_MAXSIZE; i++) sn->rs_sampleTable[i][column_index] = 0; for (i = 0; i < num_sample_rates; i++) { get_random_bytes(random_bytes, 8); newIndex = (i + (int)(random_bytes[i & 7])) % num_sample_rates; if (newIndex < 0) newIndex = 2; while (sn->rs_sampleTable[newIndex][column_index] != 0) { newIndex = ((int)(newIndex + 1)) % num_sample_rates; if (newIndex < 0) newIndex = 2; } sn->rs_sampleTable[newIndex][column_index] = i + 1; } } sn->rs_sampleColumn = 0; sn->rs_sampleIndex = 0; /* Seed value to random number geenrator, which determines when we * send a sample packet at some non-optimal rate */ sn->random_n = 1; sn->a = 1664525; sn->b = 1013904223;#if 0 char rates[200]; char *p; for(column_index = 0; column_index < MINSTREL_COLUMNS; column_index++) { p = rates + sprintf(rates, "rates :: %d ", column_index); for (i = 0; i < num_sample_rates; i++) p += sprintf(p, "%2d ", (int)sn->rs_sampleTable[i][column_index]); DPRINTF(sc, "%s\n", rates); };#endif}/* Initialize the tables for a node. */static voidath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni){ struct ath_node *an = ATH_NODE(ni); struct minstrel_node *sn = ATH_NODE_MINSTREL(an); 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++) { 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_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(sn); ni->ni_txrate = 0; sn->num_rates = ni->ni_rates.rs_nrates; if (sn->num_rates <= 0) { DPRINTF(sc, "%s: %s %s no rates (fixed %d) \n", dev_info, __func__, ether_sprintf(ni->ni_macaddr), vap->iv_fixed_rate); /* there are no rates yet we're done */ return; } if (vap->iv_fixed_rate != 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 sorted */ for (; srate >= 0 && (ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) != vap->iv_fixed_rate; srate--); KASSERT(srate >= 0, ("fixed rate %d not in rate set", vap->iv_fixed_rate)); sn->static_rate_ndx = srate; ni->ni_txrate = srate; DPRINTF(sc, "%s: %s %s fixed rate %d%sMbps\n", dev_info, __func__, ether_sprintf(ni->ni_macaddr), sn->rates[srate].rate / 2, (sn->rates[srate].rate % 0x1) ? ".5" : " "); return; } for (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_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 < 11; 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 void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -