rc80211-pid: add sharpening factor
authorStefano Brivio <stefano.brivio@polimi.it>
Wed, 19 Dec 2007 00:26:52 +0000 (01:26 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Jan 2008 22:59:43 +0000 (14:59 -0800)
This patch introduces a PID sharpening factor for faster response after
association and low activity events.

Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Signed-off-by: Mattias Nissler <mattias.nissler@gmx.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mac80211/rc80211_pid.c

index 1116dc67ddd0409403fc2b784fa8b7129aaac50e..7f8cf27ad2f94b6a57c94399031a0fd75de9eb98 100644 (file)
  *
  * The controller basically computes the following:
  *
- * adj = CP * err + CI * err_avg + CD * (err - last_err)
+ * adj = CP * err + CI * err_avg + CD * (err - last_err) * (1 + sharpening)
  *
  * where
  *     adj     adjustment value that is used to switch TX rate (see below)
  *     err     current error: target vs. current failed frames percentage
  *     last_err        last error
  *     err_avg average (i.e. poor man's integral) of recent errors
+ *     sharpening      non-zero when fast response is needed (i.e. right after
+ *                     association or no frames sent for a long time), heading
+ *                     to zero over time
  *     CP      Proportional coefficient
  *     CI      Integral coefficient
  *     CD      Derivative coefficient
 #define RC_PID_SMOOTHING_SHIFT 3
 #define RC_PID_SMOOTHING (1 << RC_PID_SMOOTHING_SHIFT)
 
+/* Sharpening factor (used for D part of PID controller) */
+#define RC_PID_SHARPENING_FACTOR 0
+#define RC_PID_SHARPENING_DURATION 0
+
 /* Fixed point arithmetic shifting amount. */
 #define RC_PID_ARITH_SHIFT 8
 
@@ -131,8 +138,11 @@ struct rc_pid_sta_info {
         */
        s32 err_avg_sc;
 
-       /* Last framed failes percentage sample */
+       /* Last framed failes percentage sample. */
        u32 last_pf;
+
+       /* Sharpening needed. */
+       u8 sharp_cnt;
 };
 
 /* Algorithm parameters. We keep them on a per-algorithm approach, so they can
@@ -267,20 +277,26 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
 
        mode = local->oper_hw_mode;
        spinfo = sta->rate_ctrl_priv;
+
+       /* In case nothing happened during the previous control interval, turn
+        * the sharpening factor on. */
+       if (jiffies - spinfo->last_sample > 2 * RC_PID_INTERVAL)
+               spinfo->sharp_cnt = RC_PID_SHARPENING_DURATION;
+
        spinfo->last_sample = jiffies;
 
-       /* If no frames were transmitted, we assume the old sample is
+       /* This should never happen, but in case, we assume the old sample is
         * still a good measurement and copy it. */
-       if (spinfo->tx_num_xmit == 0)
+       if (unlikely(spinfo->tx_num_xmit == 0))
                pf = spinfo->last_pf;
        else {
                pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
                pf <<= RC_PID_ARITH_SHIFT;
-
-               spinfo->tx_num_xmit = 0;
-               spinfo->tx_num_failed = 0;
        }
 
+       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) {
 
@@ -302,8 +318,11 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
        spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop;
        err_int = spinfo->err_avg_sc >> RC_PID_SMOOTHING_SHIFT;
 
-       err_der = pf - spinfo->last_pf;
+       err_der = pf - spinfo->last_pf
+                 * (1 + RC_PID_SHARPENING_FACTOR * spinfo->sharp_cnt);
        spinfo->last_pf = pf;
+       if (spinfo->sharp_cnt)
+                       spinfo->sharp_cnt--;
 
        /* Compute the controller output. */
        adj = (err_prop * pinfo->coeff_p + err_int * pinfo->coeff_i