diff -ruN old/tcp_bic.c new/tcp_bic.c
--- old/tcp_bic.c	2007-05-31 17:01:48.000000000 +0100
+++ new/tcp_bic.c	2007-06-01 13:47:16.000000000 +0100
@@ -20,6 +20,7 @@
 #include "ns-linux-c.h"
 #include "ns-linux-util.h"
 
+
 #define BICTCP_BETA_SCALE    1024	/* Scale factor beta calculation
 					 * max_cwnd = snd_cwnd * beta
 					 */
@@ -200,12 +201,6 @@
 	return max(tp->snd_cwnd, ca->last_max_cwnd);
 }
 
-static u32 bictcp_min_cwnd(struct sock *sk)
-{
-	const struct tcp_sock *tp = tcp_sk(sk);
-	return tp->snd_ssthresh;
-}
-
 static void bictcp_state(struct sock *sk, u8 new_state)
 {
 	if (new_state == TCP_CA_Loss)
@@ -233,7 +228,6 @@
 	.cong_avoid	= bictcp_cong_avoid,
 	.set_state	= bictcp_state,
 	.undo_cwnd	= bictcp_undo_cwnd,
-	.min_cwnd	= bictcp_min_cwnd,
 	.pkts_acked     = bictcp_acked,
 	.owner		= THIS_MODULE,
 	.name		= "bic",
@@ -241,7 +235,7 @@
 
 static int __init bictcp_register(void)
 {
-	BUG_ON(sizeof(struct bictcp) > ICSK_CA_PRIV_SIZE);
+	BUILD_BUG_ON(sizeof(struct bictcp) > ICSK_CA_PRIV_SIZE);
 	return tcp_register_congestion_control(&bictcp);
 }
 
diff -ruN old/tcp_compound.c new/tcp_compound.c
--- old/tcp_compound.c	2007-05-31 17:01:48.000000000 +0100
+++ new/tcp_compound.c	2007-06-06 10:51:30.000000000 +0100
@@ -6,7 +6,7 @@
  *    "TCP Vegas: End to end congestion avoidance on a global internet."
  *    IEEE Journal on Selected Areas in Communication, 13(8):1465--1480,
  *    October 1995. Available from:
- *	ftp://ftp.cs.arizona.edu/xkernel/Papers/jsac.ps
+ * ftp://ftp.cs.arizona.edu/xkernel/Papers/jsac.ps
  *
  * See http://www.cs.arizona.edu/xkernel/ for their implementation.
  * The main aspects that distinguish this implementation from the
@@ -54,21 +54,23 @@
 
 #define TCP_COMPOUND_ALPHA          3U
 #define TCP_COMPOUND_BETA           1U
+#define TCP_COMPOUND_KAPPA_POW      3
+#define TCP_COMPOUND_KAPPA_NSQRT    2
 #define TCP_COMPOUND_GAMMA         30
 #define TCP_COMPOUND_ZETA           1
 
 /* TCP compound variables */
 struct compound {
-	u32 beg_snd_nxt;	/* right edge during last RTT */
-	u32 beg_snd_una;	/* left edge  during last RTT */
-	u32 beg_snd_cwnd;	/* saves the size of the cwnd */
-	u8 doing_vegas_now;	/* if true, do vegas for this RTT */
-	u16 cntRTT;		/* # of RTTs measured within last RTT */
-	u32 minRTT;		/* min of RTTs measured within last RTT (in usec) */
-	u32 baseRTT;		/* the min of all Vegas RTT measurements seen (in usec) */
+u32 beg_snd_nxt; /* right edge during last RTT */
+u32 beg_snd_una; /* left edge  during last RTT */
+u32 beg_snd_cwnd; /* saves the size of the cwnd */
+u8 doing_vegas_now; /* if true, do vegas for this RTT */
+u16 cntRTT; /* # of RTTs measured within last RTT */
+u32 minRTT; /* min of RTTs measured within last RTT (in usec) */
+u32 baseRTT; /* the min of all Vegas RTT measurements seen (in usec) */
 
-	u32 cwnd;
-	u32 dwnd;
+u32 cwnd;
+u32 dwnd;
 };
 
 /* There are several situations when we must "re-start" Vegas:
@@ -89,37 +91,37 @@
  */
 static inline void cvegas_enable(struct sock *sk)
 {
-	const struct tcp_sock *tp = tcp_sk(sk);
-	struct compound *vegas = inet_csk_ca(sk);
+const struct tcp_sock *tp = tcp_sk(sk);
+struct compound *vegas = inet_csk_ca(sk);
 
-	/* Begin taking Vegas samples next time we send something. */
-	vegas->doing_vegas_now = 1;
+/* Begin taking Vegas samples next time we send something. */
+vegas->doing_vegas_now = 1;
 
-	/* Set the beginning of the next send window. */
-	vegas->beg_snd_nxt = tp->snd_nxt;
+/* Set the beginning of the next send window. */
+vegas->beg_snd_nxt = tp->snd_nxt;
 
-	vegas->cntRTT = 0;
-	vegas->minRTT = 0x7fffffff;
+vegas->cntRTT = 0;
+vegas->minRTT = 0x7fffffff;
 }
 
 /* Stop taking Vegas samples for now. */
 static inline void cvegas_disable(struct sock *sk)
 {
-	struct compound *vegas = inet_csk_ca(sk);
+struct compound *vegas = inet_csk_ca(sk);
 
-	vegas->doing_vegas_now = 0;
+vegas->doing_vegas_now = 0;
 }
 
 static void tcp_compound_init(struct sock *sk)
 {
-	struct compound *vegas = inet_csk_ca(sk);
-	const struct tcp_sock *tp = tcp_sk(sk);
+struct compound *vegas = inet_csk_ca(sk);
+const struct tcp_sock *tp = tcp_sk(sk);
 
 	vegas->baseRTT = 0x7fffffff;
 	cvegas_enable(sk);
 
-	vegas->dwnd = 0;
-	vegas->cwnd = tp->snd_cwnd;
+vegas->dwnd = 0;
+vegas->cwnd = tp->snd_cwnd;
 }
 
 /* Do RTT sampling needed for Vegas.
@@ -132,19 +134,19 @@
  */
 static void tcp_compound_rtt_calc(struct sock *sk, u32 usrtt)
 {
-	struct compound *vegas = inet_csk_ca(sk);
-	u32 vrtt = usrtt + 1;	/* Never allow zero rtt or baseRTT */
+struct compound *vegas = inet_csk_ca(sk);
+u32 vrtt = usrtt + 1; /* Never allow zero rtt or baseRTT */
 
-	/* Filter to find propagation delay: */
-	if (vrtt < vegas->baseRTT) 
-		vegas->baseRTT = vrtt;
-
-	/* Find the min RTT during the last RTT to find
-	 * the current prop. delay + queuing delay:
-	 */
+/* Filter to find propagation delay: */
+if (vrtt < vegas->baseRTT)
+vegas->baseRTT = vrtt;
 
-	vegas->minRTT = min(vegas->minRTT, vrtt);
-	vegas->cntRTT++;
+/* Find the min RTT during the last RTT to find
+* the current prop. delay + queuing delay:
+*/
+
+vegas->minRTT = min(vegas->minRTT, vrtt);
+vegas->cntRTT++;
 }
 
 static void tcp_compound_state(struct sock *sk, u8 ca_state)
@@ -156,58 +158,6 @@
 		cvegas_disable(sk);
 }
 
