static void rate_control_pid_sample(struct rc_pid_info *pinfo, struct ieee80211_local *local, struct sta_info *sta) { #ifdef CONFIG_MAC80211_MESH struct ieee80211_sub_if_data *sdata = sta->sdata; #endif struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv; struct rc_pid_rateinfo *rinfo = pinfo->rinfo; struct ieee80211_supported_band *sband; u32 pf; s32 err_avg; u32 err_prop; u32 err_int; u32 err_der; int adj, i, j, tmp; unsigned long period; sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; spinfo = sta->rate_ctrl_priv; /* In case nothing happened during the previous control interval, turn * the sharpening factor on. */ period = (HZ * pinfo->sampling_period + 500) / 1000; if (!period) period = 1; if (jiffies - spinfo->last_sample > 2 * period) spinfo->sharp_cnt = pinfo->sharpen_duration; spinfo->last_sample = jiffies; /* This should never happen, but in case, we assume the old sample is * still a good measurement and copy it. */ if (unlikely(spinfo->tx_num_xmit == 0)) pf = spinfo->last_pf; else { pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit; #ifdef CONFIG_MAC80211_MESH if (pf == 100 && sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) mesh_plink_broken(sta); #endif pf <<= RC_PID_ARITH_SHIFT; sta->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9) >> RC_PID_ARITH_SHIFT; } spinfo->tx_num_xmit = 0; spinfo->tx_num_failed = 0; /* If we just switched rate, update the rate behaviour info. */ if (pinfo->oldrate != sta->txrate_idx) { i = rinfo[pinfo->oldrate].rev_index; j = rinfo[sta->txrate_idx].rev_index; tmp = (pf - spinfo->last_pf); tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT); rinfo[j].diff = rinfo[i].diff + tmp; pinfo->oldrate = sta->txrate_idx; } rate_control_pid_normalize(pinfo, sband->n_bitrates); /* Compute the proportional, integral and derivative errors. */ err_prop = (pinfo->target << RC_PID_ARITH_SHIFT) - pf; err_avg = spinfo->err_avg_sc >> pinfo->smoothing_shift; spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop; err_int = spinfo->err_avg_sc >> pinfo->smoothing_shift; err_der = (pf - spinfo->last_pf) * (1 + pinfo->sharpen_factor * spinfo->sharp_cnt); spinfo->last_pf = pf; if (spinfo->sharp_cnt) spinfo->sharp_cnt--; #ifdef CONFIG_MAC80211_DEBUGFS rate_control_pid_event_pf_sample(&spinfo->events, pf, err_prop, err_int, err_der); #endif /* Compute the controller output. */ adj = (err_prop * pinfo->coeff_p + err_int * pinfo->coeff_i + err_der * pinfo->coeff_d); adj = RC_PID_DO_ARITH_RIGHT_SHIFT(adj, 2 * RC_PID_ARITH_SHIFT); /* Change rate. */ if (adj) rate_control_pid_adjust_rate(local, sta, adj, rinfo); }
static void rate_control_pid_sample(struct rc_pid_info *pinfo, struct ieee80211_supported_band *sband, struct ieee80211_sta *sta, struct rc_pid_sta_info *spinfo) { struct rc_pid_rateinfo *rinfo = pinfo->rinfo; u32 pf; s32 err_avg; u32 err_prop; u32 err_int; u32 err_der; int adj, i, j, tmp; unsigned long period; /* In case nothing happened during the previous control interval, turn * the sharpening factor on. */ period = msecs_to_jiffies(pinfo->sampling_period); if (jiffies - spinfo->last_sample > 2 * period) spinfo->sharp_cnt = pinfo->sharpen_duration; spinfo->last_sample = jiffies; /* This should never happen, but in case, we assume the old sample is * still a good measurement and copy it. */ if (unlikely(spinfo->tx_num_xmit == 0)) pf = spinfo->last_pf; else pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit; spinfo->tx_num_xmit = 0; spinfo->tx_num_failed = 0; /* If we just switched rate, update the rate behaviour info. */ if (pinfo->oldrate != spinfo->txrate_idx) { i = rinfo[pinfo->oldrate].rev_index; j = rinfo[spinfo->txrate_idx].rev_index; tmp = (pf - spinfo->last_pf); tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT); rinfo[j].diff = rinfo[i].diff + tmp; pinfo->oldrate = spinfo->txrate_idx; } rate_control_pid_normalize(pinfo, sband->n_bitrates); /* Compute the proportional, integral and derivative errors. */ err_prop = (pinfo->target - pf) << RC_PID_ARITH_SHIFT; err_avg = spinfo->err_avg_sc >> pinfo->smoothing_shift; spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop; err_int = spinfo->err_avg_sc >> pinfo->smoothing_shift; err_der = (pf - spinfo->last_pf) * (1 + pinfo->sharpen_factor * spinfo->sharp_cnt); spinfo->last_pf = pf; if (spinfo->sharp_cnt) spinfo->sharp_cnt--; #ifdef CONFIG_MAC80211_DEBUGFS rate_control_pid_event_pf_sample(&spinfo->events, pf, err_prop, err_int, err_der); #endif /* Compute the controller output. */ adj = (err_prop * pinfo->coeff_p + err_int * pinfo->coeff_i + err_der * pinfo->coeff_d); adj = RC_PID_DO_ARITH_RIGHT_SHIFT(adj, 2 * RC_PID_ARITH_SHIFT); /* Change rate. */ if (adj) rate_control_pid_adjust_rate(sband, sta, spinfo, adj, rinfo); }