/* Adjust the rate while ensuring that we won't switch to a lower rate if it * exhibited a worse failed frames behaviour and we'll choose the highest rate * whose failed frames behaviour is not worse than the one of the original rate * target. While at it, check that the new rate is valid. */ static void rate_control_pid_adjust_rate(struct ieee80211_local *local, struct sta_info *sta, int adj, struct rc_pid_rateinfo *rinfo) { struct ieee80211_sub_if_data *sdata; struct ieee80211_supported_band *sband; int cur_sorted, new_sorted, probe, tmp, n_bitrates, band; int cur = sta->txrate_idx; sdata = sta->sdata; sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; band = sband->band; n_bitrates = sband->n_bitrates; /* Map passed arguments to sorted values. */ cur_sorted = rinfo[cur].rev_index; new_sorted = cur_sorted + adj; /* Check limits. */ if (new_sorted < 0) new_sorted = rinfo[0].rev_index; else if (new_sorted >= n_bitrates) new_sorted = rinfo[n_bitrates - 1].rev_index; tmp = new_sorted; if (adj < 0) { /* Ensure that the rate decrease isn't disadvantageous. */ for (probe = cur_sorted; probe >= new_sorted; probe--) if (rinfo[probe].diff <= rinfo[cur_sorted].diff && rate_supported(sta, band, rinfo[probe].index)) tmp = probe; } else { /* Look for rate increase with zero (or below) cost. */ for (probe = new_sorted + 1; probe < n_bitrates; probe++) if (rinfo[probe].diff <= rinfo[new_sorted].diff && rate_supported(sta, band, rinfo[probe].index)) tmp = probe; } /* Fit the rate found to the nearest supported rate. */ do { if (rate_supported(sta, band, rinfo[tmp].index)) { sta->txrate_idx = rinfo[tmp].index; break; } if (adj < 0) tmp--; else tmp++; } while (tmp < n_bitrates && tmp >= 0); #ifdef CONFIG_MAC80211_DEBUGFS rate_control_pid_event_rate_change( &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, sta->txrate_idx, sband->bitrates[sta->txrate_idx].bitrate); #endif }
/* Adjust the rate while ensuring that we won't switch to a lower rate if it * exhibited a worse failed frames behaviour and we'll choose the highest rate * whose failed frames behaviour is not worse than the one of the original rate * target. While at it, check that the new rate is valid. */ static void rate_control_pid_adjust_rate(struct ieee80211_local *local, struct sta_info *sta, int adj, struct rc_pid_rateinfo *rinfo) { struct ieee80211_sub_if_data *sdata; struct ieee80211_hw_mode *mode; int cur_sorted, new_sorted, probe, tmp, n_bitrates; int cur = sta->txrate; sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); mode = local->oper_hw_mode; n_bitrates = mode->num_rates; /* Map passed arguments to sorted values. */ cur_sorted = rinfo[cur].rev_index; new_sorted = cur_sorted + adj; /* Check limits. */ if (new_sorted < 0) new_sorted = rinfo[0].rev_index; else if (new_sorted >= n_bitrates) new_sorted = rinfo[n_bitrates - 1].rev_index; tmp = new_sorted; if (adj < 0) { /* Ensure that the rate decrease isn't disadvantageous. */ for (probe = cur_sorted; probe >= new_sorted; probe--) if (rinfo[probe].diff <= rinfo[cur_sorted].diff && rate_supported(sta, mode, rinfo[probe].index)) tmp = probe; } else { /* Look for rate increase with zero (or below) cost. */ for (probe = new_sorted + 1; probe < n_bitrates; probe++) if (rinfo[probe].diff <= rinfo[new_sorted].diff && rate_supported(sta, mode, rinfo[probe].index)) tmp = probe; } /* Fit the rate found to the nearest supported rate. */ do { if (rate_supported(sta, mode, rinfo[tmp].index)) { sta->txrate = rinfo[tmp].index; break; } if (adj < 0) tmp--; else tmp++; } while (tmp < n_bitrates && tmp >= 0); #ifdef CONFIG_MAC80211_DEBUGFS rate_control_pid_event_rate_change( &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, cur, mode->rates[cur].rate); #endif }
static void minstrel_ht_update_cck(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, struct ieee80211_supported_band *sband, struct ieee80211_sta *sta) { int i; if (sband->band != IEEE80211_BAND_2GHZ) return; if (!ieee80211_hw_check(mp->hw, SUPPORTS_HT_CCK_RATES)) return; mi->cck_supported = 0; mi->cck_supported_short = 0; for (i = 0; i < 4; i++) { if (!rate_supported(sta, sband->band, mp->cck_rates[i])) continue; mi->cck_supported |= BIT(i); if (sband->bitrates[i].flags & IEEE80211_RATE_SHORT_PREAMBLE) mi->cck_supported_short |= BIT(i); } mi->groups[MINSTREL_CCK_GROUP].supported = mi->cck_supported; }
static void rate_control_rate_dec(struct ieee80211_local *local, struct sta_info *sta) { struct ieee80211_sub_if_data *sdata; struct ieee80211_supported_band *sband; int i = sta->txrate_idx; sdata = sta->sdata; if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { /* forced unicast rate - do not change STA rate */ return; } sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; if (i > sband->n_bitrates) i = sband->n_bitrates; while (i > 0) { i--; if (rate_supported(sta, sband->band, i)) { sta->txrate_idx = i; break; } } }
static void rate_control_rate_inc(struct ieee80211_local *local, struct sta_info *sta) { struct ieee80211_sub_if_data *sdata; struct ieee80211_supported_band *sband; int i = sta->txrate_idx; int maxrate; sdata = sta->sdata; if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { /* forced unicast rate - do not change STA rate */ return; } sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1; if (i > sband->n_bitrates) i = sband->n_bitrates - 2; while (i + 1 < sband->n_bitrates) { i++; if (rate_supported(sta, sband->band, i) && (maxrate < 0 || i <= maxrate)) { sta->txrate_idx = i; break; } } }
static void indra_rate_init(void *priv, struct ieee80211_supported_band *sband, struct cfg80211_chan_def *chandef, struct ieee80211_sta *sta, void *priv_sta) { struct indra_sta_info *ii = priv_sta; struct indra_priv *ip = priv; unsigned int i, n = 0, s, st = 0; u32 rate_flags; ii->sta = sta; ii->lowest_rix = rate_lowest_index(sband, sta); rate_flags = ieee80211_chandef_rate_flags(&ip->hw->conf.chandef); for (i = 0; i < sband->n_bitrates; i++) { struct indra_rate *ir = &ii->r[n]; if (!rate_supported(sta, sband->band, i)) continue; if ((rate_flags & sband->bitrates[i].flags) != rate_flags) continue; n++; memset(ir, 0, sizeof(*ir)); ir->rix = i; ir->last_attempts = 0; ir->last_success = 0; calc_service_time_values(ip,sband->band, ir, &sband->bitrates[i], chandef); initialize_map(ir,&sband->bitrates[i],chandef); } for (i = n; i < sband->n_bitrates; i++) { struct indra_rate *ir = &ii->r[i]; ir->rix = -1; } /* Check if max retry is compliant with constraint on service time */ for (s = 1; s <= ip->max_retry; s++) { struct indra_rate *ir = &ii->r[n-1]; st = st + ir->attempts[s-1]; if (st>ip->st_deadline) { ip->max_retry = s - 1; break; } } ii->n_rates = n; ii->last_snr = 0; ii->flags = 0; ii->tx_flags = 0; indra_update_rates(ip, ii); }