-
-/* 64bit divisor, dividend and result. dynamic precision */
-static inline u64 cdiv64_64(u64 dividend, u64 divisor)
-{
-       u32 d = divisor;
-
-       if (divisor > 0xffffffffULL) {
-               unsigned int shift = fls(divisor >> 32);
-
-               d = divisor >> shift;
-               dividend >>= shift;
-       }
-
-       /* avoid 64 bit division if possible */
-       if (dividend >> 32)
-               do_div(dividend, d);
-       else
-               dividend = (u32) dividend / d;
-
-       return dividend;
-}
-
-/* calculate the quartic root of "a" using Newton-Raphson */
-static u32 qroot(u64 a)
-{
-       u32 x, x1;
-
-       /* Initial estimate is based on:
-        * qrt(x) = exp(log(x) / 4)
-        */
-       x = 1u << (fls64(a) >> 2);
-
-       /*
-        * Iteration based on:
-        *                         3
-        * x    = ( 3 * x  +  a / x  ) / 4
-        *  k+1          k         k
-        */
-       do {
-               u64 x3 = x;
-
-               x1 = x;
-               x3 *= x;
-               x3 *= x;
-
-               x = (3 * x + (u32) cdiv64_64(a, x3)) / 4;
-       } while (abs(x1 - x) > 1);
-
-       return x;
-}
-
-
 /*
  * If the connection is idle and we are restarting,
  * then we don't want to do any Vegas calculations
@@ -219,16 +169,16 @@
  */
 static void tcp_compound_cwnd_event(struct sock *sk, enum tcp_ca_event event)
 {
-	if (event == CA_EVENT_CWND_RESTART || event == CA_EVENT_TX_START)
-		tcp_compound_init(sk);
+if (event == CA_EVENT_CWND_RESTART || event == CA_EVENT_TX_START)
+tcp_compound_init(sk);
 }
 
 static void tcp_compound_cong_avoid(struct sock *sk, u32 ack,
-				    u32 seq_rtt, u32 in_flight, int flag)
+    u32 seq_rtt, u32 in_flight, int flag)
 {
-	struct tcp_sock *tp = tcp_sk(sk);
-	struct compound *vegas = inet_csk_ca(sk);
-	u8 inc = 0;
+struct tcp_sock *tp = tcp_sk(sk);
+struct compound *vegas = inet_csk_ca(sk);
+u8 inc = 0;
 
   if (vegas->cwnd + vegas->dwnd > tp->snd_cwnd) {
 
@@ -243,211 +193,216 @@
 
   }
 
-	if (!tcp_is_cwnd_limited(sk, in_flight))
-		return;
+if (!tcp_is_cwnd_limited(sk, in_flight))
+return;
+
+if (vegas->cwnd <= tp->snd_ssthresh)
+inc = 1;
+else if (tp->snd_cwnd_cnt < tp->snd_cwnd)
+tp->snd_cwnd_cnt++;
+
+if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+inc = 1;
+tp->snd_cwnd_cnt = 0;
+}
+
+if (inc && tp->snd_cwnd < tp->snd_cwnd_clamp)
+vegas->cwnd++;
+
+/* The key players are v_beg_snd_una and v_beg_snd_nxt.
+*
+* These are so named because they represent the approximate values
+* of snd_una and snd_nxt at the beginning of the current RTT. More
+* precisely, they represent the amount of data sent during the RTT.
+* At the end of the RTT, when we receive an ACK for v_beg_snd_nxt,
+* we will calculate that (v_beg_snd_nxt - v_beg_snd_una) outstanding
+* bytes of data have been ACKed during the course of the RTT, giving
+* an "actual" rate of:
+*
+*     (v_beg_snd_nxt - v_beg_snd_una) / (rtt duration)
+*
+* Unfortunately, v_beg_snd_una is not exactly equal to snd_una,
+* because delayed ACKs can cover more than one segment, so they
+* don't line up nicely with the boundaries of RTTs.
+*
+* Another unfortunate fact of life is that delayed ACKs delay the
+* advance of the left edge of our send window, so that the number
+* of bytes we send in an RTT is often less than our cwnd will allow.
+* So we keep track of our cwnd separately, in v_beg_snd_cwnd.
+*/
+
+if (after(ack, vegas->beg_snd_nxt)) {
+/* Do the Vegas once-per-RTT cwnd adjustment. */
+u32 old_wnd, old_snd_cwnd;
+
+/* Here old_wnd is essentially the window of data that was
+* sent during the previous RTT, and has all
+* been acknowledged in the course of the RTT that ended
+* with the ACK we just received. Likewise, old_snd_cwnd
+* is the cwnd during the previous RTT.
+*/
+if (!tp->mss_cache)
+return;
+
+old_wnd = (vegas->beg_snd_nxt - vegas->beg_snd_una) /
+    tp->mss_cache;
+old_snd_cwnd = vegas->beg_snd_cwnd;
+
+/* Save the extent of the current window so we can use this
+* at the end of the next RTT.
+*/
+vegas->beg_snd_una = vegas->beg_snd_nxt;
+vegas->beg_snd_nxt = tp->snd_nxt;
+vegas->beg_snd_cwnd = tp->snd_cwnd;
+
+/* We do the Vegas calculations only if we got enough RTT
+* samples that we can be reasonably sure that we got
+* at least one RTT sample that wasn't from a delayed ACK.
+* If we only had 2 samples total,
+* then that means we're getting only 1 ACK per RTT, which
+* means they're almost certainly delayed ACKs.
+* If  we have 3 samples, we should be OK.
+*/
+
+if (vegas->cntRTT > 2) {
+u32 rtt, target_cwnd, diff;
+u32 brtt, dwnd;
+
+/* We have enough RTT samples, so, using the Vegas
+* algorithm, we determine if we should increase or
+* decrease cwnd, and by how much.
+*/
+
+/* Pluck out the RTT we are using for the Vegas
+* calculations. This is the min RTT seen during the
+* last RTT. Taking the min filters out the effects
+* of delayed ACKs, at the cost of noticing congestion
+* a bit later.
+*/
+rtt = vegas->minRTT;
+
+/* Calculate the cwnd we should have, if we weren't
+* going too fast.
+*
+* This is:
+*     (actual rate in segments) * baseRTT
+* We keep it as a fixed point number with
+* V_PARAM_SHIFT bits to the right of the binary point.
+*/
+if (!rtt)
+return;
 
-	if (vegas->cwnd <= tp->snd_ssthresh)
-		inc = 1;
-	else if (tp->snd_cwnd_cnt < tp->snd_cwnd)
-		tp->snd_cwnd_cnt++;
-
-	if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
-		inc = 1;
-		tp->snd_cwnd_cnt = 0;
-	}
-
-	if (inc && tp->snd_cwnd < tp->snd_cwnd_clamp)
-		vegas->cwnd++;
-
-	/* The key players are v_beg_snd_una and v_beg_snd_nxt.
-	 *
-	 * These are so named because they represent the approximate values
-	 * of snd_una and snd_nxt at the beginning of the current RTT. More
-	 * precisely, they represent the amount of data sent during the RTT.
-	 * At the end of the RTT, when we receive an ACK for v_beg_snd_nxt,
-	 * we will calculate that (v_beg_snd_nxt - v_beg_snd_una) outstanding
-	 * bytes of data have been ACKed during the course of the RTT, giving
-	 * an "actual" rate of:
-	 *
-	 *     (v_beg_snd_nxt - v_beg_snd_una) / (rtt duration)
-	 *
-	 * Unfortunately, v_beg_snd_una is not exactly equal to snd_una,
-	 * because delayed ACKs can cover more than one segment, so they
-	 * don't line up nicely with the boundaries of RTTs.
-	 *
-	 * Another unfortunate fact of life is that delayed ACKs delay the
-	 * advance of the left edge of our send window, so that the number
-	 * of bytes we send in an RTT is often less than our cwnd will allow.
-	 * So we keep track of our cwnd separately, in v_beg_snd_cwnd.
-	 */
-
-	if (after(ack, vegas->beg_snd_nxt)) {
-		/* Do the Vegas once-per-RTT cwnd adjustment. */
-		u32 old_wnd, old_snd_cwnd;
-
-		/* Here old_wnd is essentially the window of data that was
-		 * sent during the previous RTT, and has all
-		 * been acknowledged in the course of the RTT that ended
-		 * with the ACK we just received. Likewise, old_snd_cwnd
-		 * is the cwnd during the previous RTT.
-		 */
-		if (!tp->mss_cache)
-			return;
-
-		old_wnd = (vegas->beg_snd_nxt - vegas->beg_snd_una) /
-		    tp->mss_cache;
-		old_snd_cwnd = vegas->beg_snd_cwnd;
-
-		/* Save the extent of the current window so we can use this
-		 * at the end of the next RTT.
-		 */
-		vegas->beg_snd_una = vegas->beg_snd_nxt;
-		vegas->beg_snd_nxt = tp->snd_nxt;
-		vegas->beg_snd_cwnd = tp->snd_cwnd;
-
-		/* We do the Vegas calculations only if we got enough RTT
-		 * samples that we can be reasonably sure that we got
-		 * at least one RTT sample that wasn't from a delayed ACK.
-		 * If we only had 2 samples total,
-		 * then that means we're getting only 1 ACK per RTT, which
-		 * means they're almost certainly delayed ACKs.
-		 * If  we have 3 samples, we should be OK.
-		 */
-
-		if (vegas->cntRTT > 2) {
-			u32 rtt, target_cwnd, diff;
-			u32 brtt, dwnd;
-
-			/* We have enough RTT samples, so, using the Vegas
-			 * algorithm, we determine if we should increase or
-			 * decrease cwnd, and by how much.
-			 */
-
-			/* Pluck out the RTT we are using for the Vegas
-			 * calculations. This is the min RTT seen during the
-			 * last RTT. Taking the min filters out the effects
-			 * of delayed ACKs, at the cost of noticing congestion
-			 * a bit later.
-			 */
-			rtt = vegas->minRTT;
-
-			/* Calculate the cwnd we should have, if we weren't
-			 * going too fast.
-			 *
-			 * This is:
-			 *     (actual rate in segments) * baseRTT
-			 * We keep it as a fixed point number with
-			 * V_PARAM_SHIFT bits to the right of the binary point.
-			 */
-			if (!rtt)
-				return;
-
-			brtt = vegas->baseRTT;
-			target_cwnd = ((old_wnd * brtt)
-				       << V_PARAM_SHIFT) / rtt;
-
-			/* Calculate the difference between the window we had,
-			 * and the window we would like to have. This quantity
-			 * is the "Diff" from the Arizona Vegas papers.
-			 *
-			 * Again, this is a fixed point number with
-			 * V_PARAM_SHIFT bits to the right of the binary
-			 * point.
-			 */
-
-			diff = (old_wnd << V_PARAM_SHIFT) - target_cwnd;
-
-			dwnd = vegas->dwnd;
-
-			if (diff < (TCP_COMPOUND_GAMMA << V_PARAM_SHIFT)) {
-				u64 win3;
-				u64 x;
-				/*
-				 * The TCP Compound paper describes the choice
-				 * of "k" determines the agressiveness,
-				 * ie. slope of the response function.
-				 *
-				 * For same value as HSTCP would be 0.8
-				 * but for computaional reasons, both the
-				 * original authors and this implementation
-				 * use 0.75.
-				 */
-				win3 = old_wnd;
-				win3 *= old_wnd;
-				win3 *= old_wnd;
-				x = qroot(win3) >> TCP_COMPOUND_ALPHA;
-
-				if (x > 1)
-					dwnd = x - 1;
-				else
-					dwnd = 0;
-
-				dwnd += vegas->dwnd;
-
-			} else if ((dwnd << V_PARAM_SHIFT) <
-				   (diff * TCP_COMPOUND_BETA))
-				dwnd = 0;
-			else
-				dwnd =
-				    ((dwnd << V_PARAM_SHIFT) -
-				     (diff *
-				      TCP_COMPOUND_BETA)) >> V_PARAM_SHIFT;
-
-			vegas->dwnd = dwnd;
-
-		}
-
-		/* Wipe the slate clean for the next RTT. */
-		vegas->cntRTT = 0;
-		vegas->minRTT = 0x7fffffff;
-	}
+brtt = vegas->baseRTT;
+target_cwnd = ((old_wnd * brtt)
+      << V_PARAM_SHIFT) / rtt;
+
+/* Calculate the difference between the window we had,
+* and the window we would like to have. This quantity
+* is the "Diff" from the Arizona Vegas papers.
+*
+* Again, this is a fixed point number with
+* V_PARAM_SHIFT bits to the right of the binary
+* point.
+*/
 
-	tp->snd_cwnd = vegas->cwnd + vegas->dwnd;
+diff = (old_wnd << V_PARAM_SHIFT) - target_cwnd;
+
+dwnd = vegas->dwnd;
+
+if (diff < (TCP_COMPOUND_GAMMA << V_PARAM_SHIFT)) {
+u32 i, j, x, x2;
+        u64 v;
+
+v = 1;
+
+for (i = 0; i < TCP_COMPOUND_KAPPA_POW; i++)
+v *= old_wnd;
+
+for (i = 0; i < TCP_COMPOUND_KAPPA_NSQRT; i++) {
+x = 1;
+for (j = 0; j < 200; j++) {
+            x2 = ( x + v / x ) / 2;
+
+            if (x2 == x || !x2)
+              break;
+
+            x = x2;
+}
+v = x;
 }
 
+x = (u32)v >> TCP_COMPOUND_ALPHA;
+
+if (x > 1)
+dwnd = x - 1;
+else
+dwnd = 0;
+
+dwnd += vegas->dwnd;
+
+} else if ((dwnd << V_PARAM_SHIFT) <
+  (diff * TCP_COMPOUND_BETA))
+dwnd = 0;
+else
+dwnd =
+    ((dwnd << V_PARAM_SHIFT) -
+    (diff *
+      TCP_COMPOUND_BETA)) >> V_PARAM_SHIFT;
+
+vegas->dwnd = dwnd;
+
+}
+
+/* Wipe the slate clean for the next RTT. */
+vegas->cntRTT = 0;
+vegas->minRTT = 0x7fffffff;
+}
+
+tp->snd_cwnd = vegas->cwnd + vegas->dwnd;
+}
 
 /* Extract info for Tcp socket info provided via netlink. */
 static void tcp_compound_get_info(struct sock *sk, u32 ext, struct sk_buff *skb)
 {
-	const struct compound *ca = inet_csk_ca(sk);
-	if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
-		struct tcpvegas_info *info;
-
-		info = RTA_DATA(__RTA_PUT(skb, INET_DIAG_VEGASINFO,
-					  sizeof(*info)));
-
-		info->tcpv_enabled = ca->doing_vegas_now;
-		info->tcpv_rttcnt = ca->cntRTT;
-		info->tcpv_rtt = ca->baseRTT;
-		info->tcpv_minrtt = ca->minRTT;
-	      rtattr_failure:;
-	}
+const struct compound *ca = inet_csk_ca(sk);
+if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
+struct tcpvegas_info *info;
+
+info = RTA_DATA(__RTA_PUT(skb, INET_DIAG_VEGASINFO,
+  sizeof(*info)));
+
+info->tcpv_enabled = ca->doing_vegas_now;
+info->tcpv_rttcnt = ca->cntRTT;
+info->tcpv_rtt = ca->baseRTT;
+info->tcpv_minrtt = ca->minRTT;
+      rtattr_failure:;
+}
 }
 
 static struct tcp_congestion_ops tcp_compound = {
-	.init = tcp_compound_init,
-	.ssthresh = tcp_reno_ssthresh,
-	.cong_avoid = tcp_compound_cong_avoid,
-	.min_cwnd = tcp_reno_min_cwnd,
-	.rtt_sample = tcp_compound_rtt_calc,
-	.set_state = tcp_compound_state,
-	.cwnd_event = tcp_compound_cwnd_event,
-	.get_info = tcp_compound_get_info,
+.init = tcp_compound_init,
+.ssthresh = tcp_reno_ssthresh,
+.cong_avoid = tcp_compound_cong_avoid,
+.min_cwnd = tcp_reno_min_cwnd,
+.rtt_sample = tcp_compound_rtt_calc,
+.set_state = tcp_compound_state,
+.cwnd_event = tcp_compound_cwnd_event,
+.get_info = tcp_compound_get_info,
 
-	.owner = THIS_MODULE,
-	.name = "compound",
+.owner = THIS_MODULE,
+.name = "compound",
 };
 
 static int __init tcp_compound_register(void)
 {
-	BUG_ON(sizeof(struct compound) > ICSK_CA_PRIV_SIZE);
-	tcp_register_congestion_control(&tcp_compound);
-	return 0;
+BUG_ON(sizeof(struct compound) > ICSK_CA_PRIV_SIZE);
+tcp_register_congestion_control(&tcp_compound);
+return 0;
 }
 
 static void __exit tcp_compound_unregister(void)
 {
-	tcp_unregister_congestion_control(&tcp_compound);
+tcp_unregister_congestion_control(&tcp_compound);
 }
 
 module_init(tcp_compound_register);
@@ -456,15 +411,3 @@
 MODULE_AUTHOR("Angelo P. Castellani / Stephen Hemminger");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("TCP Compound");
-
-
-
-
-
-
-
-
-
-
-
-
diff -ruN old/tcp_cong.c new/tcp_cong.c
--- old/tcp_cong.c	2007-05-31 17:01:48.000000000 +0100
+++ new/tcp_cong.c	2007-06-07 12:41:09.000000000 +0100
@@ -41,7 +41,7 @@
 	int ret = 0;
 
 	/* all algorithms must implement ssthresh and cong_avoid ops */
-	if (!ca->ssthresh || !ca->cong_avoid || !ca->min_cwnd) {
+	if (!ca->ssthresh || !ca->cong_avoid) {
 		printk(KERN_ERR "TCP %s does not implement required ops\n",
 		       ca->name);
 		return -EINVAL;
@@ -117,7 +117,7 @@
 	spin_lock(&tcp_cong_list_lock);
 	ca = tcp_ca_find(name);
 #ifdef CONFIG_KMOD
-	if (!ca) {
+	if (!ca && capable(CAP_SYS_MODULE)) {
 		spin_unlock(&tcp_cong_list_lock);
 
 		request_module("tcp_%s", name);
@@ -157,6 +157,7 @@
 
 	rcu_read_lock();
 	ca = tcp_ca_find(name);
+	/* no change asking for existing value */
 	if (ca == icsk->icsk_ca_ops)
 		goto out;
 
@@ -193,7 +194,7 @@
 			return;
 
 		/* We MAY increase by 2 if discovered delayed ack */
-		if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) {
+		if (sysctl_tcp_abc > 1 && tp->bytes_acked >= 2*tp->mss_cache) {
 			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
 				tp->snd_cwnd++;
 		}
@@ -226,7 +227,7 @@
 
  	/* In dangerous area, increase slowly. */
 	else if (sysctl_tcp_abc) {
- 		/* RFC3465: Apppriate Byte Count
+ 		/* RFC3465: Appropriate Byte Count
  		 * increase once for each full cwnd acked
  		 */
  		if (tp->bytes_acked >= tp->snd_cwnd*tp->mss_cache) {
diff -ruN old/tcp_cubic.c new/tcp_cubic.c
--- old/tcp_cubic.c	2007-05-31 17:01:48.000000000 +0100
+++ new/tcp_cubic.c	2007-06-01 13:12:27.000000000 +0100
@@ -182,6 +182,7 @@
 			ca->bic_origin_point = ca->last_max_cwnd;
 		}
 	}
+
         /* cubic function - calc*/
         /* calculate c * time^3 / rtt,
          *  while considering overflow in calculation of time^3
@@ -197,7 +198,7 @@
          */
 
 	/* change the unit from HZ to cbictcp_HZ */
-        t = ((tcp_time_stamp + ca->delay_min - ca->epoch_start)
+        t = ((tcp_time_stamp + (ca->delay_min>>3) - ca->epoch_start)
 	     << BICTCP_HZ) / HZ;
 
         if (t < ca->bic_K)		/* t - K */
@@ -266,7 +267,7 @@
 	    (s32)(tcp_time_stamp - ca->epoch_start) < HZ)
 		return;
 
-	delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
+	delay = (tcp_time_stamp - tp->rx_opt.rcv_tsecr)<<3;
 	if (delay == 0)
 		delay = 1;
 
@@ -347,7 +348,7 @@
  */
 static void cbictcp_acked(struct sock *sk, u32 cnt)
 {
-	struct inet_connection_sock *icsk = inet_csk(sk);
+	const struct inet_connection_sock *icsk = inet_csk(sk);
 
 	if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) {
 		struct cbictcp *ca = inet_csk_ca(sk);
@@ -371,7 +372,7 @@
 
 static int __init cubictcp_register(void)
 {
-	BUG_ON(sizeof(struct cbictcp) > ICSK_CA_PRIV_SIZE);
+	BUILD_BUG_ON(sizeof(struct cbictcp) > ICSK_CA_PRIV_SIZE);
 
 	/* Precompute a bunch of the scaling factors that are used per-packet
 	 * based on SRTT of 100ms
@@ -379,7 +380,7 @@
 
 	beta_scale = 8*(BICTCP_BETA_SCALE+cbeta)/ 3 / (BICTCP_BETA_SCALE - cbeta);
 
-	cube_rtt_scale = (cbic_scale << 3) / 10;	/* 1024*c/rtt */
+	cube_rtt_scale = (cbic_scale * 10);	/* 1024*c/rtt */
 
 	/* calculate the "K" for (wmax-cwnd) = c/rtt * K^3
 	 *  so K = cubic_root( (wmax-cwnd)*rtt/c )
diff -ruN old/tcp_highspeed.c new/tcp_highspeed.c
--- old/tcp_highspeed.c	2007-05-31 17:01:48.000000000 +0100
+++ new/tcp_highspeed.c	2007-06-06 09:55:04.000000000 +0100
@@ -100,6 +100,10 @@
 	u32	ai;
 };
 
+static int max_ssthresh = 100;
+module_param(max_ssthresh, int, 0644);
+MODULE_PARM_DESC(max_ssthresh, "limited slow start threshold (RFC3742)");
+
 static void hstcp_init(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -121,26 +125,46 @@
 	if (!tcp_is_cwnd_limited(sk, in_flight))
 		return;
 
-	if (tp->snd_cwnd <= tp->snd_ssthresh)
-		tcp_slow_start(tp);
-	else {
-		/* Update AIMD parameters */
+	if (tp->snd_cwnd <= tp->snd_ssthresh) {
+		/* RFC3742: limited slow start
+		 * the window is increased by 1/K MSS for each arriving ACK,
+		 * for K = int(cwnd/(0.5 max_ssthresh))
+		 */
+		if (max_ssthresh > 0 && tp->snd_cwnd > max_ssthresh) {
+			u32 k = max(tp->snd_cwnd / (max_ssthresh >> 1), 1U);
+			if (++tp->snd_cwnd_cnt >= k) {
+				if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+					tp->snd_cwnd++;
+				tp->snd_cwnd_cnt = 0;
+			}
+		} else {
+			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+				tp->snd_cwnd++;
+		}
+	} else {
+		/* Update AIMD parameters.
+		 *
+		 * We want to guarantee that:
+		 *     hstcp_aimd_vals[ca->ai-1].cwnd <
+		 *     snd_cwnd <=
+		 *     hstcp_aimd_vals[ca->ai].cwnd
+		 */
 		if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
 			while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
 			       ca->ai < HSTCP_AIMD_MAX - 1)
 				ca->ai++;
-		} else if (tp->snd_cwnd < hstcp_aimd_vals[ca->ai].cwnd) {
-			while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
-			       ca->ai > 0)
+		} else if (ca->ai && tp->snd_cwnd <= hstcp_aimd_vals[ca->ai-1].cwnd) {
+			while (ca->ai && tp->snd_cwnd <= hstcp_aimd_vals[ca->ai-1].cwnd)
 				ca->ai--;
 		}
 
 		/* Do additive increase */
 		if (tp->snd_cwnd < tp->snd_cwnd_clamp) {
-			tp->snd_cwnd_cnt += ca->ai;
+			/* cwnd = cwnd + a(w) / cwnd */
+			tp->snd_cwnd_cnt += ca->ai + 1;
 			if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
-				tp->snd_cwnd++;
 				tp->snd_cwnd_cnt -= tp->snd_cwnd;
+				tp->snd_cwnd++;
 			}
 		}
 	}
@@ -168,7 +192,7 @@
 
 static int __init hstcp_register(void)
 {
-	BUG_ON(sizeof(struct hstcp) > ICSK_CA_PRIV_SIZE);
+	BUILD_BUG_ON(sizeof(struct hstcp) > ICSK_CA_PRIV_SIZE);
 	return tcp_register_congestion_control(&tcp_highspeed);
 }
 
diff -ruN old/tcp_htcp.c new/tcp_htcp.c
--- old/tcp_htcp.c	2007-05-31 17:01:48.000000000 +0100
+++ new/tcp_htcp.c	2007-06-06 14:05:52.000000000 +0100
@@ -27,16 +27,18 @@
 MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher");
 
 struct htcp {
-	u16	alpha;		/* Fixed point arith, << 7 */
+	u32	alpha;		/* Fixed point arith, << 7 */
 	u8	beta;           /* Fixed point arith, << 7 */
 	u8	modeswitch;     /* Delay modeswitch until we had at least one congestion event */
-	u8	ccount;		/* Number of RTTs since last congestion event */
-	u8	undo_ccount;
-	u16	packetcount;
+	u16	pkts_acked;
+	u32	ccount;
+	u32	undo_ccount;
+	u32	packetcount;
 	u32	minRTT;
 	u32	maxRTT;
 	u32	snd_cwnd_cnt2;
 
+
 	u32	undo_maxRTT;
 	u32	undo_old_maxB;
 
@@ -48,6 +50,8 @@
 	u32	lasttime;
 };
 
+
+
 static inline void htcp_reset(struct htcp *ca)
 {
 	ca->undo_ccount = ca->ccount;
@@ -95,6 +99,12 @@
 	struct htcp *ca = inet_csk_ca(sk);
 	u32 now = tcp_time_stamp;
 
+	if (icsk->icsk_ca_state == TCP_CA_Open)
+		ca->pkts_acked = pkts_acked;
+
+	if (!use_bandwidth_switch)
+		return;
+
 	/* achieved throughput calculations */
 	if (icsk->icsk_ca_state != TCP_CA_Open &&
 	    icsk->icsk_ca_state != TCP_CA_Disorder) {
@@ -268,7 +278,6 @@
 static struct tcp_congestion_ops htcp = {
 	.init		= htcp_init,
 	.ssthresh	= htcp_recalc_ssthresh,
-	.min_cwnd	= htcp_min_cwnd,
 	.cong_avoid	= htcp_cong_avoid,
 	.set_state	= htcp_state,
 	.undo_cwnd	= htcp_cwnd_undo,
@@ -279,7 +288,7 @@
 
 static int __init htcp_register(void)
 {
-	BUG_ON(sizeof(struct htcp) > ICSK_CA_PRIV_SIZE);
+	BUILD_BUG_ON(sizeof(struct htcp) > ICSK_CA_PRIV_SIZE);
 	BUILD_BUG_ON(BETA_MIN >= BETA_MAX);
 	if (!use_bandwidth_switch)
 		htcp.pkts_acked = NULL;
diff -ruN old/tcp_hybla.c new/tcp_hybla.c
--- old/tcp_hybla.c	2007-05-31 17:01:48.000000000 +0100
+++ new/tcp_hybla.c	2007-06-05 13:59:14.000000000 +0100
@@ -174,7 +174,7 @@
 
 static int __init hybla_register(void)
 {
-	BUG_ON(sizeof(struct hybla) > ICSK_CA_PRIV_SIZE);
+	BUILD_BUG_ON(sizeof(struct hybla) > ICSK_CA_PRIV_SIZE);
 	return tcp_register_congestion_control(&tcp_hybla);
 }
 
diff -ruN old/tcp_lp.c new/tcp_lp.c
--- old/tcp_lp.c	2007-05-31 17:01:48.000000000 +0100
+++ new/tcp_lp.c	2007-06-05 17:07:33.000000000 +0100
@@ -3,13 +3,8 @@
  *
  * TCP Low Priority is a distributed algorithm whose goal is to utilize only
  *   the excess network bandwidth as compared to the ``fair share`` of
- *   bandwidth as targeted by TCP. Available from:
- *     http://www.ece.rice.edu/~akuzma/Doc/akuzma/TCP-LP.pdf
+ *   bandwidth as targeted by TCP.
  *
- * Original Author:
- *   Aleksandar Kuzmanovic <akuzma@northwestern.edu>
- *
- * See http://www-ece.rice.edu/networks/TCP-LP/ for their implementation.
  * As of 2.6.13, Linux supports pluggable congestion control algorithms.
  * Due to the limitation of the API, we take the following changes from
  * the original TCP-LP implementation:
@@ -24,11 +19,18 @@
  *   o OWD is handled in relative format, where local time stamp will in
  *     tcp_time_stamp format.
  *
- * Port from 2.4.19 to 2.6.16 as module by:
- *   Wong Hoi Sing Edison <hswong3i@gmail.com>
- *   Hung Hing Lun <hlhung3i@gmail.com>
- *
- * Version: $Id: tcp_lp.c,v 1.22 2006-05-02 18:18:19 hswong3i Exp $
+ * Original Author:
+ *   Aleksandar Kuzmanovic <akuzma@northwestern.edu>
+ * Available from:
+ *   http://www.ece.rice.edu/~akuzma/Doc/akuzma/TCP-LP.pdf
+ * Original implementation for 2.4.19:
+ *   http://www-ece.rice.edu/networks/TCP-LP/
+ *
+ * 2.6.x module Authors:
+ *   Wong Hoi Sing, Edison <hswong3i@gmail.com>
+ *   Hung Hing Lun, Mike <hlhung3i@gmail.com>
+ * SourceForge project page:
+ *   http://tcp-lp-mod.sourceforge.net/
  */
 
 /*
@@ -57,10 +59,10 @@
  * We create this set of state flag mainly for debugging.
  */
 enum tcp_lp_state {
-       LP_VALID_RHZ = (1 << 0),
-       LP_VALID_OWD = (1 << 1),
-       LP_WITHIN_THR = (1 << 3),
-       LP_WITHIN_INF = (1 << 4),
+	LP_VALID_RHZ = (1 << 0),
+	LP_VALID_OWD = (1 << 1),
+	LP_WITHIN_THR = (1 << 3),
+	LP_WITHIN_INF = (1 << 4),
 };
 
 /**
@@ -81,16 +83,16 @@
  * found are really useful.
  */
 struct lp {
-       u32 flag;
-       u32 sowd;
-       u32 owd_min;
-       u32 owd_max;
-       u32 owd_max_rsv;
-       u32 remote_hz;
-       u32 remote_ref_time;
-       u32 local_ref_time;
-       u32 last_drop;
-       u32 inference;
+	u32 flag;
+	u32 sowd;
+	u32 owd_min;
+	u32 owd_max;
+	u32 owd_max_rsv;
+	u32 remote_hz;
+	u32 remote_ref_time;
+	u32 local_ref_time;
+	u32 last_drop;
+	u32 inference;
 };
 
 /**
@@ -101,18 +103,18 @@
  */
 static void tcp_lp_init(struct sock *sk)
 {
-       struct lp *lp = inet_csk_ca(sk);
+	struct lp *lp = inet_csk_ca(sk);
 
-       lp->flag = 0;
-       lp->sowd = 0;
-       lp->owd_min = 0xffffffff;
-       lp->owd_max = 0;
-       lp->owd_max_rsv = 0;
-       lp->remote_hz = 0;
-       lp->remote_ref_time = 0;
-       lp->local_ref_time = 0;
-       lp->last_drop = 0;
-       lp->inference = 0;
+	lp->flag = 0;
+	lp->sowd = 0;
+	lp->owd_min = 0xffffffff;
+	lp->owd_max = 0;
+	lp->owd_max_rsv = 0;
+	lp->remote_hz = 0;
+	lp->remote_ref_time = 0;
+	lp->local_ref_time = 0;
+	lp->last_drop = 0;
+	lp->inference = 0;
 }
 
 /**
@@ -123,12 +125,12 @@
  * From TCP-LP's paper, this will be handled in additive increasement.
  */
 static void tcp_lp_cong_avoid(struct sock *sk, u32 ack, u32 rtt, u32 in_flight,
-                             int flag)
+			      int flag)
 {
-       struct lp *lp = inet_csk_ca(sk);
+	struct lp *lp = inet_csk_ca(sk);
 
-       if (!(lp->flag & LP_WITHIN_INF))
-               tcp_reno_cong_avoid(sk, ack, rtt, in_flight, flag);
+	if (!(lp->flag & LP_WITHIN_INF))
+		tcp_reno_cong_avoid(sk, ack, rtt, in_flight, flag);
 }
 
 /**
@@ -138,44 +140,47 @@
  * We keep on updating the estimated value, where original TCP-LP
  * implementation only guest it for once and use forever.
  */
-static inline u32 tcp_lp_remote_hz_estimator(struct sock *sk)
+static u32 tcp_lp_remote_hz_estimator(struct sock *sk)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
-       struct lp *lp = inet_csk_ca(sk);
-       s64 rhz = lp->remote_hz << 6;   /* remote HZ << 6 */
-       s64 m = 0;
-
-       /* not yet record reference time
-        * go away!! record it before come back!! */
-       if (lp->remote_ref_time == 0 || lp->local_ref_time == 0)
-               goto out;
-
-       /* we can't calc remote HZ with no different!! */
-       if (tp->rx_opt.rcv_tsval == lp->remote_ref_time
-           || tp->rx_opt.rcv_tsecr == lp->local_ref_time)
-               goto out;
-
-       m = HZ * (tp->rx_opt.rcv_tsval -
-                 lp->remote_ref_time) / (tp->rx_opt.rcv_tsecr -
-                                         lp->local_ref_time);
-       if (m < 0)
-               m = -m;
-
-       if (rhz != 0) {
-               m -= (rhz >> 6);        /* m is now error in remote HZ est */
-               rhz += m;       /* 63/64 old + 1/64 new */
-       } else
-               rhz = m << 6;
-
-       /* record time for successful remote HZ calc */
-       lp->flag |= LP_VALID_RHZ;
-
-      out:
-       /* record reference time stamp */
-       lp->remote_ref_time = tp->rx_opt.rcv_tsval;
-       lp->local_ref_time = tp->rx_opt.rcv_tsecr;
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct lp *lp = inet_csk_ca(sk);
+	s64 rhz = lp->remote_hz << 6;	/* remote HZ << 6 */
+	s64 m = 0;
+
+	/* not yet record reference time
+	 * go away!! record it before come back!! */
+	if (lp->remote_ref_time == 0 || lp->local_ref_time == 0)
+		goto out;
+
+	/* we can't calc remote HZ with no different!! */
+	if (tp->rx_opt.rcv_tsval == lp->remote_ref_time
+	    || tp->rx_opt.rcv_tsecr == lp->local_ref_time)
+		goto out;
+
+	m = HZ * (tp->rx_opt.rcv_tsval -
+		  lp->remote_ref_time) / (tp->rx_opt.rcv_tsecr -
+					  lp->local_ref_time);
+	if (m < 0)
+		m = -m;
+
+	if (rhz > 0) {
+		m -= rhz >> 6;	/* m is now error in remote HZ est */
+		rhz += m;	/* 63/64 old + 1/64 new */
+	} else
+		rhz = m << 6;
+
+ out:
+	/* record time for successful remote HZ calc */
+	if ((rhz >> 6) > 0)
+		lp->flag |= LP_VALID_RHZ;
+	else
+		lp->flag &= ~LP_VALID_RHZ;
+
+	/* record reference time stamp */
+	lp->remote_ref_time = tp->rx_opt.rcv_tsval;
+	lp->local_ref_time = tp->rx_opt.rcv_tsecr;
 
-       return rhz >> 6;
+	return rhz >> 6;
 }
 
 /**
@@ -188,28 +193,28 @@
  * OWD into zero.
  * It seems to be a bug and so we fixed it.
  */
-static inline u32 tcp_lp_owd_calculator(struct sock *sk)
+static u32 tcp_lp_owd_calculator(struct sock *sk)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
-       struct lp *lp = inet_csk_ca(sk);
-       s64 owd = 0;
-
-       lp->remote_hz = tcp_lp_remote_hz_estimator(sk);
-
-       if (lp->flag & LP_VALID_RHZ) {
-               owd =
-                   tp->rx_opt.rcv_tsval * (LP_RESOL / lp->remote_hz) -
-                   tp->rx_opt.rcv_tsecr * (LP_RESOL / HZ);
-               if (owd < 0)
-                       owd = -owd;
-       }
-
-       if (owd > 0)
-               lp->flag |= LP_VALID_OWD;
-       else
-               lp->flag &= ~LP_VALID_OWD;
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct lp *lp = inet_csk_ca(sk);
+	s64 owd = 0;
+
+	lp->remote_hz = tcp_lp_remote_hz_estimator(sk);
+
+	if (lp->flag & LP_VALID_RHZ) {
+		owd =
+		    tp->rx_opt.rcv_tsval * (LP_RESOL / lp->remote_hz) -
+		    tp->rx_opt.rcv_tsecr * (LP_RESOL / HZ);
+		if (owd < 0)
+			owd = -owd;
+	}
+
+	if (owd > 0)
+		lp->flag |= LP_VALID_OWD;
+	else
+		lp->flag &= ~LP_VALID_OWD;
 
-       return owd;
+	return owd;
 }
 
 /**
@@ -224,36 +229,36 @@
  */
 static void tcp_lp_rtt_sample(struct sock *sk, u32 usrtt)
 {
-       struct lp *lp = inet_csk_ca(sk);
-       s64 mowd = tcp_lp_owd_calculator(sk);
+	struct lp *lp = inet_csk_ca(sk);
+	s64 mowd = tcp_lp_owd_calculator(sk);
 
-       /* sorry that we don't have valid data */
-       if (!(lp->flag & LP_VALID_RHZ) || !(lp->flag & LP_VALID_OWD))
-               return;
-
-       /* record the next min owd */
-       if (mowd < lp->owd_min)
-               lp->owd_min = mowd;
-
-       /* always forget the max of the max
-        * we just set owd_max as one below it */
-       if (mowd > lp->owd_max) {
-               if (mowd > lp->owd_max_rsv) {
-                       if (lp->owd_max_rsv == 0)
-                               lp->owd_max = mowd;
-                       else
-                               lp->owd_max = lp->owd_max_rsv;
-                       lp->owd_max_rsv = mowd;
-               } else
-                       lp->owd_max = mowd;
-       }
-
-       /* calc for smoothed owd */
-       if (lp->sowd != 0) {
-               mowd -= (lp->sowd >> 3);        /* m is now error in owd est */
-               lp->sowd += mowd;       /* owd = 7/8 owd + 1/8 new */
-       } else
-               lp->sowd = mowd << 3;   /* take the measured time be owd */
+	/* sorry that we don't have valid data */
+	if (!(lp->flag & LP_VALID_RHZ) || !(lp->flag & LP_VALID_OWD))
+		return;
+
+	/* record the next min owd */
+	if (mowd < lp->owd_min)
+		lp->owd_min = mowd;
+
+	/* always forget the max of the max
+	 * we just set owd_max as one below it */
+	if (mowd > lp->owd_max) {
+		if (mowd > lp->owd_max_rsv) {
+			if (lp->owd_max_rsv == 0)
+				lp->owd_max = mowd;
+			else
+				lp->owd_max = lp->owd_max_rsv;
+			lp->owd_max_rsv = mowd;
+		} else
+			lp->owd_max = mowd;
+	}
+
+	/* calc for smoothed owd */
+	if (lp->sowd != 0) {
+		mowd -= lp->sowd >> 3;	/* m is now error in owd est */
+		lp->sowd += mowd;	/* owd = 7/8 owd + 1/8 new */
+	} else
+		lp->sowd = mowd << 3;	/* take the measured time be owd */
 }
 
 /**
@@ -267,25 +272,25 @@
  */
 static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
-       struct lp *lp = inet_csk_ca(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct lp *lp = inet_csk_ca(sk);
 
-       /* calc inference */
-       if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
-               lp->inference = 3 * (tcp_time_stamp - tp->rx_opt.rcv_tsecr);
-
-       /* test if within inference */
-       if (lp->last_drop && (tcp_time_stamp - lp->last_drop < lp->inference))
-               lp->flag |= LP_WITHIN_INF;
-       else
-               lp->flag &= ~LP_WITHIN_INF;
-
-       /* test if within threshold */
-       if (lp->sowd >> 3 <
-           lp->owd_min + 15 * (lp->owd_max - lp->owd_min) / 100)
-               lp->flag |= LP_WITHIN_THR;
-       else
-               lp->flag &= ~LP_WITHIN_THR;
+	/* calc inference */
+	if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
+		lp->inference = 3 * (tcp_time_stamp - tp->rx_opt.rcv_tsecr);
+
+	/* test if within inference */
+	if (lp->last_drop && (tcp_time_stamp - lp->last_drop < lp->inference))
+		lp->flag |= LP_WITHIN_INF;
+	else
+		lp->flag &= ~LP_WITHIN_INF;
+
+	/* test if within threshold */
+	if (lp->sowd >> 3 <
+	    lp->owd_min + 15 * (lp->owd_max - lp->owd_min) / 100)
+		lp->flag |= LP_WITHIN_THR;
+	else
+		lp->flag &= ~LP_WITHIN_THR;
 
 #if CONFIG_TCP_CONG_LP_DEBUG == 1
        printk(KERN_DEBUG "TCP-LP: %05o|%5u|%5u|%15u|%15u|%15u\n", lp->flag,
@@ -293,56 +298,56 @@
 p->sowd >> 3);
 #endif
 
-       if (lp->flag & LP_WITHIN_THR)
-               return;
+	if (lp->flag & LP_WITHIN_THR)
+		return;
 
-       /* FIXME: try to reset owd_min and owd_max here
-        * so decrease the chance the min/max is no longer suitable
-        * and will usually within threshold when whithin inference */
-       lp->owd_min = (lp->sowd >> 3);
-       lp->owd_max = (lp->sowd >> 2);
-       lp->owd_max_rsv = (lp->sowd >> 2);
-
-       /* happened within inference
-        * drop snd_cwnd into 1 */
-       if (lp->flag & LP_WITHIN_INF)
-               tp->snd_cwnd = 1U;
-
-       /* happened after inference
-        * cut snd_cwnd into half */
-       else
-               tp->snd_cwnd = max(tp->snd_cwnd >> 1U, 1U);
+	/* FIXME: try to reset owd_min and owd_max here
+	 * so decrease the chance the min/max is no longer suitable
+	 * and will usually within threshold when whithin inference */
+	lp->owd_min = lp->sowd >> 3;
+	lp->owd_max = lp->sowd >> 2;
+	lp->owd_max_rsv = lp->sowd >> 2;
+
+	/* happened within inference
+	 * drop snd_cwnd into 1 */
+	if (lp->flag & LP_WITHIN_INF)
+		tp->snd_cwnd = 1U;
+
+	/* happened after inference
+	 * cut snd_cwnd into half */
+	else
+		tp->snd_cwnd = max(tp->snd_cwnd >> 1U, 1U);
 
-       /* record this drop time */
-       lp->last_drop = tcp_time_stamp;
+	/* record this drop time */
+	lp->last_drop = tcp_time_stamp;
 }
 
 static struct tcp_congestion_ops tcp_lp = {
-       .init = tcp_lp_init,
-       .ssthresh = tcp_reno_ssthresh,
-       .cong_avoid = tcp_lp_cong_avoid,
-       .min_cwnd = tcp_reno_min_cwnd,
-       .rtt_sample = tcp_lp_rtt_sample,
-       .pkts_acked = tcp_lp_pkts_acked,
+	.init = tcp_lp_init,
+	.ssthresh = tcp_reno_ssthresh,
+	.cong_avoid = tcp_lp_cong_avoid,
+	.min_cwnd = tcp_reno_min_cwnd,
+	.rtt_sample = tcp_lp_rtt_sample,
+	.pkts_acked = tcp_lp_pkts_acked,
 
-       .owner = THIS_MODULE,
-       .name = "lp"
+	.owner = THIS_MODULE,
+	.name = "lp"
 };
 
-static int __init lp_register(void)
+static int __init tcp_lp_register(void)
 {
-       BUG_ON(sizeof(struct lp) > ICSK_CA_PRIV_SIZE);
-       return tcp_register_congestion_control(&tcp_lp);
+	BUILD_BUG_ON(sizeof(struct lp) > ICSK_CA_PRIV_SIZE);
+	return tcp_register_congestion_control(&tcp_lp);
 }
 
-static void __exit lp_unregister(void)
+static void __exit tcp_lp_unregister(void)
 {
-       tcp_unregister_congestion_control(&tcp_lp);
+	tcp_unregister_congestion_control(&tcp_lp);
 }
 
-module_init(lp_register);
-module_exit(lp_unregister);
+module_init(tcp_lp_register);
+module_exit(tcp_lp_unregister);
 
-MODULE_AUTHOR("Wong Hoi Sing Edison, Hung Hing Lun");
+MODULE_AUTHOR("Wong Hoi Sing Edison, Hung Hing Lun Mike");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("TCP Low Priority");
diff -ruN old/tcp_vegas.c new/tcp_vegas.c
--- old/tcp_vegas.c	2007-05-31 17:01:48.000000000 +0100
+++ new/tcp_vegas.c	2007-06-05 10:07:51.000000000 +0100
@@ -45,8 +45,8 @@
  * with V_PARAM_SHIFT bits to the right of the binary point.
  */
 #define V_PARAM_SHIFT 1
-static int valpha = 1<<V_PARAM_SHIFT;
-static int vbeta  = 3<<V_PARAM_SHIFT;
+static int valpha = 2<<V_PARAM_SHIFT;
+static int vbeta  = 4<<V_PARAM_SHIFT;
 static int gamma = 1<<V_PARAM_SHIFT;
 
 module_param(valpha, int, 0644);
@@ -373,7 +373,7 @@
 
 static int __init tcp_vegas_register(void)
 {
-	BUG_ON(sizeof(struct vegas) > ICSK_CA_PRIV_SIZE);
+	BUILD_BUG_ON(sizeof(struct vegas) > ICSK_CA_PRIV_SIZE);
 	tcp_register_congestion_control(&tcp_vegas);
 	return 0;
 }
diff -ruN old/tcp_veno.c new/tcp_veno.c
--- old/tcp_veno.c	2007-05-31 17:01:48.000000000 +0100
+++ new/tcp_veno.c	2007-06-05 14:30:43.000000000 +0100
@@ -6,7 +6,7 @@
  *    "TCP Veno: TCP Enhancement for Transmission over Wireless Access Networks."
  *    IEEE Journal on Selected Areas in Communication,
  *    Feb. 2003.
- *     See http://www.ntu.edu.sg/home5/ZHOU0022/papers/CPFu03a.pdf
+ * 	See http://www.ntu.edu.sg/home5/ZHOU0022/papers/CPFu03a.pdf
  */
 /*
 #include <linux/config.h>
@@ -24,17 +24,16 @@
  * with V_PARAM_SHIFT bits to the right of the binary point.
  */
 #define V_PARAM_SHIFT 1
-static int vnbeta  = 3<<V_PARAM_SHIFT;
-
+static const int vnbeta  = 3 << V_PARAM_SHIFT;
 
 /* Veno variables */
 struct veno {
-       u8      doing_veno_now;/* if true, do veno for this RTT */
-       u16     cntrtt;         /* # of RTTs measured */
-       u32     minrtt;         /* min of RTTs measured within last RTT (in usec) */
-       u32     basertt;        /* the min of all Veno RTT measurements seen (in usec) */
-       u32     inc;    /* decide whether to increase cwnd */
-       u32 diff;       /* calculate the diff rate */
+	u8 doing_veno_now;	/* if true, do veno for this rtt */
+	u16 cntrtt;		/* # of rtts measured within last rtt */
+	u32 minrtt;		/* min of rtts measured within last rtt (in usec) */
+	u32 basertt;		/* the min of all Veno rtt measurements seen (in usec) */
+	u32 inc;		/* decide whether to increase cwnd */
+	u32 diff;		/* calculate the diff rate */
 };
 
 /* There are several situations when we must "re-start" Veno:
@@ -48,62 +47,60 @@
  */
 static inline void veno_enable(struct sock *sk)
 {
-       struct veno *veno = inet_csk_ca(sk);
+	struct veno *veno = inet_csk_ca(sk);
 
-       /* turn on Veno */
-       veno->doing_veno_now = 1;
+	/* turn on Veno */
+	veno->doing_veno_now = 1;
 
-       veno->minrtt = 0x7fffffff;
+	veno->minrtt = 0x7fffffff;
 }
 
 static inline void veno_disable(struct sock *sk)
 {
-       struct veno *veno = inet_csk_ca(sk);
+	struct veno *veno = inet_csk_ca(sk);
 
-       /* turn off Veno */
-       veno->doing_veno_now = 0;
+	/* turn off Veno */
+	veno->doing_veno_now = 0;
 }
 
 static void tcp_veno_init(struct sock *sk)
 {
-       struct veno *veno = inet_csk_ca(sk);
+	struct veno *veno = inet_csk_ca(sk);
 
-       veno->basertt = 0x7fffffff;
-       veno->inc = 1;
-       veno->cntrtt = 0;
-       veno_enable(sk);
+	veno->basertt = 0x7fffffff;
+	veno->inc = 1;
+	veno_enable(sk);
 }
 
-/* Do RTT sampling needed for Veno. */
+/* Do rtt sampling needed for Veno. */
 static void tcp_veno_rtt_calc(struct sock *sk, u32 usrtt)
 {
-       struct veno *veno = inet_csk_ca(sk);
-       u32 vrtt = usrtt + 1; /* Never allow zero rtt or baseRTT */
+	struct veno *veno = inet_csk_ca(sk);
+	u32 vrtt = usrtt + 1;	/* Never allow zero rtt or basertt */
 
-       /* Filter to find propagation delay: */
-       if (vrtt < veno->basertt)
-               veno->basertt = vrtt;
-
-       /* Find the min RTT during the last RTT to find
-        * the current prop. delay + queuing delay:
-        */
-       veno->minrtt = min(veno->minrtt, vrtt);
-       veno->cntrtt++;
+	/* Filter to find propagation delay: */
+	if (vrtt < veno->basertt)
+		veno->basertt = vrtt;
+
+	/* Find the min rtt during the last rtt to find
+	 * the current prop. delay + queuing delay:
+	 */
+	veno->minrtt = min(veno->minrtt, vrtt);
+	veno->cntrtt++;
 }
 
 static void tcp_veno_state(struct sock *sk, u8 ca_state)
 {
-
-       if (ca_state == TCP_CA_Open)
-               veno_enable(sk);
-       else
-               veno_disable(sk);
+	if (ca_state == TCP_CA_Open)
+		veno_enable(sk);
+	else
+		veno_disable(sk);
 }
 
 /*
  * If the connection is idle and we are restarting,
  * then we don't want to do any Veno calculations
- * until we get fresh RTT samples.  So when we
+ * until we get fresh rtt samples.  So when we
  * restart, we reset our Veno state to a clean
  * state. After we get acks for this flight of
  * packets, _then_ we can make Veno calculations
@@ -111,141 +108,122 @@
  */
 static void tcp_veno_cwnd_event(struct sock *sk, enum tcp_ca_event event)
 {
-       if (event == CA_EVENT_CWND_RESTART ||
-           event == CA_EVENT_TX_START)
-               tcp_veno_init(sk);
+	if (event == CA_EVENT_CWND_RESTART || event == CA_EVENT_TX_START)
+		tcp_veno_init(sk);
 }
 
 static void tcp_veno_cong_avoid(struct sock *sk, u32 ack,
-                                u32 seq_rtt, u32 in_flight, int flag)
+				u32 seq_rtt, u32 in_flight, int flag)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
-       struct veno *veno = inet_csk_ca(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct veno *veno = inet_csk_ca(sk);
 
-       if (!veno->doing_veno_now)
-               return tcp_reno_cong_avoid(sk, ack, seq_rtt, in_flight, flag);
+	if (!veno->doing_veno_now)
+		return tcp_reno_cong_avoid(sk, ack, seq_rtt, in_flight, flag);
 
-       /* limited by applications */
-       if (!tcp_is_cwnd_limited(sk, in_flight))
-               return;
-
-       /* We do the Veno calculations only if we got enough RTT samples */
-       if (veno->cntrtt <= 2) {
-               /* We don't have enough RTT samples to do the Veno
-                * calculation, so we'll behave like Reno.
-                */
-               tcp_reno_cong_avoid(sk, ack, seq_rtt, in_flight, flag);
-       } else {
-               u32 rtt, target_cwnd;
-
-               /* We have enough RTT samples, so, using the Veno
-                * algorithm, we determine the state of the network.
-                */
-
-               rtt = veno->minrtt;
-
-               target_cwnd = ((tp->snd_cwnd * veno->basertt)
-                              << V_PARAM_SHIFT) / rtt;
-
-               veno->diff = (tp->snd_cwnd << V_PARAM_SHIFT) - target_cwnd;
-
-               if (tp->snd_cwnd <= tp->snd_ssthresh) {
-                       /* Slow start.  */
-                       tcp_slow_start(tp);
-               }
-               else if (sysctl_tcp_abc) {
-                       /* RFC3465: Apppriate Byte Count
-                       * increase once for each full cwnd acked.
-                       * Veno has no idear about it so far, so we keep
-                       * it as Reno.
-                       */
-                       if (tp->bytes_acked >= tp->snd_cwnd*tp->mss_cache) {
-                               tp->bytes_acked -= tp->snd_cwnd*tp->mss_cache;
-                               if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-                                       tp->snd_cwnd++;
-                       }
-               }else {
-                       /* Congestion avoidance. */
-                       if (veno->diff < vnbeta) {
-                               /* In the "non-congestive state", increase cwnd
-                                *  every rtt.
-                                */
-                               if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
-                                       if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-                                               tp->snd_cwnd++;
-                                       tp->snd_cwnd_cnt = 0;
-                               } else
-                                       tp->snd_cwnd_cnt++;
-                       } else {
-                               /* In the "congestive state", increase cwnd
-                                * every other rtt.
-                                */
-                                       if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
-                                               if (veno->inc && tp->snd_cwnd < tp->snd_cwnd_clamp) {
-                                               tp->snd_cwnd++;
-                                               veno->inc = 0;
-                       }
-                                       else
-                                               veno->inc = 1;
-                                               tp->snd_cwnd_cnt = 0;
-                                       } else
-                                               tp->snd_cwnd_cnt++;
-                       }
-
-               }
-               if (tp->snd_cwnd < 2)
-                       tp->snd_cwnd = 2;
-               else if (tp->snd_cwnd > tp->snd_cwnd_clamp)
-                       tp->snd_cwnd = tp->snd_cwnd_clamp;
-       }
-               /* Wipe the state clean for the next RTT. */
-       veno->minrtt = 0x7fffffff;
+	/* limited by applications */
+	if (!tcp_is_cwnd_limited(sk, in_flight))
+		return;
+
+	/* We do the Veno calculations only if we got enough rtt samples */
+	if (veno->cntrtt <= 2) {
+		/* We don't have enough rtt samples to do the Veno
+		 * calculation, so we'll behave like Reno.
+		 */
+		tcp_reno_cong_avoid(sk, ack, seq_rtt, in_flight, flag);
+	} else {
+		u32 rtt, target_cwnd;
+
+		/* We have enough rtt samples, so, using the Veno
+		 * algorithm, we determine the state of the network.
+		 */
+
+		rtt = veno->minrtt;
+
+		target_cwnd = ((tp->snd_cwnd * veno->basertt)
+			       << V_PARAM_SHIFT) / rtt;
+
+		veno->diff = (tp->snd_cwnd << V_PARAM_SHIFT) - target_cwnd;
+
+		if (tp->snd_cwnd <= tp->snd_ssthresh) {
+			/* Slow start.  */
+			tcp_slow_start(tp);
+		} else {
+			/* Congestion avoidance. */
+			if (veno->diff < vnbeta) {
+				/* In the "non-congestive state", increase cwnd
+				 *  every rtt.
+				 */
+				if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+					if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+						tp->snd_cwnd++;
+					tp->snd_cwnd_cnt = 0;
+				} else
+					tp->snd_cwnd_cnt++;
+			} else {
+				/* In the "congestive state", increase cwnd
+				 * every other rtt.
+				 */
+				if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+					if (veno->inc
+					    && tp->snd_cwnd <
+					    tp->snd_cwnd_clamp) {
+						tp->snd_cwnd++;
+						veno->inc = 0;
+					} else
+						veno->inc = 1;
+					tp->snd_cwnd_cnt = 0;
+				} else
+					tp->snd_cwnd_cnt++;
+			}
+
+		}
+		if (tp->snd_cwnd < 2)
+			tp->snd_cwnd = 2;
+		else if (tp->snd_cwnd > tp->snd_cwnd_clamp)
+			tp->snd_cwnd = tp->snd_cwnd_clamp;
+	}
+	/* Wipe the slate clean for the next rtt. */
+	/* veno->cntrtt = 0; */
+	veno->minrtt = 0x7fffffff;
 }
 
 /* Veno MD phase */
-u32 tcp_veno_ssthresh(struct sock *sk)
+static u32 tcp_veno_ssthresh(struct sock *sk)
 {
-       const struct tcp_sock *tp = tcp_sk(sk);
-       struct veno *veno = inet_csk_ca(sk);
-       if(veno->diff < vnbeta) {
-               /* in "non-congestive state", cut cwnd by 1/5 */
-               return max(tp->snd_cwnd*4/5, 2U);
-       }else {
-               /* in "congestive state", cut cwnd by 1/2 */
-               return max(tp->snd_cwnd >> 1U, 2U);
-       }
-}
+	const struct tcp_sock *tp = tcp_sk(sk);
+	struct veno *veno = inet_csk_ca(sk);
 
-u32 tcp_veno_min_cwnd(struct sock *sk)
-{
-       const struct tcp_sock *tp = tcp_sk(sk);
-       return tp->snd_ssthresh;
+	if (veno->diff < vnbeta)
+		/* in "non-congestive state", cut cwnd by 1/5 */
+		return max(tp->snd_cwnd * 4 / 5, 2U);
+	else
+		/* in "congestive state", cut cwnd by 1/2 */
+		return max(tp->snd_cwnd >> 1U, 2U);
 }
 
-
 static struct tcp_congestion_ops tcp_veno = {
-       .init           = tcp_veno_init,
-       .ssthresh       = tcp_veno_ssthresh,
-       .cong_avoid     = tcp_veno_cong_avoid,
-       .min_cwnd       = tcp_veno_min_cwnd,
-       .rtt_sample     = tcp_veno_rtt_calc,
-       .set_state      = tcp_veno_state,
-       .cwnd_event     = tcp_veno_cwnd_event,
+	.init		= tcp_veno_init,
+	.ssthresh	= tcp_veno_ssthresh,
+	.cong_avoid	= tcp_veno_cong_avoid,
+	.rtt_sample	= tcp_veno_rtt_calc,
+	.set_state	= tcp_veno_state,
+	.cwnd_event	= tcp_veno_cwnd_event,
 
-       .owner          = THIS_MODULE,
-       .name           = "veno",
+	.owner		= THIS_MODULE,
+	.name		= "veno",
 };
 
 static int __init tcp_veno_register(void)
 {
-       BUG_ON(sizeof(struct veno) > ICSK_CA_PRIV_SIZE);
-       tcp_register_congestion_control(&tcp_veno);
-       return 0;
+	BUILD_BUG_ON(sizeof(struct veno) > ICSK_CA_PRIV_SIZE);
+	tcp_register_congestion_control(&tcp_veno);
+	return 0;
 }
 
 static void __exit tcp_veno_unregister(void)
 {
-       tcp_unregister_congestion_control(&tcp_veno);
+	tcp_unregister_congestion_control(&tcp_veno);
 }
 
 module_init(tcp_veno_register);
diff -ruN old/tcp_westwood.c new/tcp_westwood.c
--- old/tcp_westwood.c	2007-05-31 17:01:48.000000000 +0100
+++ new/tcp_westwood.c	2007-06-05 14:11:36.000000000 +0100
@@ -1,7 +1,24 @@
 /*
- * TCP Westwood+
+ * TCP Westwood+: end-to-end bandwidth estimation for TCP
  *
- *	Angelo Dell'Aera:	TCP Westwood+ support
+ *      Angelo Dell'Aera: author of the first version of TCP Westwood+ in Linux 2.4
+ *
+ * Support at http://c3lab.poliba.it/index.php/Westwood
+ * Main references in literature:
+ *
+ * - Mascolo S, Casetti, M. Gerla et al.
+ *   "TCP Westwood: bandwidth estimation for TCP" Proc. ACM Mobicom 2001
+ *
+ * - A. Grieco, s. Mascolo
+ *   "Performance evaluation of New Reno, Vegas, Westwood+ TCP" ACM Computer
+ *     Comm. Review, 2004
+ *
+ * - A. Dell'Aera, L. Grieco, S. Mascolo.
+ *   "Linux 2.4 Implementation of Westwood+ TCP with Rate-Halving :
+ *    A Performance Evaluation Over the Internet" (ICC 2004), Paris, June 2004
+ *
+ * Westwood+ employs end-to-end bandwidth measurement to set cwnd and
+ * ssthresh after packet loss. The probing phase is as the original Reno.
  */
 /*
 #include <linux/config.h>
@@ -24,6 +41,8 @@
 	u32    accounted;
 	u32    rtt;
 	u32    rtt_min;          /* minimum observed RTT */
+	u8     first_ack;        /* flag which infers that this is the first ack */
+	u8     reset_rtt_min;    /* Reset RTT min to next RTT sample*/
 };
 
 
@@ -51,9 +70,11 @@
         w->bw_est = 0;
         w->accounted = 0;
         w->cumul_ack = 0;
+	w->reset_rtt_min = 1;
 	w->rtt_min = w->rtt = TCP_WESTWOOD_INIT_RTT;
 	w->rtt_win_sx = tcp_time_stamp;
 	w->snd_una = tcp_sk(sk)->snd_una;
+	w->first_ack = 1;
 }
 
 /*
@@ -65,10 +86,16 @@
 	return (((7 * a) + b) >> 3);
 }
 
-static inline void westwood_filter(struct westwood *w, u32 delta)
+static void westwood_filter(struct westwood *w, u32 delta)
 {
-	w->bw_ns_est = westwood_do_filter(w->bw_ns_est, w->bk / delta);
-	w->bw_est = westwood_do_filter(w->bw_est, w->bw_ns_est);
+	/* If the filter is empty fill it with the first sample of bandwidth  */
+	if (w->bw_ns_est == 0 && w->bw_est == 0) {
+		w->bw_ns_est = w->bk / delta;
+		w->bw_est = w->bw_ns_est;
+	} else {
+		w->bw_ns_est = westwood_do_filter(w->bw_ns_est, w->bk / delta);
+		w->bw_est = westwood_do_filter(w->bw_est, w->bw_ns_est);
+	}
 }
 
 /*
@@ -93,6 +120,15 @@
 	struct westwood *w = inet_csk_ca(sk);
 	s32 delta = tcp_time_stamp - w->rtt_win_sx;
 
+	/* Initialize w->snd_una with the first acked sequence number in order
+	 * to fix mismatch between tp->snd_una and w->snd_una for the first
+	 * bandwidth sample
+	 */
+        if (w->first_ack) {
+		w->snd_una = tcp_sk(sk)->snd_una;
+		w->first_ack = 0;
+	}
+
 	/*
 	 * See if a RTT-window has passed.
 	 * Be careful since if RTT is less than
@@ -110,6 +146,16 @@
 	}
 }
 
+static inline void update_rtt_min(struct westwood *w)
+{
+	if (w->reset_rtt_min) {
+		w->rtt_min = w->rtt;
+		w->reset_rtt_min = 0;	
+	} else
+		w->rtt_min = min(w->rtt, w->rtt_min);
+}
+
+
 /*
  * @westwood_fast_bw
  * It is called when we are in fast path. In particular it is called when
@@ -125,7 +171,7 @@
 
 	w->bk += tp->snd_una - w->snd_una;
 	w->snd_una = tp->snd_una;
-	w->rtt_min = min(w->rtt, w->rtt_min);
+	update_rtt_min(w);
 }
 
 /*
@@ -164,12 +210,6 @@
 	return w->cumul_ack;
 }
 
-static inline u32 westwood_bw_rttmin(const struct sock *sk)
-{
-	const struct tcp_sock *tp = tcp_sk(sk);
-	const struct westwood *w = inet_csk_ca(sk);
-	return max_t(u32, (w->bw_est * w->rtt_min) / tp->mss_cache, 2);
-}
 
 /*
  * TCP Westwood
@@ -177,9 +217,11 @@
  * in packets we use mss_cache). Rttmin is guaranteed to be >= 2
  * so avoids ever returning 0.
  */
-static u32 tcp_westwood_cwnd_min(struct sock *sk)
+static u32 tcp_westwood_bw_rttmin(const struct sock *sk)
 {
-	return westwood_bw_rttmin(sk);
+	const struct tcp_sock *tp = tcp_sk(sk);
+	const struct westwood *w = inet_csk_ca(sk);
+	return max_t(u32, (w->bw_est * w->rtt_min) / tp->mss_cache, 2);
 }
 
 static void tcp_westwood_event(struct sock *sk, enum tcp_ca_event event)
@@ -193,17 +235,19 @@
 		break;
 
 	case CA_EVENT_COMPLETE_CWR:
-		tp->snd_cwnd = tp->snd_ssthresh = westwood_bw_rttmin(sk);
+		tp->snd_cwnd = tp->snd_ssthresh = tcp_westwood_bw_rttmin(sk);
 		break;
 
 	case CA_EVENT_FRTO:
-		tp->snd_ssthresh = westwood_bw_rttmin(sk);
+		tp->snd_ssthresh = tcp_westwood_bw_rttmin(sk);
+ 		/* Update RTT_min when next ack arrives */
+		w->reset_rtt_min = 1;
 		break;
 
 	case CA_EVENT_SLOW_ACK:
 		westwood_update_window(sk);
 		w->bk += westwood_acked_count(sk);
-		w->rtt_min = min(w->rtt, w->rtt_min);
+		update_rtt_min(w);
 		break;
 
 	default:
@@ -237,7 +281,7 @@
 	.init		= tcp_westwood_init,
 	.ssthresh	= tcp_reno_ssthresh,
 	.cong_avoid	= tcp_reno_cong_avoid,
-	.min_cwnd	= tcp_westwood_cwnd_min,
+	.min_cwnd	= tcp_westwood_bw_rttmin,
 	.cwnd_event	= tcp_westwood_event,
 	.get_info	= tcp_westwood_info,
 	.pkts_acked	= tcp_westwood_pkts_acked,
@@ -248,7 +292,7 @@
 
 static int __init tcp_westwood_register(void)
 {
-	BUG_ON(sizeof(struct westwood) > ICSK_CA_PRIV_SIZE);
+	BUILD_BUG_ON(sizeof(struct westwood) > ICSK_CA_PRIV_SIZE);
 	return tcp_register_congestion_control(&tcp_westwood);
 }
 
